@radiant-core/sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +230 -0
- package/dist/index.cjs +1064 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +693 -0
- package/dist/index.d.ts +693 -0
- package/dist/index.js +1015 -0
- package/dist/index.js.map +1 -0
- package/package.json +71 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Radiant Core
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# @radiant-core/sdk
|
|
2
|
+
|
|
3
|
+
A clean TypeScript SDK for building [Radiant (RXD)](https://radiantcore.org) dapps — without reading internal Photonic/radiantjs source.
|
|
4
|
+
|
|
5
|
+
It wraps [`@radiant-core/radiantjs`](https://www.npmjs.com/package/@radiant-core/radiantjs) (the low‑level tx/script library) and gives you the primitives most web/app developers actually need: an ElectrumX client, **ref‑safe** UTXO selection that never burns tokens, Glyph token mint/transfer, WAVE name resolution, and SLIP‑0044 HD wallets.
|
|
6
|
+
|
|
7
|
+
- 🔌 **ElectrumX WebSocket client** — balance, UTXOs, broadcast, subscribe, auto‑reconnect with backoff
|
|
8
|
+
- 🛡️ **Ref‑safe funding** — token‑bearing UTXOs are *never* spent as RXD funding (no silent token burns)
|
|
9
|
+
- 🪙 **Glyph tokens** — mint FT/NFT and transfer via the commit/reveal pattern
|
|
10
|
+
- 🌊 **WAVE names** — resolve `alice` → address
|
|
11
|
+
- 🔑 **HD wallets** — `m/44'/512'/0'/0/k` (Radiant coin type 512, the v3.0.0+ default)
|
|
12
|
+
- 📦 **Dual ESM + CJS**, tree‑shakeable, TypeScript types included
|
|
13
|
+
- 🔢 **Photons as `BigInt`** everywhere internally, with RXD helpers at the edge
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @radiant-core/sdk
|
|
17
|
+
# radiantjs is a peer of the token/wallet APIs; install it too:
|
|
18
|
+
npm install @radiant-core/radiantjs
|
|
19
|
+
# On Node < 22 (no global WebSocket), also:
|
|
20
|
+
npm install ws
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
> **Units.** The base unit is the *photon*. `1 RXD = 100,000,000 photons`. All
|
|
24
|
+
> amounts inside the SDK are `BigInt` photons. Use `rxdToPhotons()` /
|
|
25
|
+
> `photonsToRxd()` only at your UI/input boundary — never do balance math in
|
|
26
|
+
> floating point.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Quickstart
|
|
31
|
+
|
|
32
|
+
### Connect and read a balance
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { ElectrumClient, photonsToRxd } from "@radiant-core/sdk";
|
|
36
|
+
|
|
37
|
+
const client = new ElectrumClient({ network: "mainnet" });
|
|
38
|
+
await client.connect();
|
|
39
|
+
|
|
40
|
+
const address = "1Yourradiantaddress...";
|
|
41
|
+
const { confirmed, unconfirmed } = await client.getBalance(address);
|
|
42
|
+
console.log(`Confirmed: ${photonsToRxd(confirmed)} RXD`);
|
|
43
|
+
|
|
44
|
+
const utxos = await client.listUnspent(address); // Utxo[] (photons as BigInt)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Create / restore an HD wallet
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { HDWallet } from "@radiant-core/sdk";
|
|
51
|
+
|
|
52
|
+
// New wallet
|
|
53
|
+
const mnemonic = HDWallet.generateMnemonic();
|
|
54
|
+
const wallet = HDWallet.fromMnemonic(mnemonic, { network: "mainnet" });
|
|
55
|
+
|
|
56
|
+
// Address #0 at m/44'/512'/0'/0/0
|
|
57
|
+
const acct0 = wallet.deriveKey(0);
|
|
58
|
+
console.log(acct0.path); // m/44'/512'/0'/0/0
|
|
59
|
+
console.log(acct0.address); // base58 address
|
|
60
|
+
console.log(acct0.scriptHash); // ElectrumX scripthash
|
|
61
|
+
|
|
62
|
+
// Batch derive a gap of receive addresses
|
|
63
|
+
const receive = wallet.deriveRange(0, 20); // DerivedKey[]
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Send RXD (ref‑safe funding)
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { ElectrumClient, HDWallet, buildRxdTransfer, rxdToPhotons } from "@radiant-core/sdk";
|
|
70
|
+
|
|
71
|
+
const client = new ElectrumClient({ network: "mainnet" });
|
|
72
|
+
const wallet = HDWallet.fromMnemonic(mnemonic);
|
|
73
|
+
const me = wallet.deriveKey(0);
|
|
74
|
+
|
|
75
|
+
const utxos = await client.listUnspent(me.address);
|
|
76
|
+
|
|
77
|
+
const { hex, txid } = buildRxdTransfer({
|
|
78
|
+
address: me.address,
|
|
79
|
+
wif: me.wif,
|
|
80
|
+
to: "1Recipient...",
|
|
81
|
+
amount: rxdToPhotons("1.25"), // 1.25 RXD -> photons
|
|
82
|
+
utxos, // token‑bearing UTXOs are auto‑excluded
|
|
83
|
+
feeRate: 10_000n, // photons/byte (mainnet min‑relay)
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
await client.broadcastTx(hex);
|
|
87
|
+
console.log("sent", txid);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Ref‑safe selection, explicitly
|
|
91
|
+
|
|
92
|
+
The single most important safety property: **funding is never gathered by a
|
|
93
|
+
value heuristic.** A UTXO that carries a token ref (FT/NFT/dMint) looks like
|
|
94
|
+
plain value to a naive selector, but spending it as funding *burns the token*.
|
|
95
|
+
`selectRxdFunding` screens every candidate two ways — indexer‑reported `refs`
|
|
96
|
+
and a local script scan (`isTokenBearing`) — and throws `TokenBurnGuardError`
|
|
97
|
+
rather than risk a burn.
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
import { selectRxdFunding, filterFundingCandidates, isTokenBearing } from "@radiant-core/sdk";
|
|
101
|
+
|
|
102
|
+
const safe = filterFundingCandidates(allUtxos); // drops anything token‑bearing
|
|
103
|
+
const sel = selectRxdFunding(allUtxos, rxdToPhotons("0.5"), 10_000n);
|
|
104
|
+
console.log(sel.inputs, sel.fee, sel.change);
|
|
105
|
+
|
|
106
|
+
isTokenBearing(scriptHex); // true if the script has an OP_PUSHINPUTREF opcode
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Mint a Glyph token
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { mintFT, mintNFT, filterFundingCandidates } from "@radiant-core/sdk";
|
|
113
|
+
|
|
114
|
+
const funding = filterFundingCandidates(await client.listUnspent(me.address));
|
|
115
|
+
|
|
116
|
+
// Fungible token (FT amount == output photons)
|
|
117
|
+
const ft = await mintFT({
|
|
118
|
+
client,
|
|
119
|
+
address: me.address,
|
|
120
|
+
wif: me.wif,
|
|
121
|
+
ticker: "DEMO",
|
|
122
|
+
supply: 1_000_000n,
|
|
123
|
+
metadata: { name: "Demo Token", desc: "Minted with @radiant-core/sdk" },
|
|
124
|
+
fundingUtxos: funding,
|
|
125
|
+
});
|
|
126
|
+
console.log("FT ref:", ft.refDisplay, ft.commitTxid, ft.revealTxid);
|
|
127
|
+
|
|
128
|
+
// Non‑fungible token (singleton)
|
|
129
|
+
const nft = await mintNFT({
|
|
130
|
+
client,
|
|
131
|
+
address: me.address,
|
|
132
|
+
wif: me.wif,
|
|
133
|
+
metadata: { name: "My NFT", attrs: { rarity: "rare" } },
|
|
134
|
+
fundingUtxos: funding,
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Transfer a token
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
import { transferToken } from "@radiant-core/sdk";
|
|
142
|
+
|
|
143
|
+
// `tokenUtxo` must include its on‑chain `script` (the token output script).
|
|
144
|
+
await transferToken({
|
|
145
|
+
client,
|
|
146
|
+
address: me.address,
|
|
147
|
+
wif: me.wif,
|
|
148
|
+
tokenUtxo, // the FT/NFT UTXO to move
|
|
149
|
+
toAddress: "1Recipient...",
|
|
150
|
+
fundingUtxos: funding, // covers the fee only; token value is conserved
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Resolve a WAVE name
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import { waveResolve, waveResolveAddress } from "@radiant-core/sdk";
|
|
158
|
+
|
|
159
|
+
const rec = await waveResolve("alice"); // "alice.rxd" works too (suffix stripped)
|
|
160
|
+
if (rec.registered) console.log(rec.address, rec.owner, rec.expires);
|
|
161
|
+
|
|
162
|
+
const addr = await waveResolveAddress("alice"); // string | null
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Subscribe to address activity
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
const status = await client.subscribe(me.address, (newStatus) => {
|
|
169
|
+
console.log("address changed:", newStatus); // re‑fetch UTXOs/balance here
|
|
170
|
+
});
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## API surface
|
|
176
|
+
|
|
177
|
+
| Area | Exports |
|
|
178
|
+
| --- | --- |
|
|
179
|
+
| Client | `ElectrumClient` |
|
|
180
|
+
| Wallet | `HDWallet`, `Keys` |
|
|
181
|
+
| Funding | `selectRxdFunding`, `filterFundingCandidates`, `isFundingSafe`, `estimateFee`, `sumValue` |
|
|
182
|
+
| Tx | `buildTx`, `buildRxdTransfer` |
|
|
183
|
+
| Tokens | `mintFT`, `mintNFT`, `transferToken`, `encodeGlyph`, `ftScript`, `nftScript`, `parseTokenRef` |
|
|
184
|
+
| WAVE | `waveResolve`, `waveResolveAddress`, `waveLabel` |
|
|
185
|
+
| Script | `scriptHash`, `addressToScriptHash`, `p2pkhScript`, `isTokenBearing`, `zeroRefs`, `packRef`, `unpackRef` |
|
|
186
|
+
| Units | `rxdToPhotons`, `photonsToRxd` |
|
|
187
|
+
| Errors | `RadiantSdkError`, `InsufficientFundsError`, `TokenBurnGuardError`, `ElectrumError`, `ValidationError` |
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Design notes
|
|
192
|
+
|
|
193
|
+
- **radiantjs is wrapped, not duplicated.** All key/tx/script work delegates to
|
|
194
|
+
`@radiant-core/radiantjs`; the SDK adds BigInt photons, ref‑safety, the
|
|
195
|
+
ElectrumX transport, and Glyph/WAVE conveniences. The raw library is available
|
|
196
|
+
via the `radiantjs` export if you need an escape hatch.
|
|
197
|
+
- **Fee rate.** Mainnet min‑relay is `10,000` photons/byte (since the V2 upgrade
|
|
198
|
+
at block 410,000); testnet/regtest is `1,000`. These are exposed as
|
|
199
|
+
`MIN_RELAY_FEE_RATE` and used as defaults — pin them, don't tune them.
|
|
200
|
+
`buildTx` sets the fee from the *measured signed transaction size* (not an
|
|
201
|
+
estimate), so token transactions carrying a CBOR envelope reliably clear the
|
|
202
|
+
node's min‑relay floor. Funding selection reserves a little extra so a
|
|
203
|
+
tightly‑funded wallet still has enough inputs; any surplus returns as change.
|
|
204
|
+
- **Endpoints.** The public mainnet ElectrumX is `wss://electrumx.radiantcore.org:443`
|
|
205
|
+
(TLS on :443 only). WAVE resolution defaults to `https://radiantcore.org/api`.
|
|
206
|
+
Both are overridable.
|
|
207
|
+
|
|
208
|
+
> ✅ **Mint/transfer flows are regtest‑validated.** `mintFT` / `mintNFT` /
|
|
209
|
+
> `transferToken` reproduce the proven Photonic‑Wallet on‑chain templates and
|
|
210
|
+
> have been run end‑to‑end against a real `radiantd` regtest node — commit +
|
|
211
|
+
> reveal accepted, outputs match `ftScript`/`nftScript` and carry the ref, FT
|
|
212
|
+
> amount and singleton ref preserved across transfers. They still broadcast
|
|
213
|
+
> real, irreversible transactions, so smoke‑test your own flow on
|
|
214
|
+
> regtest/testnet before mainnet.
|
|
215
|
+
|
|
216
|
+
## Building from source
|
|
217
|
+
|
|
218
|
+
Requires Node 20.19+ or 22+ (`require(ESM)` support; radiantjs pulls in an
|
|
219
|
+
ESM-only dependency).
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
npm install
|
|
223
|
+
npm run build # tsup -> dist/ (ESM + CJS + d.ts)
|
|
224
|
+
npm run typecheck # tsc --noEmit
|
|
225
|
+
npm test # node --test against the built bundle
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## License
|
|
229
|
+
|
|
230
|
+
MIT
|