Created
November 17, 2021 13:05
-
-
Save xcaptain/4d190232411dcf27441d9fadd7ff6988 to your computer and use it in GitHub Desktop.
sign transaction offline and then submit to chain
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { ApiPromise, WsProvider } = require('@polkadot/api'); | |
const { Keyring } = require('@polkadot/keyring'); | |
const { | |
construct, | |
decode, | |
deriveAddress, | |
getRegistry, | |
methods, | |
PolkadotSS58Format, | |
} = require('@substrate/txwrapper-polkadot'); | |
const { cryptoWaitReady } = require('@polkadot/util-crypto'); | |
const fetch = require('node-fetch'); | |
const { createMetadata, OptionsWithMeta } = require('@substrate/txwrapper-polkadot'); | |
const { EXTRINSIC_VERSION } = require('@polkadot/types/extrinsic/v4/Extrinsic'); | |
async function rpcToLocalNode( | |
method, | |
params | |
) { | |
return await fetch('http://localhost:9933', { | |
body: JSON.stringify({ | |
id: 1, | |
jsonrpc: '2.0', | |
method, | |
params, | |
}), | |
headers: { | |
'Content-Type': 'application/json', | |
}, | |
method: 'POST', | |
}) | |
.then((response) => response.json()) | |
.then(({ error, result }) => { | |
if (error) { | |
throw new Error( | |
`${error.code} ${error.message}: ${JSON.stringify(error.data)}` | |
); | |
} | |
return result; | |
}); | |
} | |
async function signWith( | |
pair, | |
signingPayload, | |
options | |
) { | |
const { registry, metadataRpc } = options; | |
// Important! The registry needs to be updated with latest metadata, so make | |
// sure to run `registry.setMetadata(metadata)` before signing. | |
registry.setMetadata(createMetadata(registry, metadataRpc)); | |
const { signature } = registry | |
.createType('ExtrinsicPayload', signingPayload, { | |
version: EXTRINSIC_VERSION, | |
}) | |
.sign(pair); | |
return signature; | |
} | |
async function test5() { | |
await cryptoWaitReady(); | |
const keyring = new Keyring({ type: 'sr25519' }); | |
// Add Alice to our keyring with a hard-deived path (empty phrase, so uses dev) | |
const alice = keyring.addFromUri('//Alice'); | |
const bob = keyring.addFromUri('//Bob'); | |
const { specVersion, transactionVersion, specName } = await rpcToLocalNode( | |
'state_getRuntimeVersion' | |
); | |
const { block } = await rpcToLocalNode('chain_getBlock'); | |
const blockHash = await rpcToLocalNode('chain_getBlockHash'); | |
const genesisHash = await rpcToLocalNode('chain_getBlockHash', [0]); | |
const metadataRpc = await rpcToLocalNode('state_getMetadata'); | |
// const index = await httpRequest({ ...params, method: 'system_accountNextIndex', params: [pair.address] }); | |
const index = await rpcToLocalNode('system_accountNextIndex', [alice.address]); | |
const registry = getRegistry({ | |
chainName: 'Polkadot', | |
specName, | |
specVersion, | |
metadataRpc, | |
}); | |
const unsigned = methods.balances.transfer( | |
{ | |
dest: bob.address, | |
value: 100, | |
}, | |
{ | |
address: deriveAddress(alice.publicKey, PolkadotSS58Format.polkadot), | |
blockHash, | |
blockNumber: registry | |
.createType('BlockNumber', block.header.number) | |
.toNumber(), | |
eraPeriod: 64, | |
genesisHash, | |
metadataRpc, | |
nonce: index, // Assuming this is Alice's first tx on the chain | |
specVersion, | |
tip: 0, | |
transactionVersion, | |
}, | |
{ metadataRpc, registry } | |
); | |
const signingPayload = construct.signingPayload(unsigned, { registry }); | |
// On your offline device, sign the payload. | |
// const signature = myOfflineSigning(signingPayload); | |
const signature = await signWith(alice, signingPayload, { | |
metadataRpc, | |
registry, | |
}); | |
// `tx` is ready to be broadcasted. | |
const tx = construct.signedTx(unsigned, signature, { metadataRpc, registry }); | |
console.log('tx', tx); | |
const actualTxHash = await rpcToLocalNode('author_submitExtrinsic', [tx]); | |
console.log(`Actual Tx Hash: ${actualTxHash}`); | |
console.log('block_hash', blockHash, block, index); | |
} | |
test5() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment