@chipi-stack/backend 13.13.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/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { isValidApiKey, ChipiAuthError, STARKNET_NETWORKS, API_VERSIONING, validateErrorResponse, ChipiApiError, handleApiError, WALLET_RPC_ENDPOINTS, WALLET_CLASS_HASHES, API_ENDPOINTS, ChipiTransactionError, formatAmount, SKU_CONTRACTS, CARRIER_IDS, SERVICE_TYPES, ChipiSessionError, SESSION_ERRORS, SESSION_DEFAULTS, SESSION_ENTRYPOINTS } from '@chipi-stack/shared';
2
2
  import CryptoES from 'crypto-es';
3
3
  import { RpcProvider, ec, hash, Account, num, CairoCustomEnum, CairoOption, CairoOptionVariant, CallData, cairo, typedData } from 'starknet';
4
- import { STARKNET_CONTRACTS } from '@chipi-stack/types';
4
+ import { STARKNET_CONTRACTS, Chain } from '@chipi-stack/types';
5
5
  export { Chain, ChainToken } from '@chipi-stack/types';
6
6
 
7
7
  // src/chipi-sdk.ts
@@ -14,7 +14,7 @@ var ChipiClient = class {
14
14
  this.customAlphaUrl = config.alphaUrl;
15
15
  this.baseUrl = this.getBaseUrl();
16
16
  this.nodeUrl = config.nodeUrl || STARKNET_NETWORKS.MAINNET;
17
- this.sdkVersion = "11.21.0";
17
+ this.sdkVersion = "14.0.0";
18
18
  }
