@antseed/node 0.2.86 → 0.2.88
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/dist/discovery/peer-lookup.d.ts +4 -4
- package/dist/discovery/peer-lookup.d.ts.map +1 -1
- package/dist/discovery/peer-lookup.js +37 -17
- package/dist/discovery/peer-lookup.js.map +1 -1
- package/dist/node.d.ts +6 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +41 -2
- package/dist/node.js.map +1 -1
- package/dist/p2p/verification-codec.d.ts +16 -0
- package/dist/p2p/verification-codec.d.ts.map +1 -0
- package/dist/p2p/verification-codec.js +121 -0
- package/dist/p2p/verification-codec.js.map +1 -0
- package/dist/p2p/verification-mux.d.ts +30 -0
- package/dist/p2p/verification-mux.d.ts.map +1 -0
- package/dist/p2p/verification-mux.js +89 -0
- package/dist/p2p/verification-mux.js.map +1 -0
- package/dist/payments/buyer-payment-manager.d.ts.map +1 -1
- package/dist/payments/buyer-payment-manager.js +18 -2
- package/dist/payments/buyer-payment-manager.js.map +1 -1
- package/dist/payments/buyer-payment-negotiator.d.ts.map +1 -1
- package/dist/payments/buyer-payment-negotiator.js +27 -10
- package/dist/payments/buyer-payment-negotiator.js.map +1 -1
- package/dist/payments/evm/usage-verification-client.d.ts +72 -0
- package/dist/payments/evm/usage-verification-client.d.ts.map +1 -0
- package/dist/payments/evm/usage-verification-client.js +141 -0
- package/dist/payments/evm/usage-verification-client.js.map +1 -0
- package/dist/payments/seller-payment-manager.d.ts +11 -1
- package/dist/payments/seller-payment-manager.d.ts.map +1 -1
- package/dist/payments/seller-payment-manager.js +183 -88
- package/dist/payments/seller-payment-manager.js.map +1 -1
- package/dist/payments/usage-verification-manager.d.ts +68 -0
- package/dist/payments/usage-verification-manager.d.ts.map +1 -0
- package/dist/payments/usage-verification-manager.js +316 -0
- package/dist/payments/usage-verification-manager.js.map +1 -0
- package/dist/payments/usage-verification-store.d.ts +56 -0
- package/dist/payments/usage-verification-store.d.ts.map +1 -0
- package/dist/payments/usage-verification-store.js +146 -0
- package/dist/payments/usage-verification-store.js.map +1 -0
- package/dist/seller-request-handler.d.ts.map +1 -1
- package/dist/seller-request-handler.js +9 -6
- package/dist/seller-request-handler.js.map +1 -1
- package/dist/storage/migrations/channels/003_create_usage_verification_tables.d.ts +3 -0
- package/dist/storage/migrations/channels/003_create_usage_verification_tables.d.ts.map +1 -0
- package/dist/storage/migrations/channels/003_create_usage_verification_tables.js +54 -0
- package/dist/storage/migrations/channels/003_create_usage_verification_tables.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { UsageVerificationClient } from './evm/usage-verification-client.js';
|
|
3
|
+
import { UsageVerificationStore } from './usage-verification-store.js';
|
|
4
|
+
import { computeServiceKey, computeUsageClaimHash, computeUsageRevealHash, makeUsageVerificationDomain, signUsageCommit, USAGE_CLAIM_VERSION, USAGE_PARTY_BUYER, USAGE_PARTY_SELLER, } from './evm/signatures.js';
|
|
5
|
+
import { debugWarn } from '../utils/debug.js';
|
|
6
|
+
import { computeCostUsdc } from './pricing.js';
|
|
7
|
+
export class SellerUsageVerificationManager {
|
|
8
|
+
_signer;
|
|
9
|
+
_client;
|
|
10
|
+
_store;
|
|
11
|
+
_domain;
|
|
12
|
+
_stakingClient;
|
|
13
|
+
constructor(identity, config, stakingClient) {
|
|
14
|
+
this._signer = identity.wallet;
|
|
15
|
+
this._client = new UsageVerificationClient(config);
|
|
16
|
+
this._store = new UsageVerificationStore(config.dataDir);
|
|
17
|
+
this._domain = makeUsageVerificationDomain(config.chainId, config.contractAddress);
|
|
18
|
+
this._stakingClient = stakingClient;
|
|
19
|
+
}
|
|
20
|
+
get client() { return this._client; }
|
|
21
|
+
setSigner(signer) { this._signer = signer; }
|
|
22
|
+
async recordAndRequestCommit(input) {
|
|
23
|
+
const epoch = (await this._client.currentEpoch()).toString();
|
|
24
|
+
const serviceKey = computeServiceKey(input.providerName, input.serviceName);
|
|
25
|
+
const existing = this._store.getSnapshot(input.channel.sessionId, serviceKey, epoch);
|
|
26
|
+
const now = Date.now();
|
|
27
|
+
const sellerAgentId = await this._resolveSellerAgentId(input.channel.sellerEvmAddr);
|
|
28
|
+
const snapshot = {
|
|
29
|
+
channelId: input.channel.sessionId,
|
|
30
|
+
serviceKey,
|
|
31
|
+
providerName: input.providerName,
|
|
32
|
+
serviceName: input.serviceName,
|
|
33
|
+
epoch,
|
|
34
|
+
buyerEvmAddr: input.channel.buyerEvmAddr,
|
|
35
|
+
sellerEvmAddr: input.channel.sellerEvmAddr,
|
|
36
|
+
sellerAgentId: sellerAgentId.toString(),
|
|
37
|
+
cumulativeInputTokens: ((existing ? BigInt(existing.cumulativeInputTokens) : 0n) + input.inputTokens).toString(),
|
|
38
|
+
cumulativeCachedInputTokens: ((existing ? BigInt(existing.cumulativeCachedInputTokens) : 0n) + input.cachedInputTokens).toString(),
|
|
39
|
+
cumulativeFreshInputTokens: ((existing ? BigInt(existing.cumulativeFreshInputTokens) : 0n) + input.freshInputTokens).toString(),
|
|
40
|
+
cumulativeOutputTokens: ((existing ? BigInt(existing.cumulativeOutputTokens) : 0n) + input.outputTokens).toString(),
|
|
41
|
+
cumulativeRequestCount: ((existing ? BigInt(existing.cumulativeRequestCount) : 0n) + 1n).toString(),
|
|
42
|
+
cumulativeCostUsdc: ((existing ? BigInt(existing.cumulativeCostUsdc) : 0n) + input.costUsdc).toString(),
|
|
43
|
+
paymentCumulativeAmount: input.paymentCumulativeAmount.toString(),
|
|
44
|
+
createdAt: existing?.createdAt ?? now,
|
|
45
|
+
updatedAt: now,
|
|
46
|
+
};
|
|
47
|
+
this._store.upsertSnapshot(snapshot);
|
|
48
|
+
const claim = snapshotToClaim(snapshot);
|
|
49
|
+
const claimMsg = claimPayloadToMessage(claim);
|
|
50
|
+
const claimHash = computeUsageClaimHash(claimMsg);
|
|
51
|
+
const sellerNonce = randomNonce();
|
|
52
|
+
const sellerRevealHash = computeUsageRevealHash(claimHash, sellerNonce);
|
|
53
|
+
const expectedEpoch = BigInt(epoch);
|
|
54
|
+
const sellerSig = await signUsageCommit(this._signer, this._domain, {
|
|
55
|
+
claimHash,
|
|
56
|
+
revealHash: sellerRevealHash,
|
|
57
|
+
expectedEpoch,
|
|
58
|
+
party: USAGE_PARTY_SELLER,
|
|
59
|
+
});
|
|
60
|
+
this._store.upsertAttestation({
|
|
61
|
+
claimHash,
|
|
62
|
+
requestId: input.requestId,
|
|
63
|
+
channelId: input.channel.sessionId,
|
|
64
|
+
serviceKey,
|
|
65
|
+
epoch,
|
|
66
|
+
claim,
|
|
67
|
+
buyerRevealHash: null,
|
|
68
|
+
sellerRevealHash,
|
|
69
|
+
buyerNonce: null,
|
|
70
|
+
sellerNonce,
|
|
71
|
+
buyerSig: null,
|
|
72
|
+
sellerSig,
|
|
73
|
+
commitTxHash: null,
|
|
74
|
+
revealTxHash: null,
|
|
75
|
+
status: 'pending_buyer',
|
|
76
|
+
createdAt: now,
|
|
77
|
+
updatedAt: now,
|
|
78
|
+
});
|
|
79
|
+
input.mux.sendCommitRequest({
|
|
80
|
+
requestId: input.requestId,
|
|
81
|
+
claim,
|
|
82
|
+
claimHash,
|
|
83
|
+
revealHash: sellerRevealHash,
|
|
84
|
+
expectedEpoch: epoch,
|
|
85
|
+
sellerSig,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
async handleCommitResponse(payload, mux) {
|
|
89
|
+
const attestation = this._store.getAttestation(payload.claimHash);
|
|
90
|
+
if (!attestation)
|
|
91
|
+
return;
|
|
92
|
+
if (!payload.accepted || !payload.buyerSig || !payload.revealHash) {
|
|
93
|
+
this._store.updateAttestationStatus(payload.claimHash, 'failed');
|
|
94
|
+
debugWarn(`[UsageVerification] Buyer rejected usage commit ${payload.claimHash.slice(0, 18)}...: ${payload.reason ?? 'unknown'}`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const updated = {
|
|
98
|
+
...attestation,
|
|
99
|
+
buyerRevealHash: payload.revealHash,
|
|
100
|
+
buyerSig: payload.buyerSig,
|
|
101
|
+
status: 'buyer_signed',
|
|
102
|
+
updatedAt: Date.now(),
|
|
103
|
+
};
|
|
104
|
+
this._store.upsertAttestation(updated);
|
|
105
|
+
let commitTxHash;
|
|
106
|
+
try {
|
|
107
|
+
commitTxHash = await this._client.commitPair(this._signer, {
|
|
108
|
+
claimHash: updated.claimHash,
|
|
109
|
+
channelId: updated.channelId,
|
|
110
|
+
buyer: updated.claim.buyer,
|
|
111
|
+
seller: updated.claim.seller,
|
|
112
|
+
sellerAgentId: BigInt(updated.claim.sellerAgentId),
|
|
113
|
+
serviceKey: updated.serviceKey,
|
|
114
|
+
buyerRevealHash: payload.revealHash,
|
|
115
|
+
sellerRevealHash: updated.sellerRevealHash,
|
|
116
|
+
expectedEpoch: BigInt(updated.epoch),
|
|
117
|
+
buyerSig: payload.buyerSig,
|
|
118
|
+
sellerSig: updated.sellerSig,
|
|
119
|
+
});
|
|
120
|
+
this._store.updateAttestationStatus(updated.claimHash, 'committed', { commitTxHash });
|
|
121
|
+
mux.sendCommitProof({ requestId: updated.requestId, claimHash: updated.claimHash, txHash: commitTxHash });
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
this._store.updateAttestationStatus(updated.claimHash, 'failed');
|
|
125
|
+
debugWarn(`[UsageVerification] commitPair failed: ${err instanceof Error ? err.message : err}`);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
mux.sendRevealPackage({
|
|
129
|
+
requestId: updated.requestId,
|
|
130
|
+
claim: updated.claim,
|
|
131
|
+
claimHash: updated.claimHash,
|
|
132
|
+
nonce: updated.sellerNonce,
|
|
133
|
+
party: 'seller',
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
async retryCommittedReveals(limit = 25) {
|
|
137
|
+
const committed = this._store.listAttestationsByStatus('committed', limit);
|
|
138
|
+
for (const attestation of committed) {
|
|
139
|
+
if (!attestation.buyerNonce || !attestation.sellerNonce)
|
|
140
|
+
continue;
|
|
141
|
+
try {
|
|
142
|
+
const txHash = await this._client.revealPair(this._signer, claimPayloadToMessage(attestation.claim), attestation.buyerNonce, attestation.sellerNonce);
|
|
143
|
+
this._store.updateAttestationStatus(attestation.claimHash, 'revealed', { revealTxHash: txHash });
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// Payment coverage may still be pending; leave as committed for the next retry.
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
async handleRevealResponse(payload, mux) {
|
|
151
|
+
const attestation = this._store.getAttestation(payload.claimHash);
|
|
152
|
+
if (!attestation || !payload.accepted || !payload.nonce)
|
|
153
|
+
return;
|
|
154
|
+
if (!attestation.sellerNonce)
|
|
155
|
+
return;
|
|
156
|
+
this._store.upsertAttestation({ ...attestation, buyerNonce: payload.nonce, updatedAt: Date.now() });
|
|
157
|
+
try {
|
|
158
|
+
const txHash = await this._client.revealPair(this._signer, claimPayloadToMessage(attestation.claim), payload.nonce, attestation.sellerNonce);
|
|
159
|
+
this._store.updateAttestationStatus(attestation.claimHash, 'revealed', { revealTxHash: txHash });
|
|
160
|
+
mux.sendRevealAck({ requestId: attestation.requestId, claimHash: attestation.claimHash, txHash });
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
// Most commonly payment coverage has not landed yet. Keep committed state
|
|
164
|
+
// so a future retry can reveal after settlement.
|
|
165
|
+
this._store.updateAttestationStatus(attestation.claimHash, 'committed');
|
|
166
|
+
debugWarn(`[UsageVerification] revealPair deferred: ${err instanceof Error ? err.message : err}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
close() { this._store.close(); }
|
|
170
|
+
async _resolveSellerAgentId(seller) {
|
|
171
|
+
if (!this._stakingClient)
|
|
172
|
+
return 0n;
|
|
173
|
+
try {
|
|
174
|
+
return BigInt(await this._stakingClient.getAgentId(seller));
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return 0n;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
export class BuyerUsageVerificationManager {
|
|
182
|
+
_identity;
|
|
183
|
+
_signer;
|
|
184
|
+
_domain;
|
|
185
|
+
_store;
|
|
186
|
+
_requestService = new Map();
|
|
187
|
+
constructor(identity, config) {
|
|
188
|
+
this._identity = identity;
|
|
189
|
+
this._signer = identity.wallet;
|
|
190
|
+
this._domain = makeUsageVerificationDomain(config.chainId, config.contractAddress);
|
|
191
|
+
this._store = new UsageVerificationStore(config.dataDir);
|
|
192
|
+
}
|
|
193
|
+
setSigner(signer) { this._signer = signer; }
|
|
194
|
+
trackRequestService(requestId, service) {
|
|
195
|
+
this._requestService.set(requestId, service);
|
|
196
|
+
}
|
|
197
|
+
async handleCommitRequest(payload, mux) {
|
|
198
|
+
const expectedService = this._requestService.get(payload.requestId);
|
|
199
|
+
if (expectedService && expectedService !== payload.claim.serviceName) {
|
|
200
|
+
mux.sendCommitResponse({
|
|
201
|
+
requestId: payload.requestId,
|
|
202
|
+
accepted: false,
|
|
203
|
+
claimHash: payload.claimHash,
|
|
204
|
+
reason: `service mismatch: expected ${expectedService}, got ${payload.claim.serviceName}`,
|
|
205
|
+
});
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
if (payload.claim.buyer.toLowerCase() !== this._identity.wallet.address.toLowerCase()) {
|
|
209
|
+
mux.sendCommitResponse({ requestId: payload.requestId, accepted: false, claimHash: payload.claimHash, reason: 'buyer mismatch' });
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const claimHash = computeUsageClaimHash(claimPayloadToMessage(payload.claim));
|
|
213
|
+
if (claimHash !== payload.claimHash) {
|
|
214
|
+
mux.sendCommitResponse({ requestId: payload.requestId, accepted: false, claimHash: payload.claimHash, reason: 'claim hash mismatch' });
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const buyerNonce = randomNonce();
|
|
218
|
+
const buyerRevealHash = computeUsageRevealHash(claimHash, buyerNonce);
|
|
219
|
+
const buyerSig = await signUsageCommit(this._signer, this._domain, {
|
|
220
|
+
claimHash,
|
|
221
|
+
revealHash: buyerRevealHash,
|
|
222
|
+
expectedEpoch: BigInt(payload.expectedEpoch),
|
|
223
|
+
party: USAGE_PARTY_BUYER,
|
|
224
|
+
});
|
|
225
|
+
const now = Date.now();
|
|
226
|
+
this._store.upsertAttestation({
|
|
227
|
+
claimHash,
|
|
228
|
+
requestId: payload.requestId,
|
|
229
|
+
channelId: payload.claim.channelId,
|
|
230
|
+
serviceKey: payload.claim.serviceKey,
|
|
231
|
+
epoch: payload.expectedEpoch,
|
|
232
|
+
claim: payload.claim,
|
|
233
|
+
buyerRevealHash,
|
|
234
|
+
sellerRevealHash: payload.revealHash,
|
|
235
|
+
buyerNonce,
|
|
236
|
+
sellerNonce: null,
|
|
237
|
+
buyerSig,
|
|
238
|
+
sellerSig: payload.sellerSig,
|
|
239
|
+
commitTxHash: null,
|
|
240
|
+
revealTxHash: null,
|
|
241
|
+
status: 'buyer_signed',
|
|
242
|
+
createdAt: now,
|
|
243
|
+
updatedAt: now,
|
|
244
|
+
});
|
|
245
|
+
mux.sendCommitResponse({
|
|
246
|
+
requestId: payload.requestId,
|
|
247
|
+
accepted: true,
|
|
248
|
+
claimHash,
|
|
249
|
+
revealHash: buyerRevealHash,
|
|
250
|
+
buyerSig,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
handleRevealPackage(payload, mux) {
|
|
254
|
+
const attestation = this._store.getAttestation(payload.claimHash);
|
|
255
|
+
if (!attestation || !attestation.buyerNonce) {
|
|
256
|
+
mux.sendRevealResponse({ requestId: payload.requestId, accepted: false, claimHash: payload.claimHash, reason: 'unknown claim' });
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
this._store.upsertAttestation({ ...attestation, sellerNonce: payload.nonce, status: 'committed', updatedAt: Date.now() });
|
|
260
|
+
mux.sendRevealResponse({
|
|
261
|
+
requestId: payload.requestId,
|
|
262
|
+
accepted: true,
|
|
263
|
+
claimHash: payload.claimHash,
|
|
264
|
+
nonce: attestation.buyerNonce,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
handleRevealAck(payload) {
|
|
268
|
+
this._store.updateAttestationStatus(payload.claimHash, 'revealed', { revealTxHash: payload.txHash });
|
|
269
|
+
}
|
|
270
|
+
close() { this._store.close(); }
|
|
271
|
+
}
|
|
272
|
+
export function claimPayloadToMessage(claim) {
|
|
273
|
+
return {
|
|
274
|
+
version: BigInt(claim.version),
|
|
275
|
+
channelId: claim.channelId,
|
|
276
|
+
buyer: claim.buyer,
|
|
277
|
+
seller: claim.seller,
|
|
278
|
+
sellerAgentId: BigInt(claim.sellerAgentId),
|
|
279
|
+
serviceKey: claim.serviceKey,
|
|
280
|
+
providerName: claim.providerName,
|
|
281
|
+
serviceName: claim.serviceName,
|
|
282
|
+
cumulativeInputTokens: BigInt(claim.cumulativeInputTokens),
|
|
283
|
+
cumulativeCachedInputTokens: BigInt(claim.cumulativeCachedInputTokens),
|
|
284
|
+
cumulativeFreshInputTokens: BigInt(claim.cumulativeFreshInputTokens),
|
|
285
|
+
cumulativeOutputTokens: BigInt(claim.cumulativeOutputTokens),
|
|
286
|
+
cumulativeRequestCount: BigInt(claim.cumulativeRequestCount),
|
|
287
|
+
cumulativeCostUsdc: BigInt(claim.cumulativeCostUsdc),
|
|
288
|
+
paymentCumulativeAmount: BigInt(claim.paymentCumulativeAmount),
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
function snapshotToClaim(snapshot) {
|
|
292
|
+
return {
|
|
293
|
+
version: USAGE_CLAIM_VERSION.toString(),
|
|
294
|
+
channelId: snapshot.channelId,
|
|
295
|
+
buyer: snapshot.buyerEvmAddr,
|
|
296
|
+
seller: snapshot.sellerEvmAddr,
|
|
297
|
+
sellerAgentId: snapshot.sellerAgentId,
|
|
298
|
+
serviceKey: snapshot.serviceKey,
|
|
299
|
+
providerName: snapshot.providerName,
|
|
300
|
+
serviceName: snapshot.serviceName,
|
|
301
|
+
cumulativeInputTokens: snapshot.cumulativeInputTokens,
|
|
302
|
+
cumulativeCachedInputTokens: snapshot.cumulativeCachedInputTokens,
|
|
303
|
+
cumulativeFreshInputTokens: snapshot.cumulativeFreshInputTokens,
|
|
304
|
+
cumulativeOutputTokens: snapshot.cumulativeOutputTokens,
|
|
305
|
+
cumulativeRequestCount: snapshot.cumulativeRequestCount,
|
|
306
|
+
cumulativeCostUsdc: snapshot.cumulativeCostUsdc,
|
|
307
|
+
paymentCumulativeAmount: snapshot.paymentCumulativeAmount,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
function randomNonce() {
|
|
311
|
+
return '0x' + randomBytes(32).toString('hex');
|
|
312
|
+
}
|
|
313
|
+
export function computeUsageCostFromTokens(params) {
|
|
314
|
+
return computeCostUsdc(params.freshInputTokens, params.outputTokens, params.pricing, params.cachedInputTokens);
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=usage-verification-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-verification-manager.js","sourceRoot":"","sources":["../../src/payments/usage-verification-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { VerificationUsageClaimPayload } from '../types/protocol.js';
|
|
2
|
+
export interface UsageSnapshotRecord {
|
|
3
|
+
channelId: string;
|
|
4
|
+
serviceKey: string;
|
|
5
|
+
providerName: string;
|
|
6
|
+
serviceName: string;
|
|
7
|
+
epoch: string;
|
|
8
|
+
buyerEvmAddr: string;
|
|
9
|
+
sellerEvmAddr: string;
|
|
10
|
+
sellerAgentId: string;
|
|
11
|
+
cumulativeInputTokens: string;
|
|
12
|
+
cumulativeCachedInputTokens: string;
|
|
13
|
+
cumulativeFreshInputTokens: string;
|
|
14
|
+
cumulativeOutputTokens: string;
|
|
15
|
+
cumulativeRequestCount: string;
|
|
16
|
+
cumulativeCostUsdc: string;
|
|
17
|
+
paymentCumulativeAmount: string;
|
|
18
|
+
createdAt: number;
|
|
19
|
+
updatedAt: number;
|
|
20
|
+
}
|
|
21
|
+
export type UsageAttestationStatus = 'pending_buyer' | 'buyer_signed' | 'committed' | 'revealed' | 'partial' | 'failed';
|
|
22
|
+
export interface UsageAttestationRecord {
|
|
23
|
+
claimHash: string;
|
|
24
|
+
requestId: string;
|
|
25
|
+
channelId: string;
|
|
26
|
+
serviceKey: string;
|
|
27
|
+
epoch: string;
|
|
28
|
+
claim: VerificationUsageClaimPayload;
|
|
29
|
+
buyerRevealHash: string | null;
|
|
30
|
+
sellerRevealHash: string | null;
|
|
31
|
+
buyerNonce: string | null;
|
|
32
|
+
sellerNonce: string | null;
|
|
33
|
+
buyerSig: string | null;
|
|
34
|
+
sellerSig: string | null;
|
|
35
|
+
commitTxHash: string | null;
|
|
36
|
+
revealTxHash: string | null;
|
|
37
|
+
status: UsageAttestationStatus;
|
|
38
|
+
createdAt: number;
|
|
39
|
+
updatedAt: number;
|
|
40
|
+
}
|
|
41
|
+
export declare class UsageVerificationStore {
|
|
42
|
+
private readonly _db;
|
|
43
|
+
private readonly _stmts;
|
|
44
|
+
constructor(dataDir: string);
|
|
45
|
+
getSnapshot(channelId: string, serviceKey: string, epoch: string): UsageSnapshotRecord | null;
|
|
46
|
+
upsertSnapshot(record: UsageSnapshotRecord): void;
|
|
47
|
+
upsertAttestation(record: UsageAttestationRecord): void;
|
|
48
|
+
getAttestation(claimHash: string): UsageAttestationRecord | null;
|
|
49
|
+
listAttestationsByStatus(status: UsageAttestationStatus, limit?: number): UsageAttestationRecord[];
|
|
50
|
+
updateAttestationStatus(claimHash: string, status: UsageAttestationStatus, hashes?: {
|
|
51
|
+
commitTxHash?: string;
|
|
52
|
+
revealTxHash?: string;
|
|
53
|
+
}): void;
|
|
54
|
+
close(): void;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=usage-verification-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-verification-store.d.ts","sourceRoot":"","sources":["../../src/payments/usage-verification-store.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AAE1E,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,2BAA2B,EAAE,MAAM,CAAC;IACpC,0BAA0B,EAAE,MAAM,CAAC;IACnC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,uBAAuB,EAAE,MAAM,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,sBAAsB,GAAG,eAAe,GAAG,cAAc,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;AAExH,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,6BAA6B,CAAC;IACrC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,sBAAsB,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAOrB;gBAEU,OAAO,EAAE,MAAM;IAoE3B,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI;IAK7F,cAAc,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAIjD,iBAAiB,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI;IAOvD,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI;IAKhE,wBAAwB,CAAC,MAAM,EAAE,sBAAsB,EAAE,KAAK,SAAM,GAAG,sBAAsB,EAAE;IAK/F,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAI3I,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import { mkdirSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { runMigrations } from '../storage/migrate.js';
|
|
5
|
+
import { channelMigrations } from '../storage/migrations/channels/index.js';
|
|
6
|
+
export class UsageVerificationStore {
|
|
7
|
+
_db;
|
|
8
|
+
_stmts;
|
|
9
|
+
constructor(dataDir) {
|
|
10
|
+
mkdirSync(dataDir, { recursive: true });
|
|
11
|
+
this._db = new Database(join(dataDir, 'sessions.db'));
|
|
12
|
+
this._db.pragma('journal_mode = WAL');
|
|
13
|
+
runMigrations(this._db, channelMigrations);
|
|
14
|
+
this._stmts = {
|
|
15
|
+
upsertSnapshot: this._db.prepare(`
|
|
16
|
+
INSERT INTO usage_verification_snapshots (
|
|
17
|
+
channel_id, service_key, provider_name, service_name, epoch,
|
|
18
|
+
buyer_evm_addr, seller_evm_addr, seller_agent_id,
|
|
19
|
+
cumulative_input_tokens, cumulative_cached_input_tokens, cumulative_fresh_input_tokens,
|
|
20
|
+
cumulative_output_tokens, cumulative_request_count, cumulative_cost_usdc, payment_cumulative_amount,
|
|
21
|
+
created_at, updated_at
|
|
22
|
+
) VALUES (
|
|
23
|
+
@channelId, @serviceKey, @providerName, @serviceName, @epoch,
|
|
24
|
+
@buyerEvmAddr, @sellerEvmAddr, @sellerAgentId,
|
|
25
|
+
@cumulativeInputTokens, @cumulativeCachedInputTokens, @cumulativeFreshInputTokens,
|
|
26
|
+
@cumulativeOutputTokens, @cumulativeRequestCount, @cumulativeCostUsdc, @paymentCumulativeAmount,
|
|
27
|
+
@createdAt, @updatedAt
|
|
28
|
+
)
|
|
29
|
+
ON CONFLICT(channel_id, service_key, epoch) DO UPDATE SET
|
|
30
|
+
provider_name = @providerName,
|
|
31
|
+
service_name = @serviceName,
|
|
32
|
+
buyer_evm_addr = @buyerEvmAddr,
|
|
33
|
+
seller_evm_addr = @sellerEvmAddr,
|
|
34
|
+
seller_agent_id = @sellerAgentId,
|
|
35
|
+
cumulative_input_tokens = @cumulativeInputTokens,
|
|
36
|
+
cumulative_cached_input_tokens = @cumulativeCachedInputTokens,
|
|
37
|
+
cumulative_fresh_input_tokens = @cumulativeFreshInputTokens,
|
|
38
|
+
cumulative_output_tokens = @cumulativeOutputTokens,
|
|
39
|
+
cumulative_request_count = @cumulativeRequestCount,
|
|
40
|
+
cumulative_cost_usdc = @cumulativeCostUsdc,
|
|
41
|
+
payment_cumulative_amount = @paymentCumulativeAmount,
|
|
42
|
+
updated_at = @updatedAt
|
|
43
|
+
`),
|
|
44
|
+
getSnapshot: this._db.prepare(`
|
|
45
|
+
SELECT * FROM usage_verification_snapshots WHERE channel_id = ? AND service_key = ? AND epoch = ?
|
|
46
|
+
`),
|
|
47
|
+
upsertAttestation: this._db.prepare(`
|
|
48
|
+
INSERT INTO usage_verification_attestations (
|
|
49
|
+
claim_hash, request_id, channel_id, service_key, epoch, claim_json,
|
|
50
|
+
buyer_reveal_hash, seller_reveal_hash, buyer_nonce, seller_nonce,
|
|
51
|
+
buyer_sig, seller_sig, commit_tx_hash, reveal_tx_hash, status, created_at, updated_at
|
|
52
|
+
) VALUES (
|
|
53
|
+
@claimHash, @requestId, @channelId, @serviceKey, @epoch, @claimJson,
|
|
54
|
+
@buyerRevealHash, @sellerRevealHash, @buyerNonce, @sellerNonce,
|
|
55
|
+
@buyerSig, @sellerSig, @commitTxHash, @revealTxHash, @status, @createdAt, @updatedAt
|
|
56
|
+
)
|
|
57
|
+
ON CONFLICT(claim_hash) DO UPDATE SET
|
|
58
|
+
request_id = @requestId,
|
|
59
|
+
claim_json = @claimJson,
|
|
60
|
+
buyer_reveal_hash = @buyerRevealHash,
|
|
61
|
+
seller_reveal_hash = @sellerRevealHash,
|
|
62
|
+
buyer_nonce = @buyerNonce,
|
|
63
|
+
seller_nonce = @sellerNonce,
|
|
64
|
+
buyer_sig = @buyerSig,
|
|
65
|
+
seller_sig = @sellerSig,
|
|
66
|
+
commit_tx_hash = @commitTxHash,
|
|
67
|
+
reveal_tx_hash = @revealTxHash,
|
|
68
|
+
status = @status,
|
|
69
|
+
updated_at = @updatedAt
|
|
70
|
+
`),
|
|
71
|
+
getAttestation: this._db.prepare('SELECT * FROM usage_verification_attestations WHERE claim_hash = ?'),
|
|
72
|
+
listAttestationsByStatus: this._db.prepare('SELECT * FROM usage_verification_attestations WHERE status = ? ORDER BY updated_at LIMIT ?'),
|
|
73
|
+
updateAttestationStatus: this._db.prepare('UPDATE usage_verification_attestations SET status = ?, commit_tx_hash = COALESCE(?, commit_tx_hash), reveal_tx_hash = COALESCE(?, reveal_tx_hash), updated_at = ? WHERE claim_hash = ?'),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
getSnapshot(channelId, serviceKey, epoch) {
|
|
77
|
+
const row = this._stmts.getSnapshot.get(channelId, serviceKey, epoch);
|
|
78
|
+
return row ? snapshotFromRow(row) : null;
|
|
79
|
+
}
|
|
80
|
+
upsertSnapshot(record) {
|
|
81
|
+
this._stmts.upsertSnapshot.run(record);
|
|
82
|
+
}
|
|
83
|
+
upsertAttestation(record) {
|
|
84
|
+
this._stmts.upsertAttestation.run({
|
|
85
|
+
...record,
|
|
86
|
+
claimJson: JSON.stringify(record.claim),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
getAttestation(claimHash) {
|
|
90
|
+
const row = this._stmts.getAttestation.get(claimHash);
|
|
91
|
+
return row ? attestationFromRow(row) : null;
|
|
92
|
+
}
|
|
93
|
+
listAttestationsByStatus(status, limit = 100) {
|
|
94
|
+
const rows = this._stmts.listAttestationsByStatus.all(status, limit);
|
|
95
|
+
return rows.map(attestationFromRow);
|
|
96
|
+
}
|
|
97
|
+
updateAttestationStatus(claimHash, status, hashes) {
|
|
98
|
+
this._stmts.updateAttestationStatus.run(status, hashes?.commitTxHash ?? null, hashes?.revealTxHash ?? null, Date.now(), claimHash);
|
|
99
|
+
}
|
|
100
|
+
close() {
|
|
101
|
+
this._db.close();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function snapshotFromRow(row) {
|
|
105
|
+
return {
|
|
106
|
+
channelId: row.channel_id,
|
|
107
|
+
serviceKey: row.service_key,
|
|
108
|
+
providerName: row.provider_name,
|
|
109
|
+
serviceName: row.service_name,
|
|
110
|
+
epoch: row.epoch,
|
|
111
|
+
buyerEvmAddr: row.buyer_evm_addr,
|
|
112
|
+
sellerEvmAddr: row.seller_evm_addr,
|
|
113
|
+
sellerAgentId: row.seller_agent_id,
|
|
114
|
+
cumulativeInputTokens: row.cumulative_input_tokens,
|
|
115
|
+
cumulativeCachedInputTokens: row.cumulative_cached_input_tokens,
|
|
116
|
+
cumulativeFreshInputTokens: row.cumulative_fresh_input_tokens,
|
|
117
|
+
cumulativeOutputTokens: row.cumulative_output_tokens,
|
|
118
|
+
cumulativeRequestCount: row.cumulative_request_count,
|
|
119
|
+
cumulativeCostUsdc: row.cumulative_cost_usdc,
|
|
120
|
+
paymentCumulativeAmount: row.payment_cumulative_amount,
|
|
121
|
+
createdAt: row.created_at,
|
|
122
|
+
updatedAt: row.updated_at,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function attestationFromRow(row) {
|
|
126
|
+
return {
|
|
127
|
+
claimHash: row.claim_hash,
|
|
128
|
+
requestId: row.request_id,
|
|
129
|
+
channelId: row.channel_id,
|
|
130
|
+
serviceKey: row.service_key,
|
|
131
|
+
epoch: row.epoch,
|
|
132
|
+
claim: JSON.parse(row.claim_json),
|
|
133
|
+
buyerRevealHash: row.buyer_reveal_hash,
|
|
134
|
+
sellerRevealHash: row.seller_reveal_hash,
|
|
135
|
+
buyerNonce: row.buyer_nonce,
|
|
136
|
+
sellerNonce: row.seller_nonce,
|
|
137
|
+
buyerSig: row.buyer_sig,
|
|
138
|
+
sellerSig: row.seller_sig,
|
|
139
|
+
commitTxHash: row.commit_tx_hash,
|
|
140
|
+
revealTxHash: row.reveal_tx_hash,
|
|
141
|
+
status: row.status,
|
|
142
|
+
createdAt: row.created_at,
|
|
143
|
+
updatedAt: row.updated_at,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=usage-verification-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-verification-store.js","sourceRoot":"","sources":["../../src/payments/usage-verification-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seller-request-handler.d.ts","sourceRoot":"","sources":["../src/seller-request-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EACV,QAAQ,EAET,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EACV,qBAAqB,EAEtB,MAAM,iBAAiB,CAAC;AAMzB,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,oBAAoB,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAClD,cAAc,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC5C,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;CACtD;AAMD;;;;;;GAMG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IACjD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA6B;IACjE,OAAO,CAAC,qBAAqB,CAA8C;gBAE/D,IAAI,EAAE,wBAAwB;IAI1C;;;OAGG;IACH,gBAAgB,CACd,IAAI,EAAE,cAAc,EACpB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,UAAU,GACrB;QAAE,GAAG,EAAE,QAAQ,CAAA;KAAE;
|
|
1
|
+
{"version":3,"file":"seller-request-handler.d.ts","sourceRoot":"","sources":["../src/seller-request-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EACV,QAAQ,EAET,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EACV,qBAAqB,EAEtB,MAAM,iBAAiB,CAAC;AAMzB,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,oBAAoB,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAClD,cAAc,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC5C,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;CACtD;AAMD;;;;;;GAMG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IACjD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA6B;IACjE,OAAO,CAAC,qBAAqB,CAA8C;gBAE/D,IAAI,EAAE,wBAAwB;IAI1C;;;OAGG;IACH,gBAAgB,CACd,IAAI,EAAE,cAAc,EACpB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,UAAU,GACrB;QAAE,GAAG,EAAE,QAAQ,CAAA;KAAE;IA+VpB,OAAO,CAAC,oBAAoB;IA4C5B,aAAa,CAAC,OAAO,EAAE,qBAAqB,GAAG,QAAQ,GAAG,SAAS;IAsBnE,sBAAsB,CACpB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,iCAAiC,EAAE,iCAAiC;IAa9E,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAY7D,yBAAyB,IAAI,IAAI;IAUjC,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,wBAAwB;IAiBhC,OAAO,CAAC,yBAAyB;YASnB,eAAe;IAW7B,OAAO,CAAC,uBAAuB;IAe/B,OAAO,CAAC,wBAAwB;CAkBjC"}
|
|
@@ -140,10 +140,12 @@ export class SellerRequestHandler {
|
|
|
140
140
|
}
|
|
141
141
|
let accepted = spm.getAcceptedCumulative(session.sessionId);
|
|
142
142
|
const spent = spm.getCumulativeSpend(session.sessionId);
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
//
|
|
143
|
+
// Serving headroom only includes funds locked on-chain. Pending
|
|
144
|
+
// top-ups are not counted until topUp() succeeds, otherwise a large
|
|
145
|
+
// request could push spend above the current reserve before the extra
|
|
146
|
+
// funds are actually locked.
|
|
146
147
|
const reserveMax = spm.getEffectiveReserveMax(session.sessionId);
|
|
148
|
+
const isBlocked = spm.isChannelBlocked(session.sessionId);
|
|
147
149
|
// If spend has caught up and there is no headroom left in the reserve,
|
|
148
150
|
// stop serving before accepting any additional request cost.
|
|
149
151
|
const isAtExactSpendLimit = spent > 0n && spent === accepted && reserveMax > 0n && accepted >= reserveMax;
|
|
@@ -163,7 +165,7 @@ export class SellerRequestHandler {
|
|
|
163
165
|
debugLog(`[SellerHandler] Caught up before 402 for ${buyerPeerId.slice(0, 12)}... (spent=${spent} accepted=${accepted})`);
|
|
164
166
|
}
|
|
165
167
|
}
|
|
166
|
-
if (spent > 0n && (spent > accepted || isAtExactSpendLimit)) {
|
|
168
|
+
if (isBlocked || (spent > 0n && (spent > accepted || isAtExactSpendLimit))) {
|
|
167
169
|
const providerPricing = this.resolveProviderPricing(provider, request);
|
|
168
170
|
const baseRequirements = spm.getPaymentRequirements(request.requestId, buyerPeerId, providerPricing);
|
|
169
171
|
// Tell the buyer exactly how much delivered spend remains unsigned.
|
|
@@ -171,7 +173,7 @@ export class SellerRequestHandler {
|
|
|
171
173
|
// on-chain, so requiring more than `spent` would authorize payment
|
|
172
174
|
// for work the seller has not delivered.
|
|
173
175
|
const target = spent;
|
|
174
|
-
const isFullyExhausted = reserveMax > 0n && (accepted >= reserveMax || target > reserveMax);
|
|
176
|
+
const isFullyExhausted = isBlocked || (reserveMax > 0n && (accepted >= reserveMax || target > reserveMax));
|
|
175
177
|
const requirements = {
|
|
176
178
|
...baseRequirements,
|
|
177
179
|
requiredCumulativeAmount: target.toString(),
|
|
@@ -182,7 +184,8 @@ export class SellerRequestHandler {
|
|
|
182
184
|
...(isFullyExhausted ? { code: PAYMENT_CODE_CHANNEL_EXHAUSTED } : {}),
|
|
183
185
|
};
|
|
184
186
|
if (isFullyExhausted) {
|
|
185
|
-
|
|
187
|
+
const reason = isBlocked ? 'blocked' : 'fully exhausted';
|
|
188
|
+
debugLog(`[SellerHandler] Session ${reason} for ${buyerPeerId.slice(0, 12)}... (spent=${spent} accepted=${accepted} target=${target} reserveMax=${reserveMax}) — closing and returning 402`);
|
|
186
189
|
// Default settleSession() performs final close(); do not use
|
|
187
190
|
// settleOnly here because exhausted channels must release the
|
|
188
191
|
// buyer's unused reserve before the buyer opens a replacement.
|