A TypeScript SDK for interacting with PolkaVM Query (PVQ)
import { ApiPromise } from '@polkadot/api';
import { PvqProgram } from '@open-web3/pvq';
// Connect to a Polkadot node
const api = await ApiPromise.create({
provider: 'ws://localhost:9944'
});
// Create PVQ program instance
const program = new PvqProgram(
api,
guestProgramBytes, // Uint8Array or hex string
programMetadata // Program metadata object
);
// Execute a query
const result = await program.entrypoint.sumBalance([
21,
['15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5']
], {
gasLimit: 1000000000000000000n
});
console.log('Query result:', result);
import { ApiPromise, WsProvider } from '@polkadot/api';
import { PvqProgram } from '@open-web3/pvq';
async function executeProgram() {
const provider = new WsProvider('ws://127.0.0.1:8000');
const api = await ApiPromise.create({ provider });
const guestProgram = '0x...'; // Your program bytecode
const metadata = {
// Your program metadata
};
const program = new PvqProgram(api, guestProgram, metadata);
try {
// Execute with default gas limit
const result = await program.entrypoint.sumBalance([21, ['15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5']]);
console.log('Success:', result.toJSON());
} catch (error) {
console.error('Execution failed:', error);
}
await api.disconnect();
}
// Execute with custom gas limit
const result = await program.entrypoint.sumBalance(
[21, ['15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5']],
{ gasLimit: 1000000000000000000n }
);
// Execute using entrypoint identifier
const result = await program.executeQuery('sum_balance', { gasLimit: 1000000n }, [21, ['15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5']]);
// Fetch metadata from the chain
const metadata = await program.getMetadata();
console.log('Chain metadata:', metadata);
// Check whether the program's extensions match the extensions on the current chain
const matched = await program.checkExtensions();
console.log('Extensions matched:', matched); // true or throws error if not matched
// You can also check the cached result
console.log('Cached result:', program.extensionsMatched); // true/false/undefined
Main class for interacting with PVQ programs.
new PvqProgram(
api: ApiBase<ApiTypes>,
guestProgram: Uint8Array | `0x${string}`,
programMetadata: Record<string, unknown>
)
executeQuery(entrypoint, options, params)
- Execute a query on the programcheckExtensions()
- Check if required extensions are availablegetMetadata()
- Get runtime metadata
entrypoint
- Object containing all available entrypoints as camelCase methodsextensionsMatched
- Boolean indicating if extensions check passed
Your program metadata should follow this structure:
{
"types": {
"types": [
{
"id": 0,
"type": {
"def": { "primitive": "u32" }
}
},
{
"id": 1,
"type": {
"def": { "array": { "len": 32, "type": 2 } }
}
},
{
"id": 2,
"type": {
"def": { "primitive": "u8" }
}
},
{
"id": 3,
"type": {
"def": { "primitive": "u64" }
}
},
{
"id": 4,
"type": {
"def": { "sequence": { "type": 1 } }
}
}
]
},
"extension_fns": [
[
"4071833530116166512",
1,
{
"name": "balance",
"inputs": [
{ "name": "asset", "ty": 0 },
{ "name": "who", "ty": 1 }
],
"output": 3
}
]
],
"entrypoints": [
{
"name": "sum_balance",
"inputs": [
{ "name": "asset", "ty": 0 },
{ "name": "accounts", "ty": 4 }
],
"output": 3
}
]
}