# 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, the `userBurn` 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.

```json
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 SOL
* **mapping\_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**

* <https://solana-labs.github.io/solana-web3.js/classes/PublicKey.html#findProgramAddressSync>

**Solana Documentation**

* <https://solana.com/docs/clients/javascript-reference#publickey>

#### 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 the `userBurn` 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**

```haskell
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**

```json
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**

```json
{
    "fields": [
        {
            "int": 1
        }
    ],
    "constructor": 0
}

```

#### **2.1.4.2 userBurn Transaction Type**

**Metadata Requirements for Cross-Chain Information**

```haskell
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**

```json
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:

* <https://github.com/wanchain/wanchain-cross-sdk/tree/mainnet/packages/core>
* <https://github.com/wanchain/wanchain-cross-sdk/tree/mainnet/packages/cardano>
* <https://github.com/wanchain/wanchain-cross-sdk/blob/mainnet/packages/core/src/config/taskTypeConfig/processBurnFromCardano.js>

Reference cross-chain transaction examples:

* <https://wanscan.org/tx/b7e34ad2767e8293804ed9a52f8a6e543e7024800fee7ee428c3ea5bd526fefa?unique=0xb7e34ad2767e8293804ed9a52f8a6e543e7024800fee7ee428c3ea5bd526fefa>
* <https://cardanoscan.io/transaction/b7e34ad2767e8293804ed9a52f8a6e543e7024800fee7ee428c3ea5bd526fefa>
* <https://cardanoscan.io/transaction/297bc7be52f58aab722fd04bd71db8085db7634365b7c899e705e81ecd0e3973>
