git.delta.rocks / unique-network / refs/commits / 2e72efeb8353

difftreelog

fix hrmpchannel gov script

Daniel Shiposha2024-01-09parent: #50becf1.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 = '0x70617261';89  const encodedParaId = relayApi.createType('u32', paraid).toHex(true).substring(2);10  const suffix = '000000000000000000000000000000000000000000000000';1112  return childPrefix + encodedParaId + suffix;13};1415const proposeOpenChannel = async (relayApi: ApiPromise, relayFee: bigint, senderParaId: number, receiverParaId: number) => {16    const conf: any = await relayApi.query.configuration.activeConfig()17        .then(data => data.toJSON());18    const maxCapacity = conf.hrmpChannelMaxCapacity;19    const maxSize = conf.hrmpChannelMaxMessageSize;2021    const senderDeposit = BigInt(conf.hrmpSenderDeposit);2223    const requiredBalance = relayFee + senderDeposit;24    const sovereignAccount = await paraChildSovereignAccount(relayApi, senderParaId);25    const balance = await relayApi.query.system.account(sovereignAccount)26        .then(accountInfo => (accountInfo.toJSON() as any).data.free as bigint);2728    if(balance < requiredBalance) {29        throw Error(`Not enough balance on the sender's sovereign account: balance(${balance}) < requiredBalance(${requiredBalance})`);30    }3132    return relayApi.tx.hrmp.hrmpInitOpenChannel(33        receiverParaId,34        maxCapacity,35        maxSize,36    ).method.toHex();37};3839const proposeAcceptChannel = async (relayApi: ApiPromise, relayFee: bigint, senderParaId: number, recipientParaId: number) => {40    const conf: any = await relayApi.query.configuration.activeConfig()41        .then(data => data.toJSON());42    const recipientDeposit = BigInt(conf.hrmpRecipientDeposit);4344    const requiredBalance = relayFee + recipientDeposit;4546    const sovereignAccount = await paraChildSovereignAccount(relayApi, recipientParaId);47    const balance = await relayApi.query.system.account(sovereignAccount)48        .then(accountInfo => (accountInfo.toJSON() as any).data.free as bigint);4950    if(balance < requiredBalance) {51        throw Error(`Not enough balance on the recipient's sovereign account: balance(${balance}) < requiredBalance(${requiredBalance})`);52    }5354    return relayApi.tx.hrmp.hrmpAcceptOpenChannel(senderParaId).method.toHex();55};5657async function main() {58  const relayUrl = process.argv[2]59  const uniqueParachainUrl = process.argv[3];60  const otherParachainUrl = process.argv[4];61  const op = process.argv[5];6263  const relayWsProvider = new WsProvider(relayUrl);64  const relayApi = await ApiPromise.create({provider: relayWsProvider});6566  const uniqueWsProvider = new WsProvider(uniqueParachainUrl);67  const uniqueApi = await ApiPromise.create({provider: uniqueWsProvider});6869  const otherWsProvider = new WsProvider(otherParachainUrl);70  const otherApi = await ApiPromise.create({provider: otherWsProvider});7172  const uniqueParaId = await uniqueApi.query.parachainInfo.parachainId()73    .then(data => data.toJSON() as number);7475  const otherParaId = await otherApi.query.parachainInfo.parachainId()76    .then(data => data.toJSON() as number);7778  const relayDecimals = await relayApi.rpc.system.properties()79    .then(data => data.tokenDecimals.unwrap()[0].toNumber());8081  const relayFee = 2n * BigInt(10 ** relayDecimals);8283  let encodedRelayCall: string;84  if(op == 'open') {85    encodedRelayCall = await proposeOpenChannel(relayApi, relayFee, uniqueParaId, otherParaId);86  } else if(op == 'accept') {87    encodedRelayCall = await proposeAcceptChannel(relayApi, relayFee, otherParaId, uniqueParaId);88  } else {89    throw Error(`Unknown hrmp channel operation: ${op}`);90  }9192  const proposal = uniqueApi.tx.polkadotXcm.send(93    {94        V3: {95            parents: 1,96            interior: 'Here',97        }98    },99    {100        V3: [101            {102                WithdrawAsset: [103                    {104                        id: {105                            Concrete: {106                                parents: 0,107                                interior: 'Here',108                            },109                        },110                        fun: {111                            Fungible: relayFee,112                        },113                    },114                ],115            },116            {117                BuyExecution: {118                    fees: {119                        id: {120                            Concrete: {121                                parents: 0,122                                interior: 'Here',123                            },124                        },125                        fun: {126                            Fungible: relayFee,127                        },128                    },129                    weightLimit: 'Unlimited',130                },131            },132            {133                Transact: {134                    originKind: 'Native',135                    requireWeightAtMost: {136                        refTime: 1000000000,137                        proofSize: 65536,138                    },139                    call: {140                        encoded: encodedRelayCall,141                    },142                },143            },144            'RefundSurplus',145            {146                DepositAsset: {147                    assets: {148                        Wild: {149                            AllCounted: 1,150                        },151                    },152                    beneficiary: {153                        parents: 0,154                        interior: {155                            X1: {156                                Parachain: uniqueParaId,157                            },158                        },159                    },160                },161            },162        ],163    },164  ).method.toHex();165166  const councilMembers = (await uniqueApi.query.council.members()).toJSON() as any[];167  const councilProposalThreshold = Math.floor(councilMembers.length / 2) + 1;168169  const democracyProposalHash = blake2AsHex(proposal, 256);170  const democracyProposalPreimage = uniqueApi.tx.preimage.notePreimage(proposal).method.toHex();171172  const democracyProposal = uniqueApi.tx.democracy.externalProposeDefault({173    Legacy: democracyProposalHash,174  });175176  const councilProposal = uniqueApi.tx.council.propose(177    councilProposalThreshold,178    democracyProposal,179    democracyProposal.method.encodedLength,180  ).method.toHex();181182  const proposeBatch = uniqueApi.tx.utility.batchAll([183    democracyProposalPreimage,184    councilProposal,185  ]);186187  const encodedCall = proposeBatch.method.toHex();188189  console.log('-----------------');190  console.log('Council Proposal: ', `https://polkadot.js.org/apps/?rpc=${uniqueParachainUrl}#/extrinsics/decode/${encodedCall}`);191  console.log('-----------------');192193  await relayApi.disconnect();194  await uniqueApi.disconnect();195  await otherApi.disconnect();196}197198await 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  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();