spaps-sdk 1.6.8 → 1.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/CHANGELOG.md +7 -1
- package/README.md +107 -3
- package/dist/index.d.mts +241 -3
- package/dist/index.d.ts +241 -3
- package/dist/index.js +349 -11
- package/dist/index.mjs +341 -8
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -203,10 +203,11 @@ __export(index_exports, {
|
|
|
203
203
|
TokenManager: () => TokenManager,
|
|
204
204
|
WalletUtils: () => WalletUtils,
|
|
205
205
|
WebSocketAuthHelper: () => WebSocketAuthHelper,
|
|
206
|
+
X402PaymentRequiredSDKError: () => X402PaymentRequiredSDKError,
|
|
206
207
|
canAccessAdmin: () => canAccessAdmin,
|
|
207
208
|
createBrowserClient: () => createBrowserClient,
|
|
208
209
|
createPermissionChecker: () => createPermissionChecker,
|
|
209
|
-
createSecureMessageRequestSchema: () =>
|
|
210
|
+
createSecureMessageRequestSchema: () => import_spaps_types2.createSecureMessageRequestSchema,
|
|
210
211
|
createServerClient: () => createServerClient,
|
|
211
212
|
default: () => index_default,
|
|
212
213
|
defaultPermissionChecker: () => defaultPermissionChecker,
|
|
@@ -216,14 +217,22 @@ __export(index_exports, {
|
|
|
216
217
|
getUserRole: () => getUserRole,
|
|
217
218
|
hasPermission: () => hasPermission,
|
|
218
219
|
isAdminAccount: () => isAdminAccount,
|
|
219
|
-
|
|
220
|
-
|
|
220
|
+
isEnvelope: () => isEnvelope,
|
|
221
|
+
isErrorEnvelope: () => isErrorEnvelope,
|
|
222
|
+
isSuccessEnvelope: () => isSuccessEnvelope,
|
|
223
|
+
isX402PaymentRequired: () => import_spaps_types.isX402PaymentRequired,
|
|
224
|
+
isX402ResourceStatus: () => import_spaps_types.isX402ResourceStatus,
|
|
225
|
+
secureMessageMetadataSchema: () => import_spaps_types2.secureMessageMetadataSchema,
|
|
226
|
+
secureMessageSchema: () => import_spaps_types2.secureMessageSchema,
|
|
227
|
+
unwrapEnvelope: () => unwrapEnvelope,
|
|
228
|
+
unwrapNestedData: () => unwrapNestedData,
|
|
221
229
|
verifyCryptoWebhookSignature: () => verifyCryptoWebhookSignature
|
|
222
230
|
});
|
|
223
231
|
module.exports = __toCommonJS(index_exports);
|
|
224
232
|
var import_crypto = __toESM(require("crypto"));
|
|
225
233
|
var import_axios = __toESM(require("axios"));
|
|
226
234
|
var import_spaps_types = require("spaps-types");
|
|
235
|
+
var import_spaps_types2 = require("spaps-types");
|
|
227
236
|
init_permissions();
|
|
228
237
|
|
|
229
238
|
// src/role-hierarchy.ts
|
|
@@ -510,12 +519,23 @@ function appendSupportedIssueReportScope(q, scope) {
|
|
|
510
519
|
}
|
|
511
520
|
q.append("scope", scope);
|
|
512
521
|
}
|
|
513
|
-
var
|
|
522
|
+
var X402PaymentRequiredSDKError = class extends Error {
|
|
523
|
+
paymentRequiredHeader;
|
|
524
|
+
response;
|
|
525
|
+
constructor(paymentRequiredHeader, response) {
|
|
526
|
+
super("x402 payment required");
|
|
527
|
+
this.name = "X402PaymentRequiredSDKError";
|
|
528
|
+
this.paymentRequiredHeader = paymentRequiredHeader;
|
|
529
|
+
this.response = response;
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
var SPAPSClient = class _SPAPSClient {
|
|
514
533
|
client;
|
|
515
534
|
apiKey;
|
|
516
535
|
accessToken;
|
|
517
536
|
refreshToken;
|
|
518
537
|
_isLocalMode = false;
|
|
538
|
+
headerProvider;
|
|
519
539
|
unwrapApiResponse(response, fallback) {
|
|
520
540
|
if (!response) {
|
|
521
541
|
throw new Error(fallback);
|
|
@@ -532,6 +552,13 @@ var SPAPSClient = class {
|
|
|
532
552
|
}
|
|
533
553
|
return payload;
|
|
534
554
|
}
|
|
555
|
+
skillEvalMutationConfig(options) {
|
|
556
|
+
const ifMatch = options?.ifMatch ?? options?.caseVersion;
|
|
557
|
+
if (ifMatch === void 0 || ifMatch === null || ifMatch === "") {
|
|
558
|
+
return void 0;
|
|
559
|
+
}
|
|
560
|
+
return { headers: { "If-Match": String(ifMatch) } };
|
|
561
|
+
}
|
|
535
562
|
isAxiosResponse(value) {
|
|
536
563
|
if (!value || typeof value !== "object") {
|
|
537
564
|
return false;
|
|
@@ -551,6 +578,41 @@ var SPAPSClient = class {
|
|
|
551
578
|
const record = value;
|
|
552
579
|
return "success" in record && typeof record.success === "boolean";
|
|
553
580
|
}
|
|
581
|
+
static isSdkManagedHeader(name) {
|
|
582
|
+
const normalized = name.toLowerCase();
|
|
583
|
+
return normalized === "authorization" || normalized === "x-api-key";
|
|
584
|
+
}
|
|
585
|
+
static hasHeader(headers, name) {
|
|
586
|
+
if (!headers) return false;
|
|
587
|
+
if (typeof headers.has === "function") {
|
|
588
|
+
return headers.has(name);
|
|
589
|
+
}
|
|
590
|
+
const normalized = name.toLowerCase();
|
|
591
|
+
return Object.keys(headers).some((key) => key.toLowerCase() === normalized);
|
|
592
|
+
}
|
|
593
|
+
static setHeader(headers, name, value) {
|
|
594
|
+
if (typeof headers.set === "function") {
|
|
595
|
+
headers.set(name, value);
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
headers[name] = value;
|
|
599
|
+
}
|
|
600
|
+
static assertSafeHeaderValue(name, value) {
|
|
601
|
+
if (typeof value === "string" && /[\r\n]/.test(value)) {
|
|
602
|
+
throw new Error(`Invalid header value for ${name}: control characters not allowed`);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
applyCustomHeaders(headers) {
|
|
606
|
+
const customHeaders = this.headerProvider?.();
|
|
607
|
+
if (!customHeaders) return;
|
|
608
|
+
for (const [key, value] of Object.entries(customHeaders)) {
|
|
609
|
+
if (_SPAPSClient.isSdkManagedHeader(key) || _SPAPSClient.hasHeader(headers, key)) {
|
|
610
|
+
continue;
|
|
611
|
+
}
|
|
612
|
+
_SPAPSClient.assertSafeHeaderValue(key, value);
|
|
613
|
+
_SPAPSClient.setHeader(headers, key, value);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
554
616
|
// Admin namespace for cleaner API
|
|
555
617
|
admin = {
|
|
556
618
|
createProduct: (productData) => this.createProduct(productData),
|
|
@@ -725,8 +787,43 @@ var SPAPSClient = class {
|
|
|
725
787
|
return this.unwrapApiResponse(res, "Failed to reply to issue report");
|
|
726
788
|
}
|
|
727
789
|
};
|
|
790
|
+
/**
|
|
791
|
+
* Application-scoped short links for browser apps that need stable public URLs.
|
|
792
|
+
*/
|
|
793
|
+
appLinks = {
|
|
794
|
+
/**
|
|
795
|
+
* Create a short link owned by the authenticated user.
|
|
796
|
+
*/
|
|
797
|
+
create: async (payload) => {
|
|
798
|
+
const res = await this.client.post(
|
|
799
|
+
"/api/v1/app-links",
|
|
800
|
+
payload,
|
|
801
|
+
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
802
|
+
);
|
|
803
|
+
return this.unwrapApiResponse(res, "Failed to create app link");
|
|
804
|
+
},
|
|
805
|
+
/**
|
|
806
|
+
* Resolve a public short link for the active application.
|
|
807
|
+
*/
|
|
808
|
+
get: async (username, slug, options) => {
|
|
809
|
+
const q = new URLSearchParams();
|
|
810
|
+
if (options?.track) q.set("track", "true");
|
|
811
|
+
const qs = q.toString();
|
|
812
|
+
const res = await this.client.get(
|
|
813
|
+
`/api/v1/app-links/${encodeURIComponent(username)}/${encodeURIComponent(slug)}${qs ? `?${qs}` : ""}`,
|
|
814
|
+
this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0
|
|
815
|
+
);
|
|
816
|
+
return this.unwrapApiResponse(res, "Failed to get app link");
|
|
817
|
+
}
|
|
818
|
+
};
|
|
819
|
+
static envVar(name) {
|
|
820
|
+
if (typeof process !== "undefined" && process.env) {
|
|
821
|
+
return process.env[name];
|
|
822
|
+
}
|
|
823
|
+
return void 0;
|
|
824
|
+
}
|
|
728
825
|
constructor(config = {}) {
|
|
729
|
-
const apiUrl = config.apiUrl ||
|
|
826
|
+
const apiUrl = config.apiUrl || _SPAPSClient.envVar("SPAPS_API_URL") || _SPAPSClient.envVar("NEXT_PUBLIC_SPAPS_API_URL");
|
|
730
827
|
const isBrowser = typeof window !== "undefined";
|
|
731
828
|
let effectiveApiKey;
|
|
732
829
|
if (config.publishableKey) {
|
|
@@ -739,7 +836,7 @@ var SPAPSClient = class {
|
|
|
739
836
|
} else if (config.apiKey) {
|
|
740
837
|
effectiveApiKey = config.apiKey;
|
|
741
838
|
} else {
|
|
742
|
-
effectiveApiKey =
|
|
839
|
+
effectiveApiKey = _SPAPSClient.envVar("SPAPS_API_KEY") || _SPAPSClient.envVar("NEXT_PUBLIC_SPAPS_API_KEY");
|
|
743
840
|
}
|
|
744
841
|
if (!apiUrl || apiUrl.includes("localhost") || apiUrl.includes("127.0.0.1")) {
|
|
745
842
|
this._isLocalMode = true;
|
|
@@ -748,6 +845,7 @@ var SPAPSClient = class {
|
|
|
748
845
|
if (!this.apiKey && !this._isLocalMode) {
|
|
749
846
|
console.warn("\u26A0\uFE0F SPAPS: No API key provided. Some features may not work.");
|
|
750
847
|
}
|
|
848
|
+
this.headerProvider = config.headerProvider;
|
|
751
849
|
this.client = import_axios.default.create({
|
|
752
850
|
baseURL: apiUrl || "http://localhost:3301",
|
|
753
851
|
timeout: config.timeout || 1e4,
|
|
@@ -757,11 +855,13 @@ var SPAPSClient = class {
|
|
|
757
855
|
}
|
|
758
856
|
});
|
|
759
857
|
this.client.interceptors.request.use((config2) => {
|
|
760
|
-
|
|
761
|
-
|
|
858
|
+
config2.headers = config2.headers || {};
|
|
859
|
+
this.applyCustomHeaders(config2.headers);
|
|
860
|
+
if (this.apiKey && !_SPAPSClient.hasHeader(config2.headers, "X-API-Key")) {
|
|
861
|
+
_SPAPSClient.setHeader(config2.headers, "X-API-Key", this.apiKey);
|
|
762
862
|
}
|
|
763
|
-
if (this.accessToken && !config2.headers
|
|
764
|
-
config2.headers
|
|
863
|
+
if (this.accessToken && !_SPAPSClient.hasHeader(config2.headers, "Authorization")) {
|
|
864
|
+
_SPAPSClient.setHeader(config2.headers, "Authorization", `Bearer ${this.accessToken}`);
|
|
765
865
|
}
|
|
766
866
|
return config2;
|
|
767
867
|
});
|
|
@@ -1063,6 +1163,7 @@ var SPAPSClient = class {
|
|
|
1063
1163
|
reconcile: async (options = {}) => {
|
|
1064
1164
|
const headers = {};
|
|
1065
1165
|
if (options.reconToken) {
|
|
1166
|
+
_SPAPSClient.assertSafeHeaderValue("X-Recon-Token", options.reconToken);
|
|
1066
1167
|
headers["X-Recon-Token"] = options.reconToken;
|
|
1067
1168
|
}
|
|
1068
1169
|
const payload = {};
|
|
@@ -1288,6 +1389,176 @@ var SPAPSClient = class {
|
|
|
1288
1389
|
return this.unwrapApiResponse(res, "Failed to disconnect");
|
|
1289
1390
|
}
|
|
1290
1391
|
};
|
|
1392
|
+
/**
|
|
1393
|
+
* x402 paid-resource namespace.
|
|
1394
|
+
* Handles resource status checks, payment-gated actions, receipts, and handoff authorization.
|
|
1395
|
+
*/
|
|
1396
|
+
x402 = {
|
|
1397
|
+
getResourceStatus: async (resourceKey) => {
|
|
1398
|
+
const res = await this.client.get(
|
|
1399
|
+
`/api/x402/resources/${encodeURIComponent(resourceKey)}/status`
|
|
1400
|
+
);
|
|
1401
|
+
return this.unwrapApiResponse(res, "Failed to get x402 resource status");
|
|
1402
|
+
},
|
|
1403
|
+
executeAction: async (resourceKey, actionKey, options) => {
|
|
1404
|
+
const headers = {};
|
|
1405
|
+
if (this.accessToken) {
|
|
1406
|
+
headers["Authorization"] = `Bearer ${this.accessToken}`;
|
|
1407
|
+
}
|
|
1408
|
+
if (options?.paymentSignature) {
|
|
1409
|
+
headers["PAYMENT-SIGNATURE"] = options.paymentSignature;
|
|
1410
|
+
}
|
|
1411
|
+
const body = {};
|
|
1412
|
+
if (options?.target) body.target = options.target;
|
|
1413
|
+
const bridgeToken = options?.bridgeToken ?? options?.bridge_token;
|
|
1414
|
+
if (bridgeToken !== void 0) body.bridge_token = bridgeToken;
|
|
1415
|
+
const res = await this.client.post(
|
|
1416
|
+
`/api/x402/resources/${encodeURIComponent(resourceKey)}/actions/${encodeURIComponent(actionKey)}`,
|
|
1417
|
+
body,
|
|
1418
|
+
{ headers, validateStatus: (s) => s < 500 }
|
|
1419
|
+
);
|
|
1420
|
+
const paymentRequiredHeader = res.headers?.["payment-required"] || res.headers?.["PAYMENT-REQUIRED"] || "";
|
|
1421
|
+
if (res.status === 402 && paymentRequiredHeader) {
|
|
1422
|
+
throw new X402PaymentRequiredSDKError(
|
|
1423
|
+
paymentRequiredHeader,
|
|
1424
|
+
res.data
|
|
1425
|
+
);
|
|
1426
|
+
}
|
|
1427
|
+
return this.unwrapApiResponse(res, "Failed to execute x402 action");
|
|
1428
|
+
},
|
|
1429
|
+
getReceipt: async (receiptId) => {
|
|
1430
|
+
const res = await this.client.get(`/api/x402/receipts/${encodeURIComponent(receiptId)}`);
|
|
1431
|
+
return this.unwrapApiResponse(res, "Failed to get x402 receipt");
|
|
1432
|
+
},
|
|
1433
|
+
listReceipts: async (params) => {
|
|
1434
|
+
const q = new URLSearchParams();
|
|
1435
|
+
if (params?.resourceKey) q.append("resource_key", params.resourceKey);
|
|
1436
|
+
if (params?.limit !== void 0) q.append("limit", String(params.limit));
|
|
1437
|
+
if (params?.offset !== void 0) q.append("offset", String(params.offset));
|
|
1438
|
+
const qs = q.toString();
|
|
1439
|
+
const res = await this.client.get(`/api/x402/receipts${qs ? `?${qs}` : ""}`);
|
|
1440
|
+
return this.unwrapApiResponse(res, "Failed to list x402 receipts");
|
|
1441
|
+
},
|
|
1442
|
+
verifyHandoff: async (token, target, bridgeToken, options) => {
|
|
1443
|
+
const body = {
|
|
1444
|
+
token,
|
|
1445
|
+
resource_key: options.resourceKey,
|
|
1446
|
+
action_key: options.actionKey,
|
|
1447
|
+
target,
|
|
1448
|
+
bridge_token: bridgeToken
|
|
1449
|
+
};
|
|
1450
|
+
const res = await this.client.post("/api/x402/handoff/verify", body);
|
|
1451
|
+
return this.unwrapApiResponse(res, "Failed to verify x402 handoff");
|
|
1452
|
+
}
|
|
1453
|
+
};
|
|
1454
|
+
/**
|
|
1455
|
+
* Blind comparative skill-eval namespace.
|
|
1456
|
+
*/
|
|
1457
|
+
skillEvals = {
|
|
1458
|
+
createCase: async (payload, options) => {
|
|
1459
|
+
const headers = {};
|
|
1460
|
+
if (this.accessToken) {
|
|
1461
|
+
headers["Authorization"] = `Bearer ${this.accessToken}`;
|
|
1462
|
+
}
|
|
1463
|
+
if (options?.paymentSignature) {
|
|
1464
|
+
headers["PAYMENT-SIGNATURE"] = options.paymentSignature;
|
|
1465
|
+
}
|
|
1466
|
+
const res = await this.client.post("/api/skill-evals/cases", payload, {
|
|
1467
|
+
headers,
|
|
1468
|
+
validateStatus: (s) => s < 500
|
|
1469
|
+
});
|
|
1470
|
+
const paymentRequiredHeader = res.headers?.["payment-required"] || res.headers?.["PAYMENT-REQUIRED"] || "";
|
|
1471
|
+
if (res.status === 402 && paymentRequiredHeader) {
|
|
1472
|
+
throw new X402PaymentRequiredSDKError(paymentRequiredHeader, res.data);
|
|
1473
|
+
}
|
|
1474
|
+
return this.unwrapApiResponse(
|
|
1475
|
+
res,
|
|
1476
|
+
"Failed to create skill eval case"
|
|
1477
|
+
);
|
|
1478
|
+
},
|
|
1479
|
+
getCase: async (caseId) => {
|
|
1480
|
+
const res = await this.client.get(
|
|
1481
|
+
`/api/skill-evals/cases/${encodeURIComponent(caseId)}`
|
|
1482
|
+
);
|
|
1483
|
+
return this.unwrapApiResponse(res, "Failed to get skill eval case");
|
|
1484
|
+
},
|
|
1485
|
+
getReviewRoom: async (caseId) => {
|
|
1486
|
+
const res = await this.client.get(
|
|
1487
|
+
`/api/skill-evals/cases/${encodeURIComponent(caseId)}/room`
|
|
1488
|
+
);
|
|
1489
|
+
return this.unwrapApiResponse(res, "Failed to get skill eval room");
|
|
1490
|
+
},
|
|
1491
|
+
submitReview: async (caseId, payload, options) => {
|
|
1492
|
+
const config = this.skillEvalMutationConfig(options);
|
|
1493
|
+
const res = await this.client.post(
|
|
1494
|
+
`/api/skill-evals/cases/${encodeURIComponent(caseId)}/reviews`,
|
|
1495
|
+
payload,
|
|
1496
|
+
...config ? [config] : []
|
|
1497
|
+
);
|
|
1498
|
+
return this.unwrapApiResponse(
|
|
1499
|
+
res,
|
|
1500
|
+
"Failed to submit skill eval review"
|
|
1501
|
+
);
|
|
1502
|
+
},
|
|
1503
|
+
respondToReview: async (caseId, reviewId, payload, options) => {
|
|
1504
|
+
const config = this.skillEvalMutationConfig(options);
|
|
1505
|
+
const res = await this.client.post(
|
|
1506
|
+
`/api/skill-evals/cases/${encodeURIComponent(caseId)}/reviews/${encodeURIComponent(reviewId)}/response`,
|
|
1507
|
+
payload,
|
|
1508
|
+
...config ? [config] : []
|
|
1509
|
+
);
|
|
1510
|
+
return this.unwrapApiResponse(
|
|
1511
|
+
res,
|
|
1512
|
+
"Failed to respond to skill eval review"
|
|
1513
|
+
);
|
|
1514
|
+
},
|
|
1515
|
+
lockReviews: async (caseId, options) => {
|
|
1516
|
+
const config = this.skillEvalMutationConfig(options);
|
|
1517
|
+
const res = await this.client.post(
|
|
1518
|
+
`/api/skill-evals/cases/${encodeURIComponent(caseId)}/lock`,
|
|
1519
|
+
{},
|
|
1520
|
+
...config ? [config] : []
|
|
1521
|
+
);
|
|
1522
|
+
return this.unwrapApiResponse(
|
|
1523
|
+
res,
|
|
1524
|
+
"Failed to lock skill eval reviews"
|
|
1525
|
+
);
|
|
1526
|
+
},
|
|
1527
|
+
revealEvidence: async (caseId, payload, options) => {
|
|
1528
|
+
const config = this.skillEvalMutationConfig(options);
|
|
1529
|
+
const res = await this.client.post(
|
|
1530
|
+
`/api/skill-evals/cases/${encodeURIComponent(caseId)}/reveal`,
|
|
1531
|
+
payload,
|
|
1532
|
+
...config ? [config] : []
|
|
1533
|
+
);
|
|
1534
|
+
return this.unwrapApiResponse(
|
|
1535
|
+
res,
|
|
1536
|
+
"Failed to reveal skill eval evidence"
|
|
1537
|
+
);
|
|
1538
|
+
},
|
|
1539
|
+
createGovernanceSnapshot: async (caseId, payload, options) => {
|
|
1540
|
+
const config = this.skillEvalMutationConfig(options);
|
|
1541
|
+
const res = await this.client.post(
|
|
1542
|
+
`/api/skill-evals/cases/${encodeURIComponent(caseId)}/governance-snapshots`,
|
|
1543
|
+
payload,
|
|
1544
|
+
...config ? [config] : []
|
|
1545
|
+
);
|
|
1546
|
+
return this.unwrapApiResponse(
|
|
1547
|
+
res,
|
|
1548
|
+
"Failed to create skill eval governance snapshot"
|
|
1549
|
+
);
|
|
1550
|
+
},
|
|
1551
|
+
importGovernanceOutcome: async (snapshotId, payload) => {
|
|
1552
|
+
const res = await this.client.post(
|
|
1553
|
+
`/api/skill-evals/governance-snapshots/${encodeURIComponent(snapshotId)}/outcome`,
|
|
1554
|
+
payload
|
|
1555
|
+
);
|
|
1556
|
+
return this.unwrapApiResponse(
|
|
1557
|
+
res,
|
|
1558
|
+
"Failed to import skill eval governance outcome"
|
|
1559
|
+
);
|
|
1560
|
+
}
|
|
1561
|
+
};
|
|
1291
1562
|
/**
|
|
1292
1563
|
* DayRate (Dynamic Scheduling) namespace
|
|
1293
1564
|
* For booking half-day sessions with dynamic pricing
|
|
@@ -1316,6 +1587,21 @@ var SPAPSClient = class {
|
|
|
1316
1587
|
createMultiBooking: async (payload) => {
|
|
1317
1588
|
const res = await this.client.post("/api/dayrate/book-multi", payload);
|
|
1318
1589
|
return this.unwrapApiResponse(res, "Failed to create multi-booking");
|
|
1590
|
+
},
|
|
1591
|
+
/**
|
|
1592
|
+
* Create a single-slot booking hold backed by an x402 paid-resource action.
|
|
1593
|
+
*/
|
|
1594
|
+
createX402Booking: async (payload) => {
|
|
1595
|
+
const res = await this.client.post("/api/dayrate/book-x402", payload);
|
|
1596
|
+
return this.unwrapApiResponse(res, "Failed to create x402 booking");
|
|
1597
|
+
},
|
|
1598
|
+
/**
|
|
1599
|
+
* Get guest-safe checkout confirmation state for a Stripe session.
|
|
1600
|
+
*/
|
|
1601
|
+
getCheckoutStatus: async (sessionId) => {
|
|
1602
|
+
const query = new URLSearchParams({ sessionId }).toString();
|
|
1603
|
+
const res = await this.client.get(`/api/dayrate/checkout-status?${query}`);
|
|
1604
|
+
return this.unwrapApiResponse(res, "Failed to get checkout status");
|
|
1319
1605
|
}
|
|
1320
1606
|
};
|
|
1321
1607
|
// Stripe Methods
|
|
@@ -1604,13 +1890,24 @@ var TokenManager = class _TokenManager {
|
|
|
1604
1890
|
s.removeItem(_TokenManager.USER_KEY);
|
|
1605
1891
|
}
|
|
1606
1892
|
}
|
|
1893
|
+
static decodePayload(token) {
|
|
1894
|
+
try {
|
|
1895
|
+
const parts = token.split(".");
|
|
1896
|
+
if (parts.length !== 3 || !parts[1]) return null;
|
|
1897
|
+
const decoded = JSON.parse(_TokenManager.base64Decode(parts[1]));
|
|
1898
|
+
if (!decoded || typeof decoded !== "object" || Array.isArray(decoded)) return null;
|
|
1899
|
+
return decoded;
|
|
1900
|
+
} catch {
|
|
1901
|
+
return null;
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1607
1904
|
static isTokenExpired(token) {
|
|
1608
1905
|
try {
|
|
1609
1906
|
const parts = token.split(".");
|
|
1610
1907
|
if (parts.length !== 3 || !parts[1]) return true;
|
|
1611
1908
|
const payload = JSON.parse(_TokenManager.base64Decode(parts[1]));
|
|
1612
1909
|
const now = Math.floor(Date.now() / 1e3);
|
|
1613
|
-
return payload.exp < now;
|
|
1910
|
+
return typeof payload?.exp !== "number" || payload.exp < now;
|
|
1614
1911
|
} catch {
|
|
1615
1912
|
return true;
|
|
1616
1913
|
}
|
|
@@ -1725,6 +2022,39 @@ var WalletUtils = class _WalletUtils {
|
|
|
1725
2022
|
}
|
|
1726
2023
|
}
|
|
1727
2024
|
};
|
|
2025
|
+
function isEnvelope(value) {
|
|
2026
|
+
if (!value || typeof value !== "object") return false;
|
|
2027
|
+
const r = value;
|
|
2028
|
+
return "success" in r && typeof r.success === "boolean";
|
|
2029
|
+
}
|
|
2030
|
+
function isSuccessEnvelope(value) {
|
|
2031
|
+
return isEnvelope(value) && value.success === true;
|
|
2032
|
+
}
|
|
2033
|
+
function isErrorEnvelope(value) {
|
|
2034
|
+
if (!isEnvelope(value) || value.success !== false) return false;
|
|
2035
|
+
const error = value.error;
|
|
2036
|
+
if (!error || typeof error !== "object") return false;
|
|
2037
|
+
const r = error;
|
|
2038
|
+
return typeof r.code === "string" && typeof r.message === "string";
|
|
2039
|
+
}
|
|
2040
|
+
function unwrapEnvelope(value, fallbackMessage) {
|
|
2041
|
+
if (!isEnvelope(value)) return value;
|
|
2042
|
+
if (value.success === false) {
|
|
2043
|
+
const message = isErrorEnvelope(value) ? value.error.message : void 0;
|
|
2044
|
+
throw new Error(message || fallbackMessage || "SPAPS request failed");
|
|
2045
|
+
}
|
|
2046
|
+
return value.data;
|
|
2047
|
+
}
|
|
2048
|
+
function unwrapNestedData(value) {
|
|
2049
|
+
if (isEnvelope(value) && value.success !== false) {
|
|
2050
|
+
const inner = value.data;
|
|
2051
|
+
if (inner && typeof inner === "object" && "data" in inner) {
|
|
2052
|
+
return inner.data;
|
|
2053
|
+
}
|
|
2054
|
+
return inner;
|
|
2055
|
+
}
|
|
2056
|
+
return value;
|
|
2057
|
+
}
|
|
1728
2058
|
function createBrowserClient(publishableKey, options) {
|
|
1729
2059
|
if (!publishableKey.startsWith("spaps_pub_")) {
|
|
1730
2060
|
console.warn("\u26A0\uFE0F SPAPS: Expected a publishable key (spaps_pub_xxx). Using a secret key in browser is not recommended.");
|
|
@@ -1759,6 +2089,7 @@ function detectKeyType(key) {
|
|
|
1759
2089
|
TokenManager,
|
|
1760
2090
|
WalletUtils,
|
|
1761
2091
|
WebSocketAuthHelper,
|
|
2092
|
+
X402PaymentRequiredSDKError,
|
|
1762
2093
|
canAccessAdmin,
|
|
1763
2094
|
createBrowserClient,
|
|
1764
2095
|
createPermissionChecker,
|
|
@@ -1771,7 +2102,14 @@ function detectKeyType(key) {
|
|
|
1771
2102
|
getUserRole,
|
|
1772
2103
|
hasPermission,
|
|
1773
2104
|
isAdminAccount,
|
|
2105
|
+
isEnvelope,
|
|
2106
|
+
isErrorEnvelope,
|
|
2107
|
+
isSuccessEnvelope,
|
|
2108
|
+
isX402PaymentRequired,
|
|
2109
|
+
isX402ResourceStatus,
|
|
1774
2110
|
secureMessageMetadataSchema,
|
|
1775
2111
|
secureMessageSchema,
|
|
2112
|
+
unwrapEnvelope,
|
|
2113
|
+
unwrapNestedData,
|
|
1776
2114
|
verifyCryptoWebhookSignature
|
|
1777
2115
|
});
|