Open
Description
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
Labels
No labels