@unicitylabs/sphere-sdk 0.14.0-dev.6 → 0.14.0
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 +416 -223
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +111 -108
- package/dist/core/index.d.ts +111 -108
- package/dist/core/index.js +416 -223
- 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 +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 +416 -223
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +112 -109
- package/dist/index.d.ts +112 -109
- package/dist/index.js +416 -223
- 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
|
@@ -593,7 +593,8 @@ interface PaymentsV2Events {
|
|
|
593
593
|
detail?: string;
|
|
594
594
|
};
|
|
595
595
|
'inventory:updated': Record<string, never>;
|
|
596
|
-
|
|
596
|
+
/** The just-recorded entry, client-shaped (the same mapping history() serves). */
|
|
597
|
+
'history:updated': HistoryEntry;
|
|
597
598
|
'payment_request:incoming': PaymentRequestView;
|
|
598
599
|
'payment_request:updated': {
|
|
599
600
|
id: string;
|
|
@@ -666,6 +667,14 @@ interface DeliveryPort {
|
|
|
666
667
|
deliver(recipientPubkey: string, blob: Uint8Array, options: DeliverOptions): Promise<DeliveryReceipt>;
|
|
667
668
|
deliverBatch?(recipientPubkey: string, blobs: Uint8Array[], options: DeliverOptions): Promise<DeliveryReceipt[]>;
|
|
668
669
|
incoming(sinceCursor?: string): AsyncIterable<IncomingDelivery>;
|
|
670
|
+
/**
|
|
671
|
+
* The syncEpoch of the most recent incoming() page — updated per page, null
|
|
672
|
+
* before the first. §5.7 restore self-detection: the mailbox page is the
|
|
673
|
+
* honest epoch source, so Receive voids its (cursor, epoch) continuity on a
|
|
674
|
+
* mismatch even when the wake socket missed a server restore. (Pinned by the
|
|
675
|
+
* S7 contract suite; wallet-api#119's S7 text carries the same sentence.)
|
|
676
|
+
*/
|
|
677
|
+
incomingEpoch(): string | null;
|
|
669
678
|
ack(deliveryId: string, disposition: 'claimed' | 'rejected', reason?: 'invalid' | 'not-owned' | 'storage-rejected' | 'other'): Promise<void>;
|
|
670
679
|
onWake?(cb: () => void): () => void;
|
|
671
680
|
}
|
|
@@ -760,6 +769,8 @@ declare const STORE_KEYS: {
|
|
|
760
769
|
readonly settlingLinks: "settling";
|
|
761
770
|
readonly streamCursor: (s: StreamName) => string;
|
|
762
771
|
readonly epochLatch: "epoch-latch";
|
|
772
|
+
readonly suspectedSpent: "suspected-spent";
|
|
773
|
+
readonly knownSpends: "known-spends";
|
|
763
774
|
};
|
|
764
775
|
|
|
765
776
|
type RequestWireStatus = 'open' | 'paid' | 'declined' | 'expired';
|
|
@@ -847,6 +858,7 @@ declare class Requests implements PaymentsRequestsApi {
|
|
|
847
858
|
private now;
|
|
848
859
|
private ensureJournalLoaded;
|
|
849
860
|
private mutateJournal;
|
|
861
|
+
/** Idempotent for a same-transferId re-write: committed only ratchets up, createdAt kept. */
|
|
850
862
|
private writeLink;
|
|
851
863
|
private clearLink;
|
|
852
864
|
drainIncoming(): Promise<void>;
|
|
@@ -866,6 +878,18 @@ declare class Requests implements PaymentsRequestsApi {
|
|
|
866
878
|
}>;
|
|
867
879
|
pay(id: string): Promise<TransferResult>;
|
|
868
880
|
private payInner;
|
|
881
|
+
/**
|
|
882
|
+
* THE settlement invariant (#441 + the failed-respond P1): a settling link is
|
|
883
|
+
* removed ONLY by (a) a CONFIRMED paid respond — a 2xx, or the 409
|
|
884
|
+
* already-resolved absorb — or (b) a proven clean pre-commit failure
|
|
885
|
+
* (revertPayable). Nothing else removes one: not a network error, not a 5xx,
|
|
886
|
+
* not a reload. Every path that binds a request to a transfer outcome funnels
|
|
887
|
+
* through here — pay()'s clean success (respond now), pay()'s
|
|
888
|
+
* possibly-committed throw (respond deferred), and reconcile's deferred arms
|
|
889
|
+
* — so a failed respond always leaves the link + 'settling' and the next
|
|
890
|
+
* reconcile pass (the committed-link override) retries the respond.
|
|
891
|
+
*/
|
|
892
|
+
private settle;
|
|
869
893
|
/** 'paid' respond leg: 409 = already resolved = idempotent success; other errors defer. */
|
|
870
894
|
private respondPaid;
|
|
871
895
|
decline(id: string): Promise<void>;
|
|
@@ -873,7 +897,9 @@ declare class Requests implements PaymentsRequestsApi {
|
|
|
873
897
|
reconcile(outcomes: ResumeOutcomes): Promise<void>;
|
|
874
898
|
private doReconcile;
|
|
875
899
|
private reconcileUnaccounted;
|
|
900
|
+
/** Deferred paid: the ONE settlement path again — a failed respond keeps the link. */
|
|
876
901
|
private resolvePaid;
|
|
902
|
+
/** Removal cause (b): a PROVEN clean outcome (pre-commit failure / server-aborted). */
|
|
877
903
|
private revertPayable;
|
|
878
904
|
}
|
|
879
905
|
|
|
@@ -920,6 +946,8 @@ interface PriceReader {
|
|
|
920
946
|
getPrices(tokenNames: string[]): Promise<Map<string, PriceQuote>>;
|
|
921
947
|
}
|
|
922
948
|
|
|
949
|
+
declare const ATTENTION_RESEED_REJECTED = "intent:reseed-rejected";
|
|
950
|
+
|
|
923
951
|
/**
|
|
924
952
|
* F13 makes `mint(params, { transferId, opIndex })` idempotent-recoverable — a
|
|
925
953
|
* same-seed re-CALL recovers the existing certification via the E.2 probe
|
|
@@ -940,6 +968,14 @@ interface FacadeSession {
|
|
|
940
968
|
start(): Promise<void>;
|
|
941
969
|
stop(): Promise<void>;
|
|
942
970
|
subscribeStream(stream: 'inventory' | 'mailbox' | 'payment_requests', handler: () => void): () => void;
|
|
971
|
+
/** §5.1: the latched server syncEpoch ('' before first server contact). */
|
|
972
|
+
currentEpoch(): string;
|
|
973
|
+
/**
|
|
974
|
+
* §5.1 restore hook — REQUIRED so an unwired restore protocol is a COMPILE
|
|
975
|
+
* ERROR: handlers run and are AWAITED on a syncEpoch change BEFORE any
|
|
976
|
+
* stream nudge resumes. The facade registers handleEpochChange here.
|
|
977
|
+
*/
|
|
978
|
+
subscribeEpochChange(handler: (epoch: string) => Promise<void>): () => void;
|
|
943
979
|
/**
|
|
944
980
|
* Optional connection-status feed (same wiring pattern as the streams; the
|
|
945
981
|
* emission point is the session's existing `connection:status` transition).
|
|
@@ -947,6 +983,14 @@ interface FacadeSession {
|
|
|
947
983
|
*/
|
|
948
984
|
subscribeStatus?(handler: (status: 'connected' | 'degraded' | 'offline') => void): () => void;
|
|
949
985
|
}
|
|
986
|
+
/**
|
|
987
|
+
* §5.1/§6 restore surface of the checkpoint store: re-POST the slot's cached
|
|
988
|
+
* encrypt-once ciphertext byte-identical after a server restore (insert-once,
|
|
989
|
+
* first-write-wins server-side). Returns false when no ciphertext is cached.
|
|
990
|
+
*/
|
|
991
|
+
interface CheckpointReseeder {
|
|
992
|
+
reseedCheckpoint(transferId: string, opIndex: number): Promise<boolean>;
|
|
993
|
+
}
|
|
950
994
|
interface IntentWireLike {
|
|
951
995
|
transferId: string;
|
|
952
996
|
payload: string;
|
|
@@ -964,7 +1008,8 @@ interface PaymentsFacadeDeps {
|
|
|
964
1008
|
client: FacadeClient;
|
|
965
1009
|
storagePort: StoragePort;
|
|
966
1010
|
deliveryPort: DeliveryPort;
|
|
967
|
-
|
|
1011
|
+
/** Reseeder REQUIRED: the restore protocol re-POSTs cached ciphertexts (§5.1). */
|
|
1012
|
+
checkpointStore: SplitCheckpointStore & CheckpointReseeder;
|
|
968
1013
|
/** Initial engine source; setEngine() swaps what FUTURE operations snapshot. */
|
|
969
1014
|
engineRef: () => ITokenEngine;
|
|
970
1015
|
kv: ScopedKV;
|
|
@@ -980,7 +1025,8 @@ interface PaymentsFacadeDeps {
|
|
|
980
1025
|
ownPubkey: string;
|
|
981
1026
|
ownNametag?: () => string | undefined;
|
|
982
1027
|
requestMemo: RequestMemoCodec;
|
|
983
|
-
|
|
1028
|
+
/** REQUIRED (§5.1): reads the session's current epoch — never a default. */
|
|
1029
|
+
syncEpoch: () => string;
|
|
984
1030
|
now?: () => number;
|
|
985
1031
|
newId?: () => string;
|
|
986
1032
|
workBudget?: number;
|
|
@@ -1002,6 +1048,7 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1002
1048
|
private readonly receiveLoop;
|
|
1003
1049
|
private readonly heldStates;
|
|
1004
1050
|
private readonly ownPubkeyBytes;
|
|
1051
|
+
private readonly restoreDeps;
|
|
1005
1052
|
readonly requests: Requests;
|
|
1006
1053
|
private currentEngine;
|
|
1007
1054
|
private readonly pendingOps;
|
|
@@ -1011,6 +1058,8 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1011
1058
|
private readonly converger;
|
|
1012
1059
|
/** Resume single-flight (§7): ticks, start() and resumeNow() coalesce onto ONE pass. */
|
|
1013
1060
|
private readonly resumeFlight;
|
|
1061
|
+
/** §5.1/§7: restore + convergence passes SERIALIZE here. */
|
|
1062
|
+
private readonly passChain;
|
|
1014
1063
|
/** §7 ownership: ids with an in-process machine attempt — the pass never adopts one. */
|
|
1015
1064
|
private readonly activeMoneyOps;
|
|
1016
1065
|
constructor(deps: PaymentsFacadeDeps);
|
|
@@ -1035,24 +1084,28 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1035
1084
|
}>;
|
|
1036
1085
|
mint(coinId: string, amount: bigint): Promise<MintResult>;
|
|
1037
1086
|
resumeNow(): Promise<void>;
|
|
1087
|
+
/** §5.1 restore — awaited by the session latch BEFORE streams resume; never coalesced onto a pre-restore pass. */
|
|
1088
|
+
handleEpochChange(_newEpoch: string): Promise<void>;
|
|
1038
1089
|
/** One single-flighted pass + its reschedule: concurrent callers coalesce. */
|
|
1039
1090
|
private runConvergencePass;
|
|
1091
|
+
private convergeBody;
|
|
1040
1092
|
private nowMs;
|
|
1093
|
+
/** The ONE place a send() outcome is shaped: success emits in finishSend, a
|
|
1094
|
+
* CLEAN rejection emits `transfer:updated{status:'failed'}` here (§4). */
|
|
1095
|
+
private sendOutcome;
|
|
1096
|
+
/** Only a CLEAN failure (nothing certified, classifyError 'other') is 'failed'.
|
|
1097
|
+
* Keep-open/partial/conflict outcomes are pending/converging — labelling them
|
|
1098
|
+
* 'failed' invites a dApp re-send, i.e. a double-pay (#631/#676). */
|
|
1099
|
+
private emitCleanFailure;
|
|
1041
1100
|
private sendWithPolicy;
|
|
1042
1101
|
/** §5.6 cross-network deposit trap: refused BEFORE any reserve/certification. */
|
|
1043
1102
|
private requireSameNetworkRecipient;
|
|
1044
1103
|
private runAttempt;
|
|
1045
|
-
/**
|
|
1046
|
-
*
|
|
1047
|
-
* the machine BEFORE complete). Accumulate the settled set, then re-plan ONLY
|
|
1048
|
-
* the remainder under a NEW transferId — never the full amount.
|
|
1049
|
-
*/
|
|
1104
|
+
/** Partial (#677/#690): shortfall already durable (machine wrote it BEFORE
|
|
1105
|
+
* complete); accumulate settled, re-plan ONLY the remainder, NEW transferId. */
|
|
1050
1106
|
private consumePartial;
|
|
1051
|
-
/**
|
|
1052
|
-
*
|
|
1053
|
-
* backstop still 'open' (committed>0) → converge via the same machine's
|
|
1054
|
-
* resumeIntent; clean conflict with a demoted source → bounded full re-plan.
|
|
1055
|
-
*/
|
|
1107
|
+
/** Failure disposition: possibly-committed → rethrow UNWRAPPED; backstop
|
|
1108
|
+
* 'open' → converge via resumeIntent; clean demoted conflict → full re-plan. */
|
|
1056
1109
|
private disposeFailedAttempt;
|
|
1057
1110
|
/** #677/#690: ≥1 leg committed — the SAME machine, resumed in-process, converges it. */
|
|
1058
1111
|
private convergePartial;
|
|
@@ -1072,11 +1125,7 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1072
1125
|
private refreshThenRelease;
|
|
1073
1126
|
private accumulate;
|
|
1074
1127
|
private finishSend;
|
|
1075
|
-
/**
|
|
1076
|
-
* With nothing delivered the error passes UNWRAPPED (identity + cause kept);
|
|
1077
|
-
* after ≥1 delivered leg EVERY failure surfaces as PartialSendConflictError
|
|
1078
|
-
* over the accumulated settled set — never bare, never a full-amount retry.
|
|
1079
|
-
*/
|
|
1128
|
+
/** Nothing delivered → UNWRAPPED; after ≥1 delivered leg every failure surfaces as PartialSendConflictError over the settled set. */
|
|
1080
1129
|
private partialize;
|
|
1081
1130
|
/** #441: possibly-committed errors must carry the transferId for the settling journal. */
|
|
1082
1131
|
private stampTransferId;
|
|
@@ -1100,4 +1149,4 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1100
1149
|
declare const HEARTBEAT_SEED_MS = 5000;
|
|
1101
1150
|
declare const HEARTBEAT_CAP_MS = 120000;
|
|
1102
1151
|
|
|
1103
|
-
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 };
|
|
1152
|
+
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 };
|
|
@@ -593,7 +593,8 @@ interface PaymentsV2Events {
|
|
|
593
593
|
detail?: string;
|
|
594
594
|
};
|
|
595
595
|
'inventory:updated': Record<string, never>;
|
|
596
|
-
|
|
596
|
+
/** The just-recorded entry, client-shaped (the same mapping history() serves). */
|
|
597
|
+
'history:updated': HistoryEntry;
|
|
597
598
|
'payment_request:incoming': PaymentRequestView;
|
|
598
599
|
'payment_request:updated': {
|
|
599
600
|
id: string;
|
|
@@ -666,6 +667,14 @@ interface DeliveryPort {
|
|
|
666
667
|
deliver(recipientPubkey: string, blob: Uint8Array, options: DeliverOptions): Promise<DeliveryReceipt>;
|
|
667
668
|
deliverBatch?(recipientPubkey: string, blobs: Uint8Array[], options: DeliverOptions): Promise<DeliveryReceipt[]>;
|
|
668
669
|
incoming(sinceCursor?: string): AsyncIterable<IncomingDelivery>;
|
|
670
|
+
/**
|
|
671
|
+
* The syncEpoch of the most recent incoming() page — updated per page, null
|
|
672
|
+
* before the first. §5.7 restore self-detection: the mailbox page is the
|
|
673
|
+
* honest epoch source, so Receive voids its (cursor, epoch) continuity on a
|
|
674
|
+
* mismatch even when the wake socket missed a server restore. (Pinned by the
|
|
675
|
+
* S7 contract suite; wallet-api#119's S7 text carries the same sentence.)
|
|
676
|
+
*/
|
|
677
|
+
incomingEpoch(): string | null;
|
|
669
678
|
ack(deliveryId: string, disposition: 'claimed' | 'rejected', reason?: 'invalid' | 'not-owned' | 'storage-rejected' | 'other'): Promise<void>;
|
|
670
679
|
onWake?(cb: () => void): () => void;
|
|
671
680
|
}
|
|
@@ -760,6 +769,8 @@ declare const STORE_KEYS: {
|
|
|
760
769
|
readonly settlingLinks: "settling";
|
|
761
770
|
readonly streamCursor: (s: StreamName) => string;
|
|
762
771
|
readonly epochLatch: "epoch-latch";
|
|
772
|
+
readonly suspectedSpent: "suspected-spent";
|
|
773
|
+
readonly knownSpends: "known-spends";
|
|
763
774
|
};
|
|
764
775
|
|
|
765
776
|
type RequestWireStatus = 'open' | 'paid' | 'declined' | 'expired';
|
|
@@ -847,6 +858,7 @@ declare class Requests implements PaymentsRequestsApi {
|
|
|
847
858
|
private now;
|
|
848
859
|
private ensureJournalLoaded;
|
|
849
860
|
private mutateJournal;
|
|
861
|
+
/** Idempotent for a same-transferId re-write: committed only ratchets up, createdAt kept. */
|
|
850
862
|
private writeLink;
|
|
851
863
|
private clearLink;
|
|
852
864
|
drainIncoming(): Promise<void>;
|
|
@@ -866,6 +878,18 @@ declare class Requests implements PaymentsRequestsApi {
|
|
|
866
878
|
}>;
|
|
867
879
|
pay(id: string): Promise<TransferResult>;
|
|
868
880
|
private payInner;
|
|
881
|
+
/**
|
|
882
|
+
* THE settlement invariant (#441 + the failed-respond P1): a settling link is
|
|
883
|
+
* removed ONLY by (a) a CONFIRMED paid respond — a 2xx, or the 409
|
|
884
|
+
* already-resolved absorb — or (b) a proven clean pre-commit failure
|
|
885
|
+
* (revertPayable). Nothing else removes one: not a network error, not a 5xx,
|
|
886
|
+
* not a reload. Every path that binds a request to a transfer outcome funnels
|
|
887
|
+
* through here — pay()'s clean success (respond now), pay()'s
|
|
888
|
+
* possibly-committed throw (respond deferred), and reconcile's deferred arms
|
|
889
|
+
* — so a failed respond always leaves the link + 'settling' and the next
|
|
890
|
+
* reconcile pass (the committed-link override) retries the respond.
|
|
891
|
+
*/
|
|
892
|
+
private settle;
|
|
869
893
|
/** 'paid' respond leg: 409 = already resolved = idempotent success; other errors defer. */
|
|
870
894
|
private respondPaid;
|
|
871
895
|
decline(id: string): Promise<void>;
|
|
@@ -873,7 +897,9 @@ declare class Requests implements PaymentsRequestsApi {
|
|
|
873
897
|
reconcile(outcomes: ResumeOutcomes): Promise<void>;
|
|
874
898
|
private doReconcile;
|
|
875
899
|
private reconcileUnaccounted;
|
|
900
|
+
/** Deferred paid: the ONE settlement path again — a failed respond keeps the link. */
|
|
876
901
|
private resolvePaid;
|
|
902
|
+
/** Removal cause (b): a PROVEN clean outcome (pre-commit failure / server-aborted). */
|
|
877
903
|
private revertPayable;
|
|
878
904
|
}
|
|
879
905
|
|
|
@@ -920,6 +946,8 @@ interface PriceReader {
|
|
|
920
946
|
getPrices(tokenNames: string[]): Promise<Map<string, PriceQuote>>;
|
|
921
947
|
}
|
|
922
948
|
|
|
949
|
+
declare const ATTENTION_RESEED_REJECTED = "intent:reseed-rejected";
|
|
950
|
+
|
|
923
951
|
/**
|
|
924
952
|
* F13 makes `mint(params, { transferId, opIndex })` idempotent-recoverable — a
|
|
925
953
|
* same-seed re-CALL recovers the existing certification via the E.2 probe
|
|
@@ -940,6 +968,14 @@ interface FacadeSession {
|
|
|
940
968
|
start(): Promise<void>;
|
|
941
969
|
stop(): Promise<void>;
|
|
942
970
|
subscribeStream(stream: 'inventory' | 'mailbox' | 'payment_requests', handler: () => void): () => void;
|
|
971
|
+
/** §5.1: the latched server syncEpoch ('' before first server contact). */
|
|
972
|
+
currentEpoch(): string;
|
|
973
|
+
/**
|
|
974
|
+
* §5.1 restore hook — REQUIRED so an unwired restore protocol is a COMPILE
|
|
975
|
+
* ERROR: handlers run and are AWAITED on a syncEpoch change BEFORE any
|
|
976
|
+
* stream nudge resumes. The facade registers handleEpochChange here.
|
|
977
|
+
*/
|
|
978
|
+
subscribeEpochChange(handler: (epoch: string) => Promise<void>): () => void;
|
|
943
979
|
/**
|
|
944
980
|
* Optional connection-status feed (same wiring pattern as the streams; the
|
|
945
981
|
* emission point is the session's existing `connection:status` transition).
|
|
@@ -947,6 +983,14 @@ interface FacadeSession {
|
|
|
947
983
|
*/
|
|
948
984
|
subscribeStatus?(handler: (status: 'connected' | 'degraded' | 'offline') => void): () => void;
|
|
949
985
|
}
|
|
986
|
+
/**
|
|
987
|
+
* §5.1/§6 restore surface of the checkpoint store: re-POST the slot's cached
|
|
988
|
+
* encrypt-once ciphertext byte-identical after a server restore (insert-once,
|
|
989
|
+
* first-write-wins server-side). Returns false when no ciphertext is cached.
|
|
990
|
+
*/
|
|
991
|
+
interface CheckpointReseeder {
|
|
992
|
+
reseedCheckpoint(transferId: string, opIndex: number): Promise<boolean>;
|
|
993
|
+
}
|
|
950
994
|
interface IntentWireLike {
|
|
951
995
|
transferId: string;
|
|
952
996
|
payload: string;
|
|
@@ -964,7 +1008,8 @@ interface PaymentsFacadeDeps {
|
|
|
964
1008
|
client: FacadeClient;
|
|
965
1009
|
storagePort: StoragePort;
|
|
966
1010
|
deliveryPort: DeliveryPort;
|
|
967
|
-
|
|
1011
|
+
/** Reseeder REQUIRED: the restore protocol re-POSTs cached ciphertexts (§5.1). */
|
|
1012
|
+
checkpointStore: SplitCheckpointStore & CheckpointReseeder;
|
|
968
1013
|
/** Initial engine source; setEngine() swaps what FUTURE operations snapshot. */
|
|
969
1014
|
engineRef: () => ITokenEngine;
|
|
970
1015
|
kv: ScopedKV;
|
|
@@ -980,7 +1025,8 @@ interface PaymentsFacadeDeps {
|
|
|
980
1025
|
ownPubkey: string;
|
|
981
1026
|
ownNametag?: () => string | undefined;
|
|
982
1027
|
requestMemo: RequestMemoCodec;
|
|
983
|
-
|
|
1028
|
+
/** REQUIRED (§5.1): reads the session's current epoch — never a default. */
|
|
1029
|
+
syncEpoch: () => string;
|
|
984
1030
|
now?: () => number;
|
|
985
1031
|
newId?: () => string;
|
|
986
1032
|
workBudget?: number;
|
|
@@ -1002,6 +1048,7 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1002
1048
|
private readonly receiveLoop;
|
|
1003
1049
|
private readonly heldStates;
|
|
1004
1050
|
private readonly ownPubkeyBytes;
|
|
1051
|
+
private readonly restoreDeps;
|
|
1005
1052
|
readonly requests: Requests;
|
|
1006
1053
|
private currentEngine;
|
|
1007
1054
|
private readonly pendingOps;
|
|
@@ -1011,6 +1058,8 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1011
1058
|
private readonly converger;
|
|
1012
1059
|
/** Resume single-flight (§7): ticks, start() and resumeNow() coalesce onto ONE pass. */
|
|
1013
1060
|
private readonly resumeFlight;
|
|
1061
|
+
/** §5.1/§7: restore + convergence passes SERIALIZE here. */
|
|
1062
|
+
private readonly passChain;
|
|
1014
1063
|
/** §7 ownership: ids with an in-process machine attempt — the pass never adopts one. */
|
|
1015
1064
|
private readonly activeMoneyOps;
|
|
1016
1065
|
constructor(deps: PaymentsFacadeDeps);
|
|
@@ -1035,24 +1084,28 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1035
1084
|
}>;
|
|
1036
1085
|
mint(coinId: string, amount: bigint): Promise<MintResult>;
|
|
1037
1086
|
resumeNow(): Promise<void>;
|
|
1087
|
+
/** §5.1 restore — awaited by the session latch BEFORE streams resume; never coalesced onto a pre-restore pass. */
|
|
1088
|
+
handleEpochChange(_newEpoch: string): Promise<void>;
|
|
1038
1089
|
/** One single-flighted pass + its reschedule: concurrent callers coalesce. */
|
|
1039
1090
|
private runConvergencePass;
|
|
1091
|
+
private convergeBody;
|
|
1040
1092
|
private nowMs;
|
|
1093
|
+
/** The ONE place a send() outcome is shaped: success emits in finishSend, a
|
|
1094
|
+
* CLEAN rejection emits `transfer:updated{status:'failed'}` here (§4). */
|
|
1095
|
+
private sendOutcome;
|
|
1096
|
+
/** Only a CLEAN failure (nothing certified, classifyError 'other') is 'failed'.
|
|
1097
|
+
* Keep-open/partial/conflict outcomes are pending/converging — labelling them
|
|
1098
|
+
* 'failed' invites a dApp re-send, i.e. a double-pay (#631/#676). */
|
|
1099
|
+
private emitCleanFailure;
|
|
1041
1100
|
private sendWithPolicy;
|
|
1042
1101
|
/** §5.6 cross-network deposit trap: refused BEFORE any reserve/certification. */
|
|
1043
1102
|
private requireSameNetworkRecipient;
|
|
1044
1103
|
private runAttempt;
|
|
1045
|
-
/**
|
|
1046
|
-
*
|
|
1047
|
-
* the machine BEFORE complete). Accumulate the settled set, then re-plan ONLY
|
|
1048
|
-
* the remainder under a NEW transferId — never the full amount.
|
|
1049
|
-
*/
|
|
1104
|
+
/** Partial (#677/#690): shortfall already durable (machine wrote it BEFORE
|
|
1105
|
+
* complete); accumulate settled, re-plan ONLY the remainder, NEW transferId. */
|
|
1050
1106
|
private consumePartial;
|
|
1051
|
-
/**
|
|
1052
|
-
*
|
|
1053
|
-
* backstop still 'open' (committed>0) → converge via the same machine's
|
|
1054
|
-
* resumeIntent; clean conflict with a demoted source → bounded full re-plan.
|
|
1055
|
-
*/
|
|
1107
|
+
/** Failure disposition: possibly-committed → rethrow UNWRAPPED; backstop
|
|
1108
|
+
* 'open' → converge via resumeIntent; clean demoted conflict → full re-plan. */
|
|
1056
1109
|
private disposeFailedAttempt;
|
|
1057
1110
|
/** #677/#690: ≥1 leg committed — the SAME machine, resumed in-process, converges it. */
|
|
1058
1111
|
private convergePartial;
|
|
@@ -1072,11 +1125,7 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1072
1125
|
private refreshThenRelease;
|
|
1073
1126
|
private accumulate;
|
|
1074
1127
|
private finishSend;
|
|
1075
|
-
/**
|
|
1076
|
-
* With nothing delivered the error passes UNWRAPPED (identity + cause kept);
|
|
1077
|
-
* after ≥1 delivered leg EVERY failure surfaces as PartialSendConflictError
|
|
1078
|
-
* over the accumulated settled set — never bare, never a full-amount retry.
|
|
1079
|
-
*/
|
|
1128
|
+
/** Nothing delivered → UNWRAPPED; after ≥1 delivered leg every failure surfaces as PartialSendConflictError over the settled set. */
|
|
1080
1129
|
private partialize;
|
|
1081
1130
|
/** #441: possibly-committed errors must carry the transferId for the settling journal. */
|
|
1082
1131
|
private stampTransferId;
|
|
@@ -1100,4 +1149,4 @@ declare class PaymentsFacade implements PaymentsV2 {
|
|
|
1100
1149
|
declare const HEARTBEAT_SEED_MS = 5000;
|
|
1101
1150
|
declare const HEARTBEAT_CAP_MS = 120000;
|
|
1102
1151
|
|
|
1103
|
-
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 };
|
|
1152
|
+
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 };
|