Wanchain - We Are All Connected!
WebsiteBridgeExplorerEcosystem
  • 👋 Welcome to Wanchain
  • Products
    • WanBridge
      • Bridge-to-Earn
      • XP
    • XFlows
      • XP
    • XPort
      • XPort developer handbook
      • Supported chains
    • XStake
  • Cross-Chain Infrastructure
    • Wanchain Bridge Node Group
    • Wanchain L1 blockchain
      • Network information
    • WAN coin
      • How to get WAN coins
      • WAN coin faucets
      • xWAN
  • The Convert n' Burn System
    • Overview
    • Bridge fees
      • Conversion and distribution
    • Discounts
  • Developers
    • WanBridge API
      • 1. Information Retrieval
        • 1.1 Supported Chains and Tokense 1
        • 1.2 Cross-chain Quota and Fees
        • 1.3 Asset Lock Address
        • 1.4 Storeman Group ID (smgID)
      • 2. Creating Cross-chain Transactions for WanBridge
        • 2.1 Direct Interaction with On-chain Contracts
        • 2.2 Creating Cross-Chain Transactions Using API
      • 3. Circle CCTP Cross-Chain
        • 3.1 EVM Compatible Chains
      • 4. Status Query
    • XFlows API
      • 1.1 Basic Information
      • 1.2 Request Parameters
      • 1.3 Response Parameters
      • 1.4 Examples
      • 1.5 Notes
      • 1.6 Status Query
    • XPort Developer Handbook
  • PoS Validator Nodes
    • Important Terms and Parameter
    • Recommended Hardware & Software
    • Mainnet Node Setup (Quick Start)
    • Mainnet Node Setup (Manually)
    • Getting Started With AWS
    • Common Operations (CLI)
    • Delegation Guide
    • Commonly Used Scripts
    • GWAN PoS API
    • Partner Model Staking Guide
    • Staking FAQ
  • Wanchain Bridge Nodes
    • Fact Sheet
    • How to deploy a Bridge Node
  • External Links
    • Blog
    • Email
    • GitHub
    • Telegram
    • Telegram Tech Support
    • Twitter/X
    • WanBridge
    • XFlows
    • XStake
    • WanScan
    • Website
Powered by GitBook
On this page
  1. Developers
  2. WanBridge API
  3. 2. Creating Cross-chain Transactions for WanBridge

2.2 Creating Cross-Chain Transactions Using API

Previous2.1 Direct Interaction with On-chain ContractsNext3. Circle CCTP Cross-Chain

Last updated 1 day ago

2.2.1 EVM Compatible Chains

The transaction generation API allows the server to quickly fill in cross-chain parameters and return cross-chain transaction data that is ready for user signing.

Example:

curl -X POST -H "Content-Type: application/json"  --data '{"fromChain":"OETH", "toChain":"ETH", "fromToken":"0x0000000000000000000000000000000000000000", "toToken":"0x0000000000000000000000000000000000000000", "toAccount":"0x4Cf0A877E906DEaD748A41aE7DA8c220E4247D9e", "amount": "0.01"}' <https://bridge-api.wanchain.org/api/createTx>

Parameter explanation:

Use the HTTP POST method and provide the following JSON payload:

{
  "fromChain": "OETH",
  "toChain": "ETH",
  "fromToken": "0x0000000000000000000000000000000000000000",
  "toToken": "0x0000000000000000000000000000000000000000",
  "fromAccount": "0x4Cf0A877E906DEaD748A41aE7DA8c220E4247D9e",
  "toAccount": "0x4Cf0A877E906DEaD748A41aE7DA8c220E4247D9e",
  "amount": "0.01"
}
  • fromChain / toChain: Specify either the chainType or chainId from the table below (do not mix them).

  • fromToken / toToken: Token contract address; use 0x0000000000000000000000000000000000000000 for native coins.

  • toAccount: Destination wallet address on the target chain.

  • amount: Amount to transfer, represented as a decimal string.

Supported Chains:

Index
Chain Name
Chain Type
Chain ID

