txwrapper
txwrapper copied to clipboard
[Question] Create Smart Contract call transaction offline and submit it later
Hey, guys. Thanks for this useful lib. Is it a possibility to create a Smart Contract call offline, wrap it to string let's say, share a transaction string (for example put it to DB), and later unwrap and submit it to the Blockchain?
Thanks!
Hey 👋
I am actually not personally familiar with transactions for contracts, but if they are standard transactions (extrinsics), you can encode the transaction, which turns it into a SCALE encoded hex string.
You can store that hex string in a DB, and you can store it at various stages of construction and should still be able to decode it with polkadot-js and/or the utils from this lib to sign etc. Additionally, polkadot-js is pretty flexible when it comes into reading data so in many cases it can also read in a JSON representation of the transaction.
The final transaction is broadcasted as a hex string so you could easily store that in a DB as well and broadcast it as is.
Hi.
Have you implemented the offline creation contract call?
Hello, @azhu003 Yes, I was able to do it using extrinsics and polkadot JS lib. Here is the example:
this.appKeyring = keyring.addFromJson(
JSON.parse(process.env.APP_WALLET_JSON)
);
const gasLimitAuto = -1;
const anyValue = 0;
const transferObj = await this.contract.tx.methodName(
anyValue,
gasLimitAuto,
param1,
param2,
param3,
param4,
param5
);
return new Promise((res, rej) => {
transferObj
.signAndSend(this.appKeyring, ({ status }) => {
if (status.isInBlock) {
const hash = status.asInBlock.toHex();
this.logger.log(`In block: ${hash}`);
res(hash);
}
})
.catch((err) => rej(err));
});
Above - online call. Below offline:
public async createSignedTransaction(
privateKey: string,
destination: string,
amount: string,
): Promise<SignedDataResponse> {
const gasLimitAuto = -1;
const anyValue = 0;
const keyring = new Keyring({type: this.userKeyRingType});
const userKeyRing = keyring.addFromSeed(hexToU8a(privateKey));
const tx = await this.contract.tx
.transfer(anyValue, gasLimitAuto, destination, Number(amount), partialFee)
.signAsync(userKeyRing);
const txString = JSON.stringify(tx);
const signedDataDto = new SignedDataResponse();
signedDataDto.tx = txString;
return signedDataDto;
}
public async submitTx(tx: string, publicKey: string, appId: string): Promise<SubmitTransactionRes> {
const txn = JSON.parse(tx);
const txnHash = await this.substrateApi.rpc.author.submitExtrinsic(txn);
const txnString = JSON.stringify(txnHash);
const submitTxResponse = new SubmitTransactionRes(txnString);
this.logger.log(`Tx hash: ${txnHash}`);
return submitTxResponse;
}
@azhu003 Hope it helps.
@evgeny-s thanks😁