# 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>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.wanchain.org/developers/wanbridge-api/2.-creating-cross-chain-transactions-for-wanbridge/2.1-direct-interaction-with-on-chain-contracts.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