1

Bitcoin

BTC

2147483648

2

Litecoin

LTC

2147483650

3

Dogecoin

DOGE

2147483651

4

Ethereum

ETH

2147483708

5

XRPL

XRP

2147483792

6

EOS

EOS

2147483842

7

Tron

TRX

2147483843

8

Polkadot

DOT

2147484002

9

XinFin.Network

XDC

2147484198

10

Optimism

OETH

2147484262

11

BSC

BNB

2147484362

12

Astar

ASTR

2147484458

13

Polygon

MATIC

2147484614

14

Telos

TLOS

2147484625

15

OKT Chain

OKT

2147484644

16

Fantom

FTM

2147484655

17

Cardano

ADA

2147485463

18

Avalanche C-Chain

AVAX

2147492648

19

Energi

NRG

2147493445

20

Wanchain

WAN

2153201998

21

Bitrock

BROCK

2154655314

22

Moonriver

MOVR

1073741825

23

Arbitrum

ARETH

1073741826

24

Moonbeam

GLMR

1073741828

25

f(x)Core

FX

1073741830

26

Gather

GTH

1073741833

27

Metis

METIS

1073741834

28

Songbird

SGB

1073741836

29

zkSync Era

ZKETH

1073741837

30

Horizen EON

ZEN

1073741839

31

VinuChain

VC

1073741840

32

BASE

BASEETH

1073741841

33

Linea

LINEAETH

1073741842

Response Example:

{
  "success": true,
  "data": {
    "approveCheck": {
      "from": "0x4Cf0A877E906DEaD748A41aE7DA8c220E4247D9e",
      "token": "0xc2132d05d31c914a87c6611c10748aeb04b58e8f",
      "to": "0x2216072A246A84f7b9CE0f1415Dd239C9bF201aB",
      "amount": "10000"
    },
    "tx": {
      "from": "0x4Cf0A877E906DEaD748A41aE7DA8c220E4247D9e",
      "to": "0x2216072A246A84f7b9CE0f1415Dd239C9bF201aB",
      "value": "0xde0b6b3a7640000",
      "data": "0x257011b6000000000000000000000000000000000000000000000041726965735f30333600000000000000000000000000000000000000000000000000000000000000bb0000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000144cf0a877e906dead748a41ae7da8c220e4247d9e000000000000000000000000"
    },
    "receiveAmount": "0.01",
    "chainId": 137,
    "txDataDetail": {
      "func": "userLock(bytes32,uint256,uint256,bytes)",
      "params": [
        "0x000000000000000000000000000000000000000000000041726965735f303336",
        "187",
        "10000",
        "0x4Cf0A877E906DEaD748A41aE7DA8c220E4247D9e"
      ]
    },
    "feeAndQuota": {
      "symbol": "USDT",
      "minQuota": "0",
      "maxQuota": "28543742384",
      "networkFee": {
        "value": "1000000000000000000",
        "isPercent": false
      },
      "operationFee": {
        "value": "0",
        "isPercent": true
      }
    }
  }
}
  • If unsuccessful, success: false, and the reason for the error is returned.

  • The tx in the return value is the transaction body that can be used for wallet signing. Only the necessary parts are filled in, and the remaining parts can be automatically filled in by estimation on the chain.

  • If the approveCheck field exists, the ERC20 allowance must be checked first according to its contents. If the allowance is insufficient, an approve transaction needs to be sent first, followed by the tx.

  • receiveAmount is the expected amount of tokens to be received on the target chain.

  • txDataDetail is the detailed information of the packed transaction data field.

  • feeAndQuota is the details of the current cross-chain quota and fees, used for UI display.

Moreover, Partners can use the following API to record partner information for cross-chain initiations:

You must fill in the partner's name within the body data.

Below is an example JSON request:

