Remote Proxies For The Braves
In Ecosystem Proxy, I introduced the idea of having remote proxies - proxies that are declared at one chain and used on different chain via a storage proof. An initial version of this idea was implemented in this pull request and released alongside runtime release 1.4.2
on Kusama AssetHub (KAH). KAH is configured right now to accept proxies declared at the relay chain (Kusama). In the following, I want to explain how to use these remote proxies with a hacky polkadot-js
script until someone writes a nice UI around it :)
Basics
Right now you can only use proxies declared on Kusama on KAH. The pallet on KAH is configured to accept a proof that is at most 1 minute old. Only proxies declared as Any
, CancelProxy
, or NonTransfer
on Kusama are currently mapped to KAH. Any other proxy type is rejected because there doesn't exist a corresponding proxy type on KAH at the moment.
Sending a remote proxy transaction via Polkadot-JS
I have written the following polkadot-js
script for sending a remote proxy transaction:
import { ApiPromise, WsProvider } from '@polkadot/api';
const YOUR_ACCOUNT = '5EjdajLJp5CKhGVaWV21wiyGxUw42rhCqGN32LuVH4wrqXTN';
const PROXIED_ACCOUNT = 'D9o7gYB92kXgr1UTjYWLDwXK5BeJdxR2irjwaoDEhJnNCfp';
// Connect to Kusama and AssetHub Kusama
const kusama_wsProvider = new WsProvider('wss://kusama.public.curie.radiumblock.co/ws');
const kusama_api = await ApiPromise.create({ provider: kusama_wsProvider });
const ah_wsProvider = new WsProvider('wss://kusama-asset-hub-rpc.polkadot.io');
const ah_api = await ApiPromise.create({ provider: ah_wsProvider });
const proxyDefinitionKey = kusama_api.query.proxy.proxies.key(PROXIED_ACCOUNT);
console.log("ProxyDefinition key: " + proxyDefinitionKey);
const blockToRoot = JSON.parse(await ah_api.query.remoteProxyRelayChain.blockToRoot());
// Get the latest block for which AH knows the storage root.
const proofBlock = blockToRoot[blockToRoot.length - 1][0];
const proofBlockHash = await kusama_api.rpc.chain.getBlockHash(proofBlock);
console.log("Fetching proof for block " + proofBlock)
// Build the proof on Kusama
const proof = JSON.parse(await kusama_api.rpc.state.getReadProof([proxyDefinitionKey], proofBlockHash));
// The call that will be executed by the proxied account
const your_wrapped_call = ah_api.tx.balances.transferAll(YOUR_ACCOUNT, false);
// Construct the proxy call
const proxy_call = ah_api.tx.remoteProxyRelayChain.remoteProxy(
PROXIED_ACCOUNT,
null,
your_wrapped_call.method,
{ RelayChain: { proof: proof.proof, block: proofBlock }},
);
console.log("The call: " + proxy_call.method);
console.log("Send via PJS: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkusama-asset-hub-rpc.polkadot.io#/extrinsics/decode/" + proxy_call.method.toHex());
To execute the script you need to run the following commands:
yarn add @polkadot/api
node NAME_OF_THE_SCRIPT
First, we need to install the polkadot-js
API package and then run the script. The script outputs a URL that directs you to polkadot-js
to send the transaction to the chain:
Switching to the Submission
tab will let you send the transaction. You have below one minute between the generation of the transaction and the execution of the transaction on chain. Otherwise the transaction will be rejected because of an unknown anchor block (the block that was used to generate the proof).
The script above has my accounts hard-coded. I propose that you change these before you try to execute it :) The interesting things you need to change are YOUR_ACCOUNT
, PROXIED_ACCOUNT
, and your_wrapped_call
. YOUR_ACCOUNT
is only used as the target account for the proxied transfer-all call, while PROXIED_ACCOUNT
is the account that will be proxied.
PAPI
Currently, PAPI is missing a way to construct a proof
using the new JJSON-RPC API. After that, it should be straightforward to implement remote proxy support in PAPI.
Remote Proxies + Multisigs
I don't have an example for this, but the setup is not that much different to the normal remote proxy call. However, there are two special functions register_remote_proxy_proof
and remote_proxy_with_registered_proof
for the multisig use case. As the time between generating the proof and execution of the transaction on chain can only be 1 minute in maximum, this would not work for multisigs which need to coordinate via multiple people. When constructing a multsig call that should use a remote proxy, you can use the remote_proxy_with_registered_proof
inside call that should be executed by the multisig. The final approver of the multisig then needs to use register_remote_prox_proof
in a batch with the last approval and execution of the multisiged call. This way the proof can be generated right before sending the transaction to the chain, ensuring that the proof is still valid. The call remote_proxy_with_registered_proof
will then use the registered proof to verify that the remote proxy exists. The registering of a proof only works for the context of one transaction and doesn't work across transactions.