@0xdivyanshh/tab-sdk 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.
- package/README.md +54 -0
- package/dist/client.d.ts +48 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +140 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +39 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +62 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/receipts.d.ts +81 -0
- package/dist/receipts.d.ts.map +1 -0
- package/dist/receipts.js +309 -0
- package/dist/receipts.js.map +1 -0
- package/dist/spend.d.ts +22 -0
- package/dist/spend.d.ts.map +1 -0
- package/dist/spend.js +185 -0
- package/dist/spend.js.map +1 -0
- package/dist/types.d.ts +324 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +35 -0
package/dist/receipts.js
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { REFUSAL_CODES, WEIGHT_REASONS } from '@0xdivyanshh/tab-protocol';
|
|
2
|
+
import { TabInvalidError } from "./errors.js";
|
|
3
|
+
import { parseAmount } from "./spend.js";
|
|
4
|
+
/**
|
|
5
|
+
* Validated, not cast.
|
|
6
|
+
*
|
|
7
|
+
* A cast would type an unknown string as a valid refusal code, and the UI would
|
|
8
|
+
* then render a rule that does not exist — or worse, `isRetryable` would return
|
|
9
|
+
* false for it and an agent would stop retrying something it should retry. An
|
|
10
|
+
* unrecognised rule is dropped, which shows as a refusal with no rule rather
|
|
11
|
+
* than a refusal with a fictional one.
|
|
12
|
+
*/
|
|
13
|
+
function knownRule(value) {
|
|
14
|
+
return typeof value === 'string' && REFUSAL_CODES.includes(value);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Receipt history and pending holds.
|
|
18
|
+
*
|
|
19
|
+
* Both read the gateway's projection rather than HCS directly, because this
|
|
20
|
+
* package must stay browser-safe and a browser has no business walking a topic.
|
|
21
|
+
* A consumer that wants to verify rather than display should run
|
|
22
|
+
* `pnpm verify-tab`, which replays the topic itself and trusts nothing we say.
|
|
23
|
+
*/
|
|
24
|
+
export async function holds(client, tab) {
|
|
25
|
+
if (!tab)
|
|
26
|
+
throw new TabInvalidError('holds() needs a tab id');
|
|
27
|
+
const rows = await client.request('GET', `/v1/tabs/${tab}/holds`);
|
|
28
|
+
return rows.map((r) => ({
|
|
29
|
+
holdId: String(r['holdId']),
|
|
30
|
+
counterparty: String(r['counterparty']),
|
|
31
|
+
amount: parseAmount(r['amount'], 'hold.amount'),
|
|
32
|
+
at: String(r['at']),
|
|
33
|
+
expiresAt: String(r['expiresAt']),
|
|
34
|
+
status: r['status'] ?? 'pending',
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
export async function receipts(client, tab) {
|
|
38
|
+
if (!tab)
|
|
39
|
+
throw new TabInvalidError('receipts() needs a tab id');
|
|
40
|
+
const rows = await client.request('GET', `/v1/tabs/${tab}/entries`);
|
|
41
|
+
return rows.map((r) => {
|
|
42
|
+
const leg = String(r['kind']);
|
|
43
|
+
return {
|
|
44
|
+
leg,
|
|
45
|
+
at: String(r['at']),
|
|
46
|
+
window: Number(r['window'] ?? 0),
|
|
47
|
+
...(r['seq'] !== undefined && r['seq'] !== null ? { seq: Number(r['seq']) } : {}),
|
|
48
|
+
...(r['requestHash'] ? { requestHash: String(r['requestHash']) } : {}),
|
|
49
|
+
...(r['token'] ? { token: String(r['token']) } : {}),
|
|
50
|
+
...(r['counterparty'] ? { counterparty: String(r['counterparty']) } : {}),
|
|
51
|
+
/*
|
|
52
|
+
* A refusal carries `requested`, not `amount` — it moved no money, and
|
|
53
|
+
* conflating the two would make the Refusals view show refused intent as
|
|
54
|
+
* though it were spend. Whichever is present is mapped to `amount` so a
|
|
55
|
+
* table can render one column, and `leg` tells a reader which it is.
|
|
56
|
+
*/
|
|
57
|
+
...(r['amount'] !== undefined && r['amount'] !== null
|
|
58
|
+
? { amount: parseAmount(r['amount'], `${leg}.amount`) }
|
|
59
|
+
: r['requested'] !== undefined && r['requested'] !== null
|
|
60
|
+
? { amount: parseAmount(r['requested'], `${leg}.requested`) }
|
|
61
|
+
: {}),
|
|
62
|
+
...(typeof r['attested'] === 'boolean' ? { attested: r['attested'] } : {}),
|
|
63
|
+
...(r['transactionId'] ? { transactionId: String(r['transactionId']) } : {}),
|
|
64
|
+
...(r['holdId'] ? { holdId: String(r['holdId']) } : {}),
|
|
65
|
+
...(knownRule(r['rule']) ? { rule: r['rule'] } : {}),
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/** Is the gateway up, and which network and window is it on? */
|
|
70
|
+
export async function health(client) {
|
|
71
|
+
const body = await client.request('GET', '/health');
|
|
72
|
+
const topics = body['topics'];
|
|
73
|
+
return {
|
|
74
|
+
ok: body['ok'] === true,
|
|
75
|
+
network: String(body['network'] ?? 'unknown'),
|
|
76
|
+
token: String(body['token'] ?? ''),
|
|
77
|
+
window: Number(body['window'] ?? 0),
|
|
78
|
+
demoMode: body['demoMode'] === true,
|
|
79
|
+
...(topics?.['receipts'] && topics['ceilings'] && topics['settlements']
|
|
80
|
+
? {
|
|
81
|
+
topics: {
|
|
82
|
+
receipts: String(topics['receipts']),
|
|
83
|
+
ceilings: String(topics['ceilings']),
|
|
84
|
+
settlements: String(topics['settlements']),
|
|
85
|
+
},
|
|
86
|
+
}
|
|
87
|
+
: {}),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Published independence weights for a tab's counterparties.
|
|
92
|
+
*
|
|
93
|
+
* Reason codes are VALIDATED against `WEIGHT_REASONS`, not cast — an unknown
|
|
94
|
+
* reason from a newer server is dropped rather than typed as a real one, for
|
|
95
|
+
* the same reason an unknown refusal code is: the console would otherwise
|
|
96
|
+
* render a rule that does not exist, and `isBlocking` would answer confidently
|
|
97
|
+
* about it.
|
|
98
|
+
*/
|
|
99
|
+
export async function counterparties(client, tab) {
|
|
100
|
+
if (!tab)
|
|
101
|
+
throw new TabInvalidError('counterparties() needs a tab id');
|
|
102
|
+
const rows = await client.request('GET', `/v1/tabs/${tab}/counterparties`);
|
|
103
|
+
return rows.map((r) => {
|
|
104
|
+
const raw = Array.isArray(r['reasons']) ? r['reasons'] : [];
|
|
105
|
+
const reasons = raw.filter(knownReason);
|
|
106
|
+
return {
|
|
107
|
+
counterparty: String(r['counterparty']),
|
|
108
|
+
bp: Number(r['bp'] ?? 0),
|
|
109
|
+
/*
|
|
110
|
+
* Never empty, even if every reason was unrecognised.
|
|
111
|
+
*
|
|
112
|
+
* A weight with no reason is unreadable in the console, so an unknown
|
|
113
|
+
* vocabulary degrades to `INDEPENDENT` ONLY when the weight is full —
|
|
114
|
+
* otherwise it stays empty and the view shows the number without a
|
|
115
|
+
* fabricated justification for it.
|
|
116
|
+
*/
|
|
117
|
+
reasons: reasons.length > 0
|
|
118
|
+
? reasons
|
|
119
|
+
: Number(r['bp'] ?? 0) === 10_000
|
|
120
|
+
? ['INDEPENDENT']
|
|
121
|
+
: [],
|
|
122
|
+
blocking: r['blocking'] === true,
|
|
123
|
+
revenue: parseAmount(r['revenue'], 'counterparty.revenue'),
|
|
124
|
+
shareBp: Number(r['shareBp'] ?? 0),
|
|
125
|
+
window: Number(r['window'] ?? 0),
|
|
126
|
+
at: String(r['at']),
|
|
127
|
+
...(r['token'] ? { token: String(r['token']) } : {}),
|
|
128
|
+
// Absent stays absent — see `CounterpartyWeight` for why defaulting any
|
|
129
|
+
// of these would fabricate the evidence the panel exists to show.
|
|
130
|
+
...(r['firstSeen'] ? { firstSeen: String(r['firstSeen']) } : {}),
|
|
131
|
+
...(r['funder'] ? { funder: String(r['funder']) } : {}),
|
|
132
|
+
...(r['funderSeq'] !== undefined && r['funderSeq'] !== null
|
|
133
|
+
? { funderSeq: Number(r['funderSeq']) }
|
|
134
|
+
: {}),
|
|
135
|
+
...(r['tabFunder'] ? { tabFunder: String(r['tabFunder']) } : {}),
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
function knownReason(value) {
|
|
140
|
+
return typeof value === 'string' && WEIGHT_REASONS.includes(value);
|
|
141
|
+
}
|
|
142
|
+
const TIERS = ['A', 'B', 'C', 'Unrated'];
|
|
143
|
+
const OUTCOMES = ['clean', 'missed', 'carried'];
|
|
144
|
+
/** Validated, not cast — an unknown tier would render as a real one. */
|
|
145
|
+
function tierOf(value) {
|
|
146
|
+
return typeof value === 'string' && TIERS.includes(value)
|
|
147
|
+
? value
|
|
148
|
+
: 'Unrated';
|
|
149
|
+
}
|
|
150
|
+
function outcomeOf(value) {
|
|
151
|
+
return typeof value === 'string' && OUTCOMES.includes(value)
|
|
152
|
+
? value
|
|
153
|
+
: 'carried';
|
|
154
|
+
}
|
|
155
|
+
function ceilingOf(r) {
|
|
156
|
+
const inputs = (r['inputs'] ?? {});
|
|
157
|
+
return {
|
|
158
|
+
ceiling: parseAmount(r['ceiling'], 'ceiling.ceiling'),
|
|
159
|
+
...(r['computed'] !== undefined && r['computed'] !== null
|
|
160
|
+
? { computed: parseAmount(r['computed'], 'ceiling.computed') }
|
|
161
|
+
: {}),
|
|
162
|
+
window: Number(r['window'] ?? 0),
|
|
163
|
+
binding: String(r['binding'] ?? 'unknown'),
|
|
164
|
+
cause: String(r['cause'] ?? 'unknown'),
|
|
165
|
+
at: String(r['at'] ?? ''),
|
|
166
|
+
model: String(r['model'] ?? ''),
|
|
167
|
+
hash: String(r['hash'] ?? ''),
|
|
168
|
+
...(r['seq'] !== undefined && r['seq'] !== null ? { seq: Number(r['seq']) } : {}),
|
|
169
|
+
inputs: {
|
|
170
|
+
revenue: parseAmount(inputs['revenue'], 'ceiling.inputs.revenue'),
|
|
171
|
+
revenueAttested: parseAmount(inputs['revenueAttested'], 'ceiling.inputs.revenueAttested'),
|
|
172
|
+
revenueUnattested: parseAmount(inputs['revenueUnattested'], 'ceiling.inputs.revenueUnattested'),
|
|
173
|
+
tier: tierOf(inputs['tier']),
|
|
174
|
+
multBp: Number(inputs['multBp'] ?? 0),
|
|
175
|
+
rampBp: Number(inputs['rampBp'] ?? 0),
|
|
176
|
+
cap: parseAmount(inputs['cap'], 'ceiling.inputs.cap'),
|
|
177
|
+
floor: parseAmount(inputs['floor'], 'ceiling.inputs.floor'),
|
|
178
|
+
defaulted: inputs['defaulted'] === true,
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* The ceiling in force, its arithmetic, and the series behind it.
|
|
184
|
+
*
|
|
185
|
+
* Read from what the ENGINE published, never recomputed — the SDK is
|
|
186
|
+
* browser-safe and cannot import `@0xdivyanshh/tab-scoring`, and that is the right
|
|
187
|
+
* constraint. A client that recomputed the ceiling would hand a viewer a second
|
|
188
|
+
* answer to compare against the topic, and two answers is worse than one even
|
|
189
|
+
* when they agree.
|
|
190
|
+
*
|
|
191
|
+
* `published: false` is not an error. It means the engine has not run for this
|
|
192
|
+
* tab yet and the starter ceiling is in force — `enforced` says what that is.
|
|
193
|
+
*/
|
|
194
|
+
export async function ceiling(client, tab) {
|
|
195
|
+
if (!tab)
|
|
196
|
+
throw new TabInvalidError('ceiling() needs a tab id');
|
|
197
|
+
const body = await client.request('GET', `/v1/tabs/${tab}/ceiling`);
|
|
198
|
+
const history = (Array.isArray(body['history']) ? body['history'] : []).map((row) => ceilingOf(row));
|
|
199
|
+
const published = body['published'] === true;
|
|
200
|
+
return {
|
|
201
|
+
tab: String(body['tab'] ?? tab),
|
|
202
|
+
published,
|
|
203
|
+
enforced: parseAmount(body['enforced'], 'ceiling.enforced'),
|
|
204
|
+
// `current` is the last history element rather than a separate parse of the
|
|
205
|
+
// top-level fields, so "the number in force" and "the last point on the
|
|
206
|
+
// chart" cannot disagree on screen.
|
|
207
|
+
...(published && history.length > 0 ? { current: history[history.length - 1] } : {}),
|
|
208
|
+
history,
|
|
209
|
+
...(body['note'] ? { note: String(body['note']) } : {}),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Settled windows, ascending by window.
|
|
214
|
+
*
|
|
215
|
+
* Ordered by WINDOW rather than by arrival: a repaired or late settlement lands
|
|
216
|
+
* on the topic after the windows that follow it, and a table sorted by
|
|
217
|
+
* timestamp would put window 41 above window 39 with no explanation.
|
|
218
|
+
*
|
|
219
|
+
* The gross legs come through as absent when the topic did not carry them. A
|
|
220
|
+
* caller must render that as "not published", never as zero.
|
|
221
|
+
*/
|
|
222
|
+
export async function settlements(client, tab) {
|
|
223
|
+
if (!tab)
|
|
224
|
+
throw new TabInvalidError('settlements() needs a tab id');
|
|
225
|
+
const rows = await client.request('GET', `/v1/tabs/${tab}/settlements`);
|
|
226
|
+
return rows.map((r) => ({
|
|
227
|
+
window: Number(r['window'] ?? 0),
|
|
228
|
+
at: String(r['at'] ?? ''),
|
|
229
|
+
...(r['seq'] !== undefined && r['seq'] !== null ? { seq: Number(r['seq']) } : {}),
|
|
230
|
+
net: parseAmount(r['net'], 'settlement.net'),
|
|
231
|
+
...(r['credits'] !== undefined && r['credits'] !== null
|
|
232
|
+
? { credits: parseAmount(r['credits'], 'settlement.credits') }
|
|
233
|
+
: {}),
|
|
234
|
+
...(r['debits'] !== undefined && r['debits'] !== null
|
|
235
|
+
? { debits: parseAmount(r['debits'], 'settlement.debits') }
|
|
236
|
+
: {}),
|
|
237
|
+
...(r['interest'] !== undefined && r['interest'] !== null
|
|
238
|
+
? { interest: parseAmount(r['interest'], 'settlement.interest') }
|
|
239
|
+
: {}),
|
|
240
|
+
...(r['outstanding'] !== undefined && r['outstanding'] !== null
|
|
241
|
+
? { outstanding: parseAmount(r['outstanding'], 'settlement.outstanding') }
|
|
242
|
+
: {}),
|
|
243
|
+
...(r['receiptCount'] !== undefined && r['receiptCount'] !== null
|
|
244
|
+
? { receiptCount: Number(r['receiptCount']) }
|
|
245
|
+
: {}),
|
|
246
|
+
outcome: outcomeOf(r['outcome']),
|
|
247
|
+
rampFromBp: Number(r['rampFromBp'] ?? 0),
|
|
248
|
+
rampToBp: Number(r['rampToBp'] ?? 0),
|
|
249
|
+
...(r['transactionId'] ? { transactionId: String(r['transactionId']) } : {}),
|
|
250
|
+
...(r['token'] ? { token: String(r['token']) } : {}),
|
|
251
|
+
}));
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* The tabs this gateway knows about.
|
|
255
|
+
*
|
|
256
|
+
* Named `tabs`, not `registry`, and the response carries
|
|
257
|
+
* `registrationEnforced: false` so a caller cannot mistake it for one. Nothing
|
|
258
|
+
* writes a `register` message yet — one Starter Tab per funding root is
|
|
259
|
+
* unenforced and the README labels it OPEN — so a tab appears here the first
|
|
260
|
+
* time it spends or earns, and there is no registration time to report.
|
|
261
|
+
*/
|
|
262
|
+
export async function tabs(client) {
|
|
263
|
+
const body = await client.request('GET', '/v1/tabs');
|
|
264
|
+
const rows = Array.isArray(body['tabs']) ? body['tabs'] : [];
|
|
265
|
+
return {
|
|
266
|
+
window: Number(body['window'] ?? 0),
|
|
267
|
+
/*
|
|
268
|
+
* Defaults to FALSE when the field is absent, never true.
|
|
269
|
+
*
|
|
270
|
+
* An older gateway that does not send it has no registration flow either,
|
|
271
|
+
* so absence means unenforced. Defaulting the permissive way round would
|
|
272
|
+
* let a stale server silently license the "Registry" heading.
|
|
273
|
+
*/
|
|
274
|
+
registrationEnforced: body['registrationEnforced'] === true,
|
|
275
|
+
rootsClaimed: Number(body['rootsClaimed'] ?? 0),
|
|
276
|
+
note: String(body['note'] ?? ''),
|
|
277
|
+
tabs: rows.map((raw) => {
|
|
278
|
+
const r = raw;
|
|
279
|
+
const summary = {
|
|
280
|
+
tab: String(r['tab']),
|
|
281
|
+
balance: parseAmount(r['balance'], 'tab.balance'),
|
|
282
|
+
outstanding: parseAmount(r['outstanding'], 'tab.outstanding'),
|
|
283
|
+
holds: parseAmount(r['holds'], 'tab.holds'),
|
|
284
|
+
available: parseAmount(r['available'], 'tab.available'),
|
|
285
|
+
ceiling: parseAmount(r['ceiling'], 'tab.ceiling'),
|
|
286
|
+
entries: Number(r['entries'] ?? 0),
|
|
287
|
+
// Absent stays absent. An unpublished tab has no tier, which is not the
|
|
288
|
+
// same as being Unrated.
|
|
289
|
+
...(r['tier'] !== undefined && r['tier'] !== null ? { tier: tierOf(r['tier']) } : {}),
|
|
290
|
+
...(r['publishedCeiling'] !== undefined && r['publishedCeiling'] !== null
|
|
291
|
+
? { publishedCeiling: parseAmount(r['publishedCeiling'], 'tab.publishedCeiling') }
|
|
292
|
+
: {}),
|
|
293
|
+
...(r['binding'] ? { binding: String(r['binding']) } : {}),
|
|
294
|
+
...(r['cause'] ? { cause: String(r['cause']) } : {}),
|
|
295
|
+
...(r['model'] ? { model: String(r['model']) } : {}),
|
|
296
|
+
...(r['seq'] !== undefined && r['seq'] !== null ? { seq: Number(r['seq']) } : {}),
|
|
297
|
+
// Absent stays absent: no claim recorded is not the same as denied.
|
|
298
|
+
...(r['registeredRoot'] ? { registeredRoot: String(r['registeredRoot']) } : {}),
|
|
299
|
+
...(r['registeredAt'] ? { registeredAt: String(r['registeredAt']) } : {}),
|
|
300
|
+
...(r['registrationSeq'] !== undefined && r['registrationSeq'] !== null
|
|
301
|
+
? { registrationSeq: Number(r['registrationSeq']) }
|
|
302
|
+
: {}),
|
|
303
|
+
...(r['uaid'] ? { uaid: String(r['uaid']) } : {}),
|
|
304
|
+
};
|
|
305
|
+
return summary;
|
|
306
|
+
}),
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
//# sourceMappingURL=receipts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receipts.js","sourceRoot":"","sources":["../src/receipts.ts"],"names":[],"mappings":"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"}
|
package/dist/spend.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type MicroUsdc } from '@0xdivyanshh/tab-money';
|
|
2
|
+
import type { TabClient } from './client.ts';
|
|
3
|
+
import type { Quote, SpendRequest, SpendResult, TabState } from './types.ts';
|
|
4
|
+
/** Parse a wire amount, with a message that names the field. */
|
|
5
|
+
declare function amount(value: unknown, field: string): MicroUsdc;
|
|
6
|
+
export declare function spend(client: TabClient, request: SpendRequest): Promise<SpendResult>;
|
|
7
|
+
/**
|
|
8
|
+
* What could this tab afford right now, without reserving anything.
|
|
9
|
+
*
|
|
10
|
+
* Derived from `state()` rather than a dedicated endpoint, and deliberately so:
|
|
11
|
+
* a quote that took a hold would leave a hold that never commits, which is
|
|
12
|
+
* exactly the shape the reconciler exists to clean up. This reserves nothing
|
|
13
|
+
* and therefore guarantees nothing — between a quote and a spend, another call
|
|
14
|
+
* on the same tab can take the headroom.
|
|
15
|
+
*/
|
|
16
|
+
export declare function quote(client: TabClient, params: {
|
|
17
|
+
tab: string;
|
|
18
|
+
max: MicroUsdc;
|
|
19
|
+
}): Promise<Quote>;
|
|
20
|
+
export declare function state(client: TabClient, tab: string): Promise<TabState>;
|
|
21
|
+
export { amount as parseAmount };
|
|
22
|
+
//# sourceMappingURL=spend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spend.d.ts","sourceRoot":"","sources":["../src/spend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,YAAY,CAAA;AAGzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AA4B5E,gEAAgE;AAChE,iBAAS,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CA2CxD;AAED,wBAAsB,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAiF1F;AAED;;;;;;;;GAQG;AACH,wBAAsB,KAAK,CACzB,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,SAAS,CAAA;CAAE,GACtC,OAAO,CAAC,KAAK,CAAC,CAgChB;AAED,wBAAsB,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAc7E;AAED,OAAO,EAAE,MAAM,IAAI,WAAW,EAAE,CAAA"}
|
package/dist/spend.js
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { toWire, usdc } from '@0xdivyanshh/tab-money';
|
|
2
|
+
import { isRetryable, REFUSAL_GUIDANCE } from '@0xdivyanshh/tab-protocol';
|
|
3
|
+
import { TabInvalidError, TabProtocolError } from "./errors.js";
|
|
4
|
+
/**
|
|
5
|
+
* Spend, quote, and read state.
|
|
6
|
+
*
|
|
7
|
+
* The one design decision worth restating: **a refusal is a value.** `spend()`
|
|
8
|
+
* returns a discriminated result carrying the rule that fired, because refusal
|
|
9
|
+
* is the product demonstrating that underwriting works — not an error
|
|
10
|
+
* condition. Throwing would push every consumer into `try/catch` and make the
|
|
11
|
+
* Refusals view harder to build than the happy path.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* A key that makes a retry safe.
|
|
15
|
+
*
|
|
16
|
+
* The gateway treats it as the hold id, so the same key cannot spend twice. It
|
|
17
|
+
* is generated HERE rather than in the gateway because only the caller can
|
|
18
|
+
* decide that two calls are the same intent — and it is returned on every
|
|
19
|
+
* outcome, including failures, so a caller retrying an unknown outcome can
|
|
20
|
+
* reuse it.
|
|
21
|
+
*
|
|
22
|
+
* `crypto.randomUUID` is available in Node 19+ and every modern browser, which
|
|
23
|
+
* keeps this package browser-safe with no dependency.
|
|
24
|
+
*/
|
|
25
|
+
function newIdempotencyKey() {
|
|
26
|
+
return `h_${globalThis.crypto.randomUUID().replace(/-/g, '').slice(0, 16)}`;
|
|
27
|
+
}
|
|
28
|
+
/** Parse a wire amount, with a message that names the field. */
|
|
29
|
+
function amount(value, field) {
|
|
30
|
+
if (typeof value !== 'string') {
|
|
31
|
+
throw new TabProtocolError(`Expected "${field}" to be a decimal string amount, got ${typeof value}`, 200, value);
|
|
32
|
+
}
|
|
33
|
+
/*
|
|
34
|
+
* STRICT — exactly six decimals and an ASCII minus, which is what `toWire`
|
|
35
|
+
* emits and nothing else.
|
|
36
|
+
*
|
|
37
|
+
* `usdc()` alone is not enough here, and a test caught that: it is tolerant
|
|
38
|
+
* by design, accepting a U+2212 minus and padding a 4-decimal value. That
|
|
39
|
+
* tolerance is right for human input and wrong for a wire parser, because it
|
|
40
|
+
* makes silent data loss undetectable — the gateway once served `format()`
|
|
41
|
+
* output where a wire value belonged, `1.234567` went out as `"1.2345"`, and
|
|
42
|
+
* `usdc()` would have happily parsed it as `1234500`. Sixty-seven
|
|
43
|
+
* micro-USDC per value, no error, and a dashboard that cannot match
|
|
44
|
+
* HashScan.
|
|
45
|
+
*
|
|
46
|
+
* So the shape is checked before parsing, and a display string is rejected
|
|
47
|
+
* with a message that names the actual cause.
|
|
48
|
+
*/
|
|
49
|
+
if (!/^-?\d+\.\d{6}$/.test(value)) {
|
|
50
|
+
throw new TabProtocolError(`"${field}" = ${JSON.stringify(value)} is not a wire amount. ` +
|
|
51
|
+
'Exactly six decimals and an ASCII minus are required (`toWire`). Four decimals or a ' +
|
|
52
|
+
'U+2212 minus means the server serialised a DISPLAY string instead of a wire value, ' +
|
|
53
|
+
'which is lossy — do not "fix" this by loosening the check.', 200, value);
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
return usdc(value);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
throw new TabProtocolError(`"${field}" = ${JSON.stringify(value)} has the right shape but did not parse`, 200, error);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export async function spend(client, request) {
|
|
63
|
+
if (!request.tab)
|
|
64
|
+
throw new TabInvalidError('spend() needs a tab id');
|
|
65
|
+
if (!request.url)
|
|
66
|
+
throw new TabInvalidError('spend() needs a seller url');
|
|
67
|
+
if (request.max !== undefined && request.max <= 0n) {
|
|
68
|
+
// A zero or negative max is a programming error, not a refusal: there is no
|
|
69
|
+
// spend to underwrite, so the rail has nothing to decide.
|
|
70
|
+
throw new TabInvalidError(`spend() needs a positive max, got ${request.max}`);
|
|
71
|
+
}
|
|
72
|
+
const idempotencyKey = request.idempotencyKey ?? newIdempotencyKey();
|
|
73
|
+
const body = await client.request('POST', '/v1/spend', {
|
|
74
|
+
tab: request.tab,
|
|
75
|
+
url: request.url,
|
|
76
|
+
// Absent means "accept the seller's quote"; the gateway reads it from the
|
|
77
|
+
// 402. Sending an explicit null would instead be a value the gateway must
|
|
78
|
+
// interpret, so the key is simply left off.
|
|
79
|
+
...(request.max !== undefined ? { max: toWire(request.max) } : {}),
|
|
80
|
+
idempotencyKey,
|
|
81
|
+
...(request.init ? { init: request.init } : {}),
|
|
82
|
+
});
|
|
83
|
+
if (body.refused) {
|
|
84
|
+
const rule = body.refused.rule;
|
|
85
|
+
return {
|
|
86
|
+
outcome: 'refused',
|
|
87
|
+
rule,
|
|
88
|
+
reason: body.refused.reason,
|
|
89
|
+
/*
|
|
90
|
+
* Guidance comes from `@0xdivyanshh/tab-protocol`, not from the server's message.
|
|
91
|
+
*
|
|
92
|
+
* The rule code is the contract; the prose is not. Taking guidance from
|
|
93
|
+
* the wire would let a server version change what an agent does next
|
|
94
|
+
* without any consumer noticing.
|
|
95
|
+
*/
|
|
96
|
+
guidance: REFUSAL_GUIDANCE[rule] ?? 'Surface this to the operator.',
|
|
97
|
+
retryable: isRetryable(rule),
|
|
98
|
+
...(body.refused.evidence ? { evidence: body.refused.evidence } : {}),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
if (body.paid) {
|
|
102
|
+
return {
|
|
103
|
+
outcome: 'paid',
|
|
104
|
+
amount: amount(body.paid.amount, 'paid.amount'),
|
|
105
|
+
seller: body.paid.seller,
|
|
106
|
+
holdId: body.paid.holdId,
|
|
107
|
+
receiptSeq: body.paid.receiptSeq,
|
|
108
|
+
body: body.body ?? null,
|
|
109
|
+
elapsedMs: body.paid.elapsedMs,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
if (body.failed) {
|
|
113
|
+
return { outcome: 'failed', reason: body.failed.reason, holdId: body.failed.holdId };
|
|
114
|
+
}
|
|
115
|
+
/*
|
|
116
|
+
* Infrastructure failure reported through the top-level `error` field.
|
|
117
|
+
*
|
|
118
|
+
* Returned as `failed` rather than thrown, carrying the idempotency key —
|
|
119
|
+
* the caller needs that key to retry safely, and an exception would discard
|
|
120
|
+
* the one piece of information that makes the retry safe.
|
|
121
|
+
*/
|
|
122
|
+
if (body.error) {
|
|
123
|
+
return { outcome: 'failed', reason: body.error, holdId: idempotencyKey };
|
|
124
|
+
}
|
|
125
|
+
throw new TabProtocolError('The gateway returned neither paid, refused, nor failed', 200, body);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* What could this tab afford right now, without reserving anything.
|
|
129
|
+
*
|
|
130
|
+
* Derived from `state()` rather than a dedicated endpoint, and deliberately so:
|
|
131
|
+
* a quote that took a hold would leave a hold that never commits, which is
|
|
132
|
+
* exactly the shape the reconciler exists to clean up. This reserves nothing
|
|
133
|
+
* and therefore guarantees nothing — between a quote and a spend, another call
|
|
134
|
+
* on the same tab can take the headroom.
|
|
135
|
+
*/
|
|
136
|
+
export async function quote(client, params) {
|
|
137
|
+
const s = await state(client, params.tab);
|
|
138
|
+
if (params.max > s.perCallCap) {
|
|
139
|
+
return {
|
|
140
|
+
tab: s.tab,
|
|
141
|
+
affordable: false,
|
|
142
|
+
available: s.available,
|
|
143
|
+
ceiling: s.ceiling,
|
|
144
|
+
perCallCap: s.perCallCap,
|
|
145
|
+
wouldRefuse: 'PER_CALL_CAP',
|
|
146
|
+
reason: `${toWire(params.max)} exceeds the per-call cap of ${toWire(s.perCallCap)}`,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (params.max > s.available) {
|
|
150
|
+
return {
|
|
151
|
+
tab: s.tab,
|
|
152
|
+
affordable: false,
|
|
153
|
+
available: s.available,
|
|
154
|
+
ceiling: s.ceiling,
|
|
155
|
+
perCallCap: s.perCallCap,
|
|
156
|
+
wouldRefuse: 'CEILING_EXCEEDED',
|
|
157
|
+
reason: `${toWire(params.max)} exceeds the available ${toWire(s.available)} under a ceiling of ${toWire(s.ceiling)}`,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
tab: s.tab,
|
|
162
|
+
affordable: true,
|
|
163
|
+
available: s.available,
|
|
164
|
+
ceiling: s.ceiling,
|
|
165
|
+
perCallCap: s.perCallCap,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
export async function state(client, tab) {
|
|
169
|
+
if (!tab)
|
|
170
|
+
throw new TabInvalidError('state() needs a tab id');
|
|
171
|
+
const body = await client.request('GET', `/v1/tabs/${tab}`);
|
|
172
|
+
return {
|
|
173
|
+
tab: String(body['tab'] ?? tab),
|
|
174
|
+
balance: amount(body['balance'], 'balance'),
|
|
175
|
+
outstanding: amount(body['outstanding'], 'outstanding'),
|
|
176
|
+
holds: amount(body['holds'], 'holds'),
|
|
177
|
+
available: amount(body['available'], 'available'),
|
|
178
|
+
ceiling: amount(body['ceiling'], 'ceiling'),
|
|
179
|
+
perCallCap: amount(body['perCallCap'], 'perCallCap'),
|
|
180
|
+
window: Number(body['window'] ?? 0),
|
|
181
|
+
entries: Number(body['entries'] ?? 0),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
export { amount as parseAmount };
|
|
185
|
+
//# sourceMappingURL=spend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spend.js","sourceRoot":"","sources":["../src/spend.ts"],"names":[],"mappings":"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"}
|