@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/dist/index.d.cts
ADDED
|
@@ -0,0 +1,693 @@
|
|
|
1
|
+
/** Shared public types for the Radiant SDK. */
|
|
2
|
+
/** Supported Radiant networks. */
|
|
3
|
+
type NetworkName = "mainnet" | "testnet" | "regtest";
|
|
4
|
+
/**
|
|
5
|
+
* A reference carried by a token output. Reported by ElectrumX `listunspent`
|
|
6
|
+
* in display form ("txid:vout"). Any UTXO that carries refs is token-bearing
|
|
7
|
+
* and must NEVER be used as discretionary RXD funding.
|
|
8
|
+
*/
|
|
9
|
+
interface UtxoRef {
|
|
10
|
+
/** Display-order ref, "txid:vout". */
|
|
11
|
+
ref: string;
|
|
12
|
+
/** Indexer-classified type, e.g. "nft" | "ft" | "dmint". */
|
|
13
|
+
type: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A spendable output. `value` is in photons (BigInt). `script` is the output
|
|
17
|
+
* scriptPubKey as hex — required for ref-safety analysis and signing.
|
|
18
|
+
*/
|
|
19
|
+
interface Utxo {
|
|
20
|
+
/** Transaction id in display (big-endian) order. */
|
|
21
|
+
txid: string;
|
|
22
|
+
/** Output index. */
|
|
23
|
+
vout: number;
|
|
24
|
+
/** Value in photons. */
|
|
25
|
+
value: bigint;
|
|
26
|
+
/** Output scriptPubKey, hex. */
|
|
27
|
+
script: string;
|
|
28
|
+
/** Confirmation height; 0 (or undefined) means unconfirmed/mempool. */
|
|
29
|
+
height?: number;
|
|
30
|
+
/** Token refs attached to this output, if any (from the indexer). */
|
|
31
|
+
refs?: UtxoRef[];
|
|
32
|
+
}
|
|
33
|
+
/** A transaction output to be created. `value` is in photons. */
|
|
34
|
+
interface TxOutput {
|
|
35
|
+
/** Output scriptPubKey, hex. */
|
|
36
|
+
script: string;
|
|
37
|
+
/** Value in photons. */
|
|
38
|
+
value: bigint;
|
|
39
|
+
}
|
|
40
|
+
/** Result of a ref-safe funding selection. */
|
|
41
|
+
interface FundingSelection {
|
|
42
|
+
/** Chosen funding inputs (all guaranteed token-free). */
|
|
43
|
+
inputs: Utxo[];
|
|
44
|
+
/** Estimated fee in photons for the resulting transaction. */
|
|
45
|
+
fee: bigint;
|
|
46
|
+
/** Sum of selected input values, photons. */
|
|
47
|
+
total: bigint;
|
|
48
|
+
/** Change left over after target + fee, photons (>= 0). */
|
|
49
|
+
change: bigint;
|
|
50
|
+
}
|
|
51
|
+
/** ElectrumX scripthash balance reply. */
|
|
52
|
+
interface ScriptHashBalance {
|
|
53
|
+
/** Confirmed balance in photons. */
|
|
54
|
+
confirmed: bigint;
|
|
55
|
+
/** Unconfirmed (mempool) delta in photons; may be negative. */
|
|
56
|
+
unconfirmed: bigint;
|
|
57
|
+
}
|
|
58
|
+
/** Resolved WAVE name record. */
|
|
59
|
+
interface WaveResolution {
|
|
60
|
+
/** Normalised bare label that was resolved. */
|
|
61
|
+
name: string;
|
|
62
|
+
/** Whether the name is registered. */
|
|
63
|
+
registered: boolean;
|
|
64
|
+
/** Resolution target address, if the name resolves to one. */
|
|
65
|
+
address?: string;
|
|
66
|
+
/** Packed ref of the canonical registration, if any. */
|
|
67
|
+
ref?: string;
|
|
68
|
+
/** Owner scripthash hex, if known. */
|
|
69
|
+
owner?: string;
|
|
70
|
+
/** Expiry (unix seconds) from the zone record, if set. */
|
|
71
|
+
expires?: number;
|
|
72
|
+
/** Raw zone records (free-form). */
|
|
73
|
+
records?: Record<string, unknown>;
|
|
74
|
+
/** The unparsed indexer payload, for advanced callers. */
|
|
75
|
+
raw: unknown;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Typed error classes so callers can branch on failure modes. */
|
|
79
|
+
/** Base class for every error thrown by the SDK. */
|
|
80
|
+
declare class RadiantSdkError extends Error {
|
|
81
|
+
constructor(message: string);
|
|
82
|
+
}
|
|
83
|
+
/** Thrown when a request cannot be funded from the available UTXO set. */
|
|
84
|
+
declare class InsufficientFundsError extends RadiantSdkError {
|
|
85
|
+
readonly requiredPhotons: bigint;
|
|
86
|
+
readonly availablePhotons: bigint;
|
|
87
|
+
constructor(requiredPhotons: bigint, availablePhotons: bigint);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Thrown when a token-bearing UTXO is about to be spent as discretionary RXD
|
|
91
|
+
* funding — doing so would silently burn the token. This is the SDK's primary
|
|
92
|
+
* safety backstop.
|
|
93
|
+
*/
|
|
94
|
+
declare class TokenBurnGuardError extends RadiantSdkError {
|
|
95
|
+
readonly txid: string;
|
|
96
|
+
readonly vout: number;
|
|
97
|
+
constructor(txid: string, vout: number);
|
|
98
|
+
}
|
|
99
|
+
/** Thrown for ElectrumX transport/protocol failures. */
|
|
100
|
+
declare class ElectrumError extends RadiantSdkError {
|
|
101
|
+
readonly code?: number | undefined;
|
|
102
|
+
constructor(message: string, code?: number | undefined);
|
|
103
|
+
}
|
|
104
|
+
/** Thrown when an input/argument is malformed. */
|
|
105
|
+
declare class ValidationError extends RadiantSdkError {
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Network constants, default endpoints, and protocol parameters.
|
|
110
|
+
*
|
|
111
|
+
* Sources of truth (verified against the Radiant ecosystem, 2026-06):
|
|
112
|
+
* - Min-relay fee: 10,000 photons/byte on mainnet since the V2 upgrade
|
|
113
|
+
* (block 410,000). Testnet/regtest use 1,000. Pin these; do not "tune" them.
|
|
114
|
+
* - HD coin type: SLIP-0044 512 (Radiant), default since radiantjs v3.0.0.
|
|
115
|
+
* - Public ElectrumX is reachable on :443 only (Caddy TLS terminates to the
|
|
116
|
+
* indexer). 50010-50012 are firewalled off the public host.
|
|
117
|
+
* - WAVE/Glyph REST lives behind https://radiantcore.org/api.
|
|
118
|
+
*/
|
|
119
|
+
|
|
120
|
+
/** Base unit of Radiant. 1 RXD = 100,000,000 photons. */
|
|
121
|
+
declare const PHOTONS_PER_RXD = 100000000n;
|
|
122
|
+
/** SLIP-0044 registered coin type for Radiant. */
|
|
123
|
+
declare const RADIANT_COIN_TYPE = 512;
|
|
124
|
+
/**
|
|
125
|
+
* Min-relay fee rate in photons per byte, keyed by network.
|
|
126
|
+
* Mainnet = 10,000 since the V2 upgrade (block 410,000).
|
|
127
|
+
*/
|
|
128
|
+
declare const MIN_RELAY_FEE_RATE: Record<NetworkName, bigint>;
|
|
129
|
+
/**
|
|
130
|
+
* Dust limit in photons. Outputs below this are non-standard. Token-carrying
|
|
131
|
+
* outputs typically ride at exactly the dust value.
|
|
132
|
+
*/
|
|
133
|
+
declare const DUST_LIMIT = 1000n;
|
|
134
|
+
/** Default public ElectrumX WebSocket endpoints, keyed by network. */
|
|
135
|
+
declare const DEFAULT_ELECTRUM_ENDPOINT: Record<NetworkName, string>;
|
|
136
|
+
/** Default RXinDexer REST base used for WAVE name resolution. */
|
|
137
|
+
declare const DEFAULT_REST_BASE = "https://radiantcore.org/api";
|
|
138
|
+
/** Glyph protocol identifiers (the `p` field of a payload). */
|
|
139
|
+
declare const GLYPH_PROTOCOL: {
|
|
140
|
+
readonly FT: 1;
|
|
141
|
+
readonly NFT: 2;
|
|
142
|
+
readonly MUTABLE: 5;
|
|
143
|
+
readonly CONTAINER: 7;
|
|
144
|
+
readonly ENCRYPTED: 8;
|
|
145
|
+
readonly WAVE: 11;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Photon <-> RXD conversion helpers.
|
|
150
|
+
*
|
|
151
|
+
* Internally the SDK uses photons as BigInt everywhere (1 RXD = 100,000,000
|
|
152
|
+
* photons). These helpers exist for display/input at the application edge.
|
|
153
|
+
* Never do balance math in floating point — use the BigInt photon value.
|
|
154
|
+
*/
|
|
155
|
+
/** Number of decimal places in a whole RXD (8). */
|
|
156
|
+
declare const RXD_DECIMALS = 8;
|
|
157
|
+
/**
|
|
158
|
+
* Convert an RXD amount to photons (BigInt). Accepts a number or a decimal
|
|
159
|
+
* string; the string form avoids float rounding for large/precise amounts.
|
|
160
|
+
*
|
|
161
|
+
* @example rxdToPhotons("1.5") === 150_000_000n
|
|
162
|
+
*/
|
|
163
|
+
declare function rxdToPhotons(rxd: string | number): bigint;
|
|
164
|
+
/**
|
|
165
|
+
* Convert photons (BigInt) to a fixed-point RXD string with 8 decimals,
|
|
166
|
+
* trailing zeros trimmed (but at least one decimal kept).
|
|
167
|
+
*
|
|
168
|
+
* @example photonsToRxd(150_000_000n) === "1.5"
|
|
169
|
+
*/
|
|
170
|
+
declare function photonsToRxd(photons: bigint): string;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Script-level primitives: scripthash computation (ElectrumX convention),
|
|
174
|
+
* token-bearing detection, zero-ref normalisation, and ref packing.
|
|
175
|
+
*
|
|
176
|
+
* These mirror the proven Photonic-Wallet implementations. They are pure and
|
|
177
|
+
* dependency-light (only radiantjs for hashing / address->script).
|
|
178
|
+
*/
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* ElectrumX scripthash: sha256(scriptBytes) reversed, hex.
|
|
182
|
+
* This is the key ElectrumX uses to index an output; it is NOT a txid order.
|
|
183
|
+
*/
|
|
184
|
+
declare function scriptHash(scriptHex: string): string;
|
|
185
|
+
/**
|
|
186
|
+
* Build a P2PKH output script (hex) for an address. The script is
|
|
187
|
+
* network-independent — only the 20-byte pubkey hash matters — so the address
|
|
188
|
+
* is decoded by its version byte without imposing a network (this also avoids
|
|
189
|
+
* the testnet/regtest ambiguity, where both share version byte 0x6f). The
|
|
190
|
+
* `network` parameter is accepted for call-site symmetry but not required.
|
|
191
|
+
*/
|
|
192
|
+
declare function p2pkhScript(address: string, _network?: NetworkName): string;
|
|
193
|
+
/** Convenience: ElectrumX scripthash for a plain (P2PKH) address. */
|
|
194
|
+
declare function addressToScriptHash(address: string, network?: NetworkName): string;
|
|
195
|
+
/**
|
|
196
|
+
* Returns true if a script carries a Glyph token, i.e. it contains an
|
|
197
|
+
* OP_PUSHINPUTREF-family opcode (0xd0-0xd8) in *opcode position*.
|
|
198
|
+
*
|
|
199
|
+
* Critically, this walks the script as an opcode stream and skips push
|
|
200
|
+
* payloads, so a 0xd0-0xd8 byte that merely appears inside a pubkey hash or a
|
|
201
|
+
* data push does NOT trigger a false positive. Spending such a UTXO as
|
|
202
|
+
* discretionary RXD funding would burn the token, so funding selection relies
|
|
203
|
+
* on this check.
|
|
204
|
+
*/
|
|
205
|
+
declare function isTokenBearing(scriptHex: string): boolean;
|
|
206
|
+
/**
|
|
207
|
+
* Zero out the 36-byte operands of OP_PUSHINPUTREF-family opcodes, but only if
|
|
208
|
+
* the script also requires a signature (CHECKSIG). This reproduces how the
|
|
209
|
+
* indexer keys token-gated covenant scripts: a covenant is indexed under its
|
|
210
|
+
* zeroed-ref form, so to look up its UTXOs you must hash scriptHash(zeroRefs(s))
|
|
211
|
+
* rather than the raw script. Plain (non-checksig) ref scripts are returned
|
|
212
|
+
* unchanged.
|
|
213
|
+
*/
|
|
214
|
+
declare function zeroRefs(scriptHex: string): string;
|
|
215
|
+
/**
|
|
216
|
+
* Pack an outpoint into a 36-byte Glyph ref (72 hex chars): 32-byte txid in
|
|
217
|
+
* internal (little-endian) order followed by a 4-byte little-endian vout.
|
|
218
|
+
* This is the form consumed by OP_PUSHINPUTREF <ref>.
|
|
219
|
+
*/
|
|
220
|
+
declare function packRef(txid: string, vout: number): string;
|
|
221
|
+
/** Inverse of packRef: unpack a 72-hex ref into display "txid:vout". */
|
|
222
|
+
declare function unpackRef(ref: string): {
|
|
223
|
+
txid: string;
|
|
224
|
+
vout: number;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* ElectrumX WebSocket client.
|
|
229
|
+
*
|
|
230
|
+
* Speaks JSON-RPC 2.0 over a single wss connection, with automatic reconnect
|
|
231
|
+
* (exponential backoff + jitter), per-request timeouts, and scripthash
|
|
232
|
+
* subscriptions. Isomorphic: uses the global `WebSocket` in browsers / modern
|
|
233
|
+
* Node, and lazily imports the `ws` package on older Node.
|
|
234
|
+
*
|
|
235
|
+
* High-level helpers return SDK types (photons as BigInt). All scripthash
|
|
236
|
+
* methods also accept a plain address for convenience.
|
|
237
|
+
*/
|
|
238
|
+
|
|
239
|
+
/** A minimal structural type for the WebSocket implementations we accept. */
|
|
240
|
+
interface MinimalWebSocket {
|
|
241
|
+
send(data: string): void;
|
|
242
|
+
close(): void;
|
|
243
|
+
addEventListener(type: string, listener: (ev: any) => void): void;
|
|
244
|
+
readonly readyState: number;
|
|
245
|
+
}
|
|
246
|
+
type WebSocketCtor = new (url: string) => MinimalWebSocket;
|
|
247
|
+
/** Options for {@link ElectrumClient}. */
|
|
248
|
+
interface ElectrumClientOptions {
|
|
249
|
+
/** Full wss/ws endpoint. Overrides `network`'s default if given. */
|
|
250
|
+
endpoint?: string;
|
|
251
|
+
/** Network whose default endpoint to use when `endpoint` is omitted. */
|
|
252
|
+
network?: NetworkName;
|
|
253
|
+
/** Per-request timeout in ms. Default 15,000. */
|
|
254
|
+
requestTimeoutMs?: number;
|
|
255
|
+
/** Auto-reconnect on close. Default true. */
|
|
256
|
+
reconnect?: boolean;
|
|
257
|
+
/** Inject a WebSocket constructor (tests, custom transports). */
|
|
258
|
+
webSocketCtor?: WebSocketCtor;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Connect-on-demand ElectrumX client.
|
|
262
|
+
*
|
|
263
|
+
* @example
|
|
264
|
+
* const client = new ElectrumClient({ network: "mainnet" });
|
|
265
|
+
* await client.connect();
|
|
266
|
+
* const bal = await client.getBalance(address);
|
|
267
|
+
*/
|
|
268
|
+
declare class ElectrumClient {
|
|
269
|
+
readonly endpoint: string;
|
|
270
|
+
private readonly requestTimeoutMs;
|
|
271
|
+
private readonly autoReconnect;
|
|
272
|
+
private readonly injectedCtor?;
|
|
273
|
+
private ws?;
|
|
274
|
+
private ctor?;
|
|
275
|
+
private nextId;
|
|
276
|
+
private readonly pending;
|
|
277
|
+
private readonly subscriptions;
|
|
278
|
+
private connectPromise?;
|
|
279
|
+
private reconnectAttempts;
|
|
280
|
+
private closedByUser;
|
|
281
|
+
constructor(options?: ElectrumClientOptions);
|
|
282
|
+
/** True if the socket is open and ready. */
|
|
283
|
+
get connected(): boolean;
|
|
284
|
+
/** Open the connection (idempotent). Resolves once the socket is ready. */
|
|
285
|
+
connect(): Promise<void>;
|
|
286
|
+
private resolveCtor;
|
|
287
|
+
private openSocket;
|
|
288
|
+
private onMessage;
|
|
289
|
+
private onClose;
|
|
290
|
+
/** Exponential backoff with full jitter, capped at RECONNECT_MAX_MS. */
|
|
291
|
+
private nextReconnectDelay;
|
|
292
|
+
/** Send a JSON-RPC request and await its result. */
|
|
293
|
+
request<T = unknown>(method: string, ...params: unknown[]): Promise<T>;
|
|
294
|
+
/** Negotiate protocol version. */
|
|
295
|
+
serverVersion(client?: string, protocol?: [string, string] | string): Promise<unknown>;
|
|
296
|
+
private toScriptHash;
|
|
297
|
+
/** Confirmed + unconfirmed balance (photons) for an address or scripthash. */
|
|
298
|
+
getBalance(addressOrScriptHash: string): Promise<ScriptHashBalance>;
|
|
299
|
+
/**
|
|
300
|
+
* Unspent outputs for an address or scripthash, as SDK {@link Utxo}s.
|
|
301
|
+
*
|
|
302
|
+
* NOTE: ElectrumX `listunspent` does not return the output script. When you
|
|
303
|
+
* pass a plain address we fill `script` with that address's P2PKH script
|
|
304
|
+
* (correct for ordinary wallet UTXOs). When you pass a raw scripthash we
|
|
305
|
+
* cannot reconstruct the script, so `script` is left empty — provide the
|
|
306
|
+
* address form if you intend to fund/sign from the result.
|
|
307
|
+
*/
|
|
308
|
+
listUnspent(addressOrScriptHash: string): Promise<Utxo[]>;
|
|
309
|
+
/** Raw transaction history for an address or scripthash. */
|
|
310
|
+
getHistory(addressOrScriptHash: string): Promise<unknown[]>;
|
|
311
|
+
/** Fetch a raw transaction (hex, or verbose object when verbose=true). */
|
|
312
|
+
getTransaction(txid: string, verbose?: boolean): Promise<unknown>;
|
|
313
|
+
/**
|
|
314
|
+
* Subscribe to an address/scripthash; `onUpdate` fires with the new status
|
|
315
|
+
* hash whenever the set of outputs changes. Returns the current status.
|
|
316
|
+
*/
|
|
317
|
+
subscribe(addressOrScriptHash: string, onUpdate: (status: string | null) => void): Promise<string | null>;
|
|
318
|
+
/** Stop receiving updates for a scripthash/address. */
|
|
319
|
+
unsubscribe(addressOrScriptHash: string): Promise<unknown>;
|
|
320
|
+
/**
|
|
321
|
+
* Broadcast a raw transaction (hex). Returns the txid. Treats the node's
|
|
322
|
+
* "transaction already in blockchain" as success (returns the computed txid
|
|
323
|
+
* is the caller's job; here we surface the node's reply).
|
|
324
|
+
*/
|
|
325
|
+
broadcastTx(rawHex: string): Promise<string>;
|
|
326
|
+
/** Close the connection and stop reconnecting. */
|
|
327
|
+
close(): void;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* HD key derivation for Radiant.
|
|
332
|
+
*
|
|
333
|
+
* Default path: m/44'/512'/account'/change/index — SLIP-0044 coin type 512,
|
|
334
|
+
* the radiantjs v3.0.0+ default. The legacy coin-type-0 path is opt-in.
|
|
335
|
+
*
|
|
336
|
+
* The wallet derives keys; it never talks to the network. Combine it with
|
|
337
|
+
* {@link ElectrumClient} and the tx builders to move funds.
|
|
338
|
+
*/
|
|
339
|
+
|
|
340
|
+
/** Options when constructing an {@link HDWallet}. */
|
|
341
|
+
interface HDWalletOptions {
|
|
342
|
+
/** Network for address encoding. Default "mainnet". */
|
|
343
|
+
network?: NetworkName;
|
|
344
|
+
/** BIP39 passphrase ("25th word"). Default "". */
|
|
345
|
+
passphrase?: string;
|
|
346
|
+
/** Hardened account index. Default 0. */
|
|
347
|
+
account?: number;
|
|
348
|
+
/**
|
|
349
|
+
* SLIP-0044 coin type. Default 512 (Radiant). Pass 0 only to recover legacy
|
|
350
|
+
* wallets created before the coin-type-512 default.
|
|
351
|
+
*/
|
|
352
|
+
coinType?: number;
|
|
353
|
+
}
|
|
354
|
+
/** A derived key bundle for one address index. */
|
|
355
|
+
interface DerivedKey {
|
|
356
|
+
index: number;
|
|
357
|
+
change: number;
|
|
358
|
+
path: string;
|
|
359
|
+
/** WIF private key. */
|
|
360
|
+
wif: string;
|
|
361
|
+
/** Compressed public key, hex. */
|
|
362
|
+
publicKey: string;
|
|
363
|
+
/** Base58Check address. */
|
|
364
|
+
address: string;
|
|
365
|
+
/** ElectrumX scripthash for this address. */
|
|
366
|
+
scriptHash: string;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* BIP44 HD wallet over a single account.
|
|
370
|
+
*
|
|
371
|
+
* @example
|
|
372
|
+
* const wallet = HDWallet.fromMnemonic(mnemonic, { network: "mainnet" });
|
|
373
|
+
* const { address, wif } = wallet.deriveKey(0);
|
|
374
|
+
*/
|
|
375
|
+
declare class HDWallet {
|
|
376
|
+
private readonly root;
|
|
377
|
+
readonly network: NetworkName;
|
|
378
|
+
readonly account: number;
|
|
379
|
+
readonly coinType: number;
|
|
380
|
+
private constructor();
|
|
381
|
+
/** Create a wallet from a BIP39 mnemonic phrase. */
|
|
382
|
+
static fromMnemonic(phrase: string, options?: HDWalletOptions): HDWallet;
|
|
383
|
+
/** Create a wallet from a raw seed (Buffer or hex string). */
|
|
384
|
+
static fromSeed(seed: Buffer | string, options?: HDWalletOptions): HDWallet;
|
|
385
|
+
/** Create a wallet from an extended private key (xprv). */
|
|
386
|
+
static fromXprv(xprv: string, options?: HDWalletOptions): HDWallet;
|
|
387
|
+
/** Generate a fresh random mnemonic phrase (BIP39, 12 words). */
|
|
388
|
+
static generateMnemonic(): string;
|
|
389
|
+
private static fromMaster;
|
|
390
|
+
/** Full derivation path for a given change/index under this account. */
|
|
391
|
+
pathFor(index: number, change?: number): string;
|
|
392
|
+
/** radiantjs PrivateKey at the given index (default external chain). */
|
|
393
|
+
privateKey(index: number, change?: number): any;
|
|
394
|
+
/** Derive a full key bundle (WIF, pubkey, address, scripthash) at an index. */
|
|
395
|
+
deriveKey(index: number, change?: number): DerivedKey;
|
|
396
|
+
/** Address at an index (external chain by default). */
|
|
397
|
+
address(index?: number, change?: number): string;
|
|
398
|
+
/** WIF private key at an index. */
|
|
399
|
+
wif(index?: number, change?: number): string;
|
|
400
|
+
/** Derive a batch of key bundles [start, start+count). */
|
|
401
|
+
deriveRange(start: number, count: number, change?: number): DerivedKey[];
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Low-level WIF helpers for callers who already manage their own keys and do
|
|
405
|
+
* not need HD derivation.
|
|
406
|
+
*/
|
|
407
|
+
declare const Keys: {
|
|
408
|
+
/** Address (Base58Check) for a WIF private key. */
|
|
409
|
+
addressFromWif(wif: string, network?: NetworkName): string;
|
|
410
|
+
/** Compressed public key hex for a WIF private key. */
|
|
411
|
+
publicKeyFromWif(wif: string): string;
|
|
412
|
+
/** ElectrumX scripthash for a WIF private key's P2PKH address. */
|
|
413
|
+
scriptHashFromWif(wif: string, network?: NetworkName): string;
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Ref-safe UTXO selection.
|
|
418
|
+
*
|
|
419
|
+
* THE invariant of this module (and the whole reason it exists): RXD funding is
|
|
420
|
+
* NEVER gathered by a pure value heuristic. A UTXO that carries a token ref
|
|
421
|
+
* (FT/NFT/dMint) looks like ordinary value to a naive selector, but spending it
|
|
422
|
+
* as discretionary funding silently and irreversibly BURNS the token. So every
|
|
423
|
+
* candidate is screened two ways — indexer-reported `refs`, and a local script
|
|
424
|
+
* scan (isTokenBearing) — before it can fund a transaction.
|
|
425
|
+
*
|
|
426
|
+
* Mirrors Photonic-Wallet's `selectRxdFunding` / `fundTx` behaviour.
|
|
427
|
+
*/
|
|
428
|
+
|
|
429
|
+
/** Options for {@link selectRxdFunding}. */
|
|
430
|
+
interface SelectRxdFundingOptions {
|
|
431
|
+
/**
|
|
432
|
+
* Number of non-funding outputs the final tx will already have (e.g. the
|
|
433
|
+
* recipient/token output). Used for fee estimation. Default 1.
|
|
434
|
+
*/
|
|
435
|
+
baseOutputCount?: number;
|
|
436
|
+
/**
|
|
437
|
+
* Bytes contributed by inputs the caller has already committed (e.g. a token
|
|
438
|
+
* input being spent deliberately). Added to the fee estimate. Default 0.
|
|
439
|
+
*/
|
|
440
|
+
extraInputBytes?: bigint;
|
|
441
|
+
/** Whether a change output will be added (affects fee estimate). Default true. */
|
|
442
|
+
withChange?: boolean;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Is this UTXO safe to spend as plain RXD funding? It must carry no indexer
|
|
446
|
+
* refs and no OP_PUSHINPUTREF opcodes in its script.
|
|
447
|
+
*/
|
|
448
|
+
declare function isFundingSafe(utxo: Utxo): boolean;
|
|
449
|
+
/**
|
|
450
|
+
* Filter a UTXO set down to token-free funding candidates.
|
|
451
|
+
* Use this any time you need "spendable RXD" rather than "all my UTXOs".
|
|
452
|
+
*/
|
|
453
|
+
declare function filterFundingCandidates(utxos: Utxo[]): Utxo[];
|
|
454
|
+
/**
|
|
455
|
+
* Strict guard: throw {@link TokenBurnGuardError} on the first token-bearing
|
|
456
|
+
* UTXO. Use this when you have *already* segregated funding and want to assert
|
|
457
|
+
* the invariant loudly (e.g. before signing a hand-built transaction).
|
|
458
|
+
* {@link selectRxdFunding} does not need this — it excludes token UTXOs itself.
|
|
459
|
+
*/
|
|
460
|
+
declare function assertFundingSafe(utxos: Utxo[]): void;
|
|
461
|
+
/** Estimate the fee (photons) for a tx with the given input/output counts. */
|
|
462
|
+
declare function estimateFee(inputCount: number, outputCount: number, feeRate: bigint, extraInputBytes?: bigint): bigint;
|
|
463
|
+
/**
|
|
464
|
+
* Select RXD funding inputs to cover `target` photons plus fees, **excluding
|
|
465
|
+
* every token-bearing UTXO** (the ref-safe guarantee). You can hand this the
|
|
466
|
+
* raw output of `listUnspent` — token UTXOs are dropped, never spent. Greedy:
|
|
467
|
+
* largest token-free UTXOs first, accumulating until target + fee is met. The
|
|
468
|
+
* fee grows with each input added.
|
|
469
|
+
*
|
|
470
|
+
* @throws {InsufficientFundsError} if token-free UTXOs cannot cover the target.
|
|
471
|
+
*/
|
|
472
|
+
declare function selectRxdFunding(utxos: Utxo[], target: bigint, feeRate: bigint, options?: SelectRxdFundingOptions): FundingSelection;
|
|
473
|
+
/** Sum the photon value of a UTXO list. */
|
|
474
|
+
declare function sumValue(utxos: Utxo[]): bigint;
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Transaction building primitive.
|
|
478
|
+
*
|
|
479
|
+
* A thin, faithful port of Photonic-Wallet's `buildTx`: it wraps radiantjs
|
|
480
|
+
* (which does the real script/sighash work) and adds two things the SDK needs —
|
|
481
|
+
* BigInt photon values and a per-input scriptSig hook used by the Glyph
|
|
482
|
+
* commit/reveal flow. Everything signs with SIGHASH_ALL | FORKID.
|
|
483
|
+
*/
|
|
484
|
+
|
|
485
|
+
/** An input to {@link buildTx}. Provide `script` for non-default (token) inputs. */
|
|
486
|
+
interface BuildTxInput {
|
|
487
|
+
txid: string;
|
|
488
|
+
vout: number;
|
|
489
|
+
value: bigint;
|
|
490
|
+
/** Prevout scriptPubKey hex. If omitted, treated as P2PKH for `address`. */
|
|
491
|
+
script?: string;
|
|
492
|
+
}
|
|
493
|
+
/** Per-input scriptSig override, called after the default sig+pubkey is built. */
|
|
494
|
+
type SetInputScript = (index: number, defaultScript: any) => any | string | void;
|
|
495
|
+
interface BuildTxParams {
|
|
496
|
+
/** Change address and default signer/owner address. */
|
|
497
|
+
address: string;
|
|
498
|
+
/** Signing key(s) as WIF. A single WIF signs all inputs. */
|
|
499
|
+
wif: string | string[];
|
|
500
|
+
inputs: BuildTxInput[];
|
|
501
|
+
outputs: TxOutput[];
|
|
502
|
+
/** Append a change output back to `address`. Default true. */
|
|
503
|
+
addChange?: boolean;
|
|
504
|
+
/** Fee rate, photons/byte. */
|
|
505
|
+
feeRate: bigint;
|
|
506
|
+
/** Network (for address/change encoding). Default "mainnet". */
|
|
507
|
+
network?: NetworkName;
|
|
508
|
+
/** Override the scriptSig for specific inputs (Glyph reveal uses this). */
|
|
509
|
+
setInputScript?: SetInputScript;
|
|
510
|
+
}
|
|
511
|
+
/** A signed transaction ready to broadcast. */
|
|
512
|
+
interface BuiltTx {
|
|
513
|
+
/** The radiantjs Transaction object (escape hatch). */
|
|
514
|
+
tx: any;
|
|
515
|
+
/** Serialised raw transaction hex. */
|
|
516
|
+
hex: string;
|
|
517
|
+
/** Transaction id (display order). */
|
|
518
|
+
txid: string;
|
|
519
|
+
/** Outputs, with resolved photon values (includes any change). */
|
|
520
|
+
outputs: {
|
|
521
|
+
script: string;
|
|
522
|
+
value: bigint;
|
|
523
|
+
}[];
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Build and sign a transaction. Inputs with a `script` are added manually and
|
|
527
|
+
* signed via a scriptSig callback; inputs without are added as standard P2PKH.
|
|
528
|
+
*/
|
|
529
|
+
declare function buildTx(params: BuildTxParams): BuiltTx;
|
|
530
|
+
/**
|
|
531
|
+
* Build a simple RXD payment: pay `amount` photons to `to`, funded ref-safely
|
|
532
|
+
* from `utxos`, change back to `address`.
|
|
533
|
+
*/
|
|
534
|
+
declare function buildRxdTransfer(params: {
|
|
535
|
+
address: string;
|
|
536
|
+
wif: string;
|
|
537
|
+
to: string;
|
|
538
|
+
amount: bigint;
|
|
539
|
+
utxos: Utxo[];
|
|
540
|
+
feeRate: bigint;
|
|
541
|
+
network?: NetworkName;
|
|
542
|
+
}): BuiltTx;
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Glyph token operations: mint (FT/NFT) and transfer.
|
|
546
|
+
*
|
|
547
|
+
* Glyph uses a commit/reveal two-transaction pattern. The COMMIT output locks
|
|
548
|
+
* to a script that checks the payload hash and the Glyph magic; the REVEAL
|
|
549
|
+
* spends it, carrying the CBOR envelope in its input scriptSig, and produces
|
|
550
|
+
* the token output whose ref equals the commit outpoint. We reproduce the
|
|
551
|
+
* proven Photonic-Wallet on-chain templates here and drive them with the SDK's
|
|
552
|
+
* ref-safe funding selection.
|
|
553
|
+
*
|
|
554
|
+
* IMPORTANT: these are real consensus-level scripts. Validate any new mint flow
|
|
555
|
+
* on regtest/testnet before mainnet — see README.
|
|
556
|
+
*/
|
|
557
|
+
|
|
558
|
+
/** A Glyph payload: `p` is the protocol id list, plus free-form metadata. */
|
|
559
|
+
interface GlyphPayload {
|
|
560
|
+
/** Glyph version. Default 2. */
|
|
561
|
+
v?: number;
|
|
562
|
+
/** Protocol ids, e.g. [1]=FT, [2]=NFT, [2,5]=mutable NFT. */
|
|
563
|
+
p: number[];
|
|
564
|
+
[key: string]: unknown;
|
|
565
|
+
}
|
|
566
|
+
/** Result of a mint: the token ref plus both transaction ids. */
|
|
567
|
+
interface MintResult {
|
|
568
|
+
/** Packed 72-hex token ref (the commit outpoint). */
|
|
569
|
+
ref: string;
|
|
570
|
+
/** Display ref "txid:vout". */
|
|
571
|
+
refDisplay: string;
|
|
572
|
+
commitTxid: string;
|
|
573
|
+
revealTxid: string;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Encode a Glyph payload into its reveal scriptSig and commit payload hash.
|
|
577
|
+
* revealScriptSig = `<gly> <cbor(payload)>`; payloadHash = sha256d(cbor).
|
|
578
|
+
*/
|
|
579
|
+
declare function encodeGlyph(payload: GlyphPayload): {
|
|
580
|
+
revealScriptSig: string;
|
|
581
|
+
payloadHash: string;
|
|
582
|
+
};
|
|
583
|
+
/** FT output script: a value-summed ref bound to an owner P2PKH. */
|
|
584
|
+
declare function ftScript(address: string, ref: string, network?: NetworkName): string;
|
|
585
|
+
/** NFT output script: a singleton ref bound to an owner P2PKH. */
|
|
586
|
+
declare function nftScript(address: string, ref: string, network?: NetworkName): string;
|
|
587
|
+
/** Extract the 72-hex packed ref carried by a token script (FT or NFT). */
|
|
588
|
+
declare function parseTokenRef(scriptHex: string): string | null;
|
|
589
|
+
interface BaseMintParams {
|
|
590
|
+
client: ElectrumClient;
|
|
591
|
+
/** Owner address (receives the token; pays the fees). */
|
|
592
|
+
address: string;
|
|
593
|
+
/** Owner WIF. */
|
|
594
|
+
wif: string;
|
|
595
|
+
/** Token-free RXD funding UTXOs for `address`. */
|
|
596
|
+
fundingUtxos: Utxo[];
|
|
597
|
+
/** Fee rate, photons/byte. Defaults to the network min-relay rate. */
|
|
598
|
+
feeRate?: bigint;
|
|
599
|
+
network?: NetworkName;
|
|
600
|
+
/** Extra metadata merged into the Glyph payload (name, desc, attrs, ...). */
|
|
601
|
+
metadata?: Record<string, unknown>;
|
|
602
|
+
}
|
|
603
|
+
interface MintFtParams extends BaseMintParams {
|
|
604
|
+
ticker: string;
|
|
605
|
+
/** Token supply in base units. In Glyph FT, amount == output photons. */
|
|
606
|
+
supply: bigint;
|
|
607
|
+
}
|
|
608
|
+
interface MintNftParams extends BaseMintParams {
|
|
609
|
+
/** Mark the NFT mutable (p:[2,5]). Default false (immutable singleton). */
|
|
610
|
+
mutable?: boolean;
|
|
611
|
+
/** Carrier value (photons) for the NFT output. Default dust. */
|
|
612
|
+
outputValue?: bigint;
|
|
613
|
+
}
|
|
614
|
+
/** Mint a fungible token (Glyph FT). */
|
|
615
|
+
declare function mintFT(params: MintFtParams): Promise<MintResult>;
|
|
616
|
+
/** Mint a non-fungible token (Glyph NFT singleton). */
|
|
617
|
+
declare function mintNFT(params: MintNftParams): Promise<MintResult>;
|
|
618
|
+
interface TransferTokenParams {
|
|
619
|
+
client: ElectrumClient;
|
|
620
|
+
/** Current owner address (signs the token input, pays the fee). */
|
|
621
|
+
address: string;
|
|
622
|
+
/** Current owner WIF. */
|
|
623
|
+
wif: string;
|
|
624
|
+
/** The token UTXO to move (its `script` must be the on-chain token script). */
|
|
625
|
+
tokenUtxo: Utxo;
|
|
626
|
+
/** Recipient address. */
|
|
627
|
+
toAddress: string;
|
|
628
|
+
/** Token-free RXD funding UTXOs for `address` to cover the fee. */
|
|
629
|
+
fundingUtxos: Utxo[];
|
|
630
|
+
feeRate?: bigint;
|
|
631
|
+
network?: NetworkName;
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Transfer a Glyph token (FT or NFT) to a new owner. The token output's value
|
|
635
|
+
* is preserved (for FT this preserves the amount); the covenant preamble is
|
|
636
|
+
* carried forward unchanged and only the owner P2PKH is re-bound.
|
|
637
|
+
*/
|
|
638
|
+
declare function transferToken(params: TransferTokenParams): Promise<{
|
|
639
|
+
txid: string;
|
|
640
|
+
hex: string;
|
|
641
|
+
ref: string | null;
|
|
642
|
+
}>;
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* WAVE name resolution.
|
|
646
|
+
*
|
|
647
|
+
* WAVE names resolve through the RXinDexer REST API:
|
|
648
|
+
* GET {base}/wave/resolve/{name}
|
|
649
|
+
* The indexer keys on the BARE label (no domain suffix), so "alice.rxd" is
|
|
650
|
+
* normalised to "alice" before the request. The canonical (first) registration
|
|
651
|
+
* is always returned; later duplicates are tracked but not used for resolution.
|
|
652
|
+
*/
|
|
653
|
+
|
|
654
|
+
/** Options for WAVE resolution. */
|
|
655
|
+
interface WaveResolveOptions {
|
|
656
|
+
/** REST base URL. Default https://radiantcore.org/api */
|
|
657
|
+
restBase?: string;
|
|
658
|
+
/** Inject a fetch implementation (tests / non-global-fetch runtimes). */
|
|
659
|
+
fetchImpl?: typeof fetch;
|
|
660
|
+
/** AbortSignal to cancel the request. */
|
|
661
|
+
signal?: AbortSignal;
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Normalise a WAVE name to the label the indexer resolves on: lowercase,
|
|
665
|
+
* trimmed, with a single trailing suffix (e.g. ".rxd") stripped — mirroring the
|
|
666
|
+
* REST endpoint's `rfind('.')` behaviour, so subdomains like "mail.alice.rxd"
|
|
667
|
+
* become "mail.alice". Rejects empty names and leading/trailing dots.
|
|
668
|
+
*/
|
|
669
|
+
declare function waveLabel(name: string): string;
|
|
670
|
+
/**
|
|
671
|
+
* Resolve a WAVE name to its full record. Returns `registered: false` when the
|
|
672
|
+
* name is available (unregistered) rather than throwing.
|
|
673
|
+
*/
|
|
674
|
+
declare function waveResolve(name: string, options?: WaveResolveOptions): Promise<WaveResolution>;
|
|
675
|
+
/**
|
|
676
|
+
* Convenience: resolve a WAVE name straight to its target address, or null if
|
|
677
|
+
* the name is unregistered or has no target.
|
|
678
|
+
*/
|
|
679
|
+
declare function waveResolveAddress(name: string, options?: WaveResolveOptions): Promise<string | null>;
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Single, centralised access point to `@radiant-core/radiantjs`.
|
|
683
|
+
*
|
|
684
|
+
* radiantjs is the low-level tx/script/key library (a Radiant fork of
|
|
685
|
+
* bitcore-lib). We wrap it — never duplicate it. Every other module imports the
|
|
686
|
+
* classes it needs from here so there is exactly one place that knows about the
|
|
687
|
+
* underlying library's loose runtime shape.
|
|
688
|
+
*/
|
|
689
|
+
|
|
690
|
+
/** The raw radiantjs namespace, for advanced callers that need an escape hatch. */
|
|
691
|
+
declare const radiantjs: any;
|
|
692
|
+
|
|
693
|
+
export { type BuildTxInput, type BuildTxParams, type BuiltTx, DEFAULT_ELECTRUM_ENDPOINT, DEFAULT_REST_BASE, DUST_LIMIT, type DerivedKey, ElectrumClient, type ElectrumClientOptions, ElectrumError, type FundingSelection, GLYPH_PROTOCOL, type GlyphPayload, HDWallet, type HDWalletOptions, InsufficientFundsError, Keys, MIN_RELAY_FEE_RATE, type MintFtParams, type MintNftParams, type MintResult, type NetworkName, PHOTONS_PER_RXD, RADIANT_COIN_TYPE, RXD_DECIMALS, RadiantSdkError, type ScriptHashBalance, type SelectRxdFundingOptions, TokenBurnGuardError, type TransferTokenParams, type TxOutput, type Utxo, type UtxoRef, ValidationError, type WaveResolution, type WaveResolveOptions, addressToScriptHash, assertFundingSafe, buildRxdTransfer, buildTx, encodeGlyph, estimateFee, filterFundingCandidates, ftScript, isFundingSafe, isTokenBearing, mintFT, mintNFT, nftScript, p2pkhScript, packRef, parseTokenRef, photonsToRxd, radiantjs, rxdToPhotons, scriptHash, selectRxdFunding, sumValue, transferToken, unpackRef, waveLabel, waveResolve, waveResolveAddress, zeroRefs };
|