Transaction apis are designed to be compatible with and interfaces, so you can sign the transactions with accounts created by a or from any 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 , similarly for other networks as well.
Sign & send a transaction
Example 1: Sign transaction with a Keying account
import { 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
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 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
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
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 ...
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.
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
}