difftreelog
fix yarn fix
in: master
1 file changed
js-packages/scripts/hrmpchannel.tsdiffbeforeafterboth1import {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();