SDK Version

This Documentation is based upon avail-js version v0.4.2

TS-Node

  1. Install Node
  2. Install TS-Node globally

Save to index.ts

import { SDK } from "avail-js-sdk"

async function main() {}

main()
  .catch((e) => {
    console.log(e)
    process.exit(1)
  })
  .finally(() => {
    console.log("All Good")
    process.exit(0)
  })

Save to package.json

{
  "name": "avail-js-docs",
  "version": "0.0.1",
  "description": "Avail-js SDK",
  "dependencies": {
    "avail-js-sdk": "^0.4.2"
  },
  "resolutions": {
    "ws": ">=8.17.1"
  }
}

Save to tsconfig.json

{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "outDir": "build",
    "declaration": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "noUnusedParameters": true
  },
  "include": ["src"],
  "exclude": ["node_modules", "build"]
}

You should now have the following files

  • current directory
    • index.ts
    • package.json
    • tsconfig.json

Run the following commands:

  • npm i
  • ts-node ./index.ts

Deno

  1. Install Deno

Save to index.ts

import { SDK } from "avail-js-sdk"

async function main() {}

main()
  .catch((e) => {
    console.log(e)
    process.exit(1)
  })
  .finally(() => {
    console.log("All Good")
    process.exit(0)
  })

Save to package.json

{
  "name": "avail-js-docs",
  "version": "0.0.1",
  "description": "Avail-js SDK",
  "dependencies": {
    "avail-js-sdk": "^0.4.2"
  },
  "resolutions": {
    "ws": ">=8.17.1"
  }
}

You should now have the following files

  • current directory
    • index.ts
    • package.json

Run the following commands:

  • deno install
  • deno run -A ./index.ts

Bun

  1. Install Bun

Save to index.ts

import { SDK } from "avail-js-sdk"

async function main() {}

main()
  .catch((e) => {
    console.log(e)
    process.exit(1)
  })
  .finally(() => {
    console.log("All Good")
    process.exit(0)
  })

Save to package.json

{
  "name": "avail-js-docs",
  "version": "0.0.1",
  "description": "Avail-js SDK",
  "dependencies": {
    "avail-js-sdk": "^0.4.2"
  },
  "resolutions": {
    "ws": ">=8.17.1"
  }
}

You should now have the following files

  • current directory
    • index.ts
    • package.json

Run the following commands:

  • bun install
  • bun run ./index.ts

Data Submission

import { assert_eq, assert_true } from "."
import { Account, SDK, Pallets } from "./../src/index"

export async function runDataSubmission() {
  const sdk = await SDK.New(SDK.localEndpoint)
  const account = Account.alice()

  const key = "" + Math.ceil(Math.random() * 1_000_000_00)
  const tx = sdk.tx.dataAvailability.createApplicationKey(key)
  const res = await tx.executeWaitForInclusion(account, {})
  const isOk = res.isSuccessful()

  // If the return value from `IsSuccessful` is undefined, it means that we cannot
  // determine if the transaction was successful or not.
  assert_true(isOk !== undefined)

  // If the value of `IsSuccessful()` is false then the transaction has failed.
  assert_eq(isOk, true)

  // We might have failed to decode the events so res.events could be None.
  if (res.events == undefined) throw new Error()

  const event = res.events.findFirst(Pallets.DataAvailabilityEvents.ApplicationKeyCreated)
  if (event == undefined) throw new Error()
  const appId = event.id
  console.log(`Owner: ${event.owner}, Key: ${event.keyToString()}, App Id: ${appId}`)

  const tx2 = sdk.tx.dataAvailability.submitData("My Data")
  const res2 = await tx2.executeWaitForInclusion(account, { app_id: appId })
  assert_eq(res2.isSuccessful(), true)

  // Transaction Details
  console.log(
    `Block Hash: ${res.blockHash}, Block Number: ${res.blockNumber}, Tx Hash: ${res.txHash}, Tx Index: ${res.txIndex}`,
  )

  // Events
  if (res2.events == undefined) throw new Error()
  for (const event of res.events.iter()) {
    console.log(
      `Pallet Name: ${event.palletName()}, Pallet Index: ${event.palletIndex()}, Event Name: ${event.eventName()}, Event Index: ${event.eventIndex()}, Tx Index: ${event.txIndex()}`,
    )
  }

  const event2 = res2.events.findFirst(Pallets.DataAvailabilityEvents.DataSubmitted)
  if (event2 == undefined) throw new Error()
  console.log(`Who: ${event2.who}, DataHash: ${event2.dataHash}`)

  console.log("runDataSubmission finished correctly")
}

Account

Account Creation

import { Account, cryptoWaitReady, AccountId } from "./../src/index"

export async function runAccountCreation() {
  await cryptoWaitReady()

  // Use `new` to create an account from uri
  const alice = Account.new("//Alice")
  console.log("Alice Address: ", alice.address)

  // Use `generate` to generate a random account
  const generated = Account.generate()
  console.log("Generated Address: ", generated.address)

  // There are predefined testing accounts available to be used on local dev networks.
  console.log("Alice Address: ", Account.alice().address)
  console.log("Bob Address: ", Account.bob().address)
  console.log("Charlie Address: ", Account.charlie().address)
  console.log("Eve Address: ", Account.eve().address)
  console.log("Ferdie Address: ", Account.ferdie().address)

  // SS58 address from Keyring
  console.log("SS58 address: ", alice.address)

  // Account Id from keyring, ss58 address or accountID32
  const rawAccount = alice.publicKey
  console.log("Raw Account Id: ", rawAccount)
  const accountId1 = new AccountId(rawAccount)
  console.log("Account Id SS58 address: ", accountId1.toSS58())
  const accountId2 = AccountId.fromSS58(alice.address)
  console.log("Account Id SS58 address: ", accountId2.toSS58())

  console.log("runAccountCreation finished correctly")
}

Account Nonce

import { SDK, Account, Pallets } from "./../src/index"

export async function runAccountNonce() {
  const sdk = await SDK.New(SDK.turingEndpoint)

  // Via RPC
  const nonce1 = await sdk.client.api.rpc.system.accountNextIndex("5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY")
  console.log("Nonce: ", nonce1.toNumber())

  // Via Storage RPC
  const storageAt = await sdk.client.storageAt()
  const storage = await Pallets.SystemStorage.Account.fetch(
    storageAt,
    "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
  )
  console.log("Nonce: ", storage.value.nonce)

  // Via Abstraction
  const nonce2 = await Account.nonce(sdk.client, "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY")
  console.log("Nonce: ", nonce2)

  console.log("runAccountNonce finished correctly")
}

Account Balance

import { SDK, Account, Pallets } from "./../src/index"

export async function runAccountBalance() {
  const sdk = await SDK.New(SDK.turingEndpoint)

  // Via Storage RPC
  const storageAt = await sdk.client.storageAt()
  const storage = await Pallets.SystemStorage.Account.fetch(
    storageAt,
    "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
  )
  console.log("Free Balance: ", storage.value.accountData.free.toString())
  console.log("Reserved Balance: ", storage.value.accountData.reserved.toString())
  console.log("Frozen Balance: ", storage.value.accountData.frozen.toString())

  // Via Abstraction
  const balance = await Account.balance(sdk.client, "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY")
  console.log("Free Balance: ", balance.free.toString())
  console.log("Reserved Balance: ", balance.reserved.toString())
  console.log("Frozen Balance: ", balance.frozen.toString())

  console.log("runAccountBalance finished correctly")
}

Block

All Block Transactions

import { assert_eq } from "."
import { SDK, Block, Pallets } from "./../src/index"

export async function runBlockTransactionAll() {
  const sdk = await SDK.New(SDK.turingEndpoint)

  const block = await Block.New(sdk.client, "0x94746ba186876d7407ee618d10cb6619befc59eeb173cacb00c14d1ff492fc58")
  const blockTxs = block.transactions()
  assert_eq(blockTxs.length, 9)

  // Printout Block Transactions
  for (const tx of blockTxs) {
    console.log(
      `Pallet Name: ${tx.palletName()}, Pallet Index: ${tx.palletIndex()}, Call Name: ${tx.callName()}, Call Index: ${tx.callIndex()}, Tx hash: ${tx.txHash()}, Tx Index: ${tx.txIndex()}`,
    )
  }

  // Convert from Block Transaction to Specific Transaction
  const decodedCall = blockTxs[2].decode(Pallets.DataAvailabilityCalls.SubmitData)
  if (decodedCall == undefined) throw Error()
  console.log(`Data: ${new TextDecoder().decode(decodedCall.data)}`)

  // Printout all Transaction Events
  const txEvents = blockTxs[2].events()
  if (txEvents == undefined) throw Error()
  assert_eq(txEvents.len(), 7)

  for (const event of txEvents.iter()) {
    console.log(
      `Pallet Name: ${event.palletName()}, Pallet Index: ${event.palletIndex()}, Event Name: ${event.eventName()}, Event Index: ${event.eventIndex()}, Tx Index: ${event.txIndex()}`,
    )
  }

  // Find DataSubmitted event
  const event = txEvents.findFirst(Pallets.DataAvailabilityEvents.DataSubmitted)
  if (event == undefined) throw Error()
  console.log(`Who: ${event.who}, DataHash: ${event.dataHash}`)

  console.log("runBlockTransactionAll finished correctly")
}

