2.1 Direct Interaction with On-chain Contracts
2.1.1 EVM Compatible Chains
There are two contract interfaces available: userLock and userBurn.
For tokens whose names include
@(e.g.,wanUSDT@wanchain,WAN@ethereum), which are WanBridge Wrapped Tokens, theuserBurninterface needs to be called.For all other tokens, the
userLockinterface should be used.For all ERC-20 tokens, an
approvetransaction must be executed first.
function userLock(bytes32 smgID, uint tokenPairID, uint value, bytes userAccount)
external
payable
function userBurn(bytes32 smgID, uint tokenPairID, uint value, uint fee, address tokenAccount, bytes userAccount)
external
payable2.1.2 Tron
The process for Tron follows the same structure as described in 2.1.1 EVM-Compatible Chains.
2.1.3 Solana
There are two transaction types: userLock and userBurn. For tokens on Solana, users must determine whether they are Solana-native tokens or Wanchain-mapped tokens.
Determining Token Type and Transaction Type
If the token is a Wanchain-mapped token, use the
userBurntransaction type.If the token is a Solana-native token, use the
userLocktransaction type.
General Transaction Requirements
For cross-chain transactions, you can build transactions using your preferred wallet and Solana libraries such as solana-web3.js and anchor.
2.1.3.1 userLock Transaction Type
Program requirements
programId:
E3iKvJgGNycXrmsh2aryY25z29PpU4dvo4CBuXCKQiGB
Instruction Definition
pub fn user_lock(ctx: Context<UserLock>, smg_id: [u8; 32], token_pair_id: u32, amount: u64, user_account: Vec<u8>)
Accounts Requirements
user: User wallet account
sol_vault:
AKXdNCG4GcTQ1knC7kno9bggHuq8MG9CCb8yQd8Nx2vLprogramId:
E3iKvJgGNycXrmsh2aryY25z29PpU4dvo4CBuXCKQiGBseeds:
[Buffer.from("vault", "utf8")]
user_ata: Token ATA account for the user wallet; null if the cross-chain token is SOL
token_vault: Token ATA account for
sol_vault; null if the cross-chain token is SOLmapping_token_mint: Cross-chain token account; null if the cross-chain token is SOL
fee_receiver:
CXxYYAtiUhdUagJNQ6UAB9gmHdxeujUPdn4iRg9HeuSzadmin_board_program:
7jYCM8k5Nvwg5vyPpLk2yjivQhexPDMXuK8CSbUKqL6Bconfig_account:
9o7zWu1n3q1MCAQp5y8RYmhhVjNpkfhpbSDMeYvjwhZPtoken_pair_account: Token pair account for the token pair ID
programId: 7jYCM8k5Nvwg5vyPpLk2yjivQhexPDMXuK8CSbUKqL6B
seeds:
[Buffer.from("TokenPairInfo", "utf8"), new BN(tokenPairId).toArrayLike(Buffer, "le", 4)]
cctp_admin_board_fee_account: Chain fee account for the target chain ID from token pair info
programId:
dFYBRAFvZKq9F4mYGkLQu8DbfZRFrmi5dNSTDfwC3a8seeds:
[Buffer.from("FeeData", "utf8"), new BN(toChainId).toArrayLike(Buffer, "le", 4)]
token_program:
TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DAassociated_token_program:
ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knLsystem_program:
11111111111111111111111111111111
2.1.3.2 userBurn Transaction Type
Program Requirements
programId:
E3iKvJgGNycXrmsh2aryY25z29PpU4dvo4CBuXCKQiGB
Instruction Definition
pub fn user_burn(ctx: Context<UserBurn>, smg_id: [u8; 32], token_pair_id: u32, amount: u64, fee: u64, token_account: Pubkey, user_account: Vec<u8>)
Accounts Requirements
user: User wallet account
user_ata: Token ATA account for the user wallet
mapping_token_mint: Cross-chain token account
config_account:
9o7zWu1n3q1MCAQp5y8RYmhhVjNpkfhpbSDMeYvjwhZPtoken_manager_program:
6PcqfvWkBv3m9F5XBU2kMAedycs6BPzDGfi8zcWam3kHfee_receiver:
CXxYYAtiUhdUagJNQ6UAB9gmHdxeujUPdn4iRg9HeuSzadmin_board_program:
7jYCM8k5Nvwg5vyPpLk2yjivQhexPDMXuK8CSbUKqL6Btoken_pair_account: Token pair account for the token pair ID
programId:
7jYCM8k5Nvwg5vyPpLk2yjivQhexPDMXuK8CSbUKqL6Bseeds:
[Buffer.from("TokenPairInfo", "utf8"), new BN(tokenPairId).toArrayLike(Buffer, "le", 4)]
cctp_admin_board_fee_account: Chain fee account for the target chain ID from token pair info
programId:
dFYBRAFvZKq9F4mYGkLQu8DbfZRFrmi5dNSTDfwC3a8seeds:
[Buffer.from("FeeData", "utf8"), new BN(toChainId).toArrayLike(Buffer, "le", 4)]
token_program:
TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DAassociated_token_program:
ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knLsystem_program:
11111111111111111111111111111111
2.1.3.3 References
PublicKey.findProgramAddressSync
Solana Documentation
2.1.4 ADA
There are two types of transactions: userLock and userBurn. For tokens on the Cardano network, the user must determine whether they are Cardano native tokens or Wanchain-mapped tokens.
Determine Cardano Token Types and Transaction Types
If the token policy ID is
25c5de5f5b286073c593edfd77b48abc7a48e5a4f3d4cd9d428ff935, the token is a Wanchain-mapped token, and theuserBurntransaction type should be used.If the token policy ID is any other value, the token is a Cardano native token, and the
userLocktransaction type should be used.
General Transaction Requirements
For cross-chain transactions, users can build transactions using their preferred wallet along with the Lucid library or other libraries.
If a network fee is required, the transaction must include an additional output UTXO in ADA with the actual
networkFee, sent to the fee receiver address:addr1qyxqtjnck8f0gyzys6kwpydd5lrcjue6tg8f2elqhs65ffy7trczz375trxwfgc7zvkvxrxcr4plz8tnqv6qre7u722qhe650r
2.1.4.1 userLock Transaction Type
Metadata Requirements for Cross-Chain Information
let data = {
1: {
type: TX_TYPE.userLock,
tokenPairID: Number(tokenPairID),
fromAccount: this.tool.splitMetadata(fromAccount),
toAccount,
smgID
}
};
data = this.wasm.encode_json_str_to_metadatum(JSON.stringify(data), this.wasm.MetadataJsonSchema.BasicConversions);
return this.wasm.GeneralTransactionMetadata.from_bytes(data.to_bytes());
Metadata Example from Cardano Explorer
1
{
"type": 1,
"smgID": "0x000000000000000000000000000000000000000000000041726965735f303333",
"toAccount": "0x8b157b3ffead48c8a4cdc6bddbe1c1d170049da4",
"fromAccount": [
"addr1q8nd57644dctpmh5z49u9kxdsr6t2px0jg0es4gjpy7kvzk2decd8n4d28t",
"9helaqh6eq8tqpqxjn5km60dxreegmzuqesanym"
],
"tokenPairID": 553
}
Output Requirements to Locked Account of Cardano Contract
Only one output UTXO to the locked address is allowed.
Inline Datum:
let ls = wasm.PlutusList.new(); ls.add(wasm.PlutusData.new_integer(wasm.BigInt.from_str('1'))); return wasm.PlutusData.new_constr_plutus_data( wasm.ConstrPlutusData.new( wasm.BigNum.from_str('0'), ls ) )
Inline Datum Example from Cardano Explorer
{
"fields": [
{
"int": 1
}
],
"constructor": 0
}
2.1.4.2 userBurn Transaction Type
Metadata Requirements for Cross-Chain Information
let data = {
1: {
type: TX_TYPE.userBurn,
tokenPairID: Number(tokenPairID),
fromAccount: this.tool.splitMetadata(fromAccount),
toAccount,
smgID
}
};
data = this.wasm.encode_json_str_to_metadatum(JSON.stringify(data), this.wasm.MetadataJsonSchema.BasicConversions);
return this.wasm.GeneralTransactionMetadata.from_bytes(data.to_bytes());
Metadata Example from Cardano Explorer
1
{
"type": 8,
"smgID": "0x000000000000000000000000000000000000000000000041726965735f303335",
"toAccount": "0xca077dff2499ca3338d039abdc1939c287ca8690",
"fromAccount": [
"addr1qyrpkudmpvwyy79senufvfzc6dfq5qszkp6h099wrjcngp3zvct9scn6xme",
"ks504tjgkmdd4wjjk9j6y3k6g9cthjlusuy3lpm"
],
"tokenPairID": 510
}
Minting Requirements
The transaction must include only one token mint for the cross-chain token and amount.
2.1.4.3 References
Referene codes for Cardano transaction handling in cross-chain SDK:
Reference cross-chain transaction examples:
Last updated