@stripe/link-sdk 0.6.0 → 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.
package/dist/index.js CHANGED
@@ -521,7 +521,8 @@ var BaseResource = class {
521
521
  method: opts.method,
522
522
  ...opts.headers !== void 0 && { headers: opts.headers },
523
523
  ...opts.body !== void 0 && { body: opts.body },
524
- ...opts.signal !== void 0 && { signal: opts.signal }
524
+ ...opts.signal !== void 0 && { signal: opts.signal },
525
+ ...opts.redirect !== void 0 && { redirect: opts.redirect }
525
526
  };
526
527
  response = await this.fetchImpl(opts.url, init);
527
528
  } catch (error) {
@@ -553,8 +554,13 @@ var BaseResource = class {
553
554
  const res = await this.rawFetch(authedOpts);
554
555
  if (res.status === 401 && this.canRefreshAccessToken) {
555
556
  const refreshedToken = await this.getAccessToken({ forceRefresh: true });
556
- authedOpts.headers.Authorization = `Bearer ${refreshedToken}`;
557
- return this.rawFetch(authedOpts);
557
+ return this.rawFetch({
558
+ ...opts,
559
+ headers: {
560
+ ...opts.headers,
561
+ Authorization: `Bearer ${refreshedToken}`
562
+ }
563
+ });
558
564
  }
559
565
  return res;
560
566
  }
@@ -959,17 +965,143 @@ var BalancesResource = class extends BaseResource {
959
965
  }
960
966
  };
961
967
 
962
- // src/resources/payment-methods.ts
968
+ // src/resources/identity-credentials.ts
963
969
  import { z as z3 } from "zod";