Block Transactions Filtered By App Id

import { assert_eq } from "."
import { SDK, Block, Pallets } from "./../src/index"

export async function runBlockTransactionByAppId() {
  const sdk = await SDK.New(SDK.turingEndpoint)

  const block = await Block.New(sdk.client, "0x94746ba186876d7407ee618d10cb6619befc59eeb173cacb00c14d1ff492fc58")
  const appId = 2
  const blockTxs = block.transactions({ appId: appId })
  assert_eq(blockTxs.length, 2)

  // Printout Block Transactions filtered By App Id
  for (const tx of blockTxs) {
    assert_eq(tx.appId(), appId)
    console.log(
      `Pallet Name: ${tx.palletName()}, Pallet Index: ${tx.palletIndex()}, Call Name: ${tx.callName()}, Call Index: ${tx.callIndex()}, Tx hash: ${tx.txHash()}, Tx Index: ${tx.txIndex()}`,
    )
  }

  // Convert from Block Transaction to Specific Transaction
  const decodedCall = blockTxs[0].decode(Pallets.DataAvailabilityCalls.SubmitData)
  if (decodedCall == undefined) throw Error()
  console.log(`Data: ${new TextDecoder().decode(decodedCall.data)}`)

  // Printout all Transaction Events
  const txEvents = blockTxs[0].events()
  if (txEvents == undefined) throw Error()
  assert_eq(txEvents.len(), 7)

  for (const event of txEvents.iter()) {
    console.log(
      `Pallet Name: ${event.palletName()}, Pallet Index: ${event.palletIndex()}, Event Name: ${event.eventName()}, Event Index: ${event.eventIndex()}, Tx Index: ${event.txIndex()}`,
    )
  }

  // Find DataSubmitted event
  const event = txEvents.findFirst(Pallets.DataAvailabilityEvents.DataSubmitted)
  if (event == undefined) throw Error()
  console.log(`Who: ${event.who}, DataHash: ${event.dataHash}`)

  console.log("runBlockTransactionByAppId finished correctly")
}

Block Transactions Filtered By Transaction Hash

import { assert_eq } from "."
import { SDK, Block, Pallets } from "./../src/index"

export async function runBlockTransactionByHash() {
  const sdk = await SDK.New(SDK.turingEndpoint)

  const block = await Block.New(sdk.client, "0x94746ba186876d7407ee618d10cb6619befc59eeb173cacb00c14d1ff492fc58")
  const txHash = "0x19c486e107c926ff4af3fa9b1d95aaba130cb0bc89515d0f5b523ef6bac06338"
  const blockTxs = block.transactions({ txHash: txHash })
  assert_eq(blockTxs.length, 1)
  const tx = blockTxs[0]

  // Printout Transaction filtered by Tx Hash
  assert_eq(tx.txHash().toString(), txHash)
  console.log(
    `Pallet Name: ${tx.palletName()}, Pallet Index: ${tx.palletIndex()}, Call Name: ${tx.callName()}, Call Index: ${tx.callIndex()}, Tx hash: ${tx.txHash()}, Tx Index: ${tx.txIndex()}`,
  )

  // Convert from Block Transaction to Specific Transaction
  const decodedCall = tx.decode(Pallets.BalancesCalls.TransferKeepAlive)
  if (decodedCall == undefined) throw Error()
  console.log(`Dest: ${decodedCall.dest.toString()}, Value: ${decodedCall.value.toString()}`)

  // Printout all Transaction Events
  const txEvents = tx.events()
  if (txEvents == undefined) throw Error()
  assert_eq(txEvents.len(), 7)

  for (const event of txEvents.iter()) {
    console.log(
      `Pallet Name: ${event.palletName()}, Pallet Index: ${event.palletIndex()}, Event Name: ${event.eventName()}, Event Index: ${event.eventIndex()}, Tx Index: ${event.txIndex()}`,
    )
  }

  // Find Transfer event
  const event = txEvents.findFirst(Pallets.BalancesEvents.Transfer)
  if (event == undefined) throw Error()
  console.log(`From: ${event.from}, To: ${event.to}, Amount: ${event.amount.toString()}`)

  console.log("runBlockTransactionByHash finished correctly")
}

Block Transactions Filtered By Transaction Index

import { assert_eq } from "."
import { SDK, Block, Pallets } from "./../src/index"

export async function runBlockTransactionByIndex() {
  const sdk = await SDK.New(SDK.turingEndpoint)

  const block = await Block.New(sdk.client, "0x94746ba186876d7407ee618d10cb6619befc59eeb173cacb00c14d1ff492fc58")
  const txIndex = 1
  const blockTxs = block.transactions({ txIndex: txIndex })
  assert_eq(blockTxs.length, 1)
  const tx = blockTxs[0]

  // Printout Transaction filtered by Tx Index
  assert_eq(tx.txIndex(), txIndex)
  console.log(
    `Pallet Name: ${tx.palletName()}, Pallet Index: ${tx.palletIndex()}, Call Name: ${tx.callName()}, Call Index: ${tx.callIndex()}, Tx hash: ${tx.txHash()}, Tx Index: ${tx.txIndex()}`,
  )

  // Convert from Block Transaction to Specific Transaction
  const decodedCall = tx.decode(Pallets.BalancesCalls.TransferKeepAlive)
  if (decodedCall == undefined) throw Error()
  console.log(`Dest: ${decodedCall.dest.toString()}, Value: ${decodedCall.value.toString()}`)

  // Printout all Transaction Events
  const txEvents = tx.events()
  if (txEvents == undefined) throw Error()
  assert_eq(txEvents.len(), 9)

  for (const event of txEvents.iter()) {
    console.log(
      `Pallet Name: ${event.palletName()}, Pallet Index: ${event.palletIndex()}, Event Name: ${event.eventName()}, Event Index: ${event.eventIndex()}, Tx Index: ${event.txIndex()}`,
    )
  }

  // Find NewAccount event
  const event = txEvents.findFirst(Pallets.SystemEvents.NewAccount)
  if (event == undefined) throw Error()
  console.log(`Account: ${event.account}`)

  console.log("runBlockTransactionByIndex finished correctly")
}

Block Transactions Filtered By Signer

import { assert_eq } from "."
import { SDK, Block, Pallets } from "./../src/index"

export async function runBlockTransactionBySigner() {
  const sdk = await SDK.New(SDK.turingEndpoint)

  const block = await Block.New(sdk.client, "0x94746ba186876d7407ee618d10cb6619befc59eeb173cacb00c14d1ff492fc58")
  const singer = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"
  const blockTxs = block.transactions({ txSigner: singer })
  assert_eq(blockTxs.length, 5)

  // Printout Block Transactions filtered By Signer
  for (const tx of blockTxs) {
    assert_eq(tx.ss58Address(), singer)
    console.log(
      `Pallet Name: ${tx.palletName()}, Pallet Index: ${tx.palletIndex()}, Call Name: ${tx.callName()}, Call Index: ${tx.callIndex()}, Tx hash: ${tx.txHash()}, Tx Index: ${tx.txIndex()}`,
    )
  }

  // Convert from Block Transaction to Specific Transaction
  const decodedCall = blockTxs[0].decode(Pallets.DataAvailabilityCalls.CreateApplicationKey)
  if (decodedCall == undefined) throw Error()
  console.log(`Key: ${new TextDecoder().decode(decodedCall.key)}`)

  // Printout all Transaction Events
  const txEvents = blockTxs[0].events()
  if (txEvents == undefined) throw Error()
  assert_eq(txEvents.len(), 7)

  for (const event of txEvents.iter()) {
    console.log(
      `Pallet Name: ${event.palletName()}, Pallet Index: ${event.palletIndex()}, Event Name: ${event.eventName()}, Event Index: ${event.eventIndex()}, Tx Index: ${event.txIndex()}`,
    )
  }

  // Find ApplicationKeyCreated event
  const event = txEvents.findFirst(Pallets.DataAvailabilityEvents.ApplicationKeyCreated)
  if (event == undefined) throw Error()
  console.log(`Owner: ${event.id}, Key: ${event.keyToString()}, App Id: ${event.id}`)

  console.log("runBlockTransactionBySigner finished correctly")
}

