docs ⦿ dedot 🧑‍💻
TypinkXTelegramGithub
dedot 🧑‍💻
dedot 🧑‍💻
  • Welcome to Dedot
  • Why Dedot?
  • Getting started
    • Installation
    • Connect to network
    • @polkadot/api -> dedot
    • Packages structure
  • Clients & Providers
    • Providers
    • Clients
  • Client API
    • ChainApi
    • Constants
    • Runtime APIs
    • Storage Queries
    • Transactions
    • Events
    • Errors
  • ink! Smart Contracts
    • Introduction
    • Generate Types & APIs
    • Deploy contracts
    • Queries
    • Transactions
    • Events
    • Handle errors
  • CLI
  • Keyring & Signer
  • Runtime upgrades
  • Type system
  • Utilities
    • HexString
    • Uint8Array (U8a)
    • String
    • Hash functions
    • Address
    • BigInt & number
    • Balances
    • Merkleized Metadata
  • Help & FAQ
    • Tutorials
      • Develop ink! dApp using Typink
    • Built with Dedot
    • Forum Posts
    • Telegram
    • Github
    • API Reference
Powered by GitBook
On this page
  • Sign & send a transaction
  • SubmittableExtrinsic
  • Tx Resolver Methods
  • SubmittableResult
  • TxStatus
  • SignerOptions

Was this helpful?

Edit on GitHub
  1. Client API

Transactions

PreviousStorage QueriesNextEvents

Last updated 15 days ago

Was this helpful?

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

const 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}`);
Example 3: Submit a batch transaction
import type { PolkadotRuntimeRuntimeCallLike } from '@dedot/chaintypes/polkadot';

// Omit the detail for simplicity
const account = ...;
const signer = ...;

const transferTx = client.tx.balances.transferKeepAlive(<destAddress>, 2_000_000_000_000n);
const remarkCall: PolkadotRuntimeRuntimeCallLike = {
  pallet: 'System',
  palletCall: {
    name: 'RemarkWithEvent',
    params: {
      remark: 'Hello Dedot!',
    },
  },
};

const { status } = client.tx.utility.batch([transferTx.call, remarkCall])
    .signAndSend(account.address, { signer }, ({ status }) => {
      console.log('Transaction status', status.type);
    })
    .untilFinalized();
    
console.log(`Transaction finalized at block hash ${status.value.blockHash}`);
Example 4: Teleport WND from Westend Asset Hub to Westend via XCM
import { WestendAssetHubApi, XcmVersionedLocation, XcmVersionedAssets, XcmV3WeightLimit } from '@dedot/chaintypes/westendAssetHub';
import { AccountId32 } from 'dedot/codecs';

const TWO_TOKENS = 2_000_000_000_000n;
const destAddress = <bobAddress>;

const client = await DedotClient.new<WestendAssetHubApi>('...westend-assethub-rpc...');

const dest: XcmVersionedLocation = {
  type: 'V3',
  value: { parents: 1, interior: { type: 'Here' } },
};

const beneficiary: XcmVersionedLocation = {
  type: 'V3',
  value: {
    parents: 0,
    interior: {
      type: 'X1',
      value: {
        type: 'AccountId32',
        value: { id: new AccountId32(destAddress).raw },
      },
    },
  },
};

const assets: XcmVersionedAssets = {
  type: 'V3',
  value: [
    {
      id: {
        type: 'Concrete',
        value: {
          parents: 1,
          interior: { type: 'Here' },
        },
      },
      fun: {
        type: 'Fungible',
        value: TWO_TOKENS,
      },
    },
  ],
};

const weight: XcmV3WeightLimit = { type: 'Unlimited' };

client.tx.polkadotXcm
  .limitedTeleportAssets(dest, beneficiary, assets, 0, weight)
  .signAndSend(alice, { signer, tip: 1_000_000n })
  .untilFinalized();

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

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 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

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

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
}

Sign the extrinsic using the

IKeyringPair
Signer
Keyring
Polkadot{.js}-based
here
IKeyringPair or Signer