Cross-Consensus Query Language (XCQ)

We just opened a PR about XCQ RFC. Feedback is welcome!

PVQ Status Report

Summary

  • Rename project from XCQ to PVQ
  • Refactor PVQ extension system
  • Refactor PVQ program macros
  • XCM Intergration PoC

Example Usage

  • PVQ Extensions Definitions: Example
  • Use pvq-program macros to write a guest program. Example
  • PVQ Extensions Implementation: Example

Run Examples

Available PoC PVQ examples:

  • guest-sum-balance: sum the balances of multiple accounts
  • guest-total-supply: get the total supply of an asset
  • guest-sum-balance-percent: sum the balances of multiple accounts and calculate the percentage of the total supply
  1. Build guest program: make guests
  2. Run test runner: cargo run -p pvq-test-runner -- --program output/<guest-program>
    guest-examples contains several guest programs to test the PVQ.

XCM Integration PoC

The test case of XCM integration is located in vendor/polkadot-sdk/polkadot/xcm/xcm-simulator/example/src/tests.rs

#[test]
fn test_report_query() {
    ...
}
1 Like

We are happy to share the recent progress of PVQ:

PVQ Frontend SDK

We have created a TypeScript SDK for interacting with PolkaVM Query(PVQ) enabled chains.
In summary, the SDK supports the following use cases:

  • Create a PVQ program instance by providing the guest program and corresponding metadata files.
  • List queryable entrypoints by accessing the metadata.
  • Check if the guest program is compatible with the chain’s supported extensions.

For more details, please refer to the github repo.

PVQ Frontend Demo

And we also created a demo to demonstrate the usage of PVQ-SDK.

In this demo, you can interact with a PoC runtime that implements the core and fungibles extensions.

  1. Clone the PVQ repository.
  2. Install bun.
  3. Run make tools to install the required tools.
  4. Run make run to start the local PoC runtime.
  5. Run make guests to build the PVQ programs and generate their metadata.
  6. Open the demo in your browser.
  7. Enter the custom endpoint shown in Step 4 and connect to the chain.
  8. Upload a PVQ program, such as guest-sum-balance, along with the corresponding metadata JSON file, guest-sum-balance-metadata.json.
  9. Select the program; the program bytecode and metadata should be displayed in the UI.
  10. Switch to the Query tab, input the query argument, and execute the query to get the result. In the following example, we query the sum of the balances of asset 21 for two accounts: Alice and Bob.

Ongoing Works

We are targeting to the first release of the PVQ as well as demonstrating a more decent Demo to show how PVQ works with different chains.

1 Like

We’ve built a simple swap demo showcases how PVQ can facilitate the development of multi-chain Dapps. It has the following core functions:

  • List Liquidity Pools: Displays the available token pair pools on the selected chain.

  • Get Pool Reserves: Shows the current liquidity reserves for a selected pool.

  • Get Swap Price: Show price quote for swapping a specific amount of one token for another.

The main takeaway is that the demo works seamlessly with both Acala and AssetHub, using the exact same front-end logic despite the DEX implementations on these chains being entirely different:

  • Acala: Uses its own custom module-dex pallet.

  • AssetHub: Uses the AssetConversion pallet.

How It Works

Front-end side

From the client’s perspective, the process is simple:

  • Check for Extension: The UI first checks if the connected chain (Acala or AssetHub) implements the swap extension.

  • Construct PVQ program query arguments: If the extension is available, the UI constructs its query with the required arguments (e.g., token pair, amount to swap).

  • Call PVQ program Entrypoints: The UI sends the query to the entrypoints of the PVQ program.

The front-end code is completely agnostic of whether it’s talking to Acala’s DEX pallet or AssetHub’s AssetConversion pallet.

Runtime side

The heavy lifting is done at the runtime side, which is tailored for each chain. We implement swap extension on both Acala and AssetHub, which exposes five extension functions: quote_price_tokens_for_exact_tokens, quote_price_exact_tokens_for_tokens, get_liquidity_pool, list_pools, asset_info, assets_info.

PVQ Program

For the corresponding PVQ program, it only has four entrypoints. This is by design and demonstrates one of PVQ’s most powerful features: the ability to perform custom computations in PVQ program.

For example, the list_pools entrypoint is actually a composition of extension functions list_pools and assets_info:

#[program::entrypoint]
fn entrypoint_list_pools() -> Vec<(AssetInfo, AssetInfo)> {
    let pools = list_pools();
    let mut result = Vec::new();
    let assets_info = assets_info();
    for pool in pools {
        let asset1_info = assets_info.get(&pool.0).cloned();
        let asset2_info = assets_info.get(&pool.1).cloned();
        if let (Some(a1), Some(a2)) = (asset1_info, asset2_info) {
            result.push((a1, a2));
        }
    }
    result
}

Key Advancement

This demo is a concrete validation of the PVQ vision. We have successfully created a unified, high-level interface for a non-trivial operation (DEX interactions) across two parachains with fundamentally different runtime implementations.

For dApp developers:

  • Reduced Complexity: No need to learn the low-level details of every parachain’s pallets.

  • Faster Development: Write code once and deploy it across multiple chains.

  • Easy Extensibility: As more chains adopt the PVQ swap extension, they will instantly work with existing UIs without requiring any front-end updates.

This advancement is a crucial step toward a more cohesive and developer-friendly Polkadot ecosystem.

Next Steps

We are targeting the first release of the PVQ and integrating it into the polkadot-sdk.

We welcome feedback, questions, and collaboration from the community. Please feel free to check out the demo and share your thoughts below.

Thank you!

2 Likes