All Block Data Submissions

import { assert_eq } from "."
import { SDK, Block } from "./../src/index"

export async function runBlockDataSubmissionAll() {
  const sdk = await SDK.New(SDK.turingEndpoint)

  const block = await Block.New(sdk.client, "0x94746ba186876d7407ee618d10cb6619befc59eeb173cacb00c14d1ff492fc58")
  const blobs = block.dataSubmissions()
  assert_eq(blobs.length, 4)

  for (const blob of blobs) {
    console.log(
      `Tx Hash: ${blob.txHash}, Tx Index: ${blob.txIndex}, Data: ${blob.toAscii()}, App Id: ${blob.appId}, Signer: ${blob.txSigner}`,
    )
  }

  console.log("runBlockDataSubmissionAll finished correctly")
}

Block Data Submissions Filtered By App Id

import { assert_eq } from "."
import { SDK, Block } from "./../src/index"

export async function runBlockDataSubmissionByAppId() {
  const sdk = await SDK.New(SDK.turingEndpoint)

  const appId = 2
  const block = await Block.New(sdk.client, "0x94746ba186876d7407ee618d10cb6619befc59eeb173cacb00c14d1ff492fc58")
  const blobs = block.dataSubmissions({ appId: appId })
  assert_eq(blobs.length, 2)

  for (const blob of blobs) {
    assert_eq(blob.appId, appId)
    console.log(
      `Tx Hash: ${blob.txHash}, Tx Index: ${blob.txIndex}, Data: ${blob.toAscii()}, App Id: ${blob.appId}, Signer: ${blob.txSigner}`,
    )
  }

  console.log("runBlockDataSubmissionByAppId finished correctly")
}

Block Data Submissions Filtered By Transaction Hash

import { assert_eq } from "."
import { SDK, Block } from "./../src/index"

export async function runBlockDataSubmissionByHash() {
  const sdk = await SDK.New(SDK.turingEndpoint)

  const txHash = "0xe7efa71363d11bce370fe71a33e5ff296775f37507075c49316132131420f793"
  const block = await Block.New(sdk.client, "0x94746ba186876d7407ee618d10cb6619befc59eeb173cacb00c14d1ff492fc58")
  const blobs = block.dataSubmissions({ txHash: txHash })
  assert_eq(blobs.length, 1)

  for (const blob of blobs) {
    assert_eq(blob.txHash.toString(), txHash)
    console.log(
      `Tx Hash: ${blob.txHash}, Tx Index: ${blob.txIndex}, Data: ${blob.toAscii()}, App Id: ${blob.appId}, Signer: ${blob.txSigner}`,
    )
  }

  console.log("runBlockDataSubmissionByHash finished correctly")
}

Block Data Submissions Filtered By Transaction Index

import { assert_eq } from "."
import { SDK, Block } from "./../src/index"

export async function runBlockDataSubmissionByIndex() {
  const sdk = await SDK.New(SDK.turingEndpoint)

  const txIndex = 6
  const block = await Block.New(sdk.client, "0x94746ba186876d7407ee618d10cb6619befc59eeb173cacb00c14d1ff492fc58")
  const blobs = block.dataSubmissions({ txIndex: txIndex })
  assert_eq(blobs.length, 1)

  for (const blob of blobs) {
    assert_eq(blob.txIndex, txIndex)
    console.log(
      `Tx Hash: ${blob.txHash}, Tx Index: ${blob.txIndex}, Data: ${blob.toAscii()}, App Id: ${blob.appId}, Signer: ${blob.txSigner}`,
    )
  }

  console.log("runBlockDataSubmissionByIndex finished correctly")
}

Block Data Submissions Filtered By Signer

import { assert_eq } from "."
import { SDK, Block } from "./../src/index"

export async function runBlockDataSubmissionBySigner() {
  const sdk = await SDK.New(SDK.turingEndpoint)

  const txSigner = "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
  const block = await Block.New(sdk.client, "0x94746ba186876d7407ee618d10cb6619befc59eeb173cacb00c14d1ff492fc58")
  const blobs = block.dataSubmissions({ txSigner: txSigner })
  assert_eq(blobs.length, 1)

  for (const blob of blobs) {
    assert_eq(blob.txSigner, txSigner)
    console.log(
      `Tx Hash: ${blob.txHash}, Tx Index: ${blob.txIndex}, Data: ${blob.toAscii()}, App Id: ${blob.appId}, Signer: ${blob.txSigner}`,
    )
  }

  console.log("runBlockDataSubmissionBySigner finished correctly")
}

Block Events

import { assert_eq } from "."
import { SDK, Block, Pallets } from "./../src/index"

export async function runBlockEvents() {
  const sdk = await SDK.New(SDK.turingEndpoint)

  const block = await Block.New(sdk.client, "0x94746ba186876d7407ee618d10cb6619befc59eeb173cacb00c14d1ff492fc58")
  const blockEvents = block.events
  if (blockEvents == null) throw Error()
  assert_eq(blockEvents.len(), 53)

  // Printout All Block Events
  for (const event of blockEvents.iter()) {
    console.log(
      `Pallet Name: ${event.palletName()}, Pallet Index: ${event.palletIndex()}, Event Name: ${event.eventName()}, Event Index: ${event.eventIndex()}, Tx Index: ${event.txIndex()}`,
    )
  }

  // Find Transfer event
  const transferEvents = blockEvents.find(Pallets.BalancesEvents.Transfer)
  assert_eq(transferEvents.length, 2)

  for (const event of transferEvents) {
    console.log(`From: ${event.from}, To: ${event.to}, Amount: ${event.amount.toString()}`)
  }

  // Find ApplicationKeyCreated event
  const keyCreatedEvent = blockEvents.findFirst(Pallets.DataAvailabilityEvents.ApplicationKeyCreated)
  if (keyCreatedEvent == undefined) throw Error()
  console.log(`Owner: ${keyCreatedEvent.owner}, Key: ${keyCreatedEvent.keyToString()}, App Id: ${keyCreatedEvent.id}`)

  // Check
  assert_eq(blockEvents.find(Pallets.DataAvailabilityEvents.DataSubmitted).length, 4)
  assert_eq(blockEvents.find(Pallets.DataAvailabilityEvents.ApplicationKeyCreated).length, 1)

  // Events for Specific Transaction
  const txIndex = 0
  const txEvents = block.eventsForTransaction(txIndex)
  if (txEvents == undefined) throw Error()
  assert_eq(txEvents.len(), 1)

  // Printout All Tx Events
  for (const event of txEvents.iter()) {
    console.log(
      `Pallet Name: ${event.palletName()}, Pallet Index: ${event.palletIndex()}, Event Name: ${event.eventName()}, Event Index: ${event.eventIndex()}, Tx Index: ${event.txIndex()}`,
    )
  }

  // Find ExtrinsicSuccess event
  const successEvent = blockEvents.findFirst(Pallets.SystemEvents.ExtrinsicSuccess)
  if (successEvent == undefined) throw Error()
  console.log(`DispatchInfo Pays:`, successEvent.dispatchInfo.pays.toString())

  // Check
  const tx2 = block.transactions({ txIndex: txIndex })
  assert_eq(tx2.length, 1)
  const tx2Events = tx2[0].events()
  if (tx2Events == undefined) throw Error()
  assert_eq(tx2Events.len(), txEvents.len())

  console.log("runBlockEvents finished correctly")
}

Transaction

Transaction Execute

import { assert_eq } from "."
import { Account, SDK, Pallets, Watcher, WaitFor } from "./../src/index"

export async function runTransactionExecute() {
  const sdk = await SDK.New(SDK.localEndpoint)
  const account = Account.alice()

  // Transaction will be signed, and sent.
  //
  // There is no guarantee that the transaction was executed at all. It might have been
  // dropped or discarded for various reasons. The caller is responsible for querying future
  // blocks in order to determine the execution status of that transaction.
  const tx = sdk.tx.dataAvailability.submitData("My Data")
  const txhash = await tx.execute(account, { app_id: 1 })

  // Checking if the transaction was included
  //
  // It's not necessary to use the builtin watcher. A custom watcher
  // might yield better results in some cases.
  const watcher = new Watcher(sdk.client, txhash, WaitFor.BlockInclusion)
  const res = await watcher.run()
  if (res == null) throw Error()
  assert_eq(res.isSuccessful(), true)

  // Transaction Details
  console.log(
    `Block Hash: ${res.blockHash}, Block Number: ${res.blockNumber}, Tx Hash: ${res.txHash}, Tx Index: ${res.txIndex}`,
  )

  // Transaction Events
  if (res.events == undefined) throw Error()
  for (const event of res.events.iter()) {
    console.log(
      `Pallet Name: ${event.palletName()}, Pallet Index: ${event.palletIndex()}, Event Name: ${event.eventName()}, Event Index: ${event.eventIndex()}, Tx Index: ${event.txIndex()}`,
    )
  }

  // Find DataSubmitted event
  const event = res.events.findFirst(Pallets.DataAvailabilityEvents.DataSubmitted)
  if (event == undefined) throw new Error()
  console.log(`Who: ${event.who}, DataHash: ${event.dataHash}`)

  console.log("runTransactionExecute finished correctly")
}