{
  "fromChain": "ETH",
  "toChain": "BNB",
  "fromAccount": "0xdce713ec124daaeb25a458ef6dc51a5b48bcdbd8",
  "toAccount": "0xdce713ec124daaeb25a458ef6dc51a5b48bcdbd8",
  "amount": "100",
  "fromToken": "0xdac17f958d2ee523a2206206994597c13d831ec7",
  "toToken": "0x55d398326f99059ff775485246999027b3197955",
  "partner": "wanlend"
}

The response data format is the same as the regular createTx. In the returned transaction, the to address is replaced with crossWrapper to record the cross-chain partner information. Currently, the chains that support recording partner information include: WAN, ARETH, AVAX, ETH, MATIC, LINEAETH, PLYR, MOVR, GLMR, FTM, OETH, OKB, VC, ZEN, MATICETH, METIS, BLASTETH, XDC, FX, BASEETH, OPBNB, BNB, SGB.

TRX Chain Transaction

Transactions from the TRX chain differ from those from EVM-compatible chains.

Below is the API response format:

{
  "success": true,
  "data": {
    "approveCheck": {
      "from": "0x4Cf0A877E906DEaD748A41aE7DA8c220E4247D9e",
      "token": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c",
      "to": "41fe464ebd5bb5d95731f90aa7b9e39df920a61c97",
      "amount": "10000"
    },
    "tx": {
      "from": "0x4Cf0A877E906DEaD748A41aE7DA8c220E4247D9e",
      "to": "41fe464ebd5bb5d95731f90aa7b9e39df920a61c97",
      "abi": [
        {
          "inputs": [
            {
              "internalType": "bytes32",
              "name": "smgID",
              "type": "bytes32"
            },
            {
              "internalType": "uint256",
              "name": "tokenPairID",
              "type": "uint256"
            },
            {
              "internalType": "uint256",
              "name": "value",
              "type": "uint256"
            },
            {
              "internalType": "bytes",
              "name": "userAccount",
              "type": "bytes"
            }
          ],
          "name": "userLock",
          "outputs": [],
          "stateMutability": "payable",
          "type": "function"
        }
      ],
      "functionSelector": "userLock(bytes32,uint256,uint256,bytes)",
      "rawParameter": "0x000000000000000000000000000000000000000000000041726965735f30333900000000000000000000000000000000000000000000000000000000000001110000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000144cf0a877e906dead748a41ae7da8c220e4247d9e000000000000000000000000",
      "params": [
        "0x000000000000000000000000000000000000000000000041726965735f303339",
        "273",
        "10000",
        "0x4Cf0A877E906DEaD748A41aE7DA8c220E4247D9e"
      ],
      "value": "0x13ab6680"
    },
    "receiveAmount": "0.01",
    "feeAndQuota": {
      "symbol": "USDT",
      "minQuota": "1",
      "maxQuota": "953399472649",
      "networkFee": {
        "value": "330000000",
        "isPercent": false
      },
      "operationFee": {
        "value": "0",
        "isPercent": false
      }
    }
  }
}

The API response doesn't return the data for tx, but it returns ABI, smart contract (SC) address, function name and function params for TronLink to use. You can use the ABI and SC address to call the function by TronLink in your frontend code. Here is an exaple:

import { decodeFunctionData, parseAbi } from 'viem';

async function sendTronTx({
  toAddr,
  functionSelector,
  callValue,
  data, // raw tx.data
  params, // arrays, function params
}) {
  if (!window.tronWeb?.ready) {
    console.log('[TRON_TX] Requesting TronLink authorization...');
    const res = await window.tronLink.request({ method: 'tron_requestAccounts' });
    console.log('[TRON_TX] TronLink authorization result:', res);
    if (res.code !== 200) {
      throw new Error(`TronLink authorization failed: ${res.message}`);
    }
  }

  const isMobile = window.innerWidth <= 768;

  const abi = parseAbi(['function ' + functionSelector]);
  
  let decoded;

  if (data) {
    decoded = decodeFunctionData({
      abi,
      data: data
    });
  } else if (params) {
    decoded = {args: params};
  }
  
  console.log('function args', abi, decoded.args);
  abi[0].stateMutability = "payable";

  const sendParams = {
    feeLimit: 300_000_000,
    callValue: Number(callValue),
    shouldPollResponse: !isMobile,
    keepTxID: true,
  };
  console.log('sendParams', sendParams);

  const contract = await window.tronWeb.contract(abi, toAddr);
  const result = await contract[functionSelector.split('(')[0]](...decoded.args).send(
    sendParams
  );
  console.log('send tx', result);
  return result;
}

let txResult = await sendTronTx({
  toAddr: tx.to,
  functionSelector: tx.functionSelector,
  callValue: tx.value,
  params: tx.params,
});
console.log('tron tx result', txResult);
let txHash = Array.isArray(txResult) ? txResult[0] : txResult;

2.2.3 Bitcoin Chain Cross-chain API

2.2.3.1 Using Unisat Extension Wallet

(This method currently supports cross-chain transactions between EVM chains and Bitcoin.)

API endpoint:

  • Mainnet: https://bridge-api.wanchain.org/api/createTx2

  • Testnet:

    https://bridge-api.wanchain.org/api/testnet/createTx2

Request Body Example:

{
  "fromChain": "BTC",
  "toChain": "WAN",
  "fromAccount": "bc1qugvdunxxzqvy80hysz9y77nx50240n7ghhz3rd",
  "fromToken": "0x0000000000000000000000000000000000000000",
  "toToken": "0x50c439B6d602297252505a6799d84eA5928bCFb6",
  "toAccount": "0x4Cf0A877E906DEaD748A41aE7DA8c220E4247D9e",
  "amount": "0.001",
  "partner": "tester"
}

Response Example:

{
  "success": true,
  "data": {
    "tx": {
      "fromAccount": "bc1qugvdunxxzqvy80hysz9y77nx50240n7ghhz3rd",
      "toAccount": "bc1pqnxalrglv6jglj9w9kg0dk9tyvkraw2xlj6cpzz8t3kxjl6pywesxqdfpg",
      "value": 100000,
      "memo": "01000f4cf0a877e906dead748a41ae7da8c220e4247d9e"
    },
    "receiveAmount": "0.00064",
    "feeAndQuota": {
      "symbol": "BTC",
      "minQuota": "72000",
      "maxQuota": "100000000",
      "networkFee": {
        "value": "0",
        "isPercent": false
      },
      "operationFee": {
        "value": "0.002",
        "isPercent": true,
        "minFeeLimit": "36000",
        "maxFeeLimit": "320000",
        "discountPercent": "1"
      }
    }
  }
}

Sign the transaction using Unisat Wallet:

await (window as any).unisat.requestAccounts();
await (window as any).unisat.switchNetwork(isBtcTestnet ? 'testnet' : 'livenet');

const txData = result.data.tx;

const tx = await (window as any).unisat.sendBitcoin(txData.toAccount, txData.value, {
  memo: txData.memo
});

Demo UI: [https://bridge-api-demo-ui.vercel.app/](<https://bridge-api-demo-ui.vercel.app/>)

2.2.3.2 Using One-Time Address

Step 1: Generate a One-Time Address

1) Send Request

  • Request Method: HTTP POST

  • Request Type: Content-Type: application/json

Request Body Example:

{
	"fromChainType":"BTC", 
	"toAddress":"0x4Cf0A877E906DEaD748A41aE7DA8c220E4247D9e", 
	"toChainType":"ETH", 
	"amount":"0.03", 
	"tokenPairID":"416"
}

Please fill in the correct values as required:

  • fromChainType: Fixed as BTC.

  • toAddress: Recipient's address. Ensure the address is correct to avoid asset loss.

  • toChainType: Destination chain type.

  • amount: Amount to transfer (in BTC).

  • tokenPairID: Cross-chain pair ID.

2) Response Request

  • Success

    • Successful return with HTTP status code: 200

    • Successful return with data:

{
	"success":true,
	"data":{
		"ota":"bc1p0s57ehsgnva826zff0p4l6dajsp7cdac9uw78j2vwcqhew3cvgvqvhm6z3"
	}
}
  • Failure

    • Failed return with HTTP status code: 400 (Input parameter error) or 500 (Internal server error).

    • Failed return with data: {success: false, error: "XXXXXXX"}

