@cardano-slips/flow 0.1.0 → 0.3.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/README.md +53 -9
- package/dist/address.d.ts +12 -0
- package/dist/address.d.ts.map +1 -1
- package/dist/address.js +43 -0
- package/dist/address.js.map +1 -1
- package/dist/balance-error.d.ts +48 -0
- package/dist/balance-error.d.ts.map +1 -0
- package/dist/balance-error.js +45 -0
- package/dist/balance-error.js.map +1 -0
- package/dist/balance.d.ts +54 -0
- package/dist/balance.d.ts.map +1 -0
- package/dist/balance.js +175 -0
- package/dist/balance.js.map +1 -0
- package/dist/card.css +492 -0
- package/dist/card.d.ts +41 -0
- package/dist/card.d.ts.map +1 -0
- package/dist/card.js +69 -0
- package/dist/card.js.map +1 -0
- package/dist/cip30.d.ts +10 -0
- package/dist/cip30.d.ts.map +1 -1
- package/dist/cip30.js +16 -0
- package/dist/cip30.js.map +1 -1
- package/dist/complete-error.d.ts +57 -0
- package/dist/complete-error.d.ts.map +1 -0
- package/dist/complete-error.js +52 -0
- package/dist/complete-error.js.map +1 -0
- package/dist/complete.d.ts +77 -0
- package/dist/complete.d.ts.map +1 -0
- package/dist/complete.js +182 -0
- package/dist/complete.js.map +1 -0
- package/dist/derived.d.ts +8 -0
- package/dist/derived.d.ts.map +1 -0
- package/dist/derived.js +2 -0
- package/dist/derived.js.map +1 -0
- package/dist/effects-panel.d.ts +37 -0
- package/dist/effects-panel.d.ts.map +1 -0
- package/dist/effects-panel.js +64 -0
- package/dist/effects-panel.js.map +1 -0
- package/dist/effects.css +629 -0
- package/dist/exchange.d.ts +54 -0
- package/dist/exchange.d.ts.map +1 -0
- package/dist/exchange.js +136 -0
- package/dist/exchange.js.map +1 -0
- package/dist/explain.d.ts +39 -0
- package/dist/explain.d.ts.map +1 -0
- package/dist/explain.js +172 -0
- package/dist/explain.js.map +1 -0
- package/dist/index.d.ts +34 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -2
- package/dist/index.js.map +1 -1
- package/dist/ledger.d.ts +74 -0
- package/dist/ledger.d.ts.map +1 -0
- package/dist/ledger.js +402 -0
- package/dist/ledger.js.map +1 -0
- package/dist/outcome-panel.d.ts +63 -0
- package/dist/outcome-panel.d.ts.map +1 -0
- package/dist/outcome-panel.js +40 -0
- package/dist/outcome-panel.js.map +1 -0
- package/dist/parameter-form.d.ts +26 -0
- package/dist/parameter-form.d.ts.map +1 -0
- package/dist/parameter-form.js +42 -0
- package/dist/parameter-form.js.map +1 -0
- package/dist/resolve.d.ts +11 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/resolve.js +21 -0
- package/dist/resolve.js.map +1 -0
- package/dist/sign-error.d.ts +62 -0
- package/dist/sign-error.d.ts.map +1 -0
- package/dist/sign-error.js +42 -0
- package/dist/sign-error.js.map +1 -0
- package/dist/sign.d.ts +38 -0
- package/dist/sign.d.ts.map +1 -0
- package/dist/sign.js +79 -0
- package/dist/sign.js.map +1 -0
- package/dist/slip-card.d.ts +55 -0
- package/dist/slip-card.d.ts.map +1 -0
- package/dist/slip-card.js +89 -0
- package/dist/slip-card.js.map +1 -0
- package/dist/tokens.css +97 -123
- package/dist/utxo.d.ts +16 -0
- package/dist/utxo.d.ts.map +1 -0
- package/dist/utxo.js +51 -0
- package/dist/utxo.js.map +1 -0
- package/dist/witness.d.ts +23 -0
- package/dist/witness.d.ts.map +1 -0
- package/dist/witness.js +101 -0
- package/dist/witness.js.map +1 -0
- package/package.json +13 -6
- package/src/address.ts +53 -0
- package/src/balance-error.ts +77 -0
- package/src/balance.ts +285 -0
- package/src/card.css +492 -0
- package/src/card.ts +86 -0
- package/src/cip30.ts +19 -0
- package/src/complete-error.ts +95 -0
- package/src/complete.ts +307 -0
- package/src/derived.ts +8 -0
- package/src/effects-panel.tsx +386 -0
- package/src/effects.css +629 -0
- package/src/exchange.ts +212 -0
- package/src/explain.ts +211 -0
- package/src/index.ts +64 -3
- package/src/ledger.ts +503 -0
- package/src/outcome-panel.tsx +263 -0
- package/src/parameter-form.tsx +138 -0
- package/src/resolve.ts +40 -0
- package/src/sign-error.ts +89 -0
- package/src/sign.ts +118 -0
- package/src/slip-card.tsx +244 -0
- package/src/tokens.css +97 -123
- package/src/utxo.ts +70 -0
- package/src/witness.ts +132 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Why a Slip did not reach the chain, for the failures that belong to the whole
|
|
3
|
+
* path rather than to building, signing or submitting alone. `Blocked` is the
|
|
4
|
+
* one that matters: it is invariant 3 in the error channel, and there is no
|
|
5
|
+
* field on it that lets anyone past.
|
|
6
|
+
*/
|
|
7
|
+
import { type ClientErrorCode } from "@cardano-slips/core";
|
|
8
|
+
import type { Reason } from "@cardano-slips/verifier";
|
|
9
|
+
import type { Derived } from "./derived.js";
|
|
10
|
+
export type CompletionRefusal =
|
|
11
|
+
/** The wallet reported no unspent outputs, so there is nothing to build from. */
|
|
12
|
+
"NoUtxos"
|
|
13
|
+
/** What `getUtxos` answered is not something these bytes can be read as. */
|
|
14
|
+
| "UnreadableUtxos"
|
|
15
|
+
/** The wallet would not say which addresses are its own, or named one that cannot be read. */
|
|
16
|
+
| "UnreadableAddresses"
|
|
17
|
+
/** The effects could not be derived from the transaction, or compared with the declaration. */
|
|
18
|
+
| "CannotJudge"
|
|
19
|
+
/** The derived effects disagree with what the endpoint declared. Nothing signs after this. */
|
|
20
|
+
| "Blocked"
|
|
21
|
+
/** The caller could not put the effects in front of a person, so nothing may be signed. */
|
|
22
|
+
| "NotShown"
|
|
23
|
+
/** The person closed the transaction without signing it. Not a fault. */
|
|
24
|
+
| "Cancelled"
|
|
25
|
+
/** The funds kept moving, and the transaction has been rebuilt as often as it will be. */
|
|
26
|
+
| "OutOfAttempts";
|
|
27
|
+
/**
|
|
28
|
+
* Exhaustive by type: adding a refusal above without listing it here fails to
|
|
29
|
+
* compile, and `test/complete.test.ts` fails if any of them stops being reachable.
|
|
30
|
+
*/
|
|
31
|
+
export declare const completionRefusals: Readonly<Record<CompletionRefusal, true>>;
|
|
32
|
+
export declare const slipErrorCodeFor: (refusal: CompletionRefusal) => ClientErrorCode | undefined;
|
|
33
|
+
declare const CompletionError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
34
|
+
readonly _tag: "CompletionError";
|
|
35
|
+
} & Readonly<A>;
|
|
36
|
+
/**
|
|
37
|
+
* `reasons` is what the transaction actually does against what was declared,
|
|
38
|
+
* and `derived` is the whole of what it does, for the block to render. There is no way to carry on from one — a mismatch
|
|
39
|
+
* hard-blocks, with no override, no allowlist and no confirmation.
|
|
40
|
+
*/
|
|
41
|
+
export declare class CompletionError extends CompletionError_base<{
|
|
42
|
+
readonly refusal: CompletionRefusal;
|
|
43
|
+
readonly detail: string;
|
|
44
|
+
readonly reasons?: ReadonlyArray<Reason>;
|
|
45
|
+
readonly derived?: Derived;
|
|
46
|
+
readonly cause?: unknown;
|
|
47
|
+
}> {
|
|
48
|
+
get message(): string;
|
|
49
|
+
get code(): ClientErrorCode | undefined;
|
|
50
|
+
}
|
|
51
|
+
export declare const refuse: (refusal: CompletionRefusal, detail: string, extra?: {
|
|
52
|
+
readonly reasons?: ReadonlyArray<Reason>;
|
|
53
|
+
readonly derived?: Derived;
|
|
54
|
+
readonly cause?: unknown;
|
|
55
|
+
}) => CompletionError;
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=complete-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete-error.d.ts","sourceRoot":"","sources":["../src/complete-error.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAGrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE3C,MAAM,MAAM,iBAAiB;AAC3B,iFAAiF;AAC/E,SAAS;AACX,4EAA4E;GAC1E,iBAAiB;AACnB,8FAA8F;GAC5F,qBAAqB;AACvB,+FAA+F;GAC7F,aAAa;AACf,8FAA8F;GAC5F,SAAS;AACX,2FAA2F;GACzF,UAAU;AACZ,yEAAyE;GACvE,WAAW;AACb,0FAA0F;GACxF,eAAe,CAAA;AAEnB;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,iBAAiB,EAAE,IAAI,CAAC,CASxE,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,SAAS,iBAAiB,KAAG,eAAe,GAAG,SAe/E,CAAA;;;;AAED;;;;GAIG;AACH,qBAAa,eAAgB,SAAQ,qBAAoC;IACvE,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAA;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACxC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CACzB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAE7B;IAED,IAAI,IAAI,IAAI,eAAe,GAAG,SAAS,CAEtC;CACF;AAED,eAAO,MAAM,MAAM,GACjB,SAAS,iBAAiB,EAC1B,QAAQ,MAAM,EACd,QAAO;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,KAC7G,eAOC,CAAA"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Data } from "effect";
|
|
2
|
+
/**
|
|
3
|
+
* Exhaustive by type: adding a refusal above without listing it here fails to
|
|
4
|
+
* compile, and `test/complete.test.ts` fails if any of them stops being reachable.
|
|
5
|
+
*/
|
|
6
|
+
export const completionRefusals = {
|
|
7
|
+
NoUtxos: true,
|
|
8
|
+
UnreadableUtxos: true,
|
|
9
|
+
UnreadableAddresses: true,
|
|
10
|
+
CannotJudge: true,
|
|
11
|
+
Blocked: true,
|
|
12
|
+
NotShown: true,
|
|
13
|
+
Cancelled: true,
|
|
14
|
+
OutOfAttempts: true
|
|
15
|
+
};
|
|
16
|
+
export const slipErrorCodeFor = (refusal) => {
|
|
17
|
+
switch (refusal) {
|
|
18
|
+
case "Blocked":
|
|
19
|
+
return "EFFECTS_MISMATCH";
|
|
20
|
+
case "NoUtxos":
|
|
21
|
+
return "INSUFFICIENT_FUNDS";
|
|
22
|
+
case "CannotJudge":
|
|
23
|
+
return "CANNOT_BALANCE";
|
|
24
|
+
case "UnreadableUtxos":
|
|
25
|
+
case "UnreadableAddresses":
|
|
26
|
+
case "NotShown":
|
|
27
|
+
case "Cancelled":
|
|
28
|
+
case "OutOfAttempts":
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* `reasons` is what the transaction actually does against what was declared,
|
|
34
|
+
* and `derived` is the whole of what it does, for the block to render. There is no way to carry on from one — a mismatch
|
|
35
|
+
* hard-blocks, with no override, no allowlist and no confirmation.
|
|
36
|
+
*/
|
|
37
|
+
export class CompletionError extends Data.TaggedError("CompletionError") {
|
|
38
|
+
get message() {
|
|
39
|
+
return this.detail;
|
|
40
|
+
}
|
|
41
|
+
get code() {
|
|
42
|
+
return slipErrorCodeFor(this.refusal);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export const refuse = (refusal, detail, extra = {}) => new CompletionError({
|
|
46
|
+
refusal,
|
|
47
|
+
detail,
|
|
48
|
+
...(extra.reasons === undefined ? {} : { reasons: extra.reasons }),
|
|
49
|
+
...(extra.derived === undefined ? {} : { derived: extra.derived }),
|
|
50
|
+
...(extra.cause === undefined ? {} : { cause: extra.cause })
|
|
51
|
+
});
|
|
52
|
+
//# sourceMappingURL=complete-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete-error.js","sourceRoot":"","sources":["../src/complete-error.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAsB7B;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA8C;IAC3E,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,IAAI;IACrB,mBAAmB,EAAE,IAAI;IACzB,WAAW,EAAE,IAAI;IACjB,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,IAAI;IACd,SAAS,EAAE,IAAI;IACf,aAAa,EAAE,IAAI;CACpB,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAA0B,EAA+B,EAAE;IAC1F,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,SAAS;YACZ,OAAO,kBAAkB,CAAA;QAC3B,KAAK,SAAS;YACZ,OAAO,oBAAoB,CAAA;QAC7B,KAAK,aAAa;YAChB,OAAO,gBAAgB,CAAA;QACzB,KAAK,iBAAiB,CAAC;QACvB,KAAK,qBAAqB,CAAC;QAC3B,KAAK,UAAU,CAAC;QAChB,KAAK,WAAW,CAAC;QACjB,KAAK,eAAe;YAClB,OAAO,SAAS,CAAA;IACpB,CAAC;AACH,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,OAAO,eAAgB,SAAQ,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAMrE;IACA,IAAa,OAAO;QAClB,OAAO,IAAI,CAAC,MAAM,CAAA;IACpB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACvC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,OAA0B,EAC1B,MAAc,EACd,QAA4G,EAAE,EAC7F,EAAE,CACnB,IAAI,eAAe,CAAC;IAClB,OAAO;IACP,MAAM;IACN,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IAClE,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IAClE,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;CAC7D,CAAC,CAAA"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The whole path: build against what the wallet holds, judge it with the
|
|
3
|
+
* verifier's own engine, sign, submit. When the funds move underneath, every
|
|
4
|
+
* one of those happens again — a rebuilt transaction is a different transaction,
|
|
5
|
+
* and asking for a signature on it without deriving its effects first would put
|
|
6
|
+
* a person's name on something nobody read.
|
|
7
|
+
*/
|
|
8
|
+
import type { Intent, Network } from "@cardano-slips/core";
|
|
9
|
+
import { type Effects } from "@cardano-slips/verifier";
|
|
10
|
+
import { Effect } from "effect";
|
|
11
|
+
import { type BalancingParameters } from "./balance.js";
|
|
12
|
+
import type { BalanceError } from "./balance-error.js";
|
|
13
|
+
import { type Cip30Api } from "./cip30.js";
|
|
14
|
+
import { type CompletionError } from "./complete-error.js";
|
|
15
|
+
import type { Derived } from "./derived.js";
|
|
16
|
+
import type { SigningError } from "./sign-error.js";
|
|
17
|
+
export type Attempt = Derived & {
|
|
18
|
+
/** Counting from one, so a rendered "attempt 2 of 3" reads as a person would say it. */
|
|
19
|
+
readonly number: number;
|
|
20
|
+
readonly transactionId: string;
|
|
21
|
+
};
|
|
22
|
+
/** Where the path has got to after the person agreed, for a screen that says so. */
|
|
23
|
+
export type Progress =
|
|
24
|
+
/** The wallet has been asked for a signature on this transaction. */
|
|
25
|
+
{
|
|
26
|
+
readonly _tag: "Signing";
|
|
27
|
+
readonly transactionId: string;
|
|
28
|
+
}
|
|
29
|
+
/** The witnesses are in the body and the wallet has been asked to submit it. */
|
|
30
|
+
| {
|
|
31
|
+
readonly _tag: "Submitting";
|
|
32
|
+
readonly transactionId: string;
|
|
33
|
+
}
|
|
34
|
+
/** The funds moved under the last transaction; attempt `number` of `of` is being built. */
|
|
35
|
+
| {
|
|
36
|
+
readonly _tag: "Rebuilding";
|
|
37
|
+
readonly number: number;
|
|
38
|
+
readonly of: number;
|
|
39
|
+
};
|
|
40
|
+
export type CompletionRequest = {
|
|
41
|
+
readonly api: Cip30Api;
|
|
42
|
+
/** What the endpoint declared, and what the transaction is judged against. */
|
|
43
|
+
readonly intent: Intent;
|
|
44
|
+
readonly network: Network;
|
|
45
|
+
readonly changeAddress: string;
|
|
46
|
+
readonly parameters: BalancingParameters;
|
|
47
|
+
readonly rewardBalance?: bigint;
|
|
48
|
+
/** Read once per attempt: a rebuilt transaction gets its own validity window. */
|
|
49
|
+
readonly now?: () => number;
|
|
50
|
+
/** How many times the transaction may be built. Beyond this the funds are moving faster than we can follow. */
|
|
51
|
+
readonly attempts?: number;
|
|
52
|
+
/** Called once per attempt, after the effects are derived and before the wallet is asked to sign. */
|
|
53
|
+
readonly onAttempt?: (attempt: Attempt) => void;
|
|
54
|
+
/**
|
|
55
|
+
* Resolves `true` once the person has pressed sign on this attempt, `false`
|
|
56
|
+
* if they turned it down. Asked again for every rebuilt transaction, because
|
|
57
|
+
* agreeing to one body is not agreeing to the next. Without it, showing the
|
|
58
|
+
* effects is taken as agreement.
|
|
59
|
+
*/
|
|
60
|
+
readonly confirm?: (attempt: Attempt) => Promise<boolean>;
|
|
61
|
+
readonly onProgress?: (progress: Progress) => void;
|
|
62
|
+
};
|
|
63
|
+
export type Receipt = {
|
|
64
|
+
readonly transactionId: string;
|
|
65
|
+
readonly effects: Effects;
|
|
66
|
+
/** How many transactions it took, which is how many times the funds moved plus one. */
|
|
67
|
+
readonly attempts: number;
|
|
68
|
+
};
|
|
69
|
+
type Failure = BalanceError | CompletionError | SigningError;
|
|
70
|
+
/**
|
|
71
|
+
* Completes the Slip, or says why not. A submission that failed because an
|
|
72
|
+
* input was spent is the one failure worth repeating: everything else either
|
|
73
|
+
* cannot be helped by a rebuild or is a person having said no.
|
|
74
|
+
*/
|
|
75
|
+
export declare const completeIntent: (request: CompletionRequest) => Effect.Effect<Receipt, Failure>;
|
|
76
|
+
export {};
|
|
77
|
+
//# sourceMappingURL=complete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../src/complete.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAOL,KAAK,OAAO,EAEb,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAA;AAGvC,OAAO,EAAiB,KAAK,mBAAmB,EAAE,MAAM,cAAc,CAAA;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,KAAK,QAAQ,EAAkC,MAAM,YAAY,CAAA;AAC1E,OAAO,EAAE,KAAK,eAAe,EAAU,MAAM,qBAAqB,CAAA;AAElE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAG3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAOnD,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG;IAC9B,wFAAwF;IACxF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAC/B,CAAA;AAED,oFAAoF;AACpF,MAAM,MAAM,QAAQ;AAClB,qEAAqE;AACnE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAAE;AAC9D,gFAAgF;GAC9E;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAAE;AACjE,2FAA2F;GACzF;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AAEjF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAA;IACtB,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAA;IACxC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,iFAAiF;IACjF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAC3B,+GAA+G;IAC/G,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,qGAAqG;IACrG,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IAC/C;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACzD,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAA;CACnD,CAAA;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,uFAAuF;IACvF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B,CAAA;AAED,KAAK,OAAO,GAAG,YAAY,GAAG,eAAe,GAAG,YAAY,CAAA;AAgL5D;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,SAAS,iBAAiB,KAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CA2CtF,CAAA"}
|
package/dist/complete.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { compare, decodeBech32, decodeTransaction, deriveAssets, deriveEffects, deriveLovelace } from "@cardano-slips/verifier";
|
|
2
|
+
import { Effect, Either } from "effect";
|
|
3
|
+
import { readOwnAddress } from "./address.js";
|
|
4
|
+
import { balanceIntent } from "./balance.js";
|
|
5
|
+
import { describeApiError, readApiError } from "./cip30.js";
|
|
6
|
+
import { refuse } from "./complete-error.js";
|
|
7
|
+
import { networkIdFor } from "./connect.js";
|
|
8
|
+
import { asResolvedInputs } from "./resolve.js";
|
|
9
|
+
import { signTransaction, submitTransaction } from "./sign.js";
|
|
10
|
+
import { readWalletUtxos } from "./utxo.js";
|
|
11
|
+
import { transactionIdOf } from "./witness.js";
|
|
12
|
+
/** Enough rebuilds to outlast an unlucky moment, few enough that nobody is asked forever. */
|
|
13
|
+
const defaultAttempts = 3;
|
|
14
|
+
const fromHex = (hex) => Uint8Array.from({ length: hex.length / 2 }, (_, index) => Number.parseInt(hex.slice(index * 2, index * 2 + 2), 16));
|
|
15
|
+
const walletUtxos = (api) => Effect.gen(function* () {
|
|
16
|
+
const answered = yield* Effect.tryPromise({
|
|
17
|
+
try: () => api.getUtxos(),
|
|
18
|
+
catch: (cause) => refuse("UnreadableUtxos", "The wallet could not say what it holds.", { cause })
|
|
19
|
+
});
|
|
20
|
+
// `null` is CIP-30's own answer for a wallet with nothing to give.
|
|
21
|
+
const hexes = answered ?? [];
|
|
22
|
+
const read = readWalletUtxos(hexes);
|
|
23
|
+
if (Either.isLeft(read)) {
|
|
24
|
+
return yield* Effect.fail(refuse("UnreadableUtxos", `The wallet's unspent outputs could not be read: ${read.left}`));
|
|
25
|
+
}
|
|
26
|
+
if (read.right.length === 0) {
|
|
27
|
+
return yield* Effect.fail(refuse("NoUtxos", "This wallet holds nothing to pay with."));
|
|
28
|
+
}
|
|
29
|
+
return read.right;
|
|
30
|
+
});
|
|
31
|
+
const addressesFrom = (api, method) => Effect.tryPromise({
|
|
32
|
+
try: () => api[method](),
|
|
33
|
+
catch: (cause) => {
|
|
34
|
+
const cip30 = readApiError(cause);
|
|
35
|
+
const said = cip30 === undefined ? String(cause) : describeApiError(cip30);
|
|
36
|
+
return refuse("UnreadableAddresses", `The wallet could not say which addresses are its own: ${said}`, { cause });
|
|
37
|
+
}
|
|
38
|
+
}).pipe(Effect.filterOrFail((answered) => Array.isArray(answered), () => refuse("UnreadableAddresses", `The wallet answered ${method} with something that is not a list.`)));
|
|
39
|
+
/**
|
|
40
|
+
* Every address the wallet vouches for: those CIP-30 lists, the change address,
|
|
41
|
+
* and the address of every output it said it holds. Read with the outputs on
|
|
42
|
+
* each attempt, since both can change when the funds move. One missing is read
|
|
43
|
+
* as a stranger's, and its value would be shown as someone else's. The outputs'
|
|
44
|
+
* addresses are ahead of the spec's list, until
|
|
45
|
+
* https://github.com/emmanuel-musau/cardano-slips/issues/186 brings it into line.
|
|
46
|
+
*/
|
|
47
|
+
const ownAddresses = (request, inputs) => Effect.gen(function* () {
|
|
48
|
+
const listed = [
|
|
49
|
+
...(yield* addressesFrom(request.api, "getUsedAddresses")),
|
|
50
|
+
...(yield* addressesFrom(request.api, "getUnusedAddresses")),
|
|
51
|
+
...(yield* addressesFrom(request.api, "getRewardAddresses"))
|
|
52
|
+
];
|
|
53
|
+
const network = networkIdFor(request.network);
|
|
54
|
+
const read = [];
|
|
55
|
+
for (const hex of listed) {
|
|
56
|
+
const address = readOwnAddress(hex);
|
|
57
|
+
if (Either.isLeft(address)) {
|
|
58
|
+
return yield* Effect.fail(refuse("UnreadableAddresses", `The wallet named an address of its own that cannot be read: ${address.left}`));
|
|
59
|
+
}
|
|
60
|
+
if (address.right.networkId !== undefined && address.right.networkId !== network) {
|
|
61
|
+
return yield* Effect.fail(refuse("UnreadableAddresses", "The wallet named an address on another network as its own."));
|
|
62
|
+
}
|
|
63
|
+
read.push(address.right.bytes);
|
|
64
|
+
}
|
|
65
|
+
const change = decodeBech32(request.changeAddress);
|
|
66
|
+
if (Either.isLeft(change)) {
|
|
67
|
+
return yield* Effect.fail(refuse("UnreadableAddresses", "The change address is not an address."));
|
|
68
|
+
}
|
|
69
|
+
return [...read, change.right.bytes, ...inputs.map((input) => input.address)];
|
|
70
|
+
});
|
|
71
|
+
/**
|
|
72
|
+
* One transaction, from the wallet's outputs to a verdict. The judging happens
|
|
73
|
+
* here rather than at the caller so that no path reaches `signTransaction`
|
|
74
|
+
* without having passed it.
|
|
75
|
+
*/
|
|
76
|
+
const buildAndJudge = (request, number) => Effect.gen(function* () {
|
|
77
|
+
const utxos = yield* walletUtxos(request.api);
|
|
78
|
+
const now = (request.now ?? Date.now)();
|
|
79
|
+
const built = yield* balanceIntent({
|
|
80
|
+
intent: request.intent,
|
|
81
|
+
network: request.network,
|
|
82
|
+
changeAddress: request.changeAddress,
|
|
83
|
+
utxos,
|
|
84
|
+
parameters: request.parameters,
|
|
85
|
+
...(request.rewardBalance === undefined ? {} : { rewardBalance: request.rewardBalance }),
|
|
86
|
+
now
|
|
87
|
+
});
|
|
88
|
+
const transaction = decodeTransaction(fromHex(built.cbor));
|
|
89
|
+
if (Either.isLeft(transaction)) {
|
|
90
|
+
return yield* Effect.fail(refuse("CannotJudge", `This transaction could not be read back: ${transaction.left.message}`));
|
|
91
|
+
}
|
|
92
|
+
const resolvedInputs = asResolvedInputs(utxos);
|
|
93
|
+
const derivation = {
|
|
94
|
+
transaction: transaction.right,
|
|
95
|
+
userAddresses: yield* ownAddresses(request, resolvedInputs),
|
|
96
|
+
resolvedInputs,
|
|
97
|
+
protocolParameters: request.parameters
|
|
98
|
+
};
|
|
99
|
+
const read = Either.all({
|
|
100
|
+
effects: deriveEffects(derivation),
|
|
101
|
+
lovelace: deriveLovelace(derivation),
|
|
102
|
+
assets: deriveAssets(derivation)
|
|
103
|
+
});
|
|
104
|
+
if (Either.isLeft(read)) {
|
|
105
|
+
return yield* Effect.fail(refuse("CannotJudge", `What this transaction does could not be worked out: ${read.left.message}`));
|
|
106
|
+
}
|
|
107
|
+
const derived = read.right;
|
|
108
|
+
const verdict = compare({
|
|
109
|
+
effects: derived.effects,
|
|
110
|
+
declared: request.intent,
|
|
111
|
+
changeAddress: request.changeAddress,
|
|
112
|
+
now: BigInt(now),
|
|
113
|
+
protocolParameters: request.parameters
|
|
114
|
+
});
|
|
115
|
+
if (Either.isLeft(verdict)) {
|
|
116
|
+
return yield* Effect.fail(refuse("CannotJudge", `This transaction could not be checked against what was declared: ${verdict.left.message}`));
|
|
117
|
+
}
|
|
118
|
+
if (verdict.right._tag === "mismatch") {
|
|
119
|
+
return yield* Effect.fail(refuse("Blocked", "This transaction does not do what the Slip said it would, so it will not be signed.", {
|
|
120
|
+
reasons: verdict.right.reasons,
|
|
121
|
+
derived
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
const transactionId = yield* transactionIdOf(built.cbor);
|
|
125
|
+
const attempt = { ...derived, number, transactionId };
|
|
126
|
+
// The caller is what puts these effects in front of a person. If that
|
|
127
|
+
// throws, the person has not seen them, so this fails closed rather than
|
|
128
|
+
// carrying on to a signature — and as a refusal rather than a stack trace.
|
|
129
|
+
yield* Effect.try({
|
|
130
|
+
try: () => request.onAttempt?.(attempt),
|
|
131
|
+
catch: (cause) => refuse("NotShown", "This transaction could not be shown, so it will not be signed.", { cause })
|
|
132
|
+
});
|
|
133
|
+
return { cbor: built.cbor, attempt };
|
|
134
|
+
});
|
|
135
|
+
/** A progress report is a courtesy to the screen; one that throws must not stop a submission already under way. */
|
|
136
|
+
const report = (request, progress) => {
|
|
137
|
+
try {
|
|
138
|
+
request.onProgress?.(progress);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// Nothing to do: the flow carries on, and the next state the screen is given corrects it.
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Completes the Slip, or says why not. A submission that failed because an
|
|
146
|
+
* input was spent is the one failure worth repeating: everything else either
|
|
147
|
+
* cannot be helped by a rebuild or is a person having said no.
|
|
148
|
+
*/
|
|
149
|
+
export const completeIntent = (request) => Effect.gen(function* () {
|
|
150
|
+
const allowed = Math.max(1, request.attempts ?? defaultAttempts);
|
|
151
|
+
for (let number = 1; number <= allowed; number += 1) {
|
|
152
|
+
const { attempt, cbor } = yield* buildAndJudge(request, number);
|
|
153
|
+
const { confirm } = request;
|
|
154
|
+
if (confirm !== undefined) {
|
|
155
|
+
const agreed = yield* Effect.tryPromise({
|
|
156
|
+
try: () => confirm(attempt),
|
|
157
|
+
catch: (cause) => refuse("NotShown", "This transaction could not be put to you, so it will not be signed.", { cause })
|
|
158
|
+
});
|
|
159
|
+
if (!agreed) {
|
|
160
|
+
return yield* Effect.fail(refuse("Cancelled", "The transaction was closed without signing."));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
report(request, { _tag: "Signing", transactionId: attempt.transactionId });
|
|
164
|
+
const signed = yield* signTransaction({
|
|
165
|
+
api: request.api,
|
|
166
|
+
transaction: cbor,
|
|
167
|
+
transactionId: attempt.transactionId
|
|
168
|
+
});
|
|
169
|
+
report(request, { _tag: "Submitting", transactionId: attempt.transactionId });
|
|
170
|
+
const submitted = yield* Effect.either(submitTransaction(request.api, signed));
|
|
171
|
+
if (Either.isRight(submitted)) {
|
|
172
|
+
return { transactionId: submitted.right, effects: attempt.effects, attempts: number };
|
|
173
|
+
}
|
|
174
|
+
if (submitted.left.refusal !== "InputsSpent") {
|
|
175
|
+
return yield* Effect.fail(submitted.left);
|
|
176
|
+
}
|
|
177
|
+
if (number < allowed)
|
|
178
|
+
report(request, { _tag: "Rebuilding", number: number + 1, of: allowed });
|
|
179
|
+
}
|
|
180
|
+
return yield* Effect.fail(refuse("OutOfAttempts", `The wallet's funds moved every time this was built, ${allowed} times over. Try again in a moment.`));
|
|
181
|
+
});
|
|
182
|
+
//# sourceMappingURL=complete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete.js","sourceRoot":"","sources":["../src/complete.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** What a transaction does, read from its own bytes: the part the comparison judges, and the figures a person is shown. */
|
|
2
|
+
import type { AssetEffects, Effects, LovelaceEffects } from "@cardano-slips/verifier";
|
|
3
|
+
export type Derived = {
|
|
4
|
+
readonly effects: Effects;
|
|
5
|
+
readonly lovelace: LovelaceEffects;
|
|
6
|
+
readonly assets: AssetEffects;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=derived.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derived.d.ts","sourceRoot":"","sources":["../src/derived.ts"],"names":[],"mappings":"AAAA,2HAA2H;AAC3H,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAErF,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;IAClC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;CAC9B,CAAA"}
|
package/dist/derived.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derived.js","sourceRoot":"","sources":["../src/derived.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The transaction preview, drawn from `4 · Anatomy` and `6 · Preview states` on
|
|
3
|
+
* the design sheet. Every figure is derived from the transaction; the claim is
|
|
4
|
+
* only the title it is held against. A mismatch removes the sign button rather
|
|
5
|
+
* than disabling it, and no prop brings it back.
|
|
6
|
+
*/
|
|
7
|
+
import type { Verdict } from "@cardano-slips/verifier";
|
|
8
|
+
import type { Derived } from "./derived.js";
|
|
9
|
+
import { type Row } from "./ledger.js";
|
|
10
|
+
export type EffectsPanelProps = {
|
|
11
|
+
/** What the card promised, restated so it can be compared with what follows. */
|
|
12
|
+
readonly claim: string;
|
|
13
|
+
/** The card's description, set beside the transaction when the two disagree. */
|
|
14
|
+
readonly description?: string;
|
|
15
|
+
/** The host that served the link, as a host only. Whether it is verified is the identity chip's to say. */
|
|
16
|
+
readonly origin?: string;
|
|
17
|
+
readonly derived: Derived;
|
|
18
|
+
/** The verifier's own verdict. Required, so no caller renders a match by leaving the reasons out. */
|
|
19
|
+
readonly verdict: Verdict;
|
|
20
|
+
/** Read once a second for the countdown. */
|
|
21
|
+
readonly clock?: () => number;
|
|
22
|
+
readonly onSign?: () => void;
|
|
23
|
+
readonly onCancel?: () => void;
|
|
24
|
+
readonly onRebuild?: () => void;
|
|
25
|
+
/** "Report this link" is offered only where there is somewhere to send the report. */
|
|
26
|
+
readonly onReport?: () => void;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Past eight rows each group folds to its header and a count. A group holding
|
|
30
|
+
* a marked row never starts folded: the one thing the block points at is not
|
|
31
|
+
* something a person should have to open.
|
|
32
|
+
*/
|
|
33
|
+
export declare const Ledger: ({ rows }: {
|
|
34
|
+
readonly rows: ReadonlyArray<Row>;
|
|
35
|
+
}) => React.JSX.Element;
|
|
36
|
+
export declare const EffectsPanel: ({ claim, description, origin, derived, verdict, clock, onSign, onCancel, onRebuild, onReport }: EffectsPanelProps) => React.JSX.Element;
|
|
37
|
+
//# sourceMappingURL=effects-panel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effects-panel.d.ts","sourceRoot":"","sources":["../src/effects-panel.tsx"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AAGtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE3C,OAAO,EAWL,KAAK,GAAG,EACT,MAAM,aAAa,CAAA;AAEpB,MAAM,MAAM,iBAAiB,GAAG;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,gFAAgF;IAChF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,2GAA2G;IAC3G,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,qGAAqG;IACrG,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,4CAA4C;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,MAAM,CAAA;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IAC/B,sFAAsF;IACtF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CAC/B,CAAA;AA8DD;;;;GAIG;AACH,eAAO,MAAM,MAAM,GAAI,UAAU;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,GAAG,CAAC,CAAA;CAAE,KAAG,KAAK,CAAC,GAAG,CAAC,OA0BlF,CAAA;AA2FD,eAAO,MAAM,YAAY,GAAI,gGAW1B,iBAAiB,KAAG,KAAK,CAAC,GAAG,CAAC,OAkJhC,CAAA"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useId, useState } from "react";
|
|
4
|
+
import { formatCountdown, secondsLeft } from "./explain.js";
|
|
5
|
+
import { blockedLine, evidenceOf, groupsOf, headlineOf, isCollapsed, isGrouped, ledgerOf, matchLine, rawLines } from "./ledger.js";
|
|
6
|
+
/** Under this, the countdown leaves the meta row and takes the headline's place (state f). */
|
|
7
|
+
const expiringUnder = 60;
|
|
8
|
+
const groupNames = {
|
|
9
|
+
arriving: "Arriving",
|
|
10
|
+
leaving: "Leaving",
|
|
11
|
+
unmoved: "No value moved"
|
|
12
|
+
};
|
|
13
|
+
const markWords = { "not-in-the-link": "Not in the link", "not-as-the-link-says": "Not as the link says" };
|
|
14
|
+
const chipWords = { refundable: "Refundable", "as-stated": "As stated" };
|
|
15
|
+
const useNow = (clock) => {
|
|
16
|
+
const [now, setNow] = useState(clock);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
const timer = setInterval(() => setNow(clock()), 1000);
|
|
19
|
+
return () => clearInterval(timer);
|
|
20
|
+
}, [clock]);
|
|
21
|
+
return now;
|
|
22
|
+
};
|
|
23
|
+
const LedgerRow = ({ row }) => (_jsxs("div", { className: "slip-panel__row", "data-mark": row.mark, children: [_jsxs("div", { className: "slip-panel__row-name", children: [_jsxs("div", { className: "slip-panel__row-label", children: [_jsx("span", { className: "slip-panel__label", children: row.label }), row.chip === undefined ? undefined : (_jsx("span", { className: "slip-panel__chip", "data-chip": row.chip, children: chipWords[row.chip] })), row.mark === undefined ? undefined : (_jsx("span", { className: "slip-panel__chip", "data-chip": "mark", children: markWords[row.mark] }))] }), row.detail === undefined ? undefined : _jsx("span", { className: "slip-panel__detail", children: row.detail })] }), _jsxs("div", { className: "slip-panel__amounts", children: [row.identifier === undefined ? undefined : _jsx("span", { className: "slip-panel__identifier", children: row.identifier }), row.amounts.map((amount, index) => (_jsx("span", { className: "slip-panel__amount", "data-tone": amount.tone, children: amount.text }, index)))] }), row.note === undefined ? undefined : _jsx("p", { className: "slip-panel__note", children: row.note })] }));
|
|
24
|
+
const Rows = ({ rows }) => (_jsx("div", { className: "slip-panel__ledger", children: rows.map((row) => (_jsx(LedgerRow, { row: row }, row.key))) }));
|
|
25
|
+
/**
|
|
26
|
+
* Past eight rows each group folds to its header and a count. A group holding
|
|
27
|
+
* a marked row never starts folded: the one thing the block points at is not
|
|
28
|
+
* something a person should have to open.
|
|
29
|
+
*/
|
|
30
|
+
export const Ledger = ({ rows }) => {
|
|
31
|
+
if (!isGrouped(rows))
|
|
32
|
+
return _jsx(Rows, { rows: rows });
|
|
33
|
+
const collapsed = isCollapsed(rows);
|
|
34
|
+
return (_jsx("div", { className: "slip-panel__groups", children: groupsOf(rows).map(({ group, rows: inGroup }) => collapsed ? (_jsxs("details", { className: "slip-panel__group", open: inGroup.some((row) => row.mark !== undefined) || undefined, children: [_jsxs("summary", { className: "slip-panel__group-name", children: [groupNames[group], " \u00B7 ", inGroup.length] }), _jsx(Rows, { rows: inGroup })] }, group)) : (_jsxs("div", { className: "slip-panel__group", children: [_jsx("p", { className: "slip-panel__group-name", children: groupNames[group] }), _jsx(Rows, { rows: inGroup })] }, group))) }));
|
|
35
|
+
};
|
|
36
|
+
const Raw = ({ derived }) => (_jsx("pre", { className: "slip-panel__raw-lines", children: rawLines(derived).join("\n") }));
|
|
37
|
+
const Countdown = ({ seconds }) => (_jsx("span", { suppressHydrationWarning: true, children: formatCountdown(seconds) }));
|
|
38
|
+
const Blocked = ({ claim, description, derived, reasons, onCancel, onReport }) => {
|
|
39
|
+
const [rawOpen, setRawOpen] = useState(false);
|
|
40
|
+
const title = useId();
|
|
41
|
+
const rows = ledgerOf(derived, reasons);
|
|
42
|
+
return (_jsxs("section", { className: "slip-root slip-panel", "data-blocked": "", "aria-labelledby": title, children: [_jsxs("div", { className: "slip-panel__claim", role: "alert", children: [_jsx("p", { className: "slip-panel__kicker", "data-tone": "bad", children: "Signing blocked" }), _jsx("h2", { className: "slip-panel__title", id: title, children: "This transaction doesn't do what the link says" }), _jsx("p", { className: "slip-panel__lead", children: blockedLine(reasons) })] }), _jsxs("div", { className: "slip-panel__compare", children: [_jsxs("div", { className: "slip-panel__side", children: [_jsx("p", { className: "slip-panel__kicker", children: "The link claims" }), _jsx("p", { className: "slip-panel__claimed", children: claim }), description === undefined ? undefined : _jsx("p", { className: "slip-panel__note", children: description })] }), _jsxs("div", { className: "slip-panel__side", "data-tone": "bad", children: [_jsx("p", { className: "slip-panel__kicker", "data-tone": "bad", children: "The transaction does" }), reasons.map((reason, index) => {
|
|
43
|
+
const { figure, lines } = evidenceOf(reason, derived);
|
|
44
|
+
return (_jsxs("div", { className: "slip-panel__evidence", children: [figure === undefined ? undefined : _jsx("p", { className: "slip-panel__evidence-figure", children: figure }), lines.map((line) => (_jsx("p", { className: "slip-panel__detail", children: line }, line)))] }, index));
|
|
45
|
+
})] })] }), _jsx(Ledger, { rows: rows }), rawOpen ? _jsx(Raw, { derived: derived }) : undefined, _jsxs("div", { className: "slip-panel__exits", children: [_jsx("button", { type: "button", className: "slip-panel__button", "data-kind": "close", onClick: onCancel, children: "Close without signing" }), _jsxs("div", { className: "slip-panel__quiet", children: [_jsx("button", { type: "button", className: "slip-panel__button", "data-kind": "quiet", "aria-expanded": rawOpen, onClick: () => setRawOpen((open) => !open), children: rawOpen ? "Hide raw transaction" : "Show raw transaction" }), onReport === undefined ? undefined : (_jsx("button", { type: "button", className: "slip-panel__button", "data-kind": "quiet", onClick: onReport, children: "Report this link" }))] })] })] }));
|
|
46
|
+
};
|
|
47
|
+
export const EffectsPanel = ({ claim, description, origin, derived, verdict, clock = Date.now, onSign, onCancel, onRebuild, onReport }) => {
|
|
48
|
+
const now = useNow(clock);
|
|
49
|
+
const [rawOpen, setRawOpen] = useState(false);
|
|
50
|
+
const title = useId();
|
|
51
|
+
if (verdict._tag === "mismatch") {
|
|
52
|
+
return (_jsx(Blocked, { claim: claim, derived: derived, reasons: verdict.reasons, ...(description === undefined ? {} : { description }), ...(onCancel === undefined ? {} : { onCancel }), ...(onReport === undefined ? {} : { onReport }) }));
|
|
53
|
+
}
|
|
54
|
+
const rows = ledgerOf(derived);
|
|
55
|
+
const until = derived.effects.validity.validUntil;
|
|
56
|
+
const seconds = until === null ? undefined : secondsLeft(until.time, BigInt(now));
|
|
57
|
+
if (seconds === 0) {
|
|
58
|
+
return (_jsxs("section", { className: "slip-root slip-panel", "data-expired": "", "aria-labelledby": title, children: [_jsxs("div", { className: "slip-panel__claim", children: [_jsx("p", { className: "slip-panel__kicker", "data-tone": "warn", children: "Expired" }), _jsx("h2", { className: "slip-panel__title", id: title, children: "This transaction ran out of time" }), _jsx("p", { className: "slip-panel__lead", children: "Nothing was signed and nothing left your wallet. Building a new one takes a second, and the amounts will be checked again." })] }), _jsx("div", { className: "slip-panel__stale", children: _jsx(Ledger, { rows: rows }) }), _jsxs("div", { className: "slip-panel__buttons", children: [_jsx("button", { type: "button", className: "slip-panel__button", "data-kind": "cancel", onClick: onCancel, children: "Cancel" }), _jsx("button", { type: "button", className: "slip-panel__button", "data-kind": "primary", onClick: onRebuild, children: "Build a new transaction" })] })] }));
|
|
59
|
+
}
|
|
60
|
+
const headline = headlineOf(derived);
|
|
61
|
+
const expiring = seconds !== undefined && seconds < expiringUnder;
|
|
62
|
+
return (_jsxs("section", { className: "slip-root slip-panel", "aria-labelledby": title, children: [_jsxs("div", { className: "slip-panel__claim", children: [_jsx("p", { className: "slip-panel__kicker", children: "What you're signing" }), _jsx("h2", { className: "slip-panel__title", id: title, children: claim }), origin === undefined ? undefined : _jsx("span", { className: "slip-panel__origin", children: origin })] }), expiring ? (_jsxs("div", { className: "slip-panel__expiring", role: "timer", children: [_jsxs("div", { className: "slip-panel__expiring-head", children: [_jsx("span", { children: "This transaction expires in" }), _jsx("span", { className: "slip-panel__expiring-clock", children: _jsx(Countdown, { seconds: seconds }) })] }), _jsx("div", { className: "slip-panel__bar", "aria-hidden": "true", children: _jsx("span", { className: "slip-panel__bar-fill", suppressHydrationWarning: true, style: { width: `${(seconds / expiringUnder) * 100}%` } }) }), _jsx("p", { className: "slip-panel__note", children: "After that the amounts could be stale, so we'll build a fresh one." })] })) : (_jsxs("div", { className: "slip-panel__headline", children: [_jsxs("div", { className: "slip-panel__figure", children: [_jsx("span", { className: "slip-panel__note", children: headline.label }), _jsx("span", { className: "slip-panel__figure-amount", "data-tone": headline.tone, children: headline.amount }), headline.fee === undefined ? undefined : _jsx("span", { className: "slip-panel__note", children: headline.fee })] }), headline.held === undefined ? undefined : (_jsxs(_Fragment, { children: [_jsx("span", { className: "slip-panel__rule", "aria-hidden": "true" }), _jsxs("div", { className: "slip-panel__figure", children: [_jsx("span", { className: "slip-panel__note", children: headline.held.label }), _jsx("span", { className: "slip-panel__figure-amount", "data-tone": headline.held.tone, children: headline.held.amount })] })] }))] })), _jsx(Ledger, { rows: rows }), expiring || seconds === undefined ? undefined : (_jsxs("div", { className: "slip-panel__expiry", children: [_jsx("span", { className: "slip-panel__note", children: "Expires in" }), _jsx("span", { className: "slip-panel__clock", children: _jsx(Countdown, { seconds: seconds }) })] })), _jsxs("p", { className: "slip-panel__verdict", children: [_jsx("span", { className: "slip-panel__tick", "aria-hidden": "true", children: "\u2713" }), _jsx("span", { children: matchLine(derived, rows) })] }), _jsxs("div", { className: "slip-panel__buttons", children: [_jsx("button", { type: "button", className: "slip-panel__button", "data-kind": "cancel", onClick: onCancel, children: "Cancel" }), _jsx("button", { type: "button", className: "slip-panel__button", "data-kind": "primary", onClick: onSign, children: "Sign transaction" })] }), _jsxs("div", { className: "slip-panel__raw", children: [_jsxs("button", { type: "button", className: "slip-panel__raw-toggle", "aria-expanded": rawOpen, onClick: () => setRawOpen((open) => !open), children: [_jsx("span", { "aria-hidden": "true", children: rawOpen ? "▾" : "▸" }), _jsx("span", { children: "Raw transaction" })] }), rawOpen ? _jsx(Raw, { derived: derived }) : undefined] })] }));
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=effects-panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effects-panel.js","sourceRoot":"","sources":["../src/effects-panel.tsx"],"names":[],"mappings":"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"}
|