Transaction Execute And Watch Inclusion

import { assert_eq } from "."
import { Account, SDK, Pallets } from "./../src/index"

export async function runTransactionExecuteAndWatchInclusion() {
  const sdk = await SDK.New(SDK.localEndpoint)
  const account = Account.alice()

  // Transaction will be signed, sent, and watched
  // If the transaction was dropped or never executed, the system will retry it
  // for 2 more times using the same nonce and app id.
  //
  // Waits for transaction inclusion. Most of the time you would want to call `ExecuteAndWatchFinalization` as
  // inclusion doesn't mean that the transaction will be in the canonical chain.
  const tx = sdk.tx.dataAvailability.submitData("My Data")
  const res = await tx.executeWaitForInclusion(account, { app_id: 1 })
  assert_eq(res.isSuccessful(), true)

  // Transaction Details
  console.log(
    `Block Hash: ${res.blockHash}, Block Number: ${res.blockNumber}, Tx Hash: ${res.txHash}, Tx Index: ${res.txIndex}`,
  )

  // Transaction Events
  if (res.events == undefined) throw Error()
  for (const event of res.events.iter()) {
    console.log(
      `Pallet Name: ${event.palletName()}, Pallet Index: ${event.palletIndex()}, Event Name: ${event.eventName()}, Event Index: ${event.eventIndex()}, Tx Index: ${event.txIndex()}`,
    )
  }

  // Find DataSubmitted event
  const event = res.events.findFirst(Pallets.DataAvailabilityEvents.DataSubmitted)
  if (event == undefined) throw new Error()
  console.log(`Who: ${event.who}, DataHash: ${event.dataHash}`)

  console.log("runTransactionExecuteAndWatchInclusion finished correctly")
}

Transaction Execute And Watch Finalization

import { assert_eq } from "."
import { Account, SDK, Pallets } from "./../src/index"

export async function runTransactionExecuteAndWatchFinalization() {
  const sdk = await SDK.New(SDK.localEndpoint)
  const account = Account.alice()

  // Transaction will be signed, sent, and watched
  // If the transaction was dropped or never executed, the system will retry it
  // for 2 more times using the same nonce and app id.
  //
  // Waits for transaction inclusion. Most of the time you would want to call `ExecuteAndWatchFinalization` as
  // inclusion doesn't mean that the transaction will be in the canonical chain.
  const tx = sdk.tx.dataAvailability.submitData("My Data")
  const res = await tx.executeWaitForFinalization(account, { app_id: 1 })
  assert_eq(res.isSuccessful(), true)

  // Transaction Details
  console.log(
    `Block Hash: ${res.blockHash}, Block Number: ${res.blockNumber}, Tx Hash: ${res.txHash}, Tx Index: ${res.txIndex}`,
  )

  // Transaction Events
  if (res.events == undefined) throw Error()
  for (const event of res.events.iter()) {
    console.log(
      `Pallet Name: ${event.palletName()}, Pallet Index: ${event.palletIndex()}, Event Name: ${event.eventName()}, Event Index: ${event.eventIndex()}, Tx Index: ${event.txIndex()}`,
    )
  }

  // Find DataSubmitted event
  const event = res.events.findFirst(Pallets.DataAvailabilityEvents.DataSubmitted)
  if (event == undefined) throw new Error()
  console.log(`Who: ${event.who}, DataHash: ${event.dataHash}`)

  console.log("runTransactionExecuteAndWatchFinalization finished correctly")
}

Transaction Options

import { assert_eq } from "."
import { Account, Block, SDK } from "./../src/index"

export async function runTransactionOptions() {
  await nonce()
  await app_id()
  await tip()
  await mortality()

  console.log("runTransactionOptions finished correctly")
}

export async function nonce() {
  const sdk = await SDK.New(SDK.localEndpoint)
  const account = Account.alice()
  const nonce = await Account.nonce(sdk.client, account.address)

  const tx = sdk.tx.dataAvailability.submitData("Data")
  const res = await tx.executeWaitForInclusion(account, { nonce: nonce, app_id: 1 })
  if (res.isSuccessful() !== true) throw Error()

  const block = await Block.New(sdk.client, res.blockHash)
  const blockTx = block.transactions({ txIndex: res.txIndex })
  assert_eq(blockTx.length, 1)
  assert_eq(blockTx[0].nonce(), nonce)

  console.log("runTransactionOptionsNonce finished correctly")
}

export async function app_id() {
  const sdk = await SDK.New(SDK.localEndpoint)
  const account = Account.alice()
  const appId = 5

  const tx = sdk.tx.dataAvailability.submitData("Data")
  const res = await tx.executeWaitForInclusion(account, { app_id: appId })
  if (res.isSuccessful() !== true) throw Error()

  const block = await Block.New(sdk.client, res.blockHash)
  const blockTx = block.transactions({ txIndex: res.txIndex })
  assert_eq(blockTx.length, 1)
  assert_eq(blockTx[0].appId(), appId)

  console.log("runTransactionOptionsAppId finished correctly")
}

export async function tip() {
  const sdk = await SDK.New(SDK.localEndpoint)
  const account = Account.alice()
  const tip = SDK.oneAvail()

  const tx = sdk.tx.dataAvailability.submitData("Data")
  const res = await tx.executeWaitForInclusion(account, { tip: tip })
  if (res.isSuccessful() !== true) throw Error()

  const block = await Block.New(sdk.client, res.blockHash)
  const blockTx = block.transactions({ txIndex: res.txIndex })
  assert_eq(blockTx.length, 1)
  assert_eq(blockTx[0].tip()?.toString(), tip.toString())

  console.log("runTransactionOptionsTips finished correctly")
}

export async function mortality() {
  const sdk = await SDK.New(SDK.localEndpoint)
  const account = Account.alice()
  const mortality = 16

  const tx = sdk.tx.dataAvailability.submitData("Data")
  const res = await tx.executeWaitForInclusion(account, { mortality: mortality })
  if (res.isSuccessful() !== true) throw Error()

  const block = await Block.New(sdk.client, res.blockHash)
  const blockTx = block.transactions({ txIndex: res.txIndex })
  assert_eq(blockTx.length, 1)
  assert_eq(blockTx[0].mortality()?.asMortalEra.period.toNumber(), mortality)

  console.log("runTransactionOptionsMortality finished correctly")
}

Transaction Payment

import { assert_eq } from "."
import { Account, SDK } from "./../src/index"

export async function runTransactionPayment() {
  const sdk = await SDK.New(SDK.localEndpoint)
  const account = Account.alice()
  const tx = sdk.tx.dataAvailability.submitData("0123")

  {
    // payment_query_fee_details
    const fee_details = await tx.paymentQueryFeeDetails(account.address)
    const inclusionFee = fee_details.inclusionFee
    if (inclusionFee == null) throw Error()

    console.log("Base Fee: ", inclusionFee.baseFee.toString())
    console.log("Len Fee: ", inclusionFee.lenFee.toString())
    console.log("Adjusted weight Fee: ", inclusionFee.adjustedWeightFee.toString())
    const totalFee = inclusionFee.adjustedWeightFee.add(inclusionFee.baseFee).add(inclusionFee.lenFee)
    console.log("Total Fee: ", totalFee.toString())

    // payment_query_info
    const info = await tx.paymentQueryInfo(account.address)
    console.log("Partial Fee: ", info.partialFee.toString())
    assert_eq(info.partialFee.toString(), totalFee.toString())
  }

  {
    // payment_query_call_fee_details
    const fee_details = await tx.paymentQueryCallFeeDetails()
    const inclusionFee = fee_details.inclusionFee
    if (inclusionFee == null) throw Error()

    console.log("Base Fee: ", inclusionFee.baseFee.toString())
    console.log("Len Fee: ", inclusionFee.lenFee.toString())
    console.log("Adjusted weight Fee: ", inclusionFee.adjustedWeightFee.toString())
    const totalFee = inclusionFee.adjustedWeightFee.add(inclusionFee.baseFee).add(inclusionFee.lenFee)
    console.log("Total Fee: ", totalFee.toString())

    // payment_query_call_info
    const info = await tx.paymentQueryCallInfo()
    console.log("Partial Fee: ", info.partialFee.toString())
    assert_eq(info.partialFee.toString(), totalFee.toString())
  }

  console.log("runTransactionPayment finished correctly")
}