964
- var paymentMethodSchema = z3.looseObject({
965
- id: z3.string(),
966
- type: z3.string(),
967
- is_default: z3.boolean(),
968
- name: z3.string(),
969
- nickname: z3.optional(z3.string().nullable())
970
+
971
+ // src/resources/holder-jwk.ts
972
+ import { createHash as createHash3 } from "crypto";
973
+ function isRecord2(value) {
974
+ return typeof value === "object" && value !== null && !Array.isArray(value);
975
+ }
976
+ function holderJwkThumbprint(jwk) {
977
+ const canonical = JSON.stringify({
978
+ crv: jwk.crv,
979
+ kty: jwk.kty,
980
+ x: jwk.x
981
+ });
982
+ return createHash3("sha256").update(canonical).digest("base64url");
983
+ }
984
+ function holderJwksEqual(left, right) {
985
+ return holderJwkThumbprint(left) === holderJwkThumbprint(right);
986
+ }
987
+ function parseHolderPublicJwk(value) {
988
+ if (!isRecord2(value)) {
989
+ throw new LinkConfigurationError("Holder public key must be a JWK object");
990
+ }
991
+ if (typeof value.kty !== "string") {
992
+ throw new LinkConfigurationError("Holder public key is missing kty");
993
+ }
994
+ if (value.kty !== "OKP" || value.crv !== "Ed25519" || typeof value.x !== "string" || value.x.length === 0) {
995
+ throw new LinkConfigurationError(
996
+ "Holder public key must be an Ed25519 OKP JWK with an x member"
997
+ );
998
+ }
999
+ return { kty: "OKP", crv: "Ed25519", x: value.x };
1000
+ }
1001
+
1002
+ // src/resources/identity-credentials.ts
1003
+ var LINK_ISSUER2 = "https://api.link.com";
1004
+ var LINK_ISSUER_METADATA_URL2 = `${LINK_ISSUER2}/.well-known/aap-issuer`;
1005
+ var identityCredentialIssuerMetadataSchema = z3.looseObject({
1006
+ issuer: z3.literal(LINK_ISSUER2),
1007
+ credential_endpoint: z3.string()
1008
+ });
1009
+ var issueIdentityCredentialResponseSchema = z3.looseObject({
1010
+ credential: z3.string(),
1011
+ issuer: z3.literal(LINK_ISSUER2),
1012
+ expires_at: z3.string()
1013
+ });
1014
+ function requireLinkEndpoint2(value, field) {
1015
+ let url;
1016
+ try {
1017
+ url = new URL(value);
1018
+ } catch (error) {
1019
+ throw new TypeError(`${field} is not a valid URL`, { cause: error });
1020
+ }
1021
+ if (url.protocol !== "https:" || url.origin !== LINK_ISSUER2 || url.username || url.password) {
1022
+ throw new TypeError(`${field} must be an HTTPS URL on ${LINK_ISSUER2}`);
1023
+ }
1024
+ return url.href;
1025
+ }
1026
+ var IdentityCredentialsResource = class extends BaseResource {
1027
+ constructor(options) {
1028
+ super(options, "");
1029
+ }
1030
+ async discoverCredentialEndpoint() {
1031
+ const { status, data, rawBody } = await this.rawFetch({
1032
+ method: "GET",
1033
+ url: LINK_ISSUER_METADATA_URL2,
1034
+ redirect: "manual"
1035
+ });
1036
+ if (status >= 300 && status < 400) {
1037
+ throw new LinkApiError(
1038
+ `Refused redirect while fetching identity credential issuer metadata (${status})`,
1039
+ { status, rawBody }
1040
+ );
1041
+ }
1042
+ if (status < 200 || status >= 300) {
1043
+ this.throwApiError(
1044
+ "fetch identity credential issuer metadata",
1045
+ status,
1046
+ data,
1047
+ rawBody
1048
+ );
1049
+ }
1050
+ const metadata = this.parseResponse(
1051
+ "parse identity credential issuer metadata",
1052
+ status,
1053
+ () => identityCredentialIssuerMetadataSchema.parse(data)
1054
+ );
1055
+ return this.parseResponse(
1056
+ "validate identity credential issuer metadata",
1057
+ status,
1058
+ () => requireLinkEndpoint2(
1059
+ metadata.credential_endpoint,
1060
+ "credential_endpoint"
1061
+ )
1062
+ );
1063
+ }
1064
+ async issue(params) {
1065
+ const publicJwk = parseHolderPublicJwk(params.cnf.jwk);
1066
+ const endpoint = await this.discoverCredentialEndpoint();
1067
+ const { status, data, rawBody } = await this.apiFetch({
1068
+ method: "POST",
1069
+ url: endpoint,
1070
+ redirect: "manual",
1071
+ headers: {
1072
+ "Content-Type": "application/json",
1073
+ Accept: "application/json"
1074
+ },
1075
+ body: JSON.stringify({ cnf: { jwk: publicJwk } })
1076
+ });
1077
+ if (status >= 300 && status < 400) {
1078
+ throw new LinkApiError(
1079
+ `Refused redirect while issuing identity credential (${status})`,
1080
+ { status, rawBody }
1081
+ );
1082
+ }
1083
+ if (status < 200 || status >= 300) {
1084
+ this.throwApiError("issue identity credential", status, data, rawBody);
1085
+ }
1086
+ return this.parseResponse(
1087
+ "issue identity credential",
1088
+ status,
1089
+ () => issueIdentityCredentialResponseSchema.parse(data)
1090
+ );
1091
+ }
1092
+ };
1093
+
1094
+ // src/resources/payment-methods.ts
1095
+ import { z as z4 } from "zod";
1096
+ var paymentMethodSchema = z4.looseObject({
1097
+ id: z4.string(),
1098
+ type: z4.string(),
1099
+ is_default: z4.boolean(),
1100
+ name: z4.string(),
1101
+ nickname: z4.optional(z4.string().nullable())
970
1102
  });
971
- var paymentMethodsResponseSchema = z3.looseObject({
972
- payment_details: z3.array(paymentMethodSchema)
1103
+ var paymentMethodsResponseSchema = z4.looseObject({
1104
+ payment_details: z4.array(paymentMethodSchema)
973
1105
  });
974
1106
  var PaymentMethodsResource = class extends BaseResource {
975
1107
  constructor(options) {
@@ -992,14 +1124,14 @@ var PaymentMethodsResource = class extends BaseResource {
992
1124
  };
993
1125
 
994
1126
  // src/resources/report.ts
995
- import { z as z4 } from "zod";
996
- var reportRecordSchema = z4.looseObject({
997
- object: z4.string(),
998
- created_at: z4.string(),
999
- domain: z4.string(),
1000
- outcome: z4.string(),
1001
- spend_request_id: z4.string(),
1002
- status: z4.string()
1127
+ import { z as z5 } from "zod";
1128
+ var reportRecordSchema = z5.looseObject({
1129
+ object: z5.string(),
1130
+ created_at: z5.string(),
1131
+ domain: z5.string(),
1132
+ outcome: z5.string(),
1133
+ spend_request_id: z5.string(),
1134
+ status: z5.string()
1003
1135
  });
1004
1136
  var ReportResource = class extends BaseResource {
1005
1137
  constructor(options) {
@@ -1024,15 +1156,15 @@ var ReportResource = class extends BaseResource {
1024
1156
  };
1025
1157
 
1026
1158
  // src/resources/shipping-address.ts
1027
- import { z as z5 } from "zod";
1028
- var shippingAddressSchema = z5.looseObject({
1029
- id: z5.string(),
1030
- is_default: z5.boolean(),
1031
- nickname: z5.optional(z5.string().nullable()),
1032
- address: z5.looseObject({}).nullable()
1159
+ import { z as z6 } from "zod";
1160
+ var shippingAddressSchema = z6.looseObject({
1161
+ id: z6.string(),
1162
+ is_default: z6.boolean(),
1163
+ nickname: z6.optional(z6.string().nullable()),
1164
+ address: z6.looseObject({}).nullable()
1033
1165
  });
1034
- var shippingAddressesResponseSchema = z5.looseObject({
1035
- shipping_addresses: z5.array(shippingAddressSchema)
1166
+ var shippingAddressesResponseSchema = z6.looseObject({
1167
+ shipping_addresses: z6.array(shippingAddressSchema)
1036
1168
  });
1037
1169
  var ShippingAddressResource = class extends BaseResource {
1038
1170
  constructor(options) {
@@ -1055,21 +1187,21 @@ var ShippingAddressResource = class extends BaseResource {
1055
1187
  };
1056
1188
 
1057
1189
  // src/resources/sources.ts
1058
- import { z as z6 } from "zod";
1059
- var nullableRecordSchema = z6.record(z6.string(), z6.unknown()).nullable().optional();
1060
- var sourceSchema = z6.looseObject({
1061
- id: z6.string().nullable().optional(),
1062
- name: z6.string().nullable().optional(),
1063
- type: z6.string().nullable().optional(),
1190
+ import { z as z7 } from "zod";
1191
+ var nullableRecordSchema = z7.record(z7.string(), z7.unknown()).nullable().optional();
1192
+ var sourceSchema = z7.looseObject({
1193
+ id: z7.string().nullable().optional(),
1194
+ name: z7.string().nullable().optional(),
1195
+ type: z7.string().nullable().optional(),
1064
1196
  capabilities: nullableRecordSchema,
1065
1197
  external_connection: nullableRecordSchema,
1066
- granted_actions: z6.array(z6.string()).nullable().optional(),
1198
+ granted_actions: z7.array(z7.string()).nullable().optional(),
1067
1199
  bank_account: nullableRecordSchema,
1068
1200
  card: nullableRecordSchema
1069
1201
  });
1070
- var sourcesPageSchema = z6.looseObject({
1071
- data: z6.array(sourceSchema),
1072
- has_more: z6.boolean().optional()
1202
+ var sourcesPageSchema = z7.looseObject({
1203
+ data: z7.array(sourceSchema),
1204
+ has_more: z7.boolean().optional()
1073
1205
  });
1074
1206
  var SourcesResource = class extends BaseResource {
1075
1207
  constructor(options) {
@@ -1105,34 +1237,34 @@ var SourcesResource = class extends BaseResource {
1105
1237
  };
1106
1238
 
1107
1239
  // src/resources/spend-request.ts
1108
- import { z as z7 } from "zod";
1109
- var sharedPaymentTokenSchema = z7.union([
1110
- z7.string().transform((id) => ({ id })),
1111
- z7.looseObject({ id: z7.string() })
1240
+ import { z as z8 } from "zod";
1241
+ var sharedPaymentTokenSchema = z8.union([
1242
+ z8.string().transform((id) => ({ id })),
1243
+ z8.looseObject({ id: z8.string() })
1112
1244
  ]);
1113
- var spendRequestSchema = z7.looseObject({
1114
- id: z7.string(),
1115
- payment_details: z7.string().optional(),
1116
- status: z7.string(),
1117
- line_items: z7.array(z7.unknown()).optional(),
1118
- totals: z7.array(z7.unknown()).optional(),
1119
- created_at: z7.string(),
1120
- updated_at: z7.string(),
1245
+ var spendRequestSchema = z8.looseObject({
1246
+ id: z8.string(),
1247
+ payment_details: z8.string().optional(),
1248
+ status: z8.string(),
1249
+ line_items: z8.array(z8.unknown()).optional(),
1250
+ totals: z8.array(z8.unknown()).optional(),
1251
+ created_at: z8.string(),
1252
+ updated_at: z8.string(),
1121
1253
  shared_payment_token: sharedPaymentTokenSchema.nullable().optional()
1122
1254
  });
1123
- var spendRequestsResponseSchema = z7.looseObject({
1124
- data: z7.array(spendRequestSchema)
1255
+ var spendRequestsResponseSchema = z8.looseObject({
1256
+ data: z8.array(spendRequestSchema)
1125
1257
  });
1126
- var requestApprovalResponseSchema = z7.looseObject({
1127
- id: z7.string(),
1128
- approval_link: z7.string()
1258
+ var requestApprovalResponseSchema = z8.looseObject({
1259
+ id: z8.string(),
1260
+ approval_link: z8.string()
1129
1261
  }).transform(({ approval_link, ...response }) => ({
1130
1262
  ...response,
1131
1263
  approval_url: approval_link
1132
1264
  }));
1133
- var duplicateSpendRequestErrorSchema = z7.looseObject({
1134
- error: z7.looseObject({
1135
- duplicate_spend_request: z7.unknown().optional()
1265
+ var duplicateSpendRequestErrorSchema = z8.looseObject({
1266
+ error: z8.looseObject({
1267
+ duplicate_spend_request: z8.unknown().optional()
1136
1268
  })
1137
1269
  });
1138
1270
  function parseSpendRequest(value) {
@@ -1252,35 +1384,35 @@ var SpendRequestResource = class extends BaseResource {
1252
1384
  };
1253
1385
 
1254
1386
  // src/resources/summaries.ts
1255
- import { z as z8 } from "zod";
1256
- var summaryValueSchema = z8.discriminatedUnion("unit", [
1257
- z8.looseObject({ unit: z8.literal("count"), count: z8.number() }),
1258
- z8.looseObject({
1259
- unit: z8.literal("payment_volume"),
1260
- amount: z8.number(),
1261
- currency: z8.string()
1387
+ import { z as z9 } from "zod";
1388
+ var summaryValueSchema = z9.discriminatedUnion("unit", [
1389
+ z9.looseObject({ unit: z9.literal("count"), count: z9.number() }),
1390
+ z9.looseObject({
1391
+ unit: z9.literal("payment_volume"),
1392
+ amount: z9.number(),
1393
+ currency: z9.string()
1262
1394
  })
1263
1395
  ]);
1264
- var summaryDataValueSchema = z8.discriminatedUnion("unit", [
1265
- z8.looseObject({ unit: z8.literal("count"), amount: z8.number() }),
1266
- z8.looseObject({
1267
- unit: z8.literal("payment_volume"),
1268
- amount: z8.number(),
1269
- currency: z8.string()
1396
+ var summaryDataValueSchema = z9.discriminatedUnion("unit", [
1397
+ z9.looseObject({ unit: z9.literal("count"), amount: z9.number() }),
1398
+ z9.looseObject({
1399
+ unit: z9.literal("payment_volume"),
1400
+ amount: z9.number(),
1401
+ currency: z9.string()
1270
1402
  })
1271
1403
  ]);
1272
- var summarySchema = z8.looseObject({
1273
- id: z8.string(),
1274
- description: z8.string(),
1275
- created_at: z8.string().nullable().optional(),
1276
- status: z8.enum(["ready", "pending", "no_data"]),
1277
- entries: z8.array(z8.looseObject({ label: z8.string(), value: summaryValueSchema })).default([]),
1278
- as_of: z8.number().optional(),
1279
- data: z8.array(z8.looseObject({ label: z8.string(), value: summaryDataValueSchema })).nullable().optional()
1404
+ var summarySchema = z9.looseObject({
1405
+ id: z9.string(),
1406
+ description: z9.string(),
1407
+ created_at: z9.string().nullable().optional(),
1408
+ status: z9.enum(["ready", "pending", "no_data"]),
1409
+ entries: z9.array(z9.looseObject({ label: z9.string(), value: summaryValueSchema })).default([]),
1410
+ as_of: z9.number().optional(),
1411
+ data: z9.array(z9.looseObject({ label: z9.string(), value: summaryDataValueSchema })).nullable().optional()
1280
1412
  });
1281
- var summariesPageSchema = z8.looseObject({
1282
- data: z8.array(summarySchema),
1283
- has_more: z8.boolean().optional()
1413
+ var summariesPageSchema = z9.looseObject({
1414
+ data: z9.array(summarySchema),
1415
+ has_more: z9.boolean().optional()
1284
1416
  });
1285
1417
  var SummariesResource = class extends BaseResource {
1286
1418
  constructor(options) {
@@ -1311,23 +1443,23 @@ var SummariesResource = class extends BaseResource {
1311
1443
  };
1312
1444
 
1313
1445
  // src/resources/transactions.ts
1314
- import { z as z9 } from "zod";
1315
- var transactionSchema = z9.looseObject({
1316
- id: z9.string(),
1317
- source_id: z9.string().nullable(),
1318
- amount: z9.number(),
1319
- currency: z9.string(),
1320
- created_date: z9.string(),
1321
- description: z9.string(),
1322
- origin: z9.enum(["link", "external_connection"]),
1323
- category: z9.string().nullable(),
1324
- status: z9.string()
1446
+ import { z as z10 } from "zod";
1447
+ var transactionSchema = z10.looseObject({
1448
+ id: z10.string(),
1449
+ source_id: z10.string().nullable(),
1450
+ amount: z10.number(),
1451
+ currency: z10.string(),
1452
+ created_date: z10.string(),
1453
+ description: z10.string(),
1454
+ origin: z10.enum(["link", "external_connection"]),
1455
+ category: z10.string().nullable(),
1456
+ status: z10.string()
1325
1457
  });
1326
- var transactionsPageSchema = z9.union([
1327
- z9.array(transactionSchema).transform((data) => ({ data })),
1328
- z9.looseObject({
1329
- data: z9.array(transactionSchema),
1330
- has_more: z9.boolean().optional()
1458
+ var transactionsPageSchema = z10.union([
1459
+ z10.array(transactionSchema).transform((data) => ({ data })),
1460
+ z10.looseObject({
1461
+ data: z10.array(transactionSchema),
1462
+ has_more: z10.boolean().optional()
1331
1463
  })
1332
1464
  ]);
1333
1465
  var TransactionsResource = class extends BaseResource {
@@ -1380,36 +1512,246 @@ var TransactionsResource = class extends BaseResource {
1380
1512
  }
1381
1513
  };
1382
1514
 
1515
+ // src/resources/ucp.ts
1516
+ function extractApiError(data, rawBody) {
1517
+ if (data && typeof data === "object") {
1518
+ const body = data;
1519
+ if (body.error && typeof body.error === "object") {
1520
+ const err = body.error;
1521
+ if (typeof err.message === "string") return err.message;
1522
+ }
1523
+ if (typeof body.error === "string") return body.error;
1524
+ if (typeof body.message === "string") return body.message;
1525
+ }
1526
+ return rawBody || "unknown error";
1527
+ }
1528
+ function normalizeSearchResult(data) {
1529
+ const body = data ?? {};
1530
+ const items = Array.isArray(body.data) ? body.data : [];
1531
+ return { ...body, data: items };
1532
+ }
1533
+ function normalizeCheckout(data) {
1534
+ const body = data ?? {};
1535
+ return { ...body, id: String(body.id ?? "") };
1536
+ }
1537
+ var UcpResource = class {
1538
+ verbose;
1539
+ getAccessToken;
1540
+ fetchImpl;
1541
+ ucpEndpoint;
1542
+ logger;
1543
+ constructor(options) {
1544
+ const config = resolveLinkSdkConfig(options);
1545
+ this.verbose = config.verbose;
1546
+ this.getAccessToken = config.getAccessToken;
1547
+ this.fetchImpl = requireFetchImplementation(config);
1548
+ this.ucpEndpoint = `${config.apiBaseUrl}/ucp`;
1549
+ this.logger = config.logger;
1550
+ }
1551
+ async rawFetch(opts) {
1552
+ if (this.verbose) {
1553
+ const redactedHeaders = { ...opts.headers };
1554
+ if (redactedHeaders.Authorization)
1555
+ redactedHeaders.Authorization = "Bearer <redacted>";
1556
+ this.logger.debug(`> ${opts.method} ${opts.url}`);
1557
+ this.logger.debug(` Headers: ${JSON.stringify(redactedHeaders)}`);
1558
+ if (opts.body) this.logger.debug(opts.body);
1559
+ }
1560
+ const fetchOpts = {
1561
+ method: opts.method,
1562
+ ...opts.headers ? { headers: opts.headers } : {}
1563
+ };
1564
+ if (opts.body) fetchOpts.body = opts.body;
1565
+ let response;
1566
+ try {
1567
+ response = await this.fetchImpl(opts.url, fetchOpts);
1568
+ } catch (error) {
1569
+ throw new LinkTransportError(
1570
+ `Request failed: ${opts.method} ${opts.url}`,
1571
+ {
1572
+ cause: error
1573
+ }
1574
+ );
1575
+ }
1576
+ const rawBody = await response.text();
1577
+ let data = null;
1578
+ try {
1579
+ data = JSON.parse(rawBody);
1580
+ } catch {
1581
+ }
1582
+ if (this.verbose) {
1583
+ this.logger.debug(`< ${response.status} ${response.statusText}`);
1584
+ response.headers.forEach((value, key) => {
1585
+ this.logger.debug(` ${key}: ${value}`);
1586
+ });
1587
+ this.logger.debug(JSON.stringify(data, null, 2) ?? rawBody);
1588
+ }
1589
+ return { status: response.status, data, rawBody };
1590
+ }
1591
+ /** Injects the Bearer token; retries once on 401 after refreshing. */
1592
+ async apiFetch(opts) {
1593
+ const token = await this.getAccessToken();
1594
+ const authedOpts = {
1595
+ ...opts,
1596
+ headers: { ...opts.headers, Authorization: `Bearer ${token}` }
1597
+ };
1598
+ const res = await this.rawFetch(authedOpts);
1599
+ if (res.status === 401) {
1600
+ const refreshedToken = await this.getAccessToken({ forceRefresh: true });
1601
+ authedOpts.headers.Authorization = `Bearer ${refreshedToken}`;
1602
+ return this.rawFetch(authedOpts);
1603
+ }
1604
+ return res;
1605
+ }
1606
+ buildSearchUrl(params) {
1607
+ const url = new URL(`${this.ucpEndpoint}/catalog/search`);
1608
+ const setIf = (key, value) => {
1609
+ if (value !== void 0) url.searchParams.set(key, String(value));
1610
+ };
1611
+ setIf("query", params.query);
1612
+ setIf("profile_id", params.profile_id);
1613
+ setIf("sku", params.sku);
1614
+ setIf("price_min", params.price_min);
1615
+ setIf("price_max", params.price_max);
1616
+ setIf("currency", params.currency);
1617
+ setIf("availability", params.availability);
1618
+ setIf("sort", params.sort);
1619
+ setIf("group_by", params.group_by);
1620
+ setIf("limit", params.limit);
1621
+ setIf("offset", params.offset);
1622
+ if (params.include_facets) url.searchParams.set("include_facets", "true");
1623
+ const arrays = [
1624
+ ["brand", params.brand],
1625
+ ["category", params.category],
1626
+ ["color", params.color],
1627
+ ["size", params.size],
1628
+ ["material", params.material],
1629
+ ["gender", params.gender],
1630
+ ["condition", params.condition]
1631
+ ];
1632
+ for (const [key, values] of arrays) {
1633
+ if (values)
1634
+ for (const value of values) url.searchParams.append(`${key}[]`, value);
1635
+ }
1636
+ if (params.test) url.searchParams.set("test", "true");
1637
+ return url.toString();
1638
+ }
1639
+ async searchCatalog(params) {
1640
+ const { status, data, rawBody } = await this.apiFetch({
1641
+ method: "GET",
1642
+ url: this.buildSearchUrl(params)
1643
+ });
1644
+ if (status < 200 || status >= 300) {
1645
+ throw new LinkApiError(
1646
+ `Failed to search UCP catalog (${status}): ${extractApiError(data, rawBody)}`,
1647
+ { status, rawBody, details: data }
1648
+ );
1649
+ }
1650
+ return normalizeSearchResult(data);
1651
+ }
1652
+ async createCheckout(params) {
1653
+ const body = {
1654
+ profile_id: params.profile_id,
1655
+ line_items: params.line_items
1656
+ };
1657
+ if (params.currency !== void 0) body.currency = params.currency;
1658
+ if (params.fulfillment_details !== void 0)
1659
+ body.fulfillment_details = params.fulfillment_details;
1660
+ if (params.test) body.test = true;
1661
+ const { status, data, rawBody } = await this.apiFetch({
1662
+ method: "POST",
1663
+ url: `${this.ucpEndpoint}/checkout`,
1664
+ headers: { "Content-Type": "application/json" },
1665
+ body: JSON.stringify(body)
1666
+ });
1667
+ if (status < 200 || status >= 300) {
1668
+ throw new LinkApiError(
1669
+ `Failed to create UCP checkout (${status}): ${extractApiError(data, rawBody)}`,
1670
+ { status, rawBody, details: data }
1671
+ );
1672
+ }
1673
+ return normalizeCheckout(data);
1674
+ }
1675
+ async completeCheckout(id, params) {
1676
+ const body = {
1677
+ spend_request_id: params.spend_request_id,
1678
+ profile_id: params.profile_id
1679
+ };
1680
+ if (params.test) body.test = true;
1681
+ const { status, data, rawBody } = await this.apiFetch({
1682
+ method: "POST",
1683
+ url: `${this.ucpEndpoint}/checkout/${encodeURIComponent(id)}/complete`,
1684
+ headers: { "Content-Type": "application/json" },
1685
+ body: JSON.stringify(body)
1686
+ });
1687
+ if (status < 200 || status >= 300) {
1688
+ throw new LinkApiError(
1689
+ `Failed to complete UCP checkout (${status}): ${extractApiError(data, rawBody)}`,
1690
+ { status, rawBody, details: data }
1691
+ );
1692
+ }
1693
+ return normalizeCheckout(data);
1694
+ }
1695
+ async retrieveCheckout(id, params) {
1696
+ const url = new URL(
1697
+ `${this.ucpEndpoint}/checkout/${encodeURIComponent(id)}`
1698
+ );
1699
+ url.searchParams.set("spend_request_id", params.spend_request_id);
1700
+ if (params.test) url.searchParams.set("test", "true");
1701
+ const { status, data, rawBody } = await this.apiFetch({
1702
+ method: "GET",
1703
+ url: url.toString()
1704
+ });
1705
+ if (status < 200 || status >= 300) {
1706
+ throw new LinkApiError(
1707
+ `Failed to retrieve UCP checkout (${status}): ${extractApiError(data, rawBody)}`,
1708
+ { status, rawBody, details: data }
1709
+ );
1710
+ }
1711
+ return normalizeCheckout(data);
1712
+ }
1713
+ };
1714
+
1383
1715
  // src/resources/user-info.ts
1384
- import { z as z10 } from "zod";
1385
- var rollingSpendLimitSchema = z10.object({
1386
- limit: z10.number().int().nullable(),
1387
- used: z10.number().int(),
1388
- remaining: z10.number().int().nullable()
1716
+ import { z as z11 } from "zod";
1717
+ var rollingSpendLimitSchema = z11.object({
1718
+ limit: z11.number().int().nullable(),
1719
+ used: z11.number().int(),
1720
+ remaining: z11.number().int().nullable()
1389
1721
  });
1390
- var agentWalletSpendLimitsSchema = z10.object({
1391
- per_transaction: z10.object({
1392
- limit: z10.number().int().nullable()
1722
+ var agentWalletSpendLimitsSchema = z11.object({
1723
+ per_transaction: z11.object({
1724
+ limit: z11.number().int().nullable()
1393
1725
  }),
1394
1726
  daily: rollingSpendLimitSchema,
1395
1727
  thirty_day: rollingSpendLimitSchema
1396
1728
  });
1397
- var agentWalletVerificationRequirementSchema = z10.object({
1398
- status: z10.enum([
1729
+ var agentWalletVerificationRequirementSchema = z11.object({
1730
+ status: z11.enum([
1399
1731
  "not_required",
1400
1732
  "ssn_verification",
1401
1733
  "identity_verification",
1402
1734
  "contact_support",
1403
1735
  "complete"
1404
1736
  ]),
1405
- action_url: z10.string().nullable()
1737
+ action_url: z11.string().nullable()
1738
+ });
1739
+ var userInfoAddressSchema = z11.object({
1740
+ line1: z11.string().nullable(),
1741
+ line2: z11.string().nullable(),
1742
+ city: z11.string().nullable(),
1743
+ state: z11.string().nullable(),
1744
+ postal_code: z11.string().nullable(),
1745
+ country: z11.string().nullable()
1406
1746
  });
1407
- var userInfoSchema = z10.looseObject({
1408
- email: z10.string().nullable().optional(),
1409
- name: z10.string().nullable().optional(),
1410
- first_name: z10.string().nullable().optional(),
1411
- last_name: z10.string().nullable().optional(),
1412
- phone: z10.string().nullable().optional(),
1747
+ var userInfoSchema = z11.looseObject({
1748
+ email: z11.string().nullable().optional(),
1749
+ name: z11.string().nullable().optional(),
1750
+ first_name: z11.string().nullable().optional(),
1751
+ last_name: z11.string().nullable().optional(),
1752
+ phone: z11.string().nullable().optional(),
1753
+ address: userInfoAddressSchema.nullable().optional(),
1754
+ eligible_for_balance: z11.boolean().optional(),
1413
1755
  agent_wallet_spend_limits: agentWalletSpendLimitsSchema.optional(),
1414
1756
  agent_wallet_step_up: agentWalletVerificationRequirementSchema.optional()
1415
1757
  }).transform(
@@ -1419,6 +1761,8 @@ var userInfoSchema = z10.looseObject({
1419
1761
  first_name,
1420
1762
  last_name,
1421
1763
  phone,
1764
+ address,
1765
+ eligible_for_balance,
1422
1766
  agent_wallet_spend_limits,
1423
1767
  agent_wallet_step_up
1424
1768
  }) => ({
@@ -1427,6 +1771,8 @@ var userInfoSchema = z10.looseObject({
1427
1771
  first_name: first_name ?? null,
1428
1772
  last_name: last_name ?? null,
1429
1773
  phone: phone ?? null,
1774
+ ...address === void 0 ? {} : { address },
1775
+ ...eligible_for_balance === void 0 ? {} : { eligible_for_balance },
1430
1776
  ...agent_wallet_spend_limits === void 0 ? {} : { agent_wallet_spend_limits },
1431
1777
  ...agent_wallet_step_up === void 0 ? {} : { agent_wallet_verification_requirement: agent_wallet_step_up }
1432
1778
  })
@@ -1452,16 +1798,16 @@ var UserInfoResource = class extends BaseResource {
1452
1798
  };
1453
1799
 
1454
1800
  // src/resources/web-bot-auth.ts
1455
- import { z as z11 } from "zod";
1801
+ import { z as z12 } from "zod";
1456
1802
  var EXPIRY_BUFFER_MS = 3e4;
1457
- var webBotAuthBlockSchema = z11.looseObject({
1458
- signature: z11.string(),
1459
- signature_input: z11.string(),
1460
- signature_agent: z11.string(),
1461
- authority: z11.string(),
1462
- expires_at: z11.string()
1803
+ var webBotAuthBlockSchema = z12.looseObject({
1804
+ signature: z12.string(),
1805
+ signature_input: z12.string(),
1806
+ signature_agent: z12.string(),
1807
+ authority: z12.string(),
1808
+ expires_at: z12.string()
1463
1809
  });
1464
- var webBotAuthResponseSchema = z11.looseObject({
1810
+ var webBotAuthResponseSchema = z12.looseObject({
1465
1811
  web_bot_auth: webBotAuthBlockSchema
1466
1812
  });
1467
1813
  var WebBotAuthResource = class extends BaseResource {
@@ -1508,6 +1854,7 @@ var WebBotAuthResource = class extends BaseResource {
1508
1854
  // src/client.ts
1509
1855
  var Link = class {
1510
1856
  attestations;
1857
+ identityCredentials;
1511
1858
  spendRequests;
1512
1859
  paymentMethods;
1513
1860
  shippingAddresses;
@@ -1518,8 +1865,10 @@ var Link = class {
1518
1865
  summaries;
1519
1866
  webBotAuth;
1520
1867
  reports;
1868
+ ucp;
1521
1869
  constructor(options) {
1522
1870
  this.attestations = new AttestationsResource(options);
1871
+ this.identityCredentials = new IdentityCredentialsResource(options);
1523
1872
  this.spendRequests = new SpendRequestResource(options);
1524
1873
  this.paymentMethods = new PaymentMethodsResource(options);
1525
1874
  this.shippingAddresses = new ShippingAddressResource(options);
@@ -1530,6 +1879,7 @@ var Link = class {
1530
1879
  this.summaries = new SummariesResource(options);
1531
1880
  this.webBotAuth = new WebBotAuthResource(options);
1532
1881
  this.reports = new ReportResource(options);
1882
+ this.ucp = new UcpResource(options);
1533
1883
  }
1534
1884
  };
1535
1885
  var client_default = Link;
@@ -1566,6 +1916,9 @@ export {
1566
1916
  REPORT_TAGS,
1567
1917
  SummariesResource,
1568
1918
  client_default as default,
1569
- getDuplicateSpendRequest
1919
+ getDuplicateSpendRequest,
1920
+ holderJwkThumbprint,
1921
+ holderJwksEqual,
1922
+ parseHolderPublicJwk
1570
1923
  };
1571
1924
  //# sourceMappingURL=index.js.map