POST api/v3/nft/transfer
Field | Description | Example | Type | Required |
---|---|---|---|---|
X-API-KEY | ApiKey | "HlkcGxbqBeaF76j4rvPaOasyfPwnkQ6B6DQ6THZWbvrAGxzEdulXQvOKLrRWZLnN" | Y | |
X-API-SIG | ECDSA Signature, pay attention the signature type, sign the ecdsa hash | "0xccf0a141fce2dc5cbbd4f802c52220e9e2ce260e86704d6258603eb346eefe2d 4a450005c362b223b28402d087f7065ea5eee0314531adf6a580fce64c25dca81c02" | Y |
Query Param | Description | Example | |||
---|---|---|---|---|---|
exchange | exchangeAddress in exchange info | ||||
fromAddress | sender address | ||||
fromAccountId | sender accountId | 10110 | |||
toAddress | to address | ||||
toAccountId | payee accountId | 10111,can set to 0 if dont have | |||
token | NftTokenAmountInfo,transfer tokenId and amount | ||||
maxFee | TokenAmountInfo of offchain fee, | ||||
storageId | offchainId of storage Id | 1 | |||
validUntil | Timestamp for transfer to become invalid, seconds | normally current time + 2 months | |||
eddsaSignature | eddsa signature of the transfer eddsa hash | ||||
memo | (Optional) memo | ||||
payPayeeUpdateAccount | (Optional) transfer to pay payee updateAccount fee | true | |||
counterFactualInfo | (Optional) counterFactual Wallet Info | if it's counterFactual wallet, need pass the info |
Field | Description | Example | Type | Required |
---|---|---|---|---|
hash | The hash identifier set by the user at the time of submission, can use this hash to get the transfer info | "0x1d923ca783 4dc90484fa2e b611f0f0bc7e 741bb107007e bea19ba8caea b4f9d3" | string | Y |
status | Whether the order was successfully submitted or not, please note, user may query after a while to get real process status, as most offchain requests are async processed Allowable : ['received', 'processing', 'processed', 'failed'] | "received" | string | Y |
isIdempotent | Idempotent of submit transfer response, submit same transfer again idempotent will be true | "false" | boolean | Y |
Wrapper object used to describe a token associated with a certain quantity.
Field | Description | Example | Type | Required |
---|---|---|---|---|
tokenId | The Loopring's NFT token identifier. | 32769 | integer | Y |
amount | The amount of the NFT token | "2" | string | Y |
nftData | The Loopring's NFT token data identifier which is a hash string of NFT token address and NFT_ID | "0xf7c932351186c3a9053f313eefa16209c018f7f1dba8aa 8ca7100400f7c31085" |
Field | Description | Example | Type | Required |
---|---|---|---|---|
tokenId | The Loopring's ERC20 token identifier. | 0 | integer | Y |
amount | The amount of the ERC20 token | "100000000000000000" | string | Y |
counterFactual Wallet Info
Field | Description | Example | Type | Required |
---|---|---|---|---|
walletFactory | Counter factual wallet factory contract address | "0xbbbbca6a90 1c926f240b89 eacb641d8aec 7aeafd" | string | Y |
walletOwner | Counter factual wallet owner address, NOT the wallet address | "0xbbbbca6a90 1c926f240b89 eacb641d8aec 7aeafd" | string | Y |
walletSalt | Salt to generate address from owner & other related info | "1" | string | Y |
ECDSA hash is typedata hash
const message = {
from: data.fromAddress,
to: data.toAddress,
tokenID: data.token.tokenId,
amount: data.token.amount,
feeTokenID: data.maxFee.tokenId,
maxFee: data.maxFee.amount,
validUntil: data.validUntil,
storageID: data.storageId,
};
const typedData: EIP712TypedData = {
types: {
EIP712Domain: [
{ name: "name", type: "string" },
{ name: "version", type: "string" },
{ name: "chainId", type: "uint256" },
{ name: "verifyingContract", type: "address" },
],
Transfer: [
{ name: "from", type: "address" },
{ name: "to", type: "address" },
{ name: "tokenID", type: "uint16" },
{ name: "amount", type: "uint96" },
{ name: "feeTokenID", type: "uint16" },
{ name: "maxFee", type: "uint96" },
{ name: "validUntil", type: "uint32" },
{ name: "storageID", type: "uint32" },
],
},
primaryType: "Transfer",
domain: {
name: "Loopring Protocol",
version: "3.6.0",
chainId: chainId,
verifyingContract: data.exchange,
},
message: message,
};
const inputs = [
new BN(ethUtil.toBuffer(request.exchange)).toString(),
request.fromAccountId,
request.toAccountId,
request.token.tokenId,
request.token.amount,
request.maxFee.tokenId,
request.maxFee.amount,
new BN(ethUtil.toBuffer(request.toAddress)).toString(),
0,
0,
request.validUntil,
request.storageId,
];
const hasher = Poseidon.createHash(inputs.length + 1, 6, 53);
const hash = hasher(inputs).toString(10);