@bananapus/nana-sdk-core 2.38.2 → 2.40.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/cjs/review/heldWrite.d.ts +113 -0
- package/dist/cjs/review/heldWrite.d.ts.map +1 -0
- package/dist/cjs/review/heldWrite.js +569 -0
- package/dist/cjs/review/heldWrite.js.map +1 -0
- package/dist/cjs/review/index.d.ts +2 -0
- package/dist/cjs/review/index.d.ts.map +1 -1
- package/dist/cjs/review/index.js +2 -0
- package/dist/cjs/review/index.js.map +1 -1
- package/dist/cjs/review/messages.d.ts +30 -0
- package/dist/cjs/review/messages.d.ts.map +1 -1
- package/dist/cjs/review/messages.js +34 -1
- package/dist/cjs/review/messages.js.map +1 -1
- package/dist/cjs/review/react/HeldWritesNotice.d.ts +11 -0
- package/dist/cjs/review/react/HeldWritesNotice.d.ts.map +1 -0
- package/dist/cjs/review/react/HeldWritesNotice.js +22 -0
- package/dist/cjs/review/react/HeldWritesNotice.js.map +1 -0
- package/dist/cjs/review/react/index.d.ts +5 -0
- package/dist/cjs/review/react/index.d.ts.map +1 -0
- package/dist/cjs/review/react/index.js +21 -0
- package/dist/cjs/review/react/index.js.map +1 -0
- package/dist/cjs/review/react/useHeldWrite.d.ts +63 -0
- package/dist/cjs/review/react/useHeldWrite.d.ts.map +1 -0
- package/dist/cjs/review/react/useHeldWrite.js +107 -0
- package/dist/cjs/review/react/useHeldWrite.js.map +1 -0
- package/dist/cjs/review/react/useHeldWrites.d.ts +40 -0
- package/dist/cjs/review/react/useHeldWrites.d.ts.map +1 -0
- package/dist/cjs/review/react/useHeldWrites.js +95 -0
- package/dist/cjs/review/react/useHeldWrites.js.map +1 -0
- package/dist/cjs/review/react/useSavedAttempt.d.ts +54 -0
- package/dist/cjs/review/react/useSavedAttempt.d.ts.map +1 -0
- package/dist/cjs/review/react/useSavedAttempt.js +105 -0
- package/dist/cjs/review/react/useSavedAttempt.js.map +1 -0
- package/dist/cjs/review/savedAttempt.d.ts +180 -0
- package/dist/cjs/review/savedAttempt.d.ts.map +1 -0
- package/dist/cjs/review/savedAttempt.js +527 -0
- package/dist/cjs/review/savedAttempt.js.map +1 -0
- package/dist/cjs/review/writeHold.d.ts +94 -2
- package/dist/cjs/review/writeHold.d.ts.map +1 -1
- package/dist/cjs/review/writeHold.js +284 -43
- package/dist/cjs/review/writeHold.js.map +1 -1
- package/dist/cjs/review/writeRecovery.d.ts +58 -0
- package/dist/cjs/review/writeRecovery.d.ts.map +1 -1
- package/dist/cjs/review/writeRecovery.js +161 -2
- package/dist/cjs/review/writeRecovery.js.map +1 -1
- package/dist/esm/review/heldWrite.d.ts +113 -0
- package/dist/esm/review/heldWrite.d.ts.map +1 -0
- package/dist/esm/review/heldWrite.js +562 -0
- package/dist/esm/review/heldWrite.js.map +1 -0
- package/dist/esm/review/index.d.ts +2 -0
- package/dist/esm/review/index.d.ts.map +1 -1
- package/dist/esm/review/index.js +2 -0
- package/dist/esm/review/index.js.map +1 -1
- package/dist/esm/review/messages.d.ts +30 -0
- package/dist/esm/review/messages.d.ts.map +1 -1
- package/dist/esm/review/messages.js +32 -0
- package/dist/esm/review/messages.js.map +1 -1
- package/dist/esm/review/react/HeldWritesNotice.d.ts +11 -0
- package/dist/esm/review/react/HeldWritesNotice.d.ts.map +1 -0
- package/dist/esm/review/react/HeldWritesNotice.js +19 -0
- package/dist/esm/review/react/HeldWritesNotice.js.map +1 -0
- package/dist/esm/review/react/index.d.ts +5 -0
- package/dist/esm/review/react/index.d.ts.map +1 -0
- package/dist/esm/review/react/index.js +5 -0
- package/dist/esm/review/react/index.js.map +1 -0
- package/dist/esm/review/react/useHeldWrite.d.ts +63 -0
- package/dist/esm/review/react/useHeldWrite.d.ts.map +1 -0
- package/dist/esm/review/react/useHeldWrite.js +104 -0
- package/dist/esm/review/react/useHeldWrite.js.map +1 -0
- package/dist/esm/review/react/useHeldWrites.d.ts +40 -0
- package/dist/esm/review/react/useHeldWrites.d.ts.map +1 -0
- package/dist/esm/review/react/useHeldWrites.js +91 -0
- package/dist/esm/review/react/useHeldWrites.js.map +1 -0
- package/dist/esm/review/react/useSavedAttempt.d.ts +54 -0
- package/dist/esm/review/react/useSavedAttempt.d.ts.map +1 -0
- package/dist/esm/review/react/useSavedAttempt.js +102 -0
- package/dist/esm/review/react/useSavedAttempt.js.map +1 -0
- package/dist/esm/review/savedAttempt.d.ts +180 -0
- package/dist/esm/review/savedAttempt.d.ts.map +1 -0
- package/dist/esm/review/savedAttempt.js +524 -0
- package/dist/esm/review/savedAttempt.js.map +1 -0
- package/dist/esm/review/writeHold.d.ts +94 -2
- package/dist/esm/review/writeHold.d.ts.map +1 -1
- package/dist/esm/review/writeHold.js +285 -44
- package/dist/esm/review/writeHold.js.map +1 -1
- package/dist/esm/review/writeRecovery.d.ts +58 -0
- package/dist/esm/review/writeRecovery.d.ts.map +1 -1
- package/dist/esm/review/writeRecovery.js +160 -2
- package/dist/esm/review/writeRecovery.js.map +1 -1
- package/package.json +16 -2
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type SavedAttempt, type SavedAttemptOutcome, type SavedAttemptRecovery, type SavedAttemptRetirement, type WriteHoldClient } from "../index.js";
|
|
2
|
+
export type UseSavedAttemptOptions<T> = {
|
|
3
|
+
/** The app's one saved-attempt recovery (createSavedAttemptRecovery()). */
|
|
4
|
+
recovery: SavedAttemptRecovery;
|
|
5
|
+
/** The saved attempt; none while nothing is saved. */
|
|
6
|
+
attempt: SavedAttempt<T> | null | undefined;
|
|
7
|
+
/** Reads the attempt's chain. */
|
|
8
|
+
client: WriteHoldClient | undefined;
|
|
9
|
+
/** The check action's next step: "I checked it. <next>." ("Review it again" by default). */
|
|
10
|
+
checkNext?: string;
|
|
11
|
+
};
|
|
12
|
+
/** What a retirement returned: whether it took, and whether it outlives this tab. */
|
|
13
|
+
type Retired = Awaited<ReturnType<SavedAttemptRecovery["retire"]>>;
|
|
14
|
+
export type UseSavedAttemptResult<T> = {
|
|
15
|
+
/** How recovery ended; null until it has, or with no attempt. */
|
|
16
|
+
outcome: SavedAttemptOutcome<T> | null;
|
|
17
|
+
recovering: boolean;
|
|
18
|
+
/** Recover again now: also "Check again" on a success whose details are unavailable. */
|
|
19
|
+
recover: () => Promise<SavedAttemptOutcome<T> | null>;
|
|
20
|
+
/** On `check`: the one explicit action, which retires the attempt for every tab and reload. */
|
|
21
|
+
checkAction: {
|
|
22
|
+
line: string;
|
|
23
|
+
warning: string;
|
|
24
|
+
label: string;
|
|
25
|
+
run: () => Promise<Retired>;
|
|
26
|
+
} | null;
|
|
27
|
+
/**
|
|
28
|
+
* Only after the check action came back `reason: "unreadable"` (the browser
|
|
29
|
+
* has storage it can't read): the warned exit, "I checked my wallet.
|
|
30
|
+
* Continue anyway", which retires in this tab alone if storage still can't
|
|
31
|
+
* be read. Never a first option.
|
|
32
|
+
*/
|
|
33
|
+
unreadableAction: {
|
|
34
|
+
line: string;
|
|
35
|
+
label: string;
|
|
36
|
+
run: () => Promise<Retired>;
|
|
37
|
+
} | null;
|
|
38
|
+
/**
|
|
39
|
+
* Retire after the user's exit or a followed settlement; recovers again.
|
|
40
|
+
* Bound to the attempt it was rendered for: called after that attempt (or
|
|
41
|
+
* its recovery or client) changed, it refuses before anything is saved.
|
|
42
|
+
*/
|
|
43
|
+
retire: (reason: SavedAttemptRetirement) => Promise<Retired>;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* One saved attempt's recovery, the one way every app runs it: recovered
|
|
47
|
+
* when it (or the client) appears, before the app prepares any new send, with
|
|
48
|
+
* the check action ready on `check`. Every answer and callback belongs to the
|
|
49
|
+
* attempt, recovery and client it started with: an earlier one's, or an older
|
|
50
|
+
* request's, never reaches the current one.
|
|
51
|
+
*/
|
|
52
|
+
export declare function useSavedAttempt<T>(options: UseSavedAttemptOptions<T>): UseSavedAttemptResult<T>;
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=useSavedAttempt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSavedAttempt.d.ts","sourceRoot":"","sources":["../../../../src/review/react/useSavedAttempt.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACrB,MAAM,aAAa,CAAC;AAUrB,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAAI;IACtC,2EAA2E;IAC3E,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,sDAAsD;IACtD,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,iCAAiC;IACjC,MAAM,EAAE,eAAe,GAAG,SAAS,CAAC;IACpC,4FAA4F;IAC5F,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,qFAAqF;AACrF,KAAK,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAEnE,MAAM,MAAM,qBAAqB,CAAC,CAAC,IAAI;IACrC,iEAAiE;IACjE,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACvC,UAAU,EAAE,OAAO,CAAC;IACpB,wFAAwF;IACxF,OAAO,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACtD,+FAA+F;IAC/F,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;KAC7B,GAAG,IAAI,CAAC;IACT;;;;;OAKG;IACH,gBAAgB,EAAE;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;KAC7B,GAAG,IAAI,CAAC;IACT;;;;OAIG;IACH,MAAM,EAAE,CAAC,MAAM,EAAE,sBAAsB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9D,CAAC;AASF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC,GACjC,qBAAqB,CAAC,CAAC,CAAC,CAoG1B"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useSavedAttempt = useSavedAttempt;
|
|
4
|
+
const index_js_1 = require("../index.js");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const keyOf = (attempt) => attempt
|
|
7
|
+
? JSON.stringify({ ...attempt, authenticate: undefined }, (_, value) => typeof value === "bigint" ? value.toString() : value)
|
|
8
|
+
: null;
|
|
9
|
+
/**
|
|
10
|
+
* One saved attempt's recovery, the one way every app runs it: recovered
|
|
11
|
+
* when it (or the client) appears, before the app prepares any new send, with
|
|
12
|
+
* the check action ready on `check`. Every answer and callback belongs to the
|
|
13
|
+
* attempt, recovery and client it started with: an earlier one's, or an older
|
|
14
|
+
* request's, never reaches the current one.
|
|
15
|
+
*/
|
|
16
|
+
function useSavedAttempt(options) {
|
|
17
|
+
const { recovery, client, checkNext } = options;
|
|
18
|
+
const key = keyOf(options.attempt);
|
|
19
|
+
const attempt = options.attempt;
|
|
20
|
+
/** The attempt as last rendered: the same saved fields, with the app's newest callbacks. */
|
|
21
|
+
const latest = (0, react_1.useRef)(attempt);
|
|
22
|
+
latest.current = attempt;
|
|
23
|
+
/** One lifecycle per attempt, recovery and client, with its latest request. */
|
|
24
|
+
const lifecycle = (0, react_1.useMemo)(() => ({ attempt, recovery, client, request: 0 }),
|
|
25
|
+
// The key stands for the attempt.
|
|
26
|
+
[key, recovery, client]);
|
|
27
|
+
/** Whether `of` is the mounted hook's lifecycle now. */
|
|
28
|
+
const current = (of) => mounted.current && rendered.current === of;
|
|
29
|
+
/**
|
|
30
|
+
* The lifecycle last rendered: set during render, so a callback of an
|
|
31
|
+
* earlier one is refused from the next commit's first layout effect on. A
|
|
32
|
+
* render React then discards leaves the shown callbacks refused (fail
|
|
33
|
+
* closed) until the next commit.
|
|
34
|
+
*/
|
|
35
|
+
const rendered = (0, react_1.useRef)(undefined);
|
|
36
|
+
rendered.current = lifecycle;
|
|
37
|
+
/** Whether the hook is mounted: no callback or answer acts after unmount. */
|
|
38
|
+
const mounted = (0, react_1.useRef)(false);
|
|
39
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
40
|
+
mounted.current = true;
|
|
41
|
+
return () => {
|
|
42
|
+
mounted.current = false;
|
|
43
|
+
};
|
|
44
|
+
}, []);
|
|
45
|
+
const [shown, setShown] = (0, react_1.useState)({ outcome: null, recovering: false });
|
|
46
|
+
/** The lifecycle whose check action last found storage unreadable. */
|
|
47
|
+
const [unreadable, setUnreadable] = (0, react_1.useState)();
|
|
48
|
+
const recover = (0, react_1.useCallback)(async () => {
|
|
49
|
+
const { recovery, client } = lifecycle;
|
|
50
|
+
const attempt = latest.current;
|
|
51
|
+
if (!attempt || !client || !current(lifecycle))
|
|
52
|
+
return null;
|
|
53
|
+
const request = ++lifecycle.request;
|
|
54
|
+
setShown((now) => ({
|
|
55
|
+
of: lifecycle,
|
|
56
|
+
outcome: now.of === lifecycle ? now.outcome : null,
|
|
57
|
+
recovering: true,
|
|
58
|
+
}));
|
|
59
|
+
const outcome = await recovery.recover(attempt, client);
|
|
60
|
+
// Only the latest request of the mounted lifecycle shows.
|
|
61
|
+
if (!current(lifecycle) || lifecycle.request !== request)
|
|
62
|
+
return null;
|
|
63
|
+
setShown({ of: lifecycle, outcome, recovering: false });
|
|
64
|
+
return outcome;
|
|
65
|
+
}, [lifecycle]);
|
|
66
|
+
(0, react_1.useEffect)(() => {
|
|
67
|
+
void recover();
|
|
68
|
+
}, [recover]);
|
|
69
|
+
const retire = (0, react_1.useCallback)(async (reason) => {
|
|
70
|
+
const { recovery } = lifecycle;
|
|
71
|
+
const attempt = latest.current;
|
|
72
|
+
if (!attempt || !current(lifecycle))
|
|
73
|
+
return { retired: false };
|
|
74
|
+
const retired = await recovery.retire(attempt, reason);
|
|
75
|
+
if (!current(lifecycle))
|
|
76
|
+
return retired;
|
|
77
|
+
if (!retired.retired && retired.reason === "unreadable")
|
|
78
|
+
setUnreadable(lifecycle);
|
|
79
|
+
await recover();
|
|
80
|
+
return retired;
|
|
81
|
+
}, [lifecycle, recover]);
|
|
82
|
+
const outcome = shown.of === lifecycle ? shown.outcome : null;
|
|
83
|
+
return {
|
|
84
|
+
outcome,
|
|
85
|
+
recovering: shown.of === lifecycle && shown.recovering,
|
|
86
|
+
recover,
|
|
87
|
+
checkAction: outcome?.status === "check"
|
|
88
|
+
? {
|
|
89
|
+
line: outcome.line,
|
|
90
|
+
warning: outcome.warning,
|
|
91
|
+
label: (0, index_js_1.checkedItLabel)(checkNext),
|
|
92
|
+
run: () => retire({ by: "check", outcome }),
|
|
93
|
+
}
|
|
94
|
+
: null,
|
|
95
|
+
unreadableAction: outcome?.status === "check" && unreadable === lifecycle
|
|
96
|
+
? {
|
|
97
|
+
line: index_js_1.SAVED_ATTEMPT_UNREADABLE_LINE,
|
|
98
|
+
label: index_js_1.SAVED_ATTEMPT_CONTINUE_ANYWAY_LABEL,
|
|
99
|
+
run: () => retire({ by: "check", outcome, force: "unreadable" }),
|
|
100
|
+
}
|
|
101
|
+
: null,
|
|
102
|
+
retire,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=useSavedAttempt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSavedAttempt.js","sourceRoot":"","sources":["../../../../src/review/react/useSavedAttempt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import type { Address, Hex } from "viem";
|
|
2
|
+
import type { WriteHeldState, WriteHold, WriteHoldClient, WriteHoldHandle } from "./writeHold.js";
|
|
3
|
+
import { type HeldWriteStorage, type ReviewedWriteRecoveryInput } from "./writeRecovery.js";
|
|
4
|
+
/** What the app's domain check says of one transaction (or, given none, of a search for the attempt). */
|
|
5
|
+
export type SavedAttemptProof<T> =
|
|
6
|
+
/** The chain shows this attempt ran, with the app's result (a project ID, a launch). */
|
|
7
|
+
{
|
|
8
|
+
result: "proven";
|
|
9
|
+
value: T;
|
|
10
|
+
}
|
|
11
|
+
/** The transaction is some other write. */
|
|
12
|
+
| {
|
|
13
|
+
result: "not-this";
|
|
14
|
+
reason?: string;
|
|
15
|
+
}
|
|
16
|
+
/** It couldn't be read or shown. */
|
|
17
|
+
| {
|
|
18
|
+
result: "unknown";
|
|
19
|
+
reason?: string;
|
|
20
|
+
};
|
|
21
|
+
/** Where a saved attempt was held, and what the app saved of it. Only what was saved: nothing fresh. */
|
|
22
|
+
export type SavedAttemptScope = {
|
|
23
|
+
chainId: number;
|
|
24
|
+
/** The account that sent it: the wallet, or the Safe. */
|
|
25
|
+
account: Address;
|
|
26
|
+
/** Whether `account` is a Safe; a saved `safeTxHash` says so too. */
|
|
27
|
+
safe?: boolean;
|
|
28
|
+
/** Every intent namespace the attempt may be held under, the current one first, legacy ones after. */
|
|
29
|
+
namespaces: readonly string[];
|
|
30
|
+
/** The exact saved call, when kept: a saved hash is adopted into the hold against it. */
|
|
31
|
+
call?: ReviewedWriteRecoveryInput["call"];
|
|
32
|
+
/**
|
|
33
|
+
* The app's re-read of its own domain journal, required: awaited under
|
|
34
|
+
* the hold's locks before any check or exit retirement, it is the final say
|
|
35
|
+
* of Rule E (only a followed settlement retires a success). Return false,
|
|
36
|
+
* or throw, while the journal records the attempt's success or can't be
|
|
37
|
+
* read.
|
|
38
|
+
*/
|
|
39
|
+
confirmRetirable(): Promise<boolean>;
|
|
40
|
+
saved?: {
|
|
41
|
+
/**
|
|
42
|
+
* The app's send began: the wallet may have opened. Only an explicit
|
|
43
|
+
* `false`, with no hash or nonce evidence, is proof that nothing was sent.
|
|
44
|
+
*/
|
|
45
|
+
started?: boolean;
|
|
46
|
+
/** The transaction hash the wallet returned. */
|
|
47
|
+
hash?: Hex;
|
|
48
|
+
/** The Safe proposal the wallet returned. */
|
|
49
|
+
safeTxHash?: Hex;
|
|
50
|
+
/** That proposal's Safe nonce, when saved. */
|
|
51
|
+
safeNonce?: number;
|
|
52
|
+
/** The account's next nonce before the wallet opened, with the block it was read at. */
|
|
53
|
+
nonce?: number | bigint;
|
|
54
|
+
sentNonce?: number | bigint;
|
|
55
|
+
fromBlock?: bigint;
|
|
56
|
+
/** When the wallet returned the hash, in milliseconds since the epoch. */
|
|
57
|
+
submittedAt?: number;
|
|
58
|
+
/** Settlements already shown before this attempt began: never this attempt's. */
|
|
59
|
+
before?: readonly Hex[];
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
/** A saved attempt with the app's domain check of a transaction (or, given none, its search for the attempt). */
|
|
63
|
+
export type SavedAttempt<T> = SavedAttemptScope & {
|
|
64
|
+
authenticate(hash: Hex | undefined): Promise<SavedAttemptProof<T>>;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* What a retirement returned. `durable: false`: it lasts in this tab alone
|
|
68
|
+
* (show `SAVED_ATTEMPT_TAB_ONLY_LINE`); another tab or a reload asks
|
|
69
|
+
* again, never sends. `reason: "unreadable"`: the browser has storage but
|
|
70
|
+
* can't read it, so the warned exit may be offered.
|
|
71
|
+
*/
|
|
72
|
+
export type SavedAttemptRetired = {
|
|
73
|
+
retired: false;
|
|
74
|
+
reason?: "unreadable";
|
|
75
|
+
} | {
|
|
76
|
+
retired: true;
|
|
77
|
+
durable: boolean;
|
|
78
|
+
};
|
|
79
|
+
/** Why an attempt is retired: the only three things that retire one. */
|
|
80
|
+
export type SavedAttemptRetirement =
|
|
81
|
+
/** The user's exit released the hold. */
|
|
82
|
+
{
|
|
83
|
+
by: "exit";
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The user's "I checked it. ..." on exactly this check outcome. With
|
|
87
|
+
* `force: "unreadable"` (the warned "I checked my wallet. Continue anyway",
|
|
88
|
+
* offered only after a retirement came back `reason: "unreadable"`), it
|
|
89
|
+
* retires in this tab alone if the hold's storage still can't be read.
|
|
90
|
+
*/
|
|
91
|
+
| {
|
|
92
|
+
by: "check";
|
|
93
|
+
outcome: SavedAttemptCheck;
|
|
94
|
+
force?: "unreadable";
|
|
95
|
+
}
|
|
96
|
+
/** The app followed and recorded this settlement. */
|
|
97
|
+
| {
|
|
98
|
+
by: "settled";
|
|
99
|
+
hash?: Hex;
|
|
100
|
+
};
|
|
101
|
+
export type SavedAttemptCheck = {
|
|
102
|
+
status: "check";
|
|
103
|
+
/** What couldn't be shown, for logs and details. */
|
|
104
|
+
reason: string;
|
|
105
|
+
line: string;
|
|
106
|
+
warning: string;
|
|
107
|
+
/** The hold evidence this check evaluated: the user's check retires exactly this. */
|
|
108
|
+
evidence: string;
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* How recovering a saved attempt ended, the one rule every app follows
|
|
112
|
+
* before any send or discard:
|
|
113
|
+
* - `held`: the hold still holds the write. Count nothing; show `state`, and
|
|
114
|
+
* its exit when due (through `handle`);
|
|
115
|
+
* - `done`: `success` ran. `authenticated: true` when the app's check showed
|
|
116
|
+
* it as this attempt (`value`); `false` when the hold settled it but the
|
|
117
|
+
* app's details are unavailable (`reason`): record its `hash` and follow it,
|
|
118
|
+
* with "Check again" (recover again) as its only action. Either way, never
|
|
119
|
+
* send it again; only `retire({ by: "settled" })` retires it. `failed` is
|
|
120
|
+
* the hold's proven revert of it;
|
|
121
|
+
* - `check`: it can't be shown. One explicit action, "I checked it. ...",
|
|
122
|
+
* and only that, retires it (`retire({ by: "check", outcome })`);
|
|
123
|
+
* - `none`: the hold proves nothing was reserved and nothing saved says it
|
|
124
|
+
* was sent, or the attempt was retired (`retired`): by the user or a
|
|
125
|
+
* followed settlement, or by the SDK itself when it dropped every
|
|
126
|
+
* reservation of it on a definite wallet rejection or an abort before the
|
|
127
|
+
* wallet opened (`"rejected"`: nothing can have been sent).
|
|
128
|
+
*/
|
|
129
|
+
export type SavedAttemptOutcome<T> = {
|
|
130
|
+
status: "held";
|
|
131
|
+
state: WriteHeldState;
|
|
132
|
+
handle: WriteHoldHandle;
|
|
133
|
+
} | {
|
|
134
|
+
status: "done";
|
|
135
|
+
result: "success";
|
|
136
|
+
authenticated: true;
|
|
137
|
+
hash?: Hex;
|
|
138
|
+
value: T;
|
|
139
|
+
} | {
|
|
140
|
+
status: "done";
|
|
141
|
+
result: "success";
|
|
142
|
+
authenticated: false;
|
|
143
|
+
/** The settled transaction; absent when another tab's check proved it without one. */
|
|
144
|
+
hash?: Hex;
|
|
145
|
+
reason: string;
|
|
146
|
+
} | {
|
|
147
|
+
status: "done";
|
|
148
|
+
result: "failed";
|
|
149
|
+
hash: Hex;
|
|
150
|
+
} | SavedAttemptCheck | {
|
|
151
|
+
status: "none";
|
|
152
|
+
retired?: SavedAttemptRetirement["by"] | "rejected";
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Saved-attempt recovery over the app's write hold, framework-free: every
|
|
156
|
+
* app's launches, linked plans, shop updates and other saved writes recover
|
|
157
|
+
* the same way. Pass the hold's own `storage` and `locks` when it was made
|
|
158
|
+
* with custom ones; the defaults are the hold's defaults.
|
|
159
|
+
*
|
|
160
|
+
* - Recovery needs only what was saved: run it right after a saved attempt is
|
|
161
|
+
* found, before any fresh-send preparation.
|
|
162
|
+
* - Absence of evidence is `check`, never `none`: a missing hold record, a
|
|
163
|
+
* refused or unreadable adoption, an empty search and every exception.
|
|
164
|
+
* - A settled success always wins: it is never downgraded by a later failed
|
|
165
|
+
* or empty read, and it blocks discard until followed.
|
|
166
|
+
* - Only the user's exit, the user's check action, a followed settlement and
|
|
167
|
+
* the SDK's own drop of a rejected reservation retire an attempt, persisted under the hold's locks for every tab and
|
|
168
|
+
* reload, and only for the hold evidence they saw.
|
|
169
|
+
*/
|
|
170
|
+
export declare function createSavedAttemptRecovery(options: {
|
|
171
|
+
hold: WriteHold;
|
|
172
|
+
storage?: HeldWriteStorage;
|
|
173
|
+
locks?: Pick<LockManager, "request">;
|
|
174
|
+
}): {
|
|
175
|
+
recover: <T>(attempt: SavedAttempt<T>, client: WriteHoldClient) => Promise<SavedAttemptOutcome<T>>;
|
|
176
|
+
retire: (attempt: SavedAttemptScope, reason: SavedAttemptRetirement) => Promise<SavedAttemptRetired>;
|
|
177
|
+
canDiscard: (attempt: SavedAttemptScope) => boolean;
|
|
178
|
+
};
|
|
179
|
+
export type SavedAttemptRecovery = ReturnType<typeof createSavedAttemptRecovery>;
|
|
180
|
+
//# sourceMappingURL=savedAttempt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"savedAttempt.d.ts","sourceRoot":"","sources":["../../../src/review/savedAttempt.ts"],"names":[],"mappings":"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"}
|