@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.
- package/LICENSE +201 -0
- package/README.md +112 -2
- package/dist/accept.d.ts +170 -0
- package/dist/accept.d.ts.map +1 -0
- package/dist/accept.js +268 -0
- package/dist/accept.js.map +1 -0
- package/dist/authorization.d.ts +65 -0
- package/dist/authorization.d.ts.map +1 -0
- package/dist/authorization.js +192 -0
- package/dist/authorization.js.map +1 -0
- package/dist/chain.d.ts +160 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +72 -0
- package/dist/chain.js.map +1 -0
- package/dist/consent.d.ts +69 -0
- package/dist/consent.d.ts.map +1 -0
- package/dist/consent.js +98 -0
- package/dist/consent.js.map +1 -0
- package/dist/dependency.d.ts +252 -0
- package/dist/dependency.d.ts.map +1 -0
- package/dist/dependency.js +353 -0
- package/dist/dependency.js.map +1 -0
- package/dist/disclosure.d.ts +88 -0
- package/dist/disclosure.d.ts.map +1 -0
- package/dist/disclosure.js +210 -0
- package/dist/disclosure.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/issued.d.ts +5 -0
- package/dist/issued.d.ts.map +1 -0
- package/dist/issued.js +24 -0
- package/dist/issued.js.map +1 -0
- package/dist/lock-abi.d.ts +471 -0
- package/dist/lock-abi.d.ts.map +1 -0
- package/dist/lock-abi.js +452 -0
- package/dist/lock-abi.js.map +1 -0
- package/dist/nonce.d.ts +3 -0
- package/dist/nonce.d.ts.map +1 -0
- package/dist/nonce.js +4 -0
- package/dist/nonce.js.map +1 -0
- package/dist/references.d.ts +38 -0
- package/dist/references.d.ts.map +1 -0
- package/dist/references.js +93 -0
- package/dist/references.js.map +1 -0
- package/dist/report.d.ts +128 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +155 -0
- package/dist/report.js.map +1 -0
- package/dist/signing.d.ts +47 -0
- package/dist/signing.d.ts.map +1 -0
- package/dist/signing.js +51 -0
- package/dist/signing.js.map +1 -0
- package/dist/tempo.d.ts +70 -0
- package/dist/tempo.d.ts.map +1 -0
- package/dist/tempo.js +341 -0
- package/dist/tempo.js.map +1 -0
- package/dist/verify.d.ts +65 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +36 -0
- package/dist/verify.js.map +1 -0
- package/package.json +34 -3
package/dist/tempo.js
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import { CHARGE_KINDS, RAIL_STATES, SIDE_CODES, tempoKeychainCheck, } from '@avow-finance/spec';
|
|
2
|
+
import { BlockNotFoundError, isAddressEqual, parseEventLogs, TransactionReceiptNotFoundError, zeroAddress, } from 'viem';
|
|
3
|
+
import { getBlock, getTransactionReceipt, readContract } from 'viem/actions';
|
|
4
|
+
import { Abis, Addresses } from 'viem/tempo';
|
|
5
|
+
import { FACTORY_ABI, LOCK_ABI, LOCK_PAUSED_EVENT_ABI, PAUSE_CAUSES } from './lock-abi.js';
|
|
6
|
+
/** The keychain stores a key with no expiry as the largest uint64. */
|
|
7
|
+
const NO_EXPIRY = 2n ** 64n - 1n;
|
|
8
|
+
/**
|
|
9
|
+
* Reads an agent key from Tempo's keychain: whether it's revoked, when it expires, and the
|
|
10
|
+
* mandate hash bound into it. The keychain logs that hash as a witness in the transaction that
|
|
11
|
+
* authorized the key, and Moderato's public RPC searches logs only over short block ranges, so the
|
|
12
|
+
* caller names that transaction. Its receipt comes from the chain, so naming it proves nothing on
|
|
13
|
+
* its own: the key and the witness must both appear in it.
|
|
14
|
+
*/
|
|
15
|
+
export async function readAgentKey(client, account, key, authorizedIn) {
|
|
16
|
+
const stored = await readContract(client, {
|
|
17
|
+
address: Addresses.accountKeychain,
|
|
18
|
+
abi: Abis.accountKeychain,
|
|
19
|
+
functionName: 'getKey',
|
|
20
|
+
args: [account, key],
|
|
21
|
+
});
|
|
22
|
+
if (isAddressEqual(stored.keyId, zeroAddress))
|
|
23
|
+
return null;
|
|
24
|
+
const receipt = await getTransactionReceipt(client, { hash: authorizedIn });
|
|
25
|
+
const logs = parseEventLogs({
|
|
26
|
+
abi: Abis.accountKeychain,
|
|
27
|
+
logs: receipt.logs.filter((l) => isAddressEqual(l.address, Addresses.accountKeychain)),
|
|
28
|
+
});
|
|
29
|
+
// Tempo's witness event doesn't name the key, so the transaction must authorize exactly one key
|
|
30
|
+
// for this account, this one, with exactly one witness. Anything else can't be paired safely.
|
|
31
|
+
const authorizedKeys = logs.flatMap((l) => l.eventName === 'KeyAuthorized' && isAddressEqual(l.args.account, account)
|
|
32
|
+
? [l.args.publicKey]
|
|
33
|
+
: []);
|
|
34
|
+
const witnesses = logs.flatMap((l) => l.eventName === 'KeyAuthorizationWitness' && isAddressEqual(l.args.account, account)
|
|
35
|
+
? [l.args.witness]
|
|
36
|
+
: []);
|
|
37
|
+
const onlyThisKey = authorizedKeys.length === 1 && isAddressEqual(authorizedKeys[0] ?? zeroAddress, key);
|
|
38
|
+
return {
|
|
39
|
+
active: !stored.isRevoked,
|
|
40
|
+
expiry: stored.expiry >= NO_EXPIRY ? null : stored.expiry,
|
|
41
|
+
witness: onlyThisKey && witnesses.length === 1 ? (witnesses[0] ?? null) : null,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** Tempo puts every TIP-20 token at these 12 bytes, `0x20c0` and ten zero bytes, then its 8-byte id. */
|
|
45
|
+
const TIP20_PREFIX = '0x20c000000000000000000000';
|
|
46
|
+
/** Whether an address is a TIP-20 token's, by the whole 12-byte prefix. */
|
|
47
|
+
function isTip20(address) {
|
|
48
|
+
return address.toLowerCase().startsWith(TIP20_PREFIX);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* A transaction's receipt, read after the chain's finalized block, or null when the chain has no
|
|
52
|
+
* such transaction. The receipt counts as final only when its block is at or below that finalized
|
|
53
|
+
* block and is the chain's block at its height, so a receipt from a block that lost a
|
|
54
|
+
* reorganization never reads as final. Reading the finalized block first keeps every block at or
|
|
55
|
+
* below it the chain's block.
|
|
56
|
+
*/
|
|
57
|
+
async function finalityOf(client, transactionHash) {
|
|
58
|
+
const final = await getBlock(client, { blockTag: 'finalized' });
|
|
59
|
+
let receipt;
|
|
60
|
+
try {
|
|
61
|
+
receipt = await getTransactionReceipt(client, { hash: transactionHash });
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (error instanceof TransactionReceiptNotFoundError)
|
|
65
|
+
return null;
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
let finalized = false;
|
|
69
|
+
if (final.number !== null && receipt.blockNumber <= final.number) {
|
|
70
|
+
// A node a block behind may not have the block yet, and then the receipt reads as not final.
|
|
71
|
+
const atHeight = await getBlock(client, { blockNumber: receipt.blockNumber }).catch((error) => {
|
|
72
|
+
if (error instanceof BlockNotFoundError)
|
|
73
|
+
return null;
|
|
74
|
+
throw error;
|
|
75
|
+
});
|
|
76
|
+
finalized =
|
|
77
|
+
atHeight?.hash != null && atHeight.hash.toLowerCase() === receipt.blockHash.toLowerCase();
|
|
78
|
+
}
|
|
79
|
+
return { receipt, finalized };
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Reads the log at one index of one transaction. The log counts as a payment only when a TIP-20
|
|
83
|
+
* token emitted it and it decodes as that token's `TransferWithMemo` event, and the caller checks
|
|
84
|
+
* that the token is the one the reference names and one it accepts. The receipt is final only
|
|
85
|
+
* when its block is at or below the chain's finalized block and is the chain's block at that
|
|
86
|
+
* height, so a receipt from a block that lost a reorg never reads as final.
|
|
87
|
+
*/
|
|
88
|
+
export async function readTransfer(client, chainId, transactionHash, logIndex) {
|
|
89
|
+
const read = await finalityOf(client, transactionHash);
|
|
90
|
+
if (!read)
|
|
91
|
+
return null;
|
|
92
|
+
const { receipt, finalized } = read;
|
|
93
|
+
const log = receipt.logs.find((l) => l.logIndex === logIndex);
|
|
94
|
+
if (!log)
|
|
95
|
+
return null;
|
|
96
|
+
const [decoded] = isTip20(log.address)
|
|
97
|
+
? parseEventLogs({ abi: Abis.tip20, eventName: 'TransferWithMemo', logs: [log], strict: true })
|
|
98
|
+
: [];
|
|
99
|
+
return {
|
|
100
|
+
chainId,
|
|
101
|
+
transactionHash: receipt.transactionHash,
|
|
102
|
+
logIndex,
|
|
103
|
+
succeeded: receipt.status === 'success',
|
|
104
|
+
finalized,
|
|
105
|
+
emitter: log.address,
|
|
106
|
+
event: decoded
|
|
107
|
+
? {
|
|
108
|
+
from: decoded.args.from,
|
|
109
|
+
to: decoded.args.to,
|
|
110
|
+
amount: decoded.args.amount,
|
|
111
|
+
memo: decoded.args.memo,
|
|
112
|
+
}
|
|
113
|
+
: null,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
const KIND_NAMES = new Map(Object.entries(CHARGE_KINDS).map(([name, code]) => [code, name]));
|
|
117
|
+
/** A charge kind by the code the lock stores, refusing a code this verifier doesn't read. */
|
|
118
|
+
function kindOf(code) {
|
|
119
|
+
const kind = KIND_NAMES.get(code);
|
|
120
|
+
if (!kind)
|
|
121
|
+
throw new Error(`The lock holds charge kind ${code}, which this verifier doesn't read`);
|
|
122
|
+
return kind;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Reads what a lock holds for one side of a commitment, or null when it holds nothing. It reads
|
|
126
|
+
* only the lock, so it needs no factory, and the caller decides whether the lock is Avow's. Given
|
|
127
|
+
* a block number it reads the lock as of that block, and a node that doesn't have the block yet
|
|
128
|
+
* refuses the read.
|
|
129
|
+
*/
|
|
130
|
+
export async function readBacking(client, lock, commitmentId, side, options = {}) {
|
|
131
|
+
const at = options.blockNumber === undefined ? {} : { blockNumber: options.blockNumber };
|
|
132
|
+
const [c, token] = await Promise.all([
|
|
133
|
+
readContract(client, {
|
|
134
|
+
address: lock,
|
|
135
|
+
abi: LOCK_ABI,
|
|
136
|
+
functionName: 'commitment',
|
|
137
|
+
args: [commitmentId, SIDE_CODES[side]],
|
|
138
|
+
...at,
|
|
139
|
+
}),
|
|
140
|
+
readContract(client, { address: lock, abi: LOCK_ABI, functionName: 'token', ...at }),
|
|
141
|
+
]);
|
|
142
|
+
if (c.state === 0)
|
|
143
|
+
return null;
|
|
144
|
+
const state = RAIL_STATES[c.state];
|
|
145
|
+
if (!state)
|
|
146
|
+
throw new Error(`The lock reports state ${c.state}, which this verifier doesn't read`);
|
|
147
|
+
const charges = [];
|
|
148
|
+
for (let k = 0; k < c.most.length; k++) {
|
|
149
|
+
if ((c.kinds & (1 << k)) === 0)
|
|
150
|
+
continue;
|
|
151
|
+
charges.push({ kind: kindOf(k), most: c.most[k] ?? 0n, earliest: c.earliest[k] ?? 0n });
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
state,
|
|
155
|
+
token,
|
|
156
|
+
amount: c.amount,
|
|
157
|
+
held: c.held,
|
|
158
|
+
payee: c.payout,
|
|
159
|
+
supplier: c.supplier,
|
|
160
|
+
supplierSigner: c.supplierSigner,
|
|
161
|
+
freeCancelBy: c.freeCancelBy,
|
|
162
|
+
acceptBy: c.acceptBy,
|
|
163
|
+
chargeDeadline: c.chargeDeadline,
|
|
164
|
+
contestWindow: c.contestWindow,
|
|
165
|
+
releaseDate: c.releaseDate,
|
|
166
|
+
charges,
|
|
167
|
+
day90SupplierShareBps: c.day90ShareBps,
|
|
168
|
+
arbiter: c.arbiter,
|
|
169
|
+
termsHash: c.termsHash,
|
|
170
|
+
mandateHash: c.mandateHash,
|
|
171
|
+
approvalHash: c.approvalHash,
|
|
172
|
+
fundingKey: c.fundedBy,
|
|
173
|
+
reportCount: c.reportCount,
|
|
174
|
+
// The lock leaves the kind at zero until the first report, so only a count says one was filed.
|
|
175
|
+
reportKind: c.reportCount > 0 ? kindOf(c.reportKind) : null,
|
|
176
|
+
reportAmount: c.reportAmount,
|
|
177
|
+
hasReport: c.hasReport,
|
|
178
|
+
contested: c.contested,
|
|
179
|
+
chargeStart: c.chargeStart,
|
|
180
|
+
pausedAt: c.pausedAt,
|
|
181
|
+
hasRuling: c.hasRuling,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* The contest of one side of a commitment among one transaction's logs, from the `Paused` event the
|
|
186
|
+
* lock logged with a contest as its cause, or null when there's none. Only a log the lock itself
|
|
187
|
+
* wrote counts, since any contract can write one shaped like it. A transaction can carry calls to
|
|
188
|
+
* several commitments, so the event has to name this commitment and side.
|
|
189
|
+
*/
|
|
190
|
+
export function contestInLogs(logs, lock, commitmentId, side) {
|
|
191
|
+
const events = parseEventLogs({
|
|
192
|
+
abi: LOCK_PAUSED_EVENT_ABI,
|
|
193
|
+
logs: logs.filter((l) => isAddressEqual(l.address, lock)),
|
|
194
|
+
strict: true,
|
|
195
|
+
});
|
|
196
|
+
for (const { args } of events) {
|
|
197
|
+
if (args.cause !== PAUSE_CAUSES.contest || args.side !== SIDE_CODES[side])
|
|
198
|
+
continue;
|
|
199
|
+
if (args.commitmentId.toLowerCase() !== commitmentId.toLowerCase())
|
|
200
|
+
continue;
|
|
201
|
+
return {
|
|
202
|
+
commitmentId: args.commitmentId.toLowerCase(),
|
|
203
|
+
side,
|
|
204
|
+
reasonCode: args.reasonCode,
|
|
205
|
+
statementHash: args.evidenceHash.toLowerCase(),
|
|
206
|
+
pausedAt: args.pausedAt,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Reads the contest of one side of a commitment that one transaction carried to a lock, from the
|
|
213
|
+
* transaction's receipt, with whether its block is final as `readTransfer` judges it, and the
|
|
214
|
+
* report it named as the lock held it at that block. It returns null when the chain has no such
|
|
215
|
+
* transaction, when the transaction failed, or when it holds no contest of that side from that
|
|
216
|
+
* lock, and throws when the node can't answer, so an outage never reads as a missing contest.
|
|
217
|
+
*
|
|
218
|
+
* The lock's record is read as of the end of the contest's block, so a withdrawal and a new report
|
|
219
|
+
* later in that same block would show the new report. The lock takes a contest only when it names
|
|
220
|
+
* the latest report, so the record shows the contested report unless both happened in that block.
|
|
221
|
+
*/
|
|
222
|
+
export async function readContest(client, lock, commitmentId, side, transactionHash) {
|
|
223
|
+
const read = await finalityOf(client, transactionHash);
|
|
224
|
+
if (!read || read.receipt.status !== 'success')
|
|
225
|
+
return null;
|
|
226
|
+
const { receipt, finalized } = read;
|
|
227
|
+
const seen = contestInLogs(receipt.logs, lock, commitmentId, side);
|
|
228
|
+
if (!seen)
|
|
229
|
+
return null;
|
|
230
|
+
const held = await readBacking(client, lock, commitmentId, side, {
|
|
231
|
+
blockNumber: receipt.blockNumber,
|
|
232
|
+
});
|
|
233
|
+
if (!held?.reportKind) {
|
|
234
|
+
throw new Error(`The lock held no report on ${commitmentId} in the block its contest landed in`);
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
...seen,
|
|
238
|
+
blockNumber: receipt.blockNumber,
|
|
239
|
+
finalized,
|
|
240
|
+
report: { number: held.reportCount, kind: held.reportKind, amount: held.reportAmount },
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
/** The chain's id from the options or the client, or a setup mistake when neither names one. */
|
|
244
|
+
function chainIdOf(client, options) {
|
|
245
|
+
const chainId = options.chainId ?? client.chain?.id;
|
|
246
|
+
if (chainId === undefined)
|
|
247
|
+
throw new Error("Name the chain's id, or give the client a chain");
|
|
248
|
+
return chainId;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Reads the locks one factory created on Tempo, every read as of a block named by number, for the
|
|
252
|
+
* check of a booking another booking relies on. The latest finalized block is the one pinned, so
|
|
253
|
+
* no later block can change what it shows, and a node that doesn't have a block refuses the read.
|
|
254
|
+
* The pinned block carries its timestamp, so the check can refuse a node that has fallen behind.
|
|
255
|
+
* The caller trusts the node the client talks to, so it uses one it chose.
|
|
256
|
+
*/
|
|
257
|
+
export function tempoLockReader(client, options) {
|
|
258
|
+
const { factory } = options;
|
|
259
|
+
const lockView = (lock, name, blockNumber) => readContract(client, { address: lock, abi: LOCK_ABI, functionName: name, blockNumber });
|
|
260
|
+
return {
|
|
261
|
+
chainId: chainIdOf(client, options),
|
|
262
|
+
factory,
|
|
263
|
+
async head() {
|
|
264
|
+
const block = await getBlock(client, { blockTag: 'finalized' });
|
|
265
|
+
return { number: block.number, hash: block.hash, timestamp: block.timestamp };
|
|
266
|
+
},
|
|
267
|
+
async blockHash(blockNumber) {
|
|
268
|
+
try {
|
|
269
|
+
return (await getBlock(client, { blockNumber })).hash;
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
if (error instanceof BlockNotFoundError)
|
|
273
|
+
return null;
|
|
274
|
+
throw error;
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
isLock: (lock, blockNumber) => readContract(client, {
|
|
278
|
+
address: factory,
|
|
279
|
+
abi: FACTORY_ABI,
|
|
280
|
+
functionName: 'isLock',
|
|
281
|
+
args: [lock],
|
|
282
|
+
blockNumber,
|
|
283
|
+
}),
|
|
284
|
+
async lockFields(lock, blockNumber) {
|
|
285
|
+
const [lockFactory, account] = await Promise.all([
|
|
286
|
+
lockView(lock, 'factory', blockNumber),
|
|
287
|
+
lockView(lock, 'account', blockNumber),
|
|
288
|
+
]);
|
|
289
|
+
return { factory: lockFactory, account };
|
|
290
|
+
},
|
|
291
|
+
commitment: (lock, commitmentId, side, blockNumber) => readBacking(client, lock, commitmentId, side, { blockNumber }),
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Reads Tempo directly: the lock's settings and its record of a commitment, the agent key in the
|
|
296
|
+
* keychain, and account signatures through Tempo's own signature verifier. A lock counts as
|
|
297
|
+
* Avow's only when the factory the supplier pinned says it created it, since any contract can name
|
|
298
|
+
* a factory. The supplier trusts the node the client talks to, so it uses one it chose.
|
|
299
|
+
*/
|
|
300
|
+
export function tempoChainReader(client, options) {
|
|
301
|
+
const chainId = chainIdOf(client, options);
|
|
302
|
+
const check = tempoKeychainCheck(client);
|
|
303
|
+
const tokenOf = (lock) => readContract(client, { address: lock, abi: LOCK_ABI, functionName: 'token' });
|
|
304
|
+
async function lock(lock) {
|
|
305
|
+
const created = await readContract(client, {
|
|
306
|
+
address: options.factory,
|
|
307
|
+
abi: FACTORY_ABI,
|
|
308
|
+
functionName: 'isLock',
|
|
309
|
+
args: [lock],
|
|
310
|
+
});
|
|
311
|
+
if (!created)
|
|
312
|
+
return null;
|
|
313
|
+
const at = { address: lock, abi: LOCK_ABI };
|
|
314
|
+
const [factory, account, token, minContestWindow, confirmWindow, rulingDelay, rulingKeyEnd, day90,] = await Promise.all([
|
|
315
|
+
readContract(client, { ...at, functionName: 'factory' }),
|
|
316
|
+
readContract(client, { ...at, functionName: 'account' }),
|
|
317
|
+
tokenOf(lock),
|
|
318
|
+
readContract(client, { ...at, functionName: 'minContestWindow' }),
|
|
319
|
+
readContract(client, { ...at, functionName: 'confirmWindow' }),
|
|
320
|
+
readContract(client, { ...at, functionName: 'rulingDelay' }),
|
|
321
|
+
readContract(client, { ...at, functionName: 'rulingKeyEnd' }),
|
|
322
|
+
readContract(client, { ...at, functionName: 'day90' }),
|
|
323
|
+
]);
|
|
324
|
+
return {
|
|
325
|
+
fromFactory: isAddressEqual(factory, options.factory),
|
|
326
|
+
account,
|
|
327
|
+
token,
|
|
328
|
+
timing: { minContestWindow, confirmWindow, rulingDelay, rulingKeyEnd, day90 },
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
return {
|
|
332
|
+
chainId,
|
|
333
|
+
lock,
|
|
334
|
+
backing: (lock, commitmentId, side) => readBacking(client, lock, commitmentId, side),
|
|
335
|
+
agentKey: (account, key, authorizedIn) => readAgentKey(client, account, key, authorizedIn),
|
|
336
|
+
isAccountSignature: (account, digest, signature) => check({ signer: account, digest, signature }),
|
|
337
|
+
transfer: (transactionHash, logIndex) => readTransfer(client, chainId, transactionHash, logIndex),
|
|
338
|
+
contest: (lock, commitmentId, side, transactionHash) => readContest(client, lock, commitmentId, side, transactionHash),
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
//# sourceMappingURL=tempo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tempo.js","sourceRoot":"","sources":["../src/tempo.ts"],"names":[],"mappings":"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"}
|
package/dist/verify.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { type AnyTerms, type RailToken, type ReasonCode, type ReplayGuard, type SupplierAuthorization, type TermsProfile } from '@avow-finance/spec';
|
|
2
|
+
import type { Address } from 'viem';
|
|
3
|
+
import { type Agreed } from './authorization.js';
|
|
4
|
+
import type { ChainReader } from './chain.js';
|
|
5
|
+
export type { Agreed } from './authorization.js';
|
|
6
|
+
export { AUTHORIZATION_VALIDITY } from './authorization.js';
|
|
7
|
+
export interface VerifierConfig {
|
|
8
|
+
chainId: number;
|
|
9
|
+
/** Avow's published keys for supplier authorizations. */
|
|
10
|
+
avowKeys: readonly Address[];
|
|
11
|
+
/** The supplier's own business id, as a buyer's mandate names it. */
|
|
12
|
+
businessId: string;
|
|
13
|
+
/** The supplier's own payout address. Every reserve it accepts must pay here. */
|
|
14
|
+
payee: Address;
|
|
15
|
+
/** Tokens the supplier accepts, with the currency each stands for. */
|
|
16
|
+
acceptedTokens: readonly RailToken[];
|
|
17
|
+
profile: TermsProfile;
|
|
18
|
+
/** Whether KYB results marked as test data pass. Allowed only on a testnet. */
|
|
19
|
+
acceptTestData: boolean;
|
|
20
|
+
/** The longest an authorization may stay valid, in seconds. Five minutes when left out. */
|
|
21
|
+
maxValidity?: bigint;
|
|
22
|
+
}
|
|
23
|
+
export interface VerifierDeps {
|
|
24
|
+
config: VerifierConfig;
|
|
25
|
+
chain: ChainReader;
|
|
26
|
+
replay: ReplayGuard;
|
|
27
|
+
}
|
|
28
|
+
export interface VerifyInput {
|
|
29
|
+
/** The signed supplier authorization, as JSON. */
|
|
30
|
+
authorization: unknown;
|
|
31
|
+
/** The commitment the supplier agreed to, from the terms agreement it signed. */
|
|
32
|
+
agreed: Agreed;
|
|
33
|
+
/**
|
|
34
|
+
* The supplier's own copy of the agreed terms: version 2, or version 1 for one made under it.
|
|
35
|
+
* Version 3 terms are refused, since this check doesn't read the bookings they rely on, and
|
|
36
|
+
* `prepareAcceptance` takes them.
|
|
37
|
+
*/
|
|
38
|
+
terms: AnyTerms;
|
|
39
|
+
/** The buyer's signed mandate, as JSON, when the supplier wants to check it too. */
|
|
40
|
+
mandate?: unknown;
|
|
41
|
+
now: bigint;
|
|
42
|
+
}
|
|
43
|
+
export type Verification = {
|
|
44
|
+
ok: true;
|
|
45
|
+
authorization: SupplierAuthorization;
|
|
46
|
+
lock: Address;
|
|
47
|
+
/** The buyer's account, which owns the lock. */
|
|
48
|
+
account: Address;
|
|
49
|
+
/** The Avow key that signed. */
|
|
50
|
+
signer: Address;
|
|
51
|
+
} | {
|
|
52
|
+
ok: false;
|
|
53
|
+
reason: ReasonCode;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Checks a supplier authorization before the supplier grants capacity. It uses only the signed
|
|
57
|
+
* message, the supplier's own record of what it agreed to and the chain, and never asks Avow.
|
|
58
|
+
* It refuses with the first reason that applies. It passes once per commitment, and it records
|
|
59
|
+
* that only after every other check passes, so a refusal never uses it up.
|
|
60
|
+
*
|
|
61
|
+
* Throws when the config doesn't fit the chain, such as test data on a chain that isn't a
|
|
62
|
+
* testnet, because that's a setup mistake rather than a bad authorization.
|
|
63
|
+
*/
|
|
64
|
+
export declare function verifySupplierAuthorization(input: VerifyInput, deps: VerifierDeps): Promise<Verification>;
|
|
65
|
+
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,QAAQ,EAGb,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,EAAE,KAAK,MAAM,EAAsB,MAAM,oBAAoB,CAAA;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,YAAY,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAE3D,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,yDAAyD;IACzD,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAA;IAC5B,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAA;IAClB,iFAAiF;IACjF,KAAK,EAAE,OAAO,CAAA;IACd,sEAAsE;IACtE,cAAc,EAAE,SAAS,SAAS,EAAE,CAAA;IACpC,OAAO,EAAE,YAAY,CAAA;IACrB,+EAA+E;IAC/E,cAAc,EAAE,OAAO,CAAA;IACvB,2FAA2F;IAC3F,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,cAAc,CAAA;IACtB,KAAK,EAAE,WAAW,CAAA;IAClB,MAAM,EAAE,WAAW,CAAA;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,kDAAkD;IAClD,aAAa,EAAE,OAAO,CAAA;IACtB,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,KAAK,EAAE,QAAQ,CAAA;IACf,oFAAoF;IACpF,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,MAAM,YAAY,GACpB;IACE,EAAE,EAAE,IAAI,CAAA;IACR,aAAa,EAAE,qBAAqB,CAAA;IACpC,IAAI,EAAE,OAAO,CAAA;IACb,gDAAgD;IAChD,OAAO,EAAE,OAAO,CAAA;IAChB,gCAAgC;IAChC,MAAM,EAAE,OAAO,CAAA;CAChB,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAAA;AAErC;;;;;;;;GAQG;AACH,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,YAAY,CAAC,CA0BvB"}
|
package/dist/verify.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { commitmentKey, enforceableTerms, } from '@avow-finance/spec';
|
|
2
|
+
import { checkAuthorization } from './authorization.js';
|
|
3
|
+
export { AUTHORIZATION_VALIDITY } from './authorization.js';
|
|
4
|
+
/**
|
|
5
|
+
* Checks a supplier authorization before the supplier grants capacity. It uses only the signed
|
|
6
|
+
* message, the supplier's own record of what it agreed to and the chain, and never asks Avow.
|
|
7
|
+
* It refuses with the first reason that applies. It passes once per commitment, and it records
|
|
8
|
+
* that only after every other check passes, so a refusal never uses it up.
|
|
9
|
+
*
|
|
10
|
+
* Throws when the config doesn't fit the chain, such as test data on a chain that isn't a
|
|
11
|
+
* testnet, because that's a setup mistake rather than a bad authorization.
|
|
12
|
+
*/
|
|
13
|
+
export async function verifySupplierAuthorization(input, deps) {
|
|
14
|
+
const checked = await checkAuthorization({ ...input, terms: { kind: 'plain', terms: input.terms } }, deps.config, deps.chain);
|
|
15
|
+
if (!checked.ok)
|
|
16
|
+
return checked;
|
|
17
|
+
const { authorization: auth, domain: d } = checked;
|
|
18
|
+
const { acceptBy } = enforceableTerms(input.terms);
|
|
19
|
+
// Last, so only an authorization that passed everything uses up its commitment.
|
|
20
|
+
const recorded = await deps.replay.recordAll([
|
|
21
|
+
{
|
|
22
|
+
key: commitmentKey('SupplierAuthorization', d, auth.commitmentId),
|
|
23
|
+
expiry: acceptBy > auth.expiry ? acceptBy : auth.expiry,
|
|
24
|
+
},
|
|
25
|
+
]);
|
|
26
|
+
if (!recorded)
|
|
27
|
+
return { ok: false, reason: 'message.replayed' };
|
|
28
|
+
return {
|
|
29
|
+
ok: true,
|
|
30
|
+
authorization: auth,
|
|
31
|
+
lock: checked.lock,
|
|
32
|
+
account: checked.lockInfo.account,
|
|
33
|
+
signer: checked.signer,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EACb,gBAAgB,GAMjB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAe,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAIpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAqD3D;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,KAAkB,EAClB,IAAkB;IAElB,MAAM,OAAO,GAAG,MAAM,kBAAkB,CACtC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,EAC1D,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,KAAK,CACX,CAAA;IACD,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,OAAO,OAAO,CAAA;IAC/B,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,CAAA;IAClD,MAAM,EAAE,QAAQ,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAElD,gFAAgF;IAChF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;QAC3C;YACE,GAAG,EAAE,aAAa,CAAC,uBAAuB,EAAE,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC;YACjE,MAAM,EAAE,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;SACxD;KACF,CAAC,CAAA;IACF,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAA;IAE/D,OAAO;QACL,EAAE,EAAE,IAAI;QACR,aAAa,EAAE,IAAI;QACnB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,OAAO;QACjC,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@avow-finance/verifier",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Lets a supplier check an Avow commitment's authorization, terms and on-chain reserve without calling Avow",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=22.12"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public",
|
|
12
|
+
"provenance": true
|
|
13
|
+
},
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/Avow-Finance/avow.git",
|
|
26
|
+
"directory": "packages/verifier"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"viem": "2.57.11",
|
|
30
|
+
"@avow-finance/spec": "0.2.0"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc -p tsconfig.build.json",
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
36
|
+
}
|
|
6
37
|
}
|