git.delta.rocks / unique-network / refs/commits / 0ef2a332f919

difftreelog

fix add usage

Daniel Shiposha2024-01-09parent: #d73f42e.patch.diff
in: master

1 file changed

modifiedjs-packages/scripts/hrmpchannel.tsdiffbeforeafterboth
before · js-packages/scripts/hrmpchannel.ts
1import {ApiPromise, WsProvider} from '@polkadot/api';2import {blake2AsHex, encodeAddress} from '@polkadot/util-crypto';34export const paraChildSovereignAccount = (relayApi: ApiPromise, paraid: number) => {5  // We are getting a *child* parachain sovereign account,6  // so we need a child prefix: encoded(b"para") == 0x706172617  const childPrefix = '70617261';89  const encodedParaId = relayApi10    .createType('u32', paraid)11    .toHex(true)12    .substring(2 /* skip 0x */);1314  const addrBytesLen = 32;15  const byteLenInHex = 2;16  return '0x' + (childPrefix + encodedParaId).padEnd(addrBytesLen * byteLenInHex, '0');17};1819const proposeOpenChannel = async (relayApi: ApiPromise, relayFee: bigint, senderParaId: number, receiverParaId: number) => {20    const conf: any = await relayApi.query.configuration.activeConfig()21        .then(data => data.toJSON());22    const maxCapacity = conf.hrmpChannelMaxCapacity;23    const maxSize = conf.hrmpChannelMaxMessageSize;2425    const senderDeposit = BigInt(conf.hrmpSenderDeposit);2627    const requiredBalance = relayFee + senderDeposit;28    const sovereignAccount = paraChildSovereignAccount(relayApi, senderParaId);29    const balance = await relayApi.query.system.account(sovereignAccount)30        .then(accountInfo => (accountInfo.toJSON() as any).data.free as bigint);3132    if(balance < requiredBalance) {33        throw Error(`Not enough balance on the sender's sovereign account: balance(${balance}) < requiredBalance(${requiredBalance})`);34    }3536    return relayApi.tx.hrmp.hrmpInitOpenChannel(37        receiverParaId,38        maxCapacity,39        maxSize,40    ).method.toHex();41};4243const proposeAcceptChannel = async (relayApi: ApiPromise, relayFee: bigint, senderParaId: number, recipientParaId: number) => {44    const conf: any = await relayApi.query.configuration.activeConfig()45        .then(data => data.toJSON());46    const recipientDeposit = BigInt(conf.hrmpRecipientDeposit);4748    const requiredBalance = relayFee + recipientDeposit;4950    const sovereignAccount = paraChildSovereignAccount(relayApi, recipientParaId);51    const balance = await relayApi.query.system.account(sovereignAccount)52        .then(accountInfo => (accountInfo.toJSON() as any).data.free as bigint);5354    if(balance < requiredBalance) {55        throw Error(`Not enough balance on the recipient's sovereign account: balance(${balance}) < requiredBalance(${requiredBalance})`);56    }5758    return relayApi.tx.hrmp.hrmpAcceptOpenChannel(senderParaId).method.toHex();59};6061async function main() {62  const relayUrl = process.argv[2]63  const uniqueParachainUrl = process.argv[3];64  const otherParachainUrl = process.argv[4];65  const op = process.argv[5];6667  const relayWsProvider = new WsProvider(relayUrl);68  const relayApi = await ApiPromise.create({provider: relayWsProvider});6970  const uniqueWsProvider = new WsProvider(uniqueParachainUrl);71  const uniqueApi = await ApiPromise.create({provider: uniqueWsProvider});7273  const otherWsProvider = new WsProvider(otherParachainUrl);74  const otherApi = await ApiPromise.create({provider: otherWsProvider});7576  const uniqueParaId = await uniqueApi.query.parachainInfo.parachainId()77    .then(data => data.toJSON() as number);7879  const otherParaId = await otherApi.query.parachainInfo.parachainId()80    .then(data => data.toJSON() as number);8182  const relayDecimals = await relayApi.rpc.system.properties()83    .then(data => data.tokenDecimals.unwrap()[0].toNumber());8485  const relayFee = 2n * BigInt(10 ** relayDecimals);8687  let encodedRelayCall: string;88  if(op == 'open') {89    encodedRelayCall = await proposeOpenChannel(relayApi, relayFee, uniqueParaId, otherParaId);90  } else if(op == 'accept') {91    encodedRelayCall = await proposeAcceptChannel(relayApi, relayFee, otherParaId, uniqueParaId);92  } else {93    throw Error(`Unknown hrmp channel operation: ${op}`);94  }9596  const proposal = uniqueApi.tx.polkadotXcm.send(97    {98        V3: {99            parents: 1,100            interior: 'Here',101        }102    },103    {104        V3: [105            {106                WithdrawAsset: [107                    {108                        id: {109                            Concrete: {110                                parents: 0,111                                interior: 'Here',112                            },113                        },114                        fun: {115                            Fungible: relayFee,116                        },117                    },118                ],119            },120            {121                BuyExecution: {122                    fees: {123                        id: {124                            Concrete: {125                                parents: 0,126                                interior: 'Here',127                            },128                        },129                        fun: {130                            Fungible: relayFee,131                        },132                    },133                    weightLimit: 'Unlimited',134                },135            },136            {137                Transact: {138                    originKind: 'Native',139                    requireWeightAtMost: {140                        refTime: 1000000000,141                        proofSize: 65536,142                    },143                    call: {144                        encoded: encodedRelayCall,145                    },146                },147            },148            'RefundSurplus',149            {150                DepositAsset: {151                    assets: {152                        Wild: {153                            AllCounted: 1,154                        },155                    },156                    beneficiary: {157                        parents: 0,158                        interior: {159                            X1: {160                                Parachain: uniqueParaId,161                            },162                        },163                    },164                },165            },166        ],167    },168  ).method.toHex();169170  const councilMembers = (await uniqueApi.query.council.members()).toJSON() as any[];171  const councilProposalThreshold = Math.floor(councilMembers.length / 2) + 1;172173  const democracyProposalHash = blake2AsHex(proposal, 256);174  const democracyProposalPreimage = uniqueApi.tx.preimage.notePreimage(proposal).method.toHex();175176  const democracyProposal = uniqueApi.tx.democracy.externalProposeDefault({177    Legacy: democracyProposalHash,178  });179180  const councilProposal = uniqueApi.tx.council.propose(181    councilProposalThreshold,182    democracyProposal,183    democracyProposal.method.encodedLength,184  ).method.toHex();185186  const proposeBatch = uniqueApi.tx.utility.batchAll([187    democracyProposalPreimage,188    councilProposal,189  ]);190191  const encodedCall = proposeBatch.method.toHex();192193  console.log('-----------------');194  console.log('Council Proposal: ', `https://polkadot.js.org/apps/?rpc=${uniqueParachainUrl}#/extrinsics/decode/${encodedCall}`);195  console.log('-----------------');196197  await relayApi.disconnect();198  await uniqueApi.disconnect();199  await otherApi.disconnect();200}201202await main();
after · js-packages/scripts/hrmpchannel.ts
1import {ApiPromise, WsProvider} from '@polkadot/api';2import {blake2AsHex, encodeAddress} from '@polkadot/util-crypto';34export const paraChildSovereignAccount = (relayApi: ApiPromise, paraid: number) => {5  // We are getting a *child* parachain sovereign account,6  // so we need a child prefix: encoded(b"para") == 0x706172617  const childPrefix = '70617261';89  const encodedParaId = relayApi10    .createType('u32', paraid)11    .toHex(true)12    .substring(2 /* skip 0x */);1314  const addrBytesLen = 32;15  const byteLenInHex = 2;16  return '0x' + (childPrefix + encodedParaId).padEnd(addrBytesLen * byteLenInHex, '0');17};1819const proposeOpenChannel = async (relayApi: ApiPromise, relayFee: bigint, senderParaId: number, receiverParaId: number) => {20    const conf: any = await relayApi.query.configuration.activeConfig()21        .then(data => data.toJSON());22    const maxCapacity = conf.hrmpChannelMaxCapacity;23    const maxSize = conf.hrmpChannelMaxMessageSize;2425    const senderDeposit = BigInt(conf.hrmpSenderDeposit);2627    const requiredBalance = relayFee + senderDeposit;28    const sovereignAccount = paraChildSovereignAccount(relayApi, senderParaId);29    const balance = await relayApi.query.system.account(sovereignAccount)30        .then(accountInfo => (accountInfo.toJSON() as any).data.free as bigint);3132    if(balance < requiredBalance) {33        throw Error(`Not enough balance on the sender's sovereign account: balance(${balance}) < requiredBalance(${requiredBalance})`);34    }3536    return relayApi.tx.hrmp.hrmpInitOpenChannel(37        receiverParaId,38        maxCapacity,39        maxSize,40    ).method.toHex();41};4243const proposeAcceptChannel = async (relayApi: ApiPromise, relayFee: bigint, senderParaId: number, recipientParaId: number) => {44    const conf: any = await relayApi.query.configuration.activeConfig()45        .then(data => data.toJSON());46    const recipientDeposit = BigInt(conf.hrmpRecipientDeposit);4748    const requiredBalance = relayFee + recipientDeposit;4950    const sovereignAccount = paraChildSovereignAccount(relayApi, recipientParaId);51    const balance = await relayApi.query.system.account(sovereignAccount)52        .then(accountInfo => (accountInfo.toJSON() as any).data.free as bigint);5354    if(balance < requiredBalance) {55        throw Error(`Not enough balance on the recipient's sovereign account: balance(${balance}) < requiredBalance(${requiredBalance})`);56    }5758    return relayApi.tx.hrmp.hrmpAcceptOpenChannel(senderParaId).method.toHex();59};6061async function main() {62  if(process.argv.length != 6) {63    console.log('Usage: yarn hrmpChannel <RELAY_URL> <OUR_CHAIN_URL> <OTHER_CHAIN_URL> <open | accept>');64    process.exit(1);65  }6667  const relayUrl = process.argv[2]68  const uniqueParachainUrl = process.argv[3];69  const otherParachainUrl = process.argv[4];70  const op = process.argv[5];7172  const relayWsProvider = new WsProvider(relayUrl);73  const relayApi = await ApiPromise.create({provider: relayWsProvider});7475  const uniqueWsProvider = new WsProvider(uniqueParachainUrl);76  const uniqueApi = await ApiPromise.create({provider: uniqueWsProvider});7778  const otherWsProvider = new WsProvider(otherParachainUrl);79  const otherApi = await ApiPromise.create({provider: otherWsProvider});8081  const uniqueParaId = await uniqueApi.query.parachainInfo.parachainId()82    .then(data => data.toJSON() as number);8384  const otherParaId = await otherApi.query.parachainInfo.parachainId()85    .then(data => data.toJSON() as number);8687  const relayDecimals = await relayApi.rpc.system.properties()88    .then(data => data.tokenDecimals.unwrap()[0].toNumber());8990  const relayFee = 2n * BigInt(10 ** relayDecimals);9192  let encodedRelayCall: string;93  if(op == 'open') {94    encodedRelayCall = await proposeOpenChannel(relayApi, relayFee, uniqueParaId, otherParaId);95  } else if(op == 'accept') {96    encodedRelayCall = await proposeAcceptChannel(relayApi, relayFee, otherParaId, uniqueParaId);97  } else {98    throw Error(`Unknown hrmp channel operation: ${op}`);99  }100101  const proposal = uniqueApi.tx.polkadotXcm.send(102    {103        V3: {104            parents: 1,105            interior: 'Here',106        }107    },108    {109        V3: [110            {111                WithdrawAsset: [112                    {113                        id: {114                            Concrete: {115                                parents: 0,116                                interior: 'Here',117                            },118                        },119                        fun: {120                            Fungible: relayFee,121                        },122                    },123                ],124            },125            {126                BuyExecution: {127                    fees: {128                        id: {129                            Concrete: {130                                parents: 0,131                                interior: 'Here',132                            },133                        },134                        fun: {135                            Fungible: relayFee,136                        },137                    },138                    weightLimit: 'Unlimited',139                },140            },141            {142                Transact: {143                    originKind: 'Native',144                    requireWeightAtMost: {145                        refTime: 1000000000,146                        proofSize: 65536,147                    },148                    call: {149                        encoded: encodedRelayCall,150                    },151                },152            },153            'RefundSurplus',154            {155                DepositAsset: {156                    assets: {157                        Wild: {158                            AllCounted: 1,159                        },160                    },161                    beneficiary: {162                        parents: 0,163                        interior: {164                            X1: {165                                Parachain: uniqueParaId,166                            },167                        },168                    },169                },170            },171        ],172    },173  ).method.toHex();174175  const councilMembers = (await uniqueApi.query.council.members()).toJSON() as any[];176  const councilProposalThreshold = Math.floor(councilMembers.length / 2) + 1;177178  const democracyProposalHash = blake2AsHex(proposal, 256);179  const democracyProposalPreimage = uniqueApi.tx.preimage.notePreimage(proposal).method.toHex();180181  const democracyProposal = uniqueApi.tx.democracy.externalProposeDefault({182    Legacy: democracyProposalHash,183  });184185  const councilProposal = uniqueApi.tx.council.propose(186    councilProposalThreshold,187    democracyProposal,188    democracyProposal.method.encodedLength,189  ).method.toHex();190191  const proposeBatch = uniqueApi.tx.utility.batchAll([192    democracyProposalPreimage,193    councilProposal,194  ]);195196  const encodedCall = proposeBatch.method.toHex();197198  console.log('-----------------');199  console.log('Council Proposal: ', `https://polkadot.js.org/apps/?rpc=${uniqueParachainUrl}#/extrinsics/decode/${encodedCall}`);200  console.log('-----------------');201202  await relayApi.disconnect();203  await uniqueApi.disconnect();204  await otherApi.disconnect();205}206207await main();