@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/index.d.cts
CHANGED
|
@@ -2065,10 +2065,13 @@ declare class PaymentsModule {
|
|
|
2065
2065
|
/** Coalesces concurrent payment-request pump runs. */
|
|
2066
2066
|
private prPumpInFlight;
|
|
2067
2067
|
/**
|
|
2068
|
-
* Set after the once-per-session
|
|
2069
|
-
* incoming list is in-memory only, so
|
|
2070
|
-
*
|
|
2071
|
-
*
|
|
2068
|
+
* Set after the once-per-session full incoming hydration (#556): the surfaced
|
|
2069
|
+
* incoming list is in-memory only, so on a fresh engine the CURRENT state of
|
|
2070
|
+
* ALL incoming requests — open AND resolved (paid/declined/expired) — must be
|
|
2071
|
+
* rebuilt from a `role=incoming&since=0` pull, not just the still-open ones.
|
|
2072
|
+
* A status-filtered bootstrap (the pre-#556 `status=open` scan) dropped
|
|
2073
|
+
* requests resolved in a PRIOR session, so the payer reopened and the
|
|
2074
|
+
* 'Paid Successfully' request was gone (twin of #521/#549).
|
|
2072
2075
|
*/
|
|
2073
2076
|
private prBootstrapped;
|
|
2074
2077
|
private loadedPromise;
|
|
@@ -2805,11 +2808,19 @@ declare class PaymentsModule {
|
|
|
2805
2808
|
* mailbox-cursor pattern: the persisted `{cursor, syncEpoch}` is the resume
|
|
2806
2809
|
* point; a `syncEpoch` change (server restore — §5.4) voids cursor
|
|
2807
2810
|
* continuity, so the tail re-pulls from 0 and the id-dedup in
|
|
2808
|
-
* {@link surfaceIncomingPaymentRequest} absorbs the replays.
|
|
2809
|
-
*
|
|
2810
|
-
*
|
|
2811
|
-
*
|
|
2812
|
-
*
|
|
2811
|
+
* {@link surfaceIncomingPaymentRequest} absorbs the replays.
|
|
2812
|
+
*
|
|
2813
|
+
* Because the surfaced list is in-memory only, each session FIRST runs one
|
|
2814
|
+
* full incoming hydration from `since=0` with NO status filter (#556 —
|
|
2815
|
+
* mirrors {@link hydrateHistoryFromServer}): a fresh engine rebuilds the
|
|
2816
|
+
* CURRENT state of ALL incoming requests — open AND resolved — so a request
|
|
2817
|
+
* paid/declined/expired in a PRIOR session is still present (with its
|
|
2818
|
+
* resolved status) instead of vanishing once the cursor advanced past it.
|
|
2819
|
+
* Hydration NEVER fires the new-incoming handlers/events for resolved
|
|
2820
|
+
* requests — only `open` ones notify (the status-aware
|
|
2821
|
+
* {@link surfaceIncomingPaymentRequest}) — so reopening can't spam stale
|
|
2822
|
+
* 'new request' notifications. After hydration the `since`-cursor delta poll
|
|
2823
|
+
* picks up live updates from the resume point.
|
|
2813
2824
|
*/
|
|
2814
2825
|
private pumpIncomingPaymentRequests;
|
|
2815
2826
|
/**
|
|
@@ -2822,13 +2833,19 @@ declare class PaymentsModule {
|
|
|
2822
2833
|
* (PR twin of #546/#547).
|
|
2823
2834
|
*/
|
|
2824
2835
|
private decryptPaymentRequestMemo;
|
|
2836
|
+
/** §16 wire status → the public {@link PaymentRequestStatus} display status. */
|
|
2837
|
+
private static readonly PR_WIRE_STATUS;
|
|
2825
2838
|
/**
|
|
2826
2839
|
* Map a §16 wire request onto the public {@link IncomingPaymentRequest}
|
|
2827
|
-
* surface
|
|
2828
|
-
*
|
|
2829
|
-
*
|
|
2830
|
-
*
|
|
2831
|
-
*
|
|
2840
|
+
* surface, deduped by id (the in-memory id-dedup doubles as the replay guard
|
|
2841
|
+
* for cursor resets). Requests of EVERY status are surfaced so a reloaded
|
|
2842
|
+
* thin wallet rebuilds the CURRENT state of its incoming view (#556) — open
|
|
2843
|
+
* ones land as actionable `pending`, resolved ones carry their paid/declined
|
|
2844
|
+
* (→ `rejected`)/expired status. Only `open` requests fire the new-incoming
|
|
2845
|
+
* event + handlers; resolved requests are folded into the list silently, so a
|
|
2846
|
+
* reload (or a `syncEpoch` re-pull) never re-notifies for already-resolved
|
|
2847
|
+
* requests. Multi-asset requests surface their first asset (the module's
|
|
2848
|
+
* request surface is single-asset; module-created requests always are).
|
|
2832
2849
|
*/
|
|
2833
2850
|
private surfaceIncomingPaymentRequest;
|
|
2834
2851
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -2065,10 +2065,13 @@ declare class PaymentsModule {
|
|
|
2065
2065
|
/** Coalesces concurrent payment-request pump runs. */
|
|
2066
2066
|
private prPumpInFlight;
|
|
2067
2067
|
/**
|
|
2068
|
-
* Set after the once-per-session
|
|
2069
|
-
* incoming list is in-memory only, so
|
|
2070
|
-
*
|
|
2071
|
-
*
|
|
2068
|
+
* Set after the once-per-session full incoming hydration (#556): the surfaced
|
|
2069
|
+
* incoming list is in-memory only, so on a fresh engine the CURRENT state of
|
|
2070
|
+
* ALL incoming requests — open AND resolved (paid/declined/expired) — must be
|
|
2071
|
+
* rebuilt from a `role=incoming&since=0` pull, not just the still-open ones.
|
|
2072
|
+
* A status-filtered bootstrap (the pre-#556 `status=open` scan) dropped
|
|
2073
|
+
* requests resolved in a PRIOR session, so the payer reopened and the
|
|
2074
|
+
* 'Paid Successfully' request was gone (twin of #521/#549).
|
|
2072
2075
|
*/
|
|
2073
2076
|
private prBootstrapped;
|
|
2074
2077
|
private loadedPromise;
|
|
@@ -2805,11 +2808,19 @@ declare class PaymentsModule {
|
|
|
2805
2808
|
* mailbox-cursor pattern: the persisted `{cursor, syncEpoch}` is the resume
|
|
2806
2809
|
* point; a `syncEpoch` change (server restore — §5.4) voids cursor
|
|
2807
2810
|
* continuity, so the tail re-pulls from 0 and the id-dedup in
|
|
2808
|
-
* {@link surfaceIncomingPaymentRequest} absorbs the replays.
|
|
2809
|
-
*
|
|
2810
|
-
*
|
|
2811
|
-
*
|
|
2812
|
-
*
|
|
2811
|
+
* {@link surfaceIncomingPaymentRequest} absorbs the replays.
|
|
2812
|
+
*
|
|
2813
|
+
* Because the surfaced list is in-memory only, each session FIRST runs one
|
|
2814
|
+
* full incoming hydration from `since=0` with NO status filter (#556 —
|
|
2815
|
+
* mirrors {@link hydrateHistoryFromServer}): a fresh engine rebuilds the
|
|
2816
|
+
* CURRENT state of ALL incoming requests — open AND resolved — so a request
|
|
2817
|
+
* paid/declined/expired in a PRIOR session is still present (with its
|
|
2818
|
+
* resolved status) instead of vanishing once the cursor advanced past it.
|
|
2819
|
+
* Hydration NEVER fires the new-incoming handlers/events for resolved
|
|
2820
|
+
* requests — only `open` ones notify (the status-aware
|
|
2821
|
+
* {@link surfaceIncomingPaymentRequest}) — so reopening can't spam stale
|
|
2822
|
+
* 'new request' notifications. After hydration the `since`-cursor delta poll
|
|
2823
|
+
* picks up live updates from the resume point.
|
|
2813
2824
|
*/
|
|
2814
2825
|
private pumpIncomingPaymentRequests;
|
|
2815
2826
|
/**
|
|
@@ -2822,13 +2833,19 @@ declare class PaymentsModule {
|
|
|
2822
2833
|
* (PR twin of #546/#547).
|
|
2823
2834
|
*/
|
|
2824
2835
|
private decryptPaymentRequestMemo;
|
|
2836
|
+
/** §16 wire status → the public {@link PaymentRequestStatus} display status. */
|
|
2837
|
+
private static readonly PR_WIRE_STATUS;
|
|
2825
2838
|
/**
|
|
2826
2839
|
* Map a §16 wire request onto the public {@link IncomingPaymentRequest}
|
|
2827
|
-
* surface
|
|
2828
|
-
*
|
|
2829
|
-
*
|
|
2830
|
-
*
|
|
2831
|
-
*
|
|
2840
|
+
* surface, deduped by id (the in-memory id-dedup doubles as the replay guard
|
|
2841
|
+
* for cursor resets). Requests of EVERY status are surfaced so a reloaded
|
|
2842
|
+
* thin wallet rebuilds the CURRENT state of its incoming view (#556) — open
|
|
2843
|
+
* ones land as actionable `pending`, resolved ones carry their paid/declined
|
|
2844
|
+
* (→ `rejected`)/expired status. Only `open` requests fire the new-incoming
|
|
2845
|
+
* event + handlers; resolved requests are folded into the list silently, so a
|
|
2846
|
+
* reload (or a `syncEpoch` re-pull) never re-notifies for already-resolved
|
|
2847
|
+
* requests. Multi-asset requests surface their first asset (the module's
|
|
2848
|
+
* request surface is single-asset; module-created requests always are).
|
|
2832
2849
|
*/
|
|
2833
2850
|
private surfaceIncomingPaymentRequest;
|
|
2834
2851
|
/**
|
package/dist/index.js
CHANGED
|
@@ -11613,6 +11613,7 @@ function computeHistoryDedupKey(type, tokenId, transferId) {
|
|
|
11613
11613
|
}
|
|
11614
11614
|
var MAX_SYNCED_HISTORY_ENTRIES = 5e3;
|
|
11615
11615
|
var MAX_HISTORY_HYDRATION_PAGES = 100;
|
|
11616
|
+
var MAX_PR_HYDRATION_PAGES = 100;
|
|
11616
11617
|
var SEND_ENGINE_OP_TIMEOUT_MS = 6e4;
|
|
11617
11618
|
var DELIVERY_POLL_INTERVAL_MS = 3e4;
|
|
11618
11619
|
function enrichWithRegistry(info) {
|
|
@@ -11940,10 +11941,13 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
11940
11941
|
/** Coalesces concurrent payment-request pump runs. */
|
|
11941
11942
|
prPumpInFlight = null;
|
|
11942
11943
|
/**
|
|
11943
|
-
* Set after the once-per-session
|
|
11944
|
-
* incoming list is in-memory only, so
|
|
11945
|
-
*
|
|
11946
|
-
*
|
|
11944
|
+
* Set after the once-per-session full incoming hydration (#556): the surfaced
|
|
11945
|
+
* incoming list is in-memory only, so on a fresh engine the CURRENT state of
|
|
11946
|
+
* ALL incoming requests — open AND resolved (paid/declined/expired) — must be
|
|
11947
|
+
* rebuilt from a `role=incoming&since=0` pull, not just the still-open ones.
|
|
11948
|
+
* A status-filtered bootstrap (the pre-#556 `status=open` scan) dropped
|
|
11949
|
+
* requests resolved in a PRIOR session, so the payer reopened and the
|
|
11950
|
+
* 'Paid Successfully' request was gone (twin of #521/#549).
|
|
11947
11951
|
*/
|
|
11948
11952
|
prBootstrapped = false;
|
|
11949
11953
|
// Guard: ensure load() completes before processing incoming bundles
|
|
@@ -14792,22 +14796,28 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
14792
14796
|
* mailbox-cursor pattern: the persisted `{cursor, syncEpoch}` is the resume
|
|
14793
14797
|
* point; a `syncEpoch` change (server restore — §5.4) voids cursor
|
|
14794
14798
|
* continuity, so the tail re-pulls from 0 and the id-dedup in
|
|
14795
|
-
* {@link surfaceIncomingPaymentRequest} absorbs the replays.
|
|
14796
|
-
*
|
|
14797
|
-
*
|
|
14798
|
-
*
|
|
14799
|
-
*
|
|
14799
|
+
* {@link surfaceIncomingPaymentRequest} absorbs the replays.
|
|
14800
|
+
*
|
|
14801
|
+
* Because the surfaced list is in-memory only, each session FIRST runs one
|
|
14802
|
+
* full incoming hydration from `since=0` with NO status filter (#556 —
|
|
14803
|
+
* mirrors {@link hydrateHistoryFromServer}): a fresh engine rebuilds the
|
|
14804
|
+
* CURRENT state of ALL incoming requests — open AND resolved — so a request
|
|
14805
|
+
* paid/declined/expired in a PRIOR session is still present (with its
|
|
14806
|
+
* resolved status) instead of vanishing once the cursor advanced past it.
|
|
14807
|
+
* Hydration NEVER fires the new-incoming handlers/events for resolved
|
|
14808
|
+
* requests — only `open` ones notify (the status-aware
|
|
14809
|
+
* {@link surfaceIncomingPaymentRequest}) — so reopening can't spam stale
|
|
14810
|
+
* 'new request' notifications. After hydration the `since`-cursor delta poll
|
|
14811
|
+
* picks up live updates from the resume point.
|
|
14800
14812
|
*/
|
|
14801
14813
|
async pumpIncomingPaymentRequests(api) {
|
|
14802
14814
|
const persisted = await this.readPrCursorState();
|
|
14803
14815
|
if (!this.prBootstrapped) {
|
|
14804
|
-
|
|
14805
|
-
|
|
14806
|
-
for (
|
|
14807
|
-
|
|
14808
|
-
|
|
14809
|
-
scan = await api.listPaymentRequests({ role: "incoming", status: "open", since: scan.cursor });
|
|
14810
|
-
}
|
|
14816
|
+
let scan = await api.listPaymentRequests({ role: "incoming", since: 0n });
|
|
14817
|
+
for (let pageCount = 0; pageCount < MAX_PR_HYDRATION_PAGES; pageCount++) {
|
|
14818
|
+
for (const wire of scan.requests) this.surfaceIncomingPaymentRequest(wire);
|
|
14819
|
+
if (!scan.more) break;
|
|
14820
|
+
scan = await api.listPaymentRequests({ role: "incoming", since: scan.cursor });
|
|
14811
14821
|
}
|
|
14812
14822
|
this.prBootstrapped = true;
|
|
14813
14823
|
}
|
|
@@ -14841,17 +14851,23 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
14841
14851
|
return {};
|
|
14842
14852
|
}
|
|
14843
14853
|
}
|
|
14854
|
+
/** §16 wire status → the public {@link PaymentRequestStatus} display status. */
|
|
14855
|
+
static PR_WIRE_STATUS = { open: "pending", paid: "paid", declined: "rejected", expired: "expired" };
|
|
14844
14856
|
/**
|
|
14845
14857
|
* Map a §16 wire request onto the public {@link IncomingPaymentRequest}
|
|
14846
|
-
* surface
|
|
14847
|
-
*
|
|
14848
|
-
*
|
|
14849
|
-
*
|
|
14850
|
-
*
|
|
14858
|
+
* surface, deduped by id (the in-memory id-dedup doubles as the replay guard
|
|
14859
|
+
* for cursor resets). Requests of EVERY status are surfaced so a reloaded
|
|
14860
|
+
* thin wallet rebuilds the CURRENT state of its incoming view (#556) — open
|
|
14861
|
+
* ones land as actionable `pending`, resolved ones carry their paid/declined
|
|
14862
|
+
* (→ `rejected`)/expired status. Only `open` requests fire the new-incoming
|
|
14863
|
+
* event + handlers; resolved requests are folded into the list silently, so a
|
|
14864
|
+
* reload (or a `syncEpoch` re-pull) never re-notifies for already-resolved
|
|
14865
|
+
* requests. Multi-asset requests surface their first asset (the module's
|
|
14866
|
+
* request surface is single-asset; module-created requests always are).
|
|
14851
14867
|
*/
|
|
14852
14868
|
surfaceIncomingPaymentRequest(wire) {
|
|
14853
|
-
if (wire.status !== "open") return;
|
|
14854
14869
|
if (this.paymentRequests.some((r) => r.id === wire.id)) return;
|
|
14870
|
+
const status = _PaymentsModule.PR_WIRE_STATUS[wire.status];
|
|
14855
14871
|
const coinId = wire.assets[0]?.coinId ?? "";
|
|
14856
14872
|
const coinDef = TokenRegistry.getInstance().getDefinition(coinId);
|
|
14857
14873
|
const { memo: message, senderNametag } = this.decryptPaymentRequestMemo(wire);
|
|
@@ -14865,18 +14881,20 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
14865
14881
|
...message !== void 0 ? { message } : {},
|
|
14866
14882
|
requestId: wire.id,
|
|
14867
14883
|
timestamp: wire.createdAt,
|
|
14868
|
-
status
|
|
14884
|
+
status
|
|
14869
14885
|
};
|
|
14870
14886
|
this.paymentRequests.unshift(request);
|
|
14871
|
-
|
|
14872
|
-
|
|
14873
|
-
|
|
14874
|
-
|
|
14875
|
-
|
|
14876
|
-
|
|
14887
|
+
if (status === "pending") {
|
|
14888
|
+
this.deps?.emitEvent("payment_request:incoming", request);
|
|
14889
|
+
for (const handler of this.paymentRequestHandlers) {
|
|
14890
|
+
try {
|
|
14891
|
+
handler(request);
|
|
14892
|
+
} catch (error) {
|
|
14893
|
+
logger.debug("Payments", "Payment request handler error:", error);
|
|
14894
|
+
}
|
|
14877
14895
|
}
|
|
14878
14896
|
}
|
|
14879
|
-
logger.debug("Payments", `Incoming payment request: ${request.id} for ${request.amount} ${request.symbol}`);
|
|
14897
|
+
logger.debug("Payments", `Incoming payment request: ${request.id} (${status}) for ${request.amount} ${request.symbol}`);
|
|
14880
14898
|
}
|
|
14881
14899
|
/**
|
|
14882
14900
|
* Outgoing requests are a `?before=` backfill view (§16 — newest-first, no
|