@unicitylabs/sphere-sdk 0.14.11-dev.8 → 0.15.0-dev.1
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/README.md +55 -17
- package/dist/connect/index.cjs +10 -17
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +10 -17
- package/dist/connect/index.js.map +1 -1
- package/dist/core/index.cjs +98 -99
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +5 -14
- package/dist/core/index.d.ts +5 -14
- package/dist/core/index.js +98 -99
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/connect/index.cjs +3 -3
- package/dist/impl/browser/connect/index.cjs.map +1 -1
- package/dist/impl/browser/connect/index.js +3 -3
- package/dist/impl/browser/connect/index.js.map +1 -1
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/nodejs/connect/index.cjs +2 -2
- package/dist/impl/nodejs/connect/index.cjs.map +1 -1
- package/dist/impl/nodejs/connect/index.js +2 -2
- package/dist/impl/nodejs/connect/index.js.map +1 -1
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/impl/wallet-api-v2/index.cjs +95 -1
- package/dist/impl/wallet-api-v2/index.cjs.map +1 -1
- package/dist/impl/wallet-api-v2/index.js +95 -1
- package/dist/impl/wallet-api-v2/index.js.map +1 -1
- package/dist/index.cjs +98 -99
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -11
- package/dist/index.d.ts +6 -11
- package/dist/index.js +98 -99
- package/dist/index.js.map +1 -1
- package/dist/modules/payments-v2/index.cjs +149 -193
- package/dist/modules/payments-v2/index.cjs.map +1 -1
- package/dist/modules/payments-v2/index.d.cts +8 -5
- package/dist/modules/payments-v2/index.d.ts +8 -5
- package/dist/modules/payments-v2/index.js +146 -192
- package/dist/modules/payments-v2/index.js.map +1 -1
- package/dist/token-engine/index.cjs +43 -57
- package/dist/token-engine/index.cjs.map +1 -1
- package/dist/token-engine/index.d.cts +0 -4
- package/dist/token-engine/index.d.ts +0 -4
- package/dist/token-engine/index.js +43 -57
- package/dist/token-engine/index.js.map +1 -1
- package/package.json +2 -2
package/dist/core/index.d.cts
CHANGED
|
@@ -2286,10 +2286,6 @@ interface SphereValue {
|
|
|
2286
2286
|
* `token`, so it is NOT stored — only cached at runtime on SphereToken.value.
|
|
2287
2287
|
*/
|
|
2288
2288
|
interface TokenBlob {
|
|
2289
|
-
/** Blob format version (sphere storage migrations; independent of SDK CBOR). */
|
|
2290
|
-
readonly v: number;
|
|
2291
|
-
/** NetworkId.id the token belongs to (mainnet=1 / testnet=2 / local=3). */
|
|
2292
|
-
readonly network: number;
|
|
2293
2289
|
/**
|
|
2294
2290
|
* Genesis-stable token id — 64-char lowercase hex of the v2 `TokenId.bytes`
|
|
2295
2291
|
* (same across every state of the token). Stored on the blob so dedup / listing
|
|
@@ -3048,8 +3044,6 @@ type InitProgressCallback = (progress: InitProgress) => void;
|
|
|
3048
3044
|
interface SphereWalletApiOptions {
|
|
3049
3045
|
/** Wallet-api transport config — REQUIRED (init throws INVALID_CONFIG without it). */
|
|
3050
3046
|
walletApi?: WalletApiTransportConfig;
|
|
3051
|
-
/** @deprecated The payments-v2 vertical is the only path since the P11 flip — accepted as a no-op for one release. */
|
|
3052
|
-
paymentsV2?: boolean;
|
|
3053
3047
|
/** @deprecated REMOVED with the P11 flip — any truthy value throws INVALID_CONFIG (invoicing no longer exists in the SDK). */
|
|
3054
3048
|
accounting?: unknown;
|
|
3055
3049
|
/** @deprecated REMOVED with the P11 flip — any truthy value throws INVALID_CONFIG (swaps no longer exist in the SDK). */
|
|
@@ -3398,11 +3392,10 @@ declare class Sphere {
|
|
|
3398
3392
|
*/
|
|
3399
3393
|
private static resolveMarketConfig;
|
|
3400
3394
|
/**
|
|
3401
|
-
* The ONE sanctioned refusal fossil of the P11 flip
|
|
3402
|
-
*
|
|
3403
|
-
*
|
|
3404
|
-
*
|
|
3405
|
-
* live frontend passes it today).
|
|
3395
|
+
* The ONE sanctioned refusal fossil of the P11 flip: `accounting`/`swap` were
|
|
3396
|
+
* public init flags — silently ignoring them would hide that invoices/swaps no
|
|
3397
|
+
* longer exist in the SDK. Kept through 0.15.0, where consumers re-integrate
|
|
3398
|
+
* across the wire break and a silent no-op would be worst.
|
|
3406
3399
|
*/
|
|
3407
3400
|
private static refuseRetiredModuleOptions;
|
|
3408
3401
|
/**
|
|
@@ -3429,7 +3422,7 @@ declare class Sphere {
|
|
|
3429
3422
|
static import(options: SphereImportOptions): Promise<Sphere>;
|
|
3430
3423
|
/**
|
|
3431
3424
|
* Clear all SDK-owned wallet data from storage: wallet keys, per-address
|
|
3432
|
-
* data, and the payments vertical's `
|
|
3425
|
+
* data, and the payments vertical's `pv2g2:{network}:{pubkey}:*` scoped KV
|
|
3433
3426
|
* (refresh token, cursors, journals — all live in the plain StorageProvider,
|
|
3434
3427
|
* so the full KV wipe below removes them). Tokens are server-custody; the
|
|
3435
3428
|
* only local token artifacts are orphaned `sphere-token-storage-*` IndexedDB
|
|
@@ -3475,8 +3468,6 @@ declare class Sphere {
|
|
|
3475
3468
|
static generateMnemonic(strength?: 128 | 256): string;
|
|
3476
3469
|
/** Payments (the §4 facade — the active address's running vertical). */
|
|
3477
3470
|
get payments(): PaymentsV2;
|
|
3478
|
-
/** @deprecated Alias of {@link payments} kept for one release (the live frontend calls it). Null when no vertical runs. */
|
|
3479
|
-
get paymentsV2(): PaymentsV2 | null;
|
|
3480
3471
|
/** Communications module */
|
|
3481
3472
|
get communications(): CommunicationsModule;
|
|
3482
3473
|
/** Group chat module (NIP-29). Null if not configured. */
|
package/dist/core/index.d.ts
CHANGED
|
@@ -2286,10 +2286,6 @@ interface SphereValue {
|
|
|
2286
2286
|
* `token`, so it is NOT stored — only cached at runtime on SphereToken.value.
|
|
2287
2287
|
*/
|
|
2288
2288
|
interface TokenBlob {
|
|
2289
|
-
/** Blob format version (sphere storage migrations; independent of SDK CBOR). */
|
|
2290
|
-
readonly v: number;
|
|
2291
|
-
/** NetworkId.id the token belongs to (mainnet=1 / testnet=2 / local=3). */
|
|
2292
|
-
readonly network: number;
|
|
2293
2289
|
/**
|
|
2294
2290
|
* Genesis-stable token id — 64-char lowercase hex of the v2 `TokenId.bytes`
|
|
2295
2291
|
* (same across every state of the token). Stored on the blob so dedup / listing
|
|
@@ -3048,8 +3044,6 @@ type InitProgressCallback = (progress: InitProgress) => void;
|
|
|
3048
3044
|
interface SphereWalletApiOptions {
|
|
3049
3045
|
/** Wallet-api transport config — REQUIRED (init throws INVALID_CONFIG without it). */
|
|
3050
3046
|
walletApi?: WalletApiTransportConfig;
|
|
3051
|
-
/** @deprecated The payments-v2 vertical is the only path since the P11 flip — accepted as a no-op for one release. */
|
|
3052
|
-
paymentsV2?: boolean;
|
|
3053
3047
|
/** @deprecated REMOVED with the P11 flip — any truthy value throws INVALID_CONFIG (invoicing no longer exists in the SDK). */
|
|
3054
3048
|
accounting?: unknown;
|
|
3055
3049
|
/** @deprecated REMOVED with the P11 flip — any truthy value throws INVALID_CONFIG (swaps no longer exist in the SDK). */
|
|
@@ -3398,11 +3392,10 @@ declare class Sphere {
|
|
|
3398
3392
|
*/
|
|
3399
3393
|
private static resolveMarketConfig;
|
|
3400
3394
|
/**
|
|
3401
|
-
* The ONE sanctioned refusal fossil of the P11 flip
|
|
3402
|
-
*
|
|
3403
|
-
*
|
|
3404
|
-
*
|
|
3405
|
-
* live frontend passes it today).
|
|
3395
|
+
* The ONE sanctioned refusal fossil of the P11 flip: `accounting`/`swap` were
|
|
3396
|
+
* public init flags — silently ignoring them would hide that invoices/swaps no
|
|
3397
|
+
* longer exist in the SDK. Kept through 0.15.0, where consumers re-integrate
|
|
3398
|
+
* across the wire break and a silent no-op would be worst.
|
|
3406
3399
|
*/
|
|
3407
3400
|
private static refuseRetiredModuleOptions;
|
|
3408
3401
|
/**
|
|
@@ -3429,7 +3422,7 @@ declare class Sphere {
|
|
|
3429
3422
|
static import(options: SphereImportOptions): Promise<Sphere>;
|
|
3430
3423
|
/**
|
|
3431
3424
|
* Clear all SDK-owned wallet data from storage: wallet keys, per-address
|
|
3432
|
-
* data, and the payments vertical's `
|
|
3425
|
+
* data, and the payments vertical's `pv2g2:{network}:{pubkey}:*` scoped KV
|
|
3433
3426
|
* (refresh token, cursors, journals — all live in the plain StorageProvider,
|
|
3434
3427
|
* so the full KV wipe below removes them). Tokens are server-custody; the
|
|
3435
3428
|
* only local token artifacts are orphaned `sphere-token-storage-*` IndexedDB
|
|
@@ -3475,8 +3468,6 @@ declare class Sphere {
|
|
|
3475
3468
|
static generateMnemonic(strength?: 128 | 256): string;
|
|
3476
3469
|
/** Payments (the §4 facade — the active address's running vertical). */
|
|
3477
3470
|
get payments(): PaymentsV2;
|
|
3478
|
-
/** @deprecated Alias of {@link payments} kept for one release (the live frontend calls it). Null when no vertical runs. */
|
|
3479
|
-
get paymentsV2(): PaymentsV2 | null;
|
|
3480
3471
|
/** Communications module */
|
|
3481
3472
|
get communications(): CommunicationsModule;
|
|
3482
3473
|
/** Group chat module (NIP-29). Null if not configured. */
|
package/dist/core/index.js
CHANGED
|
@@ -9385,7 +9385,15 @@ function resolveProofTimeoutMs(configured) {
|
|
|
9385
9385
|
return configured;
|
|
9386
9386
|
}
|
|
9387
9387
|
var TRANSIENT_HTTP_STATUSES = /* @__PURE__ */ new Set([408, 425, 429, 500, 502, 503, 504]);
|
|
9388
|
+
var TransientSubmitAnswer = class extends Error {
|
|
9389
|
+
constructor(status) {
|
|
9390
|
+
super(`gateway is not ready to certify yet (${status})`);
|
|
9391
|
+
this.status = status;
|
|
9392
|
+
this.name = "TransientSubmitAnswer";
|
|
9393
|
+
}
|
|
9394
|
+
};
|
|
9388
9395
|
function isTransientGatewayError(err) {
|
|
9396
|
+
if (err instanceof TransientSubmitAnswer) return true;
|
|
9389
9397
|
return err instanceof JsonRpcNetworkError && TRANSIENT_HTTP_STATUSES.has(err.status);
|
|
9390
9398
|
}
|
|
9391
9399
|
function pause(ms, signal) {
|
|
@@ -9506,37 +9514,9 @@ function certificationFailure(err, failLabel, submitError, submitRejectedCleanly
|
|
|
9506
9514
|
);
|
|
9507
9515
|
}
|
|
9508
9516
|
|
|
9509
|
-
// token-engine/token-blob.ts
|
|
9510
|
-
var TOKEN_BLOB_TAG = 39051n;
|
|
9511
|
-
var TOKEN_BLOB_VERSION = 1;
|
|
9512
|
-
function decodeTokenBlob(bytes) {
|
|
9513
|
-
const tag = CborDeserializer.decodeTag(bytes);
|
|
9514
|
-
if (tag.tag !== TOKEN_BLOB_TAG) {
|
|
9515
|
-
throw new CborError(`Invalid TokenBlob tag: ${tag.tag}`);
|
|
9516
|
-
}
|
|
9517
|
-
const fields = CborDeserializer.decodeArray(tag.data, 4);
|
|
9518
|
-
const v = Number(CborDeserializer.decodeUnsignedInteger(fields[0]));
|
|
9519
|
-
if (v !== TOKEN_BLOB_VERSION) {
|
|
9520
|
-
throw new CborError(`Unsupported TokenBlob version: ${v}`);
|
|
9521
|
-
}
|
|
9522
|
-
return {
|
|
9523
|
-
v,
|
|
9524
|
-
network: Number(CborDeserializer.decodeUnsignedInteger(fields[1])),
|
|
9525
|
-
tokenId: CborDeserializer.decodeTextString(fields[2]),
|
|
9526
|
-
token: CborDeserializer.decodeByteString(fields[3])
|
|
9527
|
-
};
|
|
9528
|
-
}
|
|
9529
|
-
function unwrapTokenBlobBytes(bytes) {
|
|
9530
|
-
try {
|
|
9531
|
-
return decodeTokenBlob(bytes).token;
|
|
9532
|
-
} catch {
|
|
9533
|
-
return bytes;
|
|
9534
|
-
}
|
|
9535
|
-
}
|
|
9536
|
-
|
|
9537
9517
|
// token-engine/blob-keys.ts
|
|
9538
9518
|
async function deriveDeliveryKeys(blobBytes) {
|
|
9539
|
-
const token = await Token.fromCBOR(
|
|
9519
|
+
const token = await Token.fromCBOR(blobBytes);
|
|
9540
9520
|
const stateHash = HexConverter.encode((await token.latestTransaction.calculateStateHash()).imprint);
|
|
9541
9521
|
return { tokenId: HexConverter.encode(token.id.bytes), stateHash };
|
|
9542
9522
|
}
|
|
@@ -9590,8 +9570,8 @@ function deriveRealization(privKeyHex, transferId, index, field) {
|
|
|
9590
9570
|
}
|
|
9591
9571
|
|
|
9592
9572
|
// token-engine/split-checkpoint.ts
|
|
9593
|
-
var CHECKPOINT_VERSION =
|
|
9594
|
-
var CHECKPOINT_SDK_VERSION = "@unicitylabs/state-transition-sdk@
|
|
9573
|
+
var CHECKPOINT_VERSION = 2;
|
|
9574
|
+
var CHECKPOINT_SDK_VERSION = "@unicitylabs/state-transition-sdk@3.0.1";
|
|
9595
9575
|
function bytesEqual(a, b) {
|
|
9596
9576
|
if (a.length !== b.length) return false;
|
|
9597
9577
|
for (let i = 0; i < a.length; i++) {
|
|
@@ -9741,13 +9721,11 @@ var SphereTokenEngine = class {
|
|
|
9741
9721
|
const data = params.value ? await SpherePaymentData.fromValue(params.value).encode() : null;
|
|
9742
9722
|
const transferId = this.resolveTransferId(options);
|
|
9743
9723
|
const opIndex = this.resolveOpIndex(options);
|
|
9744
|
-
const mintTx = await MintTransaction.create(
|
|
9745
|
-
this.deps.networkId,
|
|
9746
|
-
recipient,
|
|
9724
|
+
const mintTx = await MintTransaction.create(this.deps.networkId, recipient, {
|
|
9747
9725
|
data,
|
|
9748
|
-
new TokenType(deriveRealization(this.privateKeyHex, transferId, opIndex, "tokenType")),
|
|
9749
|
-
TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, opIndex, "mint"))
|
|
9750
|
-
);
|
|
9726
|
+
tokenType: new TokenType(deriveRealization(this.privateKeyHex, transferId, opIndex, "tokenType")),
|
|
9727
|
+
salt: TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, opIndex, "mint"))
|
|
9728
|
+
});
|
|
9751
9729
|
const certificationData = await CertificationData.fromMintTransaction(mintTx);
|
|
9752
9730
|
const proof = await this.submitAndAwaitProof(
|
|
9753
9731
|
certificationData,
|
|
@@ -9764,7 +9742,7 @@ var SphereTokenEngine = class {
|
|
|
9764
9742
|
const recipient = SignaturePredicate.create(params.recipientPubkey);
|
|
9765
9743
|
const tokenType = params.tokenType ? new TokenType(params.tokenType) : TokenType.generate();
|
|
9766
9744
|
const salt = params.salt ? TokenSalt.fromBytes(params.salt) : TokenSalt.generate();
|
|
9767
|
-
const mintTx = await MintTransaction.create(this.deps.networkId, recipient, params.data, tokenType, salt);
|
|
9745
|
+
const mintTx = await MintTransaction.create(this.deps.networkId, recipient, { data: params.data, tokenType, salt });
|
|
9768
9746
|
const certificationData = await CertificationData.fromMintTransaction(mintTx);
|
|
9769
9747
|
const proof = await this.submitAndAwaitProof(
|
|
9770
9748
|
certificationData,
|
|
@@ -9784,7 +9762,9 @@ var SphereTokenEngine = class {
|
|
|
9784
9762
|
const stateMask = StateMask.fromBytes(
|
|
9785
9763
|
deriveRealization(this.privateKeyHex, transferId, this.resolveOpIndex(options), "stateMask")
|
|
9786
9764
|
);
|
|
9787
|
-
const transferTx = await TransferTransaction.create(params.token.sdkToken, recipient, stateMask,
|
|
9765
|
+
const transferTx = await TransferTransaction.create(params.token.sdkToken, recipient, stateMask, {
|
|
9766
|
+
data: params.data ?? null
|
|
9767
|
+
});
|
|
9788
9768
|
const unlockScript = await SignaturePredicateUnlockScript.create(transferTx, this.deps.signingService);
|
|
9789
9769
|
const certificationData = await CertificationData.fromTransaction(transferTx, unlockScript);
|
|
9790
9770
|
const proof = await this.submitAndAwaitProof(
|
|
@@ -9811,12 +9791,11 @@ var SphereTokenEngine = class {
|
|
|
9811
9791
|
TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, i, "salt"))
|
|
9812
9792
|
)
|
|
9813
9793
|
);
|
|
9814
|
-
const split = await TokenSplit.split(
|
|
9815
|
-
|
|
9816
|
-
|
|
9817
|
-
|
|
9818
|
-
|
|
9819
|
-
);
|
|
9794
|
+
const split = await TokenSplit.split(params.token.sdkToken, decodeSpherePaymentData, requests, {
|
|
9795
|
+
burnStateMask: StateMask.fromBytes(
|
|
9796
|
+
deriveRealization(this.privateKeyHex, transferId, this.resolveOpIndex(options), "burn")
|
|
9797
|
+
)
|
|
9798
|
+
});
|
|
9820
9799
|
const burntToken = await this.resolveBurntToken({ params, split, transferId, options });
|
|
9821
9800
|
const settled = [];
|
|
9822
9801
|
for (let start = 0; start < split.tokens.length; start += MAX_MINT_CONCURRENCY) {
|
|
@@ -9896,9 +9875,14 @@ var SphereTokenEngine = class {
|
|
|
9896
9875
|
await Promise.all(
|
|
9897
9876
|
ctx.split.tokens.map(async (leg) => {
|
|
9898
9877
|
const data = await leg.paymentData.encode();
|
|
9899
|
-
const probe = await MintTransaction.create(leg.networkId, leg.recipient,
|
|
9878
|
+
const probe = await MintTransaction.create(leg.networkId, leg.recipient, {
|
|
9879
|
+
data,
|
|
9880
|
+
tokenType: leg.tokenType,
|
|
9881
|
+
salt: leg.salt,
|
|
9882
|
+
justification: null
|
|
9883
|
+
});
|
|
9900
9884
|
const response = await this.deps.client.getInclusionProof(await StateId.fromTransaction(probe));
|
|
9901
|
-
if (response.inclusionProof
|
|
9885
|
+
if (response.inclusionProof !== null) {
|
|
9902
9886
|
throw new SplitCheckpointLostError(
|
|
9903
9887
|
"a split mint leaf is certified on-chain but no burn checkpoint exists \u2014 outputs are unrecoverable"
|
|
9904
9888
|
);
|
|
@@ -9910,14 +9894,12 @@ var SphereTokenEngine = class {
|
|
|
9910
9894
|
async mintSplitOutput(splitToken, burntToken, options) {
|
|
9911
9895
|
const data = await splitToken.paymentData.encode();
|
|
9912
9896
|
const justification = SplitMintJustification.create(burntToken, splitToken.proofs).toCBOR();
|
|
9913
|
-
const mintTx = await MintTransaction.create(
|
|
9914
|
-
splitToken.networkId,
|
|
9915
|
-
splitToken.recipient,
|
|
9897
|
+
const mintTx = await MintTransaction.create(splitToken.networkId, splitToken.recipient, {
|
|
9916
9898
|
data,
|
|
9917
|
-
splitToken.tokenType,
|
|
9918
|
-
splitToken.salt,
|
|
9899
|
+
tokenType: splitToken.tokenType,
|
|
9900
|
+
salt: splitToken.salt,
|
|
9919
9901
|
justification
|
|
9920
|
-
);
|
|
9902
|
+
});
|
|
9921
9903
|
const certData = await CertificationData.fromMintTransaction(mintTx);
|
|
9922
9904
|
const proof = await this.submitSplitMintLeg(certData, mintTx, options);
|
|
9923
9905
|
const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);
|
|
@@ -9962,7 +9944,7 @@ var SphereTokenEngine = class {
|
|
|
9962
9944
|
);
|
|
9963
9945
|
const stateId = await StateId.fromTransaction(probe);
|
|
9964
9946
|
const response = await this.deps.client.getInclusionProof(stateId);
|
|
9965
|
-
return response.inclusionProof
|
|
9947
|
+
return response.inclusionProof !== null;
|
|
9966
9948
|
}
|
|
9967
9949
|
// ── serialization ────────────────────────────────────────────────────────────
|
|
9968
9950
|
/** @inheritDoc — SDK-derived (Token.fromCBOR → latestTransaction.calculateStateHash().imprint). */
|
|
@@ -10046,7 +10028,13 @@ var SphereTokenEngine = class {
|
|
|
10046
10028
|
let submitRejectedCleanly = false;
|
|
10047
10029
|
try {
|
|
10048
10030
|
const { value: response, retried } = await retryTransient(
|
|
10049
|
-
() =>
|
|
10031
|
+
async () => {
|
|
10032
|
+
const answer = await this.deps.client.submitCertificationRequest(certificationData);
|
|
10033
|
+
if (String(answer.status) === String(CertificationStatus.SERVICE_NOT_READY)) {
|
|
10034
|
+
throw new TransientSubmitAnswer(String(answer.status));
|
|
10035
|
+
}
|
|
10036
|
+
return answer;
|
|
10037
|
+
},
|
|
10050
10038
|
signal,
|
|
10051
10039
|
this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS
|
|
10052
10040
|
);
|
|
@@ -10101,8 +10089,6 @@ var SphereTokenEngine = class {
|
|
|
10101
10089
|
}
|
|
10102
10090
|
}
|
|
10103
10091
|
const blob = {
|
|
10104
|
-
v: TOKEN_BLOB_VERSION,
|
|
10105
|
-
network: sdkToken.genesis.networkId.id,
|
|
10106
10092
|
tokenId: HexConverter.encode(sdkToken.id.bytes),
|
|
10107
10093
|
token: sdkToken.toCBOR()
|
|
10108
10094
|
};
|
|
@@ -11246,8 +11232,19 @@ function coalesced(run, observe) {
|
|
|
11246
11232
|
}
|
|
11247
11233
|
|
|
11248
11234
|
// modules/payments-v2/stores.ts
|
|
11235
|
+
var KV_PREFIX = "pv2g2:";
|
|
11236
|
+
var SUPERSEDED_KV_PREFIXES = ["pv2:"];
|
|
11237
|
+
async function sweepSupersededState(storage) {
|
|
11238
|
+
for (const prefix of SUPERSEDED_KV_PREFIXES) {
|
|
11239
|
+
try {
|
|
11240
|
+
await storage.clear(prefix);
|
|
11241
|
+
} catch (err) {
|
|
11242
|
+
logger.warn("PaymentsV2", `could not clear superseded state under "${prefix}": ${String(err)}`);
|
|
11243
|
+
}
|
|
11244
|
+
}
|
|
11245
|
+
}
|
|
11249
11246
|
function createScopedKV(storage, network, chainPubkey) {
|
|
11250
|
-
const prefix =
|
|
11247
|
+
const prefix = `${KV_PREFIX}${network}:${chainPubkey}:`;
|
|
11251
11248
|
return {
|
|
11252
11249
|
async get(key) {
|
|
11253
11250
|
const raw = await storage.get(prefix + key);
|
|
@@ -11829,12 +11826,7 @@ var TransferMachine = class {
|
|
|
11829
11826
|
let total = 0n;
|
|
11830
11827
|
for (const outcome of committed) {
|
|
11831
11828
|
if (outcome.recipientBlob === void 0) continue;
|
|
11832
|
-
const token = await engine.decodeToken({
|
|
11833
|
-
v: TOKEN_BLOB_VERSION,
|
|
11834
|
-
network: 0,
|
|
11835
|
-
tokenId: "",
|
|
11836
|
-
token: outcome.recipientBlob
|
|
11837
|
-
});
|
|
11829
|
+
const token = await engine.decodeToken({ tokenId: "", token: outcome.recipientBlob });
|
|
11838
11830
|
total += engine.balanceOf(token, coinId);
|
|
11839
11831
|
}
|
|
11840
11832
|
return total.toString();
|
|
@@ -11950,8 +11942,9 @@ async function fetchSources(deps, jobs) {
|
|
|
11950
11942
|
const engine = deps.engine();
|
|
11951
11943
|
for (const [tokenId, bytes] of blobs) {
|
|
11952
11944
|
try {
|
|
11953
|
-
decoded.set(tokenId, await engine.decodeToken({
|
|
11954
|
-
} catch {
|
|
11945
|
+
decoded.set(tokenId, await engine.decodeToken({ tokenId, token: bytes }));
|
|
11946
|
+
} catch (err) {
|
|
11947
|
+
logger.warn("PaymentsV2", `resume: source ${tokenId} did not decode \u2014 ${String(err)}`);
|
|
11955
11948
|
}
|
|
11956
11949
|
}
|
|
11957
11950
|
return decoded;
|
|
@@ -12978,22 +12971,24 @@ var Receive = class {
|
|
|
12978
12971
|
* the tokens just accepted, and the balance would still only move at the end.
|
|
12979
12972
|
* Ordering is preserved: store() still precedes the ack (§5.7).
|
|
12980
12973
|
*/
|
|
12981
|
-
async maybeRefresh(
|
|
12974
|
+
async maybeRefresh(ctx) {
|
|
12975
|
+
const { deps, pending, pageEpoch } = ctx;
|
|
12982
12976
|
if (deps.refreshView === void 0) return;
|
|
12983
12977
|
const now = deps.now?.() ?? Date.now();
|
|
12984
12978
|
if (now - this.lastRefreshAt < REFRESH_INTERVAL_MS) return;
|
|
12985
12979
|
this.lastRefreshAt = now;
|
|
12986
|
-
await flushAcks(deps, pending,
|
|
12987
|
-
deps.refreshView();
|
|
12980
|
+
if ((await flushAcks(deps, pending, pageEpoch)).progressed) deps.refreshView();
|
|
12988
12981
|
}
|
|
12989
12982
|
/** One listing pass: process each entry, flushing and refreshing as it goes. */
|
|
12990
12983
|
async drainPages(ctx, basis) {
|
|
12991
|
-
const { deps,
|
|
12984
|
+
const { deps, pending, pageEpoch, claimable } = ctx;
|
|
12992
12985
|
for await (const entry of deps.delivery.incoming(basis === null ? void 0 : String(basis.cursor))) {
|
|
12993
|
-
const
|
|
12994
|
-
await this.processEntry(
|
|
12995
|
-
if (pending.length >= ACK_BATCH_SIZE)
|
|
12996
|
-
|
|
12986
|
+
const claimableBefore = claimable.n;
|
|
12987
|
+
await this.processEntry(ctx, entry);
|
|
12988
|
+
if (pending.length >= ACK_BATCH_SIZE) {
|
|
12989
|
+
if (!(await flushAcks(deps, pending, pageEpoch)).progressed) return;
|
|
12990
|
+
}
|
|
12991
|
+
if (claimable.n > claimableBefore) await this.maybeRefresh(ctx);
|
|
12997
12992
|
}
|
|
12998
12993
|
await flushAcks(deps, pending, pageEpoch);
|
|
12999
12994
|
}
|
|
@@ -13004,11 +12999,16 @@ var Receive = class {
|
|
|
13004
12999
|
const stored = [];
|
|
13005
13000
|
const pending = [];
|
|
13006
13001
|
const pageEpoch = () => deps.delivery.incomingEpoch() ?? deps.syncEpoch();
|
|
13002
|
+
const claimable = { n: 0 };
|
|
13003
|
+
const finish = () => {
|
|
13004
|
+
if (claimable.n > 0) deps.refreshView?.();
|
|
13005
|
+
return stored;
|
|
13006
|
+
};
|
|
13007
13007
|
try {
|
|
13008
13008
|
const record = await deps.kv.get(STORE_KEYS.streamCursor("mailbox"));
|
|
13009
13009
|
let basis = record !== null && record.syncEpoch === deps.syncEpoch() ? record : null;
|
|
13010
13010
|
for (let pass = 0; pass < 2; pass++) {
|
|
13011
|
-
await this.drainPages({ deps, engine, pending, stored, pageEpoch }, basis);
|
|
13011
|
+
await this.drainPages({ deps, engine, pending, stored, pageEpoch, claimable }, basis);
|
|
13012
13012
|
const served = deps.delivery.incomingEpoch();
|
|
13013
13013
|
if (basis === null || served === null || served === basis.syncEpoch) break;
|
|
13014
13014
|
await deps.kv.remove(STORE_KEYS.streamCursor("mailbox"));
|
|
@@ -13016,22 +13016,25 @@ var Receive = class {
|
|
|
13016
13016
|
}
|
|
13017
13017
|
} catch (err) {
|
|
13018
13018
|
logger.warn("PaymentsV2", "receive drain interrupted \u2014 unacked entries retry next drain:", err);
|
|
13019
|
-
if (isRetryableAckError(err)) return
|
|
13019
|
+
if (isRetryableAckError(err)) return finish();
|
|
13020
13020
|
await flushAcks(deps, pending, pageEpoch).catch((flushErr) => {
|
|
13021
13021
|
logger.warn("PaymentsV2", "receive ack flush failed \u2014 cursor holds at the acked prefix:", flushErr);
|
|
13022
|
+
return { progressed: false };
|
|
13022
13023
|
});
|
|
13023
13024
|
}
|
|
13024
|
-
|
|
13025
|
-
return stored;
|
|
13025
|
+
return finish();
|
|
13026
13026
|
}
|
|
13027
|
-
async processEntry(
|
|
13027
|
+
async processEntry(ctx, entry) {
|
|
13028
|
+
const { deps, engine, pending, stored, claimable } = ctx;
|
|
13028
13029
|
const screened = await screen(deps, engine, entry);
|
|
13029
13030
|
if (screened.kind === "ack") {
|
|
13030
13031
|
pending.push(screened.ack);
|
|
13032
|
+
if (screened.ack.disposition === "claimed") claimable.n += 1;
|
|
13031
13033
|
return;
|
|
13032
13034
|
}
|
|
13033
13035
|
await deps.view.store(screened.record);
|
|
13034
13036
|
pending.push(claimAck(entry));
|
|
13037
|
+
claimable.n += 1;
|
|
13035
13038
|
const transfer = await announce(deps, entry, screened.record);
|
|
13036
13039
|
stored.push(transfer);
|
|
13037
13040
|
deps.emit("transfer:incoming", transfer);
|
|
@@ -13041,13 +13044,9 @@ async function screen(deps, engine, entry) {
|
|
|
13041
13044
|
const blobBytes = await entry.fetchBlob();
|
|
13042
13045
|
let token;
|
|
13043
13046
|
try {
|
|
13044
|
-
token = await engine.decodeToken({
|
|
13045
|
-
|
|
13046
|
-
|
|
13047
|
-
tokenId: "",
|
|
13048
|
-
token: blobBytes
|
|
13049
|
-
});
|
|
13050
|
-
} catch {
|
|
13047
|
+
token = await engine.decodeToken({ tokenId: "", token: blobBytes });
|
|
13048
|
+
} catch (err) {
|
|
13049
|
+
logger.warn("PaymentsV2", `receive: undecodable blob rejected \u2014 ${String(err)}`);
|
|
13051
13050
|
return { kind: "ack", ack: rejectAck(entry, "invalid") };
|
|
13052
13051
|
}
|
|
13053
13052
|
const verdict = await engine.verify(token);
|
|
@@ -13092,7 +13091,8 @@ async function announce(deps, entry, record) {
|
|
|
13092
13091
|
};
|
|
13093
13092
|
}
|
|
13094
13093
|
async function flushAcks(deps, pending, epochOf) {
|
|
13095
|
-
if (pending.length === 0) return;
|
|
13094
|
+
if (pending.length === 0) return { progressed: true };
|
|
13095
|
+
const before = pending.length;
|
|
13096
13096
|
let lastAcked = null;
|
|
13097
13097
|
try {
|
|
13098
13098
|
const settled = await settleAcks(deps, pending);
|
|
@@ -13110,6 +13110,7 @@ async function flushAcks(deps, pending, epochOf) {
|
|
|
13110
13110
|
await deps.kv.set(STORE_KEYS.streamCursor("mailbox"), record);
|
|
13111
13111
|
}
|
|
13112
13112
|
}
|
|
13113
|
+
return { progressed: pending.length < before };
|
|
13113
13114
|
}
|
|
13114
13115
|
async function settleAcks(deps, pending) {
|
|
13115
13116
|
const batch = deps.delivery.ackBatch?.bind(deps.delivery);
|
|
@@ -14448,7 +14449,7 @@ var PaymentsFacade = class {
|
|
|
14448
14449
|
if (bytes === void 0) {
|
|
14449
14450
|
throw new SphereError(`Selected source ${tokenId} has no blob in storage`, "STORAGE_ERROR");
|
|
14450
14451
|
}
|
|
14451
|
-
const token = await engine.decodeToken({
|
|
14452
|
+
const token = await engine.decodeToken({ tokenId, token: bytes });
|
|
14452
14453
|
const keys = await engine.deliveryKeys(bytes);
|
|
14453
14454
|
spentStates[tokenId] = { local: keys.stateHash, protocol: keys.stateHash };
|
|
14454
14455
|
sources.set(tokenId, token);
|
|
@@ -15630,7 +15631,9 @@ var WalletApiDeliveryPort = class {
|
|
|
15630
15631
|
await this.settleClaims(acks, settled, outcomes);
|
|
15631
15632
|
await this.settleRejects(acks, settled);
|
|
15632
15633
|
} catch (err) {
|
|
15633
|
-
await this.addSeenAll(settled).catch(() =>
|
|
15634
|
+
await this.addSeenAll(settled).catch((seenErr) => {
|
|
15635
|
+
logger.warn("WalletApiDelivery", `seen-set write failed for ${String(settled.length)} committed acks:`, seenErr);
|
|
15636
|
+
});
|
|
15634
15637
|
throw asRetryable(err);
|
|
15635
15638
|
}
|
|
15636
15639
|
await this.addSeenAll(settled);
|
|
@@ -15893,6 +15896,7 @@ function composePaymentsV2(spec) {
|
|
|
15893
15896
|
const network = spec.composition.network;
|
|
15894
15897
|
const identitySlice = { privateKey: identity.privateKey, chainPubkey: identity.chainPubkey };
|
|
15895
15898
|
const kv = createScopedKV(host.storage, network, identity.chainPubkey);
|
|
15899
|
+
void sweepSupersededState(host.storage);
|
|
15896
15900
|
const fieldKey = deriveFieldEncryptionKey(identity.privateKey);
|
|
15897
15901
|
const transport = spec.composition.factory({
|
|
15898
15902
|
identity: identitySlice,
|
|
@@ -16184,11 +16188,10 @@ var Sphere = class _Sphere {
|
|
|
16184
16188
|
return config;
|
|
16185
16189
|
}
|
|
16186
16190
|
/**
|
|
16187
|
-
* The ONE sanctioned refusal fossil of the P11 flip
|
|
16188
|
-
*
|
|
16189
|
-
*
|
|
16190
|
-
*
|
|
16191
|
-
* live frontend passes it today).
|
|
16191
|
+
* The ONE sanctioned refusal fossil of the P11 flip: `accounting`/`swap` were
|
|
16192
|
+
* public init flags — silently ignoring them would hide that invoices/swaps no
|
|
16193
|
+
* longer exist in the SDK. Kept through 0.15.0, where consumers re-integrate
|
|
16194
|
+
* across the wire break and a silent no-op would be worst.
|
|
16192
16195
|
*/
|
|
16193
16196
|
static refuseRetiredModuleOptions(options) {
|
|
16194
16197
|
if (options.accounting) {
|
|
@@ -16455,7 +16458,7 @@ var Sphere = class _Sphere {
|
|
|
16455
16458
|
}
|
|
16456
16459
|
/**
|
|
16457
16460
|
* Clear all SDK-owned wallet data from storage: wallet keys, per-address
|
|
16458
|
-
* data, and the payments vertical's `
|
|
16461
|
+
* data, and the payments vertical's `pv2g2:{network}:{pubkey}:*` scoped KV
|
|
16459
16462
|
* (refresh token, cursors, journals — all live in the plain StorageProvider,
|
|
16460
16463
|
* so the full KV wipe below removes them). Tokens are server-custody; the
|
|
16461
16464
|
* only local token artifacts are orphaned `sphere-token-storage-*` IndexedDB
|
|
@@ -16565,10 +16568,6 @@ var Sphere = class _Sphere {
|
|
|
16565
16568
|
}
|
|
16566
16569
|
return facade;
|
|
16567
16570
|
}
|
|
16568
|
-
/** @deprecated Alias of {@link payments} kept for one release (the live frontend calls it). Null when no vertical runs. */
|
|
16569
|
-
get paymentsV2() {
|
|
16570
|
-
return this._paymentsV2Active?.facade ?? null;
|
|
16571
|
-
}
|
|
16572
16571
|
/** Communications module */
|
|
16573
16572
|
get communications() {
|
|
16574
16573
|
this.ensureReady();
|