MsgTransferTokens
Executes token transfers between addresses.
Proto Definition
message MsgTransferTokens {
string creator = 1; // Address initiating the transfer
string collectionId = 2; // Collection containing tokens to transfer
repeated Transfer transfers = 3; // Transfer operations (must pass approvals)
}
message MsgTransferTokensResponse {}
message Transfer {
// The address of the sender of the transfer.
string from = 1;
// The addresses of the recipients of the transfer.
repeated string toAddresses = 2;
// The balances to be transferred.
repeated Balance balances = 3;
// If defined, we will use the predeterminedBalances from the specified approval to calculate the balances at execution time.
// We will override the balances field with the precalculated balances. Only applicable for approvals with predeterminedBalances set.
ApprovalIdentifierDetails precalculateBalancesFromApproval = 4;
// The Merkle proofs / solutions for all Merkle challenges required for the transfer.
repeated MerkleProof merkleProofs = 5;
// The ETH signature proofs / solutions for all ETH signature challenges required for the transfer.
repeated ETHSignatureProof ethSignatureProofs = 6;
// The memo for the transfer.
string memo = 7;
// The prioritized approvals for the transfer. By default, we scan linearly through the approvals and use the first match.
// This field can be used to prioritize specific approvals and scan through them first.
repeated ApprovalIdentifierDetails prioritizedApprovals = 8;
// Whether to only check prioritized approvals for the transfer.
// If true, we will only check the prioritized approvals and fail if none of them match (i.e. do not check any non-prioritized approvals).
// If false, we will check the prioritized approvals first and then scan through the rest of the approvals.
bool onlyCheckPrioritizedCollectionApprovals = 9;
// Whether to only check prioritized approvals for the transfer.
// If true, we will only check the prioritized approvals and fail if none of them match (i.e. do not check any non-prioritized approvals).
// If false, we will check the prioritized approvals first and then scan through the rest of the approvals.
bool onlyCheckPrioritizedIncomingApprovals = 10;
// Whether to only check prioritized approvals for the transfer.
// If true, we will only check the prioritized approvals and fail if none of them match (i.e. do not check any non-prioritized approvals).
// If false, we will check the prioritized approvals first and then scan through the rest of the approvals.
bool onlyCheckPrioritizedOutgoingApprovals = 11;
// The options for precalculating the balances.
PrecalculationOptions precalculationOptions = 12;
}
message PrecalculationOptions {
// The timestamp to override with when calculating the balances.
string overrideTimestamp = 1;
// The IDs to override with when calculating the balances.
repeated UintRange tokenIdsOverride = 2;
}Auto-Scan vs Prioritized Approvals
The transfer approval system operates in two modes to balance efficiency and precision:
Auto-Scan Mode (Default)
By default, the system automatically scans through available approvals to find a match for the transfer. This mode:
Works with: Approvals using Empty Approval Criteria (no side effects)
Behavior: Automatically finds and uses the first matching approval
Use case: Simple transfers without custom logic or side effects
No versioning required: The system handles approval selection automatically
Prioritized Approvals (Required for Side Effects)
CRITICAL REQUIREMENT: Any transfer with side effects or custom approval criteria MUST always be prioritized with proper versioning set. No exceptions.
Race Condition Protection
The versioning control ensures that before submitting, the user knows the exact approval they are using:
Example: Coin Transfer Approval
Example: Auto-Scan Safe Transfer
Control Flags
onlyCheckPrioritizedCollectionApprovals: If true, only check prioritized approvalsonlyCheckPrioritizedIncomingApprovals: If true, only check prioritized incoming approvalsonlyCheckPrioritizedOutgoingApprovals: If true, only check prioritized outgoing approvals
Setting these to true is recommended when using prioritized approvals to ensure deterministic behavior.
Related Documentation
Empty Approval Criteria - Template for auto-scan compatible approvals
Approval Criteria - Understanding approval complexity
Coin Transfers - Side effect examples
Transfer Validation Process
Each transfer undergoes a systematic validation process to ensure security and proper authorization:
Validation Steps
Override Behavior
Collection approvals can override user-level approvals:
overridesFromOutgoingApprovals: true- Forcefully skips sender approval checkoverridesToIncomingApprovals: true- Forcefully skips recipient approval checks
This allows collection managers to enable transfers that would otherwise be blocked by user settings.
Failure Points
Transfers fail at the first validation step that doesn't pass:
Insufficient Balances - Sender doesn't own the tokens
No Collection Approval - No valid collection-level approval found
Blocked by Sender - Sender's outgoing approvals reject the transfer
Blocked by Recipient - Recipient's incoming approvals reject the transfer
ETH Signature Proofs
ETH Signature Proofs are required when transfers use ETH Signature Challenges. Each proof contains:
nonce: The unique identifier that was signedsignature: The Ethereum signature of the messagenonce + "-" + creatorAddress
Important: Each signature can only be used once per challenge tracker. The system tracks used signatures to prevent replay attacks.
Related Documentation
Transferability - Approval system overview
Collection Approvals - Collection-level controls
User Approvals - User-level settings
ETH Signature Challenges - Ethereum signature requirements
Collection ID Auto-Lookup
If you specify collectionId as "0", it will automatically lookup the latest collection ID created. This can be used if you are creating a collection and do not know the official collection ID yet but want to perform a multi-message transaction.
Usage Example
JSON Example
Last updated