@unicitylabs/sphere-sdk 0.17.6 → 0.18.0-dev.2
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/dist/connect/chunks/{chunk-T4DZCXWS.js → chunk-FGQ6CKKK.js} +2 -2
- package/dist/connect/chunks/{chunk-T4DZCXWS.js.map → chunk-FGQ6CKKK.js.map} +1 -1
- package/dist/connect/chunks/{chunk-BRYRG2TL.js → chunk-JYBI36GK.js} +2 -2
- package/dist/connect/chunks/{chunk-MA32MTCD.js → chunk-OAAY2JEA.js} +2 -2
- package/dist/connect/index.cjs +1 -1
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +3 -3
- package/dist/connect/internal/host.js +2 -2
- package/dist/core/index.cjs +304 -47
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +392 -320
- package/dist/core/index.d.ts +392 -320
- package/dist/core/index.js +304 -47
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/connect/index.cjs +1 -1
- package/dist/impl/browser/connect/index.cjs.map +1 -1
- package/dist/impl/browser/connect/index.js +2 -2
- package/dist/impl/wallet-api-v2/index.cjs +2 -0
- package/dist/impl/wallet-api-v2/index.cjs.map +1 -1
- package/dist/impl/wallet-api-v2/index.d.cts +30 -30
- package/dist/impl/wallet-api-v2/index.d.ts +30 -30
- package/dist/impl/wallet-api-v2/index.js +2 -0
- package/dist/impl/wallet-api-v2/index.js.map +1 -1
- package/dist/index.cjs +304 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +279 -154
- package/dist/index.d.ts +279 -154
- package/dist/index.js +304 -47
- package/dist/index.js.map +1 -1
- package/dist/modules/payments-v2/index.cjs +249 -28
- package/dist/modules/payments-v2/index.cjs.map +1 -1
- package/dist/modules/payments-v2/index.d.cts +252 -166
- package/dist/modules/payments-v2/index.d.ts +252 -166
- package/dist/modules/payments-v2/index.js +249 -28
- package/dist/modules/payments-v2/index.js.map +1 -1
- package/dist/token-engine/index.cjs +455 -427
- package/dist/token-engine/index.cjs.map +1 -1
- package/dist/token-engine/index.d.cts +26 -1
- package/dist/token-engine/index.d.ts +26 -1
- package/dist/token-engine/index.js +455 -427
- package/dist/token-engine/index.js.map +1 -1
- package/package.json +1 -1
- /package/dist/connect/chunks/{chunk-BRYRG2TL.js.map → chunk-JYBI36GK.js.map} +0 -0
- /package/dist/connect/chunks/{chunk-MA32MTCD.js.map → chunk-OAAY2JEA.js.map} +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { IMintJustificationVerifier } from '@unicitylabs/state-transition-sdk/lib/transaction/verification/IMintJustificationVerifier.js';
|
|
1
2
|
import { Token as Token$1 } from '@unicitylabs/state-transition-sdk/lib/transaction/Token.js';
|
|
2
3
|
|
|
3
4
|
declare const NFT_METADATA_TAG = 39052n;
|
|
@@ -173,6 +174,16 @@ interface MintDataTokenParams {
|
|
|
173
174
|
readonly tokenType?: Uint8Array;
|
|
174
175
|
/** Salt bytes; deterministic salt → deterministic (terms-derived) tokenId. */
|
|
175
176
|
readonly salt?: Uint8Array;
|
|
177
|
+
/** Genesis mint reason (the SDK's `justification`): tagged CBOR a registered verifier validates. */
|
|
178
|
+
readonly justification?: Uint8Array;
|
|
179
|
+
/** Verifiers for this mint's genesis reason, in place of the ones registered on the engine. */
|
|
180
|
+
readonly mintJustificationVerifiers?: readonly IMintJustificationVerifier[];
|
|
181
|
+
}
|
|
182
|
+
/** Spend a token to a burn predicate with the reason bytes as aux data. */
|
|
183
|
+
interface BurnParams {
|
|
184
|
+
readonly token: SphereToken;
|
|
185
|
+
/** The recipient predicate is `BurnPredicate(sha256(reasonBytes))`; the bytes ride in the aux data. */
|
|
186
|
+
readonly reasonBytes: Uint8Array;
|
|
176
187
|
}
|
|
177
188
|
/** Plan an NFT mint (#785); `mintDataToken` then mints the plan. */
|
|
178
189
|
interface BuildNftMintParams {
|
|
@@ -245,6 +256,171 @@ interface NftReading {
|
|
|
245
256
|
readonly signature: NftSignatureStatus;
|
|
246
257
|
}
|
|
247
258
|
|
|
259
|
+
/**
|
|
260
|
+
* token-engine/engine.ts — the FROZEN public port (ITokenEngine) + its config.
|
|
261
|
+
*
|
|
262
|
+
* This is the contract both migration tracks build against. It is sphere-domain
|
|
263
|
+
* only (see types.ts). The granular, SDK-typed steps (buildMint, submit,
|
|
264
|
+
* awaitProof, certify, …) are an INTERNAL concern of the real adapter and are
|
|
265
|
+
* intentionally NOT part of this public interface.
|
|
266
|
+
*/
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Durable, any-device store for a split's burn checkpoint (sdk-changes E.4, sphere-sdk#501
|
|
270
|
+
* option b). The engine passes opaque PLAINTEXT bytes; a transport adapter (the wallet-api
|
|
271
|
+
* provider) is responsible for AAD-encryption and the wallet-api §16 intent-progress round-trip.
|
|
272
|
+
*
|
|
273
|
+
* The store is the resume seed for the one split input the engine cannot re-derive — the burn's
|
|
274
|
+
* aggregator-issued inclusion proof — so the mint justification is rebuilt from stored bytes, not
|
|
275
|
+
* a refetch (the aggregator regenerates proofs per request).
|
|
276
|
+
*/
|
|
277
|
+
interface SplitCheckpointStore {
|
|
278
|
+
/**
|
|
279
|
+
* Insert-once, first-write-wins. MUST resolve only AFTER the store acked durability, and MUST
|
|
280
|
+
* resolve with the AUTHORITATIVE stored bytes — the caller's own on a fresh write, or the FIRST
|
|
281
|
+
* writer's when the slot `(transferId, opIndex)` was already taken (the caller adopts those and
|
|
282
|
+
* mints from them, so concurrent resumers converge on one burn proof).
|
|
283
|
+
*/
|
|
284
|
+
put(transferId: string, opIndex: number, bytes: Uint8Array): Promise<Uint8Array>;
|
|
285
|
+
/** The stored bytes for the slot, or `null` when none exists. */
|
|
286
|
+
get(transferId: string, opIndex: number): Promise<Uint8Array | null>;
|
|
287
|
+
}
|
|
288
|
+
/** Options common to the long-running, network-bound operations. */
|
|
289
|
+
interface EngineOpOptions {
|
|
290
|
+
/** Cancels the operation (including inclusion-proof polling). */
|
|
291
|
+
readonly signal?: AbortSignal;
|
|
292
|
+
/**
|
|
293
|
+
* Durable burn-checkpoint store for a resumable split (sdk-changes E.4, sphere-sdk#501). When
|
|
294
|
+
* present, `split()` persists the burn's certified proof AND awaits its durable ack BEFORE
|
|
295
|
+
* submitting any mint leg, and rebuilds the mint justification from the stored bytes on resume —
|
|
296
|
+
* so a split resumed after any mint leg certified recovers instead of stranding its outputs.
|
|
297
|
+
*
|
|
298
|
+
* Absent keeps today's behavior (a fresh burn proof per attempt): fine for a mid-split resume
|
|
299
|
+
* with no mint yet certified, but a split resumed AFTER a mint certified cannot recover — a
|
|
300
|
+
* documented residual for fully-local compositions; the live path MUST supply the store.
|
|
301
|
+
*/
|
|
302
|
+
readonly checkpointStore?: SplitCheckpointStore;
|
|
303
|
+
/**
|
|
304
|
+
* Realization seed for deterministic transfer/split (Part E, sdk-changes E.1/E.3):
|
|
305
|
+
* a client-generated UUIDv4 in canonical lowercase string form. Every value the
|
|
306
|
+
* transaction binds to (stateMask, per-output salts) is HKDF-derived from the
|
|
307
|
+
* wallet key + this id, so re-calling the op with the same `transferId` and
|
|
308
|
+
* inputs rebuilds the byte-identical transaction and resumes an interrupted
|
|
309
|
+
* attempt instead of losing funds. Persist it BEFORE calling the engine.
|
|
310
|
+
*
|
|
311
|
+
* If absent, the engine generates one internally (`crypto.randomUUID()`) — the
|
|
312
|
+
* derivation path is identical, but the call is NOT resumable (the seed is
|
|
313
|
+
* gone if the process dies mid-op).
|
|
314
|
+
*/
|
|
315
|
+
readonly transferId?: string;
|
|
316
|
+
/**
|
|
317
|
+
* Ordinal of this engine op WITHIN one logical send sharing a `transferId`
|
|
318
|
+
* (ARCHITECTURE §7: D whole-token transfers + at most one split under ONE
|
|
319
|
+
* intent). It indexes the op-level HKDF derivations (`stateMask`, the split
|
|
320
|
+
* `burn` mask) so distinct ops never reuse a mask — §8.1's "per-transfer
|
|
321
|
+
* unique". Per-output split salts are indexed by output ordinal in their own
|
|
322
|
+
* `salt` field domain; callers MUST NOT run two splits under one transferId.
|
|
323
|
+
* Default 0 (single-op sends). Resume MUST replay the same (transferId,
|
|
324
|
+
* opIndex) pairing per source.
|
|
325
|
+
*/
|
|
326
|
+
readonly opIndex?: number;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* The token engine port. The wallet's secp256k1 identity, the target network,
|
|
330
|
+
* the aggregator client and the trust base are all bound at construction
|
|
331
|
+
* (see EngineConfig); operations below take only sphere-domain arguments.
|
|
332
|
+
*/
|
|
333
|
+
interface ITokenEngine {
|
|
334
|
+
/** This engine's wallet identity (chain pubkey). Synchronous. */
|
|
335
|
+
getIdentity(): EngineIdentity;
|
|
336
|
+
/**
|
|
337
|
+
* Legacy `DIRECT://` address for the given pubkey (defaults to this engine's
|
|
338
|
+
* identity). This is the ONLY "address" in v2 and is kept stable across the
|
|
339
|
+
* migration (Path A) so Quest XP / Unicity IDs keyed on it survive. Async —
|
|
340
|
+
* the derivation hashes via the SDK.
|
|
341
|
+
*/
|
|
342
|
+
deriveIdentityAddress(pubkey?: Uint8Array): Promise<string>;
|
|
343
|
+
/**
|
|
344
|
+
* Genesis-stable token id — 64-char lowercase hex of the v2 TokenId (same
|
|
345
|
+
* across every state). Use for dedup / history / tombstone keys. Synchronous.
|
|
346
|
+
*/
|
|
347
|
+
tokenId(token: SphereToken): string;
|
|
348
|
+
/** Decoded value of a token (cached). Synchronous. */
|
|
349
|
+
readValue(token: SphereToken): SphereValue | null;
|
|
350
|
+
/** Balance of a single coin within a token. Synchronous. */
|
|
351
|
+
balanceOf(token: SphereToken, coinId: CoinId): bigint;
|
|
352
|
+
/**
|
|
353
|
+
* The opaque on-chain memo delivered with this token: the latest transfer's
|
|
354
|
+
* data for a transferred token, else the memo in a minted output's value
|
|
355
|
+
* envelope (split). Returns `null` when there is no memo — including for data
|
|
356
|
+
* tokens (no value envelope; use `readTokenData`) and memo-less value tokens.
|
|
357
|
+
* To tell a data token from a value token, check `readValue` (null ⇒
|
|
358
|
+
* data/value-less token). Synchronous.
|
|
359
|
+
*/
|
|
360
|
+
readMemo(token: SphereToken): Uint8Array | null;
|
|
361
|
+
/** Raw genesis data of a token (e.g. a data-token's terms). `null` when absent. Synchronous. */
|
|
362
|
+
readTokenData(token: SphereToken): Uint8Array | null;
|
|
363
|
+
/** The genesis mint reason (`justification`) of a token; `null` when it was minted without one. Synchronous. */
|
|
364
|
+
readTokenJustification(token: SphereToken): Uint8Array | null;
|
|
365
|
+
/** Read a token's genesis payload as an NFT. NEVER throws; null = not a recognised NFT. */
|
|
366
|
+
readNft(token: SphereToken): Promise<NftReading | null>;
|
|
367
|
+
/**
|
|
368
|
+
* Mint (issue) a new token to a recipient pubkey. NOT a wallet end-user flow —
|
|
369
|
+
* this is the issuer/developer capability: an app issuing its own tokens
|
|
370
|
+
* (rewards, in-app currency, tickets) to users, or seeding test balances. v2
|
|
371
|
+
* makes standalone mint first-class (Token.mint accepts a genesis with a null
|
|
372
|
+
* justification). Split's per-output mint is a separate, internal path; the
|
|
373
|
+
* Unicity-ID/nametag mint is a distinct identity surface (see migration plan §4.4).
|
|
374
|
+
*/
|
|
375
|
+
mint(params: MintParams, options?: EngineOpOptions): Promise<SphereToken>;
|
|
376
|
+
/**
|
|
377
|
+
* Mint a NON-value (data) token: opaque `data` + custom `tokenType` + deterministic
|
|
378
|
+
* `salt` → a stable, terms-derived `tokenId`. The result has `value === null`;
|
|
379
|
+
* read its bytes via `readTokenData`. (Used e.g. for on-chain invoice tokens.)
|
|
380
|
+
*/
|
|
381
|
+
mintDataToken(params: MintDataTokenParams, options?: EngineOpOptions): Promise<SphereToken>;
|
|
382
|
+
/** Plan an NFT mint: encode (and optionally sign as this engine's identity) the payload and derive its token id. No chain op. */
|
|
383
|
+
buildNftMint(params: BuildNftMintParams): Promise<NftMintPlan>;
|
|
384
|
+
/** Spend a token wholesale to a recipient pubkey; returns the recipient's finished token. */
|
|
385
|
+
transfer(params: TransferParams, options?: EngineOpOptions): Promise<SphereToken>;
|
|
386
|
+
/** Spend the token to `BurnPredicate(sha256(reasonBytes))` with the reason bytes as aux data. */
|
|
387
|
+
burn(params: BurnParams, options?: EngineOpOptions): Promise<SphereToken>;
|
|
388
|
+
/** Split a token into N value-conserving outputs (burn source + internally mint each output). */
|
|
389
|
+
split(params: SplitParams, options?: EngineOpOptions): Promise<SplitResult>;
|
|
390
|
+
/** Fully verify a token against the trust base. */
|
|
391
|
+
verify(token: SphereToken, options?: EngineOpOptions): Promise<EngineVerifyResult>;
|
|
392
|
+
/** Whether the token's current state has already been spent on the network. */
|
|
393
|
+
isSpent(token: SphereToken, options?: EngineOpOptions): Promise<boolean>;
|
|
394
|
+
/**
|
|
395
|
+
* Whether the token's CURRENT state is locked to `SignaturePredicate(pubkey)`.
|
|
396
|
+
* Local + synchronous (predicate byte-compare, no network). The receive path
|
|
397
|
+
* uses it to reject tokens that are not actually addressed to this wallet.
|
|
398
|
+
*/
|
|
399
|
+
isOwnedBy(token: SphereToken, pubkey: Uint8Array): boolean;
|
|
400
|
+
/** Serialize a token for storage/transport. Synchronous. */
|
|
401
|
+
encodeToken(token: SphereToken): TokenBlob;
|
|
402
|
+
/** Reconstruct a token from its blob (decodes embedded payment data). */
|
|
403
|
+
decodeToken(blob: TokenBlob): Promise<SphereToken>;
|
|
404
|
+
/**
|
|
405
|
+
* The backend-true delivery keys for encoded TokenBlob bytes: the
|
|
406
|
+
* genesis-stable tokenId and the SDK's PROTOCOL state hash of the latest
|
|
407
|
+
* state (DataHash imprint, hex). wallet-api keys mailbox entries on exactly
|
|
408
|
+
* this pair (entry_id = SHA-256(tokenId ‖ stateHash); §8.2 step 4 validates
|
|
409
|
+
* a deposit's claimed stateHash against it) — a plain hash over the token
|
|
410
|
+
* bytes is NOT this value and 422s on deposit. Delivery implementations MUST
|
|
411
|
+
* derive their ids through this method, never locally.
|
|
412
|
+
*/
|
|
413
|
+
deliveryKeys(blobBytes: Uint8Array): Promise<{
|
|
414
|
+
tokenId: string;
|
|
415
|
+
stateHash: string;
|
|
416
|
+
}>;
|
|
417
|
+
/**
|
|
418
|
+
* Release engine-owned OS resources — today only the verification worker pool.
|
|
419
|
+
* Idempotent; optional because an engine owning none need not define it.
|
|
420
|
+
*/
|
|
421
|
+
dispose?(): void;
|
|
422
|
+
}
|
|
423
|
+
|
|
248
424
|
/**
|
|
249
425
|
* SDK2 Core Types
|
|
250
426
|
* Platform-independent type definitions
|
|
@@ -434,6 +610,40 @@ interface MintResult {
|
|
|
434
610
|
tokenId?: string;
|
|
435
611
|
error?: string;
|
|
436
612
|
}
|
|
613
|
+
/** Custom-genesis mint (a TokenPlugin's token), always to this wallet; `assets` = what the payload declares. */
|
|
614
|
+
interface MintCustomRequest {
|
|
615
|
+
readonly tokenType: Uint8Array;
|
|
616
|
+
readonly salt: Uint8Array;
|
|
617
|
+
readonly data: Uint8Array;
|
|
618
|
+
readonly justification?: Uint8Array;
|
|
619
|
+
readonly assets: readonly {
|
|
620
|
+
coinId: string;
|
|
621
|
+
amount: bigint;
|
|
622
|
+
}[];
|
|
623
|
+
readonly mintJustificationVerifiers?: readonly IMintJustificationVerifier[];
|
|
624
|
+
}
|
|
625
|
+
/** Burn a held token to `BurnPredicate(sha256(reasonBytes))` with the bytes as aux data. */
|
|
626
|
+
interface BurnRequest {
|
|
627
|
+
readonly tokenId: string;
|
|
628
|
+
readonly reasonBytes: Uint8Array;
|
|
629
|
+
}
|
|
630
|
+
interface BurnResult {
|
|
631
|
+
success: boolean;
|
|
632
|
+
burnId: string;
|
|
633
|
+
tokenId: string;
|
|
634
|
+
/** The burned blob, the proof of the burn: persist it, then `acknowledgeBurn(burnId)`. */
|
|
635
|
+
burnedToken?: Uint8Array;
|
|
636
|
+
error?: string;
|
|
637
|
+
}
|
|
638
|
+
/** A burn not yet acknowledged: in flight (`burnedToken` null), certified, or settled. */
|
|
639
|
+
interface PendingBurn {
|
|
640
|
+
readonly burnId: string;
|
|
641
|
+
readonly tokenId: string;
|
|
642
|
+
readonly reasonBytes: Uint8Array;
|
|
643
|
+
readonly burnedToken: Uint8Array | null;
|
|
644
|
+
readonly settled: boolean;
|
|
645
|
+
readonly createdAt: number;
|
|
646
|
+
}
|
|
437
647
|
/** #785: `content` uses ERC-721 field names; `sign` (default true) signs as creator with this wallet's chain key. */
|
|
438
648
|
interface MintNftRequest {
|
|
439
649
|
readonly content: NftContent;
|
|
@@ -525,6 +735,8 @@ interface PaymentsV2 {
|
|
|
525
735
|
}): Token[];
|
|
526
736
|
coinless(): CoinlessToken[];
|
|
527
737
|
tokenData(tokenId: string): Promise<Uint8Array | null>;
|
|
738
|
+
/** The genesis mint reason of one held token; null when it was minted without one. Same contract as tokenData. */
|
|
739
|
+
tokenJustification(tokenId: string): Promise<Uint8Array | null>;
|
|
528
740
|
/** One held token read as an NFT; null = its payload is not a recognised NFT. `creator` is only CLAIMED unless `signature` is 'valid'. Throws VALIDATION_ERROR when not held, STORAGE_ERROR when its blob is missing (same contract as tokenData). */
|
|
529
741
|
nft(tokenId: string): Promise<NftView | null>;
|
|
530
742
|
/** Batch read for list views. Ids not held, blobs missing or undecodable, and non-NFT payloads are simply absent from the map. Throws only on a transport failure. */
|
|
@@ -539,6 +751,10 @@ interface PaymentsV2 {
|
|
|
539
751
|
sendCoinless(req: SendWholeTokenRequest): Promise<TransferResult>;
|
|
540
752
|
mint(coinId: string, amount: bigint): Promise<MintResult>;
|
|
541
753
|
mintNft(request: MintNftRequest): Promise<MintResult>;
|
|
754
|
+
mintCustom(request: MintCustomRequest): Promise<MintResult>;
|
|
755
|
+
burn(request: BurnRequest): Promise<BurnResult>;
|
|
756
|
+
pendingBurns(): Promise<PendingBurn[]>;
|
|
757
|
+
acknowledgeBurn(burnId: string): Promise<void>;
|
|
542
758
|
receive(): Promise<{
|
|
543
759
|
transfers: IncomingTransfer[];
|
|
544
760
|
}>;
|
|
@@ -806,6 +1022,31 @@ interface NftMintJournalEntry {
|
|
|
806
1022
|
tokenTypeHex: string;
|
|
807
1023
|
createdAt: number;
|
|
808
1024
|
}
|
|
1025
|
+
interface CustomMintJournalEntry {
|
|
1026
|
+
mintId: string;
|
|
1027
|
+
tokenId: string;
|
|
1028
|
+
dataHex: string;
|
|
1029
|
+
saltHex: string;
|
|
1030
|
+
tokenTypeHex: string;
|
|
1031
|
+
justificationHex: string | null;
|
|
1032
|
+
assets: {
|
|
1033
|
+
coinId: string;
|
|
1034
|
+
amount: string;
|
|
1035
|
+
}[];
|
|
1036
|
+
createdAt: number;
|
|
1037
|
+
}
|
|
1038
|
+
interface BurnJournalEntry {
|
|
1039
|
+
burnId: string;
|
|
1040
|
+
tokenId: string;
|
|
1041
|
+
reasonHex: string;
|
|
1042
|
+
burnedTokenHex: string | null;
|
|
1043
|
+
settled: boolean;
|
|
1044
|
+
assets: {
|
|
1045
|
+
coinId: string;
|
|
1046
|
+
amount: string;
|
|
1047
|
+
}[];
|
|
1048
|
+
createdAt: number;
|
|
1049
|
+
}
|
|
809
1050
|
interface ShortfallEntry {
|
|
810
1051
|
transferId: string;
|
|
811
1052
|
remainingAmount: string;
|
|
@@ -831,6 +1072,8 @@ declare const STORE_KEYS: {
|
|
|
831
1072
|
readonly deliveryJournal: "delivery-journal";
|
|
832
1073
|
readonly mintJournal: "mint-journal";
|
|
833
1074
|
readonly nftMintJournal: "nft-mint-journal";
|
|
1075
|
+
readonly customMintJournal: "custom-mint-journal";
|
|
1076
|
+
readonly burnJournal: "burn-journal";
|
|
834
1077
|
readonly shortfalls: "shortfalls";
|
|
835
1078
|
readonly settlingLinks: "settling";
|
|
836
1079
|
readonly streamCursor: (s: StreamName) => string;
|
|
@@ -839,167 +1082,6 @@ declare const STORE_KEYS: {
|
|
|
839
1082
|
readonly knownSpends: "known-spends";
|
|
840
1083
|
};
|
|
841
1084
|
|
|
842
|
-
/**
|
|
843
|
-
* token-engine/engine.ts — the FROZEN public port (ITokenEngine) + its config.
|
|
844
|
-
*
|
|
845
|
-
* This is the contract both migration tracks build against. It is sphere-domain
|
|
846
|
-
* only (see types.ts). The granular, SDK-typed steps (buildMint, submit,
|
|
847
|
-
* awaitProof, certify, …) are an INTERNAL concern of the real adapter and are
|
|
848
|
-
* intentionally NOT part of this public interface.
|
|
849
|
-
*/
|
|
850
|
-
|
|
851
|
-
/**
|
|
852
|
-
* Durable, any-device store for a split's burn checkpoint (sdk-changes E.4, sphere-sdk#501
|
|
853
|
-
* option b). The engine passes opaque PLAINTEXT bytes; a transport adapter (the wallet-api
|
|
854
|
-
* provider) is responsible for AAD-encryption and the wallet-api §16 intent-progress round-trip.
|
|
855
|
-
*
|
|
856
|
-
* The store is the resume seed for the one split input the engine cannot re-derive — the burn's
|
|
857
|
-
* aggregator-issued inclusion proof — so the mint justification is rebuilt from stored bytes, not
|
|
858
|
-
* a refetch (the aggregator regenerates proofs per request).
|
|
859
|
-
*/
|
|
860
|
-
interface SplitCheckpointStore {
|
|
861
|
-
/**
|
|
862
|
-
* Insert-once, first-write-wins. MUST resolve only AFTER the store acked durability, and MUST
|
|
863
|
-
* resolve with the AUTHORITATIVE stored bytes — the caller's own on a fresh write, or the FIRST
|
|
864
|
-
* writer's when the slot `(transferId, opIndex)` was already taken (the caller adopts those and
|
|
865
|
-
* mints from them, so concurrent resumers converge on one burn proof).
|
|
866
|
-
*/
|
|
867
|
-
put(transferId: string, opIndex: number, bytes: Uint8Array): Promise<Uint8Array>;
|
|
868
|
-
/** The stored bytes for the slot, or `null` when none exists. */
|
|
869
|
-
get(transferId: string, opIndex: number): Promise<Uint8Array | null>;
|
|
870
|
-
}
|
|
871
|
-
/** Options common to the long-running, network-bound operations. */
|
|
872
|
-
interface EngineOpOptions {
|
|
873
|
-
/** Cancels the operation (including inclusion-proof polling). */
|
|
874
|
-
readonly signal?: AbortSignal;
|
|
875
|
-
/**
|
|
876
|
-
* Durable burn-checkpoint store for a resumable split (sdk-changes E.4, sphere-sdk#501). When
|
|
877
|
-
* present, `split()` persists the burn's certified proof AND awaits its durable ack BEFORE
|
|
878
|
-
* submitting any mint leg, and rebuilds the mint justification from the stored bytes on resume —
|
|
879
|
-
* so a split resumed after any mint leg certified recovers instead of stranding its outputs.
|
|
880
|
-
*
|
|
881
|
-
* Absent keeps today's behavior (a fresh burn proof per attempt): fine for a mid-split resume
|
|
882
|
-
* with no mint yet certified, but a split resumed AFTER a mint certified cannot recover — a
|
|
883
|
-
* documented residual for fully-local compositions; the live path MUST supply the store.
|
|
884
|
-
*/
|
|
885
|
-
readonly checkpointStore?: SplitCheckpointStore;
|
|
886
|
-
/**
|
|
887
|
-
* Realization seed for deterministic transfer/split (Part E, sdk-changes E.1/E.3):
|
|
888
|
-
* a client-generated UUIDv4 in canonical lowercase string form. Every value the
|
|
889
|
-
* transaction binds to (stateMask, per-output salts) is HKDF-derived from the
|
|
890
|
-
* wallet key + this id, so re-calling the op with the same `transferId` and
|
|
891
|
-
* inputs rebuilds the byte-identical transaction and resumes an interrupted
|
|
892
|
-
* attempt instead of losing funds. Persist it BEFORE calling the engine.
|
|
893
|
-
*
|
|
894
|
-
* If absent, the engine generates one internally (`crypto.randomUUID()`) — the
|
|
895
|
-
* derivation path is identical, but the call is NOT resumable (the seed is
|
|
896
|
-
* gone if the process dies mid-op).
|
|
897
|
-
*/
|
|
898
|
-
readonly transferId?: string;
|
|
899
|
-
/**
|
|
900
|
-
* Ordinal of this engine op WITHIN one logical send sharing a `transferId`
|
|
901
|
-
* (ARCHITECTURE §7: D whole-token transfers + at most one split under ONE
|
|
902
|
-
* intent). It indexes the op-level HKDF derivations (`stateMask`, the split
|
|
903
|
-
* `burn` mask) so distinct ops never reuse a mask — §8.1's "per-transfer
|
|
904
|
-
* unique". Per-output split salts are indexed by output ordinal in their own
|
|
905
|
-
* `salt` field domain; callers MUST NOT run two splits under one transferId.
|
|
906
|
-
* Default 0 (single-op sends). Resume MUST replay the same (transferId,
|
|
907
|
-
* opIndex) pairing per source.
|
|
908
|
-
*/
|
|
909
|
-
readonly opIndex?: number;
|
|
910
|
-
}
|
|
911
|
-
/**
|
|
912
|
-
* The token engine port. The wallet's secp256k1 identity, the target network,
|
|
913
|
-
* the aggregator client and the trust base are all bound at construction
|
|
914
|
-
* (see EngineConfig); operations below take only sphere-domain arguments.
|
|
915
|
-
*/
|
|
916
|
-
interface ITokenEngine {
|
|
917
|
-
/** This engine's wallet identity (chain pubkey). Synchronous. */
|
|
918
|
-
getIdentity(): EngineIdentity;
|
|
919
|
-
/**
|
|
920
|
-
* Legacy `DIRECT://` address for the given pubkey (defaults to this engine's
|
|
921
|
-
* identity). This is the ONLY "address" in v2 and is kept stable across the
|
|
922
|
-
* migration (Path A) so Quest XP / Unicity IDs keyed on it survive. Async —
|
|
923
|
-
* the derivation hashes via the SDK.
|
|
924
|
-
*/
|
|
925
|
-
deriveIdentityAddress(pubkey?: Uint8Array): Promise<string>;
|
|
926
|
-
/**
|
|
927
|
-
* Genesis-stable token id — 64-char lowercase hex of the v2 TokenId (same
|
|
928
|
-
* across every state). Use for dedup / history / tombstone keys. Synchronous.
|
|
929
|
-
*/
|
|
930
|
-
tokenId(token: SphereToken): string;
|
|
931
|
-
/** Decoded value of a token (cached). Synchronous. */
|
|
932
|
-
readValue(token: SphereToken): SphereValue | null;
|
|
933
|
-
/** Balance of a single coin within a token. Synchronous. */
|
|
934
|
-
balanceOf(token: SphereToken, coinId: CoinId): bigint;
|
|
935
|
-
/**
|
|
936
|
-
* The opaque on-chain memo delivered with this token: the latest transfer's
|
|
937
|
-
* data for a transferred token, else the memo in a minted output's value
|
|
938
|
-
* envelope (split). Returns `null` when there is no memo — including for data
|
|
939
|
-
* tokens (no value envelope; use `readTokenData`) and memo-less value tokens.
|
|
940
|
-
* To tell a data token from a value token, check `readValue` (null ⇒
|
|
941
|
-
* data/value-less token). Synchronous.
|
|
942
|
-
*/
|
|
943
|
-
readMemo(token: SphereToken): Uint8Array | null;
|
|
944
|
-
/** Raw genesis data of a token (e.g. a data-token's terms). `null` when absent. Synchronous. */
|
|
945
|
-
readTokenData(token: SphereToken): Uint8Array | null;
|
|
946
|
-
/** Read a token's genesis payload as an NFT. NEVER throws; null = not a recognised NFT. */
|
|
947
|
-
readNft(token: SphereToken): Promise<NftReading | null>;
|
|
948
|
-
/**
|
|
949
|
-
* Mint (issue) a new token to a recipient pubkey. NOT a wallet end-user flow —
|
|
950
|
-
* this is the issuer/developer capability: an app issuing its own tokens
|
|
951
|
-
* (rewards, in-app currency, tickets) to users, or seeding test balances. v2
|
|
952
|
-
* makes standalone mint first-class (Token.mint accepts a genesis with a null
|
|
953
|
-
* justification). Split's per-output mint is a separate, internal path; the
|
|
954
|
-
* Unicity-ID/nametag mint is a distinct identity surface (see migration plan §4.4).
|
|
955
|
-
*/
|
|
956
|
-
mint(params: MintParams, options?: EngineOpOptions): Promise<SphereToken>;
|
|
957
|
-
/**
|
|
958
|
-
* Mint a NON-value (data) token: opaque `data` + custom `tokenType` + deterministic
|
|
959
|
-
* `salt` → a stable, terms-derived `tokenId`. The result has `value === null`;
|
|
960
|
-
* read its bytes via `readTokenData`. (Used e.g. for on-chain invoice tokens.)
|
|
961
|
-
*/
|
|
962
|
-
mintDataToken(params: MintDataTokenParams, options?: EngineOpOptions): Promise<SphereToken>;
|
|
963
|
-
/** Plan an NFT mint: encode (and optionally sign as this engine's identity) the payload and derive its token id. No chain op. */
|
|
964
|
-
buildNftMint(params: BuildNftMintParams): Promise<NftMintPlan>;
|
|
965
|
-
/** Spend a token wholesale to a recipient pubkey; returns the recipient's finished token. */
|
|
966
|
-
transfer(params: TransferParams, options?: EngineOpOptions): Promise<SphereToken>;
|
|
967
|
-
/** Split a token into N value-conserving outputs (burn source + internally mint each output). */
|
|
968
|
-
split(params: SplitParams, options?: EngineOpOptions): Promise<SplitResult>;
|
|
969
|
-
/** Fully verify a token against the trust base. */
|
|
970
|
-
verify(token: SphereToken, options?: EngineOpOptions): Promise<EngineVerifyResult>;
|
|
971
|
-
/** Whether the token's current state has already been spent on the network. */
|
|
972
|
-
isSpent(token: SphereToken, options?: EngineOpOptions): Promise<boolean>;
|
|
973
|
-
/**
|
|
974
|
-
* Whether the token's CURRENT state is locked to `SignaturePredicate(pubkey)`.
|
|
975
|
-
* Local + synchronous (predicate byte-compare, no network). The receive path
|
|
976
|
-
* uses it to reject tokens that are not actually addressed to this wallet.
|
|
977
|
-
*/
|
|
978
|
-
isOwnedBy(token: SphereToken, pubkey: Uint8Array): boolean;
|
|
979
|
-
/** Serialize a token for storage/transport. Synchronous. */
|
|
980
|
-
encodeToken(token: SphereToken): TokenBlob;
|
|
981
|
-
/** Reconstruct a token from its blob (decodes embedded payment data). */
|
|
982
|
-
decodeToken(blob: TokenBlob): Promise<SphereToken>;
|
|
983
|
-
/**
|
|
984
|
-
* The backend-true delivery keys for encoded TokenBlob bytes: the
|
|
985
|
-
* genesis-stable tokenId and the SDK's PROTOCOL state hash of the latest
|
|
986
|
-
* state (DataHash imprint, hex). wallet-api keys mailbox entries on exactly
|
|
987
|
-
* this pair (entry_id = SHA-256(tokenId ‖ stateHash); §8.2 step 4 validates
|
|
988
|
-
* a deposit's claimed stateHash against it) — a plain hash over the token
|
|
989
|
-
* bytes is NOT this value and 422s on deposit. Delivery implementations MUST
|
|
990
|
-
* derive their ids through this method, never locally.
|
|
991
|
-
*/
|
|
992
|
-
deliveryKeys(blobBytes: Uint8Array): Promise<{
|
|
993
|
-
tokenId: string;
|
|
994
|
-
stateHash: string;
|
|
995
|
-
}>;
|
|
996
|
-
/**
|
|
997
|
-
* Release engine-owned OS resources — today only the verification worker pool.
|
|
998
|
-
* Idempotent; optional because an engine owning none need not define it.
|
|
999
|
-
*/
|
|
1000
|
-
dispose?(): void;
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
1085
|
interface HistoryWireAsset {
|
|
1004
1086
|
coinId: string;
|
|
1005
1087
|
amount: string;
|
|
@@ -1368,6 +1450,7 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1368
1450
|
}): Token[];
|
|
1369
1451
|
coinless(): CoinlessToken[];
|
|
1370
1452
|
tokenData(tokenId: string): Promise<Uint8Array | null>;
|
|
1453
|
+
tokenJustification(tokenId: string): Promise<Uint8Array | null>;
|
|
1371
1454
|
nft(tokenId: string): Promise<NftView | null>;
|
|
1372
1455
|
nfts(tokenIds: readonly string[]): Promise<ReadonlyMap<string, NftView>>;
|
|
1373
1456
|
private readDeps;
|
|
@@ -1391,6 +1474,10 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1391
1474
|
}>;
|
|
1392
1475
|
mint(coinId: string, amount: bigint): Promise<MintResult>;
|
|
1393
1476
|
mintNft(request: MintNftRequest): Promise<MintResult>;
|
|
1477
|
+
mintCustom: (request: MintCustomRequest) => Promise<MintResult>;
|
|
1478
|
+
burn: (request: BurnRequest) => Promise<BurnResult>;
|
|
1479
|
+
pendingBurns: () => Promise<PendingBurn[]>;
|
|
1480
|
+
acknowledgeBurn: (burnId: string) => Promise<void>;
|
|
1394
1481
|
resumeNow(): Promise<void>;
|
|
1395
1482
|
/** §5.1 restore — awaited by the session latch BEFORE streams resume; never coalesced onto a pre-restore pass. */
|
|
1396
1483
|
handleEpochChange(_newEpoch: string): Promise<void>;
|
|
@@ -1398,7 +1485,7 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1398
1485
|
private runConvergencePass;
|
|
1399
1486
|
private convergeBody;
|
|
1400
1487
|
private nowMs;
|
|
1401
|
-
/** One snapshot serves the coin and the
|
|
1488
|
+
/** One snapshot serves the coin, NFT and custom mints and the burn, live and replayed. */
|
|
1402
1489
|
private mintDeps;
|
|
1403
1490
|
/** The ONE place a send() outcome is shaped: success emits in finishSend, a
|
|
1404
1491
|
* CLEAN rejection emits `transfer:updated{status:'failed'}` here (§4). */
|
|
@@ -1436,9 +1523,8 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1436
1523
|
/** Nothing delivered → UNWRAPPED; after ≥1 delivered leg every failure surfaces as PartialSendConflictError over the settled set. */
|
|
1437
1524
|
private softAbort;
|
|
1438
1525
|
private mintInner;
|
|
1439
|
-
/** A live
|
|
1440
|
-
private
|
|
1441
|
-
private tokenInServerInventory;
|
|
1526
|
+
/** A live money op under a fresh id — its replay stays hands-off while this attempt runs (§7). */
|
|
1527
|
+
private ownedOp;
|
|
1442
1528
|
private engine;
|
|
1443
1529
|
private newId;
|
|
1444
1530
|
private seedHeldStates;
|
|
@@ -1449,4 +1535,4 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1449
1535
|
declare const HEARTBEAT_SEED_MS = 5000;
|
|
1450
1536
|
declare const HEARTBEAT_CAP_MS = 120000;
|
|
1451
1537
|
|
|
1452
|
-
export { ATTENTION_MINT_UNRESOLVED, ATTENTION_RECIPIENT_NETWORK_UNVERIFIED, ATTENTION_RESEED_REJECTED, type AckOutcome, type AckRequest, type ApplyDeltaResult, type CheckpointReseeder, type ConnectionStatus, type DeliverOptions, type DeliveryJournalEntry, type DeliveryPort, type DeliveryReceipt, type DeterministicMintCapable, type FacadeClient, type FacadeSession, HEARTBEAT_CAP_MS, HEARTBEAT_SEED_MS, type HistoryEntry, type HistoryPage, type IncomingDelivery, type IntentBackstopEntry, type IntentPayload, type InventoryAsset, type InventoryItem, type InventoryPage, MAX_RESELECT, type MintJournalEntry, type MintNftRequest, type MintResult, NFT_DOCUMENT_MEDIA_TYPE, NFT_LINK_TAG, NFT_MAX_PAYLOAD_BYTES, NFT_MEDIA_TAG, NFT_METADATA_TAG, NFT_SIGNED_TAG, type NftAttribute, type NftContent, type NftLink, type NftMedia, type NftMediaRef, type NftMetadata, type NftMintJournalEntry, type NftSignatureContext, type NftSignatureStatus, type NftView, type OpOutcome, type OutcomeClass, type PaymentRequestStatus, type PaymentRequestView, PaymentsFacade, type PaymentsFacadeDeps, type PaymentsRequestsApi, type PaymentsV2, type PaymentsV2Events, type PendingTransfer, type PlannedOp, type RecipientInfo, type RetryableAckError, STORE_KEYS, type ScopedKV, type SendCoinlessRequest, type SendRequest, type SendWholeTokenRequest, type SettlingLink, type ShortfallEntry, type StoragePort, type StreamCursor, type StreamName, createScopedKV, encodeNftContent, isNftDocumentLink, isRetryableAckError, parseNftDocument, parseNftPayload, supportsDeterministicMint, sweepSupersededState, verifyNftLinkContent };
|
|
1538
|
+
export { ATTENTION_MINT_UNRESOLVED, ATTENTION_RECIPIENT_NETWORK_UNVERIFIED, ATTENTION_RESEED_REJECTED, type AckOutcome, type AckRequest, type ApplyDeltaResult, type BurnJournalEntry, type BurnRequest, type BurnResult, type CheckpointReseeder, type ConnectionStatus, type CustomMintJournalEntry, type DeliverOptions, type DeliveryJournalEntry, type DeliveryPort, type DeliveryReceipt, type DeterministicMintCapable, type FacadeClient, type FacadeSession, HEARTBEAT_CAP_MS, HEARTBEAT_SEED_MS, type HistoryEntry, type HistoryPage, type IncomingDelivery, type IntentBackstopEntry, type IntentPayload, type InventoryAsset, type InventoryItem, type InventoryPage, MAX_RESELECT, type MintCustomRequest, type MintJournalEntry, type MintNftRequest, type MintResult, NFT_DOCUMENT_MEDIA_TYPE, NFT_LINK_TAG, NFT_MAX_PAYLOAD_BYTES, NFT_MEDIA_TAG, NFT_METADATA_TAG, NFT_SIGNED_TAG, type NftAttribute, type NftContent, type NftLink, type NftMedia, type NftMediaRef, type NftMetadata, type NftMintJournalEntry, type NftSignatureContext, type NftSignatureStatus, type NftView, type OpOutcome, type OutcomeClass, type PaymentRequestStatus, type PaymentRequestView, PaymentsFacade, type PaymentsFacadeDeps, type PaymentsRequestsApi, type PaymentsV2, type PaymentsV2Events, type PendingBurn, type PendingTransfer, type PlannedOp, type RecipientInfo, type RetryableAckError, STORE_KEYS, type ScopedKV, type SendCoinlessRequest, type SendRequest, type SendWholeTokenRequest, type SettlingLink, type ShortfallEntry, type StoragePort, type StreamCursor, type StreamName, createScopedKV, encodeNftContent, isNftDocumentLink, isRetryableAckError, parseNftDocument, parseNftPayload, supportsDeterministicMint, sweepSupersededState, verifyNftLinkContent };
|