@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/LICENSE +21 -0
- package/README.md +50 -1
- package/dist/index.js +100 -117
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +101 -118
- package/dist/index.mjs.map +1 -1
- package/dist/skuPurchases.js +27 -32
- package/dist/skuPurchases.js.map +1 -1
- package/dist/skuPurchases.mjs +28 -33
- package/dist/skuPurchases.mjs.map +1 -1
- package/dist/skus.js.map +1 -1
- package/dist/skus.mjs.map +1 -1
- package/dist/transactions.js +14 -8
- package/dist/transactions.js.map +1 -1
- package/dist/transactions.mjs +14 -8
- package/dist/transactions.mjs.map +1 -1
- package/dist/wallets.js +5 -5
- package/dist/wallets.js.map +1 -1
- package/dist/wallets.mjs +5 -5
- package/dist/wallets.mjs.map +1 -1
- package/package.json +3 -3
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 = "
|
|
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
|
|
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)
|
|
203
|
+
if (!decrypted) {
|
|
204
|
+
throw new Error("Decryption resulted in empty string");
|
|
205
|
+
}
|
|
199
206
|
return decrypted;
|
|
200
207
|
} catch (error) {
|
|
201
|
-
|
|
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
|
|
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
|
-
|
|
405
|
-
|
|
406
|
-
encryptKey
|
|
407
|
-
|
|
408
|
-
|
|
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
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
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
|
-
|
|
511
|
-
|
|
512
|
-
encryptKey
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
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
|
-
|
|
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
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
token
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
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
|
-
|
|
947
|
-
|
|
948
|
-
|
|
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
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
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
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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) {
|