@conto_finance/sdk 0.6.1 → 0.7.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.
@@ -0,0 +1,365 @@
1
+ import "./chunk-TGOYFBKZ.mjs";
2
+
3
+ // src/link-wallet.ts
4
+ import { spawn } from "child_process";
5
+ import { constants } from "fs";
6
+ import { chmod, mkdtemp, open, rm } from "fs/promises";
7
+ import { tmpdir } from "os";
8
+ import path from "path";
9
+ var LinkWalletError = class extends Error {
10
+ constructor(reason, message, linkCode) {
11
+ super(message);
12
+ this.name = "LinkWalletError";
13
+ this.reason = reason;
14
+ this.code = reason === "not_installed" || reason === "not_logged_in" ? "LINK_WALLET_UNAVAILABLE" : "LINK_WALLET_FAILED";
15
+ if (linkCode) this.linkCode = linkCode;
16
+ }
17
+ };
18
+ var LINK_REQUEST_ID = /^lsrq_[A-Za-z0-9]{1,64}$/;
19
+ var SAFE_LINK_CODE = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;
20
+ var KNOWN_STATUSES = /* @__PURE__ */ new Set([
21
+ "created",
22
+ "pending_approval",
23
+ "requires_action",
24
+ "approved",
25
+ "submitted",
26
+ "succeeded",
27
+ "denied",
28
+ "expired",
29
+ "canceled",
30
+ "failed"
31
+ ]);
32
+ var MAX_OUTPUT_BYTES = 1024 * 1024;
33
+ var COMMAND_TIMEOUT_MS = 6e4;
34
+ function record(value) {
35
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
36
+ }
37
+ function text(value) {
38
+ return typeof value === "string" && value.length > 0 ? value : void 0;
39
+ }
40
+ function httpsUrl(value) {
41
+ if (typeof value !== "string" || value.length > 2048) return void 0;
42
+ try {
43
+ return new URL(value).protocol === "https:" ? value : void 0;
44
+ } catch {
45
+ return void 0;
46
+ }
47
+ }
48
+ function isLinkRequestId(value) {
49
+ return typeof value === "string" && LINK_REQUEST_ID.test(value);
50
+ }
51
+ function requireRequestId(id) {
52
+ if (!isLinkRequestId(id)) {
53
+ throw new LinkWalletError("invalid_input", "The Link request id is not valid.");
54
+ }
55
+ return id;
56
+ }
57
+ function flagText(value, maxLength) {
58
+ const cleaned = value.replace(/[\r\n\t,]+/g, " ").replace(/\s+/g, " ").trim().slice(0, maxLength).trim();
59
+ return cleaned || "Item";
60
+ }
61
+ function parseSpendRequest(value) {
62
+ const latest = Array.isArray(value) ? value[value.length - 1] : value;
63
+ const data = record(latest);
64
+ const id = data.id;
65
+ if (!isLinkRequestId(id)) {
66
+ throw new LinkWalletError("invalid_response", "link-cli returned an unexpected response.");
67
+ }
68
+ const status = typeof data.status === "string" && KNOWN_STATUSES.has(data.status) ? data.status : "unknown";
69
+ const nextAction = record(record(record(data.status_details).requires_action).next_action);
70
+ const amount = data.amount;
71
+ return {
72
+ id,
73
+ status,
74
+ ...Number.isSafeInteger(amount) ? { amountMinor: amount } : {},
75
+ ...text(data.merchant_name) ? { merchantName: text(data.merchant_name) } : {},
76
+ ...httpsUrl(data.merchant_url) ? { merchantUrl: httpsUrl(data.merchant_url) } : {},
77
+ ...httpsUrl(data.approval_url) ? { approvalUrl: httpsUrl(data.approval_url) } : {},
78
+ ...text(nextAction.resolution) ? { actionResolution: text(nextAction.resolution) } : {},
79
+ ...httpsUrl(nextAction.action_url) ? { actionUrl: httpsUrl(nextAction.action_url) } : {}
80
+ };
81
+ }
82
+ function invalidCard() {
83
+ return new LinkWalletError("invalid_response", "Link returned card data this SDK cannot read.");
84
+ }
85
+ function validUntil(value) {
86
+ if (typeof value === "number" && Number.isFinite(value) && value > 0) {
87
+ return new Date(value < 1e12 ? value * 1e3 : value).toISOString();
88
+ }
89
+ if (typeof value === "string" && !Number.isNaN(Date.parse(value))) {
90
+ return new Date(value).toISOString();
91
+ }
92
+ return void 0;
93
+ }
94
+ function parseCard(value) {
95
+ const card = record(value);
96
+ const number = typeof card.number === "string" ? card.number.replace(/[\s-]/g, "") : "";
97
+ const rawSecurityValue = card["cvc"];
98
+ const securityValue = typeof rawSecurityValue === "string" ? rawSecurityValue.trim() : "";
99
+ const expMonth = Number(card.exp_month);
100
+ let expYear = Number(card.exp_year);
101
+ if (Number.isInteger(expYear) && expYear >= 0 && expYear < 100) expYear += 2e3;
102
+ if (!/^\d{12,19}$/.test(number) || !/^\d{3,4}$/.test(securityValue) || !Number.isInteger(expMonth) || expMonth < 1 || expMonth > 12 || !Number.isInteger(expYear) || expYear < 2e3) {
103
+ throw invalidCard();
104
+ }
105
+ const until = validUntil(card.valid_until);
106
+ const brand = text(card.brand);
107
+ return {
108
+ number,
109
+ securityValue,
110
+ expMonth,
111
+ expYear,
112
+ ...until ? { validUntil: until } : {},
113
+ last4: number.slice(-4),
114
+ ...brand ? { brand } : {}
115
+ };
116
+ }
117
+ function failureFromOutput(value) {
118
+ const data = record(value);
119
+ const code = typeof data.code === "string" && SAFE_LINK_CODE.test(data.code) ? data.code : void 0;
120
+ const message = typeof data.message === "string" ? data.message.toLowerCase() : "";
121
+ if (code === "NOT_AUTHENTICATED" || message.includes("auth login") || message.includes("not authenticated")) {
122
+ return new LinkWalletError(
123
+ "not_logged_in",
124
+ 'link-cli is not logged in. Run "link-cli auth login" on this machine.',
125
+ code
126
+ );
127
+ }
128
+ if (code === "NOT_FOUND") {
129
+ return new LinkWalletError("not_found", "Link has no spend request with this id.", code);
130
+ }
131
+ if (code === "POLLING_TIMEOUT") {
132
+ return new LinkWalletError("timed_out", "The person has not decided in Link yet.", code);
133
+ }
134
+ return new LinkWalletError("cli_failed", "link-cli could not complete the request.", code);
135
+ }
136
+ function linkCliWallet(options = {}) {
137
+ const binary = options.binary ?? "link-cli";
138
+ const defaultTimeoutSeconds = options.timeoutSeconds ?? 300;
139
+ if (!Number.isFinite(defaultTimeoutSeconds) || defaultTimeoutSeconds < 0) {
140
+ throw new LinkWalletError("invalid_input", "timeoutSeconds must be zero or more.");
141
+ }
142
+ if (options.paymentMethodId !== void 0 && !/^[A-Za-z0-9_]{1,128}$/.test(options.paymentMethodId)) {
143
+ throw new LinkWalletError(
144
+ "invalid_input",
145
+ "paymentMethodId is not a valid Link payment method id."
146
+ );
147
+ }
148
+ const env = {
149
+ ...options.env ?? process.env,
150
+ NO_UPDATE_NOTIFIER: "1",
151
+ NO_COLOR: "1"
152
+ };
153
+ function run(args, call = {}) {
154
+ return new Promise((resolve, reject) => {
155
+ if (call.signal?.aborted) {
156
+ reject(new LinkWalletError("aborted", "The Link request was stopped."));
157
+ return;
158
+ }
159
+ let child;
160
+ try {
161
+ child = spawn(binary, [...args, "--format", "json"], {
162
+ env,
163
+ shell: false,
164
+ stdio: ["ignore", "pipe", "pipe"],
165
+ windowsHide: true,
166
+ ...call.signal ? { signal: call.signal } : {}
167
+ });
168
+ } catch {
169
+ reject(new LinkWalletError("cli_failed", "link-cli could not be started."));
170
+ return;
171
+ }
172
+ const chunks = [];
173
+ let size = 0;
174
+ let overflow = false;
175
+ let timedOut = false;
176
+ const timer = setTimeout(() => {
177
+ timedOut = true;
178
+ child.kill("SIGTERM");
179
+ }, call.timeoutMs ?? COMMAND_TIMEOUT_MS);
180
+ child.stdout?.on("data", (chunk) => {
181
+ size += chunk.length;
182
+ if (size > MAX_OUTPUT_BYTES) {
183
+ overflow = true;
184
+ child.kill("SIGTERM");
185
+ return;
186
+ }
187
+ chunks.push(chunk);
188
+ });
189
+ child.stderr?.resume();
190
+ child.on("error", (error) => {
191
+ clearTimeout(timer);
192
+ if (error.code === "ENOENT") {
193
+ reject(
194
+ new LinkWalletError(
195
+ "not_installed",
196
+ 'link-cli is not installed. Run "npm i -g @stripe/link-cli", then "link-cli auth login".'
197
+ )
198
+ );
199
+ } else if (error.name === "AbortError") {
200
+ reject(new LinkWalletError("aborted", "The Link request was stopped."));
201
+ } else {
202
+ reject(new LinkWalletError("cli_failed", "link-cli could not be started."));
203
+ }
204
+ });
205
+ child.on("close", (exitCode) => {
206
+ clearTimeout(timer);
207
+ if (call.signal?.aborted) {
208
+ reject(new LinkWalletError("aborted", "The Link request was stopped."));
209
+ return;
210
+ }
211
+ if (timedOut) {
212
+ reject(new LinkWalletError("cli_failed", "link-cli did not finish in time."));
213
+ return;
214
+ }
215
+ if (overflow) {
216
+ reject(
217
+ new LinkWalletError("invalid_response", "link-cli returned an unexpected response.")
218
+ );
219
+ return;
220
+ }
221
+ let value;
222
+ try {
223
+ value = JSON.parse(Buffer.concat(chunks).toString("utf8"));
224
+ } catch {
225
+ reject(
226
+ exitCode === 0 ? new LinkWalletError("invalid_response", "link-cli returned an unexpected response.") : new LinkWalletError("cli_failed", "link-cli could not complete the request.")
227
+ );
228
+ return;
229
+ }
230
+ resolve({ exitCode, value });
231
+ });
232
+ });
233
+ }
234
+ async function runOrThrow(args, call) {
235
+ const result = await run(args, call);
236
+ if (result.exitCode !== 0) throw failureFromOutput(result.value);
237
+ return result.value;
238
+ }
239
+ async function readOnce(id, call) {
240
+ return parseSpendRequest(await runOrThrow(["spend-request", "retrieve", id], call));
241
+ }
242
+ return {
243
+ async createCardRequest(input, call) {
244
+ if (!Number.isSafeInteger(input.amountMinor) || input.amountMinor <= 0) {
245
+ throw new LinkWalletError(
246
+ "invalid_input",
247
+ "amountMinor must be a positive number of cents."
248
+ );
249
+ }
250
+ if (input.currency !== "USD") {
251
+ throw new LinkWalletError("invalid_input", "Only USD card requests are supported.");
252
+ }
253
+ if (typeof input.context !== "string" || input.context.length < 100) {
254
+ throw new LinkWalletError("invalid_input", "context must contain at least 100 characters.");
255
+ }
256
+ if (!/^[A-Za-z0-9_:.-]{8,255}$/.test(input.idempotencyKey)) {
257
+ throw new LinkWalletError("invalid_input", "idempotencyKey is not valid.");
258
+ }
259
+ if (!httpsUrl(input.merchantUrl)) {
260
+ throw new LinkWalletError("invalid_input", "merchantUrl must be an HTTPS URL.");
261
+ }
262
+ const args = [
263
+ "spend-request",
264
+ "create",
265
+ `--amount=${input.amountMinor}`,
266
+ "--currency=usd",
267
+ `--merchant-name=${input.merchantName}`,
268
+ `--merchant-url=${input.merchantUrl}`,
269
+ `--context=${input.context}`,
270
+ `--idempotency-key=${input.idempotencyKey}`,
271
+ ...input.lineItems.map(
272
+ (item) => `--line-item=name:${flagText(item.name, 200)},unit_amount:${item.unitAmountMinor},quantity:${item.quantity}`
273
+ ),
274
+ ...input.totals.map(
275
+ (total) => `--total=type:${total.type},display_text:${flagText(total.label, 120)},amount:${total.amountMinor}`
276
+ ),
277
+ ...Object.entries(input.metadata ?? {}).map(
278
+ ([key, value]) => `--metadata=${flagText(key, 40)}:${flagText(value, 500)}`
279
+ ),
280
+ ...options.paymentMethodId ? [`--payment-method-id=${options.paymentMethodId}`] : [],
281
+ ...options.test ? ["--test"] : []
282
+ ];
283
+ const result = await run(args, call);
284
+ if (result.exitCode !== 0) {
285
+ const message = record(result.value).message;
286
+ const existing = typeof message === "string" ? /matching spend request already exists: (lsrq_[A-Za-z0-9]{1,64})/.exec(message)?.[1] : void 0;
287
+ if (existing) {
288
+ const current = await readOnce(existing, call);
289
+ if (current.amountMinor === input.amountMinor && (current.merchantUrl === void 0 || new URL(current.merchantUrl).origin === new URL(input.merchantUrl).origin)) {
290
+ return current;
291
+ }
292
+ }
293
+ throw failureFromOutput(result.value);
294
+ }
295
+ return parseSpendRequest(result.value);
296
+ },
297
+ async waitForApproval(id, call = {}) {
298
+ requireRequestId(id);
299
+ const timeoutSeconds = Math.max(0, Math.floor(call.timeoutSeconds ?? defaultTimeoutSeconds));
300
+ if (timeoutSeconds === 0) return readOnce(id, call);
301
+ const result = await run(
302
+ ["spend-request", "retrieve", id, "--interval=2", `--timeout=${timeoutSeconds}`],
303
+ { signal: call.signal, timeoutMs: (timeoutSeconds + 30) * 1e3 }
304
+ );
305
+ if (result.exitCode === 0) return parseSpendRequest(result.value);
306
+ const failure = failureFromOutput(result.value);
307
+ if (failure.reason === "timed_out") return readOnce(id, call);
308
+ throw failure;
309
+ },
310
+ async retrieveCard(id, call) {
311
+ requireRequestId(id);
312
+ const directory = await mkdtemp(path.join(tmpdir(), "conto-link-"));
313
+ try {
314
+ await chmod(directory, 448);
315
+ const file = path.join(directory, "card.json");
316
+ const request = parseSpendRequest(
317
+ await runOrThrow(
318
+ ["spend-request", "retrieve", id, "--include=card", `--output-file=${file}`],
319
+ call
320
+ )
321
+ );
322
+ if (!["approved", "submitted", "succeeded"].includes(request.status)) {
323
+ throw new LinkWalletError(
324
+ "not_approved",
325
+ "The person has not approved this request in Link."
326
+ );
327
+ }
328
+ const handle = await open(
329
+ file,
330
+ constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0)
331
+ ).catch((error) => {
332
+ if (error.code === "ENOENT") return void 0;
333
+ throw new LinkWalletError("invalid_response", "The card file was not private.");
334
+ });
335
+ if (!handle) throw new LinkWalletError("invalid_response", "Link did not return a card.");
336
+ try {
337
+ const stats = await handle.stat();
338
+ if (!stats.isFile() || (stats.mode & 63) !== 0) {
339
+ throw new LinkWalletError("invalid_response", "The card file was not private.");
340
+ }
341
+ let contents;
342
+ try {
343
+ contents = JSON.parse(await handle.readFile("utf8"));
344
+ } catch {
345
+ throw invalidCard();
346
+ }
347
+ return parseCard(record(contents).card);
348
+ } finally {
349
+ await handle.close();
350
+ }
351
+ } finally {
352
+ await rm(directory, { recursive: true, force: true });
353
+ }
354
+ },
355
+ async cancel(id, call) {
356
+ requireRequestId(id);
357
+ await runOrThrow(["spend-request", "cancel", id], call);
358
+ }
359
+ };
360
+ }
361
+ export {
362
+ LinkWalletError,
363
+ isLinkRequestId,
364
+ linkCliWallet
365
+ };
@@ -1,5 +1,6 @@
1
1
  import { Browser, Page } from 'playwright-core';
