@chipi-stack/backend 13.12.0 → 14.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 Chipi Pay
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,52 @@
1
1
  # @chipi-stack/backend
2
2
 
3
- Utilities for Chipi SDKs
3
+ Server-side SDK for Chipi Pay. Handles wallet creation, transactions, SKU purchases, and exchanges.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @chipi-stack/backend
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { ChipiSDK } from "@chipi-stack/backend";
15
+
16
+ const sdk = new ChipiSDK({
17
+ apiPublicKey: process.env.CHIPI_API_PUBLIC_KEY!,
18
+ apiSecretKey: process.env.CHIPI_API_SECRET_KEY!,
19
+ });
20
+
21
+ const bearerToken = "your-bearer-token"; // From your auth provider (e.g., Clerk)
22
+
23
+ // Create a wallet
24
+ const wallet = await sdk.createWallet({
25
+ params: {
26
+ externalUserId: "user-123",
27
+ chain: "STARKNET",
28
+ encryptKey: "user-pin-or-passkey",
29
+ },
30
+ bearerToken,
31
+ });
32
+
33
+ // Transfer USDC
34
+ const tx = await sdk.transfer({
35
+ params: {
36
+ wallet: wallet.wallet,
37
+ token: "USDC",
38
+ recipient: "0x...",
39
+ amount: 10,
40
+ encryptKey: "user-pin-or-passkey",
41
+ },
42
+ bearerToken,
43
+ });
44
+ ```
45
+
46
+ ## Documentation
47
+
48
+ Full docs at [docs.chipipay.com](https://docs.chipipay.com)
49
+
50
+ ## License
51
+
52
+ MIT
@@ -36,6 +36,11 @@ declare class ChipiClient {
36
36
  bearerToken: string;
37
37
  body?: Record<string, any>;
38
38
  }): Promise<T>;
39
+ patch<T>({ endpoint, bearerToken, body, }: {
40
+ endpoint: string;
41
+ bearerToken: string;
42
+ body?: Record<string, any>;
43
+ }): Promise<T>;
39
44
  delete<T>({ endpoint, bearerToken, }: {
40
45
  endpoint: string;
41
46
  bearerToken: string;
@@ -36,6 +36,11 @@ declare class ChipiClient {
36
36
  bearerToken: string;
37
37
  body?: Record<string, any>;
38
38
  }): Promise<T>;
39
+ patch<T>({ endpoint, bearerToken, body, }: {
40
+ endpoint: string;
41
+ bearerToken: string;
42
+ body?: Record<string, any>;
43
+ }): Promise<T>;
39
44
  delete<T>({ endpoint, bearerToken, }: {
40
45
  endpoint: string;
41
46
  bearerToken: string;
package/dist/index.d.mts CHANGED
@@ -6,7 +6,7 @@ import { ChipiWallets } from './wallets.mjs';
6
6
  import { ChipiTransactions } from './transactions.mjs';
7
7
  import { ChipiSkuPurchases } from './skuPurchases.mjs';
8
8
  import { ChipiSkus } from './skus.mjs';
9
- import { C as ChipiClient } from './client-43S3tkH3.mjs';
9
+ import { C as ChipiClient } from './client-CqD_yGH0.mjs';
10
10
 
11
11
  /**
12
12
  * Session key management for CHIPI wallets (SNIP-9 compatible).
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@ import { ChipiWallets } from './wallets.js';
6
6
  import { ChipiTransactions } from './transactions.js';
7
7
  import { ChipiSkuPurchases } from './skuPurchases.js';
8
8
  import { ChipiSkus } from './skus.js';
9
- import { C as ChipiClient } from './client-43S3tkH3.js';
9
+ import { C as ChipiClient } from './client-CqD_yGH0.js';
10
10
 
11
11
  /**
12
12
  * Session key management for CHIPI wallets (SNIP-9 compatible).
package/dist/index.js CHANGED
@@ -19,7 +19,7 @@ var ChipiClient = class {
19
19
  this.customAlphaUrl = config.alphaUrl;
20
20
  this.baseUrl = this.getBaseUrl();
21
21
  this.nodeUrl = config.nodeUrl || shared.STARKNET_NETWORKS.MAINNET;
22
- this.sdkVersion = "11.21.0";
22
+ this.sdkVersion = "14.0.0";
23
23
  }
24
24
  /**
25
25
  * Get the API public key (for internal SDK use)
@@ -30,7 +30,7 @@ var ChipiClient = class {
30
30
  getBaseUrl() {
31
31
  const version = `v${shared.API_VERSIONING.VERSION}`;
32
32
  if (this.customAlphaUrl) {
33
- const cleanUrl = this.customAlphaUrl.replace(/\/v\d+$/, "").replace(/\/$/, "");
33
+ const cleanUrl = this.customAlphaUrl.replace(/\/v\d+\/?$/, "").replace(/\/$/, "");
34
34
  return `${cleanUrl}/${version}`;
35
35
  }
36
36
  return `https://celebrated-vision-production-66a5.up.railway.app/${version}`;
