@obbyx/sdk 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +89 -2
- package/dist/client/budget.d.ts +43 -0
- package/dist/client/budget.d.ts.map +1 -0
- package/dist/client/budget.js +56 -0
- package/dist/client/budget.js.map +1 -0
- package/dist/client/paying-fetch.d.ts +46 -0
- package/dist/client/paying-fetch.d.ts.map +1 -0
- package/dist/client/paying-fetch.js +186 -0
- package/dist/client/paying-fetch.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/seller/binding.d.ts +2 -0
- package/dist/seller/binding.d.ts.map +1 -0
- package/dist/seller/binding.js +3 -0
- package/dist/seller/binding.js.map +1 -0
- package/dist/seller/consumed-proofs.d.ts +72 -0
- package/dist/seller/consumed-proofs.d.ts.map +1 -0
- package/dist/seller/consumed-proofs.js +123 -0
- package/dist/seller/consumed-proofs.js.map +1 -0
- package/dist/seller/payment-identifier.d.ts +73 -0
- package/dist/seller/payment-identifier.d.ts.map +1 -0
- package/dist/seller/payment-identifier.js +75 -0
- package/dist/seller/payment-identifier.js.map +1 -0
- package/dist/seller/paywall.d.ts +99 -0
- package/dist/seller/paywall.d.ts.map +1 -0
- package/dist/seller/paywall.js +372 -0
- package/dist/seller/paywall.js.map +1 -0
- package/dist/seller/quote.d.ts +38 -0
- package/dist/seller/quote.d.ts.map +1 -0
- package/dist/seller/quote.js +39 -0
- package/dist/seller/quote.js.map +1 -0
- package/dist/seller/x402-server.d.ts +57 -0
- package/dist/seller/x402-server.d.ts.map +1 -0
- package/dist/seller/x402-server.js +152 -0
- package/dist/seller/x402-server.js.map +1 -0
- package/package.json +68 -3
- package/src/client/budget.ts +88 -0
- package/src/client/paying-fetch.ts +256 -0
- package/src/index.ts +35 -0
- package/src/seller/binding.ts +8 -0
- package/src/seller/consumed-proofs.ts +217 -0
- package/src/seller/payment-identifier.ts +104 -0
- package/src/seller/paywall.ts +566 -0
- package/src/seller/quote.ts +82 -0
- package/src/seller/x402-server.ts +224 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import { decodePaymentSignatureHeader, encodePaymentRequiredHeader, encodePaymentResponseHeader, } from '@x402/core/http';
|
|
2
|
+
import { CHANNEL_BASE_AA, getNetwork, isAddress, isAssetId, networkKey, parseAmount, } from '@obbyx/obyte';
|
|
3
|
+
import { moduleLogger, withLogContext } from '@obbyx/obyte/logger';
|
|
4
|
+
import { BATCH_SCHEME, EXACT_SCHEME, batchExtraSchema, canonical, exactExtraSchema, } from '@obbyx/x402-obyte';
|
|
5
|
+
import { bindingsEqual, sha256Hex } from './binding.js';
|
|
6
|
+
import { PAYMENT_IDENTIFIER, decidePaymentId, paymentIdOf, paymentIdentifierDeclaration, } from './payment-identifier.js';
|
|
7
|
+
import { bodyHashOf, newQuote, offerBinding, operationFingerprint, } from './quote.js';
|
|
8
|
+
const EXPOSE = 'PAYMENT-REQUIRED, PAYMENT-RESPONSE';
|
|
9
|
+
export class ObytePaywall {
|
|
10
|
+
options;
|
|
11
|
+
log;
|
|
12
|
+
now;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.options = options;
|
|
15
|
+
getNetwork(options.network);
|
|
16
|
+
if (!isAddress(options.payTo))
|
|
17
|
+
throw new Error('payTo must be a valid Obyte address');
|
|
18
|
+
if ((typeof options.secret === 'string'
|
|
19
|
+
? Buffer.byteLength(options.secret)
|
|
20
|
+
: options.secret.length) < 32) {
|
|
21
|
+
throw new Error('secret must be at least 32 bytes');
|
|
22
|
+
}
|
|
23
|
+
this.log = moduleLogger(options.logger, 'sdk.paywall', { network: options.network });
|
|
24
|
+
this.now = options.now ?? (() => Math.floor(Date.now() / 1000));
|
|
25
|
+
}
|
|
26
|
+
/** Wraps a handler so it only runs after a settled payment. */
|
|
27
|
+
paid(route, handler) {
|
|
28
|
+
const asset = route.price.asset ?? 'base';
|
|
29
|
+
if (!isAssetId(asset))
|
|
30
|
+
throw new Error(`Invalid asset ${asset}`);
|
|
31
|
+
const amount = parseAmount(route.price.amount).toString();
|
|
32
|
+
return (req, res, next) => {
|
|
33
|
+
const requestId = String(req.get('x-request-id') ?? cryptoId());
|
|
34
|
+
withLogContext({ requestId, network: this.options.network }, () => this.handle(req, res, route, { asset, amount }, handler).catch(next));
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
async handle(req, res, route, price, handler) {
|
|
38
|
+
res.setHeader('Access-Control-Expose-Headers', EXPOSE);
|
|
39
|
+
res.setHeader('Cache-Control', 'private, no-store');
|
|
40
|
+
const header = req.get('payment-signature');
|
|
41
|
+
if (header === undefined)
|
|
42
|
+
return this.paymentRequired(req, res, route, price);
|
|
43
|
+
let payload;
|
|
44
|
+
try {
|
|
45
|
+
payload = decodePaymentSignatureHeader(header);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
res.status(400).json({ error: 'invalid_payment_header' });
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const accepted = payload.accepted;
|
|
52
|
+
const scheme = accepted?.scheme;
|
|
53
|
+
const offered = this.schemesFor(route);
|
|
54
|
+
const extra = scheme === EXACT_SCHEME
|
|
55
|
+
? exactExtraSchema.safeParse(accepted?.extra)
|
|
56
|
+
: scheme === BATCH_SCHEME
|
|
57
|
+
? batchExtraSchema.safeParse(accepted?.extra)
|
|
58
|
+
: undefined;
|
|
59
|
+
const proofId = scheme === undefined ? undefined : proofIdOf(scheme, payload);
|
|
60
|
+
if (payload.x402Version !== 2 ||
|
|
61
|
+
scheme === undefined ||
|
|
62
|
+
!offered.includes(scheme) ||
|
|
63
|
+
accepted?.network !== this.options.network ||
|
|
64
|
+
accepted.asset !== price.asset ||
|
|
65
|
+
accepted.amount !== price.amount ||
|
|
66
|
+
accepted.payTo !== this.options.payTo ||
|
|
67
|
+
extra === undefined ||
|
|
68
|
+
!extra.success ||
|
|
69
|
+
proofId === undefined ||
|
|
70
|
+
(scheme === BATCH_SCHEME &&
|
|
71
|
+
extra.data.minTimeout !==
|
|
72
|
+
this.options.batch?.minChannelTimeoutSeconds)) {
|
|
73
|
+
return this.paymentRequired(req, res, route, price, 'invalid_payment_requirements');
|
|
74
|
+
}
|
|
75
|
+
const facts = this.requestFacts(req, route);
|
|
76
|
+
const terms = this.terms(price);
|
|
77
|
+
const expected = offerBinding(this.options, scheme, extra.data, facts, terms);
|
|
78
|
+
if (!bindingsEqual(expected, extra.data.binding)) {
|
|
79
|
+
this.log.warn({ proofId }, 'payment is bound to another operation or a forged quote');
|
|
80
|
+
return this.paymentRequired(req, res, route, price, 'invalid_binding');
|
|
81
|
+
}
|
|
82
|
+
const binding = extra.data.binding;
|
|
83
|
+
const key = networkKey(getNetwork(this.options.network), scheme === EXACT_SCHEME ? 'unit' : 'voucher', proofId);
|
|
84
|
+
await withLogContext({ binding, proofId }, async () => {
|
|
85
|
+
const store = this.options.store;
|
|
86
|
+
const begun = store.begin(key, binding);
|
|
87
|
+
const { created } = begun;
|
|
88
|
+
let { record } = begun;
|
|
89
|
+
// A proof left in `serving` by a crashed process is recovered after the lease.
|
|
90
|
+
if (record.state === 'serving' &&
|
|
91
|
+
store.reclaimStale(key, this.options.servingLeaseSeconds ?? 300)) {
|
|
92
|
+
this.log.warn('recovered a payment stuck in serving (lease expired)');
|
|
93
|
+
record = store.get(key) ?? record;
|
|
94
|
+
}
|
|
95
|
+
if (!bindingsEqual(record.binding, binding)) {
|
|
96
|
+
res.status(402).json({ error: 'invalid_payment_reused' });
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
// x402 payment-identifier: one client id = one operation. Decided AFTER
|
|
100
|
+
// the proof row exists, so a concurrent request always sees this proof
|
|
101
|
+
// as in progress (never as "absent") and cannot take the id over.
|
|
102
|
+
if (this.options.paymentIdentifier !== undefined) {
|
|
103
|
+
const decision = decidePaymentId(store, {
|
|
104
|
+
paymentId: paymentIdOf(payload),
|
|
105
|
+
required: this.options.paymentIdentifier.required,
|
|
106
|
+
scopeId: (id) => `${this.options.sellerId}:${id}`,
|
|
107
|
+
fingerprint: operationFingerprint(facts, terms),
|
|
108
|
+
proofKey: key,
|
|
109
|
+
});
|
|
110
|
+
if (decision.kind !== 'proceed' && created)
|
|
111
|
+
store.forget(key, 'settling');
|
|
112
|
+
if (decision.kind === 'reject') {
|
|
113
|
+
res.status(decision.status).json({ error: decision.error });
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (decision.kind === 'replay') {
|
|
117
|
+
const original = store.get(decision.proofKey);
|
|
118
|
+
this.log.info('payment-identifier repeat: stored response, new payment NOT settled');
|
|
119
|
+
return this.send(res, original?.response ?? null, original?.paymentResponse ?? null);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (created && extra.data.validUntil < this.now()) {
|
|
123
|
+
store.forget(key, 'settling');
|
|
124
|
+
return this.paymentRequired(req, res, route, price, 'quote_expired');
|
|
125
|
+
}
|
|
126
|
+
switch (record.state) {
|
|
127
|
+
case 'served':
|
|
128
|
+
this.log.info('replaying stored response for a repeated operation');
|
|
129
|
+
return this.send(res, record.response, record.paymentResponse);
|
|
130
|
+
case 'serving':
|
|
131
|
+
if (record.paymentResponse !== null)
|
|
132
|
+
res.setHeader('PAYMENT-RESPONSE', record.paymentResponse);
|
|
133
|
+
res.status(409).json({ error: 'payment_in_progress' });
|
|
134
|
+
return;
|
|
135
|
+
case 'failed':
|
|
136
|
+
res.status(402).json({ error: 'payment_failed' });
|
|
137
|
+
return;
|
|
138
|
+
case 'paid_not_served':
|
|
139
|
+
return this.serve(req, res, key, record.paymentResponse, handler);
|
|
140
|
+
case 'awaiting_settle':
|
|
141
|
+
return this.settleServed(req, res, route, price, key, payload, accepted);
|
|
142
|
+
case 'settling':
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
if (route.flow === 'authorization') {
|
|
146
|
+
return this.authorize(req, res, route, price, key, payload, accepted, handler);
|
|
147
|
+
}
|
|
148
|
+
const settled = await this.settleWithWait(payload, accepted);
|
|
149
|
+
const paymentResponse = encodePaymentResponseHeader(settled);
|
|
150
|
+
if (settled.success) {
|
|
151
|
+
store.transition(key, 'settling', 'paid_not_served', { paymentResponse });
|
|
152
|
+
this.log.info({ transaction: settled.transaction }, 'payment settled');
|
|
153
|
+
return this.serve(req, res, key, paymentResponse, handler);
|
|
154
|
+
}
|
|
155
|
+
if (settled.errorReason === 'settlement_pending') {
|
|
156
|
+
this.log.info({ transaction: settled.transaction }, 'settlement pending; client should retry with the same payment');
|
|
157
|
+
res.setHeader('PAYMENT-RESPONSE', paymentResponse);
|
|
158
|
+
res.setHeader('Retry-After', '5');
|
|
159
|
+
res.status(402).json({ error: 'settlement_pending', transaction: settled.transaction });
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (settled.transaction === '') {
|
|
163
|
+
// Rejected before reaching the network: the proof was not consumed.
|
|
164
|
+
store.forget(key, 'settling');
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
store.transition(key, 'settling', 'failed', { paymentResponse });
|
|
168
|
+
}
|
|
169
|
+
this.log.warn({ reason: settled.errorReason }, 'payment failed');
|
|
170
|
+
res.setHeader('PAYMENT-RESPONSE', paymentResponse);
|
|
171
|
+
return this.paymentRequired(req, res, route, price, settled.errorReason ?? 'payment_failed');
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
/** authorization flow: verify → handler (response stored) → settle → send. */
|
|
175
|
+
async authorize(req, res, route, price, key, payload, accepted, handler) {
|
|
176
|
+
const store = this.options.store;
|
|
177
|
+
let verified;
|
|
178
|
+
try {
|
|
179
|
+
verified = await this.options.facilitator.verify(payload, accepted);
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
this.log.warn({ err }, 'facilitator unreachable during verify');
|
|
183
|
+
store.forget(key, 'settling');
|
|
184
|
+
res.status(503).json({ error: 'facilitator_unavailable' });
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (!verified.isValid) {
|
|
188
|
+
store.forget(key, 'settling');
|
|
189
|
+
return this.paymentRequired(req, res, route, price, verified.invalidReason ?? 'invalid_payment');
|
|
190
|
+
}
|
|
191
|
+
if (!store.transition(key, 'settling', 'serving')) {
|
|
192
|
+
res.status(409).json({ error: 'payment_in_progress' });
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
let result;
|
|
196
|
+
try {
|
|
197
|
+
result = await handler(req);
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
store.transition(key, 'serving', 'settling'); // nothing settled; the same payment may retry
|
|
201
|
+
this.log.error({ err }, 'paid handler failed before settlement');
|
|
202
|
+
res.status(500).json({ error: 'handler_failed', retry: 'same payment, same request' });
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
store.transition(key, 'serving', 'awaiting_settle', { response: toStored(result) });
|
|
206
|
+
return this.settleServed(req, res, route, price, key, payload, accepted);
|
|
207
|
+
}
|
|
208
|
+
async settleServed(req, res, route, price, key, payload, accepted) {
|
|
209
|
+
const store = this.options.store;
|
|
210
|
+
const settled = await this.settleWithWait(payload, accepted);
|
|
211
|
+
const paymentResponse = encodePaymentResponseHeader(settled);
|
|
212
|
+
if (settled.success) {
|
|
213
|
+
store.transition(key, 'awaiting_settle', 'served', { paymentResponse });
|
|
214
|
+
const record = store.get(key);
|
|
215
|
+
this.log.info({ transaction: settled.transaction }, 'payment settled after the handler; response sent');
|
|
216
|
+
return this.send(res, record?.response ?? null, paymentResponse);
|
|
217
|
+
}
|
|
218
|
+
res.setHeader('PAYMENT-RESPONSE', paymentResponse);
|
|
219
|
+
if (settled.errorReason === 'settlement_pending') {
|
|
220
|
+
res.setHeader('Retry-After', '5');
|
|
221
|
+
res.status(402).json({ error: 'settlement_pending', transaction: settled.transaction });
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
store.transition(key, 'awaiting_settle', 'failed', { paymentResponse });
|
|
225
|
+
this.log.warn({ reason: settled.errorReason }, 'payment failed AFTER the handler ran (authorization flow); response withheld');
|
|
226
|
+
return this.paymentRequired(req, res, route, price, settled.errorReason ?? 'payment_failed');
|
|
227
|
+
}
|
|
228
|
+
async serve(req, res, key, paymentResponse, handler) {
|
|
229
|
+
const store = this.options.store;
|
|
230
|
+
if (!store.transition(key, 'paid_not_served', 'serving')) {
|
|
231
|
+
res.status(409).json({ error: 'payment_in_progress' });
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
let result;
|
|
235
|
+
try {
|
|
236
|
+
result = await handler(req);
|
|
237
|
+
}
|
|
238
|
+
catch (err) {
|
|
239
|
+
store.transition(key, 'serving', 'paid_not_served');
|
|
240
|
+
this.log.error({ err }, 'paid handler failed; the payment can be retried for the same operation');
|
|
241
|
+
// The payment WAS settled: tell the client (its budget must count it).
|
|
242
|
+
if (paymentResponse !== null)
|
|
243
|
+
res.setHeader('PAYMENT-RESPONSE', paymentResponse);
|
|
244
|
+
res.status(500).json({ error: 'handler_failed', retry: 'same payment, same request' });
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const response = toStored(result);
|
|
248
|
+
if (!store.transition(key, 'serving', 'served', { response })) {
|
|
249
|
+
this.log.error('lost the serving state while storing the response');
|
|
250
|
+
}
|
|
251
|
+
this.log.info({ status: response.status }, 'paid response served');
|
|
252
|
+
this.send(res, response, paymentResponse);
|
|
253
|
+
}
|
|
254
|
+
send(res, response, paymentResponse) {
|
|
255
|
+
if (response === null) {
|
|
256
|
+
res.status(500).json({ error: 'missing_stored_response' });
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (paymentResponse !== null)
|
|
260
|
+
res.setHeader('PAYMENT-RESPONSE', paymentResponse);
|
|
261
|
+
for (const [name, value] of Object.entries(response.headers))
|
|
262
|
+
res.setHeader(name, value);
|
|
263
|
+
res.status(response.status).end(Buffer.from(response.body));
|
|
264
|
+
}
|
|
265
|
+
paymentRequired(req, res, route, price, error) {
|
|
266
|
+
const quote = newQuote(this.now(), this.options.quoteTtlSeconds ?? 300);
|
|
267
|
+
const facts = this.requestFacts(req, route);
|
|
268
|
+
const terms = this.terms(price);
|
|
269
|
+
const accepts = this.schemesFor(route).map((scheme) => ({
|
|
270
|
+
scheme,
|
|
271
|
+
network: this.options.network,
|
|
272
|
+
asset: price.asset,
|
|
273
|
+
amount: price.amount,
|
|
274
|
+
payTo: this.options.payTo,
|
|
275
|
+
maxTimeoutSeconds: this.options.maxTimeoutSeconds ?? 300,
|
|
276
|
+
extra: {
|
|
277
|
+
binding: offerBinding(this.options, scheme, quote, facts, terms),
|
|
278
|
+
...quote,
|
|
279
|
+
// x402 §6.1: a non-default flow must be declared in the offer.
|
|
280
|
+
...(route.flow === 'authorization' ? {} : { paymentFlow: 'upfront' }),
|
|
281
|
+
...(scheme === BATCH_SCHEME
|
|
282
|
+
? {
|
|
283
|
+
baseAa: CHANNEL_BASE_AA,
|
|
284
|
+
minTimeout: this.options.batch?.minChannelTimeoutSeconds ?? 0,
|
|
285
|
+
}
|
|
286
|
+
: {}),
|
|
287
|
+
},
|
|
288
|
+
}));
|
|
289
|
+
const body = {
|
|
290
|
+
x402Version: 2,
|
|
291
|
+
...(error === undefined ? {} : { error }),
|
|
292
|
+
resource: {
|
|
293
|
+
url: `${req.protocol}://${req.get('host') ?? 'localhost'}${req.originalUrl}`,
|
|
294
|
+
...(route.description ? { description: route.description } : {}),
|
|
295
|
+
...(route.mimeType ? { mimeType: route.mimeType } : {}),
|
|
296
|
+
},
|
|
297
|
+
accepts,
|
|
298
|
+
...(this.options.paymentIdentifier
|
|
299
|
+
? {
|
|
300
|
+
extensions: {
|
|
301
|
+
[PAYMENT_IDENTIFIER]: paymentIdentifierDeclaration(this.options.paymentIdentifier.required),
|
|
302
|
+
},
|
|
303
|
+
}
|
|
304
|
+
: {}),
|
|
305
|
+
};
|
|
306
|
+
res.setHeader('PAYMENT-REQUIRED', encodePaymentRequiredHeader(body));
|
|
307
|
+
res.status(402).json(body);
|
|
308
|
+
}
|
|
309
|
+
requestFacts(req, route) {
|
|
310
|
+
return {
|
|
311
|
+
method: req.method,
|
|
312
|
+
url: req.originalUrl,
|
|
313
|
+
bodyHash: route.fingerprint ? route.fingerprint(req) : bodyHashOf(req.body),
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
terms(price) {
|
|
317
|
+
return { network: this.options.network, payTo: this.options.payTo, ...price };
|
|
318
|
+
}
|
|
319
|
+
schemesFor(route) {
|
|
320
|
+
const all = route.schemes ?? (this.options.batch ? [BATCH_SCHEME, EXACT_SCHEME] : [EXACT_SCHEME]);
|
|
321
|
+
return all.filter((s) => s === EXACT_SCHEME || this.options.batch !== undefined);
|
|
322
|
+
}
|
|
323
|
+
async settleWithWait(payload, req) {
|
|
324
|
+
const deadline = Date.now() + (this.options.settleWaitMs ?? 20_000);
|
|
325
|
+
const poll = this.options.settlePollMs ?? 2_000;
|
|
326
|
+
for (;;) {
|
|
327
|
+
let res;
|
|
328
|
+
try {
|
|
329
|
+
res = await this.options.facilitator.settle(payload, req);
|
|
330
|
+
}
|
|
331
|
+
catch (err) {
|
|
332
|
+
// Unknown outcome talking to the facilitator: keep the proof in `settling`.
|
|
333
|
+
this.log.warn({ err }, 'facilitator unreachable during settle');
|
|
334
|
+
return {
|
|
335
|
+
success: false,
|
|
336
|
+
errorReason: 'settlement_pending',
|
|
337
|
+
transaction: String(payload.payload['unit']?.unit ?? ''),
|
|
338
|
+
network: req.network,
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
if (res.errorReason !== 'settlement_pending' || Date.now() + poll > deadline)
|
|
342
|
+
return res;
|
|
343
|
+
await new Promise((r) => setTimeout(r, poll));
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
/** Identifies a payment proof: the unit hash (exact) or the voucher hash (batch). */
|
|
348
|
+
function proofIdOf(scheme, payload) {
|
|
349
|
+
if (scheme === EXACT_SCHEME) {
|
|
350
|
+
const hash = payload.payload?.['unit']?.unit;
|
|
351
|
+
return typeof hash === 'string' ? hash : undefined;
|
|
352
|
+
}
|
|
353
|
+
const pkg = payload.payload?.['signedPackage'];
|
|
354
|
+
return pkg !== null && typeof pkg === 'object' ? sha256Hex(canonical(pkg)) : undefined;
|
|
355
|
+
}
|
|
356
|
+
function toStored(result) {
|
|
357
|
+
const headers = { ...(result.headers ?? {}) };
|
|
358
|
+
let body;
|
|
359
|
+
if (result.body instanceof Uint8Array)
|
|
360
|
+
body = result.body;
|
|
361
|
+
else if (typeof result.body === 'string')
|
|
362
|
+
body = Buffer.from(result.body);
|
|
363
|
+
else {
|
|
364
|
+
body = Buffer.from(JSON.stringify(result.body));
|
|
365
|
+
headers['content-type'] ??= 'application/json; charset=utf-8';
|
|
366
|
+
}
|
|
367
|
+
return { status: result.status ?? 200, headers, body };
|
|
368
|
+
}
|
|
369
|
+
function cryptoId() {
|
|
370
|
+
return globalThis.crypto.randomUUID();
|
|
371
|
+
}
|
|
372
|
+
//# sourceMappingURL=paywall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paywall.js","sourceRoot":"","sources":["../../src/seller/paywall.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Offers ("quotes") and their binding to ONE request — shared by ObytePaywall
|
|
3
|
+
* and ObyteExactServer so both compute byte-identical bindings.
|
|
4
|
+
*
|
|
5
|
+
* binding = HMAC(secret, {sellerId, scheme, quoteId, validUntil, method, url,
|
|
6
|
+
* bodyHash, network, asset, amount, payTo})
|
|
7
|
+
*/
|
|
8
|
+
export interface RequestFacts {
|
|
9
|
+
readonly method: string;
|
|
10
|
+
/** Path and query string, as requested. */
|
|
11
|
+
readonly url: string;
|
|
12
|
+
/** sha256 hex of the canonical body, or a route-specific fingerprint. */
|
|
13
|
+
readonly bodyHash: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PaymentTerms {
|
|
16
|
+
readonly network: string;
|
|
17
|
+
readonly asset: string;
|
|
18
|
+
readonly amount: string;
|
|
19
|
+
readonly payTo: string;
|
|
20
|
+
}
|
|
21
|
+
export interface Quote {
|
|
22
|
+
readonly quoteId: string;
|
|
23
|
+
readonly validUntil: number;
|
|
24
|
+
}
|
|
25
|
+
export interface SellerKey {
|
|
26
|
+
readonly sellerId: string;
|
|
27
|
+
readonly secret: string | Uint8Array;
|
|
28
|
+
}
|
|
29
|
+
/** sha256 of the canonical JSON body ('' when there is none). */
|
|
30
|
+
export declare function bodyHashOf(body: unknown): string;
|
|
31
|
+
export declare function newQuote(now: number, ttlSeconds: number): Quote;
|
|
32
|
+
export declare function offerBinding(seller: SellerKey, scheme: string, quote: Quote, request: RequestFacts, terms: PaymentTerms): string;
|
|
33
|
+
/**
|
|
34
|
+
* The operation independent of the quote (method, URL, body, price, payee):
|
|
35
|
+
* what a payment-identifier is bound to.
|
|
36
|
+
*/
|
|
37
|
+
export declare function operationFingerprint(request: RequestFacts, terms: PaymentTerms): string;
|
|
38
|
+
//# sourceMappingURL=quote.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quote.d.ts","sourceRoot":"","sources":["../../src/seller/quote.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,2CAA2C;IAC3C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC;CACtC;AAED,iEAAiE;AACjE,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAEhD;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,KAAK,CAE/D;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,YAAY,GAClB,MAAM,CAcR;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,GAAG,MAAM,CAYvF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { canonical, computeBinding, newQuoteId, sha256Hex } from '@obbyx/x402-obyte';
|
|
2
|
+
/** sha256 of the canonical JSON body ('' when there is none). */
|
|
3
|
+
export function bodyHashOf(body) {
|
|
4
|
+
return sha256Hex(body === undefined ? '' : canonical(body));
|
|
5
|
+
}
|
|
6
|
+
export function newQuote(now, ttlSeconds) {
|
|
7
|
+
return { quoteId: newQuoteId(), validUntil: now + ttlSeconds };
|
|
8
|
+
}
|
|
9
|
+
export function offerBinding(seller, scheme, quote, request, terms) {
|
|
10
|
+
return computeBinding(seller.secret, {
|
|
11
|
+
sellerId: seller.sellerId,
|
|
12
|
+
scheme,
|
|
13
|
+
quoteId: quote.quoteId,
|
|
14
|
+
validUntil: quote.validUntil,
|
|
15
|
+
method: request.method,
|
|
16
|
+
url: request.url,
|
|
17
|
+
bodyHash: request.bodyHash,
|
|
18
|
+
network: terms.network,
|
|
19
|
+
asset: terms.asset,
|
|
20
|
+
amount: terms.amount,
|
|
21
|
+
payTo: terms.payTo,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The operation independent of the quote (method, URL, body, price, payee):
|
|
26
|
+
* what a payment-identifier is bound to.
|
|
27
|
+
*/
|
|
28
|
+
export function operationFingerprint(request, terms) {
|
|
29
|
+
return sha256Hex(canonical({
|
|
30
|
+
method: request.method.toUpperCase(),
|
|
31
|
+
url: request.url,
|
|
32
|
+
body: request.bodyHash,
|
|
33
|
+
network: terms.network,
|
|
34
|
+
asset: terms.asset,
|
|
35
|
+
amount: terms.amount,
|
|
36
|
+
payTo: terms.payTo,
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=quote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quote.js","sourceRoot":"","sources":["../../src/seller/quote.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAkCrF,iEAAiE;AACjE,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,SAAS,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,UAAkB;IACtD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,GAAG,GAAG,UAAU,EAAE,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,MAAiB,EACjB,MAAc,EACd,KAAY,EACZ,OAAqB,EACrB,KAAmB;IAEnB,OAAO,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE;QACnC,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM;QACN,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAqB,EAAE,KAAmB;IAC7E,OAAO,SAAS,CACd,SAAS,CAAC;QACR,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE;QACpC,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,IAAI,EAAE,OAAO,CAAC,QAAQ;QACtB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { AssetAmount, Network, PaymentRequirements, Price, SchemeNetworkServer, SchemePaymentRequiredContext, SchemeServerHooks } from '@x402/core/types';
|
|
2
|
+
import { type Logger } from '@obbyx/obyte/logger';
|
|
3
|
+
import type { ConsumedProofsStore } from './consumed-proofs.js';
|
|
4
|
+
/**
|
|
5
|
+
* Obyte `exact` for the OFFICIAL x402 resource server (`@x402/core/server`,
|
|
6
|
+
* `@x402/express`, `@x402/hono`, …): a SchemeNetworkServer.
|
|
7
|
+
*
|
|
8
|
+
* - Binding (I1/I2): `enrichPaymentRequiredResponse` adds a per-request HMAC
|
|
9
|
+
* binding + quote to every offer. On a paid request it recomputes the HMAC
|
|
10
|
+
* from the request and the quote the client accepted; only if it matches are
|
|
11
|
+
* those fields reused (declared in `dynamicExtraFields`), so the facilitator
|
|
12
|
+
* then sees exactly the requirements the client signed. Otherwise a fresh
|
|
13
|
+
* binding is issued and the facilitator refuses the payment.
|
|
14
|
+
* - One payment, one operation (I3): the official middleware keeps no
|
|
15
|
+
* consumed-proof registry, so the scheme hooks do — `onBeforeVerify` refuses
|
|
16
|
+
* a proof that already served a request, `onAfterSettle` marks it served.
|
|
17
|
+
* Unlike `@obbyx/sdk`'s ObytePaywall, a repeated request gets a 402 instead
|
|
18
|
+
* of the stored response (the official middleware cannot replay responses).
|
|
19
|
+
*/
|
|
20
|
+
export interface ObyteExactServerOptions {
|
|
21
|
+
readonly sellerId: string;
|
|
22
|
+
/** HMAC key for bindings (≥ 32 bytes). */
|
|
23
|
+
readonly secret: string | Uint8Array;
|
|
24
|
+
readonly proofs: ConsumedProofsStore;
|
|
25
|
+
readonly logger: Logger;
|
|
26
|
+
readonly quoteTtlSeconds?: number;
|
|
27
|
+
readonly now?: () => number;
|
|
28
|
+
}
|
|
29
|
+
export declare class ObyteExactServer implements SchemeNetworkServer {
|
|
30
|
+
private readonly options;
|
|
31
|
+
readonly scheme = "exact";
|
|
32
|
+
readonly defaultAssetTransferMethod = "default";
|
|
33
|
+
readonly paymentFlows: {
|
|
34
|
+
default: {
|
|
35
|
+
supported: readonly ["upfront"];
|
|
36
|
+
default: "upfront";
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
readonly dynamicExtraFields: string[];
|
|
40
|
+
readonly schemeHooks: SchemeServerHooks;
|
|
41
|
+
private readonly log;
|
|
42
|
+
private readonly now;
|
|
43
|
+
constructor(options: ObyteExactServerOptions);
|
|
44
|
+
/** `{asset, amount}` in atomic units, or "20000 bytes" / "0.00002 GBYTE". */
|
|
45
|
+
parsePrice(price: Price, network: Network): Promise<AssetAmount>;
|
|
46
|
+
getAssetDecimals(asset: string): number | undefined;
|
|
47
|
+
/** Nothing to add from /supported for exact; the per-request fields come from the enrich hook. */
|
|
48
|
+
enhancePaymentRequirements(requirements: PaymentRequirements): Promise<PaymentRequirements>;
|
|
49
|
+
/** Adds (or, for a valid paid request, re-confirms) the per-request binding and quote. */
|
|
50
|
+
enrichPaymentRequiredResponse: (ctx: SchemePaymentRequiredContext) => Promise<PaymentRequirements[]>;
|
|
51
|
+
private acceptedQuote;
|
|
52
|
+
private bindingFor;
|
|
53
|
+
/** Proof key of the payment in a hook context (undefined when malformed). */
|
|
54
|
+
private keyOf;
|
|
55
|
+
private key;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=x402-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x402-server.d.ts","sourceRoot":"","sources":["../../src/seller/x402-server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,OAAO,EACP,mBAAmB,EACnB,KAAK,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,iBAAiB,EAClB,MAAM,kBAAkB,CAAC;AAS1B,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,qBAAqB,CAAC;AAEhE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAGhE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAwBD,qBAAa,gBAAiB,YAAW,mBAAmB;IAW9C,OAAO,CAAC,QAAQ,CAAC,OAAO;IAVpC,QAAQ,CAAC,MAAM,WAAgB;IAC/B,QAAQ,CAAC,0BAA0B,aAAa;IAChD,QAAQ,CAAC,YAAY;;;;;MAEnB;IACF,QAAQ,CAAC,kBAAkB,WAAwC;IACnE,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEN,OAAO,EAAE,uBAAuB;IAoD7D,6EAA6E;IACvE,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC;IAmBtE,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAInD,kGAAkG;IAC5F,0BAA0B,CAC9B,YAAY,EAAE,mBAAmB,GAChC,OAAO,CAAC,mBAAmB,CAAC;IAI/B,0FAA0F;IAC1F,6BAA6B,GAC3B,KAAK,4BAA4B,KAChC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAmB/B;IAEF,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,UAAU;IAUlB,6EAA6E;IAC7E,OAAO,CAAC,KAAK;IAQb,OAAO,CAAC,GAAG;CAGZ"}
|