@antseed/node 0.2.93 → 0.2.95
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/buyer-request-handler.d.ts +4 -1
- package/dist/buyer-request-handler.d.ts.map +1 -1
- package/dist/buyer-request-handler.js +83 -4
- package/dist/buyer-request-handler.js.map +1 -1
- package/dist/discovery/http-metadata-resolver.d.ts +7 -0
- package/dist/discovery/http-metadata-resolver.d.ts.map +1 -1
- package/dist/discovery/http-metadata-resolver.js +16 -3
- package/dist/discovery/http-metadata-resolver.js.map +1 -1
- package/dist/discovery/index.d.ts +1 -0
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/index.js +1 -0
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/verification-links.d.ts +16 -0
- package/dist/discovery/verification-links.d.ts.map +1 -0
- package/dist/discovery/verification-links.js +71 -0
- package/dist/discovery/verification-links.js.map +1 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +25 -2
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +247 -21
- package/dist/node.js.map +1 -1
- package/dist/p2p/payment-codec.d.ts +9 -1
- package/dist/p2p/payment-codec.d.ts.map +1 -1
- package/dist/p2p/payment-codec.js +67 -0
- package/dist/p2p/payment-codec.js.map +1 -1
- package/dist/p2p/payment-mux.d.ts +13 -1
- package/dist/p2p/payment-mux.d.ts.map +1 -1
- package/dist/p2p/payment-mux.js +44 -0
- package/dist/p2p/payment-mux.js.map +1 -1
- package/dist/payments/buyer-free-usage-manager.d.ts +39 -0
- package/dist/payments/buyer-free-usage-manager.d.ts.map +1 -0
- package/dist/payments/buyer-free-usage-manager.js +280 -0
- package/dist/payments/buyer-free-usage-manager.js.map +1 -0
- package/dist/payments/buyer-payment-manager.d.ts +2 -4
- package/dist/payments/buyer-payment-manager.d.ts.map +1 -1
- package/dist/payments/buyer-payment-manager.js +34 -110
- package/dist/payments/buyer-payment-manager.js.map +1 -1
- package/dist/payments/buyer-payment-negotiator.d.ts +6 -2
- package/dist/payments/buyer-payment-negotiator.d.ts.map +1 -1
- package/dist/payments/buyer-payment-negotiator.js +41 -13
- package/dist/payments/buyer-payment-negotiator.js.map +1 -1
- package/dist/payments/chain-config.d.ts +3 -2
- package/dist/payments/chain-config.d.ts.map +1 -1
- package/dist/payments/chain-config.js +4 -4
- package/dist/payments/chain-config.js.map +1 -1
- package/dist/payments/channel-session-state.d.ts +2 -1
- package/dist/payments/channel-session-state.d.ts.map +1 -1
- package/dist/payments/channel-session-state.js +4 -3
- package/dist/payments/channel-session-state.js.map +1 -1
- package/dist/payments/channel-store.d.ts +31 -15
- package/dist/payments/channel-store.d.ts.map +1 -1
- package/dist/payments/channel-store.js +74 -35
- package/dist/payments/channel-store.js.map +1 -1
- package/dist/payments/channel-usage-accounting.d.ts +18 -0
- package/dist/payments/channel-usage-accounting.d.ts.map +1 -0
- package/dist/payments/channel-usage-accounting.js +66 -0
- package/dist/payments/channel-usage-accounting.js.map +1 -0
- package/dist/payments/evm/free-usage-client.d.ts +34 -0
- package/dist/payments/evm/free-usage-client.d.ts.map +1 -0
- package/dist/payments/evm/free-usage-client.js +61 -0
- package/dist/payments/evm/free-usage-client.js.map +1 -0
- package/dist/payments/evm/signatures.d.ts +70 -0
- package/dist/payments/evm/signatures.d.ts.map +1 -1
- package/dist/payments/evm/signatures.js +89 -0
- package/dist/payments/evm/signatures.js.map +1 -1
- package/dist/payments/index.d.ts +10 -6
- package/dist/payments/index.d.ts.map +1 -1
- package/dist/payments/index.js +7 -4
- package/dist/payments/index.js.map +1 -1
- package/dist/payments/seller-free-usage-manager.d.ts +44 -0
- package/dist/payments/seller-free-usage-manager.d.ts.map +1 -0
- package/dist/payments/seller-free-usage-manager.js +350 -0
- package/dist/payments/seller-free-usage-manager.js.map +1 -0
- package/dist/payments/seller-payment-manager.d.ts.map +1 -1
- package/dist/payments/seller-payment-manager.js +21 -20
- package/dist/payments/seller-payment-manager.js.map +1 -1
- package/dist/payments/types.d.ts +2 -0
- package/dist/payments/types.d.ts.map +1 -1
- package/dist/reputation/on-chain-reputation.d.ts +35 -3
- package/dist/reputation/on-chain-reputation.d.ts.map +1 -1
- package/dist/reputation/on-chain-reputation.js +87 -7
- package/dist/reputation/on-chain-reputation.js.map +1 -1
- package/dist/seller-request-handler.d.ts +2 -0
- package/dist/seller-request-handler.d.ts.map +1 -1
- package/dist/seller-request-handler.js +8 -0
- package/dist/seller-request-handler.js.map +1 -1
- package/dist/storage/migrations/channels/004_add_channel_kind.d.ts +3 -0
- package/dist/storage/migrations/channels/004_add_channel_kind.d.ts.map +1 -0
- package/dist/storage/migrations/channels/004_add_channel_kind.js +16 -0
- package/dist/storage/migrations/channels/004_add_channel_kind.js.map +1 -0
- package/dist/storage/migrations/channels/index.d.ts.map +1 -1
- package/dist/storage/migrations/channels/index.js +2 -1
- package/dist/storage/migrations/channels/index.js.map +1 -1
- package/dist/types/peer.d.ts +15 -1
- package/dist/types/peer.d.ts.map +1 -1
- package/dist/types/peer.js.map +1 -1
- package/dist/types/protocol.d.ts +47 -0
- package/dist/types/protocol.d.ts.map +1 -1
- package/dist/types/protocol.js +4 -0
- package/dist/types/protocol.js.map +1 -1
- package/dist/verification/samples.js +1 -1
- package/dist/verification/samples.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { peerIdToAddress } from '../types/peer.js';
|
|
3
|
+
import { debugLog, debugWarn } from '../utils/debug.js';
|
|
4
|
+
import { computeFreeUsageChannelId, computeFreeUsageMetadataHash, encodeFreeUsageMetadata, makeFreeUsageDomain, signFreeUsageAuth, signFreeUsageOpen, } from './evm/signatures.js';
|
|
5
|
+
import { CHANNEL_KIND, CHANNEL_ROLE, CHANNEL_STATUS } from './channel-store.js';
|
|
6
|
+
import { advanceUsageMetadata, RequestServiceTracker } from './channel-usage-accounting.js';
|
|
7
|
+
const DEFAULT_OPEN_ACK_TIMEOUT_MS = 30_000;
|
|
8
|
+
export class BuyerFreeUsageManager {
|
|
9
|
+
_identity;
|
|
10
|
+
_config;
|
|
11
|
+
_sellerAddressResolver;
|
|
12
|
+
_channelStore;
|
|
13
|
+
_domain;
|
|
14
|
+
_sessions = new Map();
|
|
15
|
+
_sellerLocks = new Map();
|
|
16
|
+
_openAckWaiters = new Map();
|
|
17
|
+
_requestService = new RequestServiceTracker();
|
|
18
|
+
constructor(identity, config, sellerAddressResolver, channelStore) {
|
|
19
|
+
this._identity = identity;
|
|
20
|
+
this._config = config;
|
|
21
|
+
this._sellerAddressResolver = sellerAddressResolver;
|
|
22
|
+
this._channelStore = channelStore;
|
|
23
|
+
this._domain = makeFreeUsageDomain(config.chainId, config.freeUsageContractAddress);
|
|
24
|
+
this._hydrateFromStore();
|
|
25
|
+
}
|
|
26
|
+
_hydrateFromStore() {
|
|
27
|
+
if (!this._channelStore)
|
|
28
|
+
return;
|
|
29
|
+
const activeChannels = this._channelStore.getActiveChannelsByBuyer(CHANNEL_ROLE.BUYER, this._identity.wallet.address, CHANNEL_KIND.FREE);
|
|
30
|
+
for (const channel of activeChannels) {
|
|
31
|
+
if (this._sessions.has(channel.peerId))
|
|
32
|
+
continue;
|
|
33
|
+
const metadata = this._channelStore.getChannelMetadata(channel);
|
|
34
|
+
this._sessions.set(channel.peerId, {
|
|
35
|
+
channelId: channel.sessionId,
|
|
36
|
+
// Salt is only needed to create a fresh open signature; hydrated
|
|
37
|
+
// sessions are already opened and only sign usage auths.
|
|
38
|
+
salt: '0x' + '00'.repeat(32),
|
|
39
|
+
deadline: channel.deadline,
|
|
40
|
+
sellerEvmAddr: channel.sellerEvmAddr,
|
|
41
|
+
cumulativeInputTokens: metadata.cumulativeInputTokens,
|
|
42
|
+
cumulativeOutputTokens: metadata.cumulativeOutputTokens,
|
|
43
|
+
cumulativeRequestCount: metadata.cumulativeRequestCount,
|
|
44
|
+
latestSequence: BigInt(channel.requestCount),
|
|
45
|
+
services: metadata.services,
|
|
46
|
+
openedAck: true,
|
|
47
|
+
latestMetadata: metadata,
|
|
48
|
+
openSig: channel.latestBuyerSig,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
trackRequestService(requestId, service) {
|
|
53
|
+
this._requestService.track(requestId, service);
|
|
54
|
+
}
|
|
55
|
+
async prepareOpen(peer, paymentMux) {
|
|
56
|
+
const existing = this._sessions.get(peer.peerId);
|
|
57
|
+
const nowSec = Math.floor(Date.now() / 1000);
|
|
58
|
+
if (existing && existing.deadline > nowSec + 30)
|
|
59
|
+
return;
|
|
60
|
+
const sellerEvmAddr = await this._resolveSellerAddr(peer);
|
|
61
|
+
const salt = '0x' + randomBytes(32).toString('hex');
|
|
62
|
+
const channelId = computeFreeUsageChannelId(this._identity.wallet.address, sellerEvmAddr, salt);
|
|
63
|
+
const deadline = nowSec + this._config.defaultAuthDurationSecs;
|
|
64
|
+
const openSig = await signFreeUsageOpen(this._identity.wallet, this._domain, {
|
|
65
|
+
channelId,
|
|
66
|
+
deadline: BigInt(deadline),
|
|
67
|
+
});
|
|
68
|
+
const metadata = {
|
|
69
|
+
cumulativeInputTokens: 0n,
|
|
70
|
+
cumulativeOutputTokens: 0n,
|
|
71
|
+
cumulativeRequestCount: 0n,
|
|
72
|
+
services: [],
|
|
73
|
+
};
|
|
74
|
+
const session = {
|
|
75
|
+
channelId,
|
|
76
|
+
salt,
|
|
77
|
+
deadline,
|
|
78
|
+
sellerEvmAddr,
|
|
79
|
+
cumulativeInputTokens: 0n,
|
|
80
|
+
cumulativeOutputTokens: 0n,
|
|
81
|
+
cumulativeRequestCount: 0n,
|
|
82
|
+
latestSequence: 0n,
|
|
83
|
+
services: [],
|
|
84
|
+
openedAck: false,
|
|
85
|
+
latestMetadata: metadata,
|
|
86
|
+
openSig,
|
|
87
|
+
};
|
|
88
|
+
this._sessions.set(peer.peerId, session);
|
|
89
|
+
try {
|
|
90
|
+
paymentMux.sendFreeUsageOpen({ channelId, salt, deadline, openSig });
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
if (existing) {
|
|
94
|
+
this._sessions.set(peer.peerId, existing);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
this._sessions.delete(peer.peerId);
|
|
98
|
+
}
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
debugLog(`[BuyerFreeUsage] Open sent to ${peer.peerId.slice(0, 12)}... channel=${channelId.slice(0, 18)}...`);
|
|
102
|
+
}
|
|
103
|
+
async waitForOpenAck(sellerPeerId, timeoutMs = this._config.openAckTimeoutMs ?? DEFAULT_OPEN_ACK_TIMEOUT_MS) {
|
|
104
|
+
const session = this._sessions.get(sellerPeerId);
|
|
105
|
+
if (!session) {
|
|
106
|
+
throw new Error(`free usage channel for ${sellerPeerId.slice(0, 12)}... was not prepared`);
|
|
107
|
+
}
|
|
108
|
+
if (session.openedAck)
|
|
109
|
+
return;
|
|
110
|
+
await new Promise((resolve, reject) => {
|
|
111
|
+
const waiter = {
|
|
112
|
+
session,
|
|
113
|
+
resolve,
|
|
114
|
+
reject,
|
|
115
|
+
timer: setTimeout(() => {
|
|
116
|
+
this._removeOpenAckWaiter(sellerPeerId, waiter);
|
|
117
|
+
if (this._sessions.get(sellerPeerId) === session && !session.openedAck) {
|
|
118
|
+
this._sessions.delete(sellerPeerId);
|
|
119
|
+
this._channelStore?.updateChannelStatus(session.channelId, CHANNEL_STATUS.TIMEOUT);
|
|
120
|
+
}
|
|
121
|
+
reject(new Error(`timed out waiting for free usage open ack from ${sellerPeerId.slice(0, 12)}...`));
|
|
122
|
+
}, timeoutMs),
|
|
123
|
+
};
|
|
124
|
+
let waiters = this._openAckWaiters.get(sellerPeerId);
|
|
125
|
+
if (!waiters) {
|
|
126
|
+
waiters = new Set();
|
|
127
|
+
this._openAckWaiters.set(sellerPeerId, waiters);
|
|
128
|
+
}
|
|
129
|
+
waiters.add(waiter);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
handleAck(sellerPeerId, payload) {
|
|
133
|
+
const session = this._sessions.get(sellerPeerId);
|
|
134
|
+
if (!session || session.channelId !== payload.channelId)
|
|
135
|
+
return;
|
|
136
|
+
session.openedAck = true;
|
|
137
|
+
this._persistSession(sellerPeerId, session, session.openSig, null, null);
|
|
138
|
+
this._retireOtherActiveSessions(sellerPeerId, session.channelId);
|
|
139
|
+
this._resolveOpenAckWaiters(sellerPeerId, session);
|
|
140
|
+
debugLog(`[BuyerFreeUsage] Ack from ${sellerPeerId.slice(0, 12)}... channel=${payload.channelId.slice(0, 18)}...` +
|
|
141
|
+
`${payload.acceptedSequence ? ` sequence=${payload.acceptedSequence}` : ''}`);
|
|
142
|
+
}
|
|
143
|
+
onPeerDisconnect(sellerPeerId) {
|
|
144
|
+
this._sessions.delete(sellerPeerId);
|
|
145
|
+
this._sellerLocks.delete(sellerPeerId);
|
|
146
|
+
this._rejectOpenAckWaiters(sellerPeerId, new Error(`peer ${sellerPeerId.slice(0, 12)}... disconnected before free usage open ack`));
|
|
147
|
+
}
|
|
148
|
+
async handleNeedAuth(sellerPeerId, payload, paymentMux) {
|
|
149
|
+
const lock = (this._sellerLocks.get(sellerPeerId) ?? Promise.resolve()).then(async () => {
|
|
150
|
+
await this._handleNeedAuthInner(sellerPeerId, payload, paymentMux);
|
|
151
|
+
});
|
|
152
|
+
this._sellerLocks.set(sellerPeerId, lock.catch(() => { }));
|
|
153
|
+
return lock;
|
|
154
|
+
}
|
|
155
|
+
async _handleNeedAuthInner(sellerPeerId, payload, paymentMux) {
|
|
156
|
+
const session = this._sessions.get(sellerPeerId);
|
|
157
|
+
if (!session || session.channelId !== payload.channelId) {
|
|
158
|
+
debugWarn(`[BuyerFreeUsage] NeedFreeUsageAuth for unknown channel ${payload.channelId.slice(0, 18)}...`);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const requiredSequence = BigInt(payload.requiredSequence);
|
|
162
|
+
if (requiredSequence <= session.latestSequence) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const inputTokens = BigInt(payload.inputTokens ?? '0');
|
|
166
|
+
const outputTokens = BigInt(payload.outputTokens ?? '0');
|
|
167
|
+
const attributedService = this._requestService.get(payload.requestId) ?? payload.service;
|
|
168
|
+
const metadata = advanceUsageMetadata(session.latestMetadata, attributedService, {
|
|
169
|
+
amount: 0n,
|
|
170
|
+
inputTokens,
|
|
171
|
+
cachedInputTokens: 0n,
|
|
172
|
+
outputTokens,
|
|
173
|
+
requests: 1n,
|
|
174
|
+
});
|
|
175
|
+
const metadataHash = computeFreeUsageMetadataHash(metadata);
|
|
176
|
+
const encodedMetadata = encodeFreeUsageMetadata(metadata);
|
|
177
|
+
const usageSig = await signFreeUsageAuth(this._identity.wallet, this._domain, {
|
|
178
|
+
channelId: session.channelId,
|
|
179
|
+
sequence: requiredSequence,
|
|
180
|
+
metadataHash,
|
|
181
|
+
deadline: BigInt(session.deadline),
|
|
182
|
+
});
|
|
183
|
+
paymentMux.sendFreeUsageAuth({
|
|
184
|
+
channelId: session.channelId,
|
|
185
|
+
cumulativeInputTokens: metadata.cumulativeInputTokens.toString(),
|
|
186
|
+
cumulativeOutputTokens: metadata.cumulativeOutputTokens.toString(),
|
|
187
|
+
sequence: requiredSequence.toString(),
|
|
188
|
+
metadataHash,
|
|
189
|
+
metadata: encodedMetadata,
|
|
190
|
+
deadline: session.deadline,
|
|
191
|
+
usageSig,
|
|
192
|
+
});
|
|
193
|
+
session.latestSequence = requiredSequence;
|
|
194
|
+
session.cumulativeInputTokens = metadata.cumulativeInputTokens;
|
|
195
|
+
session.cumulativeOutputTokens = metadata.cumulativeOutputTokens;
|
|
196
|
+
session.cumulativeRequestCount = metadata.cumulativeRequestCount;
|
|
197
|
+
session.services = metadata.services;
|
|
198
|
+
session.latestMetadata = metadata;
|
|
199
|
+
this._requestService.take(payload.requestId);
|
|
200
|
+
this._persistSession(sellerPeerId, session, null, usageSig, encodedMetadata);
|
|
201
|
+
debugLog(`[BuyerFreeUsage] UsageAuth sent to ${sellerPeerId.slice(0, 12)}... ` +
|
|
202
|
+
`channel=${session.channelId.slice(0, 18)}... sequence=${session.latestSequence}`);
|
|
203
|
+
}
|
|
204
|
+
async _resolveSellerAddr(peer) {
|
|
205
|
+
if (!this._sellerAddressResolver)
|
|
206
|
+
return peerIdToAddress(peer.peerId);
|
|
207
|
+
return this._sellerAddressResolver.resolveSellerAddress(peer.peerId, peer.metadata);
|
|
208
|
+
}
|
|
209
|
+
_resolveOpenAckWaiters(sellerPeerId, session) {
|
|
210
|
+
const waiters = this._openAckWaiters.get(sellerPeerId);
|
|
211
|
+
if (!waiters)
|
|
212
|
+
return;
|
|
213
|
+
for (const waiter of [...waiters]) {
|
|
214
|
+
if (waiter.session !== session)
|
|
215
|
+
continue;
|
|
216
|
+
this._removeOpenAckWaiter(sellerPeerId, waiter);
|
|
217
|
+
waiter.resolve();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
_rejectOpenAckWaiters(sellerPeerId, err) {
|
|
221
|
+
const waiters = this._openAckWaiters.get(sellerPeerId);
|
|
222
|
+
if (!waiters)
|
|
223
|
+
return;
|
|
224
|
+
for (const waiter of [...waiters]) {
|
|
225
|
+
this._removeOpenAckWaiter(sellerPeerId, waiter);
|
|
226
|
+
waiter.reject(err);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
_removeOpenAckWaiter(sellerPeerId, waiter) {
|
|
230
|
+
clearTimeout(waiter.timer);
|
|
231
|
+
const waiters = this._openAckWaiters.get(sellerPeerId);
|
|
232
|
+
if (!waiters)
|
|
233
|
+
return;
|
|
234
|
+
waiters.delete(waiter);
|
|
235
|
+
if (waiters.size === 0)
|
|
236
|
+
this._openAckWaiters.delete(sellerPeerId);
|
|
237
|
+
}
|
|
238
|
+
_retireOtherActiveSessions(sellerPeerId, keepSessionId) {
|
|
239
|
+
if (!this._channelStore)
|
|
240
|
+
return;
|
|
241
|
+
const activeChannels = this._channelStore.getActiveChannelsByBuyer(CHANNEL_ROLE.BUYER, this._identity.wallet.address, CHANNEL_KIND.FREE);
|
|
242
|
+
for (const channel of activeChannels) {
|
|
243
|
+
if (channel.peerId !== sellerPeerId || channel.sessionId === keepSessionId)
|
|
244
|
+
continue;
|
|
245
|
+
this._channelStore.updateChannelStatus(channel.sessionId, CHANNEL_STATUS.GHOST);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
_persistSession(sellerPeerId, session, openSig, usageSig, encodedMetadata) {
|
|
249
|
+
if (!this._channelStore)
|
|
250
|
+
return;
|
|
251
|
+
const now = Date.now();
|
|
252
|
+
const existing = this._channelStore.getChannel(session.channelId);
|
|
253
|
+
this._channelStore.upsertChannel({
|
|
254
|
+
sessionId: session.channelId,
|
|
255
|
+
peerId: sellerPeerId,
|
|
256
|
+
role: CHANNEL_ROLE.BUYER,
|
|
257
|
+
channelKind: CHANNEL_KIND.FREE,
|
|
258
|
+
sellerEvmAddr: session.sellerEvmAddr,
|
|
259
|
+
buyerEvmAddr: this._identity.wallet.address,
|
|
260
|
+
nonce: 0,
|
|
261
|
+
authMax: '0',
|
|
262
|
+
deadline: session.deadline,
|
|
263
|
+
previousSessionId: '0x' + '00'.repeat(32),
|
|
264
|
+
previousConsumption: session.cumulativeOutputTokens.toString(),
|
|
265
|
+
tokensDelivered: session.cumulativeInputTokens.toString(),
|
|
266
|
+
requestCount: Number(session.cumulativeRequestCount),
|
|
267
|
+
reservedAt: existing?.reservedAt ?? now,
|
|
268
|
+
settledAt: null,
|
|
269
|
+
settledAmount: null,
|
|
270
|
+
status: CHANNEL_STATUS.ACTIVE,
|
|
271
|
+
latestBuyerSig: openSig ?? existing?.latestBuyerSig ?? null,
|
|
272
|
+
latestSpendingAuthSig: usageSig ?? existing?.latestSpendingAuthSig ?? null,
|
|
273
|
+
latestMetadata: encodedMetadata ?? existing?.latestMetadata ?? null,
|
|
274
|
+
createdAt: existing?.createdAt ?? now,
|
|
275
|
+
updatedAt: now,
|
|
276
|
+
});
|
|
277
|
+
this._channelStore.replaceMetadataServiceTotals(session.channelId, session.services);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=buyer-free-usage-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buyer-free-usage-manager.js","sourceRoot":"","sources":["../../src/payments/buyer-free-usage-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAM1C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EACL,yBAAyB,EACzB,4BAA4B,EAC5B,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,GAElB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAqB,MAAM,oBAAoB,CAAC;AACnG,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AA+B5F,MAAM,2BAA2B,GAAG,MAAM,CAAC;AAE3C,MAAM,OAAO,qBAAqB;IACf,SAAS,CAAW;IACpB,OAAO,CAAuB;IAC9B,sBAAsB,CAAyB;IAC/C,aAAa,CAAgB;IAC7B,OAAO,CAAyC;IAChD,SAAS,GAAG,IAAI,GAAG,EAA4B,CAAC;IAChD,YAAY,GAAG,IAAI,GAAG,EAAyB,CAAC;IAChD,eAAe,GAAG,IAAI,GAAG,EAA8B,CAAC;IACxD,eAAe,GAAG,IAAI,qBAAqB,EAAE,CAAC;IAE/D,YACE,QAAkB,EAClB,MAA4B,EAC5B,qBAA6C,EAC7C,YAA2B;QAE3B,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,sBAAsB,GAAG,qBAAqB,CAAC;QACpD,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,mBAAmB,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,wBAAwB,CAAC,CAAC;QACpF,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3B,CAAC;IAEO,iBAAiB;QACvB,IAAI,CAAC,IAAI,CAAC,aAAa;YAAE,OAAO;QAChC,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,wBAAwB,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;QACzI,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;YACrC,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,SAAS;YACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;YAChE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE;gBACjC,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,iEAAiE;gBACjE,yDAAyD;gBACzD,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,qBAAqB,EAAE,QAAQ,CAAC,qBAAqB;gBACrD,sBAAsB,EAAE,QAAQ,CAAC,sBAAsB;gBACvD,sBAAsB,EAAE,QAAQ,CAAC,sBAAsB;gBACvD,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;gBAC5C,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,SAAS,EAAE,IAAI;gBACf,cAAc,EAAE,QAAQ;gBACxB,OAAO,EAAE,OAAO,CAAC,cAAc;aAChC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,mBAAmB,CAAC,SAAiB,EAAE,OAAe;QACpD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,IAAc,EAAE,UAAsB;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC7C,IAAI,QAAQ,IAAI,QAAQ,CAAC,QAAQ,GAAG,MAAM,GAAG,EAAE;YAAE,OAAO;QAExD,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAG,IAAI,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,yBAAyB,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;QAChG,MAAM,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC;QAC/D,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE;YAC3E,SAAS;YACT,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;SAC3B,CAAC,CAAC;QACH,MAAM,QAAQ,GAAsB;YAClC,qBAAqB,EAAE,EAAE;YACzB,sBAAsB,EAAE,EAAE;YAC1B,sBAAsB,EAAE,EAAE;YAC1B,QAAQ,EAAE,EAAE;SACb,CAAC;QAEF,MAAM,OAAO,GAAqB;YAChC,SAAS;YACT,IAAI;YACJ,QAAQ;YACR,aAAa;YACb,qBAAqB,EAAE,EAAE;YACzB,sBAAsB,EAAE,EAAE;YAC1B,sBAAsB,EAAE,EAAE;YAC1B,cAAc,EAAE,EAAE;YAClB,QAAQ,EAAE,EAAE;YACZ,SAAS,EAAE,KAAK;YAChB,cAAc,EAAE,QAAQ;YACxB,OAAO;SACR,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC;YACH,UAAU,CAAC,iBAAiB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QACvE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,QAAQ,EAAE,CAAC;gBACb,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrC,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,QAAQ,CAAC,iCAAiC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;IAChH,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,YAAoB,EAAE,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,IAAI,2BAA2B;QACjH,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACjD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,0BAA0B,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,sBAAsB,CAAC,CAAC;QAC7F,CAAC;QACD,IAAI,OAAO,CAAC,SAAS;YAAE,OAAO;QAE9B,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,MAAM,MAAM,GAAkB;gBAC5B,OAAO;gBACP,OAAO;gBACP,MAAM;gBACN,KAAK,EAAE,UAAU,CAAC,GAAG,EAAE;oBACrB,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;oBAChD,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;wBACvE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;wBACpC,IAAI,CAAC,aAAa,EAAE,mBAAmB,CAAC,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;oBACrF,CAAC;oBACD,MAAM,CAAC,IAAI,KAAK,CAAC,kDAAkD,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;gBACtG,CAAC,EAAE,SAAS,CAAC;aACd,CAAC;YACF,IAAI,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YACrD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;gBACpB,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YAClD,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,CAAC,YAAoB,EAAE,OAA4B;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACjD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,SAAS;YAAE,OAAO;QAChE,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACzE,IAAI,CAAC,0BAA0B,CAAC,YAAY,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QACjE,IAAI,CAAC,sBAAsB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACnD,QAAQ,CACN,6BAA6B,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK;YACxG,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,aAAa,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAC7E,CAAC;IACJ,CAAC;IAED,gBAAgB,CAAC,YAAoB;QACnC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACpC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACvC,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE,IAAI,KAAK,CAAC,QAAQ,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,6CAA6C,CAAC,CAAC,CAAC;IACtI,CAAC;IAED,KAAK,CAAC,cAAc,CAClB,YAAoB,EACpB,OAAiC,EACjC,UAAsB;QAEtB,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YACtF,MAAM,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAChC,YAAoB,EACpB,OAAiC,EACjC,UAAsB;QAEtB,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACjD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;YACxD,SAAS,CAAC,0DAA0D,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;YACzG,OAAO;QACT,CAAC;QAED,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAC1D,IAAI,gBAAgB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;YAC/C,OAAO;QACT,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,IAAI,GAAG,CAAC,CAAC;QACvD,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,IAAI,GAAG,CAAC,CAAC;QACzD,MAAM,iBAAiB,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC;QAEzF,MAAM,QAAQ,GAAG,oBAAoB,CAAC,OAAO,CAAC,cAAc,EAAE,iBAAiB,EAAE;YAC/E,MAAM,EAAE,EAAE;YACV,WAAW;YACX,iBAAiB,EAAE,EAAE;YACrB,YAAY;YACZ,QAAQ,EAAE,EAAE;SACb,CAAC,CAAC;QACH,MAAM,YAAY,GAAG,4BAA4B,CAAC,QAAQ,CAAC,CAAC;QAC5D,MAAM,eAAe,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;QAC1D,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE;YAC5E,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,QAAQ,EAAE,gBAAgB;YAC1B,YAAY;YACZ,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;SACnC,CAAC,CAAC;QAEH,UAAU,CAAC,iBAAiB,CAAC;YAC3B,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,qBAAqB,EAAE,QAAQ,CAAC,qBAAqB,CAAC,QAAQ,EAAE;YAChE,sBAAsB,EAAE,QAAQ,CAAC,sBAAsB,CAAC,QAAQ,EAAE;YAClE,QAAQ,EAAE,gBAAgB,CAAC,QAAQ,EAAE;YACrC,YAAY;YACZ,QAAQ,EAAE,eAAe;YACzB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,QAAQ;SACT,CAAC,CAAC;QAEH,OAAO,CAAC,cAAc,GAAG,gBAAgB,CAAC;QAC1C,OAAO,CAAC,qBAAqB,GAAG,QAAQ,CAAC,qBAAqB,CAAC;QAC/D,OAAO,CAAC,sBAAsB,GAAG,QAAQ,CAAC,sBAAsB,CAAC;QACjE,OAAO,CAAC,sBAAsB,GAAG,QAAQ,CAAC,sBAAsB,CAAC;QACjE,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;QACrC,OAAO,CAAC,cAAc,GAAG,QAAQ,CAAC;QAClC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;QAC7E,QAAQ,CACN,sCAAsC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM;YACrE,WAAW,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,OAAO,CAAC,cAAc,EAAE,CAClF,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,IAAc;QAC7C,IAAI,CAAC,IAAI,CAAC,sBAAsB;YAAE,OAAO,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtE,OAAO,IAAI,CAAC,sBAAsB,CAAC,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtF,CAAC;IAEO,sBAAsB,CAAC,YAAoB,EAAE,OAAyB;QAC5E,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC;YAClC,IAAI,MAAM,CAAC,OAAO,KAAK,OAAO;gBAAE,SAAS;YACzC,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YAChD,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;IAEO,qBAAqB,CAAC,YAAoB,EAAE,GAAU;QAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YAChD,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAEO,oBAAoB,CAAC,YAAoB,EAAE,MAAqB;QACtE,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACvD,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACvB,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;YAAE,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACpE,CAAC;IAEO,0BAA0B,CAAC,YAAoB,EAAE,aAAqB;QAC5E,IAAI,CAAC,IAAI,CAAC,aAAa;YAAE,OAAO;QAChC,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,wBAAwB,CAChE,YAAY,CAAC,KAAK,EAClB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,EAC7B,YAAY,CAAC,IAAI,CAClB,CAAC;QACF,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;YACrC,IAAI,OAAO,CAAC,MAAM,KAAK,YAAY,IAAI,OAAO,CAAC,SAAS,KAAK,aAAa;gBAAE,SAAS;YACrF,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IAEO,eAAe,CACrB,YAAoB,EACpB,OAAyB,EACzB,OAAsB,EACtB,QAAuB,EACvB,eAA8B;QAE9B,IAAI,CAAC,IAAI,CAAC,aAAa;YAAE,OAAO;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAClE,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC;YAC/B,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,MAAM,EAAE,YAAY;YACpB,IAAI,EAAE,YAAY,CAAC,KAAK;YACxB,WAAW,EAAE,YAAY,CAAC,IAAI;YAC9B,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO;YAC3C,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,GAAG;YACZ,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,iBAAiB,EAAE,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACzC,mBAAmB,EAAE,OAAO,CAAC,sBAAsB,CAAC,QAAQ,EAAE;YAC9D,eAAe,EAAE,OAAO,CAAC,qBAAqB,CAAC,QAAQ,EAAE;YACzD,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC;YACpD,UAAU,EAAE,QAAQ,EAAE,UAAU,IAAI,GAAG;YACvC,SAAS,EAAE,IAAI;YACf,aAAa,EAAE,IAAI;YACnB,MAAM,EAAE,cAAc,CAAC,MAAM;YAC7B,cAAc,EAAE,OAAO,IAAI,QAAQ,EAAE,cAAc,IAAI,IAAI;YAC3D,qBAAqB,EAAE,QAAQ,IAAI,QAAQ,EAAE,qBAAqB,IAAI,IAAI;YAC1E,cAAc,EAAE,eAAe,IAAI,QAAQ,EAAE,cAAc,IAAI,IAAI;YACnE,SAAS,EAAE,QAAQ,EAAE,SAAS,IAAI,GAAG;YACrC,SAAS,EAAE,GAAG;SACf,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,CAAC,4BAA4B,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvF,CAAC;CACF"}
|
|
@@ -5,7 +5,7 @@ import type { SpendingAuthPayload, AuthAckPayload, NeedAuthPayload } from '../ty
|
|
|
5
5
|
import { DepositsClient } from './evm/deposits-client.js';
|
|
6
6
|
import type { SellerAddressResolver } from '../discovery/seller-address-resolver.js';
|
|
7
7
|
import type { PeerMetadata } from '../discovery/peer-metadata.js';
|
|
8
|
-
import { ChannelStore, type StoredChannel } from './channel-store.js';
|
|
8
|
+
import { ChannelStore, CHANNEL_STATUS, type StoredChannel } from './channel-store.js';
|
|
9
9
|
import { type ServicePricing } from './pricing.js';
|
|
10
10
|
export interface BuyerPaymentConfig {
|
|
11
11
|
rpcUrl: string;
|
|
@@ -79,7 +79,7 @@ export declare class BuyerPaymentManager {
|
|
|
79
79
|
/** Clean up all in-memory state for a seller when the session ends. */
|
|
80
80
|
cleanupSession(sellerPeerId: string): void;
|
|
81
81
|
getActiveSession(sellerPeerId: string): StoredChannel | null;
|
|
82
|
-
retireSession(sellerPeerId: string, status:
|
|
82
|
+
retireSession(sellerPeerId: string, status: typeof CHANNEL_STATUS.SETTLED | typeof CHANNEL_STATUS.TIMEOUT | typeof CHANNEL_STATUS.GHOST, settledAmount?: bigint): void;
|
|
83
83
|
canReplayReserveAuth(sellerPeerId: string): boolean;
|
|
84
84
|
clearLockConfirmation(sellerPeerId: string): void;
|
|
85
85
|
resendCurrentSpendingAuth(sellerPeerId: string, paymentMux: PaymentMux): Promise<string>;
|
|
@@ -87,7 +87,6 @@ export declare class BuyerPaymentManager {
|
|
|
87
87
|
resendReserveAuth(sellerPeerId: string, paymentMux: PaymentMux): Promise<string>;
|
|
88
88
|
private _reopenOverdraftWindowIfCollapsed;
|
|
89
89
|
private _needsCeilingAdvance;
|
|
90
|
-
private _withServiceMetadata;
|
|
91
90
|
/**
|
|
92
91
|
* Both signPerRequestAuth (buyer-initiated) and handleNeedAuth (seller-initiated)
|
|
93
92
|
* can fire for the same request when the proactive auth doesn't fully cover the
|
|
@@ -95,7 +94,6 @@ export declare class BuyerPaymentManager {
|
|
|
95
94
|
* records its requestId here so the other path attributes only the amount delta.
|
|
96
95
|
*/
|
|
97
96
|
private readonly _serviceTokensCounted;
|
|
98
|
-
private _markServiceTokensCounted;
|
|
99
97
|
private _persistServiceMetadata;
|
|
100
98
|
private _sendUpdatedSpendingAuth;
|
|
101
99
|
private _topUpAfterSpendAuthBestEffort;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buyer-payment-manager.d.ts","sourceRoot":"","sources":["../../src/payments/buyer-payment-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACd,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"buyer-payment-manager.d.ts","sourceRoot":"","sources":["../../src/payments/buyer-payment-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { randomBytes } from 'node:crypto';
|
|
2
2
|
import { DepositsClient } from './evm/deposits-client.js';
|
|
3
|
-
import { signSpendingAuth, signReserveAuth, makeChannelsDomain, computeMetadataHash, encodeMetadata,
|
|
3
|
+
import { signSpendingAuth, signReserveAuth, makeChannelsDomain, computeMetadataHash, encodeMetadata, ZERO_METADATA, ZERO_METADATA_HASH, computeChannelId, } from './evm/signatures.js';
|
|
4
4
|
import { debugLog, debugWarn } from '../utils/debug.js';
|
|
5
5
|
import { peerIdToAddress } from '../types/peer.js';
|
|
6
|
+
import { CHANNEL_ROLE, CHANNEL_STATUS } from './channel-store.js';
|
|
7
|
+
import { advanceUsageMetadata, CountedRequestTracker, RequestServiceTracker } from './channel-usage-accounting.js';
|
|
6
8
|
import { estimateCostFromBytes, computeCostUsdc } from './pricing.js';
|
|
7
9
|
/** Default tolerance: accept seller claims up to 1.4x buyer's estimate. */
|
|
8
10
|
const DEFAULT_COST_TOLERANCE = 1.4;
|
|
@@ -35,7 +37,7 @@ export class BuyerPaymentManager {
|
|
|
35
37
|
/** requestId -> service/model the buyer requested (from its own request body).
|
|
36
38
|
* Used in handleNeedAuth to validate cost with the correct pricing tier
|
|
37
39
|
* without trusting the seller's claim of which service was used. */
|
|
38
|
-
_requestService = new
|
|
40
|
+
_requestService = new RequestServiceTracker();
|
|
39
41
|
/** sellerPeerId -> full pricing map (defaults + per-service overrides from peer metadata / 402) */
|
|
40
42
|
_sessionPricing = new Map();
|
|
41
43
|
/** Cumulative response token totals per seller, tracked independently of signing metadata. */
|
|
@@ -65,25 +67,12 @@ export class BuyerPaymentManager {
|
|
|
65
67
|
}
|
|
66
68
|
/** Hydrate cumulative tracking maps from persisted active buyer sessions. */
|
|
67
69
|
_hydrateFromStore() {
|
|
68
|
-
const activeChannels = this._channelStore.getActiveChannelsByBuyer(
|
|
70
|
+
const activeChannels = this._channelStore.getActiveChannelsByBuyer(CHANNEL_ROLE.BUYER, this._identity.wallet.address);
|
|
69
71
|
for (const channel of activeChannels) {
|
|
70
72
|
const peerId = channel.peerId;
|
|
71
73
|
const persistedCumulative = BigInt(channel.authMax);
|
|
72
|
-
const persistedServiceTotals = this._channelStore.getServiceTotals(channel.sessionId);
|
|
73
74
|
this._cumulativeAmount.set(peerId, persistedCumulative);
|
|
74
|
-
this._metadata.set(peerId,
|
|
75
|
-
cumulativeInputTokens: BigInt(channel.tokensDelivered),
|
|
76
|
-
cumulativeOutputTokens: BigInt(channel.previousConsumption),
|
|
77
|
-
cumulativeRequestCount: BigInt(channel.requestCount),
|
|
78
|
-
services: persistedServiceTotals.map((total) => ({
|
|
79
|
-
serviceId: total.serviceId,
|
|
80
|
-
cumulativeAmount: BigInt(total.cumulativeAmount),
|
|
81
|
-
cumulativeInputTokens: BigInt(total.cumulativeInputTokens),
|
|
82
|
-
cumulativeCachedInputTokens: BigInt(total.cumulativeCachedInputTokens),
|
|
83
|
-
cumulativeOutputTokens: BigInt(total.cumulativeOutputTokens),
|
|
84
|
-
cumulativeRequestCount: BigInt(total.cumulativeRequestCount),
|
|
85
|
-
})),
|
|
86
|
-
});
|
|
75
|
+
this._metadata.set(peerId, this._channelStore.getChannelMetadata(channel));
|
|
87
76
|
// Hydrate verifiedCost to authMax so _maxSignable can grow beyond maxPerRequestUsdc.
|
|
88
77
|
// Without this, maxSignable = 0 + maxPerRequestUsdc after restart, permanently capping
|
|
89
78
|
// the cumulative and causing non-monotonic SpendingAuth rejections on the seller.
|
|
@@ -123,7 +112,7 @@ export class BuyerPaymentManager {
|
|
|
123
112
|
this._responseTokenTotals.delete(sellerPeerId);
|
|
124
113
|
}
|
|
125
114
|
getActiveSession(sellerPeerId) {
|
|
126
|
-
return this._channelStore.getActiveChannelByPeerAndBuyer(sellerPeerId,
|
|
115
|
+
return this._channelStore.getActiveChannelByPeerAndBuyer(sellerPeerId, CHANNEL_ROLE.BUYER, this._identity.wallet.address);
|
|
127
116
|
}
|
|
128
117
|
retireSession(sellerPeerId, status, settledAmount) {
|
|
129
118
|
const session = this.getActiveSession(sellerPeerId);
|
|
@@ -257,59 +246,15 @@ export class BuyerPaymentManager {
|
|
|
257
246
|
_needsCeilingAdvance(requestedAmount, maxSignable, ceiling) {
|
|
258
247
|
return requestedAmount > maxSignable && maxSignable >= ceiling;
|
|
259
248
|
}
|
|
260
|
-
_withServiceMetadata(metadata, service, delta) {
|
|
261
|
-
if (!service || service.trim().length === 0)
|
|
262
|
-
return metadata;
|
|
263
|
-
const serviceId = getServiceMetadataId(service);
|
|
264
|
-
const byServiceId = new Map();
|
|
265
|
-
for (const entry of metadata.services ?? []) {
|
|
266
|
-
byServiceId.set(entry.serviceId, { ...entry });
|
|
267
|
-
}
|
|
268
|
-
const existing = byServiceId.get(serviceId) ?? {
|
|
269
|
-
serviceId,
|
|
270
|
-
cumulativeAmount: 0n,
|
|
271
|
-
cumulativeInputTokens: 0n,
|
|
272
|
-
cumulativeCachedInputTokens: 0n,
|
|
273
|
-
cumulativeOutputTokens: 0n,
|
|
274
|
-
cumulativeRequestCount: 0n,
|
|
275
|
-
};
|
|
276
|
-
byServiceId.set(serviceId, {
|
|
277
|
-
serviceId,
|
|
278
|
-
cumulativeAmount: existing.cumulativeAmount + delta.amount,
|
|
279
|
-
cumulativeInputTokens: existing.cumulativeInputTokens + delta.inputTokens,
|
|
280
|
-
cumulativeCachedInputTokens: existing.cumulativeCachedInputTokens + delta.cachedInputTokens,
|
|
281
|
-
cumulativeOutputTokens: existing.cumulativeOutputTokens + delta.outputTokens,
|
|
282
|
-
cumulativeRequestCount: existing.cumulativeRequestCount + delta.requests,
|
|
283
|
-
});
|
|
284
|
-
return {
|
|
285
|
-
...metadata,
|
|
286
|
-
services: [...byServiceId.values()].sort((a, b) => a.serviceId < b.serviceId ? -1 : a.serviceId > b.serviceId ? 1 : 0),
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
249
|
/**
|
|
290
250
|
* Both signPerRequestAuth (buyer-initiated) and handleNeedAuth (seller-initiated)
|
|
291
251
|
* can fire for the same request when the proactive auth doesn't fully cover the
|
|
292
252
|
* seller's required cumulative. Whichever path counts a request's tokens first
|
|
293
253
|
* records its requestId here so the other path attributes only the amount delta.
|
|
294
254
|
*/
|
|
295
|
-
_serviceTokensCounted = new
|
|
296
|
-
_markServiceTokensCounted(requestId) {
|
|
297
|
-
if (this._serviceTokensCounted.size >= 512) {
|
|
298
|
-
const oldest = this._serviceTokensCounted.values().next().value;
|
|
299
|
-
if (oldest !== undefined)
|
|
300
|
-
this._serviceTokensCounted.delete(oldest);
|
|
301
|
-
}
|
|
302
|
-
this._serviceTokensCounted.add(requestId);
|
|
303
|
-
}
|
|
255
|
+
_serviceTokensCounted = new CountedRequestTracker();
|
|
304
256
|
_persistServiceMetadata(sessionId, metadata) {
|
|
305
|
-
this._channelStore.
|
|
306
|
-
serviceId: service.serviceId,
|
|
307
|
-
cumulativeAmount: service.cumulativeAmount.toString(),
|
|
308
|
-
cumulativeInputTokens: service.cumulativeInputTokens.toString(),
|
|
309
|
-
cumulativeCachedInputTokens: service.cumulativeCachedInputTokens.toString(),
|
|
310
|
-
cumulativeOutputTokens: service.cumulativeOutputTokens.toString(),
|
|
311
|
-
cumulativeRequestCount: service.cumulativeRequestCount.toString(),
|
|
312
|
-
})));
|
|
257
|
+
this._channelStore.replaceMetadataServiceTotals(sessionId, metadata.services);
|
|
313
258
|
}
|
|
314
259
|
async _sendUpdatedSpendingAuth(session, sellerPeerId, cumulativeAmount, metadata, paymentMux) {
|
|
315
260
|
const metadataHashHex = computeMetadataHash(metadata);
|
|
@@ -416,7 +361,7 @@ export class BuyerPaymentManager {
|
|
|
416
361
|
const session = {
|
|
417
362
|
sessionId: channelId,
|
|
418
363
|
peerId: sellerPeerId,
|
|
419
|
-
role:
|
|
364
|
+
role: CHANNEL_ROLE.BUYER,
|
|
420
365
|
sellerEvmAddr,
|
|
421
366
|
buyerEvmAddr: this._identity.wallet.address,
|
|
422
367
|
nonce: 0,
|
|
@@ -429,7 +374,7 @@ export class BuyerPaymentManager {
|
|
|
429
374
|
reservedAt: now,
|
|
430
375
|
settledAt: null,
|
|
431
376
|
settledAmount: null,
|
|
432
|
-
status:
|
|
377
|
+
status: CHANNEL_STATUS.ACTIVE,
|
|
433
378
|
latestBuyerSig: null,
|
|
434
379
|
latestSpendingAuthSig: null,
|
|
435
380
|
latestMetadata: null,
|
|
@@ -631,29 +576,19 @@ export class BuyerPaymentManager {
|
|
|
631
576
|
this._cumulativeAmount.set(sellerPeerId, newAmount);
|
|
632
577
|
const signedDelta = newAmount - prevAmount;
|
|
633
578
|
// Update cumulative metadata
|
|
634
|
-
const prev = this._metadata.get(sellerPeerId) ?? ZERO_METADATA;
|
|
635
|
-
const totalsMeta = {
|
|
636
|
-
cumulativeInputTokens: prev.cumulativeInputTokens + estimatedInputTokens,
|
|
637
|
-
cumulativeOutputTokens: prev.cumulativeOutputTokens + estimatedOutputTokens,
|
|
638
|
-
cumulativeRequestCount: prev.cumulativeRequestCount + 1n,
|
|
639
|
-
services: prev.services ?? [],
|
|
640
|
-
};
|
|
641
579
|
// If handleNeedAuth already counted this request (seller-initiated NeedAuth
|
|
642
580
|
// raced ahead), skip service attribution entirely: service totals are
|
|
643
581
|
// documented as lower bounds, so undercounting beats double-counting.
|
|
644
|
-
const alreadyCounted =
|
|
645
|
-
const newMeta = alreadyCounted
|
|
646
|
-
|
|
647
|
-
:
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
if (responseStats.requestId != null && !alreadyCounted) {
|
|
655
|
-
this._markServiceTokensCounted(responseStats.requestId);
|
|
656
|
-
}
|
|
582
|
+
const alreadyCounted = this._serviceTokensCounted.has(responseStats.requestId);
|
|
583
|
+
const newMeta = advanceUsageMetadata(this._metadata.get(sellerPeerId), alreadyCounted ? undefined : responseStats.service, {
|
|
584
|
+
amount: signedDelta,
|
|
585
|
+
inputTokens: estimatedInputTokens,
|
|
586
|
+
cachedInputTokens: estimatedCachedInputTokens,
|
|
587
|
+
outputTokens: estimatedOutputTokens,
|
|
588
|
+
requests: 1n,
|
|
589
|
+
});
|
|
590
|
+
if (!alreadyCounted)
|
|
591
|
+
this._serviceTokensCounted.mark(responseStats.requestId);
|
|
657
592
|
this._metadata.set(sellerPeerId, newMeta);
|
|
658
593
|
this._persistServiceMetadata(session.sessionId, newMeta);
|
|
659
594
|
debugLog(`[BuyerPayment] signPerRequestAuth #${newMeta.cumulativeRequestCount}: ` +
|
|
@@ -701,7 +636,7 @@ export class BuyerPaymentManager {
|
|
|
701
636
|
debugWarn(`[BuyerPayment] NeedAuth for unknown seller: ${sellerPeerId.slice(0, 12)}...`);
|
|
702
637
|
return;
|
|
703
638
|
}
|
|
704
|
-
const buyerService =
|
|
639
|
+
const buyerService = this._requestService.get(payload.requestId);
|
|
705
640
|
const requiredCumulativeAmount = BigInt(payload.requiredCumulativeAmount);
|
|
706
641
|
const currentCumulative = this._cumulativeAmount.get(sellerPeerId) ?? 0n;
|
|
707
642
|
// Reject stale/lower NeedAuth (monotonicity guard)
|
|
@@ -709,8 +644,7 @@ export class BuyerPaymentManager {
|
|
|
709
644
|
debugLog(`[BuyerPayment] NeedAuth stale: required=${requiredCumulativeAmount} <= current=${currentCumulative} — ignoring`);
|
|
710
645
|
return;
|
|
711
646
|
}
|
|
712
|
-
|
|
713
|
-
this._requestService.delete(payload.requestId);
|
|
647
|
+
this._requestService.take(payload.requestId);
|
|
714
648
|
let acceptedServiceCost = 0n;
|
|
715
649
|
const reportedInputTokens = BigInt(payload.inputTokens ?? '0');
|
|
716
650
|
const reportedCachedInputTokens = BigInt(payload.cachedInputTokens ?? '0');
|
|
@@ -791,30 +725,20 @@ export class BuyerPaymentManager {
|
|
|
791
725
|
const serviceAmountDelta = acceptedServiceCost > 0n
|
|
792
726
|
? (acceptedServiceCost < signedDelta ? acceptedServiceCost : signedDelta)
|
|
793
727
|
: 0n;
|
|
794
|
-
const prevMeta = this._metadata.get(sellerPeerId) ?? ZERO_METADATA;
|
|
795
|
-
const totalsMeta = {
|
|
796
|
-
cumulativeInputTokens: prevMeta.cumulativeInputTokens + reportedInputTokens,
|
|
797
|
-
cumulativeOutputTokens: prevMeta.cumulativeOutputTokens + reportedOutputTokens,
|
|
798
|
-
cumulativeRequestCount: prevMeta.cumulativeRequestCount + 1n,
|
|
799
|
-
services: prevMeta.services ?? [],
|
|
800
|
-
};
|
|
801
728
|
// If signPerRequestAuth already counted this request (buyer-initiated auth
|
|
802
729
|
// raced ahead but didn't fully cover the seller's required cumulative), skip
|
|
803
730
|
// service attribution entirely: service totals are documented as lower
|
|
804
731
|
// bounds, so undercounting beats double-counting.
|
|
805
|
-
const alreadyCounted =
|
|
806
|
-
const newMeta = alreadyCounted
|
|
807
|
-
|
|
808
|
-
:
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
if (payload.requestId != null && !alreadyCounted) {
|
|
816
|
-
this._markServiceTokensCounted(payload.requestId);
|
|
817
|
-
}
|
|
732
|
+
const alreadyCounted = this._serviceTokensCounted.has(payload.requestId);
|
|
733
|
+
const newMeta = advanceUsageMetadata(this._metadata.get(sellerPeerId), alreadyCounted ? undefined : buyerService, {
|
|
734
|
+
amount: serviceAmountDelta,
|
|
735
|
+
inputTokens: reportedInputTokens,
|
|
736
|
+
cachedInputTokens: reportedCachedInputTokens,
|
|
737
|
+
outputTokens: reportedOutputTokens,
|
|
738
|
+
requests: 1n,
|
|
739
|
+
});
|
|
740
|
+
if (!alreadyCounted)
|
|
741
|
+
this._serviceTokensCounted.mark(payload.requestId);
|
|
818
742
|
this._metadata.set(sellerPeerId, newMeta);
|
|
819
743
|
// Send via PaymentMux
|
|
820
744
|
try {
|
|
@@ -956,7 +880,7 @@ export class BuyerPaymentManager {
|
|
|
956
880
|
}
|
|
957
881
|
/** Register which service the buyer requested for a given requestId. */
|
|
958
882
|
trackRequestService(requestId, service) {
|
|
959
|
-
this._requestService.
|
|
883
|
+
this._requestService.track(requestId, service);
|
|
960
884
|
}
|
|
961
885
|
/** Get the live response token totals for a seller, or null if none recorded this session. */
|
|
962
886
|
getResponseTokenTotals(sellerPeerId) {
|