@avow-finance/verifier 0.0.0-stage → 0.1.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.
Files changed (63) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +112 -2
  3. package/dist/accept.d.ts +170 -0
  4. package/dist/accept.d.ts.map +1 -0
  5. package/dist/accept.js +268 -0
  6. package/dist/accept.js.map +1 -0
  7. package/dist/authorization.d.ts +65 -0
  8. package/dist/authorization.d.ts.map +1 -0
  9. package/dist/authorization.js +192 -0
  10. package/dist/authorization.js.map +1 -0
  11. package/dist/chain.d.ts +160 -0
  12. package/dist/chain.d.ts.map +1 -0
  13. package/dist/chain.js +72 -0
  14. package/dist/chain.js.map +1 -0
  15. package/dist/consent.d.ts +69 -0
  16. package/dist/consent.d.ts.map +1 -0
  17. package/dist/consent.js +98 -0
  18. package/dist/consent.js.map +1 -0
  19. package/dist/dependency.d.ts +252 -0
  20. package/dist/dependency.d.ts.map +1 -0
  21. package/dist/dependency.js +353 -0
  22. package/dist/dependency.js.map +1 -0
  23. package/dist/disclosure.d.ts +88 -0
  24. package/dist/disclosure.d.ts.map +1 -0
  25. package/dist/disclosure.js +210 -0
  26. package/dist/disclosure.js.map +1 -0
  27. package/dist/index.d.ts +17 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +17 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/issued.d.ts +5 -0
  32. package/dist/issued.d.ts.map +1 -0
  33. package/dist/issued.js +24 -0
  34. package/dist/issued.js.map +1 -0
  35. package/dist/lock-abi.d.ts +471 -0
  36. package/dist/lock-abi.d.ts.map +1 -0
  37. package/dist/lock-abi.js +452 -0
  38. package/dist/lock-abi.js.map +1 -0
  39. package/dist/nonce.d.ts +3 -0
  40. package/dist/nonce.d.ts.map +1 -0
  41. package/dist/nonce.js +4 -0
  42. package/dist/nonce.js.map +1 -0
  43. package/dist/references.d.ts +38 -0
  44. package/dist/references.d.ts.map +1 -0
  45. package/dist/references.js +93 -0
  46. package/dist/references.js.map +1 -0
  47. package/dist/report.d.ts +128 -0
  48. package/dist/report.d.ts.map +1 -0
  49. package/dist/report.js +155 -0
  50. package/dist/report.js.map +1 -0
  51. package/dist/signing.d.ts +47 -0
  52. package/dist/signing.d.ts.map +1 -0
  53. package/dist/signing.js +51 -0
  54. package/dist/signing.js.map +1 -0
  55. package/dist/tempo.d.ts +70 -0
  56. package/dist/tempo.d.ts.map +1 -0
  57. package/dist/tempo.js +341 -0
  58. package/dist/tempo.js.map +1 -0
  59. package/dist/verify.d.ts +65 -0
  60. package/dist/verify.d.ts.map +1 -0
  61. package/dist/verify.js +36 -0
  62. package/dist/verify.js.map +1 -0
  63. package/package.json +34 -3
