@unicitylabs/sphere-sdk 0.14.11-dev.7 → 0.14.11
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/index.cjs +1 -1
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +1 -1
- package/dist/connect/index.js.map +1 -1
- package/dist/core/index.cjs +47 -19
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.js +47 -19
- 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 +1 -1
- package/dist/impl/browser/connect/index.js.map +1 -1
- package/dist/impl/wallet-api-v2/index.cjs +95 -0
- package/dist/impl/wallet-api-v2/index.cjs.map +1 -1
- package/dist/impl/wallet-api-v2/index.js +95 -0
- package/dist/impl/wallet-api-v2/index.js.map +1 -1
- package/dist/index.cjs +47 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +47 -19
- package/dist/index.js.map +1 -1
- package/dist/modules/payments-v2/index.cjs +51 -24
- package/dist/modules/payments-v2/index.cjs.map +1 -1
- package/dist/modules/payments-v2/index.d.cts +6 -1
- package/dist/modules/payments-v2/index.d.ts +6 -1
- package/dist/modules/payments-v2/index.js +50 -24
- package/dist/modules/payments-v2/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -356,6 +356,11 @@ type AckOutcome = {
|
|
|
356
356
|
readonly deliveryId: string;
|
|
357
357
|
readonly status: 'conflict';
|
|
358
358
|
};
|
|
359
|
+
/** ackBatch failed in a way a per-entry retry would hit too — do not fall back. */
|
|
360
|
+
interface RetryableAckError extends Error {
|
|
361
|
+
readonly retryable: true;
|
|
362
|
+
}
|
|
363
|
+
declare function isRetryableAckError(err: unknown): err is RetryableAckError;
|
|
359
364
|
|
|
360
365
|
interface IntentPayload {
|
|
361
366
|
v: 2;
|
|
@@ -1174,4 +1179,4 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1174
1179
|
declare const HEARTBEAT_SEED_MS = 5000;
|
|
1175
1180
|
declare const HEARTBEAT_CAP_MS = 120000;
|
|
1176
1181
|
|
|
1177
|
-
export { ATTENTION_MINT_UNRESOLVED, ATTENTION_RECIPIENT_NETWORK_UNVERIFIED, ATTENTION_RESEED_REJECTED, 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 MintResult, type OpOutcome, type OutcomeClass, type PaymentRequestStatus, type PaymentRequestView, PaymentsFacade, type PaymentsFacadeDeps, type PaymentsRequestsApi, type PaymentsV2, type PaymentsV2Events, type PendingTransfer, type PlannedOp, type RecipientInfo, STORE_KEYS, type ScopedKV, type SendRequest, type SettlingLink, type ShortfallEntry, type StoragePort, type StreamCursor, type StreamName, createScopedKV, supportsDeterministicMint };
|
|
1182
|
+
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 MintResult, 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 SendRequest, type SettlingLink, type ShortfallEntry, type StoragePort, type StreamCursor, type StreamName, createScopedKV, isRetryableAckError, supportsDeterministicMint };
|
|
@@ -356,6 +356,11 @@ type AckOutcome = {
|
|
|
356
356
|
readonly deliveryId: string;
|
|
357
357
|
readonly status: 'conflict';
|
|
358
358
|
};
|
|
359
|
+
/** ackBatch failed in a way a per-entry retry would hit too — do not fall back. */
|
|
360
|
+
interface RetryableAckError extends Error {
|
|
361
|
+
readonly retryable: true;
|
|
362
|
+
}
|
|
363
|
+
declare function isRetryableAckError(err: unknown): err is RetryableAckError;
|
|
359
364
|
|
|
360
365
|
interface IntentPayload {
|
|
361
366
|
v: 2;
|
|
@@ -1174,4 +1179,4 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1174
1179
|
declare const HEARTBEAT_SEED_MS = 5000;
|
|
1175
1180
|
declare const HEARTBEAT_CAP_MS = 120000;
|
|
1176
1181
|
|
|
1177
|
-
export { ATTENTION_MINT_UNRESOLVED, ATTENTION_RECIPIENT_NETWORK_UNVERIFIED, ATTENTION_RESEED_REJECTED, 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 MintResult, type OpOutcome, type OutcomeClass, type PaymentRequestStatus, type PaymentRequestView, PaymentsFacade, type PaymentsFacadeDeps, type PaymentsRequestsApi, type PaymentsV2, type PaymentsV2Events, type PendingTransfer, type PlannedOp, type RecipientInfo, STORE_KEYS, type ScopedKV, type SendRequest, type SettlingLink, type ShortfallEntry, type StoragePort, type StreamCursor, type StreamName, createScopedKV, supportsDeterministicMint };
|
|
1182
|
+
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 MintResult, 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 SendRequest, type SettlingLink, type ShortfallEntry, type StoragePort, type StreamCursor, type StreamName, createScopedKV, isRetryableAckError, supportsDeterministicMint };
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
// modules/payments-v2/ports.ts
|
|
2
|
+
function isRetryableAckError(err) {
|
|
3
|
+
return err !== null && typeof err === "object" && err.retryable === true;
|
|
4
|
+
}
|
|
5
|
+
|
|
1
6
|
// modules/payments-v2/stores.ts
|
|
2
7
|
function createScopedKV(storage, network, chainPubkey) {
|
|
3
8
|
const prefix = `pv2:${network}:${chainPubkey}:`;
|
|
@@ -536,12 +541,19 @@ var SerialChain = class {
|
|
|
536
541
|
return run;
|
|
537
542
|
}
|
|
538
543
|
};
|
|
539
|
-
function coalesced(run) {
|
|
544
|
+
function coalesced(run, observe) {
|
|
540
545
|
let inFlight = false;
|
|
541
546
|
let queued = false;
|
|
542
547
|
const start = () => {
|
|
543
548
|
inFlight = true;
|
|
544
|
-
|
|
549
|
+
let running;
|
|
550
|
+
try {
|
|
551
|
+
running = run();
|
|
552
|
+
} catch {
|
|
553
|
+
running = Promise.resolve();
|
|
554
|
+
}
|
|
555
|
+
observe?.(running);
|
|
556
|
+
void running.catch(() => void 0).finally(() => {
|
|
545
557
|
inFlight = false;
|
|
546
558
|
if (!queued) return;
|
|
547
559
|
queued = false;
|
|
@@ -3187,11 +3199,6 @@ var logger = {
|
|
|
3187
3199
|
}
|
|
3188
3200
|
};
|
|
3189
3201
|
|
|
3190
|
-
// modules/payments-v2/ports.ts
|
|
3191
|
-
function isRetryableAckError(err) {
|
|
3192
|
-
return err !== null && typeof err === "object" && err.retryable === true;
|
|
3193
|
-
}
|
|
3194
|
-
|
|
3195
3202
|
// modules/payments-v2/receive/Receive.ts
|
|
3196
3203
|
var ACK_BATCH_SIZE = 200;
|
|
3197
3204
|
var REFRESH_INTERVAL_MS = 2500;
|
|
@@ -3240,13 +3247,26 @@ var Receive = class {
|
|
|
3240
3247
|
* the tokens just accepted, and the balance would still only move at the end.
|
|
3241
3248
|
* Ordering is preserved: store() still precedes the ack (§5.7).
|
|
3242
3249
|
*/
|
|
3243
|
-
async maybeRefresh(
|
|
3250
|
+
async maybeRefresh(ctx) {
|
|
3251
|
+
const { deps, pending, pageEpoch } = ctx;
|
|
3244
3252
|
if (deps.refreshView === void 0) return;
|
|
3245
3253
|
const now = deps.now?.() ?? Date.now();
|
|
3246
3254
|
if (now - this.lastRefreshAt < REFRESH_INTERVAL_MS) return;
|
|
3247
3255
|
this.lastRefreshAt = now;
|
|
3248
|
-
await flushAcks(deps, pending,
|
|
3249
|
-
|
|
3256
|
+
if ((await flushAcks(deps, pending, pageEpoch)).progressed) deps.refreshView();
|
|
3257
|
+
}
|
|
3258
|
+
/** One listing pass: process each entry, flushing and refreshing as it goes. */
|
|
3259
|
+
async drainPages(ctx, basis) {
|
|
3260
|
+
const { deps, pending, pageEpoch, claimable } = ctx;
|
|
3261
|
+
for await (const entry of deps.delivery.incoming(basis === null ? void 0 : String(basis.cursor))) {
|
|
3262
|
+
const claimableBefore = claimable.n;
|
|
3263
|
+
await this.processEntry(ctx, entry);
|
|
3264
|
+
if (pending.length >= ACK_BATCH_SIZE) {
|
|
3265
|
+
if (!(await flushAcks(deps, pending, pageEpoch)).progressed) return;
|
|
3266
|
+
}
|
|
3267
|
+
if (claimable.n > claimableBefore) await this.maybeRefresh(ctx);
|
|
3268
|
+
}
|
|
3269
|
+
await flushAcks(deps, pending, pageEpoch);
|
|
3250
3270
|
}
|
|
3251
3271
|
async doDrain() {
|
|
3252
3272
|
const deps = this.deps;
|
|
@@ -3255,17 +3275,16 @@ var Receive = class {
|
|
|
3255
3275
|
const stored = [];
|
|
3256
3276
|
const pending = [];
|
|
3257
3277
|
const pageEpoch = () => deps.delivery.incomingEpoch() ?? deps.syncEpoch();
|
|
3278
|
+
const claimable = { n: 0 };
|
|
3279
|
+
const finish = () => {
|
|
3280
|
+
if (claimable.n > 0) deps.refreshView?.();
|
|
3281
|
+
return stored;
|
|
3282
|
+
};
|
|
3258
3283
|
try {
|
|
3259
3284
|
const record = await deps.kv.get(STORE_KEYS.streamCursor("mailbox"));
|
|
3260
3285
|
let basis = record !== null && record.syncEpoch === deps.syncEpoch() ? record : null;
|
|
3261
3286
|
for (let pass = 0; pass < 2; pass++) {
|
|
3262
|
-
|
|
3263
|
-
const storedBefore = stored.length;
|
|
3264
|
-
await this.processEntry(deps, engine, entry, pending, stored);
|
|
3265
|
-
if (pending.length >= ACK_BATCH_SIZE) await flushAcks(deps, pending, pageEpoch);
|
|
3266
|
-
if (stored.length > storedBefore) await this.maybeRefresh(deps, pending, pageEpoch);
|
|
3267
|
-
}
|
|
3268
|
-
await flushAcks(deps, pending, pageEpoch);
|
|
3287
|
+
await this.drainPages({ deps, engine, pending, stored, pageEpoch, claimable }, basis);
|
|
3269
3288
|
const served = deps.delivery.incomingEpoch();
|
|
3270
3289
|
if (basis === null || served === null || served === basis.syncEpoch) break;
|
|
3271
3290
|
await deps.kv.remove(STORE_KEYS.streamCursor("mailbox"));
|
|
@@ -3273,21 +3292,25 @@ var Receive = class {
|
|
|
3273
3292
|
}
|
|
3274
3293
|
} catch (err) {
|
|
3275
3294
|
logger.warn("PaymentsV2", "receive drain interrupted \u2014 unacked entries retry next drain:", err);
|
|
3276
|
-
if (isRetryableAckError(err)) return
|
|
3295
|
+
if (isRetryableAckError(err)) return finish();
|
|
3277
3296
|
await flushAcks(deps, pending, pageEpoch).catch((flushErr) => {
|
|
3278
3297
|
logger.warn("PaymentsV2", "receive ack flush failed \u2014 cursor holds at the acked prefix:", flushErr);
|
|
3298
|
+
return { progressed: false };
|
|
3279
3299
|
});
|
|
3280
3300
|
}
|
|
3281
|
-
return
|
|
3301
|
+
return finish();
|
|
3282
3302
|
}
|
|
3283
|
-
async processEntry(
|
|
3303
|
+
async processEntry(ctx, entry) {
|
|
3304
|
+
const { deps, engine, pending, stored, claimable } = ctx;
|
|
3284
3305
|
const screened = await screen(deps, engine, entry);
|
|
3285
3306
|
if (screened.kind === "ack") {
|
|
3286
3307
|
pending.push(screened.ack);
|
|
3308
|
+
if (screened.ack.disposition === "claimed") claimable.n += 1;
|
|
3287
3309
|
return;
|
|
3288
3310
|
}
|
|
3289
3311
|
await deps.view.store(screened.record);
|
|
3290
3312
|
pending.push(claimAck(entry));
|
|
3313
|
+
claimable.n += 1;
|
|
3291
3314
|
const transfer = await announce(deps, entry, screened.record);
|
|
3292
3315
|
stored.push(transfer);
|
|
3293
3316
|
deps.emit("transfer:incoming", transfer);
|
|
@@ -3348,7 +3371,8 @@ async function announce(deps, entry, record) {
|
|
|
3348
3371
|
};
|
|
3349
3372
|
}
|
|
3350
3373
|
async function flushAcks(deps, pending, epochOf) {
|
|
3351
|
-
if (pending.length === 0) return;
|
|
3374
|
+
if (pending.length === 0) return { progressed: true };
|
|
3375
|
+
const before = pending.length;
|
|
3352
3376
|
let lastAcked = null;
|
|
3353
3377
|
try {
|
|
3354
3378
|
const settled = await settleAcks(deps, pending);
|
|
@@ -3366,6 +3390,7 @@ async function flushAcks(deps, pending, epochOf) {
|
|
|
3366
3390
|
await deps.kv.set(STORE_KEYS.streamCursor("mailbox"), record);
|
|
3367
3391
|
}
|
|
3368
3392
|
}
|
|
3393
|
+
return { progressed: pending.length < before };
|
|
3369
3394
|
}
|
|
3370
3395
|
async function settleAcks(deps, pending) {
|
|
3371
3396
|
const batch = deps.delivery.ackBatch?.bind(deps.delivery);
|
|
@@ -4208,7 +4233,7 @@ function composeFacadeParts(deps, hooks) {
|
|
|
4208
4233
|
const machineDeps = buildMachineDeps(deps, hooks, historyStore);
|
|
4209
4234
|
const machineStores = createMachineStores(deps.kv);
|
|
4210
4235
|
const heldStates = /* @__PURE__ */ new Map();
|
|
4211
|
-
const refreshView = coalesced(() => view.delta());
|
|
4236
|
+
const refreshView = coalesced(() => view.delta(), hooks.track);
|
|
4212
4237
|
return {
|
|
4213
4238
|
ownPubkeyBytes,
|
|
4214
4239
|
view,
|
|
@@ -4351,7 +4376,8 @@ var PaymentsFacade = class {
|
|
|
4351
4376
|
const parts = composeFacadeParts(deps, {
|
|
4352
4377
|
engine: () => this.engine(),
|
|
4353
4378
|
send: (request) => this.send(request),
|
|
4354
|
-
isActiveOp: (id) => this.activeMoneyOps.has(id)
|
|
4379
|
+
isActiveOp: (id) => this.activeMoneyOps.has(id),
|
|
4380
|
+
track: (op) => this.trackTail(op)
|
|
4355
4381
|
});
|
|
4356
4382
|
this.view = parts.view;
|
|
4357
4383
|
this.wakeRefresh = parts.refreshView;
|
|
@@ -4491,7 +4517,6 @@ var PaymentsFacade = class {
|
|
|
4491
4517
|
}
|
|
4492
4518
|
async receive() {
|
|
4493
4519
|
const transfers = await this.track(this.receiveLoop.drainOnce());
|
|
4494
|
-
if (transfers.length > 0) this.trackTail(this.view.delta());
|
|
4495
4520
|
return { transfers };
|
|
4496
4521
|
}
|
|
4497
4522
|
mint(coinId, amount) {
|
|
@@ -4968,6 +4993,7 @@ export {
|
|
|
4968
4993
|
PaymentsFacade,
|
|
4969
4994
|
STORE_KEYS,
|
|
4970
4995
|
createScopedKV,
|
|
4996
|
+
isRetryableAckError,
|
|
4971
4997
|
supportsDeterministicMint
|
|
4972
4998
|
};
|
|
4973
4999
|
/*! Bundled license information:
|