19
19
  /**
20
20
  * Get the API public key (for internal SDK use)
@@ -25,7 +25,7 @@ var ChipiClient = class {
25
25
  getBaseUrl() {
26
26
  const version = `v${API_VERSIONING.VERSION}`;
27
27
  if (this.customAlphaUrl) {
28
- const cleanUrl = this.customAlphaUrl.replace(/\/v\d+$/, "").replace(/\/$/, "");
28
+ const cleanUrl = this.customAlphaUrl.replace(/\/v\d+\/?$/, "").replace(/\/$/, "");
29
29
  return `${cleanUrl}/${version}`;
30
30
  }
31
31
  return `https://celebrated-vision-production-66a5.up.railway.app/${version}`;
@@ -95,7 +95,6 @@ var ChipiClient = class {
95
95
  });
96
96
  const data = await response.json();
97
97
  if (!response.ok) {
98
- console.error("there was an error", data);
99
98
  const errorData = validateErrorResponse(data);
100
99
  throw new ChipiApiError(
101
100
  errorData.message,
@@ -189,16 +188,26 @@ var ChipiClient = class {
189
188
  }
190
189
  };
191
190
  var encryptPrivateKey = (privateKey, password) => {
191
+ if (!privateKey || !password) {
192
+ throw new Error("Private key and password are required");
193
+ }
192
194
  return CryptoES.AES.encrypt(privateKey, password).toString();
193
195
  };
194
196
  var decryptPrivateKey = (encryptedPrivateKey, password) => {
197
+ if (!encryptedPrivateKey || !password) {
198
+ throw new Error("Encrypted private key and password are required");
199
+ }
195
200
  try {
196
201
  const bytes = CryptoES.AES.decrypt(encryptedPrivateKey, password);
197
202
  const decrypted = bytes.toString(CryptoES.enc.Utf8);
198
- if (!decrypted) throw new Error("Decryption failed");
203
+ if (!decrypted) {
204
+ throw new Error("Decryption resulted in empty string");
205
+ }
199
206
  return decrypted;
200
207
  } catch (error) {
201
- console.error("Decryption failed:", error);
208
+ if (error instanceof Error) {
209
+ throw error;
210
+ }
202
211
  throw new Error(`Decryption failed: ${error}`);
203
212
  }
204
213
  };
@@ -243,10 +252,7 @@ var ChipiWallets = class {
243
252
  const privateKeyAX = this.getPrivateKeyAX();
244
253
  const starkKeyPubAX = ec.starkCurve.getStarkKey(privateKeyAX);
245
254
  const accountClassHash = walletType === "READY" ? WALLET_CLASS_HASHES.READY : WALLET_CLASS_HASHES.CHIPI;
246
- const constructorCallData = this.buildConstructorCallData(
247
- walletType,
248
- starkKeyPubAX
249
- );
255
+ const constructorCallData = this.buildConstructorCallData(walletType, starkKeyPubAX);
250
256
  const publicKey = hash.calculateContractAddressFromHash(
251
257
  starkKeyPubAX,
252
258
  accountClassHash,
@@ -358,7 +364,7 @@ var ChipiWallets = class {
358
364
  if (err instanceof ChipiApiError && err.status === 404) {
359
365
  return null;
360
366
  }
361
- throw new Error(`getWallet error: ${String(err)}`);
367
+ throw err;
362
368
  }
363
369
  }
364
370
  async updateWalletEncryption(params, bearerToken) {
@@ -401,12 +407,11 @@ var executePaymasterTransaction = async ({
401
407
  }
402
408
  const rpcUrl = WALLET_RPC_ENDPOINTS.READY;
403
409
  const accountClassHash = WALLET_CLASS_HASHES.READY;
404
- const privateKeyDecrypted = decryptPrivateKey(
405
- wallet.encryptedPrivateKey,
406
- encryptKey
407
- );
408
- if (!privateKeyDecrypted) {
409
- throw new Error("Failed to decrypt private key");
410
+ let privateKeyDecrypted;
411
+ try {
412
+ privateKeyDecrypted = decryptPrivateKey(wallet.encryptedPrivateKey, encryptKey);
413
+ } catch {
414
+ throw new Error("Failed to decrypt private key. Verify the encryptKey is correct.");
410
415
  }
411
416
  const provider = new RpcProvider({ nodeUrl: rpcUrl });
412
417
  const account = new Account({
@@ -479,16 +484,13 @@ var executePaymasterTransactionWithSession = async ({
479
484
  }) => {
480
485
  const { encryptKey, wallet, session, calls, saveToDatabase } = params;
481
486
  if (wallet.walletType !== "CHIPI") {
482
- console.error(
483
- "[ChipiSDK:Session:Execute] Invalid wallet type for session execution",
484
- {
485
- provided: wallet.walletType,
486
- required: "CHIPI",
487
- expectedClassHash: WALLET_CLASS_HASHES.CHIPI,
488
- walletAddress: wallet.publicKey?.slice(0, 15) + "...",
489
- hint: "Session keys only work with CHIPI wallets (SNIP-9 compatible)"
490
- }
491
- );
487
+ console.error("[ChipiSDK:Session:Execute] Invalid wallet type for session execution", {
488
+ provided: wallet.walletType,
489
+ required: "CHIPI",
490
+ expectedClassHash: WALLET_CLASS_HASHES.CHIPI,
491
+ walletAddress: wallet.publicKey?.slice(0, 15) + "...",
492
+ hint: "Session keys only work with CHIPI wallets (SNIP-9 compatible)"
493
+ });
492
494
  throw new ChipiSessionError(
493
495
  `Session execution requires CHIPI wallet type. Got: "${wallet.walletType || "undefined"}"`,
494
496
  SESSION_ERRORS.INVALID_WALLET_TYPE_FOR_SESSION
@@ -507,18 +509,14 @@ var executePaymasterTransactionWithSession = async ({
507
509
  );
508
510
  }
509
511
  try {
510
- const sessionPrivateKey = decryptPrivateKey(
511
- session.encryptedPrivateKey,
512
- encryptKey
513
- );
514
- if (!sessionPrivateKey) {
515
- console.error(
516
- "[ChipiSDK:Session:Execute] Failed to decrypt session private key",
517
- {
518
- sessionPubKey: session.publicKey?.slice(0, 15) + "...",
519
- hint: "Ensure the encryptKey matches the one used when creating the session"
520
- }
521
- );
512
+ let sessionPrivateKey;
513
+ try {
514
+ sessionPrivateKey = decryptPrivateKey(session.encryptedPrivateKey, encryptKey);
515
+ } catch {
516
+ console.error("[ChipiSDK:Session:Execute] Failed to decrypt session private key", {
517
+ sessionPubKey: session.publicKey?.slice(0, 15) + "...",
518
+ hint: "Ensure the encryptKey matches the one used when creating the session"
519
+ });
522
520
  throw new ChipiSessionError(
523
521
  "Failed to decrypt session private key. Verify the encryptKey is correct.",
524
522
  SESSION_ERRORS.SESSION_DECRYPTION_FAILED
@@ -570,12 +568,9 @@ var executePaymasterTransactionWithSession = async ({
570
568
  }
571
569
  });
572
570
  if (!result.transactionHash) {
573
- console.error(
574
- "[ChipiSDK:Session:Execute] No transaction hash in response",
575
- {
576
- result
577
- }
578
- );
571
+ console.error("[ChipiSDK:Session:Execute] No transaction hash in response", {
572
+ result
573
+ });
579
574
  throw new Error("Response does not contain transaction hash");
580
575
  }
581
576
  return result.transactionHash;
@@ -742,32 +737,21 @@ var ChipiSkuPurchases = class {
742
737
  * @returns Promise<SkuPurchaseResponse> - The purchase response with transaction details
743
738
  */
