@xlc created a guide to dry run OpenGov referenda in Chopsticks. It is simple, but it assumes a bit higher technical level of competency than many OpenGov participants that need it have.
With the transition of Governance to AssetHub, the old guidance is no longer up-to-date. On AH, we still have to get relay chain blocks for the scheduler. So we need to extend the sample a bit.
A minimal example that should work on AH currently looks like this:
As a side note: this currently does not work with the Chopsticks version that PJS comes with, since its not the latest and it seems PJS is currently not maintained. It works if you run Chopsticks yourself and point PJS towards it.
To run with Chopsticks/PAPI, you can run this code:
import { ApiPromise, WsProvider } from '@polkadot/api';
const WS_ENDPOINT = 'ws://localhost:8000';
async function main() {
const provider = new WsProvider(WS_ENDPOINT);
const api = await ApiPromise.create({ provider });
// Get current relay block number (scheduler uses relay blocks, not parachain!)
const validationData = await api.query.parachainSystem.validationData();
const relayBlock = validationData.unwrap().relayParentNumber.toNumber();
console.log('Relay block:', relayBlock);
// Example call
const encodedCall = '0x00003048656c6c6f20576f726c6421'; // system.remark("Hello World!")
console.log('Call:', encodedCall);
// Set scheduler agenda with Root origin
await provider.send('dev_setStorage', [{
scheduler: {
agenda: [[[relayBlock], [{
call: { Inline: encodedCall },
origin: { system: 'Root' }
}]]]
}
}]);
// Build block to execute
await provider.send('dev_newBlock', []);
// Check result from Dispatched event
const events = await api.query.system.events();
const dispatched = events.find(e =>
e.event.section === 'scheduler' && e.event.method === 'Dispatched'
);
if (dispatched) {
const result = dispatched.event.data[2].toHuman(); // 3rd field is result
console.log('\nResult:', result);
} else {
console.log('\nNo Dispatched event - call may have failed');
}
await api.disconnect();
}
main().catch(console.error);