@unicitylabs/sphere-sdk 0.9.1-dev.12 → 0.9.1-dev.14
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/core/index.cjs +48 -30
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +31 -14
- package/dist/core/index.d.ts +31 -14
- package/dist/core/index.js +48 -30
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +48 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -14
- package/dist/index.d.ts +31 -14
- package/dist/index.js +48 -30
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/core/index.d.cts
CHANGED
|
@@ -2125,10 +2125,13 @@ declare class PaymentsModule {
|
|
|
2125
2125
|
/** Coalesces concurrent payment-request pump runs. */
|
|
2126
2126
|
private prPumpInFlight;
|
|
2127
2127
|
/**
|
|
2128
|
-
* Set after the once-per-session
|
|
2129
|
-
* incoming list is in-memory only, so
|
|
2130
|
-
*
|
|
2131
|
-
*
|
|
2128
|
+
* Set after the once-per-session full incoming hydration (#556): the surfaced
|
|
2129
|
+
* incoming list is in-memory only, so on a fresh engine the CURRENT state of
|
|
2130
|
+
* ALL incoming requests — open AND resolved (paid/declined/expired) — must be
|
|
2131
|
+
* rebuilt from a `role=incoming&since=0` pull, not just the still-open ones.
|
|
2132
|
+
* A status-filtered bootstrap (the pre-#556 `status=open` scan) dropped
|
|
2133
|
+
* requests resolved in a PRIOR session, so the payer reopened and the
|
|
2134
|
+
* 'Paid Successfully' request was gone (twin of #521/#549).
|
|
2132
2135
|
*/
|
|
2133
2136
|
private prBootstrapped;
|
|
2134
2137
|
private loadedPromise;
|
|
@@ -2865,11 +2868,19 @@ declare class PaymentsModule {
|
|
|
2865
2868
|
* mailbox-cursor pattern: the persisted `{cursor, syncEpoch}` is the resume
|
|
2866
2869
|
* point; a `syncEpoch` change (server restore — §5.4) voids cursor
|
|
2867
2870
|
* continuity, so the tail re-pulls from 0 and the id-dedup in
|
|
2868
|
-
* {@link surfaceIncomingPaymentRequest} absorbs the replays.
|
|
2869
|
-
*
|
|
2870
|
-
*
|
|
2871
|
-
*
|
|
2872
|
-
*
|
|
2871
|
+
* {@link surfaceIncomingPaymentRequest} absorbs the replays.
|
|
2872
|
+
*
|
|
2873
|
+
* Because the surfaced list is in-memory only, each session FIRST runs one
|
|
2874
|
+
* full incoming hydration from `since=0` with NO status filter (#556 —
|
|
2875
|
+
* mirrors {@link hydrateHistoryFromServer}): a fresh engine rebuilds the
|
|
2876
|
+
* CURRENT state of ALL incoming requests — open AND resolved — so a request
|
|
2877
|
+
* paid/declined/expired in a PRIOR session is still present (with its
|
|
2878
|
+
* resolved status) instead of vanishing once the cursor advanced past it.
|
|
2879
|
+
* Hydration NEVER fires the new-incoming handlers/events for resolved
|
|
2880
|
+
* requests — only `open` ones notify (the status-aware
|
|
2881
|
+
* {@link surfaceIncomingPaymentRequest}) — so reopening can't spam stale
|
|
2882
|
+
* 'new request' notifications. After hydration the `since`-cursor delta poll
|
|
2883
|
+
* picks up live updates from the resume point.
|
|
2873
2884
|
*/
|
|
2874
2885
|
private pumpIncomingPaymentRequests;
|
|
2875
2886
|
/**
|
|
@@ -2882,13 +2893,19 @@ declare class PaymentsModule {
|
|
|
2882
2893
|
* (PR twin of #546/#547).
|
|
2883
2894
|
*/
|
|
2884
2895
|
private decryptPaymentRequestMemo;
|
|
2896
|
+
/** §16 wire status → the public {@link PaymentRequestStatus} display status. */
|
|
2897
|
+
private static readonly PR_WIRE_STATUS;
|
|
2885
2898
|
/**
|
|
2886
2899
|
* Map a §16 wire request onto the public {@link IncomingPaymentRequest}
|
|
2887
|
-
* surface
|
|
2888
|
-
*
|
|
2889
|
-
*
|
|
2890
|
-
*
|
|
2891
|
-
*
|
|
2900
|
+
* surface, deduped by id (the in-memory id-dedup doubles as the replay guard
|
|
2901
|
+
* for cursor resets). Requests of EVERY status are surfaced so a reloaded
|
|
2902
|
+
* thin wallet rebuilds the CURRENT state of its incoming view (#556) — open
|
|
2903
|
+
* ones land as actionable `pending`, resolved ones carry their paid/declined
|
|
2904
|
+
* (→ `rejected`)/expired status. Only `open` requests fire the new-incoming
|
|
2905
|
+
* event + handlers; resolved requests are folded into the list silently, so a
|
|
2906
|
+
* reload (or a `syncEpoch` re-pull) never re-notifies for already-resolved
|
|
2907
|
+
* requests. Multi-asset requests surface their first asset (the module's
|
|
2908
|
+
* request surface is single-asset; module-created requests always are).
|
|
2892
2909
|
*/
|
|
2893
2910
|
private surfaceIncomingPaymentRequest;
|
|
2894
2911
|
/**
|
package/dist/core/index.d.ts
CHANGED
|
@@ -2125,10 +2125,13 @@ declare class PaymentsModule {
|
|
|
2125
2125
|
/** Coalesces concurrent payment-request pump runs. */
|
|
2126
2126
|
private prPumpInFlight;
|
|
2127
2127
|
/**
|
|
2128
|
-
* Set after the once-per-session
|
|
2129
|
-
* incoming list is in-memory only, so
|
|
2130
|
-
*
|
|
2131
|
-
*
|
|
2128
|
+
* Set after the once-per-session full incoming hydration (#556): the surfaced
|
|
2129
|
+
* incoming list is in-memory only, so on a fresh engine the CURRENT state of
|
|
2130
|
+
* ALL incoming requests — open AND resolved (paid/declined/expired) — must be
|
|
2131
|
+
* rebuilt from a `role=incoming&since=0` pull, not just the still-open ones.
|
|
2132
|
+
* A status-filtered bootstrap (the pre-#556 `status=open` scan) dropped
|
|
2133
|
+
* requests resolved in a PRIOR session, so the payer reopened and the
|
|
2134
|
+
* 'Paid Successfully' request was gone (twin of #521/#549).
|
|
2132
2135
|
*/
|
|
2133
2136
|
private prBootstrapped;
|
|
2134
2137
|
private loadedPromise;
|
|
@@ -2865,11 +2868,19 @@ declare class PaymentsModule {
|
|
|
2865
2868
|
* mailbox-cursor pattern: the persisted `{cursor, syncEpoch}` is the resume
|
|
2866
2869
|
* point; a `syncEpoch` change (server restore — §5.4) voids cursor
|
|
2867
2870
|
* continuity, so the tail re-pulls from 0 and the id-dedup in
|
|
2868
|
-
* {@link surfaceIncomingPaymentRequest} absorbs the replays.
|
|
2869
|
-
*
|
|
2870
|
-
*
|
|
2871
|
-
*
|
|
2872
|
-
*
|
|
2871
|
+
* {@link surfaceIncomingPaymentRequest} absorbs the replays.
|
|
2872
|
+
*
|
|
2873
|
+
* Because the surfaced list is in-memory only, each session FIRST runs one
|
|
2874
|
+
* full incoming hydration from `since=0` with NO status filter (#556 —
|
|
2875
|
+
* mirrors {@link hydrateHistoryFromServer}): a fresh engine rebuilds the
|
|
2876
|
+
* CURRENT state of ALL incoming requests — open AND resolved — so a request
|
|
2877
|
+
* paid/declined/expired in a PRIOR session is still present (with its
|
|
2878
|
+
* resolved status) instead of vanishing once the cursor advanced past it.
|
|
2879
|
+
* Hydration NEVER fires the new-incoming handlers/events for resolved
|
|
2880
|
+
* requests — only `open` ones notify (the status-aware
|
|
2881
|
+
* {@link surfaceIncomingPaymentRequest}) — so reopening can't spam stale
|
|
2882
|
+
* 'new request' notifications. After hydration the `since`-cursor delta poll
|
|
2883
|
+
* picks up live updates from the resume point.
|
|
2873
2884
|
*/
|
|
2874
2885
|
private pumpIncomingPaymentRequests;
|
|
2875
2886
|
/**
|
|
@@ -2882,13 +2893,19 @@ declare class PaymentsModule {
|
|
|
2882
2893
|
* (PR twin of #546/#547).
|
|
2883
2894
|
*/
|
|
2884
2895
|
private decryptPaymentRequestMemo;
|
|
2896
|
+
/** §16 wire status → the public {@link PaymentRequestStatus} display status. */
|
|
2897
|
+
private static readonly PR_WIRE_STATUS;
|
|
2885
2898
|
/**
|
|
2886
2899
|
* Map a §16 wire request onto the public {@link IncomingPaymentRequest}
|
|
2887
|
-
* surface
|
|
2888
|
-
*
|
|
2889
|
-
*
|
|
2890
|
-
*
|
|
2891
|
-
*
|
|
2900
|
+
* surface, deduped by id (the in-memory id-dedup doubles as the replay guard
|
|
2901
|
+
* for cursor resets). Requests of EVERY status are surfaced so a reloaded
|
|
2902
|
+
* thin wallet rebuilds the CURRENT state of its incoming view (#556) — open
|
|
2903
|
+
* ones land as actionable `pending`, resolved ones carry their paid/declined
|
|
2904
|
+
* (→ `rejected`)/expired status. Only `open` requests fire the new-incoming
|
|
2905
|
+
* event + handlers; resolved requests are folded into the list silently, so a
|
|
2906
|
+
* reload (or a `syncEpoch` re-pull) never re-notifies for already-resolved
|
|
2907
|
+
* requests. Multi-asset requests surface their first asset (the module's
|
|
2908
|
+
* request surface is single-asset; module-created requests always are).
|
|
2892
2909
|
*/
|
|
2893
2910
|
private surfaceIncomingPaymentRequest;
|
|
2894
2911
|
/**
|
package/dist/core/index.js
CHANGED
|
@@ -11349,6 +11349,7 @@ function computeHistoryDedupKey(type, tokenId, transferId) {
|
|
|
11349
11349
|
}
|
|
11350
11350
|
var MAX_SYNCED_HISTORY_ENTRIES = 5e3;
|
|
11351
11351
|
var MAX_HISTORY_HYDRATION_PAGES = 100;
|
|
11352
|
+
var MAX_PR_HYDRATION_PAGES = 100;
|
|
11352
11353
|
var SEND_ENGINE_OP_TIMEOUT_MS = 6e4;
|
|
11353
11354
|
var DELIVERY_POLL_INTERVAL_MS = 3e4;
|
|
11354
11355
|
function enrichWithRegistry(info) {
|
|
@@ -11676,10 +11677,13 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
11676
11677
|
/** Coalesces concurrent payment-request pump runs. */
|
|
11677
11678
|
prPumpInFlight = null;
|
|
11678
11679
|
/**
|
|
11679
|
-
* Set after the once-per-session
|
|
11680
|
-
* incoming list is in-memory only, so
|
|
11681
|
-
*
|
|
11682
|
-
*
|
|
11680
|
+
* Set after the once-per-session full incoming hydration (#556): the surfaced
|
|
11681
|
+
* incoming list is in-memory only, so on a fresh engine the CURRENT state of
|
|
11682
|
+
* ALL incoming requests — open AND resolved (paid/declined/expired) — must be
|
|
11683
|
+
* rebuilt from a `role=incoming&since=0` pull, not just the still-open ones.
|
|
11684
|
+
* A status-filtered bootstrap (the pre-#556 `status=open` scan) dropped
|
|
11685
|
+
* requests resolved in a PRIOR session, so the payer reopened and the
|
|
11686
|
+
* 'Paid Successfully' request was gone (twin of #521/#549).
|
|
11683
11687
|
*/
|
|
11684
11688
|
prBootstrapped = false;
|
|
11685
11689
|
// Guard: ensure load() completes before processing incoming bundles
|
|
@@ -14528,22 +14532,28 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
14528
14532
|
* mailbox-cursor pattern: the persisted `{cursor, syncEpoch}` is the resume
|
|
14529
14533
|
* point; a `syncEpoch` change (server restore — §5.4) voids cursor
|
|
14530
14534
|
* continuity, so the tail re-pulls from 0 and the id-dedup in
|
|
14531
|
-
* {@link surfaceIncomingPaymentRequest} absorbs the replays.
|
|
14532
|
-
*
|
|
14533
|
-
*
|
|
14534
|
-
*
|
|
14535
|
-
*
|
|
14535
|
+
* {@link surfaceIncomingPaymentRequest} absorbs the replays.
|
|
14536
|
+
*
|
|
14537
|
+
* Because the surfaced list is in-memory only, each session FIRST runs one
|
|
14538
|
+
* full incoming hydration from `since=0` with NO status filter (#556 —
|
|
14539
|
+
* mirrors {@link hydrateHistoryFromServer}): a fresh engine rebuilds the
|
|
14540
|
+
* CURRENT state of ALL incoming requests — open AND resolved — so a request
|
|
14541
|
+
* paid/declined/expired in a PRIOR session is still present (with its
|
|
14542
|
+
* resolved status) instead of vanishing once the cursor advanced past it.
|
|
14543
|
+
* Hydration NEVER fires the new-incoming handlers/events for resolved
|
|
14544
|
+
* requests — only `open` ones notify (the status-aware
|
|
14545
|
+
* {@link surfaceIncomingPaymentRequest}) — so reopening can't spam stale
|
|
14546
|
+
* 'new request' notifications. After hydration the `since`-cursor delta poll
|
|
14547
|
+
* picks up live updates from the resume point.
|
|
14536
14548
|
*/
|
|
14537
14549
|
async pumpIncomingPaymentRequests(api) {
|
|
14538
14550
|
const persisted = await this.readPrCursorState();
|
|
14539
14551
|
if (!this.prBootstrapped) {
|
|
14540
|
-
|
|
14541
|
-
|
|
14542
|
-
for (
|
|
14543
|
-
|
|
14544
|
-
|
|
14545
|
-
scan = await api.listPaymentRequests({ role: "incoming", status: "open", since: scan.cursor });
|
|
14546
|
-
}
|
|
14552
|
+
let scan = await api.listPaymentRequests({ role: "incoming", since: 0n });
|
|
14553
|
+
for (let pageCount = 0; pageCount < MAX_PR_HYDRATION_PAGES; pageCount++) {
|
|
14554
|
+
for (const wire of scan.requests) this.surfaceIncomingPaymentRequest(wire);
|
|
14555
|
+
if (!scan.more) break;
|
|
14556
|
+
scan = await api.listPaymentRequests({ role: "incoming", since: scan.cursor });
|
|
14547
14557
|
}
|
|
14548
14558
|
this.prBootstrapped = true;
|
|
14549
14559
|
}
|
|
@@ -14577,17 +14587,23 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
14577
14587
|
return {};
|
|
14578
14588
|
}
|
|
14579
14589
|
}
|
|
14590
|
+
/** §16 wire status → the public {@link PaymentRequestStatus} display status. */
|
|
14591
|
+
static PR_WIRE_STATUS = { open: "pending", paid: "paid", declined: "rejected", expired: "expired" };
|
|
14580
14592
|
/**
|
|
14581
14593
|
* Map a §16 wire request onto the public {@link IncomingPaymentRequest}
|
|
14582
|
-
* surface
|
|
14583
|
-
*
|
|
14584
|
-
*
|
|
14585
|
-
*
|
|
14586
|
-
*
|
|
14594
|
+
* surface, deduped by id (the in-memory id-dedup doubles as the replay guard
|
|
14595
|
+
* for cursor resets). Requests of EVERY status are surfaced so a reloaded
|
|
14596
|
+
* thin wallet rebuilds the CURRENT state of its incoming view (#556) — open
|
|
14597
|
+
* ones land as actionable `pending`, resolved ones carry their paid/declined
|
|
14598
|
+
* (→ `rejected`)/expired status. Only `open` requests fire the new-incoming
|
|
14599
|
+
* event + handlers; resolved requests are folded into the list silently, so a
|
|
14600
|
+
* reload (or a `syncEpoch` re-pull) never re-notifies for already-resolved
|
|
14601
|
+
* requests. Multi-asset requests surface their first asset (the module's
|
|
14602
|
+
* request surface is single-asset; module-created requests always are).
|
|
14587
14603
|
*/
|
|
14588
14604
|
surfaceIncomingPaymentRequest(wire) {
|
|
14589
|
-
if (wire.status !== "open") return;
|
|
14590
14605
|
if (this.paymentRequests.some((r) => r.id === wire.id)) return;
|
|
14606
|
+
const status = _PaymentsModule.PR_WIRE_STATUS[wire.status];
|
|
14591
14607
|
const coinId = wire.assets[0]?.coinId ?? "";
|
|
14592
14608
|
const coinDef = TokenRegistry.getInstance().getDefinition(coinId);
|
|
14593
14609
|
const { memo: message, senderNametag } = this.decryptPaymentRequestMemo(wire);
|
|
@@ -14601,18 +14617,20 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
14601
14617
|
...message !== void 0 ? { message } : {},
|
|
14602
14618
|
requestId: wire.id,
|
|
14603
14619
|
timestamp: wire.createdAt,
|
|
14604
|
-
status
|
|
14620
|
+
status
|
|
14605
14621
|
};
|
|
14606
14622
|
this.paymentRequests.unshift(request);
|
|
14607
|
-
|
|
14608
|
-
|
|
14609
|
-
|
|
14610
|
-
|
|
14611
|
-
|
|
14612
|
-
|
|
14623
|
+
if (status === "pending") {
|
|
14624
|
+
this.deps?.emitEvent("payment_request:incoming", request);
|
|
14625
|
+
for (const handler of this.paymentRequestHandlers) {
|
|
14626
|
+
try {
|
|
14627
|
+
handler(request);
|
|
14628
|
+
} catch (error) {
|
|
14629
|
+
logger.debug("Payments", "Payment request handler error:", error);
|
|
14630
|
+
}
|
|
14613
14631
|
}
|
|
14614
14632
|
}
|
|
14615
|
-
logger.debug("Payments", `Incoming payment request: ${request.id} for ${request.amount} ${request.symbol}`);
|
|
14633
|
+
logger.debug("Payments", `Incoming payment request: ${request.id} (${status}) for ${request.amount} ${request.symbol}`);
|
|
14616
14634
|
}
|
|
14617
14635
|
/**
|
|
14618
14636
|
* Outgoing requests are a `?before=` backfill view (§16 — newest-first, no
|