@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/index.d.cts
CHANGED
|
@@ -1964,7 +1964,7 @@ declare const STORAGE_KEYS_GLOBAL: {
|
|
|
1964
1964
|
* Example: sphere_DIRECT_abc123_xyz789_pending_transfers
|
|
1965
1965
|
*
|
|
1966
1966
|
* Note: Token data is server custody (wallet-api backend), not here; the
|
|
1967
|
-
* payments vertical's durable client state self-prefixes `
|
|
1967
|
+
* payments vertical's durable client state self-prefixes `pv2g2:{network}:{pubkey}:`.
|
|
1968
1968
|
*/
|
|
1969
1969
|
declare const STORAGE_KEYS_ADDRESS: {
|
|
1970
1970
|
/** Transfer outbox for this address (pre-flip key name; kept as the network-scoping witness) */
|
|
@@ -2743,8 +2743,6 @@ type InitProgressCallback = (progress: InitProgress) => void;
|
|
|
2743
2743
|
interface SphereWalletApiOptions {
|
|
2744
2744
|
/** Wallet-api transport config — REQUIRED (init throws INVALID_CONFIG without it). */
|
|
2745
2745
|
walletApi?: WalletApiTransportConfig;
|
|
2746
|
-
/** @deprecated The payments-v2 vertical is the only path since the P11 flip — accepted as a no-op for one release. */
|
|
2747
|
-
paymentsV2?: boolean;
|
|
2748
2746
|
/** @deprecated REMOVED with the P11 flip — any truthy value throws INVALID_CONFIG (invoicing no longer exists in the SDK). */
|
|
2749
2747
|
accounting?: unknown;
|
|
2750
2748
|
/** @deprecated REMOVED with the P11 flip — any truthy value throws INVALID_CONFIG (swaps no longer exist in the SDK). */
|
|
@@ -3076,11 +3074,10 @@ declare class Sphere {
|
|
|
3076
3074
|
*/
|
|
3077
3075
|
private static resolveMarketConfig;
|
|
3078
3076
|
/**
|
|
3079
|
-
* The ONE sanctioned refusal fossil of the P11 flip
|
|
3080
|
-
*
|
|
3081
|
-
*
|
|
3082
|
-
*
|
|
3083
|
-
* live frontend passes it today).
|
|
3077
|
+
* The ONE sanctioned refusal fossil of the P11 flip: `accounting`/`swap` were
|
|
3078
|
+
* public init flags — silently ignoring them would hide that invoices/swaps no
|
|
3079
|
+
* longer exist in the SDK. Kept through 0.15.0, where consumers re-integrate
|
|
3080
|
+
* across the wire break and a silent no-op would be worst.
|
|
3084
3081
|
*/
|
|
3085
3082
|
private static refuseRetiredModuleOptions;
|
|
3086
3083
|
/**
|
|
@@ -3107,7 +3104,7 @@ declare class Sphere {
|
|
|
3107
3104
|
static import(options: SphereImportOptions): Promise<Sphere>;
|
|
3108
3105
|
/**
|
|
3109
3106
|
* Clear all SDK-owned wallet data from storage: wallet keys, per-address
|
|
3110
|
-
* data, and the payments vertical's `
|
|
3107
|
+
* data, and the payments vertical's `pv2g2:{network}:{pubkey}:*` scoped KV
|
|
3111
3108
|
* (refresh token, cursors, journals — all live in the plain StorageProvider,
|
|
3112
3109
|
* so the full KV wipe below removes them). Tokens are server-custody; the
|
|
3113
3110
|
* only local token artifacts are orphaned `sphere-token-storage-*` IndexedDB
|
|
@@ -3153,8 +3150,6 @@ declare class Sphere {
|
|
|
3153
3150
|
static generateMnemonic(strength?: 128 | 256): string;
|
|
3154
3151
|
/** Payments (the §4 facade — the active address's running vertical). */
|
|
3155
3152
|
get payments(): PaymentsV2;
|
|
3156
|
-
/** @deprecated Alias of {@link payments} kept for one release (the live frontend calls it). Null when no vertical runs. */
|
|
3157
|
-
get paymentsV2(): PaymentsV2 | null;
|
|
3158
3153
|
/** Communications module */
|
|
3159
3154
|
get communications(): CommunicationsModule;
|
|
3160
3155
|
/** Group chat module (NIP-29). Null if not configured. */
|
package/dist/index.d.ts
CHANGED
|
@@ -1964,7 +1964,7 @@ declare const STORAGE_KEYS_GLOBAL: {
|
|
|
1964
1964
|
* Example: sphere_DIRECT_abc123_xyz789_pending_transfers
|
|
1965
1965
|
*
|
|
1966
1966
|
* Note: Token data is server custody (wallet-api backend), not here; the
|
|
1967
|
-
* payments vertical's durable client state self-prefixes `
|
|
1967
|
+
* payments vertical's durable client state self-prefixes `pv2g2:{network}:{pubkey}:`.
|
|
1968
1968
|
*/
|
|
1969
1969
|
declare const STORAGE_KEYS_ADDRESS: {
|
|
1970
1970
|
/** Transfer outbox for this address (pre-flip key name; kept as the network-scoping witness) */
|
|
@@ -2743,8 +2743,6 @@ type InitProgressCallback = (progress: InitProgress) => void;
|
|
|
2743
2743
|
interface SphereWalletApiOptions {
|
|
2744
2744
|
/** Wallet-api transport config — REQUIRED (init throws INVALID_CONFIG without it). */
|
|
2745
2745
|
walletApi?: WalletApiTransportConfig;
|
|
2746
|
-
/** @deprecated The payments-v2 vertical is the only path since the P11 flip — accepted as a no-op for one release. */
|
|
2747
|
-
paymentsV2?: boolean;
|
|
2748
2746
|
/** @deprecated REMOVED with the P11 flip — any truthy value throws INVALID_CONFIG (invoicing no longer exists in the SDK). */
|
|
2749
2747
|
accounting?: unknown;
|
|
2750
2748
|
/** @deprecated REMOVED with the P11 flip — any truthy value throws INVALID_CONFIG (swaps no longer exist in the SDK). */
|
|
@@ -3076,11 +3074,10 @@ declare class Sphere {
|
|
|
3076
3074
|
*/
|
|
3077
3075
|
private static resolveMarketConfig;
|
|
3078
3076
|
/**
|
|
3079
|
-
* The ONE sanctioned refusal fossil of the P11 flip
|
|
3080
|
-
*
|
|
3081
|
-
*
|
|
3082
|
-
*
|
|
3083
|
-
* live frontend passes it today).
|
|
3077
|
+
* The ONE sanctioned refusal fossil of the P11 flip: `accounting`/`swap` were
|
|
3078
|
+
* public init flags — silently ignoring them would hide that invoices/swaps no
|
|
3079
|
+
* longer exist in the SDK. Kept through 0.15.0, where consumers re-integrate
|
|
3080
|
+
* across the wire break and a silent no-op would be worst.
|
|
3084
3081
|
*/
|
|
3085
3082
|
private static refuseRetiredModuleOptions;
|
|
3086
3083
|
/**
|
|
@@ -3107,7 +3104,7 @@ declare class Sphere {
|
|
|
3107
3104
|
static import(options: SphereImportOptions): Promise<Sphere>;
|
|
3108
3105
|
/**
|
|
3109
3106
|
* Clear all SDK-owned wallet data from storage: wallet keys, per-address
|
|
3110
|
-
* data, and the payments vertical's `
|
|
3107
|
+
* data, and the payments vertical's `pv2g2:{network}:{pubkey}:*` scoped KV
|
|
3111
3108
|
* (refresh token, cursors, journals — all live in the plain StorageProvider,
|
|
3112
3109
|
* so the full KV wipe below removes them). Tokens are server-custody; the
|
|
3113
3110
|
* only local token artifacts are orphaned `sphere-token-storage-*` IndexedDB
|
|
@@ -3153,8 +3150,6 @@ declare class Sphere {
|
|
|
3153
3150
|
static generateMnemonic(strength?: 128 | 256): string;
|
|
3154
3151
|
/** Payments (the §4 facade — the active address's running vertical). */
|
|
3155
3152
|
get payments(): PaymentsV2;
|
|
3156
|
-
/** @deprecated Alias of {@link payments} kept for one release (the live frontend calls it). Null when no vertical runs. */
|
|
3157
|
-
get paymentsV2(): PaymentsV2 | null;
|
|
3158
3153
|
/** Communications module */
|
|
3159
3154
|
get communications(): CommunicationsModule;
|
|
3160
3155
|
/** Group chat module (NIP-29). Null if not configured. */
|
package/dist/index.js
CHANGED
|
@@ -9401,7 +9401,15 @@ function resolveProofTimeoutMs(configured) {
|
|
|
9401
9401
|
return configured;
|
|
9402
9402
|
}
|
|
9403
9403
|
var TRANSIENT_HTTP_STATUSES = /* @__PURE__ */ new Set([408, 425, 429, 500, 502, 503, 504]);
|
|
9404
|
+
var TransientSubmitAnswer = class extends Error {
|
|
9405
|
+
constructor(status) {
|
|
9406
|
+
super(`gateway is not ready to certify yet (${status})`);
|
|
9407
|
+
this.status = status;
|
|
9408
|
+
this.name = "TransientSubmitAnswer";
|
|
9409
|
+
}
|
|
9410
|
+
};
|
|
9404
9411
|
function isTransientGatewayError(err) {
|
|
9412
|
+
if (err instanceof TransientSubmitAnswer) return true;
|
|
9405
9413
|
return err instanceof JsonRpcNetworkError && TRANSIENT_HTTP_STATUSES.has(err.status);
|
|
9406
9414
|
}
|
|
9407
9415
|
function pause(ms, signal) {
|
|
@@ -9522,37 +9530,9 @@ function certificationFailure(err, failLabel, submitError, submitRejectedCleanly
|
|
|
9522
9530
|
);
|
|
9523
9531
|
}
|
|
9524
9532
|
|
|
9525
|
-
// token-engine/token-blob.ts
|
|
9526
|
-
var TOKEN_BLOB_TAG = 39051n;
|
|
9527
|
-
var TOKEN_BLOB_VERSION = 1;
|
|
9528
|
-
function decodeTokenBlob(bytes) {
|
|
9529
|
-
const tag = CborDeserializer.decodeTag(bytes);
|
|
9530
|
-
if (tag.tag !== TOKEN_BLOB_TAG) {
|
|
9531
|
-
throw new CborError(`Invalid TokenBlob tag: ${tag.tag}`);
|
|
9532
|
-
}
|
|
9533
|
-
const fields = CborDeserializer.decodeArray(tag.data, 4);
|
|
9534
|
-
const v = Number(CborDeserializer.decodeUnsignedInteger(fields[0]));
|
|
9535
|
-
if (v !== TOKEN_BLOB_VERSION) {
|
|
9536
|
-
throw new CborError(`Unsupported TokenBlob version: ${v}`);
|
|
9537
|
-
}
|
|
9538
|
-
return {
|
|
9539
|
-
v,
|
|
9540
|
-
network: Number(CborDeserializer.decodeUnsignedInteger(fields[1])),
|
|
9541
|
-
tokenId: CborDeserializer.decodeTextString(fields[2]),
|
|
9542
|
-
token: CborDeserializer.decodeByteString(fields[3])
|
|
9543
|
-
};
|
|
9544
|
-
}
|
|
9545
|
-
function unwrapTokenBlobBytes(bytes) {
|
|
9546
|
-
try {
|
|
9547
|
-
return decodeTokenBlob(bytes).token;
|
|
9548
|
-
} catch {
|
|
9549
|
-
return bytes;
|
|
9550
|
-
}
|
|
9551
|
-
}
|
|
9552
|
-
|
|
9553
9533
|
// token-engine/blob-keys.ts
|
|
9554
9534
|
async function deriveDeliveryKeys(blobBytes) {
|
|
9555
|
-
const token = await Token.fromCBOR(
|
|
9535
|
+
const token = await Token.fromCBOR(blobBytes);
|
|
9556
9536
|
const stateHash = HexConverter.encode((await token.latestTransaction.calculateStateHash()).imprint);
|
|
9557
9537
|
return { tokenId: HexConverter.encode(token.id.bytes), stateHash };
|
|
9558
9538
|
}
|
|
@@ -9606,8 +9586,8 @@ function deriveRealization(privKeyHex, transferId, index, field) {
|
|
|
9606
9586
|
}
|
|
9607
9587
|
|
|
9608
9588
|
// token-engine/split-checkpoint.ts
|
|
9609
|
-
var CHECKPOINT_VERSION =
|
|
9610
|
-
var CHECKPOINT_SDK_VERSION = "@unicitylabs/state-transition-sdk@
|
|
9589
|
+
var CHECKPOINT_VERSION = 2;
|
|
9590
|
+
var CHECKPOINT_SDK_VERSION = "@unicitylabs/state-transition-sdk@3.0.1";
|
|
9611
9591
|
function bytesEqual(a, b) {
|
|
9612
9592
|
if (a.length !== b.length) return false;
|
|
9613
9593
|
for (let i = 0; i < a.length; i++) {
|
|
@@ -9757,13 +9737,11 @@ var SphereTokenEngine = class {
|
|
|
9757
9737
|
const data = params.value ? await SpherePaymentData.fromValue(params.value).encode() : null;
|
|
9758
9738
|
const transferId = this.resolveTransferId(options);
|
|
9759
9739
|
const opIndex = this.resolveOpIndex(options);
|
|
9760
|
-
const mintTx = await MintTransaction.create(
|
|
9761
|
-
this.deps.networkId,
|
|
9762
|
-
recipient,
|
|
9740
|
+
const mintTx = await MintTransaction.create(this.deps.networkId, recipient, {
|
|
9763
9741
|
data,
|
|
9764
|
-
new TokenType(deriveRealization(this.privateKeyHex, transferId, opIndex, "tokenType")),
|
|
9765
|
-
TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, opIndex, "mint"))
|
|
9766
|
-
);
|
|
9742
|
+
tokenType: new TokenType(deriveRealization(this.privateKeyHex, transferId, opIndex, "tokenType")),
|
|
9743
|
+
salt: TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, opIndex, "mint"))
|
|
9744
|
+
});
|
|
9767
9745
|
const certificationData = await CertificationData.fromMintTransaction(mintTx);
|
|
9768
9746
|
const proof = await this.submitAndAwaitProof(
|
|
9769
9747
|
certificationData,
|
|
@@ -9780,7 +9758,7 @@ var SphereTokenEngine = class {
|
|
|
9780
9758
|
const recipient = SignaturePredicate.create(params.recipientPubkey);
|
|
9781
9759
|
const tokenType = params.tokenType ? new TokenType(params.tokenType) : TokenType.generate();
|
|
9782
9760
|
const salt = params.salt ? TokenSalt.fromBytes(params.salt) : TokenSalt.generate();
|
|
9783
|
-
const mintTx = await MintTransaction.create(this.deps.networkId, recipient, params.data, tokenType, salt);
|
|
9761
|
+
const mintTx = await MintTransaction.create(this.deps.networkId, recipient, { data: params.data, tokenType, salt });
|
|
9784
9762
|
const certificationData = await CertificationData.fromMintTransaction(mintTx);
|
|
9785
9763
|
const proof = await this.submitAndAwaitProof(
|
|
9786
9764
|
certificationData,
|
|
@@ -9800,7 +9778,9 @@ var SphereTokenEngine = class {
|
|
|
9800
9778
|
const stateMask = StateMask.fromBytes(
|
|
9801
9779
|
deriveRealization(this.privateKeyHex, transferId, this.resolveOpIndex(options), "stateMask")
|
|
9802
9780
|
);
|
|
9803
|
-
const transferTx = await TransferTransaction.create(params.token.sdkToken, recipient, stateMask,
|
|
9781
|
+
const transferTx = await TransferTransaction.create(params.token.sdkToken, recipient, stateMask, {
|
|
9782
|
+
data: params.data ?? null
|
|
9783
|
+
});
|
|
9804
9784
|
const unlockScript = await SignaturePredicateUnlockScript.create(transferTx, this.deps.signingService);
|
|
9805
9785
|
const certificationData = await CertificationData.fromTransaction(transferTx, unlockScript);
|
|
9806
9786
|
const proof = await this.submitAndAwaitProof(
|
|
@@ -9827,12 +9807,11 @@ var SphereTokenEngine = class {
|
|
|
9827
9807
|
TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, i, "salt"))
|
|
9828
9808
|
)
|
|
9829
9809
|
);
|
|
9830
|
-
const split = await TokenSplit.split(
|
|
9831
|
-
|
|
9832
|
-
|
|
9833
|
-
|
|
9834
|
-
|
|
9835
|
-
);
|
|
9810
|
+
const split = await TokenSplit.split(params.token.sdkToken, decodeSpherePaymentData, requests, {
|
|
9811
|
+
burnStateMask: StateMask.fromBytes(
|
|
9812
|
+
deriveRealization(this.privateKeyHex, transferId, this.resolveOpIndex(options), "burn")
|
|
9813
|
+
)
|
|
9814
|
+
});
|
|
9836
9815
|
const burntToken = await this.resolveBurntToken({ params, split, transferId, options });
|
|
9837
9816
|
const settled = [];
|
|
9838
9817
|
for (let start = 0; start < split.tokens.length; start += MAX_MINT_CONCURRENCY) {
|
|
@@ -9912,9 +9891,14 @@ var SphereTokenEngine = class {
|
|
|
9912
9891
|
await Promise.all(
|
|
9913
9892
|
ctx.split.tokens.map(async (leg) => {
|
|
9914
9893
|
const data = await leg.paymentData.encode();
|
|
9915
|
-
const probe = await MintTransaction.create(leg.networkId, leg.recipient,
|
|
9894
|
+
const probe = await MintTransaction.create(leg.networkId, leg.recipient, {
|
|
9895
|
+
data,
|
|
9896
|
+
tokenType: leg.tokenType,
|
|
9897
|
+
salt: leg.salt,
|
|
9898
|
+
justification: null
|
|
9899
|
+
});
|
|
9916
9900
|
const response = await this.deps.client.getInclusionProof(await StateId.fromTransaction(probe));
|
|
9917
|
-
if (response.inclusionProof
|
|
9901
|
+
if (response.inclusionProof !== null) {
|
|
9918
9902
|
throw new SplitCheckpointLostError(
|
|
9919
9903
|
"a split mint leaf is certified on-chain but no burn checkpoint exists \u2014 outputs are unrecoverable"
|
|
9920
9904
|
);
|
|
@@ -9926,14 +9910,12 @@ var SphereTokenEngine = class {
|
|
|
9926
9910
|
async mintSplitOutput(splitToken, burntToken, options) {
|
|
9927
9911
|
const data = await splitToken.paymentData.encode();
|
|
9928
9912
|
const justification = SplitMintJustification.create(burntToken, splitToken.proofs).toCBOR();
|
|
9929
|
-
const mintTx = await MintTransaction.create(
|
|
9930
|
-
splitToken.networkId,
|
|
9931
|
-
splitToken.recipient,
|
|
9913
|
+
const mintTx = await MintTransaction.create(splitToken.networkId, splitToken.recipient, {
|
|
9932
9914
|
data,
|
|
9933
|
-
splitToken.tokenType,
|
|
9934
|
-
splitToken.salt,
|
|
9915
|
+
tokenType: splitToken.tokenType,
|
|
9916
|
+
salt: splitToken.salt,
|
|
9935
9917
|
justification
|
|
9936
|
-
);
|
|
9918
|
+
});
|
|
9937
9919
|
const certData = await CertificationData.fromMintTransaction(mintTx);
|
|
9938
9920
|
const proof = await this.submitSplitMintLeg(certData, mintTx, options);
|
|
9939
9921
|
const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);
|
|
@@ -9978,7 +9960,7 @@ var SphereTokenEngine = class {
|
|
|
9978
9960
|
);
|
|
9979
9961
|
const stateId = await StateId.fromTransaction(probe);
|
|
9980
9962
|
const response = await this.deps.client.getInclusionProof(stateId);
|
|
9981
|
-
return response.inclusionProof
|
|
9963
|
+
return response.inclusionProof !== null;
|
|
9982
9964
|
}
|
|
9983
9965
|
// ── serialization ────────────────────────────────────────────────────────────
|
|
9984
9966
|
/** @inheritDoc — SDK-derived (Token.fromCBOR → latestTransaction.calculateStateHash().imprint). */
|
|
@@ -10062,7 +10044,13 @@ var SphereTokenEngine = class {
|
|
|
10062
10044
|
let submitRejectedCleanly = false;
|
|
10063
10045
|
try {
|
|
10064
10046
|
const { value: response, retried } = await retryTransient(
|
|
10065
|
-
() =>
|
|
10047
|
+
async () => {
|
|
10048
|
+
const answer = await this.deps.client.submitCertificationRequest(certificationData);
|
|
10049
|
+
if (String(answer.status) === String(CertificationStatus.SERVICE_NOT_READY)) {
|
|
10050
|
+
throw new TransientSubmitAnswer(String(answer.status));
|
|
10051
|
+
}
|
|
10052
|
+
return answer;
|
|
10053
|
+
},
|
|
10066
10054
|
signal,
|
|
10067
10055
|
this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS
|
|
10068
10056
|
);
|
|
@@ -10117,8 +10105,6 @@ var SphereTokenEngine = class {
|
|
|
10117
10105
|
}
|
|
10118
10106
|
}
|
|
10119
10107
|
const blob = {
|
|
10120
|
-
v: TOKEN_BLOB_VERSION,
|
|
10121
|
-
network: sdkToken.genesis.networkId.id,
|
|
10122
10108
|
tokenId: HexConverter.encode(sdkToken.id.bytes),
|
|
10123
10109
|
token: sdkToken.toCBOR()
|
|
10124
10110
|
};
|
|
@@ -11262,8 +11248,19 @@ function coalesced(run, observe) {
|
|
|
11262
11248
|
}
|
|
11263
11249
|
|
|
11264
11250
|
// modules/payments-v2/stores.ts
|
|
11251
|
+
var KV_PREFIX = "pv2g2:";
|
|
11252
|
+
var SUPERSEDED_KV_PREFIXES = ["pv2:"];
|
|
11253
|
+
async function sweepSupersededState(storage) {
|
|
11254
|
+
for (const prefix of SUPERSEDED_KV_PREFIXES) {
|
|
11255
|
+
try {
|
|
11256
|
+
await storage.clear(prefix);
|
|
11257
|
+
} catch (err) {
|
|
11258
|
+
logger.warn("PaymentsV2", `could not clear superseded state under "${prefix}": ${String(err)}`);
|
|
11259
|
+
}
|
|
11260
|
+
}
|
|
11261
|
+
}
|
|
11265
11262
|
function createScopedKV(storage, network, chainPubkey) {
|
|
11266
|
-
const prefix =
|
|
11263
|
+
const prefix = `${KV_PREFIX}${network}:${chainPubkey}:`;
|
|
11267
11264
|
return {
|
|
11268
11265
|
async get(key) {
|
|
11269
11266
|
const raw = await storage.get(prefix + key);
|
|
@@ -11845,12 +11842,7 @@ var TransferMachine = class {
|
|
|
11845
11842
|
let total = 0n;
|
|
11846
11843
|
for (const outcome of committed) {
|
|
11847
11844
|
if (outcome.recipientBlob === void 0) continue;
|
|
11848
|
-
const token = await engine.decodeToken({
|
|
11849
|
-
v: TOKEN_BLOB_VERSION,
|
|
11850
|
-
network: 0,
|
|
11851
|
-
tokenId: "",
|
|
11852
|
-
token: outcome.recipientBlob
|
|
11853
|
-
});
|
|
11845
|
+
const token = await engine.decodeToken({ tokenId: "", token: outcome.recipientBlob });
|
|
11854
11846
|
total += engine.balanceOf(token, coinId);
|
|
11855
11847
|
}
|
|
11856
11848
|
return total.toString();
|
|
@@ -11966,8 +11958,9 @@ async function fetchSources(deps, jobs) {
|
|
|
11966
11958
|
const engine = deps.engine();
|
|
11967
11959
|
for (const [tokenId, bytes] of blobs) {
|
|
11968
11960
|
try {
|
|
11969
|
-
decoded.set(tokenId, await engine.decodeToken({
|
|
11970
|
-
} catch {
|
|
11961
|
+
decoded.set(tokenId, await engine.decodeToken({ tokenId, token: bytes }));
|
|
11962
|
+
} catch (err) {
|
|
11963
|
+
logger.warn("PaymentsV2", `resume: source ${tokenId} did not decode \u2014 ${String(err)}`);
|
|
11971
11964
|
}
|
|
11972
11965
|
}
|
|
11973
11966
|
return decoded;
|
|
@@ -12994,22 +12987,24 @@ var Receive = class {
|
|
|
12994
12987
|
* the tokens just accepted, and the balance would still only move at the end.
|
|
12995
12988
|
* Ordering is preserved: store() still precedes the ack (§5.7).
|
|
12996
12989
|
*/
|
|
12997
|
-
async maybeRefresh(
|
|
12990
|
+
async maybeRefresh(ctx) {
|
|
12991
|
+
const { deps, pending, pageEpoch } = ctx;
|
|
12998
12992
|
if (deps.refreshView === void 0) return;
|
|
12999
12993
|
const now = deps.now?.() ?? Date.now();
|
|
13000
12994
|
if (now - this.lastRefreshAt < REFRESH_INTERVAL_MS) return;
|
|
13001
12995
|
this.lastRefreshAt = now;
|
|
13002
|
-
await flushAcks(deps, pending,
|
|
13003
|
-
deps.refreshView();
|
|
12996
|
+
if ((await flushAcks(deps, pending, pageEpoch)).progressed) deps.refreshView();
|
|
13004
12997
|
}
|
|
13005
12998
|
/** One listing pass: process each entry, flushing and refreshing as it goes. */
|
|
13006
12999
|
async drainPages(ctx, basis) {
|
|
13007
|
-
const { deps,
|
|
13000
|
+
const { deps, pending, pageEpoch, claimable } = ctx;
|
|
13008
13001
|
for await (const entry of deps.delivery.incoming(basis === null ? void 0 : String(basis.cursor))) {
|
|
13009
|
-
const
|
|
13010
|
-
await this.processEntry(
|
|
13011
|
-
if (pending.length >= ACK_BATCH_SIZE)
|
|
13012
|
-
|
|
13002
|
+
const claimableBefore = claimable.n;
|
|
13003
|
+
await this.processEntry(ctx, entry);
|
|
13004
|
+
if (pending.length >= ACK_BATCH_SIZE) {
|
|
13005
|
+
if (!(await flushAcks(deps, pending, pageEpoch)).progressed) return;
|
|
13006
|
+
}
|
|
13007
|
+
if (claimable.n > claimableBefore) await this.maybeRefresh(ctx);
|
|
13013
13008
|
}
|
|
13014
13009
|
await flushAcks(deps, pending, pageEpoch);
|
|
13015
13010
|
}
|
|
@@ -13020,11 +13015,16 @@ var Receive = class {
|
|
|
13020
13015
|
const stored = [];
|
|
13021
13016
|
const pending = [];
|
|
13022
13017
|
const pageEpoch = () => deps.delivery.incomingEpoch() ?? deps.syncEpoch();
|
|
13018
|
+
const claimable = { n: 0 };
|
|
13019
|
+
const finish = () => {
|
|
13020
|
+
if (claimable.n > 0) deps.refreshView?.();
|
|
13021
|
+
return stored;
|
|
13022
|
+
};
|
|
13023
13023
|
try {
|
|
13024
13024
|
const record = await deps.kv.get(STORE_KEYS.streamCursor("mailbox"));
|
|
13025
13025
|
let basis = record !== null && record.syncEpoch === deps.syncEpoch() ? record : null;
|
|
13026
13026
|
for (let pass = 0; pass < 2; pass++) {
|
|
13027
|
-
await this.drainPages({ deps, engine, pending, stored, pageEpoch }, basis);
|
|
13027
|
+
await this.drainPages({ deps, engine, pending, stored, pageEpoch, claimable }, basis);
|
|
13028
13028
|
const served = deps.delivery.incomingEpoch();
|
|
13029
13029
|
if (basis === null || served === null || served === basis.syncEpoch) break;
|
|
13030
13030
|
await deps.kv.remove(STORE_KEYS.streamCursor("mailbox"));
|
|
@@ -13032,22 +13032,25 @@ var Receive = class {
|
|
|
13032
13032
|
}
|
|
13033
13033
|
} catch (err) {
|
|
13034
13034
|
logger.warn("PaymentsV2", "receive drain interrupted \u2014 unacked entries retry next drain:", err);
|
|
13035
|
-
if (isRetryableAckError(err)) return
|
|
13035
|
+
if (isRetryableAckError(err)) return finish();
|
|
13036
13036
|
await flushAcks(deps, pending, pageEpoch).catch((flushErr) => {
|
|
13037
13037
|
logger.warn("PaymentsV2", "receive ack flush failed \u2014 cursor holds at the acked prefix:", flushErr);
|
|
13038
|
+
return { progressed: false };
|
|
13038
13039
|
});
|
|
13039
13040
|
}
|
|
13040
|
-
|
|
13041
|
-
return stored;
|
|
13041
|
+
return finish();
|
|
13042
13042
|
}
|
|
13043
|
-
async processEntry(
|
|
13043
|
+
async processEntry(ctx, entry) {
|
|
13044
|
+
const { deps, engine, pending, stored, claimable } = ctx;
|
|
13044
13045
|
const screened = await screen(deps, engine, entry);
|
|
13045
13046
|
if (screened.kind === "ack") {
|
|
13046
13047
|
pending.push(screened.ack);
|
|
13048
|
+
if (screened.ack.disposition === "claimed") claimable.n += 1;
|
|
13047
13049
|
return;
|
|
13048
13050
|
}
|
|
13049
13051
|
await deps.view.store(screened.record);
|
|
13050
13052
|
pending.push(claimAck(entry));
|
|
13053
|
+
claimable.n += 1;
|
|
13051
13054
|
const transfer = await announce(deps, entry, screened.record);
|
|
13052
13055
|
stored.push(transfer);
|
|
13053
13056
|
deps.emit("transfer:incoming", transfer);
|
|
@@ -13057,13 +13060,9 @@ async function screen(deps, engine, entry) {
|
|
|
13057
13060
|
const blobBytes = await entry.fetchBlob();
|
|
13058
13061
|
let token;
|
|
13059
13062
|
try {
|
|
13060
|
-
token = await engine.decodeToken({
|
|
13061
|
-
|
|
13062
|
-
|
|
13063
|
-
tokenId: "",
|
|
13064
|
-
token: blobBytes
|
|
13065
|
-
});
|
|
13066
|
-
} catch {
|
|
13063
|
+
token = await engine.decodeToken({ tokenId: "", token: blobBytes });
|
|
13064
|
+
} catch (err) {
|
|
13065
|
+
logger.warn("PaymentsV2", `receive: undecodable blob rejected \u2014 ${String(err)}`);
|
|
13067
13066
|
return { kind: "ack", ack: rejectAck(entry, "invalid") };
|
|
13068
13067
|
}
|
|
13069
13068
|
const verdict = await engine.verify(token);
|
|
@@ -13108,7 +13107,8 @@ async function announce(deps, entry, record) {
|
|
|
13108
13107
|
};
|
|
13109
13108
|
}
|
|
13110
13109
|
async function flushAcks(deps, pending, epochOf) {
|
|
13111
|
-
if (pending.length === 0) return;
|
|
13110
|
+
if (pending.length === 0) return { progressed: true };
|
|
13111
|
+
const before = pending.length;
|
|
13112
13112
|
let lastAcked = null;
|
|
13113
13113
|
try {
|
|
13114
13114
|
const settled = await settleAcks(deps, pending);
|
|
@@ -13126,6 +13126,7 @@ async function flushAcks(deps, pending, epochOf) {
|
|
|
13126
13126
|
await deps.kv.set(STORE_KEYS.streamCursor("mailbox"), record);
|
|
13127
13127
|
}
|
|
13128
13128
|
}
|
|
13129
|
+
return { progressed: pending.length < before };
|
|
13129
13130
|
}
|
|
13130
13131
|
async function settleAcks(deps, pending) {
|
|
13131
13132
|
const batch = deps.delivery.ackBatch?.bind(deps.delivery);
|
|
@@ -14464,7 +14465,7 @@ var PaymentsFacade = class {
|
|
|
14464
14465
|
if (bytes === void 0) {
|
|
14465
14466
|
throw new SphereError(`Selected source ${tokenId} has no blob in storage`, "STORAGE_ERROR");
|
|
14466
14467
|
}
|
|
14467
|
-
const token = await engine.decodeToken({
|
|
14468
|
+
const token = await engine.decodeToken({ tokenId, token: bytes });
|
|
14468
14469
|
const keys = await engine.deliveryKeys(bytes);
|
|
14469
14470
|
spentStates[tokenId] = { local: keys.stateHash, protocol: keys.stateHash };
|
|
14470
14471
|
sources.set(tokenId, token);
|
|
@@ -15646,7 +15647,9 @@ var WalletApiDeliveryPort = class {
|
|
|
15646
15647
|
await this.settleClaims(acks, settled, outcomes);
|
|
15647
15648
|
await this.settleRejects(acks, settled);
|
|
15648
15649
|
} catch (err) {
|
|
15649
|
-
await this.addSeenAll(settled).catch(() =>
|
|
15650
|
+
await this.addSeenAll(settled).catch((seenErr) => {
|
|
15651
|
+
logger.warn("WalletApiDelivery", `seen-set write failed for ${String(settled.length)} committed acks:`, seenErr);
|
|
15652
|
+
});
|
|
15650
15653
|
throw asRetryable(err);
|
|
15651
15654
|
}
|
|
15652
15655
|
await this.addSeenAll(settled);
|
|
@@ -15909,6 +15912,7 @@ function composePaymentsV2(spec) {
|
|
|
15909
15912
|
const network = spec.composition.network;
|
|
15910
15913
|
const identitySlice = { privateKey: identity.privateKey, chainPubkey: identity.chainPubkey };
|
|
15911
15914
|
const kv = createScopedKV(host.storage, network, identity.chainPubkey);
|
|
15915
|
+
void sweepSupersededState(host.storage);
|
|
15912
15916
|
const fieldKey = deriveFieldEncryptionKey(identity.privateKey);
|
|
15913
15917
|
const transport = spec.composition.factory({
|
|
15914
15918
|
identity: identitySlice,
|
|
@@ -16200,11 +16204,10 @@ var Sphere = class _Sphere {
|
|
|
16200
16204
|
return config;
|
|
16201
16205
|
}
|
|
16202
16206
|
/**
|
|
16203
|
-
* The ONE sanctioned refusal fossil of the P11 flip
|
|
16204
|
-
*
|
|
16205
|
-
*
|
|
16206
|
-
*
|
|
16207
|
-
* live frontend passes it today).
|
|
16207
|
+
* The ONE sanctioned refusal fossil of the P11 flip: `accounting`/`swap` were
|
|
16208
|
+
* public init flags — silently ignoring them would hide that invoices/swaps no
|
|
16209
|
+
* longer exist in the SDK. Kept through 0.15.0, where consumers re-integrate
|
|
16210
|
+
* across the wire break and a silent no-op would be worst.
|
|
16208
16211
|
*/
|
|
16209
16212
|
static refuseRetiredModuleOptions(options) {
|
|
16210
16213
|
if (options.accounting) {
|
|
@@ -16471,7 +16474,7 @@ var Sphere = class _Sphere {
|
|
|
16471
16474
|
}
|
|
16472
16475
|
/**
|
|
16473
16476
|
* Clear all SDK-owned wallet data from storage: wallet keys, per-address
|
|
16474
|
-
* data, and the payments vertical's `
|
|
16477
|
+
* data, and the payments vertical's `pv2g2:{network}:{pubkey}:*` scoped KV
|
|
16475
16478
|
* (refresh token, cursors, journals — all live in the plain StorageProvider,
|
|
16476
16479
|
* so the full KV wipe below removes them). Tokens are server-custody; the
|
|
16477
16480
|
* only local token artifacts are orphaned `sphere-token-storage-*` IndexedDB
|
|
@@ -16581,10 +16584,6 @@ var Sphere = class _Sphere {
|
|
|
16581
16584
|
}
|
|
16582
16585
|
return facade;
|
|
16583
16586
|
}
|
|
16584
|
-
/** @deprecated Alias of {@link payments} kept for one release (the live frontend calls it). Null when no vertical runs. */
|
|
16585
|
-
get paymentsV2() {
|
|
16586
|
-
return this._paymentsV2Active?.facade ?? null;
|
|
16587
|
-
}
|
|
16588
16587
|
/** Communications module */
|
|
16589
16588
|
get communications() {
|
|
16590
16589
|
this.ensureReady();
|