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, theuserBurn
interface needs to be called.For all other tokens, the
userLock
interface should be used.For all ERC-20 tokens, an
approve
transaction 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
payable
2.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
userBurn
transaction type.If the token is a Solana-native token, use the
userLock
transaction 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:
AKXdNCG4GcTQ1knC7kno9bggHuq8MG9CCb8yQd8Nx2vL
programId:
E3iKvJgGNycXrmsh2aryY25z29PpU4dvo4CBuXCKQiGB
seeds:
[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:
CXxYYAtiUhdUagJNQ6UAB9gmHdxeujUPdn4iRg9HeuSz
admin_board_program:
7jYCM8k5Nvwg5vyPpLk2yjivQhexPDMXuK8CSbUKqL6B
config_account:
9o7zWu1n3q1MCAQp5y8RYmhhVjNpkfhpbSDMeYvjwhZP
token_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:
dFYBRAFvZKq9F4mYGkLQu8DbfZRFrmi5dNSTDfwC3a8
seeds:
[Buffer.from("FeeData", "utf8"), new BN(toChainId).toArrayLike(Buffer, "le", 4)]
token_program:
TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
associated_token_program:
ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL
system_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:
9o7zWu1n3q1MCAQp5y8RYmhhVjNpkfhpbSDMeYvjwhZP
token_manager_program:
6PcqfvWkBv3m9F5XBU2kMAedycs6BPzDGfi8zcWam3kH
fee_receiver:
CXxYYAtiUhdUagJNQ6UAB9gmHdxeujUPdn4iRg9HeuSz
admin_board_program:
7jYCM8k5Nvwg5vyPpLk2yjivQhexPDMXuK8CSbUKqL6B
token_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:
dFYBRAFvZKq9F4mYGkLQu8DbfZRFrmi5dNSTDfwC3a8
seeds:
[Buffer.from("FeeData", "utf8"), new BN(toChainId).toArrayLike(Buffer, "le", 4)]
token_program:
TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
associated_token_program:
ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL
system_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 theuserBurn
transaction type should be used.If the token policy ID is any other value, the token is a Cardano native token, and the
userLock
transaction 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