Transactions
Transaction apis are designed to be compatible with IKeyringPair
and Signer
interfaces, so you can sign the transactions with accounts created by a Keyring
or from any Polkadot{.js}-based wallet extensions.
All transaction apis are exposed in ChainApi
interface and can be access with syntax: client.tx.<pallet>.<transactionName>
. E.g: Available transaction apis for Polkadot network are defined here, similarly for other networks as well.
Sign & send a transaction
Example 1: Sign transaction with a Keying
account
Keying
accountimport { cryptoWaitReady } from '@polkadot/util-crypto';
import { Keyring } from '@polkadot/keyring';
// ...
await cryptoWaitReady();
const keyring = new Keyring({ type: 'sr25519' });
const alice = keyring.addFromUri('//Alice');
const { status } = await client.tx.balances
.transferKeepAlive(<destAddress>, 2_000_000_000_000n)
.signAndSend(alice, ({ status }) => {
console.log('Transaction status', status.type);
})
.untilFinalized();
console.log(`Transaction finalized at block hash ${status.value.blockHash}`);
Example 2: Sign transaction using Signer
from Polkadot{.js} wallet extension
Signer
from Polkadot{.js} wallet extensionconst injected = await window.injectedWeb3['polkadot-js'].enable('A cool dapp');
const account = (await injected.accounts.get())[0];
const signer = injected.signer;
const { status } = await client.tx.balances
.transferKeepAlive(<destAddress>, 2_000_000_000_000n)
.signAndSend(account.address, { signer }, ({ status }) => {
console.log('Transaction status', status.type);
})
.untilFinalized();
console.log(`Transaction finalized at block hash ${status.value.blockHash}`);
SubmittableExtrinsic
SubmittableExtrinsic
is an extrinsic instance that's ready to sign and send to the network for inclusion. A SubmittableExtrinsic
will be created after you execute a tx method with required arguments.
const extrinsic: SubmittableExtrinsic = client.tx.balances.transferKeepAlive(<destAddress>, 2_000_000_000_000n)
sign
sign
Sign the extrinsic using the IKeyringPair
or Signer
client.tx.balances
.transferKeepAlive(<destAddress>, 2_000_000_000_000n)
.sign(<signer_address>);
You can also customize the transaction by using signer options as the second parameter:
import { SignerOptions } from 'dedot/types';
const options: SignerOptions = {
nonce: 10,
tip: 1_000n,
metadataHash: '0x...',
assetId: { ... },
signer: CustomSignerInstance,
}
client.tx.balances
.transferKeepAlive(<destAddress>, 2_000_000_000_000n)
.sign(<signer_address>, options);
send
send
Send the extrinsic to the network
const txHash = await client.tx.balances
.transferKeepAlive(<destAddress>, 2_000_000_000_000n)
.sign(<signer_address>) // we need to sign the tx before sending it
.send();
And watch its status as needed
const unsubFn = await client.tx.balances
.transferKeepAlive(<destAddress>, 2_000_000_000_000n)
.sign(<signer_address>) // we need to sign the tx before sending it
.send(({ status }) => { console.log(status) }); // ref: TxStatus
signAndSend
signAndSend
Sign and send the extrinsic to the network. This method's simply a combination of sign
& send
methods.
const txHash = await client.tx.balances
.transferKeepAlive(<destAddress>, 2_000_000_000_000n)
.signAndSend(<signer_address>);
// Or keep watching the tx status
const unsubFn = await client.tx.balances
.transferKeepAlive(<destAddress>, 2_000_000_000_000n)
.signAndSend(<signer_address>, (result) => {
const { status } = result;
console.log(status);
});
Or pass in an options object to customize the transaction parameters
import { SignerOptions } from 'dedot/types';
const options: SignerOptions = {
nonce: 10,
tip: 1_000n,
metadataHash: '0x...',
assetId: { ... },
signer: CustomSignerInstance,
}
const unsubFn = await client.tx.balances
.transferKeepAlive(<destAddress>, 2_000_000_000_000n)
.signAndSend(<signer_address>, options, (result) => {
const { status } = result;
console.log(status);
});
paymentInfo
paymentInfo
Estimate gas fee for a transaction
const { partialFee } = client.tx.balances
.transferKeepAlive(<destAddress>, 2_000_000_000_000n)
.paymentInfo(<signer_address>);
console.log('Estimated gas fee', partialFee);
Tx Resolver Methods
untilBestChainBlockIncluded
Wait until the transaction is included in best chain block and resolve to return the result (SubmittableResult
) with access to on-chain events, status, and dispatchInfo ...
const result = await client.tx.balances
.transferKeepAlive(<destAddress>, 2_000_000_000_000n)
.signAndSend(<signer_address>) // or .send(...)
.untilBestChainBlockIncluded();
const { status, events, ... } = result; // status.type = 'BestChainBlockIncluded'
Please note that the BestChainBlockIncluded
event might occurred multiple times during a transaction life-cycle due to forks. This method will resolve when it receives the first BestChainBlockIncluded
event. So please use this with caution.
untilFinalized
Similarly, wait until the transaction is included in a finalized block and resolve.
const result = await client.tx.balances
.transferKeepAlive(<destAddress>, 2_000_000_000_000n)
.signAndSend(<signer_address>) // or .send(...)
.untilFinalized();
const { status, events, ... } = result; // status.type = 'Finalized'
SubmittableResult
TODO
TxStatus
Available statuses of a transaction:
export type TxStatus =
// emits after we validate the transaction via `call.taggedTransactionQueue.validateTransaction`
| { type: 'Validated' }
// emits after we submit the transaction via TxBroadcaster
| { type: 'Broadcasting' }
// emits when the tx is included in the best block of the chain
| { type: 'BestChainBlockIncluded'; value: { blockHash: HexString; blockNumber: number; txIndex: number } }
// emits when the tx was retracted from the chain for various reasons
| { type: 'NoLongerInBestChain' }
// emits when the tx is finalized
| { type: 'Finalized'; value: { blockHash: HexString; blockNumber: number; txIndex: number } }
// emits when the tx is invalid for some reasons: invalid nonce ...
| { type: 'Invalid'; value: { error: string } }
// emits when the client cannot keep track of the tx
| { type: 'Drop'; value: { error: string } };
SignerOptions
export interface PayloadOptions {
nonce?: number; // customize the nonce
tip?: bigint; // add a tip for the block producer
assetId?: number | object; // customize asset to pay for fee
metadataHash?: HexString; // submit metadata hash for validation
}
export interface SignerOptions extends PayloadOptions {
signer?: Signer; // customize the signer instance to sign the transaction
}
Last updated
Was this helpful?