My implementation wont let me batch more than 4 transfers. Am I doing something wrong?
I know the code is a bit complex because its normally not in one func but i has to be in this way. I am suprised that it wont work for more than 4 transfers. Its a bit odd to me tbh.
Can someone please help me asap? Thanks.
Error i am getting : 1010: Invalid Transaction: Transaction has a bad signature
Note: If i use transfer and batchAll it gives -32603: Internal error
,
if i use transfer and batch it gives the same invalid Signature error
const specVersion = getSpecVersion();
const transactionVersion = getTransactionVersion();
const specName: any = getSpecName();
const chainName = getChainName();
[block, metadataRpc] = await Promise.all([
rawBlock = await getBlock(blockHash),
metadataRpc = getMetaDataRpc(),
]);
const registry = this.getRegistry({
chainName,
specName,
specVersion,
metadataRpc,
asCallsOnlyArg: true,
});
const account = getAccount(publicKey);
const transferArgs = []
// logic that converts transfers to {dest, value} and pushes them to transferArgs
const batchTransferMethods = transferArgs.map((args) => {
const txInfo = methods.balances.transferKeepAlive(
args,
{
address: account.address,
blockHash,
blockNumber,
eraPeriod,
genesisHash,
metadataRpc,
nonce,
specVersion,
tip,
transactionVersion,
},
{
metadataRpc,
registry,
},
);
return txInfo.method;
});
const unsigned = methods.utility.batchAll(
{
calls: batchTransferMethods,
},
{
address: account.address,
blockHash,
blockNumber,
eraPeriod,
genesisHash,
metadataRpc,
nonce,
tip,
transactionVersion,
},
{
metadataRpc,
registry,
},
);
const extrinsicPayload = registry.createType('ExtrinsicPayload', unsigned, {
version: unsigned.version,
});
const extrinsicPayloadU8a = extrinsicPayload.toU8a({ method: true });
const dataToSign = Buffer.from(registry.hash(extrinsicPayloadU8a)).toString(
'hex',
);
// signing operation and logic
const signedTransaction = construct.signedTx(
unsigned,
signatureWithPrefix,
{
metadataRpc,
registry,
},
);
const signedTransaction = transaction({ transactionToSubmit });
let response: {
events: EventRecord[];
status: ExtrinsicStatus;
txHash: Hash;
};
let blockNumber: string, signedBlock: SignedBlock;
try {
response = await new Promise((resolve, reject) => {
signedTransaction
.send(({ events = [], status, txHash }) => {
if (status.isFinalized) {
resolve({ events, status, txHash });
}
})
.catch((err) => {
reject(err);
});
});
signedBlock = await getBlock(response.status.asFinalized.toHex());
blockNumber = signedBlock.block.header.number.toString();
response.events.forEach(({ event }) => {
if (this.api.events.system.ExtrinsicFailed.is(event)) {
// extract the data for this event
const [dispatchError] = event.data;
let errorInfo: string;
// decode the error
if (dispatchError.isModule) {
const decoded = this.api.registry.findMetaError(
dispatchError.asModule,
);
errorInfo = `${decoded.section}.${decoded.name}`;
} else {
// Other, CannotLookup, BadOrigin, no extra info
errorInfo = dispatchError.toString();
}
throw new BadRequestException(
`Transaction has been reverted. transactionHash: ${blockNumber}-${
(response.events[0].phase.toJSON() as any).applyExtrinsic
} , ExtrinsicFailed:: ${errorInfo} `,
);
}
});
} catch (error) {
throw new BroadcastFailedError(error.message);
}