@avow-finance/verifier 0.0.0-stage → 0.2.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,252 @@
1
+ import { type Approval, type ChainedTerms, type CheckedChainedTerms, type CheckedDependency, type CommitmentReference, type JobVerification, type PinnedBlock, type RailState, type ReasonCode, type Side } from '@avow-finance/spec';
2
+ import { type Address, type Hex } from 'viem';
3
+ import type { LockedBacking } from './chain.js';
4
+ /**
5
+ * The check of a booking another booking relies on. A version 3 booking names each one in its
6
+ * dependencies section, and before a buyer funds or a seller accepts, this reads each one's lock
7
+ * directly and runs five tests. Any failure stops the step. It runs the same whoever the terms say
8
+ * checks for the buyer, since it needs the terms in full, and terms carrying the dependencies
9
+ * section only as its digest are refused with `dependency.elided` before anything is read.
10
+ *
11
+ * 1. Provenance. The lock is on a chain this check supports, the supported factory there lists it,
12
+ * and the lock's own factory field names that factory.
13
+ * 2. Ownership. The lock's account is the account Avow's approval names as this booking's supplier,
14
+ * which the lock copies into the commitment, so a seller can't cite another business's booking
15
+ * by naming that business. The terms name only the buyer side of a lock, so terms naming the
16
+ * supplier side are refused before anything is read.
17
+ * 3. State. The lock holds it, someone other than the seller's own account supplies it, the lock
18
+ * holds it as accepted with no report filed, and its free cancellation had closed by the pinned
19
+ * block's timestamp, so cancelling it from then on costs the seller a late-cancellation charge.
20
+ * 4. Terms. The lock holds it under the terms hash the dependency names, and the section the
21
+ * seller shows hashes to that terms hash.
22
+ * 5. Fit. The booking asks for no more than the booking it relies on, by its template's rule.
23
+ *
24
+ * The first read on each chain pins that chain's latest finalized block once per check, so every
25
+ * booking on that chain is read at that one block, named by number, through whichever reader reads
26
+ * it, and the result records that block's number, hash and timestamp. A finalized block older than the read age limit by the caller's clock refuses with
27
+ * `dependency.stale`, since a node that has fallen behind would show a state the chain has left. A
28
+ * read that fails, times out or can't be pinned refuses with `dependency.unreadable`, never as not
29
+ * found and never as a pass.
30
+ *
31
+ * It proves that a matching booking had been accepted when it was read. It doesn't set that
32
+ * capacity aside, so two bookings that rely on the same one both pass. It refuses a seller that
33
+ * supplied the booking relied on from its own account, and it can't tell when one owner runs two
34
+ * registered businesses. Nothing on the chain enforces a dependency, and the booking relied on can
35
+ * leave the accepted state right after the read.
36
+ */
37
+ export type { CheckedChainedTerms, CheckedDependency, PinnedBlock } from '@avow-finance/spec';
38
+ /** What a lock's record of one side of a commitment says, as far as this check reads it. */
39
+ export type DependencyRecord = Pick<LockedBacking, 'state' | 'hasReport' | 'termsHash' | 'supplier' | 'freeCancelBy'>;
40
+ /**
41
+ * Reads the locks one factory created on one chain, each read as of a block named by number. The
42
+ * check reads a booking relied on only through one of these, so the readers it's given are the
43
+ * chain and factory pairs it supports. `tempoLockReader` reads Tempo, and tests script one.
44
+ */
45
+ export interface PinnedLockReader {
46
+ readonly chainId: number;
47
+ /** The factory whose locks count. */
48
+ readonly factory: Address;
49
+ /** The latest finalized block's number, hash and timestamp. */
50
+ head(): Promise<PinnedBlock>;
51
+ /** The hash the chain's block at this height has now, or null when the node has none. */
52
+ blockHash(number: bigint): Promise<Hex | null>;
53
+ /** Whether the factory lists the lock as one it created, as of the block. */
54
+ isLock(lock: Address, at: bigint): Promise<boolean>;
55
+ /** The factory and the account the lock's own fields name, as of the block. */
56
+ lockFields(lock: Address, at: bigint): Promise<{
57
+ factory: Address;
58
+ account: Address;
59
+ }>;
60
+ /** The lock's record of one side of a commitment as of the block, or null when it holds none. */
61
+ commitment(lock: Address, commitmentId: Hex, side: Side, at: bigint): Promise<DependencyRecord | null>;
62
+ }
63
+ /** Ten seconds for the reads of one booking relied on through one reader. */
64
+ export declare const DEPENDENCY_READ_TIMEOUT_MS = 10000;
65
+ /**
66
+ * Thirty seconds, the oldest a pinned finalized block may be by the caller's clock. Tempo finalizes
67
+ * blocks within about a second, so this leaves room for clock drift and nothing more.
68
+ */
69
+ export declare const DEPENDENCY_MAX_READ_AGE = 30n;
70
+ export interface DependencyDeps {
71
+ /**
72
+ * One reader for each chain and factory pair whose locks count. A lock on any other chain, or
73
+ * from any other factory, is refused without being read.
74
+ */
75
+ readers: readonly PinnedLockReader[];
76
+ /**
77
+ * How long the reads of one booking through one reader may take, `DEPENDENCY_READ_TIMEOUT_MS`
78
+ * by default.
79
+ */
80
+ timeoutMs?: number;
81
+ /**
82
+ * The oldest, in seconds by the caller's clock, a pinned block may be, `DEPENDENCY_MAX_READ_AGE`
83
+ * by default.
84
+ */
85
+ maxReadAge?: bigint;
86
+ }
87
+ /**
88
+ * What the check reads of Avow's approval of this booking's reserve. Its supplier is the account
89
+ * the lock copies into the commitment as the supplier, so it is the account whose lock has to hold
90
+ * each booking relied on.
91
+ */
92
+ export type DependencyApproval = Pick<Approval, 'side' | 'supplier'>;
93
+ export interface DependencyInput {
94
+ /** The booking that relies on others, in version 3 terms in full. */
95
+ terms: ChainedTerms;
96
+ /**
97
+ * Avow's approval of this booking's reserve, or for Avow's own check the approval it is about to
98
+ * sign. A buyer passes the approval it is about to fund, and `prepareAcceptance` passes the
99
+ * approval the lock holds, which its later checks confirm. The supplier is taken from it and
100
+ * from nowhere else, so neither what a seller says nor a caller's setting can name the owner.
101
+ */
102
+ approval: DependencyApproval;
103
+ /**
104
+ * For each dependency in the terms' order, the section of the booking relied on that its seller
105
+ * shows, as JSON, as `discloseSection` writes it. The subject holds no price.
106
+ */
107
+ disclosed: readonly unknown[];
108
+ /** The caller's clock, in seconds, which the pinned block's timestamp is held against. */
109
+ now: bigint;
110
+ }
111
+ /** Why a check refused, with where and as of which block. */
112
+ export interface DependencyRefusal {
113
+ ok: false;
114
+ reason: ReasonCode;
115
+ /** The dependency that failed, by its place in the terms, or null when the input did. */
116
+ index: number | null;
117
+ /** The block its reads were pinned to, or null when it failed before a block was pinned. */
118
+ block: PinnedBlock | null;
119
+ }
120
+ export type DependencyCheck = {
121
+ ok: true;
122
+ terms: CheckedChainedTerms;
123
+ checked: readonly CheckedDependency[];
124
+ } | DependencyRefusal;
125
+ /**
126
+ * A commitment's state as every check reads it. An accepted commitment with a report filed has a
127
+ * charge pending in all but name, so it counts as `charge_pending`. The check of a booking relied
128
+ * on and the check of a job's link both read states through this, so they can't disagree.
129
+ */
130
+ export declare function standingState(record: Pick<DependencyRecord, 'state' | 'hasReport'>): RailState;
131
+ /**
132
+ * Checks every booking a version 3 booking relies on, in the order its terms name them, and stops
133
+ * at the first that fails. A buyer runs it on Avow's approval before it funds its reserve, and the
134
+ * seller's acceptance runs it through `prepareAcceptance`. It reads only the chain, the approval's
135
+ * supplier and what the seller shows. The lock's public view of a booking relied on shows anyone
136
+ * its reserve, charge caps, deadlines and supplier, so of what the seller pays for it, only the rate
137
+ * stays hidden.
138
+ */
139
+ export declare function verifyDependencies(input: DependencyInput, deps: DependencyDeps): Promise<DependencyCheck>;
140
+ export interface JobVerificationInput {
141
+ /** What a link to verify a job carries, from `decodeJobVerification`. */
142
+ verification: JobVerification;
143
+ /** The caller's clock, in seconds, which the pinned block's timestamp is held against. */
144
+ now: bigint;
145
+ }
146
+ /**
147
+ * A job's states while a charge is open: reported and pending, or paused while the customer
148
+ * contests it. The reserve is still held.
149
+ */
150
+ export declare const CHARGE_OPEN_JOB_STATES: readonly ["charge_pending", "paused"];
151
+ export type ChargeOpenJobState = (typeof CHARGE_OPEN_JOB_STATES)[number];
152
+ /** A job's states once it ended: its reserve released, charged or resolved, and gone from the lock. */
153
+ export declare const ENDED_JOB_STATES: readonly ["released", "charged", "resolved"];
154
+ export type EndedJobState = (typeof ENDED_JOB_STATES)[number];
155
+ /** The job commitment as the customer's lock held it at the pinned block, in one state. */
156
+ export interface CheckedJob<S extends RailState> {
157
+ state: S;
158
+ /** The customer's free-cancellation deadline as the lock holds it, which is when work starts. */
159
+ freeCancelBy: bigint;
160
+ /** The block the job commitment was read at, which every read on its chain shares. */
161
+ block: PinnedBlock;
162
+ }
163
+ /**
164
+ * A booking a job's link names, as the link's check read it: standing, or with the reason it
165
+ * doesn't stand at the block it was read at. The link carries the job's subject only as its hash,
166
+ * so the check never tests whether the job fits inside the booking. A `CheckedDependency` comes only
167
+ * from a check that tested fit, as the customer's check and the developer's acceptance do, so this
168
+ * has fields of its own and neither can stand for the other.
169
+ */
170
+ export type LinkedBooking = {
171
+ booking: CommitmentReference;
172
+ readAt: PinnedBlock;
173
+ fit: 'unchecked';
174
+ standing: true;
175
+ } | {
176
+ booking: CommitmentReference;
177
+ /** The block the booking was read at, or null when its read stopped before one was pinned. */
178
+ readAt: PinnedBlock | null;
179
+ fit: 'unchecked';
180
+ standing: false;
181
+ reason: ReasonCode;
182
+ };
183
+ /** A booking that stood when the link's check read it. */
184
+ export type StandingBooking = Extract<LinkedBooking, {
185
+ standing: true;
186
+ }>;
187
+ /**
188
+ * What a link to verify a job shows, as the chain held it at one pinned block. A page switches on
189
+ * the outcome, and only `stands` is a job a page can show as standing.
190
+ *
191
+ * - `refused`: the link doesn't match the chain or couldn't be read, or a booking a reserved job
192
+ * relies on doesn't stand, with the reason, the booking by its place and the block.
193
+ * - `awaiting_acceptance`: the customer reserved and the developer's business hasn't accepted, and
194
+ * every booking the job relies on stands.
195
+ * - `stands`: the job is accepted with no report filed. Each booking comes back as read, since a
196
+ * booking cancelled or failed after the customer accepted leaves the job standing.
197
+ * - `charge_pending`: a charge is reported and pending, or paused while it's contested, and the
198
+ * reserve is still held. Each booking comes back as read.
199
+ * - `ended`: the reserve was released, charged or resolved. Each booking comes back as read.
200
+ */
201
+ export type JobVerificationCheck = {
202
+ outcome: 'refused';
203
+ reason: ReasonCode;
204
+ index: number | null;
205
+ block: PinnedBlock | null;
206
+ } | (JobLinkParties & {
207
+ outcome: 'awaiting_acceptance';
208
+ job: CheckedJob<'reserved'>;
209
+ bookings: readonly StandingBooking[];
210
+ }) | (JobLinkParties & {
211
+ outcome: 'stands';
212
+ job: CheckedJob<'accepted'>;
213
+ bookings: readonly LinkedBooking[];
214
+ }) | (JobLinkParties & {
215
+ outcome: 'charge_pending';
216
+ job: CheckedJob<ChargeOpenJobState>;
217
+ bookings: readonly LinkedBooking[];
218
+ }) | (JobLinkParties & {
219
+ outcome: 'ended';
220
+ job: CheckedJob<EndedJobState>;
221
+ bookings: readonly LinkedBooking[];
222
+ });
223
+ interface JobLinkParties {
224
+ /**
225
+ * The supplier the customer's lock names for the job, copied there from Avow's approval, whose
226
+ * own lock has to hold each compute booking.
227
+ */
228
+ supplier: Address;
229
+ }
230
+ /**
231
+ * The check a page runs on a link to verify a job, reading the chain at one pinned finalized
232
+ * block. It works out the job's terms hash from what the link carries, reads the job commitment
233
+ * from the customer's lock with its state and free-cancellation deadline, and takes the supplier
234
+ * from the lock's record of it, which the lock copied from Avow's approval. Then it runs the tests
235
+ * `verifyDependencies` runs on each compute booking the job names that need only the chain:
236
+ * provenance, ownership by that supplier, state with free cancellation, the terms hash the lock
237
+ * holds and a fresh block. It skips the shown section and fit, which need the job's terms in full.
238
+ *
239
+ * The job's state, read through `standingState`, decides the outcome. While the job is reserved the
240
+ * bookings gate it, as they gate the developer's acceptance, so a booking that doesn't stand refuses.
241
+ * Once the job is accepted, has a charge open or has ended, each booking is reported as read and the
242
+ * outcome stays the job's, since a booking cancelled or failed after the customer accepted leaves
243
+ * the job standing. A read on the job's own chain that finds the pinned block's hash changed refuses
244
+ * the whole link as `reference.unreadable` in every state, since the job was read at that block.
245
+ *
246
+ * A link whose parts don't hash to its reference's terms hash is `terms.hash_mismatch`, a
247
+ * customer's lock no supported factory created is `chain.lock_unknown`, a read of the job that
248
+ * fails is `reference.unreadable`, and a lock that holds no job commitment under that terms hash is
249
+ * `reference.commitment_mismatch`, each before any compute booking is read.
250
+ */
251
+ export declare function verifyJobVerification(input: JobVerificationInput, deps: DependencyDeps): Promise<JobVerificationCheck>;
252
+ //# sourceMappingURL=dependency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency.d.ts","sourceRoot":"","sources":["../src/dependency.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,353 @@
1
+ import { chainedTermsShapeProblem, checkSectionDisclosure, dependenciesProblem, dependencyCheckProblem, jobVerificationProblem, parseSectionDisclosure, subjectFits, subjectProblem, } from '@avow-finance/spec';
2
+ import { isAddressEqual } from 'viem';
3
+ /** Ten seconds for the reads of one booking relied on through one reader. */
4
+ export const DEPENDENCY_READ_TIMEOUT_MS = 10_000;
5
+ /**
6
+ * Thirty seconds, the oldest a pinned finalized block may be by the caller's clock. Tempo finalizes
7
+ * blocks within about a second, so this leaves room for clock drift and nothing more.
8
+ */
9
+ export const DEPENDENCY_MAX_READ_AGE = 30n;
10
+ /**
11
+ * A commitment's state as every check reads it. An accepted commitment with a report filed has a
12
+ * charge pending in all but name, so it counts as `charge_pending`. The check of a booking relied
13
+ * on and the check of a job's link both read states through this, so they can't disagree.
14
+ */
15
+ export function standingState(record) {
16
+ return record.state === 'accepted' && record.hasReport ? 'charge_pending' : record.state;
17
+ }
18
+ /** What the state test makes of each state the lock has. The build fails when one is missing. */
19
+ const STATE_REASONS = {
20
+ none: 'dependency.not_found',
21
+ reserved: 'dependency.not_accepted',
22
+ // Accepted passes only with no report filed, which `standingState` counts as a pending charge.
23
+ accepted: null,
24
+ charge_pending: 'dependency.charge_pending',
25
+ paused: 'dependency.charge_pending',
26
+ released: 'dependency.ended',
27
+ charged: 'dependency.ended',
28
+ resolved: 'dependency.ended',
29
+ };
30
+ function stateProblem(record, seller, block) {
31
+ if (!record)
32
+ return 'dependency.not_found';
33
+ // A booking the seller supplied from its own account shows no one else accepted it.
34
+ if (isAddressEqual(record.supplier, seller))
35
+ return 'dependency.self_supplied';
36
+ const reason = STATE_REASONS[standingState(record)];
37
+ if (reason)
38
+ return reason;
39
+ // The lock lets the seller's account cancel an accepted booking at no charge in any block before
40
+ // its free-cancellation deadline, and block timestamps never go back, so this one has to be at or
41
+ // past the deadline.
42
+ return block.timestamp < record.freeCancelBy ? 'dependency.cancellable' : null;
43
+ }
44
+ /**
45
+ * A read that couldn't be finished or can't be relied on, carrying the block it had pinned when it
46
+ * stopped and why.
47
+ */
48
+ class Unreadable extends Error {
49
+ block;
50
+ reason;
51
+ moved;
52
+ constructor(block, reason = 'dependency.unreadable',
53
+ /** Whether the chain gave another hash for the pinned block, so the block itself moved. */
54
+ moved = false) {
55
+ super('The booking relied on could not be read at one recent block');
56
+ this.block = block;
57
+ this.reason = reason;
58
+ this.moved = moved;
59
+ }
60
+ }
61
+ /** The work, or a rejection once `ms` has passed. */
62
+ function within(work, ms) {
63
+ let timer;
64
+ const late = new Promise((_, reject) => {
65
+ timer = setTimeout(() => reject(new Error(`No answer within ${ms} ms`)), ms);
66
+ });
67
+ return Promise.race([work, late]).finally(() => clearTimeout(timer));
68
+ }
69
+ /**
70
+ * Reads one booking relied on through one reader, every read at the block pinned for its chain in
71
+ * this check. The first read on a chain pins the latest finalized block through the reader making
72
+ * it, and every later read on that chain in the same check, through any reader, reads at that
73
+ * block too. A pinned block older than the freshness limit stops
74
+ * the check before the lock is read. A lock the reader's factory doesn't list is never read from.
75
+ * Whatever was read stands only once the block at that height still has the hash it had when it
76
+ * was pinned, a lock no factory lists included.
77
+ */
78
+ async function observe(on, reader, pins, timeoutMs, fresh) {
79
+ const work = async () => {
80
+ let block = pins.get(reader.chainId);
81
+ if (!block) {
82
+ block = await reader.head();
83
+ pins.set(reader.chainId, block);
84
+ }
85
+ if (fresh.now - block.timestamp > fresh.maxAge)
86
+ throw new Unreadable(block, 'dependency.stale');
87
+ const listed = await reader.isLock(on.lock, block.number);
88
+ const fields = listed ? await reader.lockFields(on.lock, block.number) : null;
89
+ const record = listed
90
+ ? await reader.commitment(on.lock, on.commitmentId, on.side, block.number)
91
+ : null;
92
+ const still = await reader.blockHash(block.number);
93
+ if (still?.toLowerCase() !== block.hash.toLowerCase()) {
94
+ throw new Unreadable(block, 'dependency.unreadable', still !== null);
95
+ }
96
+ return { reader, block, fields, record };
97
+ };
98
+ try {
99
+ return await within(work(), timeoutMs);
100
+ }
101
+ catch (error) {
102
+ throw error instanceof Unreadable ? error : new Unreadable(pins.get(reader.chainId) ?? null);
103
+ }
104
+ }
105
+ /**
106
+ * Whether a lock is one the reader's factory made: the factory lists it, and the lock's own factory
107
+ * field names that factory. Each caller gives its own reason when it isn't.
108
+ */
109
+ function madeByFactory(seen) {
110
+ return seen.fields !== null && isAddressEqual(seen.fields.factory, seen.reader.factory);
111
+ }
112
+ /** Whether the lock holds the commitment read under the terms hash given. */
113
+ const heldUnder = (seen, termsHash) => seen.record?.termsHash.toLowerCase() === termsHash.toLowerCase();
114
+ /** A check's refusal, with the dependency that failed and the block its reads were pinned to. */
115
+ const refusal = (reason, index, block) => ({ ok: false, reason, index, block });
116
+ /** How long a check's reads may take and how old its blocks may be, the defaults unless set. */
117
+ function readLimits(deps, now) {
118
+ return {
119
+ timeoutMs: deps.timeoutMs ?? DEPENDENCY_READ_TIMEOUT_MS,
120
+ fresh: { now, maxAge: deps.maxReadAge ?? DEPENDENCY_MAX_READ_AGE },
121
+ };
122
+ }
123
+ /**
124
+ * The tests that need only the chain, in order, or null when all pass: provenance, ownership,
125
+ * state, and the terms hash the lock holds the booking under.
126
+ */
127
+ function standingProblem(on, seen, supplier) {
128
+ // 1. Provenance.
129
+ if (!madeByFactory(seen))
130
+ return 'dependency.lock_unknown';
131
+ // 2. Ownership.
132
+ if (!isAddressEqual(seen.fields.account, supplier))
133
+ return 'dependency.not_owned';
134
+ // 3. State.
135
+ const state = stateProblem(seen.record, supplier, seen.block);
136
+ if (state)
137
+ return state;
138
+ // 4. Terms, as the lock holds them.
139
+ if (!heldUnder(seen, on.termsHash))
140
+ return 'dependency.terms_mismatch';
141
+ return null;
142
+ }
143
+ /** The five tests on what was read, in order, or null when all pass. */
144
+ function problemOf(dependency, seen, terms, supplier, disclosed) {
145
+ const standing = standingProblem(dependency.on, seen, supplier);
146
+ if (standing)
147
+ return standing;
148
+ const { on } = dependency;
149
+ // 4. Terms, as the seller shows them.
150
+ const shown = parseSectionDisclosure(disclosed);
151
+ if (!shown.ok ||
152
+ shown.value.section !== dependency.disclosed ||
153
+ checkSectionDisclosure(shown.value, on.termsHash) !== null) {
154
+ return 'dependency.disclosure_invalid';
155
+ }
156
+ // 5. Fit.
157
+ const inner = { template: terms.template, subject: terms.subject };
158
+ const outer = { template: shown.value.header.template, subject: shown.value.content };
159
+ return subjectFits(inner, outer) ? null : 'dependency.does_not_fit';
160
+ }
161
+ /**
162
+ * Checks every booking a version 3 booking relies on, in the order its terms name them, and stops
163
+ * at the first that fails. A buyer runs it on Avow's approval before it funds its reserve, and the
164
+ * seller's acceptance runs it through `prepareAcceptance`. It reads only the chain, the approval's
165
+ * supplier and what the seller shows. The lock's public view of a booking relied on shows anyone
166
+ * its reserve, charge caps, deadlines and supplier, so of what the seller pays for it, only the rate
167
+ * stays hidden.
168
+ */
169
+ export async function verifyDependencies(input, deps) {
170
+ const t = input.terms;
171
+ const shape = chainedTermsShapeProblem(t);
172
+ if (shape)
173
+ return refusal(shape, null, null);
174
+ const setting = dependencyCheckProblem(t);
175
+ if (setting)
176
+ return refusal(setting, null, null);
177
+ const rules = dependenciesProblem(t.dependencies);
178
+ if (rules)
179
+ return refusal(rules, null, null);
180
+ // The fit test compares subjects, so a subject its template refuses stops the check before any
181
+ // read.
182
+ const subject = subjectProblem({ template: t.template, subject: t.subject });
183
+ if (subject)
184
+ return refusal(subject, null, null);
185
+ if (input.disclosed.length > t.dependencies.length)
186
+ return refusal('message.invalid', null, null);
187
+ // The approval of this booking's reserve is for its buyer side, the only side version 3 terms
188
+ // can be reserved on.
189
+ if (input.approval.side !== 'buyer')
190
+ return refusal('approval.terms_mismatch', null, null);
191
+ const supplier = input.approval.supplier;
192
+ const { timeoutMs, fresh } = readLimits(deps, input.now);
193
+ const pins = new Map();
194
+ const checked = [];
195
+ for (const [index, dependency] of t.dependencies.entries()) {
196
+ const seen = await readThrough(dependency.on, deps.readers, pins, timeoutMs, fresh);
197
+ if (!('reader' in seen))
198
+ return refusal(seen.reason, index, seen.block);
199
+ const problem = problemOf(dependency, seen, t, supplier, input.disclosed[index]);
200
+ if (problem)
201
+ return refusal(problem, index, seen.block);
202
+ checked.push(copied(dependency.on, seen.block));
203
+ }
204
+ return { ok: true, terms: t, checked };
205
+ }
206
+ /**
207
+ * Copies of a booking and its block, so freezing what a check gives back leaves the caller's
208
+ * terms and the reader's block alone.
209
+ */
210
+ function copied(on, block) {
211
+ const { number, hash, timestamp } = block;
212
+ return { on: { ...on }, block: { number, hash, timestamp } };
213
+ }
214
+ /**
215
+ * Reads one booking through each supported reader on its chain in turn, until one's factory lists
216
+ * its lock. The last one read stands for a lock none of them lists, and a chain no reader supports
217
+ * is `dependency.lock_unknown`, with nothing read.
218
+ */
219
+ async function readThrough(on, readers, pins, timeoutMs, fresh) {
220
+ let seen = null;
221
+ for (const reader of readers.filter((r) => r.chainId === on.chainId)) {
222
+ try {
223
+ seen = await observe(on, reader, pins, timeoutMs, fresh);
224
+ }
225
+ catch (error) {
226
+ if (error instanceof Unreadable) {
227
+ return { reason: error.reason, block: error.block, moved: error.moved };
228
+ }
229
+ return { reason: 'dependency.unreadable', block: null, moved: false };
230
+ }
231
+ if (seen.fields)
232
+ break;
233
+ }
234
+ return seen ?? { reason: 'dependency.lock_unknown', block: null, moved: false };
235
+ }
236
+ /**
237
+ * A job's states while a charge is open: reported and pending, or paused while the customer
238
+ * contests it. The reserve is still held.
239
+ */
240
+ export const CHARGE_OPEN_JOB_STATES = [
241
+ 'charge_pending',
242
+ 'paused',
243
+ ];
244
+ /** A job's states once it ended: its reserve released, charged or resolved, and gone from the lock. */
245
+ export const ENDED_JOB_STATES = [
246
+ 'released',
247
+ 'charged',
248
+ 'resolved',
249
+ ];
250
+ const jobRefusal = (reason, index, block) => ({ outcome: 'refused', reason, index, block });
251
+ const isChargeOpen = (state) => CHARGE_OPEN_JOB_STATES.includes(state);
252
+ const isEnded = (state) => ENDED_JOB_STATES.includes(state);
253
+ /**
254
+ * What a read of the job's own commitment that stopped means, in the job's terms. The reasons a
255
+ * read of a booking relied on stops with name that booking, so these name the job's lock and the
256
+ * job's reference instead. A stale block means the same for either, so it stays.
257
+ */
258
+ const JOB_READ_REASONS = {
259
+ 'dependency.lock_unknown': 'chain.lock_unknown',
260
+ 'dependency.unreadable': 'reference.unreadable',
261
+ };
262
+ /**
263
+ * The check a page runs on a link to verify a job, reading the chain at one pinned finalized
264
+ * block. It works out the job's terms hash from what the link carries, reads the job commitment
265
+ * from the customer's lock with its state and free-cancellation deadline, and takes the supplier
266
+ * from the lock's record of it, which the lock copied from Avow's approval. Then it runs the tests
267
+ * `verifyDependencies` runs on each compute booking the job names that need only the chain:
268
+ * provenance, ownership by that supplier, state with free cancellation, the terms hash the lock
269
+ * holds and a fresh block. It skips the shown section and fit, which need the job's terms in full.
270
+ *
271
+ * The job's state, read through `standingState`, decides the outcome. While the job is reserved the
272
+ * bookings gate it, as they gate the developer's acceptance, so a booking that doesn't stand refuses.
273
+ * Once the job is accepted, has a charge open or has ended, each booking is reported as read and the
274
+ * outcome stays the job's, since a booking cancelled or failed after the customer accepted leaves
275
+ * the job standing. A read on the job's own chain that finds the pinned block's hash changed refuses
276
+ * the whole link as `reference.unreadable` in every state, since the job was read at that block.
277
+ *
278
+ * A link whose parts don't hash to its reference's terms hash is `terms.hash_mismatch`, a
279
+ * customer's lock no supported factory created is `chain.lock_unknown`, a read of the job that
280
+ * fails is `reference.unreadable`, and a lock that holds no job commitment under that terms hash is
281
+ * `reference.commitment_mismatch`, each before any compute booking is read.
282
+ */
283
+ export async function verifyJobVerification(input, deps) {
284
+ const v = input.verification;
285
+ const hashed = jobVerificationProblem(v);
286
+ if (hashed)
287
+ return jobRefusal(hashed, null, null);
288
+ const rules = dependenciesProblem(v.dependencies);
289
+ if (rules)
290
+ return jobRefusal(rules, null, null);
291
+ if (v.commitment.side !== 'buyer')
292
+ return jobRefusal('reference.commitment_mismatch', null, null);
293
+ const { timeoutMs, fresh } = readLimits(deps, input.now);
294
+ const pins = new Map();
295
+ const job = await readThrough(v.commitment, deps.readers, pins, timeoutMs, fresh);
296
+ if (!('reader' in job)) {
297
+ return jobRefusal(JOB_READ_REASONS[job.reason] ?? job.reason, null, job.block);
298
+ }
299
+ if (!madeByFactory(job))
300
+ return jobRefusal('chain.lock_unknown', null, job.block);
301
+ const state = job.record ? standingState(job.record) : 'none';
302
+ if (!job.record || state === 'none' || !heldUnder(job, v.commitment.termsHash)) {
303
+ return jobRefusal('reference.commitment_mismatch', null, job.block);
304
+ }
305
+ const supplier = job.record.supplier;
306
+ const gated = state === 'reserved';
307
+ const bookings = [];
308
+ for (const [index, dependency] of v.dependencies.entries()) {
309
+ const seen = await readThrough(dependency.on, deps.readers, pins, timeoutMs, fresh);
310
+ const booking = { ...dependency.on };
311
+ if (!('reader' in seen)) {
312
+ // The job was read at the same block on its chain, so a block that moved there leaves
313
+ // nothing about the job standing either.
314
+ if (seen.moved && dependency.on.chainId === v.commitment.chainId) {
315
+ return jobRefusal('reference.unreadable', null, seen.block);
316
+ }
317
+ if (gated)
318
+ return jobRefusal(seen.reason, index, seen.block);
319
+ const readAt = seen.block ? copied(dependency.on, seen.block).block : null;
320
+ bookings.push({ booking, readAt, fit: 'unchecked', standing: false, reason: seen.reason });
321
+ continue;
322
+ }
323
+ const problem = standingProblem(dependency.on, seen, supplier);
324
+ if (problem && gated)
325
+ return jobRefusal(problem, index, seen.block);
326
+ const readAt = copied(dependency.on, seen.block).block;
327
+ bookings.push(problem
328
+ ? { booking, readAt, fit: 'unchecked', standing: false, reason: problem }
329
+ : { booking, readAt, fit: 'unchecked', standing: true });
330
+ }
331
+ const at = {
332
+ freeCancelBy: job.record.freeCancelBy,
333
+ block: copied(v.commitment, job.block).block,
334
+ };
335
+ if (state === 'reserved') {
336
+ const standing = bookings.filter((b) => b.standing);
337
+ return {
338
+ outcome: 'awaiting_acceptance',
339
+ job: { state, ...at },
340
+ supplier,
341
+ bookings: standing,
342
+ };
343
+ }
344
+ if (state === 'accepted')
345
+ return { outcome: 'stands', job: { state, ...at }, supplier, bookings };
346
+ if (isChargeOpen(state)) {
347
+ return { outcome: 'charge_pending', job: { state, ...at }, supplier, bookings };
348
+ }
349
+ if (isEnded(state))
350
+ return { outcome: 'ended', job: { state, ...at }, supplier, bookings };
351
+ return jobRefusal('reference.commitment_mismatch', null, job.block);
352
+ }
353
+ //# sourceMappingURL=dependency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency.js","sourceRoot":"","sources":["../src/dependency.ts"],"names":[],"mappings":"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"}