2
2
  import { GuardedCheckoutInput, PrivilegedBrowserCheckoutDriver, RunGuardedCheckoutResult, AgentCheckoutActionKind, CommerceCheckoutMethod, BrowserCheckoutAction } from './index.mjs';
3
+ import './link-wallet.mjs';
3
4
 
4
5
  interface PlaywrightCheckoutTargetRegistration {
5
6
  browserSessionId: string;
@@ -255,4 +256,5 @@ declare function createGuardedPlaywrightCheckoutRuntimeHost(config: GuardedPlayw
255
256
  */
256
257
  declare function createGuardedPlaywrightCheckoutHttpHandler(config: GuardedPlaywrightCheckoutHttpHandlerConfig): GuardedPlaywrightCheckoutHttpHandler;
257
258
 
258
- export { type DiscoverPlaywrightCheckoutTargetInput, type DiscoveredPlaywrightCheckoutTarget, type EncryptedPlaywrightCheckoutTargetStoreConfig, type GuardedPlaywrightCheckoutClient, type GuardedPlaywrightCheckoutHttpHandler, type GuardedPlaywrightCheckoutHttpHandlerConfig, type GuardedPlaywrightCheckoutHttpRequest, type GuardedPlaywrightCheckoutRuntime, type GuardedPlaywrightCheckoutRuntimeConfig, type GuardedPlaywrightCheckoutRuntimeHost, type GuardedPlaywrightCheckoutRuntimeHostConfig, type PlaywrightCdpSessionRegistry, type PlaywrightCdpSessionRegistryConfig, type PlaywrightCheckoutAdapter, type PlaywrightCheckoutAdapterConfig, type PlaywrightCheckoutDispatchResult, type PlaywrightCheckoutTargetBlobStore, type PlaywrightCheckoutTargetRegistration, type PlaywrightCheckoutTargetStore, type PlaywrightSessionInteractiveTarget, type PlaywrightSessionObservation, type PlaywrightSessionObserver, type PlaywrightSessionObserverConfig, createEncryptedPlaywrightCheckoutTargetStore, createGuardedPlaywrightCheckoutHttpHandler, createGuardedPlaywrightCheckoutRuntime, createGuardedPlaywrightCheckoutRuntimeHost, createInMemoryPlaywrightCheckoutTargetStore, createPlaywrightCdpSessionRegistry, createPlaywrightCheckoutAdapter, createPlaywrightSessionObserver };
259
+ export { createEncryptedPlaywrightCheckoutTargetStore, createGuardedPlaywrightCheckoutHttpHandler, createGuardedPlaywrightCheckoutRuntime, createGuardedPlaywrightCheckoutRuntimeHost, createInMemoryPlaywrightCheckoutTargetStore, createPlaywrightCdpSessionRegistry, createPlaywrightCheckoutAdapter, createPlaywrightSessionObserver };
260
+ export type { DiscoverPlaywrightCheckoutTargetInput, DiscoveredPlaywrightCheckoutTarget, EncryptedPlaywrightCheckoutTargetStoreConfig, GuardedPlaywrightCheckoutClient, GuardedPlaywrightCheckoutHttpHandler, GuardedPlaywrightCheckoutHttpHandlerConfig, GuardedPlaywrightCheckoutHttpRequest, GuardedPlaywrightCheckoutRuntime, GuardedPlaywrightCheckoutRuntimeConfig, GuardedPlaywrightCheckoutRuntimeHost, GuardedPlaywrightCheckoutRuntimeHostConfig, PlaywrightCdpSessionRegistry, PlaywrightCdpSessionRegistryConfig, PlaywrightCheckoutAdapter, PlaywrightCheckoutAdapterConfig, PlaywrightCheckoutDispatchResult, PlaywrightCheckoutTargetBlobStore, PlaywrightCheckoutTargetRegistration, PlaywrightCheckoutTargetStore, PlaywrightSessionInteractiveTarget, PlaywrightSessionObservation, PlaywrightSessionObserver, PlaywrightSessionObserverConfig };
@@ -1,5 +1,6 @@
1
1
  import { Browser, Page } from 'playwright-core';
2
2
  import { GuardedCheckoutInput, PrivilegedBrowserCheckoutDriver, RunGuardedCheckoutResult, AgentCheckoutActionKind, CommerceCheckoutMethod, BrowserCheckoutAction } from './index.js';
3
+ import './link-wallet.js';
3
4
 
4
5
  interface PlaywrightCheckoutTargetRegistration {
5
6
  browserSessionId: string;
@@ -255,4 +256,5 @@ declare function createGuardedPlaywrightCheckoutRuntimeHost(config: GuardedPlayw
255
256
  */
256
257
  declare function createGuardedPlaywrightCheckoutHttpHandler(config: GuardedPlaywrightCheckoutHttpHandlerConfig): GuardedPlaywrightCheckoutHttpHandler;
257
258
 
258
- export { type DiscoverPlaywrightCheckoutTargetInput, type DiscoveredPlaywrightCheckoutTarget, type EncryptedPlaywrightCheckoutTargetStoreConfig, type GuardedPlaywrightCheckoutClient, type GuardedPlaywrightCheckoutHttpHandler, type GuardedPlaywrightCheckoutHttpHandlerConfig, type GuardedPlaywrightCheckoutHttpRequest, type GuardedPlaywrightCheckoutRuntime, type GuardedPlaywrightCheckoutRuntimeConfig, type GuardedPlaywrightCheckoutRuntimeHost, type GuardedPlaywrightCheckoutRuntimeHostConfig, type PlaywrightCdpSessionRegistry, type PlaywrightCdpSessionRegistryConfig, type PlaywrightCheckoutAdapter, type PlaywrightCheckoutAdapterConfig, type PlaywrightCheckoutDispatchResult, type PlaywrightCheckoutTargetBlobStore, type PlaywrightCheckoutTargetRegistration, type PlaywrightCheckoutTargetStore, type PlaywrightSessionInteractiveTarget, type PlaywrightSessionObservation, type PlaywrightSessionObserver, type PlaywrightSessionObserverConfig, createEncryptedPlaywrightCheckoutTargetStore, createGuardedPlaywrightCheckoutHttpHandler, createGuardedPlaywrightCheckoutRuntime, createGuardedPlaywrightCheckoutRuntimeHost, createInMemoryPlaywrightCheckoutTargetStore, createPlaywrightCdpSessionRegistry, createPlaywrightCheckoutAdapter, createPlaywrightSessionObserver };
259
+ export { createEncryptedPlaywrightCheckoutTargetStore, createGuardedPlaywrightCheckoutHttpHandler, createGuardedPlaywrightCheckoutRuntime, createGuardedPlaywrightCheckoutRuntimeHost, createInMemoryPlaywrightCheckoutTargetStore, createPlaywrightCdpSessionRegistry, createPlaywrightCheckoutAdapter, createPlaywrightSessionObserver };
260
+ export type { DiscoverPlaywrightCheckoutTargetInput, DiscoveredPlaywrightCheckoutTarget, EncryptedPlaywrightCheckoutTargetStoreConfig, GuardedPlaywrightCheckoutClient, GuardedPlaywrightCheckoutHttpHandler, GuardedPlaywrightCheckoutHttpHandlerConfig, GuardedPlaywrightCheckoutHttpRequest, GuardedPlaywrightCheckoutRuntime, GuardedPlaywrightCheckoutRuntimeConfig, GuardedPlaywrightCheckoutRuntimeHost, GuardedPlaywrightCheckoutRuntimeHostConfig, PlaywrightCdpSessionRegistry, PlaywrightCdpSessionRegistryConfig, PlaywrightCheckoutAdapter, PlaywrightCheckoutAdapterConfig, PlaywrightCheckoutDispatchResult, PlaywrightCheckoutTargetBlobStore, PlaywrightCheckoutTargetRegistration, PlaywrightCheckoutTargetStore, PlaywrightSessionInteractiveTarget, PlaywrightSessionObservation, PlaywrightSessionObserver, PlaywrightSessionObserverConfig };
@@ -322,13 +322,16 @@ function createEncryptedPlaywrightCheckoutTargetStore(config) {
322
322
  if (envelope.version !== TARGET_STORE_ENVELOPE_VERSION || typeof envelope.iv !== "string" || typeof envelope.ciphertext !== "string" || typeof envelope.tag !== "string") {
323
323
  throw new Error("invalid envelope");
324
324
  }
325
+ const tag = Buffer.from(envelope.tag, "base64url");
326
+ if (tag.length !== 16) throw new Error("invalid envelope");
325
327
  const decipher = (0, import_node_crypto2.createDecipheriv)(
326
328
  "aes-256-gcm",
327
329
  key,
328
- Buffer.from(envelope.iv, "base64url")
330
+ Buffer.from(envelope.iv, "base64url"),
331
+ { authTagLength: 16 }
329
332
  );
330
333
  decipher.setAAD(Buffer.from(storageKey));
331
- decipher.setAuthTag(Buffer.from(envelope.tag, "base64url"));
334
+ decipher.setAuthTag(tag);
332
335
  const plaintext = Buffer.concat([
333
336
  decipher.update(Buffer.from(envelope.ciphertext, "base64url")),
334
337
  decipher.final()
@@ -7,9 +7,9 @@ import {
7
7
  createPlaywrightCdpSessionRegistry,
8
8
  createPlaywrightCheckoutAdapter,
9
9
  createPlaywrightSessionObserver
10
- } from "./chunk-VSIO6PYA.mjs";
10
+ } from "./chunk-JBTJXIMI.mjs";
11
11
  import "./chunk-O5RAAB2U.mjs";
12
- import "./chunk-WSIKPUZJ.mjs";
12
+ import "./chunk-TGOYFBKZ.mjs";
13
13
  export {
14
14
  createEncryptedPlaywrightCheckoutTargetStore,
15
15
  createGuardedPlaywrightCheckoutHttpHandler,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@conto_finance/sdk",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "description": "Conto SDK for AI agent payment authorization",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -25,6 +25,11 @@
25
25
  "types": "./dist/checkout-verifier.d.ts",
26
26
  "import": "./dist/checkout-verifier.mjs",
27
27
  "require": "./dist/checkout-verifier.js"
28
+ },
29
+ "./link-wallet": {
30
+ "types": "./dist/link-wallet.d.ts",
31
+ "import": "./dist/link-wallet.mjs",
32
+ "require": "./dist/link-wallet.js"
28
33
  }
29
34
  },
30
35
  "publishConfig": {
@@ -41,7 +46,7 @@
41
46
  "dev": "tsup --watch",
42
47
  "lint": "tsc --noEmit",
43
48
  "test": "npm run lint && npm run test:contract && npm run test:consumer",
44
- "test:contract": "npm run build && node --test test/contract.test.mjs test/playwright.test.mjs test/browserbase.test.mjs test/checkout-verifier.test.mjs test/developer-experience.test.mjs test/checkout.test.mjs test/purchases.test.mjs",
49
+ "test:contract": "npm run build && node --test test/contract.test.mjs test/playwright.test.mjs test/browserbase.test.mjs test/checkout-verifier.test.mjs test/developer-experience.test.mjs test/checkout.test.mjs test/link-wallet.test.mjs test/purchases.test.mjs test/allowances.test.mjs test/purchase-watch-lifecycle.test.mjs ../../examples/link-wallet-agent/verify.test.mjs",
45
50
  "test:consumer": "npm run build && node --test test/consumer.test.mjs",
46
51
  "verify:release": "node scripts/verify-release.mjs",
47
52
  "prepublishOnly": "npm run verify:release && npm run lint && npm run test:contract && npm run test:consumer"
@@ -66,7 +71,7 @@
66
71
  "email": "support@conto.finance"
67
72
  },
68
73
  "dependencies": {
69
- "@sentry/node": "^10.63.0"
74
+ "@sentry/node": "^11.8.0"
70
75
  },
71
76
  "peerDependencies": {
72
77
  "playwright-core": ">=1.50.0"
@@ -80,9 +85,9 @@
80
85
  "esbuild": "0.28.1"
81
86
  },
82
87
  "devDependencies": {
83
- "@types/node": "22.19.18",
88
+ "@types/node": "26.6.5",
84
89
  "playwright-core": "1.61.0",
85
- "tsup": "^8.5.1",
86
- "typescript": "^5.9.3"
90
+ "tsup": "^9.0.0",
91
+ "typescript": "^6.0.3"
87
92
  }
88
93
  }