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
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 unsub = await client.tx.balances
.transferKeepAlive(<destAddress>, 2_000_000_000_000n)
.signAndSend(alice, async ({ status }) => {
console.log('Transaction status', status.type);
if (status.type === 'BestChainBlockIncluded') { // or status.type === 'Finalized'
console.log(`Transaction completed at block hash ${status.value.blockHash}`);
await unsub();
}
});
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
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
}