@@ -0,0 +1,160 @@
1
+ import { type Charge, type ChargeKind, type LockTiming, type ObservedTransfer, type RailState, type Side } from '@avow-finance/spec';
2
+ import type { Address, Hex } from 'viem';
3
+ /** What a lock stores for one side of a commitment. */
4
+ export interface LockedBacking {
5
+ state: RailState;
6
+ /** The lock's one token. */
7
+ token: Address;
8
+ /** Base units of the token, as funded. */
9
+ amount: bigint;
10
+ /** What the lock still holds for the commitment, less any part already returned or paid. */
11
+ held: bigint;
12
+ /** The supplier's payout address, copied from the approval. */
13
+ payee: Address;
14
+ /** The supplier's account, which consents to releases. */
15
+ supplier: Address;
16
+ /** The supplier's signing key, which accepts the reserve and reports charges. */
17
+ supplierSigner: Address;
18
+ freeCancelBy: bigint;
19
+ acceptBy: bigint;
20
+ chargeDeadline: bigint;
21
+ contestWindow: bigint;
22
+ releaseDate: bigint;
23
+ charges: readonly Charge[];
24
+ day90SupplierShareBps: number;
25
+ arbiter: Address;
26
+ termsHash: Hex;
27
+ mandateHash: Hex;
28
+ /** The digest of Avow's approval the lock took, which the supplier's acceptance names. */
29
+ approvalHash: Hex;
30
+ /** The key that funded the reserve, or the zero address when the account's root key did. */
31
+ fundingKey: Address;
32
+ /** Every report ever filed on the commitment, which a release consent names. */
33
+ reportCount: number;
34
+ /** The kind of charge the latest report names, or null before any report is filed. */
35
+ reportKind: ChargeKind | null;
36
+ /** The latest report's amount in base units of the token, or zero before any report is filed. */
37
+ reportAmount: bigint;
38
+ /**
39
+ * Whether a report stands on the commitment, filed and not withdrawn. The lock takes no other
40
+ * report while one does, and on an accepted commitment it's open, waiting for Avow's answer.
41
+ */
42
+ hasReport: boolean;
43
+ /**
44
+ * Whether the business has contested a charge on the commitment. The contest stays on record
45
+ * when the supplier withdraws the report, so the lock takes no second one, and a later report
46
+ * pauses at once.
47
+ */
48
+ contested: boolean;
49
+ /** When a confirmed charge became pending and its contest window opened, or zero if one never did. */
50
+ chargeStart: bigint;
51
+ /** When the charge paused, which days 30 and 90 count from, or zero if it never paused. */
52
+ pausedAt: bigint;
53
+ /** Whether a ruling has been posted on the commitment. */
54
+ hasRuling: boolean;
55
+ }
56
+ /** A contest a lock logged, as the `Paused` event its contest wrote shows it. */
57
+ export interface ObservedContest {
58
+ commitmentId: Hex;
59
+ side: Side;
60
+ /** The reason's code, which `contestReasonOf` reads as one of the six reasons or as none. */
61
+ reasonCode: number;
62
+ /** The hash of the business's statement, which the event logs as its `evidenceHash`. */
63
+ statementHash: Hex;
64
+ /** When the lock paused the charge, which days 30 and 90 count from. */
65
+ pausedAt: bigint;
66
+ }
67
+ /** A contest read from the chain, with where it landed and the report it named. */
68
+ export interface ContestOnChain extends ObservedContest {
69
+ /** The block the contest landed in. */
70
+ blockNumber: bigint;
71
+ /**
72
+ * Whether that block is at or below the chain's finalized block and is the chain's block at its
73
+ * height, so no reorganization can drop the contest.
74
+ */
75
+ finalized: boolean;
76
+ /**
77
+ * The report the contest named, as the lock held it at the end of the contest's block: its
78
+ * number, which the lock checked the contest against, its kind and its amount in base units.
79
+ */
80
+ report: {
81
+ number: number;
82
+ kind: ChargeKind;
83
+ amount: bigint;
84
+ };
85
+ }
86
+ /** The most reports a lock takes for one commitment, which the spec defines for every package. */
87
+ export { MAX_REPORTS } from '@avow-finance/spec';
88
+ export interface LockInfo {
89
+ /** True when Avow's factory, as the reader was set up with it, created the lock. */
90
+ fromFactory: boolean;
91
+ /** The business account that owns the lock. */
92
+ account: Address;
93
+ /** The token the lock holds reserves in. */
94
+ token: Address;
95
+ /** The timing the factory fixed in the lock. */
96
+ timing: LockTiming;
97
+ }
98
+ export interface AgentKeyInfo {
99
+ /** False once the key is revoked. */
100
+ active: boolean;
101
+ /** When the key stops working, or null when it doesn't expire. */
102
+ expiry: bigint | null;
103
+ /** The mandate hash bound into the key's authorization, or null when there is none. */
104
+ witness: Hex | null;
105
+ }
106
+ /**
107
+ * Everything the verifier reads from the chain. Nothing here comes from Avow, so a supplier's
108
+ * check doesn't depend on Avow's database. `tempoChainReader` reads Tempo, and `MemoryChain` stands
109
+ * in for it in tests. A supplier trusts whichever node it reads through, so it picks that node.
110
+ */
111
+ export interface ChainReader {
112
+ readonly chainId: number;
113
+ lock(lock: Address): Promise<LockInfo | null>;
114
+ backing(lock: Address, commitmentId: Hex, side: Side): Promise<LockedBacking | null>;
115
+ /**
116
+ * A key on an account, with the mandate hash logged in the transaction that authorized it.
117
+ * Returns null when the account has no such key.
118
+ */
119
+ agentKey(account: Address, key: Address, authorizedIn: Hex): Promise<AgentKeyInfo | null>;
120
+ /**
121
+ * Whether the account's root key or one of its admin keys signed the digest, in the keychain
122
+ * envelope Tempo requires. On Tempo this asks the chain's own signature verifier.
123
+ */
124
+ isAccountSignature(account: Address, digest: Hex, signature: Hex): Promise<boolean>;
125
+ /**
126
+ * The log at one index of one transaction, decoded as a TIP-20 `TransferWithMemo` event when it
127
+ * is one, with whether the transaction succeeded and whether its block is finalized. Returns
128
+ * null when the chain has no such transaction or log. Nothing is read from calldata.
129
+ */
130
+ transfer(transactionHash: Hex, logIndex: number): Promise<ObservedTransfer | null>;
131
+ /**
132
+ * The contest of one side of a commitment that one transaction carried, from the `Paused` event
133
+ * the lock logged with a contest as its cause, with whether its block is final and the report it
134
+ * named. Returns null when the chain has no such transaction, when it failed, or when it holds no
135
+ * contest of that side from that lock.
136
+ */
137
+ contest(lock: Address, commitmentId: Hex, side: Side, transactionHash: Hex): Promise<ContestOnChain | null>;
138
+ }
139
+ /** A chain reader held in memory, for tests and dry runs. */
140
+ export declare class MemoryChain implements ChainReader {
141
+ #private;
142
+ readonly chainId: number;
143
+ constructor(chainId: number);
144
+ setLock(lock: Address, info: LockInfo): void;
145
+ setBacking(lock: Address, commitmentId: Hex, side: Side, backing: LockedBacking | null): void;
146
+ /** Records a key. With `authorizedIn`, the witness reads back only for that transaction. */
147
+ setAgentKey(account: Address, key: Address, info: AgentKeyInfo, authorizedIn?: Hex): void;
148
+ /** Records what the chain holds at one log index of one transaction. */
149
+ setTransfer(seen: ObservedTransfer): void;
150
+ /** Records a contest a successful transaction carried to a lock. */
151
+ setContest(lock: Address, transactionHash: Hex, contest: ContestOnChain): void;
152
+ addAdminKey(account: Address, key: Address): void;
153
+ lock(lock: Address): Promise<LockInfo | null>;
154
+ backing(lock: Address, commitmentId: Hex, side: Side): Promise<LockedBacking | null>;
155
+ agentKey(account: Address, key: Address, authorizedIn: Hex): Promise<AgentKeyInfo | null>;
156
+ isAccountSignature(account: Address, digest: Hex, signature: Hex): Promise<boolean>;
157
+ transfer(transactionHash: Hex, logIndex: number): Promise<ObservedTransfer | null>;
158
+ contest(lock: Address, commitmentId: Hex, side: Side, transactionHash: Hex): Promise<ContestOnChain | null>;
159
+ }
160
+ //# sourceMappingURL=chain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain.d.ts","sourceRoot":"","sources":["../src/chain.ts"],"names":[],"mappings":"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"}
package/dist/chain.js ADDED
@@ -0,0 +1,72 @@
1
+ import { keychainSignatureCheck, } from '@avow-finance/spec';
2
+ /** The most reports a lock takes for one commitment, which the spec defines for every package. */
3
+ export { MAX_REPORTS } from '@avow-finance/spec';
4
+ /** A chain reader held in memory, for tests and dry runs. */
5
+ export class MemoryChain {
6
+ chainId;
7
+ #locks = new Map();
8
+ #backings = new Map();
9
+ #keys = new Map();
10
+ #admins = new Set();
11
+ #transfers = new Map();
12
+ #contests = new Map();
13
+ #check = keychainSignatureCheck((account, key) => this.#admins.has(`${account.toLowerCase()}:${key.toLowerCase()}`));
14
+ constructor(chainId) {
15
+ this.chainId = chainId;
16
+ }
17
+ setLock(lock, info) {
18
+ this.#locks.set(lock.toLowerCase(), info);
19
+ }
20
+ setBacking(lock, commitmentId, side, backing) {
21
+ const key = `${lock.toLowerCase()}:${commitmentId.toLowerCase()}:${side}`;
22
+ if (backing)
23
+ this.#backings.set(key, backing);
24
+ else
25
+ this.#backings.delete(key);
26
+ }
27
+ /** Records a key. With `authorizedIn`, the witness reads back only for that transaction. */
28
+ setAgentKey(account, key, info, authorizedIn) {
29
+ this.#keys.set(`${account.toLowerCase()}:${key.toLowerCase()}`, {
30
+ ...info,
31
+ authorizedIn: authorizedIn ?? null,
32
+ });
33
+ }
34
+ /** Records what the chain holds at one log index of one transaction. */
35
+ setTransfer(seen) {
36
+ this.#transfers.set(`${seen.transactionHash.toLowerCase()}:${seen.logIndex}`, seen);
37
+ }
38
+ /** Records a contest a successful transaction carried to a lock. */
39
+ setContest(lock, transactionHash, contest) {
40
+ const { commitmentId, side } = contest;
41
+ this.#contests.set(contestKey(lock, commitmentId, side, transactionHash), contest);
42
+ }
43
+ addAdminKey(account, key) {
44
+ this.#admins.add(`${account.toLowerCase()}:${key.toLowerCase()}`);
45
+ }
46
+ async lock(lock) {
47
+ return this.#locks.get(lock.toLowerCase()) ?? null;
48
+ }
49
+ async backing(lock, commitmentId, side) {
50
+ return this.#backings.get(`${lock.toLowerCase()}:${commitmentId.toLowerCase()}:${side}`) ?? null;
51
+ }
52
+ async agentKey(account, key, authorizedIn) {
53
+ const stored = this.#keys.get(`${account.toLowerCase()}:${key.toLowerCase()}`);
54
+ if (!stored)
55
+ return null;
56
+ const { authorizedIn: tx, ...info } = stored;
57
+ const sameTx = tx === null || tx.toLowerCase() === authorizedIn.toLowerCase();
58
+ return sameTx ? info : { ...info, witness: null };
59
+ }
60
+ async isAccountSignature(account, digest, signature) {
61
+ return this.#check({ signer: account, digest, signature });
62
+ }
63
+ async transfer(transactionHash, logIndex) {
64
+ return this.#transfers.get(`${transactionHash.toLowerCase()}:${logIndex}`) ?? null;
65
+ }
66
+ async contest(lock, commitmentId, side, transactionHash) {
67
+ return this.#contests.get(contestKey(lock, commitmentId, side, transactionHash)) ?? null;
68
+ }
69
+ }
70
+ /** One side of one commitment's contest in one transaction to one lock, as a map's key. */
71
+ const contestKey = (lock, commitmentId, side, transactionHash) => `${lock.toLowerCase()}:${commitmentId.toLowerCase()}:${side}:${transactionHash.toLowerCase()}`;
72
+ //# sourceMappingURL=chain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain.js","sourceRoot":"","sources":["../src/chain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import { type AvowDomain, type HashSigner, type RailToken, type ReasonCode, type ReleaseConsent, type ReleaseReason, type Signed } from '@avow-finance/spec';
2
+ import { type Address, type Hex } from 'viem';
3
+ import { type ChainReader } from './chain.js';
4
+ import { type Disclosure } from './disclosure.js';
5
+ export interface ConsentConfig {
6
+ chainId: number;
7
+ /** The supplier's account, whose root key or admin key signs the consent. */
8
+ account: Address;
9
+ /** Tokens the supplier accepts, used to show the amount the consent releases. */
10
+ acceptedTokens: readonly RailToken[];
11
+ }
12
+ export interface ConsentDeps {
13
+ config: ConsentConfig;
14
+ chain: ChainReader;
15
+ }
16
+ export interface ReleaseConsentRequest {
17
+ lock: Address;
18
+ commitmentId: Hex;
19
+ reason: ReleaseReason;
20
+ evidenceHash: Hex;
21
+ /**
22
+ * The report count the consent names, the commitment's current count when left out. A later
23
+ * count makes the consent a preauthorization, which the signer has to confirm.
24
+ */
25
+ reportCount?: number;
26
+ /** When the consent stops working. A supplier keeps its consents short. */
27
+ expiry: bigint;
28
+ now: bigint;
29
+ /** The consent's nonce, a fresh random one when left out. */
30
+ nonce?: bigint;
31
+ }
32
+ export interface ReadyReleaseConsent {
33
+ ok: true;
34
+ consent: ReleaseConsent;
35
+ domain: AvowDomain;
36
+ /** The digest the supplier account signs, in Tempo's keychain envelope. */
37
+ digest: Hex;
38
+ /** The account that has to sign, the supplier's own. */
39
+ supplierAccount: Address;
40
+ /** What to show the person who approves the signature, before signing. */
41
+ disclosure: Disclosure;
42
+ }
43
+ export type PreparedReleaseConsent = ReadyReleaseConsent | {
44
+ ok: false;
45
+ reason: ReasonCode;
46
+ };
47
+ /**
48
+ * The supported way for a supplier account to get a release consent to sign. It reads the
49
+ * commitment from the lock and refuses a commitment that isn't this supplier's, one the lock
50
+ * wouldn't release on consent, a consent that has already expired, and a report count the
51
+ * commitment has passed or can never reach. A count above the current one is preauthorization,
52
+ * and the disclosure says so. What it returns is frozen, and `signReleaseConsent` signs nothing
53
+ * else. The lock takes a correctly signed consent however it was built.
54
+ */
55
+ export declare function prepareReleaseConsent(request: ReleaseConsentRequest, deps: ConsentDeps): Promise<PreparedReleaseConsent>;
56
+ /**
57
+ * Signs a consent as the supplier account, with its root key or an admin key, once the person has
58
+ * seen its disclosure. A consent that names a later report count than the commitment has also
59
+ * needs `preauthorize: true`. It signs only the object `prepareReleaseConsent` returned, which is
60
+ * frozen, so a copy or an edit of it throws. It also throws when the confirmation doesn't match,
61
+ * or when the signature isn't one the chain accepts for the supplier account.
62
+ */
63
+ export declare function signReleaseConsent(prepared: ReadyReleaseConsent, key: HashSigner, confirmation: {
64
+ disclosureId: Hex;
65
+ preauthorize?: boolean;
66
+ }, deps: {
67
+ chain: ChainReader;
68
+ }): Promise<Signed<ReleaseConsent>>;
69
+ //# sourceMappingURL=consent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent.d.ts","sourceRoot":"","sources":["../src/consent.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EAEf,KAAK,UAAU,EACf,KAAK,SAAS,EAEd,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,aAAa,EAElB,KAAK,MAAM,EAGZ,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,GAAG,EAA+B,MAAM,MAAM,CAAA;AAC1E,OAAO,EAAE,KAAK,WAAW,EAAe,MAAM,YAAY,CAAA;AAC1D,OAAO,EAAE,KAAK,UAAU,EAAyC,MAAM,iBAAiB,CAAA;AAKxF,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,6EAA6E;IAC7E,OAAO,EAAE,OAAO,CAAA;IAChB,iFAAiF;IACjF,cAAc,EAAE,SAAS,SAAS,EAAE,CAAA;CACrC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,aAAa,CAAA;IACrB,KAAK,EAAE,WAAW,CAAA;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,GAAG,CAAA;IACjB,MAAM,EAAE,aAAa,CAAA;IACrB,YAAY,EAAE,GAAG,CAAA;IACjB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,IAAI,CAAA;IACR,OAAO,EAAE,cAAc,CAAA;IACvB,MAAM,EAAE,UAAU,CAAA;IAClB,2EAA2E;IAC3E,MAAM,EAAE,GAAG,CAAA;IACX,wDAAwD;IACxD,eAAe,EAAE,OAAO,CAAA;IACxB,0EAA0E;IAC1E,UAAU,EAAE,UAAU,CAAA;CACvB;AAED,MAAM,MAAM,sBAAsB,GAAG,mBAAmB,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAAA;AAE5F;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,qBAAqB,EAC9B,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,sBAAsB,CAAC,CAyDjC;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,mBAAmB,EAC7B,GAAG,EAAE,UAAU,EACf,YAAY,EAAE;IAAE,YAAY,EAAE,GAAG,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,EAC3D,IAAI,EAAE;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,GAC3B,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAgBjC"}
@@ -0,0 +1,98 @@
1
+ import { digestOf, RELEASE_REASONS, releaseConsentTypedData, signForAccount, takesConsent, } from '@avow-finance/spec';
2
+ import { isAddressEqual, isHex, size } from 'viem';
3
+ import { MAX_REPORTS } from './chain.js';
4
+ import { listedToken, releaseConsentDisclosure } from './disclosure.js';
5
+ import { issue } from './issued.js';
6
+ import { randomNonce } from './nonce.js';
7
+ import { checkPrepared, signedMessage } from './signing.js';
8
+ /**
9
+ * The supported way for a supplier account to get a release consent to sign. It reads the
10
+ * commitment from the lock and refuses a commitment that isn't this supplier's, one the lock
11
+ * wouldn't release on consent, a consent that has already expired, and a report count the
12
+ * commitment has passed or can never reach. A count above the current one is preauthorization,
13
+ * and the disclosure says so. What it returns is frozen, and `signReleaseConsent` signs nothing
14
+ * else. The lock takes a correctly signed consent however it was built.
15
+ */
16
+ export async function prepareReleaseConsent(request, deps) {
17
+ const { config, chain } = deps;
18
+ if (chain.chainId !== config.chainId) {
19
+ throw new Error(`The chain reader is for chain ${chain.chainId}, not ${config.chainId}`);
20
+ }
21
+ const refuse = (reason) => ({ ok: false, reason });
22
+ if (!Object.hasOwn(RELEASE_REASONS, request.reason) ||
23
+ !isHex(request.evidenceHash) ||
24
+ size(request.evidenceHash) !== 32) {
25
+ return refuse('message.invalid');
26
+ }
27
+ const lockInfo = await chain.lock(request.lock);
28
+ if (!lockInfo?.fromFactory)
29
+ return refuse('chain.lock_unknown');
30
+ const b = await chain.backing(request.lock, request.commitmentId, 'buyer');
31
+ if (!b || b.state === 'none')
32
+ return refuse('chain.reserve_missing');
33
+ if (!isAddressEqual(b.supplier, config.account))
34
+ return refuse('chain.supplier_mismatch');
35
+ const releasable = takesConsent(b.state) && !(b.state === 'paused' && b.hasRuling);
36
+ if (!releasable)
37
+ return refuse('consent.not_releasable');
38
+ if (request.expiry <= request.now)
39
+ return refuse('message.expired');
40
+ const count = request.reportCount ?? b.reportCount;
41
+ if (!Number.isInteger(count) || count < 0 || count > MAX_REPORTS) {
42
+ return refuse('consent.count_out_of_range');
43
+ }
44
+ if (count < b.reportCount)
45
+ return refuse('consent.count_passed');
46
+ const consent = {
47
+ commitmentId: request.commitmentId,
48
+ side: 'buyer',
49
+ reportCount: count,
50
+ reason: request.reason,
51
+ evidenceHash: request.evidenceHash,
52
+ nonce: request.nonce ?? randomNonce(),
53
+ expiry: request.expiry,
54
+ };
55
+ const d = { chainId: config.chainId, verifyingContract: request.lock };
56
+ const digest = digestOf(releaseConsentTypedData(consent, d));
57
+ return issue({
58
+ ok: true,
59
+ consent,
60
+ domain: d,
61
+ digest,
62
+ supplierAccount: config.account,
63
+ disclosure: releaseConsentDisclosure({
64
+ digest,
65
+ consent,
66
+ lock: request.lock,
67
+ chainId: config.chainId,
68
+ account: lockInfo.account,
69
+ held: b.held,
70
+ token: listedToken(config.acceptedTokens, config.chainId, lockInfo.token),
71
+ currentCount: b.reportCount,
72
+ now: request.now,
73
+ }),
74
+ });
75
+ }
76
+ /**
77
+ * Signs a consent as the supplier account, with its root key or an admin key, once the person has
78
+ * seen its disclosure. A consent that names a later report count than the commitment has also
79
+ * needs `preauthorize: true`. It signs only the object `prepareReleaseConsent` returned, which is
80
+ * frozen, so a copy or an edit of it throws. It also throws when the confirmation doesn't match,
81
+ * or when the signature isn't one the chain accepts for the supplier account.
82
+ */
83
+ export async function signReleaseConsent(prepared, key, confirmation, deps) {
84
+ const typedData = releaseConsentTypedData(prepared.consent, prepared.domain);
85
+ const digest = checkPrepared(prepared, typedData, confirmation, {
86
+ message: 'consent',
87
+ prepare: 'prepareReleaseConsent',
88
+ });
89
+ if (prepared.disclosure.preauthorization && confirmation?.preauthorize !== true) {
90
+ throw new Error('This consent names a later report count than the commitment has, so it releases the reserve after a report not yet filed. Pass preauthorize: true only if the person means that');
91
+ }
92
+ const signature = await signForAccount(prepared.supplierAccount, digest, key);
93
+ if (!(await deps.chain.isAccountSignature(prepared.supplierAccount, digest, signature))) {
94
+ throw new Error("The key that signed isn't the supplier account's root key or an admin key");
95
+ }
96
+ return signedMessage(typedData, prepared.domain, prepared.consent, signature);
97
+ }
98
+ //# sourceMappingURL=consent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent.js","sourceRoot":"","sources":["../src/consent.ts"],"names":[],"mappings":"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"}