@unicitylabs/sphere-sdk 0.9.1-dev.10 → 0.9.1-dev.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/core/index.cjs +82 -2
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +69 -17
- package/dist/core/index.d.ts +69 -17
- package/dist/core/index.js +82 -2
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +82 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -17
- package/dist/index.d.ts +69 -17
- package/dist/index.js +82 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/core/index.cjs
CHANGED
|
@@ -9643,6 +9643,7 @@ function computeHistoryDedupKey(type, tokenId, transferId) {
|
|
|
9643
9643
|
return `${type}_${crypto.randomUUID()}`;
|
|
9644
9644
|
}
|
|
9645
9645
|
var MAX_SYNCED_HISTORY_ENTRIES = 5e3;
|
|
9646
|
+
var MAX_HISTORY_HYDRATION_PAGES = 100;
|
|
9646
9647
|
var SEND_ENGINE_OP_TIMEOUT_MS = 6e4;
|
|
9647
9648
|
var DELIVERY_POLL_INTERVAL_MS = 3e4;
|
|
9648
9649
|
function enrichWithRegistry(info) {
|
|
@@ -11932,10 +11933,20 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
11932
11933
|
this.deps.emitEvent("history:updated", historyEntry);
|
|
11933
11934
|
}
|
|
11934
11935
|
/**
|
|
11935
|
-
* Load history
|
|
11936
|
-
*
|
|
11936
|
+
* Load history into the in-memory cache.
|
|
11937
|
+
*
|
|
11938
|
+
* In the wallet-api composition (the `walletApi` client is present) the
|
|
11939
|
+
* durable §10 history log lives on the SERVER — the thin storage provider
|
|
11940
|
+
* keeps none — so the cache is rebuilt from `walletApi.listHistory()`. The
|
|
11941
|
+
* twin of the #521 inventory reload bug: `_historyCache` is process-lifetime,
|
|
11942
|
+
* so a reload (tab refresh) must re-pull it or render an empty history.
|
|
11943
|
+
* Compositions WITHOUT `walletApi` keep the legacy local path below.
|
|
11937
11944
|
*/
|
|
11938
11945
|
async loadHistory() {
|
|
11946
|
+
if (this.deps.walletApi?.listHistory) {
|
|
11947
|
+
await this.hydrateHistoryFromServer(this.deps.walletApi);
|
|
11948
|
+
return;
|
|
11949
|
+
}
|
|
11939
11950
|
const provider = this.getLocalTokenStorageProvider();
|
|
11940
11951
|
if (provider?.getHistoryEntries) {
|
|
11941
11952
|
this._historyCache = await provider.getHistoryEntries();
|
|
@@ -11967,6 +11978,75 @@ var PaymentsModule = class _PaymentsModule {
|
|
|
11967
11978
|
}
|
|
11968
11979
|
}
|
|
11969
11980
|
}
|
|
11981
|
+
/**
|
|
11982
|
+
* Rebuild `_historyCache` from the server's §10 history log (the wallet-api
|
|
11983
|
+
* composition). Pages newest-first via the keyset cursor until `more:false`
|
|
11984
|
+
* or the page cap; dedups by `dedupKey` (a hydrate-then-receive in the same
|
|
11985
|
+
* session must not double-list). The S6 `memo` / `counterpartyNametag`
|
|
11986
|
+
* envelopes are decrypted with the owner's own field key on the way in.
|
|
11987
|
+
*
|
|
11988
|
+
* Best-effort, like the §10 history POST: history is untrusted DISPLAY data,
|
|
11989
|
+
* so a backend outage during hydration must NEVER fail `load()` (the money
|
|
11990
|
+
* path) — the in-session cache is left intact and the pull retries next load.
|
|
11991
|
+
*/
|
|
11992
|
+
async hydrateHistoryFromServer(api) {
|
|
11993
|
+
const byDedupKey = /* @__PURE__ */ new Map();
|
|
11994
|
+
try {
|
|
11995
|
+
let before;
|
|
11996
|
+
for (let page = 0; page < MAX_HISTORY_HYDRATION_PAGES; page++) {
|
|
11997
|
+
const result = await api.listHistory(before !== void 0 ? { before } : {});
|
|
11998
|
+
for (const wire of result.records) {
|
|
11999
|
+
if (!byDedupKey.has(wire.dedupKey)) {
|
|
12000
|
+
byDedupKey.set(wire.dedupKey, this.historyEntryFromWire(wire));
|
|
12001
|
+
}
|
|
12002
|
+
}
|
|
12003
|
+
if (!result.more || result.cursor === null) break;
|
|
12004
|
+
before = result.cursor;
|
|
12005
|
+
}
|
|
12006
|
+
} catch (err) {
|
|
12007
|
+
logger.warn("Payments", "history hydration from server failed (kept in-memory; retries next load):", err);
|
|
12008
|
+
return;
|
|
12009
|
+
}
|
|
12010
|
+
this._historyCache = [...byDedupKey.values()];
|
|
12011
|
+
}
|
|
12012
|
+
/**
|
|
12013
|
+
* Map one §16 history wire record onto the display
|
|
12014
|
+
* {@link TransactionHistoryEntry}. `counterpartyNametag` lands on the role-
|
|
12015
|
+
* appropriate field (sender for RECEIVED, recipient otherwise); the S6 memo +
|
|
12016
|
+
* nametag envelopes decrypt under THIS wallet's field key (self-scoped at
|
|
12017
|
+
* rest — §8.3), surfaced as absent if they don't decrypt rather than as
|
|
12018
|
+
* ciphertext (same rule as mailbox/payment-request memos).
|
|
12019
|
+
*/
|
|
12020
|
+
historyEntryFromWire(wire) {
|
|
12021
|
+
const asset = wire.assets[0];
|
|
12022
|
+
const coinId = asset?.coinId ?? "";
|
|
12023
|
+
const received = wire.type === "RECEIVED";
|
|
12024
|
+
const memo = this.tryDecryptField(wire.memo);
|
|
12025
|
+
const nametag = this.tryDecryptField(wire.counterpartyNametag);
|
|
12026
|
+
return {
|
|
12027
|
+
id: wire.id,
|
|
12028
|
+
dedupKey: wire.dedupKey,
|
|
12029
|
+
type: wire.type,
|
|
12030
|
+
amount: asset?.amount ?? "0",
|
|
12031
|
+
coinId,
|
|
12032
|
+
symbol: this.getCoinSymbol(coinId),
|
|
12033
|
+
timestamp: Date.parse(wire.ts),
|
|
12034
|
+
...wire.transferId !== void 0 ? { transferId: wire.transferId } : {},
|
|
12035
|
+
...wire.tokenId !== void 0 ? { tokenId: wire.tokenId } : {},
|
|
12036
|
+
...wire.counterpartyPubkey !== void 0 ? received ? { senderPubkey: wire.counterpartyPubkey } : { recipientPubkey: wire.counterpartyPubkey } : {},
|
|
12037
|
+
...nametag !== void 0 ? received ? { senderNametag: nametag } : { recipientNametag: nametag } : {},
|
|
12038
|
+
...memo !== void 0 ? { memo } : {}
|
|
12039
|
+
};
|
|
12040
|
+
}
|
|
12041
|
+
/** S6 field decrypt that surfaces an undecryptable envelope as absent (§8.3). */
|
|
12042
|
+
tryDecryptField(envelope) {
|
|
12043
|
+
if (envelope === void 0) return void 0;
|
|
12044
|
+
try {
|
|
12045
|
+
return decryptField(this.getFieldEncryptionKey(), envelope);
|
|
12046
|
+
} catch {
|
|
12047
|
+
return void 0;
|
|
12048
|
+
}
|
|
12049
|
+
}
|
|
11970
12050
|
/**
|
|
11971
12051
|
* Import history entries from remote TXF data into local store.
|
|
11972
12052
|
* Delegates to the local TokenStorageProvider's importHistoryEntries() for
|