@@ -100,7 +100,6 @@ var ChipiClient = class {
100
100
  });
101
101
  const data = await response.json();
102
102
  if (!response.ok) {
103
- console.error("there was an error", data);
104
103
  const errorData = shared.validateErrorResponse(data);
105
104
  throw new shared.ChipiApiError(
106
105
  errorData.message,
@@ -140,6 +139,33 @@ var ChipiClient = class {
140
139
  throw shared.handleApiError(error);
141
140
  }
142
141
  }
142
+ async patch({
143
+ endpoint,
144
+ bearerToken,
145
+ body
146
+ }) {
147
+ try {
148
+ const url = new URL(`${this.baseUrl}${endpoint}`);
149
+ this.addVersionParams(url);
150
+ const response = await fetch(url.toString(), {
151
+ method: "PATCH",
152
+ headers: this.getHeaders(bearerToken),
153
+ body: body ? JSON.stringify(body) : void 0
154
+ });
155
+ const data = await response.json();
156
+ if (!response.ok) {
157
+ const errorData = shared.validateErrorResponse(data);
158
+ throw new shared.ChipiApiError(
159
+ errorData.message,
160
+ errorData.code || `HTTP_${response.status}`,
161
+ response.status
162
+ );
163
+ }
164
+ return data;
165
+ } catch (error) {
166
+ throw shared.handleApiError(error);
167
+ }
168
+ }
143
169
  async delete({
144
170
  endpoint,
145
171
  bearerToken
@@ -167,16 +193,26 @@ var ChipiClient = class {
167
193
  }
168
194
  };
169
195
  var encryptPrivateKey = (privateKey, password) => {
196
+ if (!privateKey || !password) {
197
+ throw new Error("Private key and password are required");
198
+ }
170
199
  return CryptoES__default.default.AES.encrypt(privateKey, password).toString();
171
200
  };
172
201
  var decryptPrivateKey = (encryptedPrivateKey, password) => {
202
+ if (!encryptedPrivateKey || !password) {
203
+ throw new Error("Encrypted private key and password are required");
204
+ }
173
205
  try {
174
206
  const bytes = CryptoES__default.default.AES.decrypt(encryptedPrivateKey, password);
175
207
  const decrypted = bytes.toString(CryptoES__default.default.enc.Utf8);
176
- if (!decrypted) throw new Error("Decryption failed");
208
+ if (!decrypted) {
209
+ throw new Error("Decryption resulted in empty string");
210
+ }
177
211
  return decrypted;
178
212
  } catch (error) {
179
- console.error("Decryption failed:", error);
213
+ if (error instanceof Error) {
214
+ throw error;
215
+ }
180
216
  throw new Error(`Decryption failed: ${error}`);
181
217
  }
182
218
  };
@@ -221,10 +257,7 @@ var ChipiWallets = class {
221
257
  const privateKeyAX = this.getPrivateKeyAX();
222
258
  const starkKeyPubAX = starknet.ec.starkCurve.getStarkKey(privateKeyAX);
223
259
  const accountClassHash = walletType === "READY" ? shared.WALLET_CLASS_HASHES.READY : shared.WALLET_CLASS_HASHES.CHIPI;
224
- const constructorCallData = this.buildConstructorCallData(
225
- walletType,
226
- starkKeyPubAX
227
- );
260
+ const constructorCallData = this.buildConstructorCallData(walletType, starkKeyPubAX);
228
261
  const publicKey = starknet.hash.calculateContractAddressFromHash(
229
262
  starkKeyPubAX,
230
263
  accountClassHash,
@@ -336,8 +369,22 @@ var ChipiWallets = class {
336
369
  if (err instanceof shared.ChipiApiError && err.status === 404) {
337
370
  return null;
338
371
  }
339
- throw new Error(`getWallet error: ${String(err)}`);
372
+ throw err;
373
+ }
374
+ }
375
+ async updateWalletEncryption(params, bearerToken) {
376
+ const body = {
377
+ externalUserId: params.externalUserId,
378
+ newEncryptedPrivateKey: params.newEncryptedPrivateKey
379
+ };
380
+ if (params.publicKey != null) {
381
+ body.publicKey = params.publicKey;
340
382
  }
383
+ return this.client.patch({
384
+ endpoint: `${shared.API_ENDPOINTS.CHIPI_WALLETS}/update-encryption-details`,
385
+ bearerToken,
386
+ body
387
+ });
341
388
  }
342
389
  async getTokenBalance({
343
390
  params,
@@ -365,12 +412,11 @@ var executePaymasterTransaction = async ({
365
412
  }
366
413
  const rpcUrl = shared.WALLET_RPC_ENDPOINTS.READY;
367
414
  const accountClassHash = shared.WALLET_CLASS_HASHES.READY;
368
- const privateKeyDecrypted = decryptPrivateKey(
369
- wallet.encryptedPrivateKey,
370
- encryptKey
371
- );
372
- if (!privateKeyDecrypted) {
373
- throw new Error("Failed to decrypt private key");
415
+ let privateKeyDecrypted;
416
+ try {
417
+ privateKeyDecrypted = decryptPrivateKey(wallet.encryptedPrivateKey, encryptKey);
418
+ } catch {
419
+ throw new Error("Failed to decrypt private key. Verify the encryptKey is correct.");
374
420
  }
375
421
  const provider = new starknet.RpcProvider({ nodeUrl: rpcUrl });
376
422
  const account = new starknet.Account({
@@ -443,16 +489,13 @@ var executePaymasterTransactionWithSession = async ({
443
489
  }) => {
444
490
  const { encryptKey, wallet, session, calls, saveToDatabase } = params;
445
491
  if (wallet.walletType !== "CHIPI") {
446
- console.error(
447
- "[ChipiSDK:Session:Execute] Invalid wallet type for session execution",
448
- {
449
- provided: wallet.walletType,
450
- required: "CHIPI",
451
- expectedClassHash: shared.WALLET_CLASS_HASHES.CHIPI,
452
- walletAddress: wallet.publicKey?.slice(0, 15) + "...",
453
- hint: "Session keys only work with CHIPI wallets (SNIP-9 compatible)"
454
- }
455
- );
492
+ console.error("[ChipiSDK:Session:Execute] Invalid wallet type for session execution", {
493
+ provided: wallet.walletType,
494
+ required: "CHIPI",
495
+ expectedClassHash: shared.WALLET_CLASS_HASHES.CHIPI,
496
+ walletAddress: wallet.publicKey?.slice(0, 15) + "...",
497
+ hint: "Session keys only work with CHIPI wallets (SNIP-9 compatible)"
498
+ });
456
499
  throw new shared.ChipiSessionError(
457
500
  `Session execution requires CHIPI wallet type. Got: "${wallet.walletType || "undefined"}"`,
458
501
  shared.SESSION_ERRORS.INVALID_WALLET_TYPE_FOR_SESSION
@@ -471,18 +514,14 @@ var executePaymasterTransactionWithSession = async ({
471
514
  );
472
515
  }
473
516
  try {
474
- const sessionPrivateKey = decryptPrivateKey(
475
- session.encryptedPrivateKey,
476
- encryptKey
477
- );
478
- if (!sessionPrivateKey) {
479
- console.error(
480
- "[ChipiSDK:Session:Execute] Failed to decrypt session private key",
481
- {
482
- sessionPubKey: session.publicKey?.slice(0, 15) + "...",
483
- hint: "Ensure the encryptKey matches the one used when creating the session"
484
- }
485
- );
517
+ let sessionPrivateKey;
518
+ try {
519
+ sessionPrivateKey = decryptPrivateKey(session.encryptedPrivateKey, encryptKey);
520
+ } catch {
521
+ console.error("[ChipiSDK:Session:Execute] Failed to decrypt session private key", {
522
+ sessionPubKey: session.publicKey?.slice(0, 15) + "...",
523
+ hint: "Ensure the encryptKey matches the one used when creating the session"
524
+ });
486
525
  throw new shared.ChipiSessionError(
487
526
  "Failed to decrypt session private key. Verify the encryptKey is correct.",
488
527
  shared.SESSION_ERRORS.SESSION_DECRYPTION_FAILED
@@ -534,12 +573,9 @@ var executePaymasterTransactionWithSession = async ({
534
573
  }
535
574
  });
536
575
  if (!result.transactionHash) {
537
- console.error(
538
- "[ChipiSDK:Session:Execute] No transaction hash in response",
539
- {
540
- result
541
- }
542
- );
576
+ console.error("[ChipiSDK:Session:Execute] No transaction hash in response", {
577
+ result
578
+ });
543
579
  throw new Error("Response does not contain transaction hash");
544
580
  }
545
581
  return result.transactionHash;
@@ -706,32 +742,21 @@ var ChipiSkuPurchases = class {
706
742
  * @returns Promise<SkuPurchaseResponse> - The purchase response with transaction details
707
743
  */
708
744
  async purchaseSku(params, bearerToken) {
709
- const {
710
- skuId,
711
- skuReference,
712
- currencyAmount,
713
- currency,
714
- chain,
715
- token,
716
- encryptKey,
717
- wallet
718
- } = params;
719
- const usdAmount = await this.exchanges.getUsdAmount(
720
- currencyAmount,
721
- currency,
722
- bearerToken
723
- );
724
- const tokenAddress = types.STARKNET_CONTRACTS[token].contractAddress;
725
- if (usdAmount <= 0) {
726
- throw new Error(
727
- `Invalid USD amount: ${usdAmount}. Amount must be positive.`
728
- );
745
+ const { skuId, skuReference, currencyAmount, currency, chain, token, encryptKey, wallet } = params;
746
+ if (chain !== types.Chain.STARKNET) {
747
+ throw new Error(`Unsupported chain for SKU purchases: ${chain}`);
748
+ }
749
+ const tokenConfig = types.STARKNET_CONTRACTS[token];
750
+ if (!tokenConfig?.contractAddress) {
751
+ throw new Error(`Unsupported token for Starknet SKU purchases: ${token}`);
752
+ }
753
+ const usdAmount = await this.exchanges.getUsdAmount(currencyAmount, currency, bearerToken);
754
+ const tokenAddress = tokenConfig.contractAddress;
755
+ if (!Number.isFinite(usdAmount) || usdAmount <= 0) {
756
+ throw new Error(`Invalid USD amount: ${usdAmount}. Amount must be positive.`);
729
757
  }
730
758
  const minUsdAmount = Math.max(usdAmount, 1e-6);
731
- const parsedAmount = shared.formatAmount(
732
- minUsdAmount.toString(),
733
- types.STARKNET_CONTRACTS[token].decimals
734
- );
759
+ const parsedAmount = shared.formatAmount(minUsdAmount.toString(), tokenConfig.decimals);
735
760
  const calls = [
736
761
  {
737
762
  contractAddress: tokenAddress,
@@ -893,6 +918,12 @@ var ChipiSessions = class {
893
918
  */
894
919
  createSessionKey(params) {
895
920
  const { encryptKey, durationSeconds = shared.SESSION_DEFAULTS.DURATION_SECONDS } = params;
921
+ if (typeof durationSeconds !== "number" || !Number.isFinite(durationSeconds) || !Number.isInteger(durationSeconds) || durationSeconds <= 0) {
922
+ throw new shared.ChipiSessionError(
923
+ `Invalid session duration: ${durationSeconds}. Must be a positive integer.`,
924
+ shared.SESSION_ERRORS.SESSION_CREATION_FAILED
925
+ );
926
+ }
896
927
  try {
897
928
  const rawPrivateKey = starknet.ec.starkCurve.utils.randomPrivateKey();
898
929
  const privateKeyHex = this.toHex(rawPrivateKey);
@@ -906,13 +937,10 @@ var ChipiSessions = class {
906
937
  };
907
938
  } catch (error) {
908
939
  const err = error instanceof Error ? error : new Error(String(error));
909
- console.error(
910
- "[ChipiSDK:Session:Create] Failed to generate session key",
911
- {
912
- error: err.message,
913
- durationRequested: durationSeconds
914
- }
915
- );
940
+ console.error("[ChipiSDK:Session:Create] Failed to generate session key", {
941
+ error: err.message,
942
+ durationRequested: durationSeconds
943
+ });
916
944
  throw new shared.ChipiSessionError(
917
945
  `Failed to create session key: ${err.message}`,
918
946
  shared.SESSION_ERRORS.SESSION_CREATION_FAILED
@@ -947,22 +975,15 @@ var ChipiSessions = class {
947
975
  */
948
976
  async addSessionKeyToContract(params, bearerToken) {
949
977
  const { encryptKey, wallet, sessionConfig } = params;
950
- this.validateChipiWallet(
951
- wallet.walletType,
952
- "AddToContract",
953
- wallet.publicKey
954
- );
978
+ this.validateChipiWallet(wallet.walletType, "AddToContract", wallet.publicKey);
955
979
  try {
956
- console.log(
957
- "[ChipiSDK:Session:AddToContract] Registering session on-chain",
958
- {
959
- walletAddress: wallet.publicKey.slice(0, 15) + "...",
960
- sessionPubKey: sessionConfig.sessionPublicKey.slice(0, 15) + "...",
961
- validUntil: new Date(sessionConfig.validUntil * 1e3).toISOString(),
962
- maxCalls: sessionConfig.maxCalls,
963
- allowedEntrypoints: sessionConfig.allowedEntrypoints.length
964
- }
965
- );
980
+ console.log("[ChipiSDK:Session:AddToContract] Registering session on-chain", {
981
+ walletAddress: wallet.publicKey.slice(0, 15) + "...",
982
+ sessionPubKey: sessionConfig.sessionPublicKey.slice(0, 15) + "...",
983
+ validUntil: new Date(sessionConfig.validUntil * 1e3).toISOString(),
984
+ maxCalls: sessionConfig.maxCalls,
985
+ allowedEntrypoints: sessionConfig.allowedEntrypoints.length
986
+ });
966
987
  const calldata = [
967
988
  sessionConfig.sessionPublicKey,
968
989
  starknet.num.toHex(sessionConfig.validUntil),
@@ -988,13 +1009,10 @@ var ChipiSessions = class {
988
1009
  bearerToken,
989
1010
  client: this.client
990
1011
  });
991
- console.log(
992
- "[ChipiSDK:Session:AddToContract] Session registered successfully",
993
- {
994
- txHash,
995
- sessionPubKey: sessionConfig.sessionPublicKey.slice(0, 15) + "..."
996
- }
997
- );
1012
+ console.log("[ChipiSDK:Session:AddToContract] Session registered successfully", {
1013
+ txHash,
1014
+ sessionPubKey: sessionConfig.sessionPublicKey.slice(0, 15) + "..."
1015
+ });
998
1016
  return txHash;
999
1017
  } catch (error) {
1000
1018
  const err = error instanceof Error ? error : new Error(String(error));
@@ -1142,17 +1160,33 @@ var ChipiSessions = class {
1142
1160
  return sessionData;
1143
1161
  } catch (error) {
1144
1162
  const err = error instanceof Error ? error : new Error(String(error));
1145
- console.error("[ChipiSDK:Session:GetData] Query failed", {
1163
+ const sessionNotFoundPatterns = [
1164
+ /entry point.*not found/i,
1165
+ /requested entrypoint was not found/i,
1166
+ /invalid message selector/i,
1167
+ /contract not found/i,
1168
+ /is not deployed/i,
1169
+ /revert.*get_session_data/i
1170
+ ];
1171
+ const isSessionNotFound = sessionNotFoundPatterns.some((p) => p.test(err.message));
1172
+ if (isSessionNotFound) {
1173
+ console.log("[ChipiSDK:Session:GetData] Session not found on contract", {
1174
+ walletAddress: walletAddress?.slice(0, 15) + "...",
1175
+ sessionPubKey: sessionPublicKey?.slice(0, 15) + "..."
1176
+ });
1177
+ return {
1178
+ isActive: false,
1179
+ validUntil: 0,
1180
+ remainingCalls: 0,
1181
+ allowedEntrypoints: []
1182
+ };
1183
+ }
1184
+ console.error("[ChipiSDK:Session:GetData] RPC/network error", {
1146
1185
  error: err.message,
1147
1186
  walletAddress: walletAddress?.slice(0, 15) + "...",
1148
1187
  sessionPubKey: sessionPublicKey?.slice(0, 15) + "..."
1149
1188
  });
1150
- return {
1151
- isActive: false,
1152
- validUntil: 0,
1153
- remainingCalls: 0,
1154
- allowedEntrypoints: []
1155
- };
1189
+ throw err;
1156
1190
  }
1157
1191
  }
1158
1192
  /**
@@ -1365,7 +1399,6 @@ var ChipiSDK = class {
1365
1399
  params,
1366
1400
  bearerToken
1367
1401
  }) {
1368
- console.log("createWallet params:", params);
1369
1402
  return this.wallets.createWallet({
1370
1403
  ...params,
1371
1404
  bearerToken: this.resolveBearerToken(bearerToken)
@@ -1381,10 +1414,7 @@ var ChipiSDK = class {
1381
1414
  });
1382
1415
  }
1383
1416
  async getTransactionList(query, bearerToken) {
1384
- return this.transactions.getTransactionList(
1385
- query,
1386
- this.resolveBearerToken(bearerToken)
1387
- );
1417
+ return this.transactions.getTransactionList(query, this.resolveBearerToken(bearerToken));
1388
1418
  }
1389
1419
  async getWallet(params, bearerToken) {
1390
1420
  return this.wallets.getWallet(params, this.resolveBearerToken(bearerToken));
@@ -1402,19 +1432,13 @@ var ChipiSDK = class {
1402
1432
  params,
1403
1433
  bearerToken
1404
1434
  }) {
1405
- return this.skuPurchases.purchaseSku(
1406
- params,
1407
- this.resolveBearerToken(bearerToken)
1408
- );
1435
+ return this.skuPurchases.purchaseSku(params, this.resolveBearerToken(bearerToken));
1409
1436
  }
1410
1437
  /**
1411
1438
  * Get a SKU purchase by id
1412
1439
  */
1413
1440
  async getSkuPurchase(id, bearerToken) {
1414
- return this.skuPurchases.getSkuPurchase(
1415
- id,
1416
- this.resolveBearerToken(bearerToken)
1417
- );
1441
+ return this.skuPurchases.getSkuPurchase(id, this.resolveBearerToken(bearerToken));
1418
1442
  }
1419
1443
  /// SKUS
1420
1444
  async getSkuList(params, bearerToken) {