Radiant SDK: Build Radiant dapps in TypeScript

@radiant-core/sdk v0.1.0 Last Updated: June 2026

1. What Is the Radiant SDK?

@radiant-core/sdk is the clean TypeScript SDK most web and app developers reach for first. It lets you build Radiant (RXD) dapps — wallets, marketplaces, games, payment flows — without reading internal wallet or library source. It wraps radiantjs (the low-level tx/script library) and adds the ecosystem-specific pieces app devs actually need.

SDK vs. radiantjs. radiantjs is the low-level engine (keys, raw transactions, scripts, signing). @radiant-core/sdk is the application layer built on top of it (networking, token-safe funding, Glyph, WAVE, units). You install only the SDK — radiantjs comes along as a dependency and you never touch its API directly.

2. Installation

npm install @radiant-core/sdk
# Node < 22 has no global WebSocket — also install the optional peer:
npm install ws

Requires Node 20.19+ or 22+ (radiantjs pulls in an ESM-only dependency that needs require(ESM) support). Ships dual ESM + CJS with bundled types.

Units. Every amount in the SDK is in photons as a BigInt1 RXD = 100,000,000 photons. Convert only at your UI edge with rxdToPhotons() / photonsToRxd(). Never do balance math in floating point.

3. Connect & Read Balances

The ElectrumClient speaks JSON-RPC over a single reconnecting WebSocket. Scripthash methods accept a plain address (the scripthash is computed for you).

import { ElectrumClient, photonsToRxd } from '@radiant-core/sdk';

const client = new ElectrumClient({ network: 'mainnet' });
await client.connect();

const address = '1Yourradiantaddress...';
const { confirmed, unconfirmed } = await client.getBalance(address);
console.log(`Confirmed: ${photonsToRxd(confirmed)} RXD`);

const utxos = await client.listUnspent(address); // Utxo[] (photons as BigInt)

// React to incoming payments:
await client.subscribe(address, (status) => {
  console.log('address changed:', status); // re-fetch balance/UTXOs here
});

The default mainnet endpoint is wss://electrumx.radiantcore.org:443; pass endpoint to point at your own ElectrumX/RXinDexer.

4. Wallets & Keys

Create or restore a BIP39 HD wallet. Derivation defaults to the Radiant path m/44'/512'/account'/0/index.

import { HDWallet } from '@radiant-core/sdk';

// New wallet
const mnemonic = HDWallet.generateMnemonic();
const wallet = HDWallet.fromMnemonic(mnemonic, { network: 'mainnet' });

const me = wallet.deriveKey(0);   // m/44'/512'/0'/0/0
console.log(me.path, me.address, me.scriptHash);

// Batch derive a gap of receive addresses
const receive = wallet.deriveRange(0, 20);   // DerivedKey[]

5. Sending RXD (Ref-Safe)

The single most important safety property of the SDK: funding is never gathered by a value heuristic. A UTXO that carries a token ref (FT/NFT/dMint) looks like plain value to a naive selector, but spending it as funding burns the token. selectRxdFunding screens every candidate two ways — indexer-reported refs and a local script scan — and silently excludes token UTXOs.

import { ElectrumClient, HDWallet, buildRxdTransfer, rxdToPhotons } from '@radiant-core/sdk';

const client = new ElectrumClient({ network: 'mainnet' });
const wallet = HDWallet.fromMnemonic(mnemonic);
const me = wallet.deriveKey(0);

const utxos = await client.listUnspent(me.address);

const { hex, txid } = buildRxdTransfer({
  address: me.address,
  wif: me.wif,
  to: '1Recipient...',
  amount: rxdToPhotons('1.25'), // 1.25 RXD -> photons
  utxos,                        // token-bearing UTXOs are auto-excluded
  feeRate: 10_000n,             // photons/byte (mainnet min-relay)
});

