Submit order

Here is a detailed explanation of the parameters for the submitOrder API:

FieldsDescription

Evmaddress

The current address of the user's connected wallet.

Signature

The user's signature of the post body

Body

FieldsDescription

channel

Unique identification of third parties

extra

The "extra" field is used to define interface rules, with the format "{type}_{value}". Multiple rules are connected using ";". example: "1_10000;2_30"

Rule 1:

Example: 1_1000000

1: Expect received quantity for the user

1000000: Minimum received quantity for the user

Rule 2:

Example: 2_50 (0-0.5%)

2: Third-party user profit sharing identifier

50: Third-party profit sharing ratio, in basis points, ranging from 0 to 50

orderType

Order type: 1: cross-chain 2: transaction

slippage

Slippage, in basis points format(range: 0.01% ~ 50%). For example, 1% in basis points format is represented as 100.

sourceCerts

Transaction parameters represented in hexadecimal format.

toChain

Target chain name.

toIndex

Target token index.

toAddr

Recipient EVM address.

execStrategy

Reserved field, pass the string "".

timeout

Reserved field, pass the string "0".

triggerPrice

Reserved field, pass the string "0".

sourceCerts:

FieldDescription

fromAmount

Amount paid by the user

fromIndex

From Token index

fromChain

From Chain name

fromAddr

The current address of the user's connected wallet.

certHash

Current tx Hash

fromPublicKey

Reserved field, pass the string "" for EVM system.

signature

Reserved field, pass the string "123456"

get sourceCerts hex examples:

// sourceCerts hex
const sourceCertsObj = {
    fromAmount: '10000000', // 10 usdt
    fromIndex: '5', // usdt
    fromChain: 'FSN',
    fromAddr: '0x42a6685ef29886Cbcb595Aa903f00dea0d1787d8',
    certHash: '0x4190dc4627cb4e97292b6b718d718d3c3af93f14477346efc181ff549f69f794',
    fromPublicKey: '',
    signature: '123456'
}
const sourceCertsStr = JSON.stringify(sourceCertsObj);
let sourceCertsHex = toHex(sourceCertsStr);
let sourceCerts = sourceCertsHex.substring(2);
console.log(sourceCerts) 
// 7b2266726f6d416d6f756e74223a223130303030303030222c2266726f6d496e646578223a2235222c2266726f6d436861696e223a2246534e222c2266726f6d41646472223a22307834326136363835656632393838364362636235393541613930336630306465613064313738376438222c226365727448617368223a22307834313930646334363237636234653937323932623662373138643731386433633361663933663134343737333436656663313831666635343966363966373934222c2266726f6d5075626c69634b6579223a22222c227369676e6174757265223a22313233343536227d

Signature:

To obtain a correct interface signature, we need to follow these 5 steps:

  1. Construct the body parameter object correctly according to the requirements.

  2. Concatenate the parameters of the complete body parameter object, sorted alphabetically, using '&' as a separator. For example: channel=chainge&extra=1_6495000&orderType....

  3. Prefix the string generated in step 2 with EvmAddress=...&{result of step 2}, for example: EvmAddress=0x42a6685ef29886Cbcb595Aa903f00dea0d1787d8&channel=chainge&extra=1_6495000&orderType....

  4. Apply keccak256 hashing to the result of step 3.

  5. Sign the result of step 4 with the wallet.

get Signature examples:

const sortParams = (params, evmAddress) => {
    let keys = Object.keys(params)
    if(!keys.length) return undefined
    keys = keys.sort();
    const keyValList = []
    for (const key of keys) {
        const val = params[key];
        if(val) {
            keyValList.push(`${key}=${val}`)
        }
    }
    const data = keyValList.join('&')
    const raw = `EvmAddress=${evmAddress}&${data}`
    return raw
}

// step 1
const bodyParams = {
    channel: "chainge",
    extra: `1_6495000`,
    orderType: '1',
    slippage: '0',
    sourceCerts: sourceCerts, // 7b2266726f6d416d6f756e74223a223130303030303030222c2266726f6d496e646578223a2235222c2266726f6d436861696e223a2246534e222c2266726f6d41646472223a22307834326136363835656632393838364362636235393541613930336630306465613064313738376438222c226365727448617368223a22307834313930646334363237636234653937323932623662373138643731386433633361663933663134343737333436656663313831666635343966363966373934222c2266726f6d5075626c69634b6579223a22222c227369676e6174757265223a22313233343536227d
    toChain: 'ETH',
    toIndex: '5',
    toAddr: '0x42a6685ef29886Cbcb595Aa903f00dea0d1787d8',
    execStrategy: "",
    timeout: "0",
    triggerPrice: "0",
}

// step 2 & setp3
let raw = sortParams(bodyParams, '0x42a6685ef29886Cbcb595Aa903f00dea0d1787d8') as string;
console.log(raw) // EvmAddress=0x42a6685ef29886Cbcb595Aa903f00dea0d1787d8&channel=chainge&extra=1_6495000&orderType=1&slippage=0&sourceCerts=7b2266726f6d416d6f756e74223a223130303030303030222c2266726f6d496e646578223a2235222c2266726f6d436861696e223a2246534e222c2266726f6d41646472223a22307834326136363835656632393838364362636235393541613930336630306465613064313738376438222c226365727448617368223a22307834313930646334363237636234653937323932623662373138643731386433633361663933663134343737333436656663313831666635343966363966373934222c2266726f6d5075626c69634b6579223a22222c227369676e6174757265223a22313233343536227d&timeout=0&toAddr=0x42a6685ef29886Cbcb595Aa903f00dea0d1787d8&toChain=ETH&toIndex=5&triggerPrice=0

// step4
raw = keccak256(toHex(raw));
console.log(raw) // 0x24129902c42ed3eb40c93dddfe80bf12cc44853ecbda70427dff75c0ce6d189b

// step5 Calling wallet message signing
// Calculates an Ethereum-specific signature in EIP-191 format: keccak256("\x19Ethereum Signed Message:\n" + len(message) + message)).
// Note: The signature should not include the prefix '0x'.
let signature = wallet.signMessage(raw)

Complete example:

const sortParams = (params, evmAddress) => {
    let keys = Object.keys(params)
    if(!keys.length) return undefined
    keys = keys.sort();
    const keyValList = []
    for (const key of keys) {
        const val = params[key];
        if(val) {
            keyValList.push(`${key}=${val}`)
        }
    }
    const data = keyValList.join('&')
    const raw = `EvmAddress=${evmAddress}&${data}`
    return raw
}

const userAddress = '0x42a6685ef29886Cbcb595Aa903f00dea0d1787d8'
const receiveAddress = '0x42a6685ef29886Cbcb595Aa903f00dea0d1787d8'
// sourceCerts hex
const sourceCertsObj = {
    fromAmount: '10000000', // 10 usdt
    fromIndex: '5', // usdt
    fromChain: 'FSN',
    fromAddr: userAddress,
    certHash: '0x4190dc4627cb4e97292b6b718d718d3c3af93f14477346efc181ff549f69f794',
    fromPublicKey: '',
    signature: '123456'
}
const sourceCertsStr = JSON.stringify(sourceCertsObj);
let sourceCertsHex = toHex(sourceCertsStr);
let sourceCerts = sourceCertsHex.substring(2);
// 7b2266726f6d416d6f756e74223a223130303030303030222c2266726f6d496e646578223a2235222c2266726f6d436861696e223a2246534e222c2266726f6d41646472223a22307834326136363835656632393838364362636235393541613930336630306465613064313738376438222c226365727448617368223a22307834313930646334363237636234653937323932623662373138643731386433633361663933663134343737333436656663313831666635343966363966373934222c2266726f6d5075626c69634b6579223a22222c227369676e6174757265223a22313233343536227d

// step 1
const bodyParams = {
    channel: "chainge",
    extra: `1_6495000;2_30`, // "2_30" represents the project charging a 0.3% fee.
    orderType: '1',
    slippage: '0',
    sourceCerts: sourceCerts, 
    toChain: 'ETH',
    toIndex: '5',
    toAddr: receiveAddress,
    execStrategy: "",
    timeout: "0",
    triggerPrice: "0",
}

// step 2 & setp3
let raw = sortParams(bodyParams, userAddress) as string;
console.log(raw) // EvmAddress=0x42a6685ef29886Cbcb595Aa903f00dea0d1787d8&channel=chainge&extra=1_6495000&orderType=1&slippage=0&sourceCerts=7b2266726f6d416d6f756e74223a223130303030303030222c2266726f6d496e646578223a2235222c2266726f6d436861696e223a2246534e222c2266726f6d41646472223a22307834326136363835656632393838364362636235393541613930336630306465613064313738376438222c226365727448617368223a22307834313930646334363237636234653937323932623662373138643731386433633361663933663134343737333436656663313831666635343966363966373934222c2266726f6d5075626c69634b6579223a22222c227369676e6174757265223a22313233343536227d&timeout=0&toAddr=0x42a6685ef29886Cbcb595Aa903f00dea0d1787d8&toChain=ETH&toIndex=5&triggerPrice=0

// step4
raw = keccak256(toHex(raw));
console.log(raw) // 0x24129902c42ed3eb40c93dddfe80bf12cc44853ecbda70427dff75c0ce6d189b

// step5 Calling wallet message signing
// Calculates an Ethereum-specific signature in EIP-191 format: keccak256("\x19Ethereum Signed Message:\n" + len(message) + message)).
// Note: The signature should not include the prefix '0x'.
let signature = wallet.signMessage(raw)


// Request header
const headers = {
  EvmAddress: userAddress,
  Signature: signature,
};
// request
const result = await axios.post('https://api2.chainge.finance/v1/submitOrder', bodyParams, {
    headers: headers
})

Last updated