@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.cjs
CHANGED
|
@@ -9471,7 +9471,15 @@ function resolveProofTimeoutMs(configured) {
|
|
|
9471
9471
|
return configured;
|
|
9472
9472
|
}
|
|
9473
9473
|
var TRANSIENT_HTTP_STATUSES = /* @__PURE__ */ new Set([408, 425, 429, 500, 502, 503, 504]);
|
|
9474
|
+
var TransientSubmitAnswer = class extends Error {
|
|
9475
|
+
constructor(status) {
|
|
9476
|
+
super(`gateway is not ready to certify yet (${status})`);
|
|
9477
|
+
this.status = status;
|
|
9478
|
+
this.name = "TransientSubmitAnswer";
|
|
9479
|
+
}
|
|
9480
|
+
};
|
|
9474
9481
|
function isTransientGatewayError(err) {
|
|
9482
|
+
if (err instanceof TransientSubmitAnswer) return true;
|
|
9475
9483
|
return err instanceof import_JsonRpcNetworkError.JsonRpcNetworkError && TRANSIENT_HTTP_STATUSES.has(err.status);
|
|
9476
9484
|
}
|
|
9477
9485
|
function pause(ms, signal) {
|
|
@@ -9592,37 +9600,9 @@ function certificationFailure(err, failLabel, submitError, submitRejectedCleanly
|
|
|
9592
9600
|
);
|
|
9593
9601
|
}
|
|
9594
9602
|
|
|
9595
|
-
// token-engine/token-blob.ts
|
|
9596
|
-
var TOKEN_BLOB_TAG = 39051n;
|
|
9597
|
-
var TOKEN_BLOB_VERSION = 1;
|
|
9598
|
-
function decodeTokenBlob(bytes) {
|
|
9599
|
-
const tag = import_CborDeserializer.CborDeserializer.decodeTag(bytes);
|
|
9600
|
-
if (tag.tag !== TOKEN_BLOB_TAG) {
|
|
9601
|
-
throw new import_CborError.CborError(`Invalid TokenBlob tag: ${tag.tag}`);
|
|
9602
|
-
}
|
|
9603
|
-
const fields = import_CborDeserializer.CborDeserializer.decodeArray(tag.data, 4);
|
|
9604
|
-
const v = Number(import_CborDeserializer.CborDeserializer.decodeUnsignedInteger(fields[0]));
|
|
9605
|
-
if (v !== TOKEN_BLOB_VERSION) {
|
|
9606
|
-
throw new import_CborError.CborError(`Unsupported TokenBlob version: ${v}`);
|
|
9607
|
-
}
|
|
9608
|
-
return {
|
|
9609
|
-
v,
|
|
9610
|
-
network: Number(import_CborDeserializer.CborDeserializer.decodeUnsignedInteger(fields[1])),
|
|
9611
|
-
tokenId: import_CborDeserializer.CborDeserializer.decodeTextString(fields[2]),
|
|
9612
|
-
token: import_CborDeserializer.CborDeserializer.decodeByteString(fields[3])
|
|
9613
|
-
};
|
|
9614
|
-
}
|
|
9615
|
-
function unwrapTokenBlobBytes(bytes) {
|
|
9616
|
-
try {
|
|
9617
|
-
return decodeTokenBlob(bytes).token;
|
|
9618
|
-
} catch {
|
|
9619
|
-
return bytes;
|
|
9620
|
-
}
|
|
9621
|
-
}
|
|
9622
|
-
|
|
9623
9603
|
// token-engine/blob-keys.ts
|
|
9624
9604
|
async function deriveDeliveryKeys(blobBytes) {
|
|
9625
|
-
const token = await import_Token.Token.fromCBOR(
|
|
9605
|
+
const token = await import_Token.Token.fromCBOR(blobBytes);
|
|
9626
9606
|
const stateHash = import_HexConverter.HexConverter.encode((await token.latestTransaction.calculateStateHash()).imprint);
|
|
9627
9607
|
return { tokenId: import_HexConverter.HexConverter.encode(token.id.bytes), stateHash };
|
|
9628
9608
|
}
|
|
@@ -9676,8 +9656,8 @@ function deriveRealization(privKeyHex, transferId, index, field) {
|
|
|
9676
9656
|
}
|
|
9677
9657
|
|
|
9678
9658
|
// token-engine/split-checkpoint.ts
|
|
9679
|
-
var CHECKPOINT_VERSION =
|
|
9680
|
-
var CHECKPOINT_SDK_VERSION = "@unicitylabs/state-transition-sdk@
|
|
9659
|
+
var CHECKPOINT_VERSION = 2;
|
|
9660
|
+
var CHECKPOINT_SDK_VERSION = "@unicitylabs/state-transition-sdk@3.0.1";
|
|
9681
9661
|
function bytesEqual(a, b) {
|
|
9682
9662
|
if (a.length !== b.length) return false;
|
|
9683
9663
|
for (let i = 0; i < a.length; i++) {
|
|
@@ -9827,13 +9807,11 @@ var SphereTokenEngine = class {
|
|
|
9827
9807
|
const data = params.value ? await SpherePaymentData.fromValue(params.value).encode() : null;
|
|
9828
9808
|
const transferId = this.resolveTransferId(options);
|
|
9829
9809
|
const opIndex = this.resolveOpIndex(options);
|
|
9830
|
-
const mintTx = await import_MintTransaction.MintTransaction.create(
|
|
9831
|
-
this.deps.networkId,
|
|
9832
|
-
recipient,
|
|
9810
|
+
const mintTx = await import_MintTransaction.MintTransaction.create(this.deps.networkId, recipient, {
|
|
9833
9811
|
data,
|
|
9834
|
-
new import_TokenType.TokenType(deriveRealization(this.privateKeyHex, transferId, opIndex, "tokenType")),
|
|
9835
|
-
import_TokenSalt.TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, opIndex, "mint"))
|
|
9836
|
-
);
|
|
9812
|
+
tokenType: new import_TokenType.TokenType(deriveRealization(this.privateKeyHex, transferId, opIndex, "tokenType")),
|
|
9813
|
+
salt: import_TokenSalt.TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, opIndex, "mint"))
|
|
9814
|
+
});
|
|
9837
9815
|
const certificationData = await import_CertificationData.CertificationData.fromMintTransaction(mintTx);
|
|
9838
9816
|
const proof = await this.submitAndAwaitProof(
|
|
9839
9817
|
certificationData,
|
|
@@ -9850,7 +9828,7 @@ var SphereTokenEngine = class {
|
|
|
9850
9828
|
const recipient = import_SignaturePredicate.SignaturePredicate.create(params.recipientPubkey);
|
|
9851
9829
|
const tokenType = params.tokenType ? new import_TokenType.TokenType(params.tokenType) : import_TokenType.TokenType.generate();
|
|
9852
9830
|
const salt = params.salt ? import_TokenSalt.TokenSalt.fromBytes(params.salt) : import_TokenSalt.TokenSalt.generate();
|
|
9853
|
-
const mintTx = await import_MintTransaction.MintTransaction.create(this.deps.networkId, recipient, params.data, tokenType, salt);
|
|
9831
|
+
const mintTx = await import_MintTransaction.MintTransaction.create(this.deps.networkId, recipient, { data: params.data, tokenType, salt });
|
|
9854
9832
|
const certificationData = await import_CertificationData.CertificationData.fromMintTransaction(mintTx);
|
|
9855
9833
|
const proof = await this.submitAndAwaitProof(
|
|
9856
9834
|
certificationData,
|
|
@@ -9870,7 +9848,9 @@ var SphereTokenEngine = class {
|
|
|
9870
9848
|
const stateMask = import_StateMask.StateMask.fromBytes(
|
|
9871
9849
|
deriveRealization(this.privateKeyHex, transferId, this.resolveOpIndex(options), "stateMask")
|
|
9872
9850
|
);
|
|
9873
|
-
const transferTx = await import_TransferTransaction.TransferTransaction.create(params.token.sdkToken, recipient, stateMask,
|
|
9851
|
+
const transferTx = await import_TransferTransaction.TransferTransaction.create(params.token.sdkToken, recipient, stateMask, {
|
|
9852
|
+
data: params.data ?? null
|
|
9853
|
+
});
|
|
9874
9854
|
const unlockScript = await import_SignaturePredicateUnlockScript.SignaturePredicateUnlockScript.create(transferTx, this.deps.signingService);
|
|
9875
9855
|
const certificationData = await import_CertificationData.CertificationData.fromTransaction(transferTx, unlockScript);
|
|
9876
9856
|
const proof = await this.submitAndAwaitProof(
|
|
@@ -9897,12 +9877,11 @@ var SphereTokenEngine = class {
|
|
|
9897
9877
|
import_TokenSalt.TokenSalt.fromBytes(deriveRealization(this.privateKeyHex, transferId, i, "salt"))
|
|
9898
9878
|
)
|
|
9899
9879
|
);
|
|
9900
|
-
const split = await import_TokenSplit.TokenSplit.split(
|
|
9901
|
-
|
|
9902
|
-
|
|
9903
|
-
|
|
9904
|
-
|
|
9905
|
-
);
|
|
9880
|
+
const split = await import_TokenSplit.TokenSplit.split(params.token.sdkToken, decodeSpherePaymentData, requests, {
|
|
9881
|
+
burnStateMask: import_StateMask.StateMask.fromBytes(
|
|
9882
|
+
deriveRealization(this.privateKeyHex, transferId, this.resolveOpIndex(options), "burn")
|
|
9883
|
+
)
|
|
9884
|
+
});
|
|
9906
9885
|
const burntToken = await this.resolveBurntToken({ params, split, transferId, options });
|
|
9907
9886
|
const settled = [];
|
|
9908
9887
|
for (let start = 0; start < split.tokens.length; start += MAX_MINT_CONCURRENCY) {
|
|
@@ -9982,9 +9961,14 @@ var SphereTokenEngine = class {
|
|
|
9982
9961
|
await Promise.all(
|
|
9983
9962
|
ctx.split.tokens.map(async (leg) => {
|
|
9984
9963
|
const data = await leg.paymentData.encode();
|
|
9985
|
-
const probe = await import_MintTransaction.MintTransaction.create(leg.networkId, leg.recipient,
|
|
9964
|
+
const probe = await import_MintTransaction.MintTransaction.create(leg.networkId, leg.recipient, {
|
|
9965
|
+
data,
|
|
9966
|
+
tokenType: leg.tokenType,
|
|
9967
|
+
salt: leg.salt,
|
|
9968
|
+
justification: null
|
|
9969
|
+
});
|
|
9986
9970
|
const response = await this.deps.client.getInclusionProof(await import_StateId.StateId.fromTransaction(probe));
|
|
9987
|
-
if (response.inclusionProof
|
|
9971
|
+
if (response.inclusionProof !== null) {
|
|
9988
9972
|
throw new SplitCheckpointLostError(
|
|
9989
9973
|
"a split mint leaf is certified on-chain but no burn checkpoint exists \u2014 outputs are unrecoverable"
|
|
9990
9974
|
);
|
|
@@ -9996,14 +9980,12 @@ var SphereTokenEngine = class {
|
|
|
9996
9980
|
async mintSplitOutput(splitToken, burntToken, options) {
|
|
9997
9981
|
const data = await splitToken.paymentData.encode();
|
|
9998
9982
|
const justification = import_SplitMintJustification.SplitMintJustification.create(burntToken, splitToken.proofs).toCBOR();
|
|
9999
|
-
const mintTx = await import_MintTransaction.MintTransaction.create(
|
|
10000
|
-
splitToken.networkId,
|
|
10001
|
-
splitToken.recipient,
|
|
9983
|
+
const mintTx = await import_MintTransaction.MintTransaction.create(splitToken.networkId, splitToken.recipient, {
|
|
10002
9984
|
data,
|
|
10003
|
-
splitToken.tokenType,
|
|
10004
|
-
splitToken.salt,
|
|
9985
|
+
tokenType: splitToken.tokenType,
|
|
9986
|
+
salt: splitToken.salt,
|
|
10005
9987
|
justification
|
|
10006
|
-
);
|
|
9988
|
+
});
|
|
10007
9989
|
const certData = await import_CertificationData.CertificationData.fromMintTransaction(mintTx);
|
|
10008
9990
|
const proof = await this.submitSplitMintLeg(certData, mintTx, options);
|
|
10009
9991
|
const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);
|
|
@@ -10048,7 +10030,7 @@ var SphereTokenEngine = class {
|
|
|
10048
10030
|
);
|
|
10049
10031
|
const stateId = await import_StateId.StateId.fromTransaction(probe);
|
|
10050
10032
|
const response = await this.deps.client.getInclusionProof(stateId);
|
|
10051
|
-
return response.inclusionProof
|
|
10033
|
+
return response.inclusionProof !== null;
|
|
10052
10034
|
}
|
|
10053
10035
|
// ── serialization ────────────────────────────────────────────────────────────
|
|
10054
10036
|
/** @inheritDoc — SDK-derived (Token.fromCBOR → latestTransaction.calculateStateHash().imprint). */
|
|
@@ -10132,7 +10114,13 @@ var SphereTokenEngine = class {
|
|
|
10132
10114
|
let submitRejectedCleanly = false;
|
|
10133
10115
|
try {
|
|
10134
10116
|
const { value: response, retried } = await retryTransient(
|
|
10135
|
-
() =>
|
|
10117
|
+
async () => {
|
|
10118
|
+
const answer = await this.deps.client.submitCertificationRequest(certificationData);
|
|
10119
|
+
if (String(answer.status) === String(import_CertificationResponse.CertificationStatus.SERVICE_NOT_READY)) {
|
|
10120
|
+
throw new TransientSubmitAnswer(String(answer.status));
|
|
10121
|
+
}
|
|
10122
|
+
return answer;
|
|
10123
|
+
},
|
|
10136
10124
|
signal,
|
|
10137
10125
|
this.deps.proofPollIntervalMs ?? DEFAULT_PROOF_POLL_INTERVAL_MS
|
|
10138
10126
|
);
|
|
@@ -10187,8 +10175,6 @@ var SphereTokenEngine = class {
|
|
|
10187
10175
|
}
|
|
10188
10176
|
}
|
|
10189
10177
|
const blob = {
|
|
10190
|
-
v: TOKEN_BLOB_VERSION,
|
|
10191
|
-
network: sdkToken.genesis.networkId.id,
|
|
10192
10178
|
tokenId: import_HexConverter.HexConverter.encode(sdkToken.id.bytes),
|
|
10193
10179
|
token: sdkToken.toCBOR()
|
|
10194
10180
|
};
|
|
@@ -11332,8 +11318,19 @@ function coalesced(run, observe) {
|
|
|
11332
11318
|
}
|
|
11333
11319
|
|
|
11334
11320
|
// modules/payments-v2/stores.ts
|
|
11321
|
+
var KV_PREFIX = "pv2g2:";
|
|
11322
|
+
var SUPERSEDED_KV_PREFIXES = ["pv2:"];
|
|
11323
|
+
async function sweepSupersededState(storage) {
|
|
11324
|
+
for (const prefix of SUPERSEDED_KV_PREFIXES) {
|
|
11325
|
+
try {
|
|
11326
|
+
await storage.clear(prefix);
|
|
11327
|
+
} catch (err) {
|
|
11328
|
+
logger.warn("PaymentsV2", `could not clear superseded state under "${prefix}": ${String(err)}`);
|
|
11329
|
+
}
|
|
11330
|
+
}
|
|
11331
|
+
}
|
|
11335
11332
|
function createScopedKV(storage, network, chainPubkey) {
|
|
11336
|
-
const prefix =
|
|
11333
|
+
const prefix = `${KV_PREFIX}${network}:${chainPubkey}:`;
|
|
11337
11334
|
return {
|
|
11338
11335
|
async get(key) {
|
|
11339
11336
|
const raw = await storage.get(prefix + key);
|
|
@@ -11915,12 +11912,7 @@ var TransferMachine = class {
|
|
|
11915
11912
|
let total = 0n;
|
|
11916
11913
|
for (const outcome of committed) {
|
|
11917
11914
|
if (outcome.recipientBlob === void 0) continue;
|
|
11918
|
-
const token = await engine.decodeToken({
|
|
11919
|
-
v: TOKEN_BLOB_VERSION,
|
|
11920
|
-
network: 0,
|
|
11921
|
-
tokenId: "",
|
|
11922
|
-
token: outcome.recipientBlob
|
|
11923
|
-
});
|
|
11915
|
+
const token = await engine.decodeToken({ tokenId: "", token: outcome.recipientBlob });
|
|
11924
11916
|
total += engine.balanceOf(token, coinId);
|
|
11925
11917
|
}
|
|
11926
11918
|
return total.toString();
|
|
@@ -12036,8 +12028,9 @@ async function fetchSources(deps, jobs) {
|
|
|
12036
12028
|
const engine = deps.engine();
|
|
12037
12029
|
for (const [tokenId, bytes] of blobs) {
|
|
12038
12030
|
try {
|
|
12039
|
-
decoded.set(tokenId, await engine.decodeToken({
|
|
12040
|
-
} catch {
|
|
12031
|
+
decoded.set(tokenId, await engine.decodeToken({ tokenId, token: bytes }));
|
|
12032
|
+
} catch (err) {
|
|
12033
|
+
logger.warn("PaymentsV2", `resume: source ${tokenId} did not decode \u2014 ${String(err)}`);
|
|
12041
12034
|
}
|
|
12042
12035
|
}
|
|
12043
12036
|
return decoded;
|
|
@@ -13064,22 +13057,24 @@ var Receive = class {
|
|
|
13064
13057
|
* the tokens just accepted, and the balance would still only move at the end.
|
|
13065
13058
|
* Ordering is preserved: store() still precedes the ack (§5.7).
|
|
13066
13059
|
*/
|
|
13067
|
-
async maybeRefresh(
|
|
13060
|
+
async maybeRefresh(ctx) {
|
|
13061
|
+
const { deps, pending, pageEpoch } = ctx;
|
|
13068
13062
|
if (deps.refreshView === void 0) return;
|
|
13069
13063
|
const now = deps.now?.() ?? Date.now();
|
|
13070
13064
|
if (now - this.lastRefreshAt < REFRESH_INTERVAL_MS) return;
|
|
13071
13065
|
this.lastRefreshAt = now;
|
|
13072
|
-
await flushAcks(deps, pending,
|
|
13073
|
-
deps.refreshView();
|
|
13066
|
+
if ((await flushAcks(deps, pending, pageEpoch)).progressed) deps.refreshView();
|
|
13074
13067
|
}
|
|
13075
13068
|
/** One listing pass: process each entry, flushing and refreshing as it goes. */
|
|
13076
13069
|
async drainPages(ctx, basis) {
|
|
13077
|
-
const { deps,
|
|
13070
|
+
const { deps, pending, pageEpoch, claimable } = ctx;
|
|
13078
13071
|
for await (const entry of deps.delivery.incoming(basis === null ? void 0 : String(basis.cursor))) {
|
|
13079
|
-
const
|
|
13080
|
-
await this.processEntry(
|
|
13081
|
-
if (pending.length >= ACK_BATCH_SIZE)
|
|
13082
|
-
|
|
13072
|
+
const claimableBefore = claimable.n;
|
|
13073
|
+
await this.processEntry(ctx, entry);
|
|
13074
|
+
if (pending.length >= ACK_BATCH_SIZE) {
|
|
13075
|
+
if (!(await flushAcks(deps, pending, pageEpoch)).progressed) return;
|
|
13076
|
+
}
|
|
13077
|
+
if (claimable.n > claimableBefore) await this.maybeRefresh(ctx);
|
|
13083
13078
|
}
|
|
13084
13079
|
await flushAcks(deps, pending, pageEpoch);
|
|
13085
13080
|
}
|
|
@@ -13090,11 +13085,16 @@ var Receive = class {
|
|
|
13090
13085
|
const stored = [];
|
|
13091
13086
|
const pending = [];
|
|
13092
13087
|
const pageEpoch = () => deps.delivery.incomingEpoch() ?? deps.syncEpoch();
|
|
13088
|
+
const claimable = { n: 0 };
|
|
13089
|
+
const finish = () => {
|
|
13090
|
+
if (claimable.n > 0) deps.refreshView?.();
|
|
13091
|
+
return stored;
|
|
13092
|
+
};
|
|
13093
13093
|
try {
|
|
13094
13094
|
const record = await deps.kv.get(STORE_KEYS.streamCursor("mailbox"));
|
|
13095
13095
|
let basis = record !== null && record.syncEpoch === deps.syncEpoch() ? record : null;
|
|
13096
13096
|
for (let pass = 0; pass < 2; pass++) {
|
|
13097
|
-
await this.drainPages({ deps, engine, pending, stored, pageEpoch }, basis);
|
|
13097
|
+
await this.drainPages({ deps, engine, pending, stored, pageEpoch, claimable }, basis);
|
|
13098
13098
|
const served = deps.delivery.incomingEpoch();
|
|
13099
13099
|
if (basis === null || served === null || served === basis.syncEpoch) break;
|
|
13100
13100
|
await deps.kv.remove(STORE_KEYS.streamCursor("mailbox"));
|
|
@@ -13102,22 +13102,25 @@ var Receive = class {
|
|
|
13102
13102
|
}
|
|
13103
13103
|
} catch (err) {
|
|
13104
13104
|
logger.warn("PaymentsV2", "receive drain interrupted \u2014 unacked entries retry next drain:", err);
|
|
13105
|
-
if (isRetryableAckError(err)) return
|
|
13105
|
+
if (isRetryableAckError(err)) return finish();
|
|
13106
13106
|
await flushAcks(deps, pending, pageEpoch).catch((flushErr) => {
|
|
13107
13107
|
logger.warn("PaymentsV2", "receive ack flush failed \u2014 cursor holds at the acked prefix:", flushErr);
|
|
13108
|
+
return { progressed: false };
|
|
13108
13109
|
});
|
|
13109
13110
|
}
|
|
13110
|
-
|
|
13111
|
-
return stored;
|
|
13111
|
+
return finish();
|
|
13112
13112
|
}
|
|
13113
|
-
async processEntry(
|
|
13113
|
+
async processEntry(ctx, entry) {
|
|
13114
|
+
const { deps, engine, pending, stored, claimable } = ctx;
|
|
13114
13115
|
const screened = await screen(deps, engine, entry);
|
|
13115
13116
|
if (screened.kind === "ack") {
|
|
13116
13117
|
pending.push(screened.ack);
|
|
13118
|
+
if (screened.ack.disposition === "claimed") claimable.n += 1;
|
|
13117
13119
|
return;
|
|
13118
13120
|
}
|
|
13119
13121
|
await deps.view.store(screened.record);
|
|
13120
13122
|
pending.push(claimAck(entry));
|
|
13123
|
+
claimable.n += 1;
|
|
13121
13124
|
const transfer = await announce(deps, entry, screened.record);
|
|
13122
13125
|
stored.push(transfer);
|
|
13123
13126
|
deps.emit("transfer:incoming", transfer);
|
|
@@ -13127,13 +13130,9 @@ async function screen(deps, engine, entry) {
|
|
|
13127
13130
|
const blobBytes = await entry.fetchBlob();
|
|
13128
13131
|
let token;
|
|
13129
13132
|
try {
|
|
13130
|
-
token = await engine.decodeToken({
|
|
13131
|
-
|
|
13132
|
-
|
|
13133
|
-
tokenId: "",
|
|
13134
|
-
token: blobBytes
|
|
13135
|
-
});
|
|
13136
|
-
} catch {
|
|
13133
|
+
token = await engine.decodeToken({ tokenId: "", token: blobBytes });
|
|
13134
|
+
} catch (err) {
|
|
13135
|
+
logger.warn("PaymentsV2", `receive: undecodable blob rejected \u2014 ${String(err)}`);
|
|
13137
13136
|
return { kind: "ack", ack: rejectAck(entry, "invalid") };
|
|
13138
13137
|
}
|
|
13139
13138
|
const verdict = await engine.verify(token);
|
|
@@ -13178,7 +13177,8 @@ async function announce(deps, entry, record) {
|
|
|
13178
13177
|
};
|
|
13179
13178
|
}
|
|
13180
13179
|
async function flushAcks(deps, pending, epochOf) {
|
|
13181
|
-
if (pending.length === 0) return;
|
|
13180
|
+
if (pending.length === 0) return { progressed: true };
|
|
13181
|
+
const before = pending.length;
|
|
13182
13182
|
let lastAcked = null;
|
|
13183
13183
|
try {
|
|
13184
13184
|
const settled = await settleAcks(deps, pending);
|
|
@@ -13196,6 +13196,7 @@ async function flushAcks(deps, pending, epochOf) {
|
|
|
13196
13196
|
await deps.kv.set(STORE_KEYS.streamCursor("mailbox"), record);
|
|
13197
13197
|
}
|
|
13198
13198
|
}
|
|
13199
|
+
return { progressed: pending.length < before };
|
|
13199
13200
|
}
|
|
13200
13201
|
async function settleAcks(deps, pending) {
|
|
13201
13202
|
const batch = deps.delivery.ackBatch?.bind(deps.delivery);
|
|
@@ -14534,7 +14535,7 @@ var PaymentsFacade = class {
|
|
|
14534
14535
|
if (bytes === void 0) {
|
|
14535
14536
|
throw new SphereError(`Selected source ${tokenId} has no blob in storage`, "STORAGE_ERROR");
|
|
14536
14537
|
}
|
|
14537
|
-
const token = await engine.decodeToken({
|
|
14538
|
+
const token = await engine.decodeToken({ tokenId, token: bytes });
|
|
14538
14539
|
const keys = await engine.deliveryKeys(bytes);
|
|
14539
14540
|
spentStates[tokenId] = { local: keys.stateHash, protocol: keys.stateHash };
|
|
14540
14541
|
sources.set(tokenId, token);
|
|
@@ -15716,7 +15717,9 @@ var WalletApiDeliveryPort = class {
|
|
|
15716
15717
|
await this.settleClaims(acks, settled, outcomes);
|
|
15717
15718
|
await this.settleRejects(acks, settled);
|
|
15718
15719
|
} catch (err) {
|
|
15719
|
-
await this.addSeenAll(settled).catch(() =>
|
|
15720
|
+
await this.addSeenAll(settled).catch((seenErr) => {
|
|
15721
|
+
logger.warn("WalletApiDelivery", `seen-set write failed for ${String(settled.length)} committed acks:`, seenErr);
|
|
15722
|
+
});
|
|
15720
15723
|
throw asRetryable(err);
|
|
15721
15724
|
}
|
|
15722
15725
|
await this.addSeenAll(settled);
|
|
@@ -15979,6 +15982,7 @@ function composePaymentsV2(spec) {
|
|
|
15979
15982
|
const network = spec.composition.network;
|
|
15980
15983
|
const identitySlice = { privateKey: identity.privateKey, chainPubkey: identity.chainPubkey };
|
|
15981
15984
|
const kv = createScopedKV(host.storage, network, identity.chainPubkey);
|
|
15985
|
+
void sweepSupersededState(host.storage);
|
|
15982
15986
|
const fieldKey = deriveFieldEncryptionKey(identity.privateKey);
|
|
15983
15987
|
const transport = spec.composition.factory({
|
|
15984
15988
|
identity: identitySlice,
|
|
@@ -16270,11 +16274,10 @@ var Sphere = class _Sphere {
|
|
|
16270
16274
|
return config;
|
|
16271
16275
|
}
|
|
16272
16276
|
/**
|
|
16273
|
-
* The ONE sanctioned refusal fossil of the P11 flip
|
|
16274
|
-
*
|
|
16275
|
-
*
|
|
16276
|
-
*
|
|
16277
|
-
* live frontend passes it today).
|
|
16277
|
+
* The ONE sanctioned refusal fossil of the P11 flip: `accounting`/`swap` were
|
|
16278
|
+
* public init flags — silently ignoring them would hide that invoices/swaps no
|
|
16279
|
+
* longer exist in the SDK. Kept through 0.15.0, where consumers re-integrate
|
|
16280
|
+
* across the wire break and a silent no-op would be worst.
|
|
16278
16281
|
*/
|
|
16279
16282
|
static refuseRetiredModuleOptions(options) {
|
|
16280
16283
|
if (options.accounting) {
|
|
@@ -16541,7 +16544,7 @@ var Sphere = class _Sphere {
|
|
|
16541
16544
|
}
|
|
16542
16545
|
/**
|
|
16543
16546
|
* Clear all SDK-owned wallet data from storage: wallet keys, per-address
|
|
16544
|
-
* data, and the payments vertical's `
|
|
16547
|
+
* data, and the payments vertical's `pv2g2:{network}:{pubkey}:*` scoped KV
|
|
16545
16548
|
* (refresh token, cursors, journals — all live in the plain StorageProvider,
|
|
16546
16549
|
* so the full KV wipe below removes them). Tokens are server-custody; the
|
|
16547
16550
|
* only local token artifacts are orphaned `sphere-token-storage-*` IndexedDB
|
|
@@ -16651,10 +16654,6 @@ var Sphere = class _Sphere {
|
|
|
16651
16654
|
}
|
|
16652
16655
|
return facade;
|
|
16653
16656
|
}
|
|
16654
|
-
/** @deprecated Alias of {@link payments} kept for one release (the live frontend calls it). Null when no vertical runs. */
|
|
16655
|
-
get paymentsV2() {
|
|
16656
|
-
return this._paymentsV2Active?.facade ?? null;
|
|
16657
|
-
}
|
|
16658
16657
|
/** Communications module */
|
|
16659
16658
|
get communications() {
|
|
16660
16659
|
this.ensureReady();
|