@dtelecom/x402-client 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/dist/index.js ADDED
@@ -0,0 +1,403 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ ConcurrencyLimitError: () => ConcurrencyLimitError,
24
+ DtelecomGateway: () => DtelecomGateway,
25
+ GatewayError: () => GatewayError,
26
+ InsufficientCreditsError: () => InsufficientCreditsError,
27
+ NoCapacityError: () => NoCapacityError,
28
+ PaymentError: () => PaymentError,
29
+ RateLimitError: () => RateLimitError,
30
+ createAuthHeaders: () => createAuthHeaders
31
+ });
32
+ module.exports = __toCommonJS(index_exports);
33
+
34
+ // src/client.ts
35
+ var import_viem = require("viem");
36
+ var import_chains = require("viem/chains");
37
+ var import_fetch = require("@x402/fetch");
38
+ var import_client = require("@x402/evm/exact/client");
39
+ var import_evm = require("@x402/evm");
40
+
41
+ // src/auth.ts
42
+ async function createAuthHeaders(account, method, path) {
43
+ const timestamp = Math.floor(Date.now() / 1e3).toString();
44
+ const pathname = path.split("?")[0];
45
+ const message = `${method}
46
+ ${pathname}
47
+ ${timestamp}`;
48
+ const signature = await account.signMessage({ message });
49
+ return {
50
+ Authorization: `evm:${signature}`,
51
+ "X-Wallet-Address": account.address,
52
+ "X-Wallet-Chain": "evm",
53
+ "X-Timestamp": timestamp
54
+ };
55
+ }
56
+
57
+ // src/errors.ts
58
+ var GatewayError = class extends Error {
59
+ status;
60
+ constructor(message, status) {
61
+ super(message);
62
+ this.name = "GatewayError";
63
+ this.status = status;
64
+ }
65
+ };
66
+ var InsufficientCreditsError = class extends GatewayError {
67
+ constructor(message) {
68
+ super(message, 402);
69
+ this.name = "InsufficientCreditsError";
70
+ }
71
+ };
72
+ var ConcurrencyLimitError = class extends GatewayError {
73
+ constructor(message) {
74
+ super(message, 429);
75
+ this.name = "ConcurrencyLimitError";
76
+ }
77
+ };
78
+ var RateLimitError = class extends GatewayError {
79
+ constructor(message) {
80
+ super(message, 429);
81
+ this.name = "RateLimitError";
82
+ }
83
+ };
84
+ var NoCapacityError = class extends GatewayError {
85
+ service;
86
+ constructor(message, service) {
87
+ super(message, 503);
88
+ this.name = "NoCapacityError";
89
+ this.service = service;
90
+ }
91
+ };
92
+ var PaymentError = class extends GatewayError {
93
+ constructor(message) {
94
+ super(message, 402);
95
+ this.name = "PaymentError";
96
+ }
97
+ };
98
+
99
+ // src/client.ts
100
+ var DtelecomGateway = class {
101
+ baseUrl;
102
+ account;
103
+ fetchWithPayment;
104
+ constructor(config) {
105
+ this.baseUrl = config.gatewayUrl.replace(/\/+$/, "");
106
+ this.account = config.account;
107
+ const publicClient = (0, import_viem.createPublicClient)({ chain: import_chains.base, transport: (0, import_viem.http)() });
108
+ const signer = (0, import_evm.toClientEvmSigner)(config.account, publicClient);
109
+ const x402 = new import_fetch.x402Client();
110
+ (0, import_client.registerExactEvmScheme)(x402, { signer });
111
+ this.fetchWithPayment = (0, import_fetch.wrapFetchWithPayment)(fetch, x402);
112
+ }
113
+ // --- Credits ---
114
+ async buyCredits(options) {
115
+ const r = await this.requestWithPayment("/v1/credits/purchase", {
116
+ wallet_address: this.account.address,
117
+ wallet_chain: "evm",
118
+ amount_usd: options.amountUsd
119
+ });
120
+ return {
121
+ accountId: r.account_id,
122
+ creditedMicrocredits: r.credited_microcredits,
123
+ amountUsd: r.amount_usd
124
+ };
125
+ }
126
+ // --- Account ---
127
+ async getAccount() {
128
+ const r = await this.request("GET", "/v1/account");
129
+ return {
130
+ id: r.id,
131
+ walletAddress: r.wallet_address,
132
+ walletChain: r.wallet_chain,
133
+ creditBalance: r.credit_balance,
134
+ availableBalance: r.available_balance,
135
+ maxConcurrentSessions: r.max_concurrent_sessions,
136
+ maxApiRate: r.max_api_rate,
137
+ createdAt: r.created_at
138
+ };
139
+ }
140
+ async getTransactions(options) {
141
+ const params = new URLSearchParams();
142
+ if (options?.limit !== void 0) params.set("limit", String(options.limit));
143
+ if (options?.offset !== void 0)
144
+ params.set("offset", String(options.offset));
145
+ const qs = params.toString();
146
+ const r = await this.request(
147
+ "GET",
148
+ `/v1/account/transactions${qs ? `?${qs}` : ""}`
149
+ );
150
+ return {
151
+ transactions: r.transactions.map(mapTransaction),
152
+ limit: r.limit,
153
+ offset: r.offset
154
+ };
155
+ }
156
+ async getSessions(options) {
157
+ const params = new URLSearchParams();
158
+ if (options?.limit !== void 0) params.set("limit", String(options.limit));
159
+ if (options?.offset !== void 0)
160
+ params.set("offset", String(options.offset));
161
+ if (options?.status) params.set("status", options.status);
162
+ const qs = params.toString();
163
+ const r = await this.request(
164
+ "GET",
165
+ `/v1/account/sessions${qs ? `?${qs}` : ""}`
166
+ );
167
+ return {
168
+ sessions: r.sessions.map(mapSession),
169
+ limit: r.limit,
170
+ offset: r.offset
171
+ };
172
+ }
173
+ // --- Bundled Agent Session ---
174
+ async createAgentSession(options) {
175
+ const r = await this.request("POST", "/v1/agent-session", {
176
+ room_name: options.roomName,
177
+ participant_identity: options.participantIdentity,
178
+ duration_minutes: options.durationMinutes,
179
+ language: options.language,
180
+ tts_max_characters: options.ttsMaxCharacters,
181
+ metadata: options.metadata
182
+ });
183
+ return {
184
+ bundleId: r.bundle_id,
185
+ webrtc: {
186
+ sessionId: r.webrtc.session_id,
187
+ token: r.webrtc.token,
188
+ wsUrl: r.webrtc.ws_url
189
+ },
190
+ stt: {
191
+ sessionId: r.stt.session_id,
192
+ token: r.stt.token,
193
+ serverUrl: r.stt.server_url
194
+ },
195
+ tts: {
196
+ sessionId: r.tts.session_id,
197
+ token: r.tts.token,
198
+ serverUrl: r.tts.server_url
199
+ },
200
+ expiresAt: r.expires_at
201
+ };
202
+ }
203
+ async extendAgentSession(options) {
204
+ const r = await this.request("POST", "/v1/agent-session/extend", {
205
+ bundle_id: options.bundleId,
206
+ additional_minutes: options.additionalMinutes,
207
+ additional_tts_characters: options.additionalTtsCharacters
208
+ });
209
+ const result = {};
210
+ if (r.webrtc) {
211
+ result.webrtc = {
212
+ token: r.webrtc.token,
213
+ newExpiresAt: r.webrtc.new_expires_at
214
+ };
215
+ }
216
+ if (r.stt) {
217
+ result.stt = {
218
+ token: r.stt.token,
219
+ newExpiresAt: r.stt.new_expires_at
220
+ };
221
+ }
222
+ if (r.tts) {
223
+ result.tts = {
224
+ token: r.tts.token,
225
+ newExpiresAt: r.tts.new_expires_at
226
+ };
227
+ }
228
+ return result;
229
+ }
230
+ // --- Standalone WebRTC ---
231
+ async createWebRTCToken(options) {
232
+ const r = await this.request("POST", "/v1/webrtc/token", {
233
+ room_name: options.roomName,
234
+ participant_identity: options.participantIdentity,
235
+ duration_minutes: options.durationMinutes,
236
+ metadata: options.metadata
237
+ });
238
+ return {
239
+ sessionId: r.session_id,
240
+ token: r.token,
241
+ wsUrl: r.ws_url,
242
+ expiresAt: r.expires_at
243
+ };
244
+ }
245
+ async extendWebRTCToken(options) {
246
+ const r = await this.request("POST", "/v1/webrtc/token/extend", {
247
+ session_id: options.sessionId,
248
+ additional_minutes: options.additionalMinutes
249
+ });
250
+ return {
251
+ token: r.token,
252
+ wsUrl: r.ws_url,
253
+ newExpiresAt: r.new_expires_at
254
+ };
255
+ }
256
+ // --- Standalone STT ---
257
+ async createSTTSession(options) {
258
+ const r = await this.request("POST", "/v1/stt/session", {
259
+ duration_minutes: options.durationMinutes,
260
+ language: options.language
261
+ });
262
+ return {
263
+ sessionId: r.session_id,
264
+ token: r.token,
265
+ serverUrl: r.server_url,
266
+ expiresAt: r.expires_at
267
+ };
268
+ }
269
+ async extendSTTSession(options) {
270
+ const r = await this.request("POST", "/v1/stt/session/extend", {
271
+ session_id: options.sessionId,
272
+ additional_minutes: options.additionalMinutes
273
+ });
274
+ return {
275
+ token: r.token,
276
+ newExpiresAt: r.new_expires_at
277
+ };
278
+ }
279
+ // --- Standalone TTS ---
280
+ async createTTSSession(options) {
281
+ const r = await this.request("POST", "/v1/tts/session", {
282
+ max_characters: options.maxCharacters,
283
+ language: options.language
284
+ });
285
+ return {
286
+ sessionId: r.session_id,
287
+ token: r.token,
288
+ serverUrl: r.server_url,
289
+ expiresAt: r.expires_at
290
+ };
291
+ }
292
+ async extendTTSSession(options) {
293
+ const r = await this.request("POST", "/v1/tts/session/extend", {
294
+ session_id: options.sessionId,
295
+ additional_characters: options.additionalCharacters
296
+ });
297
+ return {
298
+ token: r.token,
299
+ maxCharacters: r.max_characters,
300
+ newExpiresAt: r.new_expires_at
301
+ };
302
+ }
303
+ // --- Internal: authenticated request ---
304
+ async request(method, path, body) {
305
+ const headers = await createAuthHeaders(this.account, method, path);
306
+ const init = {
307
+ method,
308
+ headers: {
309
+ ...headers,
310
+ ...body !== void 0 ? { "Content-Type": "application/json" } : {}
311
+ },
312
+ ...body !== void 0 ? { body: JSON.stringify(body) } : {}
313
+ };
314
+ const resp = await fetch(`${this.baseUrl}${path}`, init);
315
+ return this.handleResponse(resp, path);
316
+ }
317
+ // --- Internal: x402 payment request (for buyCredits) ---
318
+ async requestWithPayment(path, body) {
319
+ let resp;
320
+ try {
321
+ resp = await this.fetchWithPayment(`${this.baseUrl}${path}`, {
322
+ method: "POST",
323
+ headers: { "Content-Type": "application/json" },
324
+ body: JSON.stringify(body)
325
+ });
326
+ } catch (err) {
327
+ throw new PaymentError(
328
+ `Payment failed: ${err instanceof Error ? err.message : String(err)}`
329
+ );
330
+ }
331
+ return this.handleResponse(resp, path);
332
+ }
333
+ // --- Internal: response handling ---
334
+ async handleResponse(resp, path) {
335
+ if (resp.ok) {
336
+ return await resp.json();
337
+ }
338
+ const text = await resp.text().catch(() => "");
339
+ let errorMessage;
340
+ try {
341
+ const parsed = JSON.parse(text);
342
+ errorMessage = parsed.error ?? text;
343
+ } catch {
344
+ errorMessage = text || resp.statusText;
345
+ }
346
+ switch (resp.status) {
347
+ case 402:
348
+ throw new InsufficientCreditsError(errorMessage);
349
+ case 429: {
350
+ if (errorMessage.toLowerCase().includes("concurrent")) {
351
+ throw new ConcurrencyLimitError(errorMessage);
352
+ }
353
+ throw new RateLimitError(errorMessage);
354
+ }
355
+ case 503: {
356
+ const service = path.split("/")[2] ?? "unknown";
357
+ throw new NoCapacityError(errorMessage, service);
358
+ }
359
+ default:
360
+ throw new GatewayError(errorMessage, resp.status);
361
+ }
362
+ }
363
+ };
364
+ function mapTransaction(r) {
365
+ return {
366
+ id: r.id,
367
+ amount: r.amount,
368
+ balanceAfter: r.balance_after,
369
+ type: r.type,
370
+ referenceId: r.reference_id,
371
+ service: r.service,
372
+ description: r.description,
373
+ createdAt: r.created_at
374
+ };
375
+ }
376
+ function mapSession(r) {
377
+ return {
378
+ id: r.id,
379
+ service: r.service,
380
+ bundleId: r.bundle_id,
381
+ status: r.status,
382
+ roomName: r.room_name,
383
+ serverUrl: r.server_url,
384
+ reservedMicrocredits: r.reserved_microcredits,
385
+ chargedMicrocredits: r.charged_microcredits,
386
+ tokenExpiresAt: r.token_expires_at,
387
+ startedAt: r.started_at,
388
+ endedAt: r.ended_at,
389
+ settlementMethod: r.settlement_method,
390
+ createdAt: r.created_at
391
+ };
392
+ }
393
+ // Annotate the CommonJS export names for ESM import in node:
394
+ 0 && (module.exports = {
395
+ ConcurrencyLimitError,
396
+ DtelecomGateway,
397
+ GatewayError,
398
+ InsufficientCreditsError,
399
+ NoCapacityError,
400
+ PaymentError,
401
+ RateLimitError,
402
+ createAuthHeaders
403
+ });