Storage

import { assert_eq, assert_true } from "."
import { Pallets, SDK } from "./../src/index"

export async function runStorage() {
  const sdk = await SDK.New(SDK.turingEndpoint)
  const storageAt = await sdk.client.storageAt("0x9e813bb85fca217f8f3967bd4b550b05f7d559412571ca1dd621aa37343b300b")

  // Simple Storage
  {
    const value = await Pallets.StakingStorage.MinValidatorBond.fetch(storageAt)
    assert_eq(value.toString(), "100000000000000000000000")
  }

  // Simple Storage that can return null
  {
    const value = await Pallets.StakingStorage.CurrentEra.fetch(storageAt)
    assert_true(value != null && value == 301)
  }

  // Fetch Map Storage
  {
    const key = "5C869t2dWzmmYkE8NT1oocuEEdwqNnAm2XhvnuHcavNUcTTT"
    const entry = await Pallets.SystemStorage.Account.fetch(storageAt, key)
    assert_eq(entry.key.toSS58(), key)
    assert_eq(entry.value.nonce, 11)
  }

  // Fetch Map Storage 2
  {
    const key = "Reserved-3"
    const entry = await Pallets.DataAvailabilityStorage.AppKeys.fetch(storageAt, key)
    if (entry == undefined) throw Error()
    assert_eq(entry.value.appId, 3)
    assert_eq(entry.value.owner.toSS58(), "5CK87QdvhcSJvVa7ZACcEfd5i7J1GqoqbEFB2kzNn3Ms13fE")
  }

  // Fetch All Map Storage
  {
    const entires = await Pallets.DataAvailabilityStorage.AppKeys.fetchAll(storageAt)
    assert_eq(entires.length, 232)
  }

  console.log("runStorage finished correctly")
}

Batch

import { assert_eq } from "."
import { BN, SDK, Account, Pallets } from "./../src/index"

export async function runBatch() {
  const sdk = await SDK.New(SDK.localEndpoint)

  const account = Account.alice()

  const value1 = SDK.oneAvail()
  const value2 = SDK.oneAvail().mul(new BN("100000000"))
  const destBob = "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
  const destCharlie = "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y"

  const call1 = sdk.tx.balances.transferKeepAlive(destBob, value1)
  const call2 = sdk.tx.balances.transferKeepAlive(destCharlie, value1)
  const calls = [call1.tx, call2.tx]

  //
  // Happy Path
  //

  // Batch call
  {
    const tx = sdk.tx.utility.batch(calls)
    const res = await tx.executeWaitForInclusion(account, {})
    assert_eq(res.isSuccessful(), true)
    if (res.events == undefined) throw new Error("")

    const events1 = res.events.find(Pallets.UtilityEvents.BatchCompleted)
    assert_eq(events1.length, 1)

    const events2 = res.events.find(Pallets.UtilityEvents.ItemCompleted)
    assert_eq(events2.length, 2)
  }

  // Batch All call
  {
    const tx = sdk.tx.utility.batchAll(calls)
    const res = await tx.executeWaitForInclusion(account, {})
    assert_eq(res.isSuccessful(), true)
    if (res.events == undefined) throw new Error("")

    const events1 = res.events.find(Pallets.UtilityEvents.BatchCompleted)
    assert_eq(events1.length, 1)

    const events2 = res.events.find(Pallets.UtilityEvents.ItemCompleted)
    assert_eq(events2.length, 2)
  }

  // Force Batch call
  {
    const tx = sdk.tx.utility.forceBatch(calls)
    const res = await tx.executeWaitForInclusion(account, {})
    assert_eq(res.isSuccessful(), true)
    if (res.events == undefined) throw new Error("")

    const events1 = res.events.find(Pallets.UtilityEvents.BatchCompleted)
    assert_eq(events1.length, 1)

    const events2 = res.events.find(Pallets.UtilityEvents.ItemCompleted)
    assert_eq(events2.length, 2)
  }

  //
  //	Things differ when we introduce a call that will fail
  //

  const call3 = sdk.tx.balances.transferKeepAlive(destBob, value2)
  const call4 = sdk.tx.balances.transferKeepAlive(destCharlie, value1)
  calls.push(call3.tx)
  calls.push(call4.tx)

  // Batch call
  {
    const tx = sdk.tx.utility.batch(calls)
    const res = await tx.executeWaitForInclusion(account, {})
    assert_eq(res.isSuccessful(), true)
    if (res.events == undefined) throw new Error("")

    const events1 = res.events.find(Pallets.UtilityEvents.BatchInterrupted)
    assert_eq(events1.length, 1)

    const events2 = res.events.find(Pallets.UtilityEvents.BatchCompleted)
    assert_eq(events2.length, 0)

    const events3 = res.events.find(Pallets.UtilityEvents.ItemCompleted)
    assert_eq(events3.length, 2)
  }

  // Batch All call
  {
    const tx = sdk.tx.utility.batchAll(calls)
    const res = await tx.executeWaitForInclusion(account, {})
    assert_eq(res.isSuccessful(), false)
  }

  // Force Batch call
  {
    const tx = sdk.tx.utility.forceBatch(calls)
    const res = await tx.executeWaitForInclusion(account, {})
    assert_eq(res.isSuccessful(), true)
    if (res.events == undefined) throw new Error("")

    const events1 = res.events.find(Pallets.UtilityEvents.BatchCompletedWithErrors)
    assert_eq(events1.length, 1)

    const events3 = res.events.find(Pallets.UtilityEvents.ItemCompleted)
    assert_eq(events3.length, 3)

    const events2 = res.events.find(Pallets.UtilityEvents.ItemFailed)
    assert_eq(events2.length, 1)
  }

  console.log("runBatch finished correctly")
}

RPC

import { BN, SDK } from "./../src/index"

export async function runRpc() {
  await normalRpcs()
  await kateRpcs()
}

async function normalRpcs() {
  const sdk = await SDK.New(SDK.localEndpoint)

  // chain.getBlock
  const block = await sdk.client.api.rpc.chain.getBlock()
  console.log("getBlock")
  console.log(block.toJSON())
  /*
    Output
    {
      block: {
        header: {
          parentHash: '0x42670561b854f78e6a4e08d5d3f5971f6057e215467fb0684f1a2af17fe8b369',
          number: 707,
          stateRoot: '0xa32347f3ae7ae6d0c534e6cbe0b19148b5a971eb860cdd682428ecf623401a1e',
          extrinsicsRoot: '0x3c9492204d29fc822f5a046d252119f6be0236767c8b16afedfd8457eafd5ec3',
          digest: [Object],
          extension: [Object]
        },
        extrinsics: [ '0x280403000bb0037bf09301', '0x1004270b00' ]
      },
      justifications: null
    }
  */

  // chain.getBlockHash
  const hash = await sdk.client.api.rpc.chain.getBlockHash()
  console.log("getBlockHash")
  console.log(hash.toJSON())
  /*
    Output
    0x2079190e8bf27a01687b3ecdfdbbee4cc4246695b5dc3d40fdd62aa4a2b4a0be
  */

  // chain.getFinalizedHead
  const hash2 = await sdk.client.api.rpc.chain.getFinalizedHead()
  console.log("getFinalizedHead")
  console.log(hash2.toJSON())
  /*
    Output
    {
      parentHash: '0x42670561b854f78e6a4e08d5d3f5971f6057e215467fb0684f1a2af17fe8b369',
      number: 707,
      stateRoot: '0xa32347f3ae7ae6d0c534e6cbe0b19148b5a971eb860cdd682428ecf623401a1e',
      extrinsicsRoot: '0x3c9492204d29fc822f5a046d252119f6be0236767c8b16afedfd8457eafd5ec3',
      digest: { logs: [ [Object], [Object] ] },
      extension: { v3: { appLookup: [Object], commitment: [Object] } }
    }
  */

  // chain.getHeader
  const header = await sdk.client.api.rpc.chain.getHeader()
  console.log("getHeader")
  console.log(header.toJSON())
  /*
    Output
    0x1c1bdd7d76d4366c736e1c6a591fdd9f14ddef87b5ffc0fc2df4a81f3e2b00e6
  */

  // system.accountNextIndex
  const address = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"
  const nodeNonce: BN = await sdk.client.api.rpc.system.accountNextIndex(address)
  console.log("accountNextIndex")
  console.log(nodeNonce.toNumber())
  /*
    Output
    44
  */

  // system.chain
  const chain = await sdk.client.api.rpc.system.chain()
  console.log("chain")
  console.log(chain.toJSON())
  /*
    Output
    Avail Development Network
  */

  // system_chainType
  const chainType = await sdk.client.api.rpc.system.chainType()
  console.log("chainType")
  console.log(chainType.toString())
  /*
    Output
    Development
  */

  // system.health
  const health = await sdk.client.api.rpc.system.health()
  console.log("health")
  console.log(health.peers.toNumber())
  console.log(health.isSyncing.toString())
  console.log(health.shouldHavePeers.toString())
  /*
    Output
    0
    false
    false
  */

  // system.localListenAddresses
  const localListenAddresses = await sdk.client.api.rpc.system.localListenAddresses()
  console.log("localListenAddresses")
  localListenAddresses.forEach((e) => console.log(e.toString()))
  /*
    Output
    /ip6/fe80::a333:1e13:2097:7c0a/tcp/30333/p2p/12D3KooWNb38SjUDDGAJxytmPPEV1t9Fz65JTw3C87poFFdF5x3n
    /ip4/192.168.1.103/tcp/30333/p2p/12D3KooWNb38SjUDDGAJxytmPPEV1t9Fz65JTw3C87poFFdF5x3n
    /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWNb38SjUDDGAJxytmPPEV1t9Fz65JTw3C87poFFdF5x3n
    /ip6/::1/tcp/30333/p2p/12D3KooWNb38SjUDDGAJxytmPPEV1t9Fz65JTw3C87poFFdF5x3n
  */

  // system.localPeerId
  const localPeerId = await sdk.client.api.rpc.system.localPeerId()
  console.log("localPeerId")
  console.log(localPeerId.toJSON())
  /*
    Output
    12D3KooWNb38SjUDDGAJxytmPPEV1t9Fz65JTw3C87poFFdF5x3n
  */

  // system.name
  const name = await sdk.client.api.rpc.system.name()
  console.log("name")
  console.log(name.toJSON())
  /*
    Output
    Avail Node
  */

  // system.nodeRoles
  const nodeRoles = await sdk.client.api.rpc.system.nodeRoles()
  console.log("nodeRoles")
  nodeRoles.forEach((e) => console.log(e.toString()))
  /*
    Output
    Authority
  */

  // system.peers
  const peers = await sdk.client.api.rpc.system.peers()
  console.log("peers")
  peers.forEach((e) => console.log(e.toString()))
  /*
    Output
    []
  */

  // system.properties
  const properties = await sdk.client.api.rpc.system.properties()
  console.log("properties")
  console.log("isEthereum: " + properties.isEthereum.toString())
  console.log("ss58Format: " + properties.ss58Format.toString())
  if (properties.tokenDecimals.isSome) {
    properties.tokenDecimals.value.forEach((e) => console.log(e.toString()))
  }
  if (properties.tokenSymbol.isSome) {
    properties.tokenSymbol.value.forEach((e) => console.log(e.toString()))
  }
  /*
    Output
    isEthereum: false
    ss58Format: 42
    18
    AVAIL
  */

  // system.syncState
  const syncState = await sdk.client.api.rpc.system.syncState()
  console.log("syncState")
  console.log("startingBlock: " + syncState.startingBlock.toNumber())
  console.log("currentBlock: " + syncState.currentBlock.toNumber())
  if (syncState.highestBlock.isSome) {
    console.log("highestBlock:" + syncState.highestBlock.value.toNumber())
  }
  /*
    Output
    startingBlock: 0
    currentBlock: 707
    highestBlock:707
  */

  // system.version
  const version = await sdk.client.api.rpc.system.version()
  console.log("version")
  console.log("Version: " + version.toString())
  /*
    Output
    Version: 2.2.1-4f0439f4448
  */
}

async function kateRpcs() {
  const sdk = await SDK.New(SDK.turingEndpoint)

  // kate.blockLength
  const [txIndex, blockHash] = [1, "0xbb39ac467ad71293c212d3a9689226828d0c442d2e9d5e70e0bf7bc9c3a61115"]

  const blockLength = await (sdk.client.api.rpc as any).kate.blockLength(blockHash)
  console.log("blockLength")
  console.log("Normal: " + blockLength.max.normal.toNumber())
  console.log("Operational: " + blockLength.max.operational.toNumber())
  console.log("Mandatory:" + blockLength.max.mandatory.toNumber())
  console.log("Cols: " + blockLength.cols.toNumber())
  console.log("Rows: " + blockLength.rows.toNumber())
  console.log("ChunkSize: " + blockLength.chunkSize.toNumber())
  /*
    Output
    Normal: 2097152
    Operational: 2097152
    Mandatory: 2097152
    Cols: 256
    Rows: 256
    ChunkSize: 32
  */

  // kate.queryDataProof
  const dataProof = await (sdk.client.api.rpc as any).kate.queryDataProof(txIndex, blockHash)
  console.log("queryDataProof")
  console.log("DataRoot: " + dataProof.dataProof.roots.dataRoot.toString())
  console.log("BlobRoot: " + dataProof.dataProof.roots.blobRoot.toString())
  console.log("BridgeRoot: " + dataProof.dataProof.roots.bridgeRoot.toString())
  dataProof.dataProof.proof.forEach((e: any) => console.log(e))
  console.log("NumberOfLeaves: " + dataProof.dataProof.numberOfLeaves.toNumber())
  console.log("LeafIndex: " + dataProof.dataProof.leafIndex.toNumber())
  console.log("Leaf: " + dataProof.dataProof.leaf.toString())
  console.log("Message: " + dataProof.message.toString())
  /*
    Output
    DataRoot: 0xd6e516bbf0b0d964a6a6a41a18c58a2eac4757001c2338a8601c4cc961332fda
    BlobRoot: 0x29c73490baca9fe2b11095a69294de4b4a86bcb3a2eb3cd04b51dfdd0b4030f9
    BridgeRoot: 0x0000000000000000000000000000000000000000000000000000000000000000
    NumberOfLeaves: 1
    LeafIndex: 0
    Leaf: 0x47a59a7805e0bfe350ee0395d426c15770edc03fee72aa6532b5bbcffaf28030
    Message: 
  */

  // kate.queryProof
  const cell = [[0, 0]]
  const proof = await (sdk.client.api.rpc as any).kate.queryProof(cell, blockHash)
  console.log("proof")
  proof.forEach((e: any) => e.forEach((g: any) => console.log(g.toString())))
  /*
    Output
    2178534751726990040338027377623275511556638494274780568875624948149315822336
    0xb7be11461735c1c52a96c3319def842092b51b54142d1e7e6f307cade9b3966897e8b8499e1c2fe9f3213c337560e5bb
  */

  // kate.queryRows
  const rows = [0]
  const rowsResult = await (sdk.client.api.rpc as any).kate.queryRows(rows, blockHash)
  console.log("queryRows")
  rowsResult.forEach((e: any) => e.forEach((g: any) => console.log(g.toString())))
  /*
    Output
    2178534751726990040338027377623275511556638494274780568875624948149315822336
    69809044805081050561184934886915677873289200296740001199394424254799507156224
    4352252970560996938972626135851379325521790154040731149679347419805560005632
    104879959288272688727650528319334922080558860381160795517508406844350550507520
  */
}

Validator

import { SDK, Account, Pallets, BN } from "./../src/index"

export async function runValidator() {
  const sdk = await SDK.New(SDK.localEndpoint)
  const account = Account.generate()

  // Min Bond Value
  const storageAt = await sdk.client.storageAt()
  let minValidatorBond = await Pallets.StakingStorage.MinValidatorBond.fetch(storageAt)
  minValidatorBond = minValidatorBond.add(SDK.oneAvail())

  // Fund Random Account
  {
    const tx = sdk.tx.balances.transferKeepAlive(account.address, minValidatorBond.add(SDK.oneAvail().mul(new BN(10))))
    const res = await tx.executeWaitForInclusion(Account.alice(), {})
    const isOk = res.isSuccessful()
    if (isOk == undefined || isOk == false) throw Error()
  }

  // Bond
  {
    const tx = sdk.tx.staking.bond(minValidatorBond, "Staked")
    const res = await tx.executeWaitForInclusion(account, {})
    const isOk = res.isSuccessful()
    if (isOk == undefined || isOk == false) throw Error()
  }

  // Generate Session Keys
  const sessionKeys = await sdk.client.rotateKeys()

  // Set Session Keys
  {
    const tx = sdk.tx.session.setKeys(sessionKeys, new Uint8Array())
    const res = await tx.executeWaitForInclusion(account, {})
    const isOk = res.isSuccessful()
    if (isOk == undefined || isOk == false) throw Error()
  }

  // Validate
  {
    const tx = sdk.tx.staking.validate(50, false)
    const res = await tx.executeWaitForInclusion(account, {})
    const isOk = res.isSuccessful()
    if (isOk == undefined || isOk == false) throw Error()
  }

  console.log("runValidator finished correctly")
}

Proxy

import { Account, Pallets, SDK, AccountId } from "./../src/index"
import { assert_eq } from "."

export async function runProxy() {
  await runProxyNormal()
  await runProxyPure()
  await runProxyFailure()

  console.log("runProxy finished correctly")
}

export async function runProxyNormal() {
  const sdk = await SDK.New(SDK.localEndpoint)

  const proxyAccount = Account.bob()
  const mainAccount = Account.ferdie()

  // Creating Proxy
  {
    const tx = sdk.tx.proxy.addProxy(proxyAccount.address, "Any", 0)
    const res = await tx.executeWaitForInclusion(mainAccount, {})
    assert_eq(res.isSuccessful(), true)
    if (res.events == undefined) throw Error()

    const event = res.events.findFirst(Pallets.ProxyEvents.ProxyAdded)
    if (event == undefined) throw Error()
    console.log(
      `Delegatee: ${event.delegatee.toSS58()}, Delegator: ${event.delegator.toSS58()}, ProxyType: ${event.proxyType.toString()}, Delay: ${event.delay}`,
    )
  }

  // Executing the Proxy.Proxy() call
  {
    const call = sdk.tx.balances.transferKeepAlive(proxyAccount.address, SDK.oneAvail()).tx
    const tx = sdk.tx.proxy.proxy(mainAccount.address, null, call)
    const res = await tx.executeWaitForInclusion(proxyAccount, {})
    assert_eq(res.isSuccessful(), true)
    if (res.events == undefined) throw Error()

    const event = res.events.findFirst(Pallets.ProxyEvents.ProxyExecuted)
    if (event == undefined) throw Error()
    assert_eq(event.result.variantIndex, 0)
    console.log(`Result: ${event.result.toString()}`)
  }

  // Removing Proxy
  {
    const tx = sdk.tx.proxy.removeProxy(proxyAccount.address, "Any", 0)
    const res = await tx.executeWaitForInclusion(mainAccount, {})
    assert_eq(res.isSuccessful(), true)
    if (res.events == undefined) throw Error()

    const event = res.events.findFirst(Pallets.ProxyEvents.ProxyRemoved)
    if (event == undefined) throw Error()
    console.log(
      `Delegatee: ${event.delegatee.toSS58()}, Delegator: ${event.delegator.toSS58()}, ProxyType: ${event.proxyType.toString()}, Delay: ${event.delay}`,
    )
  }

  console.log("runProxyNormal finished correctly")
}

export async function runProxyPure() {
  const sdk = await SDK.New(SDK.localEndpoint)
  const mainAccount = Account.bob()

  const proxyType = "Any"
  const index = 0
  let proxyAccountId: AccountId

  // Creating Pure Proxy
  {
    const tx = sdk.tx.proxy.createPure(proxyType, 0, index)
    const res = await tx.executeWaitForInclusion(mainAccount, {})
    assert_eq(res.isSuccessful(), true)
    if (res.events == undefined) throw Error()

    const event = res.events.findFirst(Pallets.ProxyEvents.PureCreated)
    if (event == undefined) throw Error()
    console.log(
      `Pure: ${event.pure.toSS58()}, Who: ${event.who.toSS58()}, ProxyType: ${event.proxyType.toString()}, Index: ${event.disambiguationIndex}`,
    )
    proxyAccountId = event.pure
  }

  // Executing the Proxy.Proxy() call
  {
    const key = "" + Math.ceil(Math.random() * 1_000_000_00)
    const call = sdk.tx.dataAvailability.createApplicationKey(key).tx
    const tx = sdk.tx.proxy.proxy(proxyAccountId, null, call)
    const res = await tx.executeWaitForInclusion(mainAccount, {})
    assert_eq(res.isSuccessful(), true)
    if (res.events == undefined) throw Error()

    const event = res.events.findFirst(Pallets.ProxyEvents.ProxyExecuted)
    if (event == undefined) throw Error()
    assert_eq(event.result.variantIndex, 0)
    console.log(`Result: ${event.result.toString()}`)
  }

  console.log("runProxyPure finished correctly")
}

export async function runProxyFailure() {
  const sdk = await SDK.New(SDK.localEndpoint)

  const proxyAccount = Account.bob()
  const mainAccount = Account.ferdie()

  // Creating Proxy
  {
    const tx = sdk.tx.proxy.addProxy(proxyAccount.address, "NonTransfer", 0)
    const res = await tx.executeWaitForInclusion(mainAccount, {})
    assert_eq(res.isSuccessful(), true)
    if (res.events == undefined) throw Error()
  }

  // Executing the Proxy.Proxy() call
  {
    const call = sdk.tx.balances.transferKeepAlive(proxyAccount.address, SDK.oneAvail()).tx
    const tx = sdk.tx.proxy.proxy(mainAccount.address, null, call)
    const res = await tx.executeWaitForInclusion(proxyAccount, {})
    assert_eq(res.isSuccessful(), true)
    if (res.events == undefined) throw Error()

    const event = res.events.findFirst(Pallets.ProxyEvents.ProxyExecuted)
    if (event == undefined) throw Error()
    assert_eq(event.result.variantIndex, 1)
    console.log(`Result: ${event.result.toString()}`)
  }

  // Removing Proxy
  {
    const tx = sdk.tx.proxy.removeProxy(proxyAccount.address, "NonTransfer", 0)
    const res = await tx.executeWaitForInclusion(mainAccount, {})
    assert_eq(res.isSuccessful(), true)
    if (res.events == undefined) throw Error()
  }

  console.log("runProxyFailure finished correctly")
}

Multisig

import { assert_eq } from "."
import { SDK, BN, KeyringPair, TransactionDetails, utils, Account, Metadata, Pallets } from "./../src/index"

export async function runMultisig() {
  const sdk = await SDK.New(SDK.localEndpoint)

  // Multisig Signatures
  const [alice, bob, charlie] = [Account.alice(), Account.bob(), Account.charlie()]

  // Create Multisig Account
  const threshold = 3
  const multisigAddress = utils.generateMultisig([alice.address, bob.address, charlie.address], threshold)
  await fundMultisigAccount(sdk, alice, multisigAddress)

  // Define what action will be taken by the multisig account
  const amount = SDK.oneAvail()
  const call = sdk.tx.balances.transferKeepAlive(multisigAddress, amount)
  // Data needed for multisig approval and execution
  const callHash = call.tx.method.hash.toString()
  const callData = call.tx.unwrap().toHex()
  const maxWeight = (await call.paymentQueryCallInfo()).weight

  /*
      The first signature creates and approves the multisig transaction. All the next signatures (besides the last one) should 
      use the `nextApproval` function to approve the tx. The last signature should use the `lastApproval` function to approve
      and execute the multisig tx.
  
      In practice it means the following:
      - If the threshold is 2 do the following:
        - firstApproval
        - lastApproval
      - If the threshold is 4 do the following:
        - firstApproval
        - nextApproval
        - nextApproval
        - lastApproval
    */

  // Create New Multisig
  const call1signatures = utils.sortMultisigAddresses([bob.address, charlie.address])
  const firstResult = await firstApproval(sdk, alice, threshold, call1signatures, callHash, maxWeight)
  {
    const event = firstResult.events?.findFirst(Pallets.MultisigEvents.NewMultisig)
    if (event == undefined) throw Error()
    console.log(
      `Approving: ${event.approving.toSS58()}, Multisig: ${event.multisig.toSS58()}, Call Hash: ${event.callHash.toHex()}`,
    )
  }

  // Approve existing Multisig
  const timepoint: Metadata.TimepointBlocknumber = { height: firstResult.blockNumber, index: firstResult.txIndex }
  const call2signatures = utils.sortMultisigAddresses([alice.address, charlie.address])
  const secondResult = await nextApproval(sdk, bob, threshold, call2signatures, timepoint, callHash, maxWeight)

  {
    const event = secondResult.events?.findFirst(Pallets.MultisigEvents.MultisigApproval)
    if (event == undefined) throw Error()
    console.log(
      `Approving: ${event.approving.toSS58()}, Timepoint Height: ${event.timepoint.height}, Timepoint Index: ${event.timepoint.index}, Multisig: ${event.multisig.toSS58()}, Call Hash: ${event.callHash.toHex()}`,
    )
  }

  // Execute Multisig
  const call3signatures = utils.sortMultisigAddresses([alice.address, bob.address])
  const thirdResult = await lastApproval(sdk, charlie, threshold, call3signatures, timepoint, callData, maxWeight)

  {
    const event = thirdResult.events?.findFirst(Pallets.MultisigEvents.MultisigExecuted)
    if (event == undefined) throw Error()
    assert_eq(event.result.variantIndex, 0)
    console.log(
      `Approving: ${event.approving.toSS58()}, Timepoint Height: ${event.timepoint.height}, Timepoint Index: ${event.timepoint.index}, Multisig: ${event.multisig.toSS58()}, Call Hash: ${event.callHash.toHex()}, Result: ${event.result.toString()}`,
    )
  }

  console.log("runMultisig finished correctly")
}

