@unicitylabs/sphere-sdk 0.14.1-dev.1 → 0.14.1-dev.2
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 +20 -5
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.d.cts +0 -1
- package/dist/connect/index.d.ts +0 -1
- package/dist/connect/index.js +20 -5
- package/dist/connect/index.js.map +1 -1
- package/dist/core/index.cjs +395 -213
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +10 -3
- package/dist/core/index.d.ts +10 -3
- package/dist/core/index.js +395 -213
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/connect/index.cjs +10 -2
- package/dist/impl/browser/connect/index.cjs.map +1 -1
- package/dist/impl/browser/connect/index.d.cts +0 -1
- package/dist/impl/browser/connect/index.d.ts +0 -1
- package/dist/impl/browser/connect/index.js +10 -2
- package/dist/impl/browser/connect/index.js.map +1 -1
- package/dist/impl/nodejs/connect/index.cjs +9 -1
- package/dist/impl/nodejs/connect/index.cjs.map +1 -1
- package/dist/impl/nodejs/connect/index.d.cts +0 -1
- package/dist/impl/nodejs/connect/index.d.ts +0 -1
- package/dist/impl/nodejs/connect/index.js +9 -1
- package/dist/impl/nodejs/connect/index.js.map +1 -1
- package/dist/impl/nodejs/index.d.cts +8 -1
- package/dist/impl/nodejs/index.d.ts +8 -1
- package/dist/impl/shared/wallet-api/index.d.cts +8 -1
- package/dist/impl/shared/wallet-api/index.d.ts +8 -1
- package/dist/impl/wallet-api-v2/index.cjs +38 -5
- package/dist/impl/wallet-api-v2/index.cjs.map +1 -1
- package/dist/impl/wallet-api-v2/index.d.cts +23 -2
- package/dist/impl/wallet-api-v2/index.d.ts +23 -2
- package/dist/impl/wallet-api-v2/index.js +38 -5
- package/dist/impl/wallet-api-v2/index.js.map +1 -1
- package/dist/index.cjs +395 -213
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +395 -213
- package/dist/index.js.map +1 -1
- package/dist/modules/payments-v2/index.cjs +340 -199
- package/dist/modules/payments-v2/index.cjs.map +1 -1
- package/dist/modules/payments-v2/index.d.cts +68 -19
- package/dist/modules/payments-v2/index.d.ts +68 -19
- package/dist/modules/payments-v2/index.js +339 -199
- package/dist/modules/payments-v2/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -253,7 +253,8 @@ interface PaymentsV2Events {
|
|
|
253
253
|
detail?: string;
|
|
254
254
|
};
|
|
255
255
|
'inventory:updated': Record<string, never>;
|
|
256
|
-
|
|
256
|
+
/** The just-recorded entry, client-shaped (the same mapping history() serves). */
|
|
257
|
+
'history:updated': HistoryEntry;
|
|
257
258
|
'payment_request:incoming': PaymentRequestView;
|
|
258
259
|
'payment_request:updated': {
|
|
259
260
|
id: string;
|
|
@@ -326,6 +327,14 @@ interface DeliveryPort {
|
|
|
326
327
|
deliver(recipientPubkey: string, blob: Uint8Array, options: DeliverOptions): Promise<DeliveryReceipt>;
|
|
327
328
|
deliverBatch?(recipientPubkey: string, blobs: Uint8Array[], options: DeliverOptions): Promise<DeliveryReceipt[]>;
|
|
328
329
|
incoming(sinceCursor?: string): AsyncIterable<IncomingDelivery>;
|
|
330
|
+
/**
|
|
331
|
+
* The syncEpoch of the most recent incoming() page — updated per page, null
|
|
332
|
+
* before the first. §5.7 restore self-detection: the mailbox page is the
|
|
333
|
+
* honest epoch source, so Receive voids its (cursor, epoch) continuity on a
|
|
334
|
+
* mismatch even when the wake socket missed a server restore. (Pinned by the
|
|
335
|
+
* S7 contract suite; wallet-api#119's S7 text carries the same sentence.)
|
|
336
|
+
*/
|
|
337
|
+
incomingEpoch(): string | null;
|
|
329
338
|
ack(deliveryId: string, disposition: 'claimed' | 'rejected', reason?: 'invalid' | 'not-owned' | 'storage-rejected' | 'other'): Promise<void>;
|
|
330
339
|
onWake?(cb: () => void): () => void;
|
|
331
340
|
}
|
|
@@ -468,6 +477,8 @@ declare const STORE_KEYS: {
|
|
|
468
477
|
readonly settlingLinks: "settling";
|
|
469
478
|
readonly streamCursor: (s: StreamName) => string;
|
|
470
479
|
readonly epochLatch: "epoch-latch";
|
|
480
|
+
readonly suspectedSpent: "suspected-spent";
|
|
481
|
+
readonly knownSpends: "known-spends";
|
|
471
482
|
};
|
|
472
483
|
|
|
473
484
|
/**
|
|
@@ -841,6 +852,7 @@ declare class Requests implements PaymentsRequestsApi {
|
|
|
841
852
|
private now;
|
|
842
853
|
private ensureJournalLoaded;
|
|
843
854
|
private mutateJournal;
|
|
855
|
+
/** Idempotent for a same-transferId re-write: committed only ratchets up, createdAt kept. */
|
|
844
856
|
private writeLink;
|
|
845
857
|
private clearLink;
|
|
846
858
|
drainIncoming(): Promise<void>;
|
|
@@ -860,6 +872,18 @@ declare class Requests implements PaymentsRequestsApi {
|
|
|
860
872
|
}>;
|
|
861
873
|
pay(id: string): Promise<TransferResult>;
|
|
862
874
|
private payInner;
|
|
875
|
+
/**
|
|
876
|
+
* THE settlement invariant (#441 + the failed-respond P1): a settling link is
|
|
877
|
+
* removed ONLY by (a) a CONFIRMED paid respond — a 2xx, or the 409
|
|
878
|
+
* already-resolved absorb — or (b) a proven clean pre-commit failure
|
|
879
|
+
* (revertPayable). Nothing else removes one: not a network error, not a 5xx,
|
|
880
|
+
* not a reload. Every path that binds a request to a transfer outcome funnels
|
|
881
|
+
* through here — pay()'s clean success (respond now), pay()'s
|
|
882
|
+
* possibly-committed throw (respond deferred), and reconcile's deferred arms
|
|
883
|
+
* — so a failed respond always leaves the link + 'settling' and the next
|
|
884
|
+
* reconcile pass (the committed-link override) retries the respond.
|
|
885
|
+
*/
|
|
886
|
+
private settle;
|
|
863
887
|
/** 'paid' respond leg: 409 = already resolved = idempotent success; other errors defer. */
|
|
864
888
|
private respondPaid;
|
|
865
889
|
decline(id: string): Promise<void>;
|
|
@@ -867,7 +891,9 @@ declare class Requests implements PaymentsRequestsApi {
|
|
|
867
891
|
reconcile(outcomes: ResumeOutcomes): Promise<void>;
|
|
868
892
|
private doReconcile;
|
|
869
893
|
private reconcileUnaccounted;
|
|
894
|
+
/** Deferred paid: the ONE settlement path again — a failed respond keeps the link. */
|
|
870
895
|
private resolvePaid;
|
|
896
|
+
/** Removal cause (b): a PROVEN clean outcome (pre-commit failure / server-aborted). */
|
|
871
897
|
private revertPayable;
|
|
872
898
|
}
|
|
873
899
|
|
|
@@ -914,6 +940,8 @@ interface PriceReader {
|
|
|
914
940
|
getPrices(tokenNames: string[]): Promise<Map<string, PriceQuote>>;
|
|
915
941
|
}
|
|
916
942
|
|
|
943
|
+
declare const ATTENTION_RESEED_REJECTED = "intent:reseed-rejected";
|
|
944
|
+
|
|
917
945
|
/**
|
|
918
946
|
* F13 makes `mint(params, { transferId, opIndex })` idempotent-recoverable — a
|
|
919
947
|
* same-seed re-CALL recovers the existing certification via the E.2 probe
|
|
@@ -934,6 +962,14 @@ interface FacadeSession {
|
|
|
934
962
|
start(): Promise<void>;
|
|
935
963
|
stop(): Promise<void>;
|
|
936
964
|
subscribeStream(stream: 'inventory' | 'mailbox' | 'payment_requests', handler: () => void): () => void;
|
|
965
|
+
/** §5.1: the latched server syncEpoch ('' before first server contact). */
|
|
966
|
+
currentEpoch(): string;
|
|
967
|
+
/**
|
|
968
|
+
* §5.1 restore hook — REQUIRED so an unwired restore protocol is a COMPILE
|
|
969
|
+
* ERROR: handlers run and are AWAITED on a syncEpoch change BEFORE any
|
|
970
|
+
* stream nudge resumes. The facade registers handleEpochChange here.
|
|
971
|
+
*/
|
|
972
|
+
subscribeEpochChange(handler: (epoch: string) => Promise<void>): () => void;
|
|
937
973
|
/**
|
|
938
974
|
* Optional connection-status feed (same wiring pattern as the streams; the
|
|
939
975
|
* emission point is the session's existing `connection:status` transition).
|
|
@@ -941,6 +977,14 @@ interface FacadeSession {
|
|
|
941
977
|
*/
|
|
942
978
|
subscribeStatus?(handler: (status: 'connected' | 'degraded' | 'offline') => void): () => void;
|
|
943
979
|
}
|
|
980
|
+
/**
|
|
981
|
+
* §5.1/§6 restore surface of the checkpoint store: re-POST the slot's cached
|
|
982
|
+
* encrypt-once ciphertext byte-identical after a server restore (insert-once,
|
|
983
|
+
* first-write-wins server-side). Returns false when no ciphertext is cached.
|
|
984
|
+
*/
|
|
985
|
+
interface CheckpointReseeder {
|
|
986
|
+
reseedCheckpoint(transferId: string, opIndex: number): Promise<boolean>;
|
|
987
|
+
}
|
|
944
988
|
interface IntentWireLike {
|
|
945
989
|
transferId: string;
|
|
946
990
|
payload: string;
|
|
@@ -958,7 +1002,8 @@ interface PaymentsFacadeDeps {
|
|
|
958
1002
|
client: FacadeClient;
|
|
959
1003
|
storagePort: StoragePort;
|
|
960
1004
|
deliveryPort: DeliveryPort;
|
|
961
|
-
|
|
1005
|
+
/** Reseeder REQUIRED: the restore protocol re-POSTs cached ciphertexts (§5.1). */
|
|
1006
|
+
checkpointStore: SplitCheckpointStore & CheckpointReseeder;
|
|
962
1007
|
/** Initial engine source; setEngine() swaps what FUTURE operations snapshot. */
|
|
963
1008
|
engineRef: () => ITokenEngine;
|
|
964
1009
|
kv: ScopedKV;
|
|
@@ -974,7 +1019,8 @@ interface PaymentsFacadeDeps {
|
|
|
974
1019
|
ownPubkey: string;
|
|
975
1020
|
ownNametag?: () => string | undefined;
|
|
976
1021
|
requestMemo: RequestMemoCodec;
|
|
977
|
-
|
|
1022
|
+
/** REQUIRED (§5.1): reads the session's current epoch — never a default. */
|
|
1023
|
+
syncEpoch: () => string;
|
|
978
1024
|
now?: () => number;
|
|
979
1025
|
newId?: () => string;
|
|
980
1026
|
workBudget?: number;
|
|
@@ -996,6 +1042,7 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
996
1042
|
private readonly receiveLoop;
|
|
997
1043
|
private readonly heldStates;
|
|
998
1044
|
private readonly ownPubkeyBytes;
|
|
1045
|
+
private readonly restoreDeps;
|
|
999
1046
|
readonly requests: Requests;
|
|
1000
1047
|
private currentEngine;
|
|
1001
1048
|
private readonly pendingOps;
|
|
@@ -1005,6 +1052,8 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1005
1052
|
private readonly converger;
|
|
1006
1053
|
/** Resume single-flight (§7): ticks, start() and resumeNow() coalesce onto ONE pass. */
|
|
1007
1054
|
private readonly resumeFlight;
|
|
1055
|
+
/** §5.1/§7: restore + convergence passes SERIALIZE here. */
|
|
1056
|
+
private readonly passChain;
|
|
1008
1057
|
/** §7 ownership: ids with an in-process machine attempt — the pass never adopts one. */
|
|
1009
1058
|
private readonly activeMoneyOps;
|
|
1010
1059
|
constructor(deps: PaymentsFacadeDeps);
|
|
@@ -1029,24 +1078,28 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1029
1078
|
}>;
|
|
1030
1079
|
mint(coinId: string, amount: bigint): Promise<MintResult>;
|
|
1031
1080
|
resumeNow(): Promise<void>;
|
|
1081
|
+
/** §5.1 restore — awaited by the session latch BEFORE streams resume; never coalesced onto a pre-restore pass. */
|
|
1082
|
+
handleEpochChange(_newEpoch: string): Promise<void>;
|
|
1032
1083
|
/** One single-flighted pass + its reschedule: concurrent callers coalesce. */
|
|
1033
1084
|
private runConvergencePass;
|
|
1085
|
+
private convergeBody;
|
|
1034
1086
|
private nowMs;
|
|
1087
|
+
/** The ONE place a send() outcome is shaped: success emits in finishSend, a
|
|
1088
|
+
* CLEAN rejection emits `transfer:updated{status:'failed'}` here (§4). */
|
|
1089
|
+
private sendOutcome;
|
|
1090
|
+
/** Only a CLEAN failure (nothing certified, classifyError 'other') is 'failed'.
|
|
1091
|
+
* Keep-open/partial/conflict outcomes are pending/converging — labelling them
|
|
1092
|
+
* 'failed' invites a dApp re-send, i.e. a double-pay (#631/#676). */
|
|
1093
|
+
private emitCleanFailure;
|
|
1035
1094
|
private sendWithPolicy;
|
|
1036
1095
|
/** §5.6 cross-network deposit trap: refused BEFORE any reserve/certification. */
|
|
1037
1096
|
private requireSameNetworkRecipient;
|
|
1038
1097
|
private runAttempt;
|
|
1039
|
-
/**
|
|
1040
|
-
*
|
|
1041
|
-
* the machine BEFORE complete). Accumulate the settled set, then re-plan ONLY
|
|
1042
|
-
* the remainder under a NEW transferId — never the full amount.
|
|
1043
|
-
*/
|
|
1098
|
+
/** Partial (#677/#690): shortfall already durable (machine wrote it BEFORE
|
|
1099
|
+
* complete); accumulate settled, re-plan ONLY the remainder, NEW transferId. */
|
|
1044
1100
|
private consumePartial;
|
|
1045
|
-
/**
|
|
1046
|
-
*
|
|
1047
|
-
* backstop still 'open' (committed>0) → converge via the same machine's
|
|
1048
|
-
* resumeIntent; clean conflict with a demoted source → bounded full re-plan.
|
|
1049
|
-
*/
|
|
1101
|
+
/** Failure disposition: possibly-committed → rethrow UNWRAPPED; backstop
|
|
1102
|
+
* 'open' → converge via resumeIntent; clean demoted conflict → full re-plan. */
|
|
1050
1103
|
private disposeFailedAttempt;
|
|
1051
1104
|
/** #677/#690: ≥1 leg committed — the SAME machine, resumed in-process, converges it. */
|
|
1052
1105
|
private convergePartial;
|
|
@@ -1066,11 +1119,7 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1066
1119
|
private refreshThenRelease;
|
|
1067
1120
|
private accumulate;
|
|
1068
1121
|
private finishSend;
|
|
1069
|
-
/**
|
|
1070
|
-
* With nothing delivered the error passes UNWRAPPED (identity + cause kept);
|
|
1071
|
-
* after ≥1 delivered leg EVERY failure surfaces as PartialSendConflictError
|
|
1072
|
-
* over the accumulated settled set — never bare, never a full-amount retry.
|
|
1073
|
-
*/
|
|
1122
|
+
/** Nothing delivered → UNWRAPPED; after ≥1 delivered leg every failure surfaces as PartialSendConflictError over the settled set. */
|
|
1074
1123
|
private partialize;
|
|
1075
1124
|
/** #441: possibly-committed errors must carry the transferId for the settling journal. */
|
|
1076
1125
|
private stampTransferId;
|
|
@@ -1094,4 +1143,4 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1094
1143
|
declare const HEARTBEAT_SEED_MS = 5000;
|
|
1095
1144
|
declare const HEARTBEAT_CAP_MS = 120000;
|
|
1096
1145
|
|
|
1097
|
-
export { ATTENTION_MINT_UNRESOLVED, type ApplyDeltaResult, 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 };
|
|
1146
|
+
export { ATTENTION_MINT_UNRESOLVED, ATTENTION_RESEED_REJECTED, type ApplyDeltaResult, type CheckpointReseeder, 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 };
|
|
@@ -253,7 +253,8 @@ interface PaymentsV2Events {
|
|
|
253
253
|
detail?: string;
|
|
254
254
|
};
|
|
255
255
|
'inventory:updated': Record<string, never>;
|
|
256
|
-
|
|
256
|
+
/** The just-recorded entry, client-shaped (the same mapping history() serves). */
|
|
257
|
+
'history:updated': HistoryEntry;
|
|
257
258
|
'payment_request:incoming': PaymentRequestView;
|
|
258
259
|
'payment_request:updated': {
|
|
259
260
|
id: string;
|
|
@@ -326,6 +327,14 @@ interface DeliveryPort {
|
|
|
326
327
|
deliver(recipientPubkey: string, blob: Uint8Array, options: DeliverOptions): Promise<DeliveryReceipt>;
|
|
327
328
|
deliverBatch?(recipientPubkey: string, blobs: Uint8Array[], options: DeliverOptions): Promise<DeliveryReceipt[]>;
|
|
328
329
|
incoming(sinceCursor?: string): AsyncIterable<IncomingDelivery>;
|
|
330
|
+
/**
|
|
331
|
+
* The syncEpoch of the most recent incoming() page — updated per page, null
|
|
332
|
+
* before the first. §5.7 restore self-detection: the mailbox page is the
|
|
333
|
+
* honest epoch source, so Receive voids its (cursor, epoch) continuity on a
|
|
334
|
+
* mismatch even when the wake socket missed a server restore. (Pinned by the
|
|
335
|
+
* S7 contract suite; wallet-api#119's S7 text carries the same sentence.)
|
|
336
|
+
*/
|
|
337
|
+
incomingEpoch(): string | null;
|
|
329
338
|
ack(deliveryId: string, disposition: 'claimed' | 'rejected', reason?: 'invalid' | 'not-owned' | 'storage-rejected' | 'other'): Promise<void>;
|
|
330
339
|
onWake?(cb: () => void): () => void;
|
|
331
340
|
}
|
|
@@ -468,6 +477,8 @@ declare const STORE_KEYS: {
|
|
|
468
477
|
readonly settlingLinks: "settling";
|
|
469
478
|
readonly streamCursor: (s: StreamName) => string;
|
|
470
479
|
readonly epochLatch: "epoch-latch";
|
|
480
|
+
readonly suspectedSpent: "suspected-spent";
|
|
481
|
+
readonly knownSpends: "known-spends";
|
|
471
482
|
};
|
|
472
483
|
|
|
473
484
|
/**
|
|
@@ -841,6 +852,7 @@ declare class Requests implements PaymentsRequestsApi {
|
|
|
841
852
|
private now;
|
|
842
853
|
private ensureJournalLoaded;
|
|
843
854
|
private mutateJournal;
|
|
855
|
+
/** Idempotent for a same-transferId re-write: committed only ratchets up, createdAt kept. */
|
|
844
856
|
private writeLink;
|
|
845
857
|
private clearLink;
|
|
846
858
|
drainIncoming(): Promise<void>;
|
|
@@ -860,6 +872,18 @@ declare class Requests implements PaymentsRequestsApi {
|
|
|
860
872
|
}>;
|
|
861
873
|
pay(id: string): Promise<TransferResult>;
|
|
862
874
|
private payInner;
|
|
875
|
+
/**
|
|
876
|
+
* THE settlement invariant (#441 + the failed-respond P1): a settling link is
|
|
877
|
+
* removed ONLY by (a) a CONFIRMED paid respond — a 2xx, or the 409
|
|
878
|
+
* already-resolved absorb — or (b) a proven clean pre-commit failure
|
|
879
|
+
* (revertPayable). Nothing else removes one: not a network error, not a 5xx,
|
|
880
|
+
* not a reload. Every path that binds a request to a transfer outcome funnels
|
|
881
|
+
* through here — pay()'s clean success (respond now), pay()'s
|
|
882
|
+
* possibly-committed throw (respond deferred), and reconcile's deferred arms
|
|
883
|
+
* — so a failed respond always leaves the link + 'settling' and the next
|
|
884
|
+
* reconcile pass (the committed-link override) retries the respond.
|
|
885
|
+
*/
|
|
886
|
+
private settle;
|
|
863
887
|
/** 'paid' respond leg: 409 = already resolved = idempotent success; other errors defer. */
|
|
864
888
|
private respondPaid;
|
|
865
889
|
decline(id: string): Promise<void>;
|
|
@@ -867,7 +891,9 @@ declare class Requests implements PaymentsRequestsApi {
|
|
|
867
891
|
reconcile(outcomes: ResumeOutcomes): Promise<void>;
|
|
868
892
|
private doReconcile;
|
|
869
893
|
private reconcileUnaccounted;
|
|
894
|
+
/** Deferred paid: the ONE settlement path again — a failed respond keeps the link. */
|
|
870
895
|
private resolvePaid;
|
|
896
|
+
/** Removal cause (b): a PROVEN clean outcome (pre-commit failure / server-aborted). */
|
|
871
897
|
private revertPayable;
|
|
872
898
|
}
|
|
873
899
|
|
|
@@ -914,6 +940,8 @@ interface PriceReader {
|
|
|
914
940
|
getPrices(tokenNames: string[]): Promise<Map<string, PriceQuote>>;
|
|
915
941
|
}
|
|
916
942
|
|
|
943
|
+
declare const ATTENTION_RESEED_REJECTED = "intent:reseed-rejected";
|
|
944
|
+
|
|
917
945
|
/**
|
|
918
946
|
* F13 makes `mint(params, { transferId, opIndex })` idempotent-recoverable — a
|
|
919
947
|
* same-seed re-CALL recovers the existing certification via the E.2 probe
|
|
@@ -934,6 +962,14 @@ interface FacadeSession {
|
|
|
934
962
|
start(): Promise<void>;
|
|
935
963
|
stop(): Promise<void>;
|
|
936
964
|
subscribeStream(stream: 'inventory' | 'mailbox' | 'payment_requests', handler: () => void): () => void;
|
|
965
|
+
/** §5.1: the latched server syncEpoch ('' before first server contact). */
|
|
966
|
+
currentEpoch(): string;
|
|
967
|
+
/**
|
|
968
|
+
* §5.1 restore hook — REQUIRED so an unwired restore protocol is a COMPILE
|
|
969
|
+
* ERROR: handlers run and are AWAITED on a syncEpoch change BEFORE any
|
|
970
|
+
* stream nudge resumes. The facade registers handleEpochChange here.
|
|
971
|
+
*/
|
|
972
|
+
subscribeEpochChange(handler: (epoch: string) => Promise<void>): () => void;
|
|
937
973
|
/**
|
|
938
974
|
* Optional connection-status feed (same wiring pattern as the streams; the
|
|
939
975
|
* emission point is the session's existing `connection:status` transition).
|
|
@@ -941,6 +977,14 @@ interface FacadeSession {
|
|
|
941
977
|
*/
|
|
942
978
|
subscribeStatus?(handler: (status: 'connected' | 'degraded' | 'offline') => void): () => void;
|
|
943
979
|
}
|
|
980
|
+
/**
|
|
981
|
+
* §5.1/§6 restore surface of the checkpoint store: re-POST the slot's cached
|
|
982
|
+
* encrypt-once ciphertext byte-identical after a server restore (insert-once,
|
|
983
|
+
* first-write-wins server-side). Returns false when no ciphertext is cached.
|
|
984
|
+
*/
|
|
985
|
+
interface CheckpointReseeder {
|
|
986
|
+
reseedCheckpoint(transferId: string, opIndex: number): Promise<boolean>;
|
|
987
|
+
}
|
|
944
988
|
interface IntentWireLike {
|
|
945
989
|
transferId: string;
|
|
946
990
|
payload: string;
|
|
@@ -958,7 +1002,8 @@ interface PaymentsFacadeDeps {
|
|
|
958
1002
|
client: FacadeClient;
|
|
959
1003
|
storagePort: StoragePort;
|
|
960
1004
|
deliveryPort: DeliveryPort;
|
|
961
|
-
|
|
1005
|
+
/** Reseeder REQUIRED: the restore protocol re-POSTs cached ciphertexts (§5.1). */
|
|
1006
|
+
checkpointStore: SplitCheckpointStore & CheckpointReseeder;
|
|
962
1007
|
/** Initial engine source; setEngine() swaps what FUTURE operations snapshot. */
|
|
963
1008
|
engineRef: () => ITokenEngine;
|
|
964
1009
|
kv: ScopedKV;
|
|
@@ -974,7 +1019,8 @@ interface PaymentsFacadeDeps {
|
|
|
974
1019
|
ownPubkey: string;
|
|
975
1020
|
ownNametag?: () => string | undefined;
|
|
976
1021
|
requestMemo: RequestMemoCodec;
|
|
977
|
-
|
|
1022
|
+
/** REQUIRED (§5.1): reads the session's current epoch — never a default. */
|
|
1023
|
+
syncEpoch: () => string;
|
|
978
1024
|
now?: () => number;
|
|
979
1025
|
newId?: () => string;
|
|
980
1026
|
workBudget?: number;
|
|
@@ -996,6 +1042,7 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
996
1042
|
private readonly receiveLoop;
|
|
997
1043
|
private readonly heldStates;
|
|
998
1044
|
private readonly ownPubkeyBytes;
|
|
1045
|
+
private readonly restoreDeps;
|
|
999
1046
|
readonly requests: Requests;
|
|
1000
1047
|
private currentEngine;
|
|
1001
1048
|
private readonly pendingOps;
|
|
@@ -1005,6 +1052,8 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1005
1052
|
private readonly converger;
|
|
1006
1053
|
/** Resume single-flight (§7): ticks, start() and resumeNow() coalesce onto ONE pass. */
|
|
1007
1054
|
private readonly resumeFlight;
|
|
1055
|
+
/** §5.1/§7: restore + convergence passes SERIALIZE here. */
|
|
1056
|
+
private readonly passChain;
|
|
1008
1057
|
/** §7 ownership: ids with an in-process machine attempt — the pass never adopts one. */
|
|
1009
1058
|
private readonly activeMoneyOps;
|
|
1010
1059
|
constructor(deps: PaymentsFacadeDeps);
|
|
@@ -1029,24 +1078,28 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1029
1078
|
}>;
|
|
1030
1079
|
mint(coinId: string, amount: bigint): Promise<MintResult>;
|
|
1031
1080
|
resumeNow(): Promise<void>;
|
|
1081
|
+
/** §5.1 restore — awaited by the session latch BEFORE streams resume; never coalesced onto a pre-restore pass. */
|
|
1082
|
+
handleEpochChange(_newEpoch: string): Promise<void>;
|
|
1032
1083
|
/** One single-flighted pass + its reschedule: concurrent callers coalesce. */
|
|
1033
1084
|
private runConvergencePass;
|
|
1085
|
+
private convergeBody;
|
|
1034
1086
|
private nowMs;
|
|
1087
|
+
/** The ONE place a send() outcome is shaped: success emits in finishSend, a
|
|
1088
|
+
* CLEAN rejection emits `transfer:updated{status:'failed'}` here (§4). */
|
|
1089
|
+
private sendOutcome;
|
|
1090
|
+
/** Only a CLEAN failure (nothing certified, classifyError 'other') is 'failed'.
|
|
1091
|
+
* Keep-open/partial/conflict outcomes are pending/converging — labelling them
|
|
1092
|
+
* 'failed' invites a dApp re-send, i.e. a double-pay (#631/#676). */
|
|
1093
|
+
private emitCleanFailure;
|
|
1035
1094
|
private sendWithPolicy;
|
|
1036
1095
|
/** §5.6 cross-network deposit trap: refused BEFORE any reserve/certification. */
|
|
1037
1096
|
private requireSameNetworkRecipient;
|
|
1038
1097
|
private runAttempt;
|
|
1039
|
-
/**
|
|
1040
|
-
*
|
|
1041
|
-
* the machine BEFORE complete). Accumulate the settled set, then re-plan ONLY
|
|
1042
|
-
* the remainder under a NEW transferId — never the full amount.
|
|
1043
|
-
*/
|
|
1098
|
+
/** Partial (#677/#690): shortfall already durable (machine wrote it BEFORE
|
|
1099
|
+
* complete); accumulate settled, re-plan ONLY the remainder, NEW transferId. */
|
|
1044
1100
|
private consumePartial;
|
|
1045
|
-
/**
|
|
1046
|
-
*
|
|
1047
|
-
* backstop still 'open' (committed>0) → converge via the same machine's
|
|
1048
|
-
* resumeIntent; clean conflict with a demoted source → bounded full re-plan.
|
|
1049
|
-
*/
|
|
1101
|
+
/** Failure disposition: possibly-committed → rethrow UNWRAPPED; backstop
|
|
1102
|
+
* 'open' → converge via resumeIntent; clean demoted conflict → full re-plan. */
|
|
1050
1103
|
private disposeFailedAttempt;
|
|
1051
1104
|
/** #677/#690: ≥1 leg committed — the SAME machine, resumed in-process, converges it. */
|
|
1052
1105
|
private convergePartial;
|
|
@@ -1066,11 +1119,7 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1066
1119
|
private refreshThenRelease;
|
|
1067
1120
|
private accumulate;
|
|
1068
1121
|
private finishSend;
|
|
1069
|
-
/**
|
|
1070
|
-
* With nothing delivered the error passes UNWRAPPED (identity + cause kept);
|
|
1071
|
-
* after ≥1 delivered leg EVERY failure surfaces as PartialSendConflictError
|
|
1072
|
-
* over the accumulated settled set — never bare, never a full-amount retry.
|
|
1073
|
-
*/
|
|
1122
|
+
/** Nothing delivered → UNWRAPPED; after ≥1 delivered leg every failure surfaces as PartialSendConflictError over the settled set. */
|
|
1074
1123
|
private partialize;
|
|
1075
1124
|
/** #441: possibly-committed errors must carry the transferId for the settling journal. */
|
|
1076
1125
|
private stampTransferId;
|
|
@@ -1094,4 +1143,4 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1094
1143
|
declare const HEARTBEAT_SEED_MS = 5000;
|
|
1095
1144
|
declare const HEARTBEAT_CAP_MS = 120000;
|
|
1096
1145
|
|
|
1097
|
-
export { ATTENTION_MINT_UNRESOLVED, type ApplyDeltaResult, 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 };
|
|
1146
|
+
export { ATTENTION_MINT_UNRESOLVED, ATTENTION_RESEED_REJECTED, type ApplyDeltaResult, type CheckpointReseeder, 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 };
|