Skip to content

Instantly share code, notes, and snippets.

@amintalebi
Last active July 26, 2022 11:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amintalebi/f782b395f7bf982530d9010f97c8a290 to your computer and use it in GitHub Desktop.
Save amintalebi/f782b395f7bf982530d9010f97c8a290 to your computer and use it in GitHub Desktop.
import { u8aToHex } from '@polkadot/util';
import { getRegistry, methods } from '@substrate/txwrapper-polkadot';
async constructTransaction(from: string, to: string, value: string, tip: number): Promise<{ signingPayload: string }> {
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 { specVersion, transactionVersion, specName } = await rpcToLocalNode(
'state_getRuntimeVersion'
);
const nonce = await api.rpc.system.accountNextIndex(from);
const registry = getRegistry({
chainName: specName,
specName,
specVersion,
metadataRpc,
});
const unsigned = methods.balances.transfer(
{
value: value,
dest: to,
},
{
address: from,
blockHash,
blockNumber: registry.createType('BlockNumber', block.header.number).toNumber(),
eraPeriod: 64,
genesisHash,
metadataRpc,
nonce: nonce.toNumber(),
specVersion,
tip: tip,
transactionVersion,
},
{
metadataRpc,
registry,
}
);
const extrinsicPayload = registry.createType('ExtrinsicPayload', unsigned, {
version: unsigned.version,
});
const extrinsicPayloadU8a = extrinsicPayload.toU8a({ method: true });
const actualPayload = extrinsicPayloadU8a.length > 256 ? registry.hash(extrinsicPayloadU8a) : extrinsicPayloadU8a;
return {
signingPayload: u8aToHex(actualPayload),
};
}
async function rpcToLocalNode(method: string, params: any[] = []): Promise<any> {
const url = process.env.SAS_SUBSTRATE_RPC_URL as string;
return fetch(url, {
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 constructSignedTransaction(signature: string): Promise<{ extrinsic: string }> {
const extrinsic = registry.createType(
'Extrinsic',
{ method: method },
{ version: version }
);
const extrinsicPayloadValue = {
blockHash: blockHash,
era: era,
genesisHash: genesisHash,
method: method,
nonce: nonce,
specVersion: specVersion,
tip: tip,
transactionVersion: version,
}
extrinsic.addSignature(address, signature, extrinsicPayloadValue);
return {
extrinsic: extrinsic.toHex(),
};
}
const signingPayload = constructTransaction(...);
const signature = sign(signingPayload);
const extrinsic = constructSignedTransaction(signature);
// extrinsic is ready for broadcast
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment