QubicTypeScript
Guides

Send a QU transfer

Build, sign, and broadcast a QU transfer in four steps using @qubic.org/wallet and @qubic.org/rpc.

This guide walks through the minimum code needed to transfer QU from one identity to another. The same pattern applies to any transfer — only the destination and amount change.

Prerequisites

Install the required packages:

bun add @qubic.org/wallet @qubic.org/rpc @qubic.org/types
npm install @qubic.org/wallet @qubic.org/rpc @qubic.org/types
pnpm add @qubic.org/wallet @qubic.org/rpc @qubic.org/types

Steps

Create a wallet from a seed

A wallet holds your identity and signs transactions. Pass a 55-character lowercase seed string.

import { createWallet } from "@qubic.org/wallet"

const wallet = createWallet("your_seed_here_aaaaaa...")
console.log("Identity:", wallet.identity)

Never hard-code a real seed in source code. Read it from an environment variable or a secrets manager.

Connect to the network and fetch the current tick

The target tick determines when the transaction is valid. Set it a few ticks ahead of the current tick to give nodes time to process.

import { createLiveClient } from "@qubic.org/rpc"

const live = createLiveClient()
const { tick } = await live.getTickInfo()

By default createLiveClient connects to the public Qubic RPC gateway.

Build and sign the transaction

buildTransfer returns { encoded, hash }. encoded is the signed transaction bytes ready to broadcast; hash is the canonical transaction hash.

import { toIdentity } from "@qubic.org/types"

const destination = toIdentity("CFBMEMZOIDEXQAUXYYSZIURADQLAPWPMNJXQSNVQZAHYVOPYUKKJBJUCTVJL")

const { encoded, hash } = await wallet.buildTransfer({
  destination,
  amount: 1_000_000n,       // amount in QU (bigint)
  targetTick: tick + 5,     // ~5 ticks ahead
  currentTick: tick,
})

console.log("TX hash:", hash)

amount is a bigint. Use n suffix literals (100_000n) or BigInt("100000").

Broadcast

const result = await live.broadcastTransaction(encoded)
console.log(`Broadcast to ${result.peersBroadcastedTo} peers`)

broadcastTransaction throws QubicRpcError on network failure. The node does not confirm inclusion at this point — you need to query the tick's transactions after the target tick passes to confirm.

Complete example

transfer.ts
import { createWallet } from "@qubic.org/wallet"
import { createLiveClient } from "@qubic.org/rpc"
import { toIdentity } from "@qubic.org/types"

const live = createLiveClient()
const wallet = createWallet(process.env.SEED!)

const { tick } = await live.getTickInfo()

const destination = toIdentity("CFBMEMZOIDEXQAUXYYSZIURADQLAPWPMNJXQSNVQZAHYVOPYUKKJBJUCTVJL")

const { encoded, hash } = await wallet.buildTransfer({
  destination,
  amount: 1_000_000n,
  targetTick: tick + 5,
  currentTick: tick,
})

const result = await live.broadcastTransaction(encoded)
console.log(`TX hash: ${hash}`)
console.log(`Broadcast to ${result.peersBroadcastedTo} peers`)

Run it:

SEED=your_seed bun transfer.ts

Confirming the transaction

After the target tick has passed, query the archive to confirm inclusion:

import { createQueryClient } from "@qubic.org/rpc"

const archive = createQueryClient()
const tx = await archive.getTransaction(hash)

console.log("Included in tick:", tx.tickNumber)
console.log("Status:", tx.transactionStatus)

getTransaction throws if the transaction is not found or the archive hasn't indexed the tick yet.

Common errors

ErrorCauseFix
QubicRpcError on broadcastGateway unreachable or malformed transactionCheck the seed and amount; retry with a new tick
toIdentity throwsDestination string has wrong length or invalid charactersVerify the 60-character uppercase identity string
Transaction not confirmedTarget tick already passed when broadcast was sentFetch a fresh tick and try again

On this page