Skip to content

document proxy functionality wiht polkadot-js #543

Open
@MichaelTrestman

Description

@MichaelTrestman

proxy wallets offer strong protection for sensitive coldkeys, but are complex to implement because they are not included in btcli or bittensor python sdk, you have to use polkadot-js

Create proxy

import { ApiPromise, WsProvider, Keyring } from '@polkadot/api';

// Replace with your Polkadot or Kusama WebSocket endpoint
const WS_PROVIDER = 'wss://test.finney.opentensor.ai:443    '; // Use Polkadot's endpoint if needed

// Replace with your accounts
const PROXIED_ACCOUNT_MNEMONIC = 'famous caution muscle liar castle fire marble impact design run fetch cake'; // The account that is assigning the proxy
const PROXY_ACCOUNT_ADDRESS = '5DUe8dTokgDNr34aq9jtJYZcmb8gtCaksjXGes2HnYk3oJDK'; // The proxy account
const PROXY_TYPE = 'Any'; // Options: 'Any', 'NonTransfer', 'Governance', etc.
const DELAY = 0; // Set delay if needed

async function setupProxy() {
    try {
        // Connect to the blockchain
        const provider = new WsProvider(WS_PROVIDER);
        const api = await ApiPromise.create({ provider });

        // Load the proxied account's key
        const keyring = new Keyring({ type: 'sr25519' });
        const proxiedAccount = keyring.addFromUri(PROXIED_ACCOUNT_MNEMONIC);

        // Create the extrinsic to add the proxy
        const extrinsic = api.tx.proxy.addProxy(PROXY_ACCOUNT_ADDRESS, PROXY_TYPE, DELAY);

        console.log('Sending transaction to add proxy...');

        // Sign and send the transaction
        const unsub = await extrinsic.signAndSend(proxiedAccount, ({ status }) => {
            console.log(`Current status: ${status.type}`);

            if (status.isInBlock) {
                console.log(`Transaction included at blockHash ${status.asInBlock}`);
            } else if (status.isFinalized) {
                console.log(`Transaction finalized at blockHash ${status.asFinalized}`);
                unsub();
            }
        });
    } catch (error) {
        console.error('Error:', error);
    }
}

// Run the function
setupProxy();

Transfer with proxy:

import { ApiPromise, WsProvider, Keyring } from '@polkadot/api';

const WS_PROVIDER = 'wss://test.finney.opentensor.ai:443';
const PROXY_ACCOUNT_MNEMONIC = 'minute pistol liberty welcome harbor august between spend cherry genius doll jar';
const PROXIED_CK_ADDRESS = '5ECaCSR1tEzcF6yDiribP1JVsw2ZTepZ1ZPy7xgk7yoUv69b';
const DESTINATION_COLDKEY = '5EspBPxFuBm8D2MgEENa6HBpAW7mEqzFxaDzd8yhbBdTpkd9';
const TRANSFER_AMOUNT = 11000000000; // Adjust for token decimals, e.g., TAO uses 9 decimals

async function setupProxy() {
    try {
        const provider = new WsProvider(WS_PROVIDER);
        const api = await ApiPromise.create({ provider });

        const keyring = new Keyring({ type: 'sr25519' });
        const proxyAccount = keyring.addFromUri(PROXY_ACCOUNT_MNEMONIC);

        // Create the inner transfer call (what the proxied account would do)
        const innerCall = api.tx.balances.transferKeepAlive(
            DESTINATION_COLDKEY,
            TRANSFER_AMOUNT
        );

        // Wrap it in a proxy.proxy extrinsic
        const proxyExtrinsic = api.tx.proxy.proxy(
            PROXIED_CK_ADDRESS,
            'Any', // Proxy type: must match the registered type
            innerCall
        );

        console.log('Sending proxy-wrapped transaction...');

        const unsub = await proxyExtrinsic.signAndSend(proxyAccount, ({ status, dispatchError }) => {
            if (status.isInBlock) {
                console.log(`Included in block: ${status.asInBlock}`);
            } else if (status.isFinalized) {
                console.log(`Finalized block: ${status.asFinalized}`);
                unsub();
            }

            if (dispatchError) {
                if (dispatchError.isModule) {
                    const decoded = api.registry.findMetaError(dispatchError.asModule);
                    console.error(`Error: ${decoded.section}.${decoded.name} - ${decoded.docs.join(' ')}`);
                } else {
                    console.error(`Dispatch error: ${dispatchError.toString()}`);
                }
            }
        });

    } catch (err) {
        console.error('Error during proxy transfer:', err);
    }
}

setupProxy();

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions