@ninsei-labs/sdk 0.39.0 → 0.39.1

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/src/actions.mjs CHANGED
@@ -1,72 +1,72 @@
1
- // ORDER ACTIONS: MARKING READY, CLAIMING, REFUNDING.
2
- //
3
- // All three go through ONE wallet seam (the `send`/`receipt` role) and through the slot check that in the engine
4
- // stands BEFORE signing. What is added here is exactly what the engine cannot do: `expect` is MANDATORY.
5
- //
6
- // Why it is mandatory. The slot check compares the order we assembled with the one lying on the chain. Without
7
- // expectations there is nothing to compare against, and the signature goes out under an order whose commitments
8
- // nobody checked: for marking ready that is granting a foreign address the right to take the settlement, for
9
- // claiming it is revealing your own half (irreversible), for refunding the same reveal. The transaction still
10
- // looks successful.
11
- import { SdkError } from "./errors.mjs";
12
- import * as engine from "./engine.mjs";
13
- // THE DEAL FLOW IS NOW A PACKAGE MODULE, NOT AN ENGINE FILE (#32, wave 3): www/js/core/swap-flow.js moved to
14
- // sdk/src/swap-flow.mjs. The actions therefore call the module directly instead of reaching it through the
15
- // mirror - there is exactly one implementation, and it lives here.
16
- import * as flow from "./swap-flow.mjs";
17
-
18
- const missingFields = (object, fields) =>
19
- fields.filter((k) => object[k] === undefined || object[k] === null || object[k] === "");
20
-
21
- const walletOrFail = (wallet) => {
22
- const role = ["send", "receipt"];
23
- const missing = wallet ? role.filter((k) => typeof wallet[k] !== "function") : role;
24
- if (missing.length) throw new SdkError("bad-input", { field: "wallet", missing });
25
- return wallet;
26
- };
27
-
28
- const requestOrFail = (request, extra) => {
29
- if (!request || typeof request !== "object") throw new SdkError("bad-input", { field: "request" });
30
- const missing = missingFields(request, ["escrow", "expect", ...extra]);
31
- if (missing.length) throw new SdkError("bad-input", { field: "request", missing });
32
- return request;
33
- };
34
-
35
- // The engine's refusal arrives as text; a CODE goes out. Texts are the interface's business, the core speaks in codes.
36
- const withCodes = async (step, work) => {
37
- try { return await work(); }
38
- catch (error) {
39
- if (error && typeof error.code === "string") throw error;
40
- throw new SdkError("contract-reverted", { step });
41
- }
42
- };
43
-
44
- export function createActions({ call = null } = {}) {
45
- // WHAT READS THE CHAIN IS ALSO A SEAM, and not only for the checks: the slot check and the signature must go
46
- // ONE way, otherwise part of the check goes past the wallet and part does not. By default - the engine's read.
47
- const reader = call || engine.evm.readContract;
48
- const deps = (wallet) => ({ call: reader, send: (tx) => wallet.send(tx), receipt: (h) => wallet.receipt(h) });
49
- return {
50
- /** Marking "I saw the XMR on the shared address". Without it, claiming is forbidden by the contract. */
51
- async markReady(request, wallet) {
52
- requestOrFail(request, []);
53
- walletOrFail(wallet);
54
- const { escrow, expect, onStep } = request;
55
- return await withCodes("mark-ready", () => flow.markReadyOrder({ escrow, expect, onStep, deps: deps(wallet) }));
56
- },
57
- /** Claiming: it reveals your own half, so expectations are mandatory. */
58
- async claim(request, wallet) {
59
- requestOrFail(request, ["halfClaimer"]);
60
- walletOrFail(wallet);
61
- const { escrow, halfClaimer, expect, onStep } = request;
62
- return await withCodes("claim", () => flow.claimOrder({ escrow, halfClaimer, expect, onStep, deps: deps(wallet) }));
63
- },
64
- /** Refunding: it also reveals a half. The core passes the expectations ALWAYS, though the engine does not require them. */
65
- async refund(request, wallet) {
66
- requestOrFail(request, ["halfLocker"]);
67
- walletOrFail(wallet);
68
- const { escrow, halfLocker, expect, onStep } = request;
69
- return await withCodes("refund", () => flow.refundOrder({ escrow, halfLocker, expect, onStep, deps: deps(wallet) }));
70
- },
71
- };
72
- }
1
+ // ORDER ACTIONS: MARKING READY, CLAIMING, REFUNDING.
2
+ //
3
+ // All three go through ONE wallet seam (the `send`/`receipt` role) and through the slot check that in the engine
4
+ // stands BEFORE signing. What is added here is exactly what the engine cannot do: `expect` is MANDATORY.
5
+ //
6
+ // Why it is mandatory. The slot check compares the order we assembled with the one lying on the chain. Without
7
+ // expectations there is nothing to compare against, and the signature goes out under an order whose commitments
8
+ // nobody checked: for marking ready that is granting a foreign address the right to take the settlement, for
9
+ // claiming it is revealing your own half (irreversible), for refunding the same reveal. The transaction still
10
+ // looks successful.
11
+ import { SdkError } from "./errors.mjs";
12
+ import * as engine from "./engine.mjs";
13
+ // THE DEAL FLOW IS NOW A PACKAGE MODULE, NOT AN ENGINE FILE (#32, wave 3): www/js/core/swap-flow.js moved to
14
+ // sdk/src/swap-flow.mjs. The actions therefore call the module directly instead of reaching it through the
15
+ // mirror - there is exactly one implementation, and it lives here.
16
+ import * as flow from "./swap-flow.mjs";
17
+
18
+ const missingFields = (object, fields) =>
19
+ fields.filter((k) => object[k] === undefined || object[k] === null || object[k] === "");
20
+
21
+ const walletOrFail = (wallet) => {
22
+ const role = ["send", "receipt"];
23
+ const missing = wallet ? role.filter((k) => typeof wallet[k] !== "function") : role;
24
+ if (missing.length) throw new SdkError("bad-input", { field: "wallet", missing });
25
+ return wallet;
26
+ };
27
+
28
+ const requestOrFail = (request, extra) => {
29
+ if (!request || typeof request !== "object") throw new SdkError("bad-input", { field: "request" });
30
+ const missing = missingFields(request, ["escrow", "expect", ...extra]);
31
+ if (missing.length) throw new SdkError("bad-input", { field: "request", missing });
32
+ return request;
33
+ };
34
+
35
+ // The engine's refusal arrives as text; a CODE goes out. Texts are the interface's business, the core speaks in codes.
36
+ const withCodes = async (step, work) => {
37
+ try { return await work(); }
38
+ catch (error) {
39
+ if (error && typeof error.code === "string") throw error;
40
+ throw new SdkError("contract-reverted", { step });
41
+ }
42
+ };
43
+
44
+ export function createActions({ call = null } = {}) {
45
+ // WHAT READS THE CHAIN IS ALSO A SEAM, and not only for the checks: the slot check and the signature must go
46
+ // ONE way, otherwise part of the check goes past the wallet and part does not. By default - the engine's read.
47
+ const reader = call || engine.evm.readContract;
48
+ const deps = (wallet) => ({ call: reader, send: (tx) => wallet.send(tx), receipt: (h) => wallet.receipt(h) });
49
+ return {
50
+ /** Marking "I saw the XMR on the shared address". Without it, claiming is forbidden by the contract. */
51
+ async markReady(request, wallet) {
52
+ requestOrFail(request, []);
53
+ walletOrFail(wallet);
54
+ const { escrow, expect, onStep } = request;
55
+ return await withCodes("mark-ready", () => flow.markReadyOrder({ escrow, expect, onStep, deps: deps(wallet) }));
56
+ },
57
+ /** Claiming: it reveals your own half, so expectations are mandatory. */
58
+ async claim(request, wallet) {
59
+ requestOrFail(request, ["halfClaimer"]);
60
+ walletOrFail(wallet);
61
+ const { escrow, halfClaimer, expect, onStep } = request;
62
+ return await withCodes("claim", () => flow.claimOrder({ escrow, halfClaimer, expect, onStep, deps: deps(wallet) }));
63
+ },
64
+ /** Refunding: it also reveals a half. The core passes the expectations ALWAYS, though the engine does not require them. */
65
+ async refund(request, wallet) {
66
+ requestOrFail(request, ["halfLocker"]);
67
+ walletOrFail(wallet);
68
+ const { escrow, halfLocker, expect, onStep } = request;
69
+ return await withCodes("refund", () => flow.refundOrder({ escrow, halfLocker, expect, onStep, deps: deps(wallet) }));
70
+ },
71
+ };
72
+ }