Astar - polkadotxcm (transfer_assets) fails
Previously, I was able to transfer an asset successfully. Below is one of the transactions that went through:
✅ Successful Astar XCM Message: https://astar.subscan.io/xcm_message/polkadot-7e4831457e531eb534d28b15b5f6318065ef56b5
However, when attempting to create the same transaction now, I encounter an error.
❌ Failing Attempt:
Extrinsic: https://assethub-polkadot.subscan.io/extrinsic/9222368-2
XCM Message: https://assethub-polkadot.subscan.io/xcm_message/polkadot-49b259ffb25566ddb6cef15c68037d54955c4bd0
@jpinhog Can you confirm which version was asset-transfer-api was being used?
Hi @andrew-ifrita, I'm using the latest version 1.0.0
@jpinhog Can you share how createTransferTransaction(...) is being used to generate the XCMs here? That will help me recreate the issue and resolve the problem.
Hi @andrew-ifrita, below is how we create the transfer transaction.
//Create Transfer Transaction
const safeXcmVersion = 3;
const tx = await this.assetTransferApi.createTransferTransaction(
destChainId,
recipient,
[tokenCode],
[amount],
{
sendersAddr: 'senderAddress',
format: 'payload',
dryRunCall: true,
xcmVersion: this.safeXcmVersion,
xcmFeeAsset: 'dot',
},
);
//Generate Signature
const signature = this.assetTransferApi.api.registry.createType(
'ExtrinsicPayload',
tx,
{ version: this.safeXcmVersion },
);
const extrinsic = this.assetTransferApi.api.tx({
method: tx.method,
signature,
...tx.toJSON(),
});
const transactionHash = await this.assetTransferApi.api
.tx(extrinsic)
.signAndSend(this.sender);
@jpinhog The main difference in the examples provided seems to be sending USDT (working example) vs DOT (failing example). This seems sensible since Astar doesn't support DOT.
Was this the intent or was the asset wrongly changed inside of asset-transfer-api? If so, can you provide the value of tokenCode and the other parameters from the above example?
Hi @andrew-ifrita, below is the full payload for createTransferTransaction. We’re using DOT as the xcmFeeAsset. Should the xcmFeeAsset always match the tokenCode used in the transfer? For example, if the tokenCode is 1984 (USDT), should the xcmFeeAsset be 'usdt' as well?
const tx = await this.assetTransferApi.createTransferTransaction(
'2006',
'16FNntR3F4ZjsTdYHysWSiP2vGHoVL7uZ9tyfyd4o5Cdaghf',
[1984],
[amount],
{
sendersAddr: 'senderAddress',
format: 'payload',
dryRunCall: true,
xcmVersion: this.safeXcmVersion,
xcmFeeAsset: 'dot',
},
);
Hi @andrew-ifrita, below is the full payload for createTransferTransaction. We’re using DOT as the xcmFeeAsset. Should the xcmFeeAsset always match the tokenCode used in the transfer? For example, if the tokenCode is 1984 (USDT), should the xcmFeeAsset be 'usdt' as well?
xcmFeeAsset is an optional parameter used to explicitly set an asset to be used to pay fees. By default the native asset will be used if it is left empty. This asset needs to be a valid asset of the destination chain, so in this case you would likely want to be using USDT for the fees.
I can try to put together a chopsticks test that you can use to recreate the scenario and test things out.
Hi @andrew-ifrita, the xcmFeeAsset is required when the dryRunCall option is set to true, which is why it's included.
If it's removed, we get the following error: InvalidInput: xcmFeeAsset option must be provided when the dryRunCall option is set to true.
Also, if both dryRunCall and xcmFeeAsset are removed, we still encounter the same error. Here's the code snippet for reference:
const tx = await this.assetTransferApi.createTransferTransaction(
'2006',
'16FNntR3F4ZjsTdYHysWSiP2vGHoVL7uZ9tyfyd4o5Cdaghf',
[1984],
[amount],
{
sendersAddr: 'senderAddress',
format: 'payload',
xcmVersion: this.safeXcmVersion,
},
);
I started putting together a test case in this PR, https://github.com/paritytech/asset-transfer-api/pull/626.
For sanity sake I also tried doing the following on Kusama Asset Hub -> Shiden
const ata = new AssetTransferApi(api, specName, 5);
const from = "J97drEQy6sYPXf2D1uj1hJfeHsxjvwr4tVGKs9o8VDSht8r";
const to = "aSCLonoQ8zS3Ys59HwfDxbaN4xXhGMJwrnbhVUiByGZxUo9";
const amount = "100000";
const tx = await ata.createTransferTransaction(
"2007", // Shiden
to,
["1984"],
[amount.toString()],
{
sendersAddr: from,
format: "submittable",
xcmFeeAsset: "USDT",
},
);
Which worked and was able to broadcast successfully.
- https://shiden.subscan.io/xcm_message/kusama-6df8b86ded6fab546d51a9ee16469dac3b3f9d14
- https://shiden.subscan.io/xcm_message/kusama-9711e5f667d9cae9e3e2aaac990b30c7dede8bfb
- https://shiden.subscan.io/xcm_message/kusama-ac235488415536802e89c9f511da61d80d38a345
I will clean up the e2e Polkadot Asset Hub -> Astar test and see if I can exactly recreate the issue you are having. If not, you can still take advantage of these tests yourself. This could potentially be a dryRun related bug as I haven't had a chance to test that yet, but it was only take a moment to try out once I clean up that MR
Hi @andrew-ifrita, I found that using getDestinationXcmWeightToFeeAsset amounting 0.1 USDT or USDC returns a wrong xcmFee value
Successful transfer with 0.000188 USDt xcmFee(https://astar.subscan.io/xcm_message/polkadot-953ae891b060997ebcddc615e3fd221df4b3e7fe)
Here is the code snippet Im using
const dryRunResult = await assetsApi.dryRunCall(sendersAddress, extrinsic, 'submittable',
3, // xcmVersion
);
const destinationFeesInfo = await AssetTransferApi.getDestinationXcmWeightToFeeAsset(
'astar',
'wss://rpc.astar.network',
3, // xcmVersion
dryRunResult,
'usdt',
);
Response:
{
destinationFeesInfo: [
Type {
registry: [TypeRegistry],
createdAtHash: undefined,
initialU8aLength: 112,
isStorageFallback: undefined
},
{
xcmDest: '{"v3":{"parents":1,"interior":{"x1":{"parachain":2006}}}}',
xcmFee: '25555814861728783',
xcmFeeAsset: '{"V3":{"Concrete":{}}}',
xcmWeight: '{"refTime":895816000,"proofSize":9377}'
}
]
}
Yes, I am able to recreate this as well. I will take a deeper look. At first glance it looks like the xcmFeeAsset is being mishandled as the response doesn't seem to match up with USDT and thus the units and values would be off.
Marking as won't fix as we are dropping support for asset-transfer-api in favor of ParaSpell. See more in this issue: https://github.com/paritytech/asset-transfer-api/issues/652