git.delta.rocks / unique-network / refs/commits / 50becf1c3138

difftreelog

feat check required balance before sending the msg

Daniel Shiposha2023-12-25parent: #99f6558.patch.diff
in: master

1 file changed

modifiedjs-packages/scripts/hrmpchannel.tsdiffbeforeafterboth
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 = '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();