-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add XCM Dry Run and Location to Account Runtime Calls #1010
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { ApiPromise, WsProvider } from '@polkadot/api'; | ||
|
||
const main = async () => { | ||
// Construct API provider | ||
const wsProvider = new WsProvider('INSERT_WSS_ENDPOINT'); | ||
const api = await ApiPromise.create({ provider: wsProvider }); | ||
|
||
// Define the multilocation parameter | ||
const multilocation = { | ||
V4: { | ||
parents: 1, | ||
interior: 'Here', | ||
}, | ||
}; | ||
|
||
// Query the locationToAccountApi using convertLocation method | ||
const result = | ||
await api.call.locationToAccountApi.convertLocation(multilocation); | ||
console.log('Conversion result:', result.toHuman()); | ||
|
||
// Disconnect the API | ||
await api.disconnect(); | ||
}; | ||
|
||
main().catch(console.error); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
Ok: { | ||
executionResult: { | ||
Ok: { | ||
actualWeight: { | ||
refTime: 7,301,734,000 | ||
proofSize: 20,928 | ||
} | ||
paysFee: Yes | ||
} | ||
} | ||
emittedEvents: [ | ||
{ | ||
method: Burned | ||
section: balances | ||
index: 0x030b | ||
data: { | ||
who: 0x88bcE0b038eFFa09e58fE6d24fDe4b5Af21aa798 | ||
amount: 100,000,000,000,000,000 | ||
} | ||
} | ||
{ | ||
method: Minted | ||
section: balances | ||
index: 0x030a | ||
data: { | ||
who: 0x3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0 | ||
amount: 100,000,000,000,000,000 | ||
} | ||
} | ||
{ | ||
method: Attempted | ||
section: polkadotXcm | ||
index: 0x1c00 | ||
data: { | ||
outcome: { | ||
Complete: { | ||
used: { | ||
refTime: 7,250,000,000 | ||
proofSize: 19,374 | ||
} | ||
} | ||
} | ||
} | ||
} | ||
] // Additional events returned here | ||
// Omitted for clarity |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { ApiPromise, WsProvider } from '@polkadot/api'; | ||
import { hexToU8a } from '@polkadot/util'; | ||
|
||
const main = async () => { | ||
try { | ||
// Construct API provider | ||
const wsProvider = new WsProvider('INSERT_WSS_ENDPOINT'); | ||
const api = await ApiPromise.create({ provider: wsProvider }); | ||
|
||
console.log('Connected to the API. Preparing dry run call...'); | ||
|
||
// Create a test account (you should replace this with an actual account) | ||
const testAccount = api.createType( | ||
'AccountId20', | ||
'0x88bcE0b038eFFa09e58fE6d24fDe4b5Af21aa798' | ||
); | ||
|
||
// The call data (replace with your actual call data) | ||
const callData = | ||
'0x1c030408000400010403001300008a5d784563010d010204000103003cd0a705a2dc65e5b1e1205896baa2be8a07c6e007803822b001ba2e0100'; // Your hex-encoded call data | ||
|
||
// Convert hex to Uint8Array | ||
const callDataU8a = hexToU8a(callData); | ||
|
||
// Perform the dry run call | ||
const result = await api.call.dryRunApi.dryRunCall( | ||
{ system: { Signed: testAccount } }, // origin | ||
callDataU8a // call | ||
); | ||
|
||
console.log('Dry run result:', result.toHuman()); | ||
|
||
// Disconnect the API | ||
await api.disconnect(); | ||
console.log('Disconnected from the API.'); | ||
} catch (error) { | ||
console.error('An error occurred:', error); | ||
} | ||
}; | ||
|
||
main().catch(console.error); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
Ok: { | ||
executionResult: { | ||
Complete: { | ||
used: { | ||
refTime: 76,473,048,000 | ||
proofSize: 222,483 | ||
} | ||
} | ||
} | ||
emittedEvents: [ | ||
{ | ||
method: Burned | ||
section: assets | ||
index: 0x1d03 | ||
data: { | ||
assetId: 42,259,045,809,535,163,221,576,417,993,425,387,648 | ||
owner: 0x506172656E740000000000000000000000000000 | ||
balance: 1,000,000,000,000 | ||
} | ||
} | ||
{ | ||
method: NewAccount | ||
section: system | ||
index: 0x0003 | ||
data: { | ||
account: 0x1Ccc29B6C837be6A0C03d544b5Aa8580f9fb9489 | ||
} | ||
} | ||
{ | ||
method: Issued | ||
section: assets | ||
index: 0x1d01 | ||
data: { | ||
assetId: 42,259,045,809,535,163,221,576,417,993,425,387,648 | ||
owner: 0x1Ccc29B6C837be6A0C03d544b5Aa8580f9fb9489 | ||
amount: 959,944,978,002 | ||
} | ||
} | ||
{ | ||
method: Issued | ||
section: assets | ||
index: 0x1d01 | ||
data: { | ||
assetId: 42,259,045,809,535,163,221,576,417,993,425,387,648 | ||
owner: 0x6d6F646c70632f74727372790000000000000000 | ||
amount: 40,055,021,998 | ||
} | ||
} | ||
] | ||
forwardedXcms: [ | ||
[ | ||
{ | ||
V4: { | ||
parents: 1 | ||
interior: Here | ||
} | ||
} | ||
[] | ||
] // Additional events returned here | ||
// Omitted for clarity |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { ApiPromise, WsProvider } from '@polkadot/api'; | ||
|
||
const main = async () => { | ||
try { | ||
// Construct API provider | ||
const wsProvider = new WsProvider('INSERT_WSS_ENDPOINT'); | ||
const api = await ApiPromise.create({ provider: wsProvider }); | ||
console.log('Connected to the API. Preparing dry run XCM call...'); | ||
|
||
// Define the origin | ||
const origin = { V4: { parents: 1, interior: 'Here' } }; | ||
|
||
const assetMultiLocation = { | ||
parents: 0, | ||
interior: { X1: { PalletInstance: 3 } }, | ||
}; // The asset's location (adjust PalletInstance as needed) | ||
|
||
const amountToSend = 1000000000000; // Adjust this value as needed | ||
|
||
const message = { | ||
V4: [ | ||
{ | ||
WithdrawAsset: [ | ||
{ | ||
id: { parents: 1, interior: 'Here' }, | ||
fun: { Fungible: amountToSend }, | ||
}, | ||
], | ||
}, | ||
{ | ||
BuyExecution: { | ||
fees: { | ||
id: { parents: 1, interior: 'Here' }, | ||
fun: { Fungible: amountToSend }, | ||
}, | ||
weightLimit: { Unlimited: null }, | ||
}, | ||
}, | ||
{ | ||
ClearOrigin: null, | ||
}, | ||
], | ||
}; | ||
|
||
// Perform the dry run XCM call | ||
const result = await api.call.dryRunApi.dryRunXcm(origin, message); | ||
|
||
// Use JSON.stringify for better output formatting | ||
console.log( | ||
'Dry run XCM result:', | ||
JSON.stringify(result.toJSON(), null, 2) | ||
); | ||
|
||
// Disconnect the API | ||
await api.disconnect(); | ||
console.log('Disconnected from the API.'); | ||
} catch (error) { | ||
console.error('An error occurred:', error); | ||
} | ||
}; | ||
|
||
main().catch(console.error); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -180,6 +180,75 @@ Now that you have the values for each of the parameters, you can write the scrip | |
|
||
Once the transaction is processed, the 0.1 DEV tokens should be withdrawn from Alice's account along with the associated XCM fees, and the destination account should have received 0.1 DEV tokens in their account. A `polkadotXcm.Attempted` event will be emitted with the outcome. | ||
|
||
|
||
### Test an XCM Message with the XCM Dry Run API {: #test-an-xcm-message-with-the-dry-run-api } | ||
|
||
The XCM Dry Run API is an easy and convenient way to test the integrity of your XCM message without incurring any transaction fees. The XCM Dry Run API can be accessed from the [Runtime Calls](https://polkadot.js.org/apps/#/runtime){target=\_blank} tab of the **Developer** section of Polkadot.js Apps. | ||
|
||
#### Dry Run Call API Method {: #dry-run-call-api-method } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this is not XCM-specific tho right? This section works for any call outside of XCM. So maybe moving this to another section is better? Somewhere in the Substrate API for Moonbeam? Maybe even a new section on testing or something. We should discuss |
||
|
||
This method takes as a parameter the origin and the call data and returns an execution result, actual weight, and event data. | ||
|
||
```javascript | ||
const testAccount = api.createType( | ||
'AccountId20', | ||
'0x88bcE0b038eFFa09e58fE6d24fDe4b5Af21aa798' | ||
); | ||
const callData = | ||
'0x1c030408000400010403001300008a5d784563010d010204000103003cd0a705a2dc65e5b1e1205896baa2be8a07c6e007803822b001ba2e0100'; | ||
const callDataU8a = hexToU8a(callData); | ||
|
||
const result = await api.call.dryRunApi.dryRunCall( | ||
{ system: { Signed: testAccount } }, | ||
callDataU8a | ||
); | ||
``` | ||
|
||
??? code "View the complete script" | ||
|
||
```js | ||
--8<-- 'code/builders/interoperability/xcm/send-execute-xcm/dry-run/dry-run-call.js' | ||
``` | ||
|
||
Upon calling the XCM Dry Run API, the method will tell you whether the call would be successful and returns the event data that would be emitted if the XCM were to be actually submitted on chain. You can view the initial output of the `dryRunCall` below. | ||
|
||
??? code "View the complete output" | ||
|
||
```json | ||
--8<-- 'code/builders/interoperability/xcm/send-execute-xcm/dry-run/dry-run-call-return-data.json' | ||
``` | ||
|
||
#### Dry Run XCM API Method {: #dry-run-xcm-api-method } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is relevant for this section, but unsure if being under Wdyt? |
||
|
||
The `dryRunXCM` method of the XCM Dry Run API takes a full XCM message as a parameter instead of an encoded call, as well as the origin of the message. | ||
|
||
`dryRunXCM` takes as a parameter the origin and the XCM message and returns an execution result, actual weight, and event data. | ||
|
||
```javascript | ||
// Define the origin | ||
const origin = { V4: { parents: 1, interior: 'Here' } }; | ||
|
||
const message = []; // Insert XCM Message Here | ||
|
||
// Perform the dry run XCM call | ||
const result = await api.call.dryRunApi.dryRunXcm(origin, message); | ||
``` | ||
|
||
??? code "View the complete script" | ||
|
||
```js | ||
--8<-- 'code/builders/interoperability/xcm/send-execute-xcm/dry-run/dry-run-xcm.js' | ||
``` | ||
|
||
Upon calling the XCM Dry Run API, the method will tell you whether the call would be successful and returns the event data that would be emitted if the XCM were to be actually submitted on chain. You can view the initial output of the `dryRunXCM` below. | ||
|
||
??? code "View the complete output" | ||
|
||
```json | ||
--8<-- 'code/builders/interoperability/xcm/send-execute-xcm/dry-run/dry-run-xcm-return-data.json' | ||
``` | ||
|
||
|
||
### Execute an XCM Message with the XCM Utilities Precompile {: #execute-xcm-utils-precompile } | ||
|
||
In this section, you'll use the `xcmExecute` function of the [XCM Utilities Precompile](/builders/interoperability/xcm/xcm-utils/){target=\_blank}, which is only supported on Moonbase Alpha, to execute an XCM message locally. The XCM Utilities Precompile is located at the following address: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Im curious as to this XCM message that you put here. There is no Deposit Asset so this would actually result in AssetsTrapped right?