await client.broadcastTx(hex);
console.log('sent', txid);
Why this matters. On Radiant, tokens live in ordinary-looking UTXOs guarded by ref opcodes. Spend one as fee/change and the token is gone — irreversibly. If you select inputs yourself, always filter with filterFundingCandidates(utxos) or guard with assertFundingSafe(utxos) first.

6. Glyph Tokens

Mint and move Glyph tokens with the commit/reveal pattern handled for you. Fund from token-free UTXOs.

import { mintFT, mintNFT, transferToken, filterFundingCandidates } from '@radiant-core/sdk';

const funding = filterFundingCandidates(await client.listUnspent(me.address));

// Fungible token (FT amount == output photons)
const ft = await mintFT({
  client, address: me.address, wif: me.wif,
  ticker: 'DEMO',
  supply: 1_000_000n,
  metadata: { name: 'Demo Token', desc: 'Minted with @radiant-core/sdk' },
  fundingUtxos: funding,
});
console.log('FT ref:', ft.refDisplay, ft.commitTxid, ft.revealTxid);

// Non-fungible token (singleton)
const nft = await mintNFT({
  client, address: me.address, wif: me.wif,
  metadata: { name: 'My NFT', attrs: { rarity: 'rare' } },
  fundingUtxos: funding,
});

// Transfer a token (FT or NFT) to a new owner
await transferToken({
  client, address: me.address, wif: me.wif,
  tokenUtxo,                 // the FT/NFT UTXO (must include its on-chain script)
  toAddress: '1Recipient...',
  fundingUtxos: funding,     // covers the fee; token value is conserved
});
Finding your tokens. The indexer keys a token UTXO under scriptHash(zeroRefs(tokenScript)), not the owner's plain address. To list a held token, query client.listUnspent(scriptHash(zeroRefs(ftScript(owner, ref)))) — the entries come back with refs:[{ ref, type }] (type is "normal" for FT, "single" for an NFT singleton).
Test on regtest first. mintFT / mintNFT / transferToken broadcast real, irreversible transactions. They reproduce the proven Photonic-Wallet on-chain templates and are regtest-validated, but you should smoke-test your own flow on regtest/testnet before mainnet.

7. WAVE Names

Resolve WAVE names to addresses through the public indexer.

import { waveResolve, waveResolveAddress } from '@radiant-core/sdk';

const rec = await waveResolve('alice');        // "alice.rxd" works too
if (rec.registered) console.log(rec.address, rec.owner, rec.expires);

const addr = await waveResolveAddress('alice'); // string | null

8. API Overview

AreaExports
ClientElectrumClient
WalletHDWallet, Keys
FundingselectRxdFunding, filterFundingCandidates, isFundingSafe, assertFundingSafe, estimateFee, sumValue
TransactionsbuildRxdTransfer, buildTx
TokensmintFT, mintNFT, transferToken, encodeGlyph, ftScript, nftScript, parseTokenRef
WAVEwaveResolve, waveResolveAddress, waveLabel
ScriptscriptHash, addressToScriptHash, p2pkhScript, isTokenBearing, zeroRefs, packRef, unpackRef
UnitsrxdToPhotons, photonsToRxd
ErrorsRadiantSdkError, InsufficientFundsError, TokenBurnGuardError, ElectrumError, ValidationError

Full reference (every export, options, and return types) is in docs/API.md.

9. Notes & Links

Validated end-to-end. The SDK ships with unit tests (CI on Node 20/22/24), on-chain consensus validation against a radiantd regtest node (FT/NFT mint + transfer accepted), and indexer validation against RXinDexer/ElectrumX (tokens surfaced via listUnspent with their refs).

Fee policy. Mainnet min-relay is 10,000 photons/byte; testnet/regtest is 1,000. The SDK sets the fee from the measured signed transaction size, so token transactions reliably clear the floor.

ResourceLink
npm package@radiant-core/sdk
Source & issuesgithub.com/Radiant-Core/radiant-sdk
API referencedocs/API.md
Low-level libraryradiantjs
Related guidesDeveloper Guide · Token Creation · WAVE Names