Step 2: Submit cross-chain ID (txHash)

After completing the BTC transfer to the one-time address using the front-end wallet (e.g., OKX extension wallet), this API is used to submit the transaction ID (txid) for tracking and monitoring.

1) Send Request

  • Request Method: HTTP POST

  • Request Type: Content-Type: application/json

Request Body Example:

{
	"fromChainType":"BTC", 
	"toAddress":"0x4Cf0A877E906DEaD748A41aE7DA8c220E4247D9e", 
	"toChainType":"ETH", 
	"amount":"0.03", 
	"tokenPairID":"416",
	"ota":"bc1p0s57ehsgnva826zff0p4l6dajsp7cdac9uw78j2vwcqhew3cvgvqvhm6z3",
	"txid":"0e9086c7568b6892bbbd1e407791749b2ed04efd7d1302f54236875a94b23dad",
}

Please fill in the correct values as required. The information is the same as the previous step, with the addition of the ota and txid fields:

  • fromChainType: Fixed as BTC.

  • toAddress: Recipient's address. Ensure the address is correct to avoid asset loss.

  • toChainType: Destination chain type.

  • amount: Amount to transfer (in BTC).

  • tokenPairID: Cross-chain pair ID.

  • ota: One-time address generated in Step 1.

  • txid: Transaction ID of the user's transfer to the one-time address.

2) Response Request

  • Success

    • Successful return with HTTP status code: 200

    • Successful return with data:

{
	"success":true
}
  • Failure

    • Failed return with HTTP status code: 400 (Input parameter error) or 500 (Internal server error).

    • Failed return with data: {success: false, error: "XXXXXXX"}

Step 3: Query cross-chain status

The status query API uses the transaction ID (txid) as the key for querying the cross-chain status.

The query interface and return value rules for cross-chain status are the same as those for other cross-chain status queries, with TXID as the key value for querying.

Example:

<https://bridge-api.wanchain.org/api/status/c3bf5e2d50bbb5574659014478b691c1173fc783f82143105519e876d42f1443>

Response:

{
  "success": true,
  "data": {
    "timestamp": 1715244313,
    "tokenPair": "14",
    "lockHash": "c3bf5e2d50bbb5574659014478b691c1173fc783f82143105519e876d42f1443",
    "redeemHash": null,
    "status": "Processing",
    "sendAmount": "620000",
    "receiveAmount": "450000"
  }
}

2.2.3 Solana Cross-chain API

The API requires Base64 format for both the token address and user address.

API Endpoint:

