#
Cross-Chain Operations
Detailed technical flows for minting, burning, and transferring Tortuga tokens across chains.
#
Operation Types
#
Mint Operation
Minting creates tokens on an external chain for a KYC-verified user.
#
Flow Diagram
sequenceDiagram
participant User
participant ML as Master Ledger
participant KYC as KYC Registry
participant CF as Chain Fusion
participant EXT as External Chain
User->>ML: request_mint(token, amount, chain, address)
ML->>KYC: is_verified(user)
KYC-->>ML: true
ML->>ML: Check balance on ICP
ML->>ML: Lock tokens
ML->>CF: request_mint(token, amount, chain, address)
CF->>CF: Build transaction
CF->>CF: Request threshold signature
Note over CF: ICP nodes sign collectively
CF->>EXT: Submit signed transaction
EXT-->>CF: tx_hash
CF->>CF: Monitor for confirmation
EXT-->>CF: Confirmed (N blocks)
CF->>ML: confirm_mint(request_id, tx_hash)
ML->>ML: Update balances
ML-->>User: Success
#
Request Structure
type MintRequest = record {
token_id : TokenId;
amount : nat;
target_chain : Chain;
recipient_address : Text; // Chain-specific format
memo : opt Text;
};
// EVM address: "0x742d35Cc6634C0532925a3b844Bc9e7595f..."
// Solana address: "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83T..."
// Cosmos address: "osmo1abc123..."
#
Validation Steps
- KYC Check: User must be verified
- Balance Check: Sufficient ICP balance
- Address Validation: Valid format for target chain
- Token Status: Token must be active (not suspended/matured)
- Chain Status: Target chain must be active
#
Burn Operation
Burning destroys tokens on an external chain and credits the user on ICP.
#
Flow Diagram
sequenceDiagram
participant User
participant EXT as External Chain
participant CF as Chain Fusion
participant ML as Master Ledger
participant KYC as KYC Registry
User->>EXT: Call burn(amount)
EXT->>EXT: Burn tokens
EXT->>EXT: Emit Burn event
Note over CF: Chain monitor detects event
CF->>EXT: Fetch event details
CF->>CF: Verify event authenticity
CF->>CF: Wait for finality
CF->>ML: report_burn(user, token, amount, tx_hash)
ML->>KYC: is_verified(user)
KYC-->>ML: true
ML->>ML: Credit ICP balance
ML-->>CF: Confirmed
Note over User: Balance updated on ICP
#
Burn Event Detection
Chain Fusion monitors external chains for burn events:
EVM Event:
event Burn(
address indexed from,
uint256 amount,
bytes32 icpPrincipal
);
Event Processing:
type BurnEvent = record {
chain : Chain;
tx_hash : Text;
block_number : nat64;
log_index : nat32;
burner : Text; // External chain address
amount : nat;
icp_principal : Principal; // Encoded in event data
};
#
Finality Requirements
#
Cross-Chain Transfer
Moving tokens from one external chain to another.
#
Flow Diagram
sequenceDiagram
participant User
participant ChainA as Source Chain
participant CF as Chain Fusion
participant ML as Master Ledger
participant ChainB as Target Chain
User->>ChainA: burn(amount, targetChain, targetAddress)
ChainA->>ChainA: Burn tokens
CF->>ChainA: Detect burn event
CF->>CF: Wait for finality
CF->>ML: Report burn
ML->>ML: Update balance (ChainA → pending)
ML->>CF: Request mint on ChainB
CF->>CF: Build transaction for ChainB
CF->>CF: Threshold signature
CF->>ChainB: Submit mint transaction
ChainB-->>CF: Confirmed
CF->>ML: Confirm mint
ML->>ML: Update balance (pending → ChainB)
#
Cross-Chain Message Format
type CrossChainMessage = record {
source_chain : Chain;
source_tx_hash : Text;
target_chain : Chain;
target_address : Text;
token_id : TokenId;
amount : nat;
sender_principal : Principal;
nonce : nat64;
};
#
Transaction Building
#
EVM Transaction
type EvmTransaction = record {
chain_id : nat64;
nonce : nat64;
max_priority_fee_per_gas : nat64;
max_fee_per_gas : nat64;
gas_limit : nat64;
to : Text; // Contract address
value : nat; // Always 0 for token ops
data : blob; // Encoded function call
};
// Mint function call
// mint(address to, uint256 amount)
// Selector: 0x40c10f19
#
Solana Transaction
type SolanaTransaction = record {
recent_blockhash : Text;
instructions : vec SolanaInstruction;
signers : vec Text;
};
type SolanaInstruction = record {
program_id : Text;
accounts : vec AccountMeta;
data : blob;
};
#
Cosmos Transaction
type CosmosTransaction = record {
chain_id : Text;
account_number : nat64;
sequence : nat64;
fee : CosmosFee;
msgs : vec CosmosMsg;
memo : Text;
};
type CosmosMsg = variant {
MsgExecuteContract : record {
sender : Text;
contract : Text;
msg : blob; // JSON encoded
funds : vec Coin;
};
};
#
Signature Schemes
#
ECDSA (EVM, Cosmos)
flowchart TB
subgraph Signing Process
TX[Transaction Hash] --> NODES[ICP Nodes]
NODES --> SHARE1[Signature Share 1]
NODES --> SHARE2[Signature Share 2]
NODES --> SHARE3[Signature Share N]
SHARE1 & SHARE2 & SHARE3 --> AGG[Aggregation]
AGG --> SIG[ECDSA Signature]
end
SIG --> VERIFY[Verify on Chain]Signature Format:
type EcdsaSignature = record {
r : blob; // 32 bytes
s : blob; // 32 bytes
v : nat8; // Recovery ID
};
#
EdDSA (Solana)
type EddsaSignature = record {
signature : blob; // 64 bytes
};
#
Nonce Management
#
EVM Nonce Tracking
type NonceManager = record {
chain : EvmChain;
current_nonce : nat64;
pending_txs : vec PendingTx;
};
type PendingTx = record {
nonce : nat64;
tx_hash : opt Text;
status : TxStatus;
created_at : Timestamp;
};
Nonce Handling:
flowchart TB
REQ[New TX Request] --> GET[Get Current Nonce]
GET --> INC[Increment Nonce]
INC --> BUILD[Build TX with Nonce]
BUILD --> SIGN[Sign TX]
SIGN --> SUBMIT[Submit TX]
SUBMIT --> CONFIRM{Confirmed?}
CONFIRM -->|Yes| DONE[Done]
CONFIRM -->|No, Timeout| REPLACE[Replace TX]
REPLACE --> BUILD
#
Error Recovery
#
Stuck Transaction
flowchart TB
STUCK[TX Stuck in Mempool] --> CHECK{Check Status}
CHECK -->|Still Pending| WAIT{Wait Threshold?}
WAIT -->|No| CHECK
WAIT -->|Yes| REPLACE[Build Replacement TX]
REPLACE --> HIGHER[Higher Gas Price]
HIGHER --> RESIGN[Re-sign TX]
RESIGN --> RESUBMIT[Resubmit]
CHECK -->|Dropped| REBUILD[Rebuild TX]
REBUILD --> RESIGN
#
Failed Transaction
type TxFailure = variant {
InsufficientGas;
Reverted : Text; // Revert reason
NonceConflict;
NetworkError : Text;
SignatureFailed;
};
type RecoveryAction = variant {
Retry;
RetryWithHigherGas;
RetryWithNewNonce;
ManualReview;
Abort;
};
#
Rate Limiting & Batching
#
Rate Limits
#
Transaction Batching
For chains that support it, multiple mints can be batched:
flowchart LR
Q[TX Queue] --> BATCH[Batch Builder]
BATCH --> CHECK{Batch Full?}
CHECK -->|Yes| SIGN[Sign Batch]
CHECK -->|No| WAIT[Wait]
WAIT --> TIMEOUT{Timeout?}
TIMEOUT -->|Yes| SIGN
TIMEOUT -->|No| Q
SIGN --> SUBMIT[Submit]
#
Monitoring & Alerts
#
Metrics Tracked
#
Health Check
candid
service : {
health_check : () -> (HealthStatus) query;
}
type HealthStatus = record {
overall : Status;
chains : vec ChainHealth;
pending_txs : nat32;
last_successful_tx : Timestamp;
};
type ChainHealth = record {
chain : Chain;
status : Status;
last_block : nat64;
pending_count : nat32;
error_rate : float64;
};