spaps-sdk 1.1.2 → 1.1.3

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.mjs CHANGED
@@ -259,6 +259,30 @@ var SPAPSClient = class {
259
259
  }
260
260
  );
261
261
  }
262
+ // -------- Helper methods (for tests and convenience) --------
263
+ /** Raw API request helper that returns an ApiResponse-like shape */
264
+ async request(method, url, data, requiresAuth = false) {
265
+ try {
266
+ const config = { method, url, data };
267
+ if (requiresAuth && this.accessToken) {
268
+ config.headers = { ...config.headers || {}, Authorization: `Bearer ${this.accessToken}` };
269
+ }
270
+ const res = await this.client.request(config);
271
+ return { success: true, data: res.data };
272
+ } catch (err) {
273
+ const message = err?.response?.data?.error?.message || err?.message || "Request failed";
274
+ return Promise.reject(new Error(message));
275
+ }
276
+ }
277
+ /** Health check helper that returns boolean */
278
+ async healthCheck() {
279
+ try {
280
+ const res = await this.client.get("/health");
281
+ return Boolean(res.data?.success);
282
+ } catch {
283
+ return false;
284
+ }
285
+ }
262
286
  // Authentication Methods
263
287
  async login(email, password) {
264
288
  const response = await this.client.post("/api/auth/login", {
@@ -305,6 +329,327 @@ var SPAPSClient = class {
305
329
  async getUser() {
306
330
  return this.client.get("/api/auth/user");
307
331
  }
332
+ // -------- Facade namespaces (compat with previous SDK shape) --------
333
+ auth = {
334
+ /**
335
+ * Verify magic link token without mutating token state.
336
+ * Returns a simple success object from the API.
337
+ */
338
+ getNonce: async (walletAddress) => {
339
+ const res = await this.client.post("/api/auth/nonce", { wallet_address: walletAddress });
340
+ const body = res.data;
341
+ if (body?.success === false) throw new Error(body?.error?.message || "Failed to generate nonce");
342
+ return body?.data ?? body;
343
+ },
344
+ signInWithWallet: async (req) => {
345
+ const res = await this.client.post("/api/auth/wallet-sign-in", req);
346
+ const body = res.data;
347
+ if (body?.success === false) throw new Error(body?.error?.message || "Wallet sign-in failed");
348
+ const data = body?.data ?? body;
349
+ this.accessToken = data.access_token;
350
+ this.refreshToken = data.refresh_token;
351
+ return data;
352
+ },
353
+ authenticateWallet: async (walletAddress, signFn, chainType, username) => {
354
+ const nonce = await this.auth.getNonce(walletAddress);
355
+ const signature = await signFn(nonce.message);
356
+ return this.auth.signInWithWallet({ wallet_address: walletAddress, signature, message: nonce.message, chain_type: chainType, username });
357
+ },
358
+ signInWithPassword: async (payload) => {
359
+ const res = await this.client.post("/api/auth/login", payload);
360
+ const body = res.data;
361
+ if (body?.success === false) throw new Error(body?.error?.message || "Login failed");
362
+ const data = body?.data ?? body;
363
+ this.accessToken = data.access_token;
364
+ this.refreshToken = data.refresh_token;
365
+ return data;
366
+ },
367
+ requestMagicLink: async (payload) => {
368
+ await this.client.post("/api/auth/magic-link", payload);
369
+ },
370
+ requestPasswordReset: async (payload) => {
371
+ await this.client.post("/api/auth/password-reset", payload);
372
+ },
373
+ confirmPasswordReset: async (payload) => {
374
+ await this.client.post("/api/auth/reset-password-confirm", payload);
375
+ },
376
+ register: async (payload) => {
377
+ const res = await this.client.post("/api/auth/register", payload);
378
+ const body = res.data;
379
+ if (body?.success === false) throw new Error(body?.error?.message || "Register failed");
380
+ const data = body?.data ?? body;
381
+ this.accessToken = data.access_token;
382
+ this.refreshToken = data.refresh_token;
383
+ return data;
384
+ },
385
+ /**
386
+ * Verify a magic link token. Does not set access/refresh tokens.
387
+ * Consumers should redirect or prompt login based on the returned status.
388
+ */
389
+ verifyMagicLink: async (payload) => {
390
+ const res = await this.client.post("/api/auth/verify-magic-link", payload);
391
+ const body = res.data;
392
+ if (body?.success === false) throw new Error(body?.error?.message || "Failed to verify magic link");
393
+ return body?.data || body || { success: true };
394
+ },
395
+ solana: {
396
+ linkWallet: async (payload) => {
397
+ const res = await this.client.post("/api/auth/solana/link-wallet", payload);
398
+ return res.data;
399
+ },
400
+ verifySignature: async (payload) => {
401
+ const res = await this.client.post("/api/auth/solana/verify-signature", payload);
402
+ return res.data;
403
+ },
404
+ generateMessage: async (wallet_address) => {
405
+ const res = await this.client.get(`/api/auth/solana/generate-message/${wallet_address}`);
406
+ return res.data;
407
+ },
408
+ getWallets: async () => {
409
+ const res = await this.client.get("/api/auth/solana/wallets");
410
+ return res.data;
411
+ },
412
+ networkInfo: async () => {
413
+ const res = await this.client.get("/api/auth/solana/network-info");
414
+ return res.data;
415
+ }
416
+ },
417
+ ethereum: {
418
+ linkWallet: async (payload) => {
419
+ const res = await this.client.post("/api/auth/ethereum/link-wallet", payload);
420
+ return res.data;
421
+ },
422
+ verifySignature: async (payload) => {
423
+ const res = await this.client.post("/api/auth/ethereum/verify-signature", payload);
424
+ return res.data;
425
+ },
426
+ verifyTypedData: async (payload) => {
427
+ const res = await this.client.post("/api/auth/ethereum/verify-typed-data", payload);
428
+ return res.data;
429
+ },
430
+ generateMessage: async (wallet_address) => {
431
+ const res = await this.client.get(`/api/auth/ethereum/generate-message/${wallet_address}`);
432
+ return res.data;
433
+ },
434
+ generateTypedData: async (wallet_address) => {
435
+ const res = await this.client.get(`/api/auth/ethereum/generate-typed-data/${wallet_address}`);
436
+ return res.data;
437
+ },
438
+ getWallets: async () => {
439
+ const res = await this.client.get("/api/auth/ethereum/wallets");
440
+ return res.data;
441
+ },
442
+ networkInfo: async () => {
443
+ const res = await this.client.get("/api/auth/ethereum/network-info");
444
+ return res.data;
445
+ },
446
+ balance: async (wallet_address) => {
447
+ const res = await this.client.get(`/api/auth/ethereum/balance/${wallet_address}`);
448
+ return res.data;
449
+ },
450
+ contractCheck: async (wallet_address, contract_address) => {
451
+ const res = await this.client.get(`/api/auth/ethereum/contract-check/${wallet_address}/${contract_address}`);
452
+ return res.data;
453
+ }
454
+ },
455
+ refreshToken: async (refreshToken) => {
456
+ const res = await this.client.post("/api/auth/refresh", { refresh_token: refreshToken });
457
+ const body = res.data;
458
+ if (body?.success === false) throw new Error(body?.error?.message || "Token refresh failed");
459
+ const data = body?.data ?? body;
460
+ this.accessToken = data.access_token;
461
+ this.refreshToken = data.refresh_token;
462
+ return data;
463
+ },
464
+ /**
465
+ * Logout and clear tokens. Network errors are intentionally swallowed
466
+ * to avoid trapping users in a bad state during sign‑out flows.
467
+ */
468
+ logout: async () => {
469
+ try {
470
+ await this.client.post("/api/auth/logout");
471
+ } catch {
472
+ } finally {
473
+ this.accessToken = void 0;
474
+ this.refreshToken = void 0;
475
+ }
476
+ },
477
+ getCurrentUser: async () => {
478
+ const res = await this.client.get("/api/auth/user");
479
+ const body = res.data;
480
+ if (body?.success === false) throw new Error(body?.error?.message || "Failed to get user profile");
481
+ return body?.data?.user ?? body?.user;
482
+ },
483
+ isAuthenticated: () => !!this.accessToken
484
+ };
485
+ payments = {
486
+ createCheckoutSession: async (payload) => {
487
+ const headers = {};
488
+ if (this.accessToken) headers["Authorization"] = `Bearer ${this.accessToken}`;
489
+ const res = await this.client.post("/api/stripe/checkout-sessions", payload, { headers });
490
+ return res.data;
491
+ },
492
+ createPaymentCheckout: async (params) => {
493
+ const payload = { mode: "payment", line_items: [{ price_id: params.price_id, quantity: params.quantity ?? 1 }], success_url: params.success_url, cancel_url: params.cancel_url };
494
+ return this.payments.createCheckoutSession(payload);
495
+ },
496
+ createSubscriptionCheckout: async (params) => {
497
+ const payload = { mode: "subscription", line_items: [{ price_id: params.price_id, quantity: 1 }], success_url: params.success_url, cancel_url: params.cancel_url };
498
+ if (params.trial_period_days) payload.subscription_data = { trial_period_days: params.trial_period_days };
499
+ return this.payments.createCheckoutSession(payload);
500
+ },
501
+ getCheckoutSession: async (sessionId) => {
502
+ const res = await this.client.get(`/api/stripe/checkout-sessions/${sessionId}`);
503
+ return res.data;
504
+ },
505
+ listCheckoutSessions: async (query = {}) => {
506
+ const q = new URLSearchParams();
507
+ if (query.limit) q.append("limit", String(query.limit));
508
+ if (query.starting_after) q.append("starting_after", query.starting_after);
509
+ const res = await this.client.get(`/api/stripe/checkout-sessions${q.toString() ? `?${q.toString()}` : ""}`);
510
+ return res.data;
511
+ },
512
+ expireCheckoutSession: async (sessionId) => {
513
+ const res = await this.client.post(`/api/stripe/checkout-sessions/${sessionId}/expire`);
514
+ return res.data;
515
+ },
516
+ listProducts: async (query = {}) => {
517
+ const q = new URLSearchParams();
518
+ if (query.category) q.append("category", query.category);
519
+ if (typeof query.active === "boolean") q.append("active", String(query.active));
520
+ if (query.limit) q.append("limit", String(query.limit));
521
+ if (query.starting_after) q.append("starting_after", query.starting_after);
522
+ const headers = {};
523
+ if (this.accessToken) headers["Authorization"] = `Bearer ${this.accessToken}`;
524
+ const res = await this.client.get(`/api/stripe/products${q.toString() ? `?${q.toString()}` : ""}`, { headers });
525
+ return res.data;
526
+ },
527
+ getProduct: async (productId) => {
528
+ const headers = {};
529
+ if (this.accessToken) headers["Authorization"] = `Bearer ${this.accessToken}`;
530
+ const res = await this.client.get(`/api/stripe/products/${productId}`, { headers });
531
+ return res.data;
532
+ },
533
+ createCustomerPortalSession: async (payload) => {
534
+ const headers = {};
535
+ if (this.accessToken) headers["Authorization"] = `Bearer ${this.accessToken}`;
536
+ const res = await this.client.post("/api/stripe/portal-session", payload, { headers });
537
+ return res.data;
538
+ },
539
+ // Guest checkout helpers
540
+ createGuestCheckoutSession: async (payload) => {
541
+ const headers = {};
542
+ if (this.accessToken) headers["Authorization"] = `Bearer ${this.accessToken}`;
543
+ const res = await this.client.post("/api/stripe/guest-checkout-sessions", payload, { headers });
544
+ return res.data;
545
+ },
546
+ getGuestCheckoutSession: async (sessionId) => {
547
+ const headers = {};
548
+ if (this.accessToken) headers["Authorization"] = `Bearer ${this.accessToken}`;
549
+ const res = await this.client.get(`/api/stripe/guest-checkout-sessions/${sessionId}`, { headers });
550
+ return res.data;
551
+ },
552
+ listGuestCheckoutSessions: async (query = {}) => {
553
+ const q = new URLSearchParams();
554
+ if (query.limit) q.append("limit", String(query.limit));
555
+ if (query.starting_after) q.append("starting_after", query.starting_after);
556
+ const headers = {};
557
+ if (this.accessToken) headers["Authorization"] = `Bearer ${this.accessToken}`;
558
+ const res = await this.client.get(`/api/stripe/guest-checkout-sessions${q.toString() ? `?${q.toString()}` : ""}`, { headers });
559
+ return res.data;
560
+ },
561
+ convertGuestCheckoutSession: async (payload) => {
562
+ const headers = {};
563
+ if (this.accessToken) headers["Authorization"] = `Bearer ${this.accessToken}`;
564
+ const res = await this.client.post("/api/stripe/guest-checkout-sessions/convert", payload, { headers });
565
+ return res.data;
566
+ },
567
+ convertGuestCheckout: async (payload) => this.payments.convertGuestCheckoutSession(payload),
568
+ // Super-admin product helpers (admin token required)
569
+ listAllProductsSuperAdmin: async () => {
570
+ if (!this.accessToken) throw new Error("Authentication required. Please authenticate first.");
571
+ const res = await this.client.get("/api/stripe/products/super-admin/all", { headers: { Authorization: `Bearer ${this.accessToken}` } });
572
+ return res.data;
573
+ },
574
+ updateProductSuperAdmin: async (productId, updates) => {
575
+ if (!this.accessToken) throw new Error("Authentication required. Please authenticate first.");
576
+ const res = await this.client.put(`/api/stripe/products/super-admin/${productId}`, updates, { headers: { Authorization: `Bearer ${this.accessToken}` } });
577
+ return res.data;
578
+ },
579
+ deleteProductSuperAdmin: async (productId) => {
580
+ if (!this.accessToken) throw new Error("Authentication required. Please authenticate first.");
581
+ const res = await this.client.delete(`/api/stripe/products/super-admin/${productId}`, { headers: { Authorization: `Bearer ${this.accessToken}` } });
582
+ return res.data;
583
+ },
584
+ createProductWithPrice: async (payload) => {
585
+ if (!this.accessToken) throw new Error("Authentication required. Please authenticate first.");
586
+ const res = await this.client.post("/api/stripe/products/with-price", payload, { headers: { Authorization: `Bearer ${this.accessToken}` } });
587
+ return res.data;
588
+ },
589
+ createProductWithPriceSuperAdmin: async (productId, payload) => {
590
+ if (!this.accessToken) throw new Error("Authentication required. Please authenticate first.");
591
+ const res = await this.client.post(`/api/stripe/products/super-admin/${productId}/with-price`, payload, { headers: { Authorization: `Bearer ${this.accessToken}` } });
592
+ return res.data;
593
+ },
594
+ setDefaultPrice: async (productId, payload) => {
595
+ if (!this.accessToken) throw new Error("Authentication required. Please authenticate first.");
596
+ const res = await this.client.post(`/api/stripe/products/${productId}/default-price`, payload, { headers: { Authorization: `Bearer ${this.accessToken}` } });
597
+ return res.data;
598
+ },
599
+ setDefaultPriceSuperAdmin: async (productId, payload) => {
600
+ if (!this.accessToken) throw new Error("Authentication required. Please authenticate first.");
601
+ const res = await this.client.put(`/api/stripe/products/super-admin/${productId}/default-price`, payload, { headers: { Authorization: `Bearer ${this.accessToken}` } });
602
+ return res.data;
603
+ },
604
+ createDefaultNewPrice: async (productId, payload) => {
605
+ if (!this.accessToken) throw new Error("Authentication required. Please authenticate first.");
606
+ const res = await this.client.post(`/api/stripe/products/${productId}/prices/default-new`, payload, { headers: { Authorization: `Bearer ${this.accessToken}` } });
607
+ return res.data;
608
+ },
609
+ superAdminListAllProducts: async () => this.payments.listAllProductsSuperAdmin(),
610
+ superAdminUpdateProduct: async (productId, updates) => this.payments.updateProductSuperAdmin(productId, updates),
611
+ superAdminArchiveProduct: async (productId) => this.payments.deleteProductSuperAdmin(productId),
612
+ superAdminCreateProductWithPrice: async (applicationId, payload) => {
613
+ if (!this.accessToken) throw new Error("Authentication required. Please authenticate first.");
614
+ const res = await this.client.post(`/api/stripe/products/super-admin/${applicationId}/with-price`, payload, { headers: { Authorization: `Bearer ${this.accessToken}` } });
615
+ return res.data;
616
+ },
617
+ superAdminCreatePriceAndSetDefault: async (productId, payload) => {
618
+ if (!this.accessToken) throw new Error("Authentication required. Please authenticate first.");
619
+ const res = await this.client.post(`/api/stripe/products/super-admin/${productId}/prices/default-new`, payload, { headers: { Authorization: `Bearer ${this.accessToken}` } });
620
+ return res.data;
621
+ },
622
+ superAdminSetDefaultPrice: async (productId, payload) => this.payments.setDefaultPriceSuperAdmin(productId, payload)
623
+ };
624
+ sessions = {
625
+ getCurrent: async () => {
626
+ const res = await this.client.get("/api/sessions/current", this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0);
627
+ return res.data;
628
+ },
629
+ list: async (params = {}) => {
630
+ const q = new URLSearchParams();
631
+ if (params.limit) q.append("limit", String(params.limit));
632
+ if (params.starting_after) q.append("starting_after", params.starting_after);
633
+ const res = await this.client.get(`/api/sessions${q.toString() ? `?${q.toString()}` : ""}`, this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0);
634
+ return res.data;
635
+ },
636
+ validate: async () => {
637
+ const res = await this.client.post("/api/sessions/validate", {}, this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0);
638
+ return res.data || { valid: true };
639
+ },
640
+ revoke: async (sessionId) => {
641
+ const res = await this.client.delete(`/api/sessions/${sessionId}`, this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0);
642
+ return res.data || { revoked: true };
643
+ },
644
+ revokeAll: async () => {
645
+ const res = await this.client.delete("/api/sessions/all", this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0);
646
+ return res.data || { revoked: true };
647
+ },
648
+ touch: async () => {
649
+ const res = await this.client.post("/api/sessions/touch", {}, this.accessToken ? { headers: { Authorization: `Bearer ${this.accessToken}` } } : void 0);
650
+ return res.data || { touched: true };
651
+ }
652
+ };
308
653
  // Stripe Methods
309
654
  async createCheckoutSession(priceId, successUrl, cancelUrl) {
310
655
  return this.client.post("/api/stripe/create-checkout-session", {
@@ -434,12 +779,106 @@ var SPAPSClient = class {
434
779
  }
435
780
  };
436
781
  var index_default = SPAPSClient;
782
+ var TokenManager = class _TokenManager {
783
+ static ACCESS_TOKEN_KEY = "sweet_potato_access_token";
784
+ static REFRESH_TOKEN_KEY = "sweet_potato_refresh_token";
785
+ static USER_KEY = "sweet_potato_user";
786
+ static getStorage() {
787
+ if (typeof globalThis !== "undefined" && globalThis.localStorage) return globalThis.localStorage;
788
+ if (typeof globalThis !== "undefined" && globalThis.window?.localStorage) return globalThis.window.localStorage;
789
+ if (typeof global !== "undefined" && global.window?.localStorage) return global.window.localStorage;
790
+ return null;
791
+ }
792
+ static storeTokens(tokens) {
793
+ const s = _TokenManager.getStorage();
794
+ if (s) {
795
+ s.setItem(_TokenManager.ACCESS_TOKEN_KEY, tokens.access_token);
796
+ s.setItem(_TokenManager.REFRESH_TOKEN_KEY, tokens.refresh_token);
797
+ s.setItem(_TokenManager.USER_KEY, JSON.stringify(tokens.user));
798
+ }
799
+ }
800
+ static getAccessToken() {
801
+ const s = _TokenManager.getStorage();
802
+ return s ? s.getItem(_TokenManager.ACCESS_TOKEN_KEY) : null;
803
+ }
804
+ static getRefreshToken() {
805
+ const s = _TokenManager.getStorage();
806
+ return s ? s.getItem(_TokenManager.REFRESH_TOKEN_KEY) : null;
807
+ }
808
+ static getStoredUser() {
809
+ const s = _TokenManager.getStorage();
810
+ if (!s) return null;
811
+ const v = s.getItem(_TokenManager.USER_KEY);
812
+ return v ? JSON.parse(v) : null;
813
+ }
814
+ static clearTokens() {
815
+ const s = _TokenManager.getStorage();
816
+ if (s) {
817
+ s.removeItem(_TokenManager.ACCESS_TOKEN_KEY);
818
+ s.removeItem(_TokenManager.REFRESH_TOKEN_KEY);
819
+ s.removeItem(_TokenManager.USER_KEY);
820
+ }
821
+ }
822
+ static isTokenExpired(token) {
823
+ try {
824
+ const parts = token.split(".");
825
+ if (parts.length !== 3 || !parts[1]) return true;
826
+ const payload = JSON.parse(atob(parts[1]));
827
+ const now = Math.floor(Date.now() / 1e3);
828
+ return payload.exp < now;
829
+ } catch {
830
+ return true;
831
+ }
832
+ }
833
+ static async autoRefreshToken(sdk) {
834
+ const accessToken = _TokenManager.getAccessToken();
835
+ const refreshToken = _TokenManager.getRefreshToken();
836
+ if (!accessToken || !refreshToken) return false;
837
+ if (!_TokenManager.isTokenExpired(accessToken)) {
838
+ sdk.setAccessToken(accessToken);
839
+ return true;
840
+ }
841
+ try {
842
+ const newTokens = await sdk.auth.refreshToken(refreshToken);
843
+ _TokenManager.storeTokens(newTokens);
844
+ return true;
845
+ } catch {
846
+ _TokenManager.clearTokens();
847
+ return false;
848
+ }
849
+ }
850
+ };
851
+ var WalletUtils = class _WalletUtils {
852
+ static detectChainType(address) {
853
+ if (/^0x[a-fA-F0-9]{40}$/.test(address)) return "ethereum";
854
+ if (/^bc1[a-z0-9]{39,59}$/.test(address)) return "bitcoin";
855
+ if (/^[1-9A-HJ-NP-Za-km-z]{32}$/.test(address) || /^[1-9A-HJ-NP-Za-km-z]{44}$/.test(address)) return "solana";
856
+ if (/^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$/.test(address) && address.length >= 26 && address.length <= 35) return "bitcoin";
857
+ if (/^[1-9A-HJ-NP-Za-km-z]{35,44}$/.test(address)) return "solana";
858
+ return null;
859
+ }
860
+ static isValidAddress(address, chainType) {
861
+ if (!chainType) chainType = _WalletUtils.detectChainType(address) || "ethereum";
862
+ switch (chainType) {
863
+ case "solana":
864
+ return /^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(address);
865
+ case "ethereum":
866
+ case "base":
867
+ return /^0x[a-fA-F0-9]{40}$/.test(address);
868
+ case "bitcoin":
869
+ return /^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$/.test(address) || /^bc1[a-z0-9]{39,59}$/.test(address);
870
+ default:
871
+ return false;
872
+ }
873
+ }
874
+ };
437
875
  export {
438
876
  DEFAULT_ADMIN_ACCOUNTS,
439
877
  PermissionChecker,
440
878
  SPAPSClient as SPAPS,
441
879
  SPAPSClient,
442
- SPAPSClient as SweetPotatoSDK,
880
+ TokenManager,
881
+ WalletUtils,
443
882
  canAccessAdmin,
444
883
  createPermissionChecker,
445
884
  index_default as default,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spaps-sdk",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "Sweet Potato Authentication & Payment Service SDK - Zero-config client with built-in permission checking and role-based access control",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -34,17 +34,17 @@
34
34
  "wallet-auth"
35
35
  ],
36
36
  "author": "buildooor",
37
- "license": "MIT",
37
+ "license": "UNLICENSED",
38
38
  "repository": {
39
39
  "type": "git",
40
- "url": "https://github.com/buildooor/sweet-potato",
41
- "directory": "packages/sdk"
40
+ "url": "https://github.com/build000r"
42
41
  },
43
- "homepage": "https://github.com/buildooor/sweet-potato/tree/main/packages/sdk",
42
+ "homepage": "https://www.buildooor.com/services",
44
43
  "bugs": {
45
- "url": "https://github.com/buildooor/sweet-potato/issues"
44
+ "email": "buildooor@gmail.com"
46
45
  },
47
46
  "dependencies": {
47
+ "spaps-types": "^1.0.7",
48
48
  "axios": "^1.6.0",
49
49
  "cross-fetch": "^4.0.0"
50
50
  },