[https://bridge-api.wanchain.org/api/createTx2](<https://bridge-api.wanchain.org/api/createTx2>)

Example:

{
  "fromChain": "SOL",
  "toChain": "WAN",
  "fromAccount": "2SFMj2XNzFCTzeQE8rEk82MxBq3A4u4J6uQvEnpmcqyh",
  "fromToken": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
  "toToken": "0x11e77e27af5539872efed10abaa0b408cfd9fbbd",
  "toAccount": "0x4Cf0A877E906DEaD748A41aE7DA8c220E4247D9e",
  "amount": "100",
  "partner": "tester"
}

Response:

{
  "success": true,
  "data": {
    "tx": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAkQFVNw5ypthVgz8lFRPNfRPMe/ufQ6BixH/73YR4GegvARmRgCboMLEMpUIcrDJaFrT4GCoPLTAasQxQbfGF0hBYp4RFa7pb2pvCGzouPhTK/JjmCmAjbAyeRbZYwlN7IBq17IstiexWxlH5f1eUaTIUFwyRjo2Jgy/OIrGqOCkbvOAQ5gr+2yJxe9YxkvVBRaP5ZaM7uC0scCnrLOHiCCZPhDqGSG9NzvJAMjouHzKK6fXYMZ7xqdRKf3uzsun46y9OK3dD15Njl2BIn/TZRozoWixzhnIbCG0CkSCmmjy3sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSwg0+FVMmk6FXkLPjnIEQ+TzLKfJflaFCjyd8PEuNaZAvJ3zPF3TuKHxCJuoD0D12vyiNb33Pn7X9aQQr1uVh3YW5fcGFydG5lcjp0ZXN0ZXIAAAAAAAAAAAAAAAAAAIKuHjxKyDYGsUdRHhJStJ+ig4GshjU9tRes6hpJ9C5mjJclj04kifG7PRApFI4NgwtaE5na/xCEBI572Nvp+FkDBkZv5SEXMv/srbpyw5vnvIzlu8X3EmssQ5s6QAAAAMHZ0b/TXl3f9PqMZ5KMpkjVm5YHFgVTF3+dEkEumuJMBt324ddloZPZy+FGzut5rBy0he1fWzeROoz1hX7/AKmcldRJK8MokqBJ+Nqmh+6Aa6vYo/toVwRHbm2r0+UehgIODgACAQUEAwkLBggPDAcKYkIR1n7rhVJyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBcmllc18wNTFTAwAAAOH1BQAAAAAqAAAAMHg0Q2YwQTg3N0U5MDZERWFENzQ4QTQxYUU3REE4YzIyMEU0MjQ3RDllDQAFAkBCDwA=",
    "receiveAmount": "99.8",
    "chainId": "0x384",
    "feeAndQuota": {
      "symbol": "USDT",
      "minQuota": "400000",
      "maxQuota": "7174693343715",
      "networkFee": {
        "value": "100000",
        "isPercent": false
      },
      "operationFee": {
        "value": "0.002",
        "isPercent": true,
        "minFeeLimit": "200000",
        "maxFeeLimit": "100000000"
      }
    }
  }
}

Usage:


const rawTx = ret.data.tx; // defautl base64
const data = xxxx; // base58 (Optional) (OKX api return in this format)
export async function sendSolanaTx({rawTx, data}) {
  console.log('Send Solana tx', {rawTx});
  const provider = window.solana;
  const connection = new Connection('https://YOUR_SOLANA_RPC');

  // Deserialize the transaction using VersionedTransaction
  const buffer = rawTx ? Buffer.from(rawTx, 'base64') : Buffer.from(bs58.decode(data));
  const tx = VersionedTransaction.deserialize(new Uint8Array(buffer));
  const { blockhash } = await connection.getLatestBlockhash();
  tx.message.recentBlockhash = blockhash;
  console.log('Deserialized Solana transaction:', tx);
  // Sign and send transaction
  const signature = await provider.signAndSendTransaction(tx, {skipPreflight: false, maxRetries: 20});
  console.log('Transaction sent successfully', 'success');
  const signatureStr = typeof signature === 'object' ? signature.signature?.toString() : signature.toString();
  console.log('Transaction signature:', 'info', signatureStr);
  // sleep 3 seconds
  await sleep(3000);
  return signatureStr;
}

2.2.4 Cardano Cross-chain API

This section details the API for transferring tokens from a user's Cardano account to another blockchain. The Cardano account can be either a payment address or a base address (also referred to as an enterprise address, which combines payment and stake addresses).

  • Testnet Endpoint: https://bridge-api.wanchain.org/api/testnet/createTx2

  • HTTP Request Method: POST

  • HTTP Request Content Type: Content-Type: application/json

Request Body

Example:

{
  "fromChain": "ADA",
  "toChain": "ETH",
  "fromAccount": "addr_test1vq......",
  "toAccount": "0x1bBdd8f.....",
  "amount": "1.118",
  "fromToken": "0x0000000000000000000000000000000000000000",
  "toToken": "0xfdee9454b39419a17b151e2922778df3712d0026",
  "partner": "newDex"
}

Parameters:

  • fromChain: The source chain, fixed as ADA.

  • toChain: The destination chain name. Refer to Section 2.2.1 or retrieve it from token-pair information.

  • fromAccount: The user's Cardano wallet address, which can be either a payment address or a base address.

  • toAccount: The recipient's address on the destination chain. Ensure the address is correct to avoid asset loss.

  • amount: The transfer amount, which supports decimal values (e.g., "1.12345").

  • fromToken: The coin or token address on the ADA chain. Use 0x0000000000000000000000000000000000000000 for ADA coins or the encoded unit value for tokens. Retrieve this from token-pair information.

  • toToken: The token address on the destination chain. Ensure it matches the token-pair information.

  • partner: Optional field for partner identification.

Response Example:

{
  "success": true,
  "data": {
    "tx": "84a50081825...7479706501",
    "receiveAmount": "1.118",
    "chainId": "0x385",
    "feeAndQuota": {
      "symbol": "ADA",
      "minQuota": "400000",
      "maxQuota": "7174693343715",
      "networkFee": {
        "value": "100000",
        "isPercent": false
      },
      "operationFee": {
        "value": "0.002",
        "isPercent": true,
        "minFeeLimit": "200000",
        "maxFeeLimit": "100000000"
      }
    }
  }
}

The data.tx field is the full transaction hex string.

Usage:

import * as CardanoWasm from "@emurgo/cardano-serialization-lib-asmjs-gc";

// Example for reference to process the txHex return from endpoint

async function signAndSendTransaction(txHex) {
    if (window.cardano && window.cardano.lace) {

        const handler = async function (walletApi) {
            try {
                const tx = CardanoWasm.Transaction.from_hex(txHex);
                
                // 1) sign transaction
                const witnessSetHex = await walletApi.signTx(txHex);
                const witnessSet = CardanoWasm.TransactionWitnessSet.from_hex(witnessSetHex);
                const redeemers = tx.witness_set().redeemers();
                if (redeemers) {
                    witnessSet.set_redeemers(redeemers);
                }

                const signedTx = CardanoWasm.Transaction.new(tx.body(), witnessSet, tx.auxiliary_data());

                // 2) send
                let txHash = await walletApi.submitTx(signedTx.to_hex());
                console.debug("sendTransaction() got txHash: %O", txHash);
                return txHash;
            } catch (error) {
                console.error("Failed to sign transaction:", error);
                throw error; // Re-throw error for handling in the caller
            }
        }

        const walletApi = await window.cardano.lace.enable().catch((err) => {
            console.error("Cardano wallet is not enabled");
            throw new Error("Cardano wallet not enabled");
        });

        return handler(walletApi);
    } else {
        console.error("Cardano wallet is not found");
        throw new Error("Cardano wallet not found");
    }
}

You need to install "@emurgo/cardano-serialization-lib-asmjs-gc": "^12.0.1" to process the transaction hex string returned by this API. Other versions may fail when submitting transactions, so please verify compatibility on your own.

2.2.6 Vechain Cross-chain

Testnet API path: https://bridge-api.wanchain.org/api/testnet/createTx2

HTTP POST request body:

{
  "fromChain": "VET",
  "toChain": "WAN",
  "fromAccount": "0xF6eB3CB4b187d3201AfBF96A38e62367325b29F9",
  "fromToken": "0x0000000000000000000000000000456e65726779",
  "toToken": "0x91cb1718bb65aef73e16deb6b068aea5dd4fcad1",
  "toAccount": "0xF6eB3CB4b187d3201AfBF96A38e62367325b29F9",
  "amount": "1"
}

API Response:

{
  "success": true,
  "data": {
    "approveCheck": {
      "from": "0xF6eB3CB4b187d3201AfBF96A38e62367325b29F9",
      "token": "0x0000000000000000000000000000456e65726779",
      "to": "0x8dc369fa992f2f3c38474e84b0a93cc9957b1b73",
      "amount": "1000000000000000000"
    },
    "tx": {
      "from": "0xF6eB3CB4b187d3201AfBF96A38e62367325b29F9",
      "to": "0x8dc369fa992f2f3c38474e84b0a93cc9957b1b73",
      "value": "0x0",
      "data": "0x257011b6000000000000000000000000000000000000000000000000006465765f32323800000000000000000000000000000000000000000000000000000000000003a60000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000014f6eb3cb4b187d3201afbf96a38e62367325b29f9000000000000000000000000"
    },
    "receiveAmount": "1.0",
    "chainId": "0x186aa",
    "txDataDetail": {
      "func": "userLock(bytes32,uint256,uint256,bytes)",
      "params": [
        "0x000000000000000000000000000000000000000000000000006465765f323238",
        "934",
        "1000000000000000000",
        "0xF6eB3CB4b187d3201AfBF96A38e62367325b29F9"
      ]
    },
    "feeAndQuota": {
      "symbol": "VTHO",
      "minQuota": "0",
      "maxQuota": "1160075277287119653415045092614",
      "networkFee": {
        "value": "0",
        "isPercent": false
      },
      "operationFee": {
        "value": "0",
        "isPercent": false,
        "discountPercent": "1"
      }
    }
  }
}

Front end code example:

import { DAppKit } from '@vechain/dapp-kit';
import { ABIContract, Address, Clause } from '@vechain/sdk-core';

async function getVechainProvider(isTestnet: boolean) {
  console.log('Getting Vechain provider...', isTestnet);
  const DefaultProvider = {
    mainnet: "<https://mainnet.vechain.org>",
    testnet: "<https://testnet.vechain.org>"
  }

  const kit: DAppKit = new DAppKit({ // { thor, vendor, wallet }
    nodeUrl: DefaultProvider[isTestnet ? 'testnet' : 'mainnet'],
    genesis: (isTestnet) ? 'test' : 'main'
  });

  kit.wallet.setSource('veworld');
  let {account} = await kit.wallet.connect();
  if (!account) {
    throw new Error('Failed to connect to wallet');
  }
  console.log('account', account);
  return kit;
}

async function sendVeTransaction(kit: DAppKit, clauses: Connex.VM.Clause[], sender: string) {
  console.log('Sending transaction...', clauses, sender);
  let tx = await kit.vendor.sign('tx', clauses).signer(sender);
  let { txid } = await tx.request();
  return txid;
}

function generatorErc20ApproveData(erc20Addr: string, spenderAddr: string, value: string) {
  let clauses = [Clause.callFunction(
    Address.of(erc20Addr),
    ABIContract.ofAbi(ERC20_ABI as any).getFunction('approve'),
    [spenderAddr, value]
  )];
  return clauses;
}

if (formData.fromChain === 'VET') {
  const kit = await getVechainProvider(isTestnet);
  if (result.data.approveCheck) {
    const rpcUrl = isTestnet ? '<https://rpc.testnet.dev.node.vechain.org>' : '<https://rpc.mainnet.dev.node.vechain.org>';
    let provider = new ethers.JsonRpcProvider(rpcUrl);
    const clauses = generatorErc20ApproveData(result.data.approveCheck.token, result.data.approveCheck.to, result.data.approveCheck.amount);
    let txHash = await sendVeTransaction(kit, clauses, formData.fromAccount);
    await provider.waitForTransaction(txHash);
  }

  let tx = await sendVeTransaction(kit, [
    {
      to: result.data.tx.to,
      data: result.data.tx.data,
      value: result.data.tx.value || '0x0',
    }
  ], formData.fromAccount);
}

Demo UI:

Demo UI Source Code:

Request Endpoint:

Request Endpoint:

API Endpoint:

API Demo UI code:

API Demo UI:

https://bridge-api.wanchain.org/api/createTx
https://bridge-api.wanchain.org/api/createTx2
https://bridge-api-demo-ui.vercel.app/
https://github.com/wandevs/bridge-api-demo-ui.git
https://bridge-api.wanchain.org/api/createBtcOta
https://bridge-api.wanchain.org/api/submitBtcOrder
https://bridge-api.wanchain.org/api/createTx2
https://github.com/wandevs/bridge-api-demo-ui
https://bridge-api-demo-ui.vercel.app/