async function fundMultisigAccount(sdk: SDK, alice: KeyringPair, multisigAddress: string): Promise<string> {
  console.log("Funding multisig account...")
  const amount = SDK.oneAvail().mul(new BN(100)) // 100 Avail
  const tx = sdk.tx.balances.transferKeepAlive(multisigAddress, amount)
  const res = await tx.executeWaitForInclusion(alice, {})
  assert_eq(res.isSuccessful(), true)
  if (res.events == undefined) throw Error()

  return multisigAddress
}

async function firstApproval(
  sdk: SDK,
  account: KeyringPair,
  threshold: number,
  otherSignatures: string[],
  callHash: string,
  maxWeight: Metadata.Weight,
): Promise<TransactionDetails> {
  console.log("Alice is creating a Multisig Transaction...")

  const tx = sdk.tx.multisig.approveAsMulti(threshold, otherSignatures, null, callHash, maxWeight)
  const res = await tx.executeWaitForInclusion(account, {})
  assert_eq(res.isSuccessful(), true)
  if (res.events == undefined) throw Error()

  return res
}

async function nextApproval(
  sdk: SDK,
  account: KeyringPair,
  threshold: number,
  otherSignatures: string[],
  timepoint: Metadata.TimepointBlocknumber,
  callHash: string,
  maxWeight: Metadata.Weight,
): Promise<TransactionDetails> {
  console.log("Bob is approving the existing Multisig Transaction...")

  const tx = sdk.tx.multisig.approveAsMulti(threshold, otherSignatures, timepoint, callHash, maxWeight)
  const res = await tx.executeWaitForInclusion(account, {})
  assert_eq(res.isSuccessful(), true)
  if (res.events == undefined) throw Error()

  return res
}

async function lastApproval(
  sdk: SDK,
  account: KeyringPair,
  threshold: number,
  otherSignatures: string[],
  timepoint: Metadata.TimepointBlocknumber,
  callData: string,
  maxWeight: Metadata.Weight,
): Promise<TransactionDetails> {
  console.log("Charlie is approving and executing the existing Multisig Transaction...")

  const tx = sdk.tx.multisig.asMulti(threshold, otherSignatures, timepoint, callData, maxWeight)
  const res = await tx.executeWaitForInclusion(account, {})
  assert_eq(res.isSuccessful(), true)
  if (res.events == undefined) throw Error()

  return res
}

Transaction State

import { assert_eq } from "."
import { Account, Metadata, SDK } from "./../src/index"

export async function runTransactionState() {
  const sdk = await SDK.New(SDK.localEndpoint)
  const account = Account.alice()

  const tx = sdk.tx.dataAvailability.submitData("My Data")
  const txhash = await tx.execute(account, { app_id: 1 })

  let states: Metadata.TransactionState[] = []
  while (true) {
    states = await sdk.client.transactionState(txhash)
    if (states.length != 0) {
      break
    }

    await sleep(1_000)
  }

  assert_eq(states.length, 1)
  for (const state of states) {
    console.log(
      `Block Hash: ${state.blockHash.toHuman()}, Block Height: ${state.blockHeight}, Tx Hash: ${state.txHash.toHuman()}, Tx Index: ${state.txIndex}`,
    )
    console.log(
      `Pallet Index: ${state.palletIndex}, Call Index: ${state.callIndex}, Tx Successful: ${state.txSuccess}, Is Finalized: ${state.isFinalized}`,
    )
  }

  console.log("runTransactionState finished correctly")
}

function sleep(ms: number) {
  return new Promise((resolve) => setTimeout(resolve, ms))
}

Indexer

import { SDK, Block, H256, UnsubscribePromise } from "./../src/index"

export async function runIndexer() {
  const sdk = await SDK.New(SDK.turingEndpoint)
  const indexer = new Indexer(sdk)
  indexer.run(Kind.Manual)

  // Fetching blocks in procedural way
  const sub = await indexer.subscribe()
  for (let i = 0; i < 3; i++) {
    const block = await sub.fetch()
    console.log(`Current: Block Height: ${block.height}, Block Hash: ${block.hash}`)
  }

  // Fetching historical blocks
  sub.blockHeight = sub.blockHeight - 100
  for (let i = 0; i < 3; i++) {
    const block = await sub.fetch()
    console.log(`Historical: Block Height: ${block.height}, Block Hash: ${block.hash}`)
  }

  // Callback
  const sub2 = await indexer.callback(callback)
  await sleep(25000)

  sub2.stop()
  await indexer.stop()
}

async function callback(block: IndexedBlock) {
  console.log(`Callback: Block Height: ${block.height}, Block Hash: ${block.hash}`)
}

interface IndexedBlock {
  hash: H256
  height: number
  block: Block
}

enum Kind {
  Manual,
  Stream,
}

class Indexer {
  sdk: SDK
  block: IndexedBlock | null
  unsub: UnsubscribePromise | null
  shutdown: boolean

  constructor(sdk: SDK) {
    this.sdk = sdk
    this.block = null
    this.unsub = null
    this.shutdown = false
  }

  public async run(kind: Kind) {
    if (this.unsub != null) {
      return
    }

    if (kind == Kind.Manual) {
      console.log("Manual")
      this.taskManual()
    } else if (kind == Kind.Stream) {
      console.log("Stream")
      this.taskStream()
    }
  }

  public async taskManual() {
    new Promise(() => {
      ;(async () => {
        for (;;) {
          if (this.shutdown) {
            return
          }

          const hash = await this.sdk.client.finalizedBlockHash()
          if (this.block != null && this.block.hash == hash) {
            await sleep(15000)
            continue
          }

          const height = await this.sdk.client.blockNumber(hash)
          const block = await Block.New(this.sdk.client, hash)
          this.block = { hash: hash, height: height, block }
        }
      })()
    })
  }

  public async taskStream() {
    const unsub = this.sdk.client.api.rpc.chain.subscribeFinalizedHeads(async (header) => {
      const height = header.number.toNumber()
      const hash = await this.sdk.client.blockHash(header.number.toNumber())
      const block = await Block.New(this.sdk.client, hash)

      this.block = { hash: hash, height: height, block }
    })

    this.unsub = unsub
  }

  public async getBlock(blockHeight: number): Promise<IndexedBlock> {
    for (;;) {
      if (this.block == null) {
        await sleep(1000)
        continue
      }
      const block = this.block

      if (this.shutdown) {
        return block
      }

      if (blockHeight > block.height) {
        await sleep(15000)
        continue
      }

      if (blockHeight == block.height) {
        return { ...block }
      }

      const oldHash = await this.sdk.client.blockHash(blockHeight)
      const oldBlock = await Block.New(this.sdk.client, oldHash)

      return { hash: oldHash, height: blockHeight, block: oldBlock }
    }
  }

  public async subscribe(): Promise<Subscription> {
    for (;;) {
      if (this.block == null) {
        await sleep(1000)
        continue
      }

      return new Subscription(this, this.block.height)
    }
  }

  public async callback(fn: (arg0: IndexedBlock) => Promise<void>): Promise<Subscription> {
    const sub = await this.subscribe()

    new Promise(() => {
      ;(async () => {
        for (;;) {
          const block = await sub.fetch()
          if (sub.state.shutdown == true) {
            return
          }

          await fn(block)
        }
      })()
    })

    return sub
  }

  public async stop() {
    this.shutdown = true
    if (this.unsub != null) {
      ;(await this.unsub)()
    }
    this.unsub = null
  }
}

class Subscription {
  private indexer: Indexer
  blockHeight: number
  state: { shutdown: boolean }

  constructor(indexer: Indexer, blockHeight: number) {
    this.indexer = indexer
    this.blockHeight = blockHeight
    this.state = { shutdown: false }
  }

  public async fetch(): Promise<IndexedBlock> {
    let block = this.indexer.getBlock(this.blockHeight)
    this.blockHeight += 1
    return block
  }

  public stop() {
    this.state.shutdown = true
  }
}

function sleep(ms: number) {
  return new Promise((resolve) => setTimeout(resolve, ms))
}