744
739
  async purchaseSku(params, bearerToken) {
745
- const {
746
- skuId,
747
- skuReference,
748
- currencyAmount,
749
- currency,
750
- chain,
751
- token,
752
- encryptKey,
753
- wallet
754
- } = params;
755
- const usdAmount = await this.exchanges.getUsdAmount(
756
- currencyAmount,
757
- currency,
758
- bearerToken
759
- );
760
- const tokenAddress = STARKNET_CONTRACTS[token].contractAddress;
761
- if (usdAmount <= 0) {
762
- throw new Error(
763
- `Invalid USD amount: ${usdAmount}. Amount must be positive.`
764
- );
740
+ const { skuId, skuReference, currencyAmount, currency, chain, token, encryptKey, wallet } = params;
741
+ if (chain !== Chain.STARKNET) {
742
+ throw new Error(`Unsupported chain for SKU purchases: ${chain}`);
743
+ }
744
+ const tokenConfig = STARKNET_CONTRACTS[token];
745
+ if (!tokenConfig?.contractAddress) {
746
+ throw new Error(`Unsupported token for Starknet SKU purchases: ${token}`);
747
+ }
748
+ const usdAmount = await this.exchanges.getUsdAmount(currencyAmount, currency, bearerToken);
749
+ const tokenAddress = tokenConfig.contractAddress;
750
+ if (!Number.isFinite(usdAmount) || usdAmount <= 0) {
751
+ throw new Error(`Invalid USD amount: ${usdAmount}. Amount must be positive.`);
765
752
  }
766
753
  const minUsdAmount = Math.max(usdAmount, 1e-6);
767
- const parsedAmount = formatAmount(
768
- minUsdAmount.toString(),
769
- STARKNET_CONTRACTS[token].decimals
770
- );
754
+ const parsedAmount = formatAmount(minUsdAmount.toString(), tokenConfig.decimals);
771
755
  const calls = [
772
756
  {
773
757
  contractAddress: tokenAddress,
@@ -929,6 +913,12 @@ var ChipiSessions = class {
929
913
  */
930
914
  createSessionKey(params) {
931
915
  const { encryptKey, durationSeconds = SESSION_DEFAULTS.DURATION_SECONDS } = params;
916
+ if (typeof durationSeconds !== "number" || !Number.isFinite(durationSeconds) || !Number.isInteger(durationSeconds) || durationSeconds <= 0) {
917
+ throw new ChipiSessionError(
918
+ `Invalid session duration: ${durationSeconds}. Must be a positive integer.`,
919
+ SESSION_ERRORS.SESSION_CREATION_FAILED
920
+ );
921
+ }
932
922
  try {
933
923
  const rawPrivateKey = ec.starkCurve.utils.randomPrivateKey();
934
924
  const privateKeyHex = this.toHex(rawPrivateKey);
@@ -942,13 +932,10 @@ var ChipiSessions = class {
942
932
  };
943
933
  } catch (error) {
944
934
  const err = error instanceof Error ? error : new Error(String(error));
945
- console.error(
946
- "[ChipiSDK:Session:Create] Failed to generate session key",
947
- {
948
- error: err.message,
949
- durationRequested: durationSeconds
950
- }
951
- );
935
+ console.error("[ChipiSDK:Session:Create] Failed to generate session key", {
936
+ error: err.message,
937
+ durationRequested: durationSeconds
938
+ });
952
939
  throw new ChipiSessionError(
953
940
  `Failed to create session key: ${err.message}`,
954
941
  SESSION_ERRORS.SESSION_CREATION_FAILED
@@ -983,22 +970,15 @@ var ChipiSessions = class {
983
970
  */
984
971
  async addSessionKeyToContract(params, bearerToken) {
985
972
  const { encryptKey, wallet, sessionConfig } = params;
986
- this.validateChipiWallet(
987
- wallet.walletType,
988
- "AddToContract",
989
- wallet.publicKey
990
- );
973
+ this.validateChipiWallet(wallet.walletType, "AddToContract", wallet.publicKey);
991
974
  try {
992
- console.log(
993
- "[ChipiSDK:Session:AddToContract] Registering session on-chain",
994
- {
995
- walletAddress: wallet.publicKey.slice(0, 15) + "...",
996
- sessionPubKey: sessionConfig.sessionPublicKey.slice(0, 15) + "...",
997
- validUntil: new Date(sessionConfig.validUntil * 1e3).toISOString(),
998
- maxCalls: sessionConfig.maxCalls,
999
- allowedEntrypoints: sessionConfig.allowedEntrypoints.length
1000
- }
1001
- );
975
+ console.log("[ChipiSDK:Session:AddToContract] Registering session on-chain", {
976
+ walletAddress: wallet.publicKey.slice(0, 15) + "...",
977
+ sessionPubKey: sessionConfig.sessionPublicKey.slice(0, 15) + "...",
978
+ validUntil: new Date(sessionConfig.validUntil * 1e3).toISOString(),
979
+ maxCalls: sessionConfig.maxCalls,
980
+ allowedEntrypoints: sessionConfig.allowedEntrypoints.length
981
+ });
1002
982
  const calldata = [
1003
983
  sessionConfig.sessionPublicKey,
1004
984
  num.toHex(sessionConfig.validUntil),
@@ -1024,13 +1004,10 @@ var ChipiSessions = class {
1024
1004
  bearerToken,
1025
1005
  client: this.client
1026
1006
  });
1027
- console.log(
1028
- "[ChipiSDK:Session:AddToContract] Session registered successfully",
1029
- {
1030
- txHash,
1031
- sessionPubKey: sessionConfig.sessionPublicKey.slice(0, 15) + "..."
1032
- }
1033
- );
1007
+ console.log("[ChipiSDK:Session:AddToContract] Session registered successfully", {
1008
+ txHash,
1009
+ sessionPubKey: sessionConfig.sessionPublicKey.slice(0, 15) + "..."
1010
+ });
1034
1011
  return txHash;
1035
1012
  } catch (error) {
1036
1013
  const err = error instanceof Error ? error : new Error(String(error));
@@ -1178,17 +1155,33 @@ var ChipiSessions = class {
1178
1155
  return sessionData;
1179
1156
  } catch (error) {
1180
1157
  const err = error instanceof Error ? error : new Error(String(error));
1181
- console.error("[ChipiSDK:Session:GetData] Query failed", {
1158
+ const sessionNotFoundPatterns = [
1159
+ /entry point.*not found/i,
1160
+ /requested entrypoint was not found/i,
1161
+ /invalid message selector/i,
1162
+ /contract not found/i,
1163
+ /is not deployed/i,
1164
+ /revert.*get_session_data/i
1165
+ ];
1166
+ const isSessionNotFound = sessionNotFoundPatterns.some((p) => p.test(err.message));
1167
+ if (isSessionNotFound) {
1168
+ console.log("[ChipiSDK:Session:GetData] Session not found on contract", {
1169
+ walletAddress: walletAddress?.slice(0, 15) + "...",
1170
+ sessionPubKey: sessionPublicKey?.slice(0, 15) + "..."
1171
+ });
1172
+ return {
1173
+ isActive: false,
1174
+ validUntil: 0,
1175
+ remainingCalls: 0,
1176
+ allowedEntrypoints: []
1177
+ };
1178
+ }
1179
+ console.error("[ChipiSDK:Session:GetData] RPC/network error", {
1182
1180
  error: err.message,
1183
1181
  walletAddress: walletAddress?.slice(0, 15) + "...",
1184
1182
  sessionPubKey: sessionPublicKey?.slice(0, 15) + "..."
1185
1183
  });
1186
- return {
1187
- isActive: false,
1188
- validUntil: 0,
1189
- remainingCalls: 0,
1190
- allowedEntrypoints: []
1191
- };
1184
+ throw err;
1192
1185
  }
1193
1186
  }
1194
1187
  /**
@@ -1401,7 +1394,6 @@ var ChipiSDK = class {
1401
1394
  params,
1402
1395
  bearerToken
1403
1396
  }) {
1404
- console.log("createWallet params:", params);
1405
1397
  return this.wallets.createWallet({
1406
1398
  ...params,
1407
1399
  bearerToken: this.resolveBearerToken(bearerToken)
@@ -1417,10 +1409,7 @@ var ChipiSDK = class {
1417
1409
  });
1418
1410
  }
1419
1411
  async getTransactionList(query, bearerToken) {
1420
- return this.transactions.getTransactionList(
1421
- query,
1422
- this.resolveBearerToken(bearerToken)
1423
- );
1412
+ return this.transactions.getTransactionList(query, this.resolveBearerToken(bearerToken));
1424
1413
  }
1425
1414
  async getWallet(params, bearerToken) {
1426
1415
  return this.wallets.getWallet(params, this.resolveBearerToken(bearerToken));
@@ -1438,19 +1427,13 @@ var ChipiSDK = class {
1438
1427
  params,
1439
1428
  bearerToken
1440
1429
  }) {
1441
- return this.skuPurchases.purchaseSku(
1442
- params,
1443
- this.resolveBearerToken(bearerToken)
1444
- );
1430
+ return this.skuPurchases.purchaseSku(params, this.resolveBearerToken(bearerToken));
1445
1431
  }
1446
1432
  /**
1447
1433
  * Get a SKU purchase by id
1448
1434
  */
1449
1435
  async getSkuPurchase(id, bearerToken) {
1450
- return this.skuPurchases.getSkuPurchase(
1451
- id,
1452
- this.resolveBearerToken(bearerToken)
1453
- );
1436
+ return this.skuPurchases.getSkuPurchase(id, this.resolveBearerToken(bearerToken));
1454
1437
  }
1455
1438
  /// SKUS
1456
1439
  async getSkuList(params, bearerToken) {