@chipi-stack/shared 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 +21 -0
- package/README.md +19 -1
- package/dist/constants/index.d.mts +17 -3
- package/dist/constants/index.d.ts +17 -3
- package/dist/constants/index.js +27 -5
- package/dist/constants/index.js.map +1 -1
- package/dist/constants/index.mjs +26 -6
- package/dist/constants/index.mjs.map +1 -1
- package/dist/index.d.mts +20 -6
- package/dist/index.d.ts +20 -6
- package/dist/index.js +42 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +40 -14
- package/dist/index.mjs.map +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +2 -2
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,21 @@
|
|
|
1
1
|
# @chipi-stack/shared
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Shared constants, utilities, error classes, and validators for the Chipi SDK ecosystem.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @chipi-stack/shared
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Key Exports
|
|
12
|
+
|
|
13
|
+
- **Constants** (`constants/`): WALLET_CLASS_HASHES, LEGACY_CHIPI_CLASS_HASHES, CONTRACT_ADDRESSES, STARKNET_NETWORKS, API_ENDPOINTS, TOKEN_DECIMALS, SKU_CONTRACTS, CHAIN_TOKEN_TYPES, WALLET_RPC_ENDPOINTS, PAYMASTER_CONFIG, SESSION_DEFAULTS, SESSION_ERRORS, SESSION_ENTRYPOINTS, getWalletTypeFromClassHash
|
|
14
|
+
- **Errors** (`errors.ts`): ChipiError, ChipiApiError, ChipiWalletError, ChipiTransactionError, ChipiSessionError, ChipiSkuError, ChipiValidationError, ChipiAuthError, isChipiError, hasHttpStatus, handleApiError
|
|
15
|
+
- **Formatters** (`formatters.ts`): formatCurrency, formatNumber, formatDate, formatAddress, formatTransactionHash, camelToSnake, snakeToCamel, capitalizeFirst
|
|
16
|
+
- **Utils** (`utils/`): isValidAddress, isValidApiKey, formatAmount, parseAmount, sleep, retry, createPaginatedResponse, validatePagination, sanitizeUrl, deepMerge
|
|
17
|
+
- **Validation** (`validation.ts`): ApiResponseSchema, ErrorResponseSchema, SuccessResponseSchema, validateApiResponse, validateErrorResponse
|
|
18
|
+
|
|
19
|
+
## License
|
|
20
|
+
|
|
21
|
+
MIT
|
|
@@ -17,8 +17,9 @@ declare const API_VERSIONING: {
|
|
|
17
17
|
readonly VERSION_DATE: "2025-12-30";
|
|
18
18
|
};
|
|
19
19
|
declare const STARKNET_NETWORKS: {
|
|
20
|
-
readonly MAINNET:
|
|
21
|
-
readonly
|
|
20
|
+
readonly MAINNET: string;
|
|
21
|
+
readonly MAINNET_FALLBACK: "https://rpc.starknet.lava.build";
|
|
22
|
+
readonly SEPOLIA: string;
|
|
22
23
|
};
|
|
23
24
|
declare const CONTRACT_ADDRESSES: {
|
|
24
25
|
readonly USDC_MAINNET: "0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";
|
|
@@ -71,6 +72,19 @@ declare const CHAIN_TOKEN_TYPES: {
|
|
|
71
72
|
readonly OTHER: "OTHER";
|
|
72
73
|
};
|
|
73
74
|
declare const WALLET_CLASS_HASHES: Record<WalletType, string>;
|
|
75
|
+
/**
|
|
76
|
+
* Previous CHIPI wallet class hashes that are still deployed on-chain.
|
|
77
|
+
* Used by getWalletTypeFromClassHash() to identify legacy wallets.
|
|
78
|
+
*/
|
|
79
|
+
declare const LEGACY_CHIPI_CLASS_HASHES: string[];
|
|
80
|
+
/**
|
|
81
|
+
* Determine wallet type from an on-chain class hash.
|
|
82
|
+
* - If it matches the READY hash → READY
|
|
83
|
+
* - If it matches the current CHIPI hash → CHIPI
|
|
84
|
+
* - If it matches a legacy CHIPI hash → CHIPI
|
|
85
|
+
* - Otherwise → CHIPI (safe default since CHIPI wallets have had multiple class hashes)
|
|
86
|
+
*/
|
|
87
|
+
declare function getWalletTypeFromClassHash(classHash: string): WalletType;
|
|
74
88
|
declare const WALLET_RPC_ENDPOINTS: Record<WalletType, string>;
|
|
75
89
|
declare const PAYMASTER_CONFIG: {
|
|
76
90
|
readonly URL: "https://paymaster.chipipay.com";
|
|
@@ -108,4 +122,4 @@ declare const SESSION_ENTRYPOINTS: {
|
|
|
108
122
|
readonly GET_DATA: "get_session_data";
|
|
109
123
|
};
|
|
110
124
|
|
|
111
|
-
export { API_ENDPOINTS, API_VERSIONING, CARRIER_IDS, CHAIN_TOKEN_TYPES, CHAIN_TYPES, CONTRACT_ADDRESSES, ERRORS, PAYMASTER_CONFIG, SERVICE_TYPES, SESSION_DEFAULTS, SESSION_ENTRYPOINTS, SESSION_ERRORS, SKU_CONTRACTS, STARKNET_NETWORKS, TOKEN_DECIMALS, WALLET_CLASS_HASHES, WALLET_RPC_ENDPOINTS };
|
|
125
|
+
export { API_ENDPOINTS, API_VERSIONING, CARRIER_IDS, CHAIN_TOKEN_TYPES, CHAIN_TYPES, CONTRACT_ADDRESSES, ERRORS, LEGACY_CHIPI_CLASS_HASHES, PAYMASTER_CONFIG, SERVICE_TYPES, SESSION_DEFAULTS, SESSION_ENTRYPOINTS, SESSION_ERRORS, SKU_CONTRACTS, STARKNET_NETWORKS, TOKEN_DECIMALS, WALLET_CLASS_HASHES, WALLET_RPC_ENDPOINTS, getWalletTypeFromClassHash };
|
|
@@ -17,8 +17,9 @@ declare const API_VERSIONING: {
|
|
|
17
17
|
readonly VERSION_DATE: "2025-12-30";
|
|
18
18
|
};
|
|
19
19
|
declare const STARKNET_NETWORKS: {
|
|
20
|
-
readonly MAINNET:
|
|
21
|
-
readonly
|
|
20
|
+
readonly MAINNET: string;
|
|
21
|
+
readonly MAINNET_FALLBACK: "https://rpc.starknet.lava.build";
|
|
22
|
+
readonly SEPOLIA: string;
|
|
22
23
|
};
|
|
23
24
|
declare const CONTRACT_ADDRESSES: {
|
|
24
25
|
readonly USDC_MAINNET: "0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";
|
|
@@ -71,6 +72,19 @@ declare const CHAIN_TOKEN_TYPES: {
|
|
|
71
72
|
readonly OTHER: "OTHER";
|
|
72
73
|
};
|
|
73
74
|
declare const WALLET_CLASS_HASHES: Record<WalletType, string>;
|
|
75
|
+
/**
|
|
76
|
+
* Previous CHIPI wallet class hashes that are still deployed on-chain.
|
|
77
|
+
* Used by getWalletTypeFromClassHash() to identify legacy wallets.
|
|
78
|
+
*/
|
|
79
|
+
declare const LEGACY_CHIPI_CLASS_HASHES: string[];
|
|
80
|
+
/**
|
|
81
|
+
* Determine wallet type from an on-chain class hash.
|
|
82
|
+
* - If it matches the READY hash → READY
|
|
83
|
+
* - If it matches the current CHIPI hash → CHIPI
|
|
84
|
+
* - If it matches a legacy CHIPI hash → CHIPI
|
|
85
|
+
* - Otherwise → CHIPI (safe default since CHIPI wallets have had multiple class hashes)
|
|
86
|
+
*/
|
|
87
|
+
declare function getWalletTypeFromClassHash(classHash: string): WalletType;
|
|
74
88
|
declare const WALLET_RPC_ENDPOINTS: Record<WalletType, string>;
|
|
75
89
|
declare const PAYMASTER_CONFIG: {
|
|
76
90
|
readonly URL: "https://paymaster.chipipay.com";
|
|
@@ -108,4 +122,4 @@ declare const SESSION_ENTRYPOINTS: {
|
|
|
108
122
|
readonly GET_DATA: "get_session_data";
|
|
109
123
|
};
|
|
110
124
|
|
|
111
|
-
export { API_ENDPOINTS, API_VERSIONING, CARRIER_IDS, CHAIN_TOKEN_TYPES, CHAIN_TYPES, CONTRACT_ADDRESSES, ERRORS, PAYMASTER_CONFIG, SERVICE_TYPES, SESSION_DEFAULTS, SESSION_ENTRYPOINTS, SESSION_ERRORS, SKU_CONTRACTS, STARKNET_NETWORKS, TOKEN_DECIMALS, WALLET_CLASS_HASHES, WALLET_RPC_ENDPOINTS };
|
|
125
|
+
export { API_ENDPOINTS, API_VERSIONING, CARRIER_IDS, CHAIN_TOKEN_TYPES, CHAIN_TYPES, CONTRACT_ADDRESSES, ERRORS, LEGACY_CHIPI_CLASS_HASHES, PAYMASTER_CONFIG, SERVICE_TYPES, SESSION_DEFAULTS, SESSION_ENTRYPOINTS, SESSION_ERRORS, SKU_CONTRACTS, STARKNET_NETWORKS, TOKEN_DECIMALS, WALLET_CLASS_HASHES, WALLET_RPC_ENDPOINTS, getWalletTypeFromClassHash };
|
package/dist/constants/index.js
CHANGED
|
@@ -7,9 +7,12 @@ var API_VERSIONING = {
|
|
|
7
7
|
VERSION_DATE: "2025-12-30"
|
|
8
8
|
// Detailed version - sent as query param for tracking
|
|
9
9
|
};
|
|
10
|
+
var DEFAULT_MAINNET_RPC = "https://starknet-mainnet.infura.io/v3/4a4a1fdd7d704509aa99154fb29886e2";
|
|
11
|
+
var DEFAULT_SEPOLIA_RPC = "https://starknet-sepolia.infura.io/v3/4a4a1fdd7d704509aa99154fb29886e2";
|
|
10
12
|
var STARKNET_NETWORKS = {
|
|
11
|
-
MAINNET:
|
|
12
|
-
|
|
13
|
+
MAINNET: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,
|
|
14
|
+
MAINNET_FALLBACK: "https://rpc.starknet.lava.build",
|
|
15
|
+
SEPOLIA: process.env.STARKNET_RPC_URL_SEPOLIA ?? DEFAULT_SEPOLIA_RPC
|
|
13
16
|
};
|
|
14
17
|
var CONTRACT_ADDRESSES = {
|
|
15
18
|
USDC_MAINNET: "0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb",
|
|
@@ -66,12 +69,29 @@ var CHAIN_TOKEN_TYPES = {
|
|
|
66
69
|
};
|
|
67
70
|
var WALLET_CLASS_HASHES = {
|
|
68
71
|
CHIPI: "0x53f4f8791ed5bed0fddaa553d180c664e32cfaf8316bb232ae77bb08f459f2a",
|
|
69
|
-
// CHIPI: "0x2de1565226d5215a38b68c4d9a4913989b54edff64c68c45e453c417b44cd83", // Old class Hash
|
|
70
72
|
READY: "0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f"
|
|
71
73
|
};
|
|
74
|
+
var LEGACY_CHIPI_CLASS_HASHES = [
|
|
75
|
+
"0x2de1565226d5215a38b68c4d9a4913989b54edff64c68c45e453c417b44cd83"
|
|
76
|
+
// v28
|
|
77
|
+
];
|
|
78
|
+
function getWalletTypeFromClassHash(classHash) {
|
|
79
|
+
const normalized = classHash.toLowerCase().replace(/^0x0+/, "0x");
|
|
80
|
+
const normalize = (h) => h.toLowerCase().replace(/^0x0+/, "0x");
|
|
81
|
+
if (normalize(WALLET_CLASS_HASHES.READY) === normalized) {
|
|
82
|
+
return "READY";
|
|
83
|
+
}
|
|
84
|
+
if (normalize(WALLET_CLASS_HASHES.CHIPI) === normalized) {
|
|
85
|
+
return "CHIPI";
|
|
86
|
+
}
|
|
87
|
+
if (LEGACY_CHIPI_CLASS_HASHES.some((h) => normalize(h) === normalized)) {
|
|
88
|
+
return "CHIPI";
|
|
89
|
+
}
|
|
90
|
+
return "CHIPI";
|
|
91
|
+
}
|
|
72
92
|
var WALLET_RPC_ENDPOINTS = {
|
|
73
|
-
CHIPI:
|
|
74
|
-
READY:
|
|
93
|
+
CHIPI: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,
|
|
94
|
+
READY: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC
|
|
75
95
|
};
|
|
76
96
|
var PAYMASTER_CONFIG = {
|
|
77
97
|
URL: "https://paymaster.chipipay.com"
|
|
@@ -116,6 +136,7 @@ exports.CHAIN_TOKEN_TYPES = CHAIN_TOKEN_TYPES;
|
|
|
116
136
|
exports.CHAIN_TYPES = CHAIN_TYPES;
|
|
117
137
|
exports.CONTRACT_ADDRESSES = CONTRACT_ADDRESSES;
|
|
118
138
|
exports.ERRORS = ERRORS;
|
|
139
|
+
exports.LEGACY_CHIPI_CLASS_HASHES = LEGACY_CHIPI_CLASS_HASHES;
|
|
119
140
|
exports.PAYMASTER_CONFIG = PAYMASTER_CONFIG;
|
|
120
141
|
exports.SERVICE_TYPES = SERVICE_TYPES;
|
|
121
142
|
exports.SESSION_DEFAULTS = SESSION_DEFAULTS;
|
|
@@ -126,5 +147,6 @@ exports.STARKNET_NETWORKS = STARKNET_NETWORKS;
|
|
|
126
147
|
exports.TOKEN_DECIMALS = TOKEN_DECIMALS;
|
|
127
148
|
exports.WALLET_CLASS_HASHES = WALLET_CLASS_HASHES;
|
|
128
149
|
exports.WALLET_RPC_ENDPOINTS = WALLET_RPC_ENDPOINTS;
|
|
150
|
+
exports.getWalletTypeFromClassHash = getWalletTypeFromClassHash;
|
|
129
151
|
//# sourceMappingURL=index.js.map
|
|
130
152
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/constants/index.ts"],"names":[],"mappings":";;;AAcO,IAAM,cAAA,GAAiB;AAAA,EAC5B,OAAA,EAAS,GAAA;AAAA;AAAA,EACT,YAAA,EAAc;AAAA;AAChB;
|
|
1
|
+
{"version":3,"sources":["../../src/constants/index.ts"],"names":[],"mappings":";;;AAcO,IAAM,cAAA,GAAiB;AAAA,EAC5B,OAAA,EAAS,GAAA;AAAA;AAAA,EACT,YAAA,EAAc;AAAA;AAChB;AAGA,IAAM,mBAAA,GACJ,wEAAA;AACF,IAAM,mBAAA,GACJ,wEAAA;AAEK,IAAM,iBAAA,GAAoB;AAAA,EAC/B,OAAA,EAAS,OAAA,CAAQ,GAAA,CAAI,gBAAA,IAAoB,mBAAA;AAAA,EACzC,gBAAA,EAAkB,iCAAA;AAAA,EAClB,OAAA,EAAS,OAAA,CAAQ,GAAA,CAAI,wBAAA,IAA4B;AACnD;AAEO,IAAM,kBAAA,GAAqB;AAAA,EAChC,YAAA,EAAc,oEAAA;AAAA;AAAA,EACd,iBAAA,EAAmB;AACrB;AAEO,IAAM,cAAA,GAAiB;AAAA,EAC5B,IAAA,EAAM,CAAA;AAAA,EACN,IAAA,EAAM,CAAA;AAAA,EACN,GAAA,EAAK,EAAA;AAAA,EACL,IAAA,EAAM,EAAA;AAAA,EACN,GAAA,EAAK;AACP;AAEO,IAAM,aAAA,GAAgB;AAAA,EAC3B,aAAA,EAAe,gBAAA;AAAA,EACf,YAAA,EAAc,eAAA;AAAA,EACd,IAAA,EAAM,OAAA;AAAA,EACN,aAAA,EAAe,gBAAA;AAAA,EACf,SAAA,EAAW,YAAA;AAAA,EACX,KAAA,EAAO;AACT;AAEO,IAAM,MAAA,GAAS;AAAA,EACpB,eAAA,EAAiB,iBAAA;AAAA,EACjB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,oBAAA,EAAsB,sBAAA;AAAA,EACtB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,iBAAA,EAAmB,mBAAA;AAAA,EACnB,aAAA,EAAe,eAAA;AAAA,EACf,eAAA,EAAiB;AACnB;AAEO,IAAM,aAAA,GAAgB;AAAA,EAC3B,2BAAA,EAA6B,oEAAA;AAAA;AAAA,EAC7B,kBAAA,EAAoB;AACtB;AAGO,IAAM,aAAA,GAAgB;AAAA,EAC3B,WAAA,EAAa;AACf;AAGO,IAAM,WAAA,GAAc;AAAA,EACzB,SAAA,EAAW;AACb;AAEO,IAAM,WAAA,GAAc;AAAA,EACzB,QAAA,EAAU;AACZ;AAEO,IAAM,iBAAA,GAAoB;AAAA,EAC/B,IAAA,EAAM,MAAA;AAAA;AAAA,EACN,IAAA,EAAM,MAAA;AAAA,EACN,GAAA,EAAK,KAAA;AAAA,EACL,IAAA,EAAM,MAAA;AAAA,EACN,GAAA,EAAK,KAAA;AAAA,EACL,IAAA,EAAM,MAAA;AAAA,EACN,KAAA,EAAO;AACT;AAEO,IAAM,mBAAA,GAAkD;AAAA,EAC7D,KAAA,EAAO,mEAAA;AAAA,EACP,KAAA,EAAO;AACT;AAMO,IAAM,yBAAA,GAAsC;AAAA,EACjD;AAAA;AACF;AASO,SAAS,2BAA2B,SAAA,EAA+B;AACxE,EAAA,MAAM,aAAa,SAAA,CAAU,WAAA,EAAY,CAAE,OAAA,CAAQ,SAAS,IAAI,CAAA;AAChE,EAAA,MAAM,SAAA,GAAY,CAAC,CAAA,KAAc,CAAA,CAAE,aAAY,CAAE,OAAA,CAAQ,SAAS,IAAI,CAAA;AAEtE,EAAA,IAAI,SAAA,CAAU,mBAAA,CAAoB,KAAK,CAAA,KAAM,UAAA,EAAY;AACvD,IAAA,OAAO,OAAA;AAAA,EACT;AAEA,EAAA,IAAI,SAAA,CAAU,mBAAA,CAAoB,KAAK,CAAA,KAAM,UAAA,EAAY;AACvD,IAAA,OAAO,OAAA;AAAA,EACT;AACA,EAAA,IAAI,yBAAA,CAA0B,KAAK,CAAC,CAAA,KAAM,UAAU,CAAC,CAAA,KAAM,UAAU,CAAA,EAAG;AACtE,IAAA,OAAO,OAAA;AAAA,EACT;AAEA,EAAA,OAAO,OAAA;AACT;AAIO,IAAM,oBAAA,GAAmD;AAAA,EAC9D,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,gBAAA,IAAoB,mBAAA;AAAA,EACvC,KAAA,EAAO,OAAA,CAAQ,GAAA,CAAI,gBAAA,IAAoB;AACzC;AAGO,IAAM,gBAAA,GAAmB;AAAA,EAC9B,GAAA,EAAK;AACP;AAGO,IAAM,gBAAA,GAAmB;AAAA;AAAA,EAE9B,gBAAA,EAAkB,KAAA;AAAA;AAAA,EAElB,SAAA,EAAW;AACb;AAGO,IAAM,cAAA,GAAiB;AAAA;AAAA,EAE5B,+BAAA,EAAiC,iCAAA;AAAA;AAAA,EAEjC,eAAA,EAAiB,iBAAA;AAAA;AAAA,EAEjB,sBAAA,EAAwB,wBAAA;AAAA;AAAA,EAExB,eAAA,EAAiB,iBAAA;AAAA;AAAA,EAEjB,0BAAA,EAA4B,4BAAA;AAAA;AAAA,EAE5B,8BAAA,EAAgC,gCAAA;AAAA;AAAA,EAEhC,yBAAA,EAA2B,2BAAA;AAAA;AAAA,EAE3B,uBAAA,EAAyB;AAC3B;AAGO,IAAM,mBAAA,GAAsB;AAAA;AAAA,EAEjC,aAAA,EAAe,2BAAA;AAAA;AAAA,EAEf,MAAA,EAAQ,oBAAA;AAAA;AAAA,EAER,QAAA,EAAU;AACZ","file":"index.js","sourcesContent":["/**\n * Constants used across Chipi SDK packages\n */\n\nimport { WalletType } from \"@chipi-stack/types\";\n\n/**\n * API Versioning\n * - VERSION: Major version for path-based versioning (/v1, /v2, etc.)\n * - VERSION_DATE: Detailed version for tracking breaking changes (YYYY-MM-DD format)\n *\n * Update VERSION_DATE when making API changes.\n * Update VERSION when making major breaking changes (typically 1-2 times per year).\n */\nexport const API_VERSIONING = {\n VERSION: \"1\", // Major version - used in URL path\n VERSION_DATE: \"2025-12-30\", // Detailed version - sent as query param for tracking\n} as const;\n\n// Default RPC URLs — override via STARKNET_RPC_URL / STARKNET_RPC_URL_SEPOLIA env vars.\nconst DEFAULT_MAINNET_RPC =\n \"https://starknet-mainnet.infura.io/v3/4a4a1fdd7d704509aa99154fb29886e2\";\nconst DEFAULT_SEPOLIA_RPC =\n \"https://starknet-sepolia.infura.io/v3/4a4a1fdd7d704509aa99154fb29886e2\";\n\nexport const STARKNET_NETWORKS = {\n MAINNET: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,\n MAINNET_FALLBACK: \"https://rpc.starknet.lava.build\",\n SEPOLIA: process.env.STARKNET_RPC_URL_SEPOLIA ?? DEFAULT_SEPOLIA_RPC,\n} as const;\n\nexport const CONTRACT_ADDRESSES = {\n USDC_MAINNET: \"0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb\", // Changed to Native USDC (was bridged USDC.e)\n VESU_USDC_MAINNET: \"0x017f19582c61479f2fe0b6606300e975c0a8f439102f43eeecc1d0e9b3d84350\",\n} as const;\n\nexport const TOKEN_DECIMALS = {\n USDC: 6,\n USDT: 6,\n ETH: 18,\n STRK: 18,\n DAI: 18,\n} as const;\n\nexport const API_ENDPOINTS = {\n CHIPI_WALLETS: \"/chipi-wallets\",\n TRANSACTIONS: \"/transactions\",\n SKUS: \"/skus\",\n SKU_PURCHASES: \"/sku-purchases\",\n EXCHANGES: \"/exchanges\",\n USERS: \"/users\",\n} as const;\n\nexport const ERRORS = {\n INVALID_API_KEY: \"INVALID_API_KEY\",\n WALLET_NOT_FOUND: \"WALLET_NOT_FOUND\",\n INSUFFICIENT_BALANCE: \"INSUFFICIENT_BALANCE\",\n TRANSACTION_FAILED: \"TRANSACTION_FAILED\",\n INVALID_SIGNATURE: \"INVALID_SIGNATURE\",\n SKU_NOT_FOUND: \"SKU_NOT_FOUND\",\n SKU_UNAVAILABLE: \"SKU_UNAVAILABLE\",\n} as const;\n\nexport const SKU_CONTRACTS = {\n RECHARGER_WITH_STRK_MAINNET: \"0x02d65bb726d2c29e3c97669cf297c5145eac19284fb6f935c05c0bfc68dae2b7\", //changed contract address used to be 0x0f3\n CHIPI_BILL_SERVICE: \"0x4e8150110d580069de26adec9b179023289d55859ea07487aaade5458d7aa8b\",\n} as const;\n\n// Service types\nexport const SERVICE_TYPES = {\n BUY_SERVICE: \"BUY_SERVICE\",\n} as const;\n\n// Carrier IDs\nexport const CARRIER_IDS = {\n CHIPI_PAY: \"chipi_pay\",\n} as const;\n\nexport const CHAIN_TYPES = {\n STARKNET: \"STARKNET\",\n} as const;\n\nexport const CHAIN_TOKEN_TYPES = {\n USDC: \"USDC\", // Changed to Native USDC (was bridged USDC.e)\n USDT: \"USDT\",\n ETH: \"ETH\",\n STRK: \"STRK\",\n DAI: \"DAI\",\n WBTC: \"WBTC\",\n OTHER: \"OTHER\",\n} as const;\n\nexport const WALLET_CLASS_HASHES: Record<WalletType, string> = {\n CHIPI: \"0x53f4f8791ed5bed0fddaa553d180c664e32cfaf8316bb232ae77bb08f459f2a\",\n READY: \"0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f\",\n};\n\n/**\n * Previous CHIPI wallet class hashes that are still deployed on-chain.\n * Used by getWalletTypeFromClassHash() to identify legacy wallets.\n */\nexport const LEGACY_CHIPI_CLASS_HASHES: string[] = [\n \"0x2de1565226d5215a38b68c4d9a4913989b54edff64c68c45e453c417b44cd83\", // v28\n];\n\n/**\n * Determine wallet type from an on-chain class hash.\n * - If it matches the READY hash → READY\n * - If it matches the current CHIPI hash → CHIPI\n * - If it matches a legacy CHIPI hash → CHIPI\n * - Otherwise → CHIPI (safe default since CHIPI wallets have had multiple class hashes)\n */\nexport function getWalletTypeFromClassHash(classHash: string): WalletType {\n const normalized = classHash.toLowerCase().replace(/^0x0+/, \"0x\");\n const normalize = (h: string) => h.toLowerCase().replace(/^0x0+/, \"0x\");\n\n if (normalize(WALLET_CLASS_HASHES.READY) === normalized) {\n return \"READY\";\n }\n // Current or legacy CHIPI hashes\n if (normalize(WALLET_CLASS_HASHES.CHIPI) === normalized) {\n return \"CHIPI\";\n }\n if (LEGACY_CHIPI_CLASS_HASHES.some((h) => normalize(h) === normalized)) {\n return \"CHIPI\";\n }\n // Default to CHIPI — unknown hashes are more likely to be older CHIPI deployments\n return \"CHIPI\";\n}\n\n// RPC endpoints per wallet type — any standard Starknet RPC works for all wallet types.\n// Override via STARKNET_RPC_URL env var; falls back to the default Infura endpoint.\nexport const WALLET_RPC_ENDPOINTS: Record<WalletType, string> = {\n CHIPI: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,\n READY: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,\n};\n\n// Paymaster configuration\nexport const PAYMASTER_CONFIG = {\n URL: \"https://paymaster.chipipay.com\",\n} as const;\n\n// Session key configuration (CHIPI wallets only - SNIP-9 compatible)\nexport const SESSION_DEFAULTS = {\n /** Default session duration: 6 hours in seconds */\n DURATION_SECONDS: 21600,\n /** Default max calls per session */\n MAX_CALLS: 1000,\n} as const;\n\n// Session-specific error codes\nexport const SESSION_ERRORS = {\n /** Session keys only work with CHIPI wallets */\n INVALID_WALLET_TYPE_FOR_SESSION: \"INVALID_WALLET_TYPE_FOR_SESSION\",\n /** Session has expired (validUntil < now) */\n SESSION_EXPIRED: \"SESSION_EXPIRED\",\n /** Session key not registered on contract */\n SESSION_NOT_REGISTERED: \"SESSION_NOT_REGISTERED\",\n /** Session key has been revoked */\n SESSION_REVOKED: \"SESSION_REVOKED\",\n /** Session has exceeded max calls */\n SESSION_MAX_CALLS_EXCEEDED: \"SESSION_MAX_CALLS_EXCEEDED\",\n /** Entrypoint not allowed for this session */\n SESSION_ENTRYPOINT_NOT_ALLOWED: \"SESSION_ENTRYPOINT_NOT_ALLOWED\",\n /** Failed to decrypt session private key */\n SESSION_DECRYPTION_FAILED: \"SESSION_DECRYPTION_FAILED\",\n /** Failed to create session key */\n SESSION_CREATION_FAILED: \"SESSION_CREATION_FAILED\",\n} as const;\n\n// Session contract entrypoint names\nexport const SESSION_ENTRYPOINTS = {\n /** Add or update a session key (owner only) */\n ADD_OR_UPDATE: \"add_or_update_session_key\",\n /** Revoke a session key (owner only) */\n REVOKE: \"revoke_session_key\",\n /** Query session data (public read) */\n GET_DATA: \"get_session_data\",\n} as const;\n"]}
|
package/dist/constants/index.mjs
CHANGED
|
@@ -5,9 +5,12 @@ var API_VERSIONING = {
|
|
|
5
5
|
VERSION_DATE: "2025-12-30"
|
|
6
6
|
// Detailed version - sent as query param for tracking
|
|
7
7
|
};
|
|
8
|
+
var DEFAULT_MAINNET_RPC = "https://starknet-mainnet.infura.io/v3/4a4a1fdd7d704509aa99154fb29886e2";
|
|
9
|
+
var DEFAULT_SEPOLIA_RPC = "https://starknet-sepolia.infura.io/v3/4a4a1fdd7d704509aa99154fb29886e2";
|
|
8
10
|
var STARKNET_NETWORKS = {
|
|
9
|
-
MAINNET:
|
|
10
|
-
|
|
11
|
+
MAINNET: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,
|
|
12
|
+
MAINNET_FALLBACK: "https://rpc.starknet.lava.build",
|
|
13
|
+
SEPOLIA: process.env.STARKNET_RPC_URL_SEPOLIA ?? DEFAULT_SEPOLIA_RPC
|
|
11
14
|
};
|
|
12
15
|
var CONTRACT_ADDRESSES = {
|
|
13
16
|
USDC_MAINNET: "0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb",
|
|
@@ -64,12 +67,29 @@ var CHAIN_TOKEN_TYPES = {
|
|
|
64
67
|
};
|
|
65
68
|
var WALLET_CLASS_HASHES = {
|
|
66
69
|
CHIPI: "0x53f4f8791ed5bed0fddaa553d180c664e32cfaf8316bb232ae77bb08f459f2a",
|
|
67
|
-
// CHIPI: "0x2de1565226d5215a38b68c4d9a4913989b54edff64c68c45e453c417b44cd83", // Old class Hash
|
|
68
70
|
READY: "0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f"
|
|
69
71
|
};
|
|
72
|
+
var LEGACY_CHIPI_CLASS_HASHES = [
|
|
73
|
+
"0x2de1565226d5215a38b68c4d9a4913989b54edff64c68c45e453c417b44cd83"
|
|
74
|
+
// v28
|
|
75
|
+
];
|
|
76
|
+
function getWalletTypeFromClassHash(classHash) {
|
|
77
|
+
const normalized = classHash.toLowerCase().replace(/^0x0+/, "0x");
|
|
78
|
+
const normalize = (h) => h.toLowerCase().replace(/^0x0+/, "0x");
|
|
79
|
+
if (normalize(WALLET_CLASS_HASHES.READY) === normalized) {
|
|
80
|
+
return "READY";
|
|
81
|
+
}
|
|
82
|
+
if (normalize(WALLET_CLASS_HASHES.CHIPI) === normalized) {
|
|
83
|
+
return "CHIPI";
|
|
84
|
+
}
|
|
85
|
+
if (LEGACY_CHIPI_CLASS_HASHES.some((h) => normalize(h) === normalized)) {
|
|
86
|
+
return "CHIPI";
|
|
87
|
+
}
|
|
88
|
+
return "CHIPI";
|
|
89
|
+
}
|
|
70
90
|
var WALLET_RPC_ENDPOINTS = {
|
|
71
|
-
CHIPI:
|
|
72
|
-
READY:
|
|
91
|
+
CHIPI: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,
|
|
92
|
+
READY: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC
|
|
73
93
|
};
|
|
74
94
|
var PAYMASTER_CONFIG = {
|
|
75
95
|
URL: "https://paymaster.chipipay.com"
|
|
@@ -107,6 +127,6 @@ var SESSION_ENTRYPOINTS = {
|
|
|
107
127
|
GET_DATA: "get_session_data"
|
|
108
128
|
};
|
|
109
129
|
|
|
110
|
-
export { API_ENDPOINTS, API_VERSIONING, CARRIER_IDS, CHAIN_TOKEN_TYPES, CHAIN_TYPES, CONTRACT_ADDRESSES, ERRORS, PAYMASTER_CONFIG, SERVICE_TYPES, SESSION_DEFAULTS, SESSION_ENTRYPOINTS, SESSION_ERRORS, SKU_CONTRACTS, STARKNET_NETWORKS, TOKEN_DECIMALS, WALLET_CLASS_HASHES, WALLET_RPC_ENDPOINTS };
|
|
130
|
+
export { API_ENDPOINTS, API_VERSIONING, CARRIER_IDS, CHAIN_TOKEN_TYPES, CHAIN_TYPES, CONTRACT_ADDRESSES, ERRORS, LEGACY_CHIPI_CLASS_HASHES, PAYMASTER_CONFIG, SERVICE_TYPES, SESSION_DEFAULTS, SESSION_ENTRYPOINTS, SESSION_ERRORS, SKU_CONTRACTS, STARKNET_NETWORKS, TOKEN_DECIMALS, WALLET_CLASS_HASHES, WALLET_RPC_ENDPOINTS, getWalletTypeFromClassHash };
|
|
111
131
|
//# sourceMappingURL=index.mjs.map
|
|
112
132
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/constants/index.ts"],"names":[],"mappings":";AAcO,IAAM,cAAA,GAAiB;AAAA,EAC5B,OAAA,EAAS,GAAA;AAAA;AAAA,EACT,YAAA,EAAc;AAAA;AAChB;
|
|
1
|
+
{"version":3,"sources":["../../src/constants/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Constants used across Chipi SDK packages\n */\n\nimport { WalletType } from \"@chipi-stack/types\";\n\n/**\n * API Versioning\n * - VERSION: Major version for path-based versioning (/v1, /v2, etc.)\n * - VERSION_DATE: Detailed version for tracking breaking changes (YYYY-MM-DD format)\n *\n * Update VERSION_DATE when making API changes.\n * Update VERSION when making major breaking changes (typically 1-2 times per year).\n */\nexport const API_VERSIONING = {\n VERSION: \"1\", // Major version - used in URL path\n VERSION_DATE: \"2025-12-30\", // Detailed version - sent as query param for tracking\n} as const;\n\n// Default RPC URLs — override via STARKNET_RPC_URL / STARKNET_RPC_URL_SEPOLIA env vars.\nconst DEFAULT_MAINNET_RPC =\n \"https://starknet-mainnet.infura.io/v3/4a4a1fdd7d704509aa99154fb29886e2\";\nconst DEFAULT_SEPOLIA_RPC =\n \"https://starknet-sepolia.infura.io/v3/4a4a1fdd7d704509aa99154fb29886e2\";\n\nexport const STARKNET_NETWORKS = {\n MAINNET: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,\n MAINNET_FALLBACK: \"https://rpc.starknet.lava.build\",\n SEPOLIA: process.env.STARKNET_RPC_URL_SEPOLIA ?? DEFAULT_SEPOLIA_RPC,\n} as const;\n\nexport const CONTRACT_ADDRESSES = {\n USDC_MAINNET: \"0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb\", // Changed to Native USDC (was bridged USDC.e)\n VESU_USDC_MAINNET: \"0x017f19582c61479f2fe0b6606300e975c0a8f439102f43eeecc1d0e9b3d84350\",\n} as const;\n\nexport const TOKEN_DECIMALS = {\n USDC: 6,\n USDT: 6,\n ETH: 18,\n STRK: 18,\n DAI: 18,\n} as const;\n\nexport const API_ENDPOINTS = {\n CHIPI_WALLETS: \"/chipi-wallets\",\n TRANSACTIONS: \"/transactions\",\n SKUS: \"/skus\",\n SKU_PURCHASES: \"/sku-purchases\",\n EXCHANGES: \"/exchanges\",\n USERS: \"/users\",\n} as const;\n\nexport const ERRORS = {\n INVALID_API_KEY: \"INVALID_API_KEY\",\n WALLET_NOT_FOUND: \"WALLET_NOT_FOUND\",\n INSUFFICIENT_BALANCE: \"INSUFFICIENT_BALANCE\",\n TRANSACTION_FAILED: \"TRANSACTION_FAILED\",\n INVALID_SIGNATURE: \"INVALID_SIGNATURE\",\n SKU_NOT_FOUND: \"SKU_NOT_FOUND\",\n SKU_UNAVAILABLE: \"SKU_UNAVAILABLE\",\n} as const;\n\nexport const SKU_CONTRACTS = {\n RECHARGER_WITH_STRK_MAINNET: \"0x02d65bb726d2c29e3c97669cf297c5145eac19284fb6f935c05c0bfc68dae2b7\", //changed contract address used to be 0x0f3\n CHIPI_BILL_SERVICE: \"0x4e8150110d580069de26adec9b179023289d55859ea07487aaade5458d7aa8b\",\n} as const;\n\n// Service types\nexport const SERVICE_TYPES = {\n BUY_SERVICE: \"BUY_SERVICE\",\n} as const;\n\n// Carrier IDs\nexport const CARRIER_IDS = {\n CHIPI_PAY: \"chipi_pay\",\n} as const;\n\nexport const CHAIN_TYPES = {\n STARKNET: \"STARKNET\",\n} as const;\n\nexport const CHAIN_TOKEN_TYPES = {\n USDC: \"USDC\", // Changed to Native USDC (was bridged USDC.e)\n USDT: \"USDT\",\n ETH: \"ETH\",\n STRK: \"STRK\",\n DAI: \"DAI\",\n WBTC: \"WBTC\",\n OTHER: \"OTHER\",\n} as const;\n\nexport const WALLET_CLASS_HASHES: Record<WalletType, string> = {\n CHIPI: \"0x53f4f8791ed5bed0fddaa553d180c664e32cfaf8316bb232ae77bb08f459f2a\",\n READY: \"0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f\",\n};\n\n/**\n * Previous CHIPI wallet class hashes that are still deployed on-chain.\n * Used by getWalletTypeFromClassHash() to identify legacy wallets.\n */\nexport const LEGACY_CHIPI_CLASS_HASHES: string[] = [\n \"0x2de1565226d5215a38b68c4d9a4913989b54edff64c68c45e453c417b44cd83\", // v28\n];\n\n/**\n * Determine wallet type from an on-chain class hash.\n * - If it matches the READY hash → READY\n * - If it matches the current CHIPI hash → CHIPI\n * - If it matches a legacy CHIPI hash → CHIPI\n * - Otherwise → CHIPI (safe default since CHIPI wallets have had multiple class hashes)\n */\nexport function getWalletTypeFromClassHash(classHash: string): WalletType {\n const normalized = classHash.toLowerCase().replace(/^0x0+/, \"0x\");\n const normalize = (h: string) => h.toLowerCase().replace(/^0x0+/, \"0x\");\n\n if (normalize(WALLET_CLASS_HASHES.READY) === normalized) {\n return \"READY\";\n }\n // Current or legacy CHIPI hashes\n if (normalize(WALLET_CLASS_HASHES.CHIPI) === normalized) {\n return \"CHIPI\";\n }\n if (LEGACY_CHIPI_CLASS_HASHES.some((h) => normalize(h) === normalized)) {\n return \"CHIPI\";\n }\n // Default to CHIPI — unknown hashes are more likely to be older CHIPI deployments\n return \"CHIPI\";\n}\n\n// RPC endpoints per wallet type — any standard Starknet RPC works for all wallet types.\n// Override via STARKNET_RPC_URL env var; falls back to the default Infura endpoint.\nexport const WALLET_RPC_ENDPOINTS: Record<WalletType, string> = {\n CHIPI: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,\n READY: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,\n};\n\n// Paymaster configuration\nexport const PAYMASTER_CONFIG = {\n URL: \"https://paymaster.chipipay.com\",\n} as const;\n\n// Session key configuration (CHIPI wallets only - SNIP-9 compatible)\nexport const SESSION_DEFAULTS = {\n /** Default session duration: 6 hours in seconds */\n DURATION_SECONDS: 21600,\n /** Default max calls per session */\n MAX_CALLS: 1000,\n} as const;\n\n// Session-specific error codes\nexport const SESSION_ERRORS = {\n /** Session keys only work with CHIPI wallets */\n INVALID_WALLET_TYPE_FOR_SESSION: \"INVALID_WALLET_TYPE_FOR_SESSION\",\n /** Session has expired (validUntil < now) */\n SESSION_EXPIRED: \"SESSION_EXPIRED\",\n /** Session key not registered on contract */\n SESSION_NOT_REGISTERED: \"SESSION_NOT_REGISTERED\",\n /** Session key has been revoked */\n SESSION_REVOKED: \"SESSION_REVOKED\",\n /** Session has exceeded max calls */\n SESSION_MAX_CALLS_EXCEEDED: \"SESSION_MAX_CALLS_EXCEEDED\",\n /** Entrypoint not allowed for this session */\n SESSION_ENTRYPOINT_NOT_ALLOWED: \"SESSION_ENTRYPOINT_NOT_ALLOWED\",\n /** Failed to decrypt session private key */\n SESSION_DECRYPTION_FAILED: \"SESSION_DECRYPTION_FAILED\",\n /** Failed to create session key */\n SESSION_CREATION_FAILED: \"SESSION_CREATION_FAILED\",\n} as const;\n\n// Session contract entrypoint names\nexport const SESSION_ENTRYPOINTS = {\n /** Add or update a session key (owner only) */\n ADD_OR_UPDATE: \"add_or_update_session_key\",\n /** Revoke a session key (owner only) */\n REVOKE: \"revoke_session_key\",\n /** Query session data (public read) */\n GET_DATA: \"get_session_data\",\n} as const;\n"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { createPaginatedResponse, deepMerge, formatAmount, isValidAddress, isValidApiKey, parseAmount, retry, sanitizeUrl, sleep, validatePagination } from './utils/index.mjs';
|
|
2
|
-
export { API_ENDPOINTS, API_VERSIONING, CARRIER_IDS, CHAIN_TOKEN_TYPES, CHAIN_TYPES, CONTRACT_ADDRESSES, ERRORS, PAYMASTER_CONFIG, SERVICE_TYPES, SESSION_DEFAULTS, SESSION_ENTRYPOINTS, SESSION_ERRORS, SKU_CONTRACTS, STARKNET_NETWORKS, TOKEN_DECIMALS, WALLET_CLASS_HASHES, WALLET_RPC_ENDPOINTS } from './constants/index.mjs';
|
|
2
|
+
export { API_ENDPOINTS, API_VERSIONING, CARRIER_IDS, CHAIN_TOKEN_TYPES, CHAIN_TYPES, CONTRACT_ADDRESSES, ERRORS, LEGACY_CHIPI_CLASS_HASHES, PAYMASTER_CONFIG, SERVICE_TYPES, SESSION_DEFAULTS, SESSION_ENTRYPOINTS, SESSION_ERRORS, SKU_CONTRACTS, STARKNET_NETWORKS, TOKEN_DECIMALS, WALLET_CLASS_HASHES, WALLET_RPC_ENDPOINTS, getWalletTypeFromClassHash } from './constants/index.mjs';
|
|
3
3
|
import { ErrorWithCode } from '@chipi-stack/types';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
|
|
@@ -32,7 +32,15 @@ declare class ChipiValidationError extends ChipiError {
|
|
|
32
32
|
declare class ChipiAuthError extends ChipiError {
|
|
33
33
|
constructor(message: string, code?: string);
|
|
34
34
|
}
|
|
35
|
-
declare function isChipiError(error:
|
|
35
|
+
declare function isChipiError(error: unknown): error is ChipiError;
|
|
36
|
+
/**
|
|
37
|
+
* Type guard to check if an error has an HTTP status property.
|
|
38
|
+
* Useful for retry logic where you need to distinguish API errors
|
|
39
|
+
* (which have status codes) from network errors (which don't).
|
|
40
|
+
*/
|
|
41
|
+
declare function hasHttpStatus(error: unknown): error is {
|
|
42
|
+
status: number;
|
|
43
|
+
};
|
|
36
44
|
declare function handleApiError(error: any): ChipiError;
|
|
37
45
|
|
|
38
46
|
/**
|
|
@@ -46,8 +54,8 @@ declare function formatNumber(value: number, options?: {
|
|
|
46
54
|
}): string;
|
|
47
55
|
declare function formatDate(date: Date | string, options?: {
|
|
48
56
|
locale?: string;
|
|
49
|
-
dateStyle?:
|
|
50
|
-
timeStyle?:
|
|
57
|
+
dateStyle?: "full" | "long" | "medium" | "short";
|
|
58
|
+
timeStyle?: "full" | "long" | "medium" | "short";
|
|
51
59
|
}): string;
|
|
52
60
|
declare function formatAddress(address: string, length?: number): string;
|
|
53
61
|
declare function formatTransactionHash(hash: string): string;
|
|
@@ -66,11 +74,17 @@ declare const ErrorResponseSchema: z.ZodObject<{
|
|
|
66
74
|
status: z.ZodOptional<z.ZodNumber>;
|
|
67
75
|
}, z.core.$strip>;
|
|
68
76
|
declare const SuccessResponseSchema: <T extends z.ZodTypeAny>(dataSchema: T) => z.ZodObject<{
|
|
77
|
+
message: z.ZodOptional<z.ZodString>;
|
|
78
|
+
code: z.ZodOptional<z.ZodString>;
|
|
69
79
|
data: T;
|
|
70
80
|
}, z.core.$strip>;
|
|
71
|
-
type ApiResponse<T> =
|
|
81
|
+
type ApiResponse<T> = {
|
|
82
|
+
data: T;
|
|
83
|
+
message?: string;
|
|
84
|
+
code?: string;
|
|
85
|
+
};
|
|
72
86
|
type ErrorResponse = z.infer<typeof ErrorResponseSchema>;
|
|
73
87
|
declare function validateApiResponse<T>(response: unknown, dataSchema: z.ZodType<T>): void;
|
|
74
88
|
declare function validateErrorResponse(response: unknown): ErrorResponse;
|
|
75
89
|
|
|
76
|
-
export { type ApiResponse, ApiResponseSchema, ChipiApiError, ChipiAuthError, ChipiError, ChipiSessionError, ChipiSkuError, ChipiTransactionError, ChipiValidationError, ChipiWalletError, type ErrorResponse, ErrorResponseSchema, SuccessResponseSchema, camelToSnake, capitalizeFirst, formatAddress, formatCurrency, formatDate, formatNumber, formatTransactionHash, handleApiError, isChipiError, snakeToCamel, validateApiResponse, validateErrorResponse };
|
|
90
|
+
export { type ApiResponse, ApiResponseSchema, ChipiApiError, ChipiAuthError, ChipiError, ChipiSessionError, ChipiSkuError, ChipiTransactionError, ChipiValidationError, ChipiWalletError, type ErrorResponse, ErrorResponseSchema, SuccessResponseSchema, camelToSnake, capitalizeFirst, formatAddress, formatCurrency, formatDate, formatNumber, formatTransactionHash, handleApiError, hasHttpStatus, isChipiError, snakeToCamel, validateApiResponse, validateErrorResponse };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { createPaginatedResponse, deepMerge, formatAmount, isValidAddress, isValidApiKey, parseAmount, retry, sanitizeUrl, sleep, validatePagination } from './utils/index.js';
|
|
2
|
-
export { API_ENDPOINTS, API_VERSIONING, CARRIER_IDS, CHAIN_TOKEN_TYPES, CHAIN_TYPES, CONTRACT_ADDRESSES, ERRORS, PAYMASTER_CONFIG, SERVICE_TYPES, SESSION_DEFAULTS, SESSION_ENTRYPOINTS, SESSION_ERRORS, SKU_CONTRACTS, STARKNET_NETWORKS, TOKEN_DECIMALS, WALLET_CLASS_HASHES, WALLET_RPC_ENDPOINTS } from './constants/index.js';
|
|
2
|
+
export { API_ENDPOINTS, API_VERSIONING, CARRIER_IDS, CHAIN_TOKEN_TYPES, CHAIN_TYPES, CONTRACT_ADDRESSES, ERRORS, LEGACY_CHIPI_CLASS_HASHES, PAYMASTER_CONFIG, SERVICE_TYPES, SESSION_DEFAULTS, SESSION_ENTRYPOINTS, SESSION_ERRORS, SKU_CONTRACTS, STARKNET_NETWORKS, TOKEN_DECIMALS, WALLET_CLASS_HASHES, WALLET_RPC_ENDPOINTS, getWalletTypeFromClassHash } from './constants/index.js';
|
|
3
3
|
import { ErrorWithCode } from '@chipi-stack/types';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
|
|
@@ -32,7 +32,15 @@ declare class ChipiValidationError extends ChipiError {
|
|
|
32
32
|
declare class ChipiAuthError extends ChipiError {
|
|
33
33
|
constructor(message: string, code?: string);
|
|
34
34
|
}
|
|
35
|
-
declare function isChipiError(error:
|
|
35
|
+
declare function isChipiError(error: unknown): error is ChipiError;
|
|
36
|
+
/**
|
|
37
|
+
* Type guard to check if an error has an HTTP status property.
|
|
38
|
+
* Useful for retry logic where you need to distinguish API errors
|
|
39
|
+
* (which have status codes) from network errors (which don't).
|
|
40
|
+
*/
|
|
41
|
+
declare function hasHttpStatus(error: unknown): error is {
|
|
42
|
+
status: number;
|
|
43
|
+
};
|
|
36
44
|
declare function handleApiError(error: any): ChipiError;
|
|
37
45
|
|
|
38
46
|
/**
|
|
@@ -46,8 +54,8 @@ declare function formatNumber(value: number, options?: {
|
|
|
46
54
|
}): string;
|
|
47
55
|
declare function formatDate(date: Date | string, options?: {
|
|
48
56
|
locale?: string;
|
|
49
|
-
dateStyle?:
|
|
50
|
-
timeStyle?:
|
|
57
|
+
dateStyle?: "full" | "long" | "medium" | "short";
|
|
58
|
+
timeStyle?: "full" | "long" | "medium" | "short";
|
|
51
59
|
}): string;
|
|
52
60
|
declare function formatAddress(address: string, length?: number): string;
|
|
53
61
|
declare function formatTransactionHash(hash: string): string;
|
|
@@ -66,11 +74,17 @@ declare const ErrorResponseSchema: z.ZodObject<{
|
|
|
66
74
|
status: z.ZodOptional<z.ZodNumber>;
|
|
67
75
|
}, z.core.$strip>;
|
|
68
76
|
declare const SuccessResponseSchema: <T extends z.ZodTypeAny>(dataSchema: T) => z.ZodObject<{
|
|
77
|
+
message: z.ZodOptional<z.ZodString>;
|
|
78
|
+
code: z.ZodOptional<z.ZodString>;
|
|
69
79
|
data: T;
|
|
70
80
|
}, z.core.$strip>;
|
|
71
|
-
type ApiResponse<T> =
|
|
81
|
+
type ApiResponse<T> = {
|
|
82
|
+
data: T;
|
|
83
|
+
message?: string;
|
|
84
|
+
code?: string;
|
|
85
|
+
};
|
|
72
86
|
type ErrorResponse = z.infer<typeof ErrorResponseSchema>;
|
|
73
87
|
declare function validateApiResponse<T>(response: unknown, dataSchema: z.ZodType<T>): void;
|
|
74
88
|
declare function validateErrorResponse(response: unknown): ErrorResponse;
|
|
75
89
|
|
|
76
|
-
export { type ApiResponse, ApiResponseSchema, ChipiApiError, ChipiAuthError, ChipiError, ChipiSessionError, ChipiSkuError, ChipiTransactionError, ChipiValidationError, ChipiWalletError, type ErrorResponse, ErrorResponseSchema, SuccessResponseSchema, camelToSnake, capitalizeFirst, formatAddress, formatCurrency, formatDate, formatNumber, formatTransactionHash, handleApiError, isChipiError, snakeToCamel, validateApiResponse, validateErrorResponse };
|
|
90
|
+
export { type ApiResponse, ApiResponseSchema, ChipiApiError, ChipiAuthError, ChipiError, ChipiSessionError, ChipiSkuError, ChipiTransactionError, ChipiValidationError, ChipiWalletError, type ErrorResponse, ErrorResponseSchema, SuccessResponseSchema, camelToSnake, capitalizeFirst, formatAddress, formatCurrency, formatDate, formatNumber, formatTransactionHash, handleApiError, hasHttpStatus, isChipiError, snakeToCamel, validateApiResponse, validateErrorResponse };
|
package/dist/index.js
CHANGED
|
@@ -95,9 +95,12 @@ var API_VERSIONING = {
|
|
|
95
95
|
VERSION_DATE: "2025-12-30"
|
|
96
96
|
// Detailed version - sent as query param for tracking
|
|
97
97
|
};
|
|
98
|
+
var DEFAULT_MAINNET_RPC = "https://starknet-mainnet.infura.io/v3/4a4a1fdd7d704509aa99154fb29886e2";
|
|
99
|
+
var DEFAULT_SEPOLIA_RPC = "https://starknet-sepolia.infura.io/v3/4a4a1fdd7d704509aa99154fb29886e2";
|
|
98
100
|
var STARKNET_NETWORKS = {
|
|
99
|
-
MAINNET:
|
|
100
|
-
|
|
101
|
+
MAINNET: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,
|
|
102
|
+
MAINNET_FALLBACK: "https://rpc.starknet.lava.build",
|
|
103
|
+
SEPOLIA: process.env.STARKNET_RPC_URL_SEPOLIA ?? DEFAULT_SEPOLIA_RPC
|
|
101
104
|
};
|
|
102
105
|
var CONTRACT_ADDRESSES = {
|
|
103
106
|
USDC_MAINNET: "0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb",
|
|
@@ -154,12 +157,29 @@ var CHAIN_TOKEN_TYPES = {
|
|
|
154
157
|
};
|
|
155
158
|
var WALLET_CLASS_HASHES = {
|
|
156
159
|
CHIPI: "0x53f4f8791ed5bed0fddaa553d180c664e32cfaf8316bb232ae77bb08f459f2a",
|
|
157
|
-
// CHIPI: "0x2de1565226d5215a38b68c4d9a4913989b54edff64c68c45e453c417b44cd83", // Old class Hash
|
|
158
160
|
READY: "0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f"
|
|
159
161
|
};
|
|
162
|
+
var LEGACY_CHIPI_CLASS_HASHES = [
|
|
163
|
+
"0x2de1565226d5215a38b68c4d9a4913989b54edff64c68c45e453c417b44cd83"
|
|
164
|
+
// v28
|
|
165
|
+
];
|
|
166
|
+
function getWalletTypeFromClassHash(classHash) {
|
|
167
|
+
const normalized = classHash.toLowerCase().replace(/^0x0+/, "0x");
|
|
168
|
+
const normalize = (h) => h.toLowerCase().replace(/^0x0+/, "0x");
|
|
169
|
+
if (normalize(WALLET_CLASS_HASHES.READY) === normalized) {
|
|
170
|
+
return "READY";
|
|
171
|
+
}
|
|
172
|
+
if (normalize(WALLET_CLASS_HASHES.CHIPI) === normalized) {
|
|
173
|
+
return "CHIPI";
|
|
174
|
+
}
|
|
175
|
+
if (LEGACY_CHIPI_CLASS_HASHES.some((h) => normalize(h) === normalized)) {
|
|
176
|
+
return "CHIPI";
|
|
177
|
+
}
|
|
178
|
+
return "CHIPI";
|
|
179
|
+
}
|
|
160
180
|
var WALLET_RPC_ENDPOINTS = {
|
|
161
|
-
CHIPI:
|
|
162
|
-
READY:
|
|
181
|
+
CHIPI: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,
|
|
182
|
+
READY: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC
|
|
163
183
|
};
|
|
164
184
|
var PAYMASTER_CONFIG = {
|
|
165
185
|
URL: "https://paymaster.chipipay.com"
|
|
@@ -236,6 +256,7 @@ var ChipiSessionError = class extends ChipiError {
|
|
|
236
256
|
var ChipiSkuError = class extends ChipiError {
|
|
237
257
|
constructor(message, code = "SKU_ERROR") {
|
|
238
258
|
super(message, code);
|
|
259
|
+
this.name = "ChipiSkuError";
|
|
239
260
|
}
|
|
240
261
|
};
|
|
241
262
|
var ChipiValidationError = class extends ChipiError {
|
|
@@ -253,20 +274,25 @@ var ChipiAuthError = class extends ChipiError {
|
|
|
253
274
|
function isChipiError(error) {
|
|
254
275
|
return error instanceof ChipiError;
|
|
255
276
|
}
|
|
277
|
+
function hasHttpStatus(error) {
|
|
278
|
+
return typeof error === "object" && error !== null && "status" in error && typeof error.status === "number";
|
|
279
|
+
}
|
|
256
280
|
function handleApiError(error) {
|
|
257
281
|
if (isChipiError(error)) {
|
|
258
282
|
return error;
|
|
259
283
|
}
|
|
260
|
-
if (error?.response?.status) {
|
|
284
|
+
if (typeof error?.response?.status === "number") {
|
|
261
285
|
const status = error.response.status;
|
|
262
286
|
const message = error.response.data?.message || error.message || "API request failed";
|
|
263
287
|
const code = error.response.data?.code || `HTTP_${status}`;
|
|
264
288
|
return new ChipiApiError(message, code, status);
|
|
265
289
|
}
|
|
266
|
-
|
|
267
|
-
error?.message || "
|
|
268
|
-
|
|
269
|
-
|
|
290
|
+
if (error?.status && typeof error.status === "number") {
|
|
291
|
+
const message = error?.message || "API request failed";
|
|
292
|
+
const code = error?.code || `HTTP_${error.status}`;
|
|
293
|
+
return new ChipiApiError(message, code, error.status);
|
|
294
|
+
}
|
|
295
|
+
return new ChipiError(error?.message || "An unknown error occurred", "UNKNOWN_ERROR");
|
|
270
296
|
}
|
|
271
297
|
|
|
272
298
|
// src/formatters.ts
|
|
@@ -320,18 +346,18 @@ var ErrorResponseSchema = zod.z.object({
|
|
|
320
346
|
code: zod.z.string().optional(),
|
|
321
347
|
status: zod.z.number().optional()
|
|
322
348
|
});
|
|
323
|
-
var SuccessResponseSchema = (dataSchema) =>
|
|
349
|
+
var SuccessResponseSchema = (dataSchema) => ApiResponseSchema.extend({
|
|
324
350
|
data: dataSchema
|
|
325
351
|
});
|
|
326
352
|
function validateApiResponse(response, dataSchema) {
|
|
327
353
|
const result = SuccessResponseSchema(dataSchema).safeParse(response);
|
|
328
|
-
if (!result.
|
|
354
|
+
if (!result.success) {
|
|
329
355
|
throw new Error(`Invalid API response format: ${result.error.message}`);
|
|
330
356
|
}
|
|
331
357
|
}
|
|
332
358
|
function validateErrorResponse(response) {
|
|
333
359
|
const result = ErrorResponseSchema.safeParse(response);
|
|
334
|
-
if (result.
|
|
360
|
+
if (result.success) {
|
|
335
361
|
return result.data;
|
|
336
362
|
}
|
|
337
363
|
return {
|
|
@@ -357,6 +383,7 @@ exports.ChipiValidationError = ChipiValidationError;
|
|
|
357
383
|
exports.ChipiWalletError = ChipiWalletError;
|
|
358
384
|
exports.ERRORS = ERRORS;
|
|
359
385
|
exports.ErrorResponseSchema = ErrorResponseSchema;
|
|
386
|
+
exports.LEGACY_CHIPI_CLASS_HASHES = LEGACY_CHIPI_CLASS_HASHES;
|
|
360
387
|
exports.PAYMASTER_CONFIG = PAYMASTER_CONFIG;
|
|
361
388
|
exports.SERVICE_TYPES = SERVICE_TYPES;
|
|
362
389
|
exports.SESSION_DEFAULTS = SESSION_DEFAULTS;
|
|
@@ -378,7 +405,9 @@ exports.formatCurrency = formatCurrency;
|
|
|
378
405
|
exports.formatDate = formatDate;
|
|
379
406
|
exports.formatNumber = formatNumber;
|
|
380
407
|
exports.formatTransactionHash = formatTransactionHash;
|
|
408
|
+
exports.getWalletTypeFromClassHash = getWalletTypeFromClassHash;
|
|
381
409
|
exports.handleApiError = handleApiError;
|
|
410
|
+
exports.hasHttpStatus = hasHttpStatus;
|
|
382
411
|
exports.isChipiError = isChipiError;
|
|
383
412
|
exports.isValidAddress = isValidAddress;
|
|
384
413
|
exports.isValidApiKey = isValidApiKey;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/index.ts","../src/constants/index.ts","../src/errors.ts","../src/formatters.ts","../src/validation.ts"],"names":["amountBN","z"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n PaginationQuery,\n PaginatedResponse,\n Currency,\n} from \"@chipi-stack/types\";\nimport { API_ENDPOINTS } from \"../constants\";\n\n/**\n * Utility functions used across Chipi SDK packages\n */\n\nexport function isValidAddress(address: string): boolean {\n // Validate Starknet address format\n return /^0x[0-9a-fA-F]{1,64}$/.test(address);\n}\n\nexport function isValidApiKey(apiKey: string): boolean {\n // Validate API key format (pk_dev_ or pk_prod_)\n return /^pk_(dev|prod)_[a-zA-Z0-9]{32,}$/.test(apiKey);\n}\n\nexport function formatAmount(amount: string, decimals: number = 18): string {\n // If it's an integer, multiply by 10^decimals\n if (!amount.includes(\".\")) {\n const amountBN = BigInt(amount) * BigInt(10) ** BigInt(decimals);\n return amountBN.toString();\n }\n\n // If it has decimals, handle properly\n const [integerPart, decimalPart = \"\"] = amount.split(\".\");\n const paddedDecimal = decimalPart.padEnd(decimals, \"0\").slice(0, decimals);\n const amountBN = BigInt(integerPart + paddedDecimal);\n\n return amountBN.toString();\n}\n\nexport function parseAmount(amount: string, decimals: number = 18): number {\n const amountBN = BigInt(amount);\n const divisor = BigInt(10) ** BigInt(decimals);\n return Number(amountBN) / Number(divisor);\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function retry<T>(\n fn: () => Promise<T>,\n options: {\n maxAttempts?: number;\n delay?: number;\n backoff?: boolean;\n } = {},\n): Promise<T> {\n const { maxAttempts = 3, delay = 1000, backoff = true } = options;\n\n return new Promise((resolve, reject) => {\n let attempt = 0;\n\n const tryFn = async () => {\n try {\n const result = await fn();\n resolve(result);\n } catch (error) {\n attempt++;\n\n if (attempt >= maxAttempts) {\n reject(error);\n return;\n }\n\n const waitTime = backoff ? delay * Math.pow(2, attempt - 1) : delay;\n setTimeout(tryFn, waitTime);\n }\n };\n\n tryFn();\n });\n}\n\nexport function createPaginatedResponse<T>(\n data: T[],\n query: PaginationQuery,\n total: number,\n): PaginatedResponse<T> {\n const page = query.page || 1;\n const limit = query.limit || 10;\n const totalPages = Math.ceil(total / limit);\n\n return {\n data,\n total,\n page,\n limit,\n totalPages,\n };\n}\n\nexport function validatePagination(query: PaginationQuery): {\n page: number;\n limit: number;\n} {\n const page = Math.max(1, query.page || 1);\n const limit = Math.min(100, Math.max(1, query.limit || 10));\n\n return { page, limit };\n}\n\nexport function sanitizeUrl(url: string): string {\n try {\n const parsed = new URL(url);\n return parsed.toString();\n } catch (error) {\n throw new Error(`Invalid URL: ${url}`);\n }\n}\n\nexport function deepMerge<T extends Record<string, any>>(\n target: T,\n source: Partial<T>,\n): T {\n const result = { ...target };\n\n for (const key in source) {\n if (source[key] !== undefined) {\n const sourceValue = source[key];\n if (\n typeof sourceValue === \"object\" &&\n sourceValue !== null &&\n !Array.isArray(sourceValue) &&\n typeof result[key] === \"object\" &&\n result[key] !== null &&\n !Array.isArray(result[key])\n ) {\n result[key] = deepMerge(result[key], sourceValue);\n } else {\n result[key] = sourceValue as T[Extract<keyof T, string>];\n }\n }\n }\n\n return result;\n}\n","/**\n * Constants used across Chipi SDK packages\n */\n\nimport { WalletType } from \"@chipi-stack/types\";\n\n/**\n * API Versioning\n * - VERSION: Major version for path-based versioning (/v1, /v2, etc.)\n * - VERSION_DATE: Detailed version for tracking breaking changes (YYYY-MM-DD format)\n *\n * Update VERSION_DATE when making API changes.\n * Update VERSION when making major breaking changes (typically 1-2 times per year).\n */\nexport const API_VERSIONING = {\n VERSION: \"1\", // Major version - used in URL path\n VERSION_DATE: \"2025-12-30\", // Detailed version - sent as query param for tracking\n} as const;\n\nexport const STARKNET_NETWORKS = {\n MAINNET: \"https://starknet-mainnet.public.blastapi.io/rpc/v0_7\",\n SEPOLIA: \"https://starknet-sepolia.public.blastapi.io/rpc/v0_7\",\n} as const;\n\nexport const CONTRACT_ADDRESSES = {\n USDC_MAINNET:\n \"0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb\", // Changed to Native USDC (was bridged USDC.e)\n VESU_USDC_MAINNET:\n \"0x017f19582c61479f2fe0b6606300e975c0a8f439102f43eeecc1d0e9b3d84350\",\n} as const;\n\nexport const TOKEN_DECIMALS = {\n USDC: 6,\n USDT: 6,\n ETH: 18,\n STRK: 18,\n DAI: 18,\n} as const;\n\nexport const API_ENDPOINTS = {\n CHIPI_WALLETS: \"/chipi-wallets\",\n TRANSACTIONS: \"/transactions\",\n SKUS: \"/skus\",\n SKU_PURCHASES: \"/sku-purchases\",\n EXCHANGES: \"/exchanges\",\n USERS: \"/users\",\n} as const;\n\nexport const ERRORS = {\n INVALID_API_KEY: \"INVALID_API_KEY\",\n WALLET_NOT_FOUND: \"WALLET_NOT_FOUND\",\n INSUFFICIENT_BALANCE: \"INSUFFICIENT_BALANCE\",\n TRANSACTION_FAILED: \"TRANSACTION_FAILED\",\n INVALID_SIGNATURE: \"INVALID_SIGNATURE\",\n SKU_NOT_FOUND: \"SKU_NOT_FOUND\",\n SKU_UNAVAILABLE: \"SKU_UNAVAILABLE\",\n} as const;\n\nexport const SKU_CONTRACTS = {\n RECHARGER_WITH_STRK_MAINNET:\n \"0x02d65bb726d2c29e3c97669cf297c5145eac19284fb6f935c05c0bfc68dae2b7\", //changed contract address used to be 0x0f3\n CHIPI_BILL_SERVICE:\n \"0x4e8150110d580069de26adec9b179023289d55859ea07487aaade5458d7aa8b\",\n} as const;\n\n// Service types\nexport const SERVICE_TYPES = {\n BUY_SERVICE: \"BUY_SERVICE\",\n} as const;\n\n// Carrier IDs\nexport const CARRIER_IDS = {\n CHIPI_PAY: \"chipi_pay\",\n} as const;\n\nexport const CHAIN_TYPES = {\n STARKNET: \"STARKNET\",\n} as const;\n\nexport const CHAIN_TOKEN_TYPES = {\n USDC: \"USDC\", // Changed to Native USDC (was bridged USDC.e)\n USDT: \"USDT\",\n ETH: \"ETH\",\n STRK: \"STRK\",\n DAI: \"DAI\",\n WBTC: \"WBTC\",\n OTHER: \"OTHER\",\n} as const;\n\nexport const WALLET_CLASS_HASHES: Record<WalletType, string> = {\n CHIPI: \"0x53f4f8791ed5bed0fddaa553d180c664e32cfaf8316bb232ae77bb08f459f2a\",\n // CHIPI: \"0x2de1565226d5215a38b68c4d9a4913989b54edff64c68c45e453c417b44cd83\", // Old class Hash\n READY: \"0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f\",\n};\n\n// RPC endpoints per wallet type\nexport const WALLET_RPC_ENDPOINTS: Record<WalletType, string> = {\n CHIPI: \"https://starknet-mainnet.public.blastapi.io/rpc/v0_7\",\n READY: \"https://cloud.argent-api.com/v1/starknet/mainnet/rpc/v0.7\",\n};\n\n// Paymaster configuration\nexport const PAYMASTER_CONFIG = {\n URL: \"https://paymaster.chipipay.com\",\n} as const;\n\n// Session key configuration (CHIPI wallets only - SNIP-9 compatible)\nexport const SESSION_DEFAULTS = {\n /** Default session duration: 6 hours in seconds */\n DURATION_SECONDS: 21600,\n /** Default max calls per session */\n MAX_CALLS: 1000,\n} as const;\n\n// Session-specific error codes\nexport const SESSION_ERRORS = {\n /** Session keys only work with CHIPI wallets */\n INVALID_WALLET_TYPE_FOR_SESSION: \"INVALID_WALLET_TYPE_FOR_SESSION\",\n /** Session has expired (validUntil < now) */\n SESSION_EXPIRED: \"SESSION_EXPIRED\",\n /** Session key not registered on contract */\n SESSION_NOT_REGISTERED: \"SESSION_NOT_REGISTERED\",\n /** Session key has been revoked */\n SESSION_REVOKED: \"SESSION_REVOKED\",\n /** Session has exceeded max calls */\n SESSION_MAX_CALLS_EXCEEDED: \"SESSION_MAX_CALLS_EXCEEDED\",\n /** Entrypoint not allowed for this session */\n SESSION_ENTRYPOINT_NOT_ALLOWED: \"SESSION_ENTRYPOINT_NOT_ALLOWED\",\n /** Failed to decrypt session private key */\n SESSION_DECRYPTION_FAILED: \"SESSION_DECRYPTION_FAILED\",\n /** Failed to create session key */\n SESSION_CREATION_FAILED: \"SESSION_CREATION_FAILED\",\n} as const;\n\n// Session contract entrypoint names\nexport const SESSION_ENTRYPOINTS = {\n /** Add or update a session key (owner only) */\n ADD_OR_UPDATE: \"add_or_update_session_key\",\n /** Revoke a session key (owner only) */\n REVOKE: \"revoke_session_key\",\n /** Query session data (public read) */\n GET_DATA: \"get_session_data\",\n} as const;\n","import type { ErrorWithCode } from '@chipi-stack/types';\n\n/**\n * Error classes and utilities for Chipi SDK\n */\n\nexport class ChipiError extends Error implements ErrorWithCode {\n public readonly code: string;\n public readonly status?: number;\n\n constructor(message: string, code: string, status?: number) {\n super(message);\n this.name = 'ChipiError';\n this.code = code;\n this.status = status;\n \n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ChipiError);\n }\n }\n}\n\nexport class ChipiApiError extends ChipiError {\n constructor(message: string, code: string, status: number) {\n super(message, code, status);\n this.name = 'ChipiApiError';\n }\n}\n\nexport class ChipiWalletError extends ChipiError {\n constructor(message: string, code: string = 'WALLET_ERROR') {\n super(message, code);\n this.name = 'ChipiWalletError';\n }\n}\n\nexport class ChipiTransactionError extends ChipiError {\n constructor(message: string, code: string = 'TRANSACTION_ERROR') {\n super(message, code);\n this.name = 'ChipiTransactionError';\n }\n}\n\nexport class ChipiSessionError extends ChipiError {\n constructor(message: string, code: string = 'SESSION_ERROR') {\n super(message, code);\n this.name = 'ChipiSessionError';\n }\n}\n\nexport class ChipiSkuError extends ChipiError {\n constructor(message: string, code: string = 'SKU_ERROR') {\n super(message, code);\n }\n}\n\nexport class ChipiValidationError extends ChipiError {\n constructor(message: string, code: string = 'VALIDATION_ERROR') {\n super(message, code, 400);\n this.name = 'ChipiValidationError';\n }\n}\n\nexport class ChipiAuthError extends ChipiError {\n constructor(message: string, code: string = 'AUTH_ERROR') {\n super(message, code, 401);\n this.name = 'ChipiAuthError';\n }\n}\n\nexport function isChipiError(error: any): error is ChipiError {\n return error instanceof ChipiError;\n}\n\nexport function handleApiError(error: any): ChipiError {\n if (isChipiError(error)) {\n return error;\n }\n\n if (error?.response?.status) {\n const status = error.response.status;\n const message = error.response.data?.message || error.message || 'API request failed';\n const code = error.response.data?.code || `HTTP_${status}`;\n \n return new ChipiApiError(message, code, status);\n }\n\n return new ChipiError(\n error?.message || 'An unknown error occurred',\n 'UNKNOWN_ERROR'\n );\n}\n","/**\n * Data formatters and transformers for Chipi SDK\n */\n\nexport function formatCurrency(\n amount: number,\n currency: string = 'USD',\n locale: string = 'en-US'\n): string {\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n }).format(amount);\n}\n\nexport function formatNumber(\n value: number,\n options: {\n decimals?: number;\n locale?: string;\n compact?: boolean;\n } = {}\n): string {\n const { decimals = 2, locale = 'en-US', compact = false } = options;\n \n return new Intl.NumberFormat(locale, {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n notation: compact ? 'compact' : 'standard',\n }).format(value);\n}\n\nexport function formatDate(\n date: Date | string,\n options: {\n locale?: string;\n dateStyle?: 'full' | 'long' | 'medium' | 'short';\n timeStyle?: 'full' | 'long' | 'medium' | 'short';\n } = {}\n): string {\n const { locale = 'en-US', dateStyle = 'medium', timeStyle } = options;\n const dateObj = typeof date === 'string' ? new Date(date) : date;\n \n return new Intl.DateTimeFormat(locale, {\n dateStyle,\n timeStyle,\n }).format(dateObj);\n}\n\nexport function formatAddress(address: string, length: number = 8): string {\n if (address.length <= length * 2) {\n return address;\n }\n \n return `${address.slice(0, length)}...${address.slice(-length)}`;\n}\n\nexport function formatTransactionHash(hash: string): string {\n return formatAddress(hash, 6);\n}\n\n\n\nexport function camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);\n}\n\nexport function snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n}\n\nexport function capitalizeFirst(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n","import { z } from \"zod\";\n\n// Base API response schema\nexport const ApiResponseSchema = z.object({\n data: z.unknown(),\n message: z.string().optional(),\n code: z.string().optional(),\n});\n\n// Error response schema\nexport const ErrorResponseSchema = z.object({\n message: z.string(),\n code: z.string().optional(),\n status: z.number().optional(),\n});\n\n// Generic success response schema\nexport const SuccessResponseSchema = <T extends z.ZodTypeAny>(dataSchema: T) =>\n z.object({\n data: dataSchema,\n });\n\n// Type helpers\nexport type ApiResponse<T> = z.infer<\n ReturnType<typeof SuccessResponseSchema<z.ZodType<T>>>\n>;\nexport type ErrorResponse = z.infer<typeof ErrorResponseSchema>;\n\n// Validation functions\n// This is not very good nor useful without passing a data schema\nexport function validateApiResponse<T>(\n response: unknown,\n dataSchema: z.ZodType<T>\n): void {\n // Validate with specific data schema\n const result = SuccessResponseSchema(dataSchema).safeParse(response);\n if (!result.data) {\n throw new Error(`Invalid API response format: ${result.error.message}`);\n }\n}\n\nexport function validateErrorResponse(response: unknown): ErrorResponse {\n const result = ErrorResponseSchema.safeParse(response);\n if (result.data) {\n return result.data;\n }\n\n // Fallback for malformed error responses\n return {\n message: \"Unknown error occurred\",\n code: \"UNKNOWN_ERROR\",\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/index.ts","../src/constants/index.ts","../src/errors.ts","../src/formatters.ts","../src/validation.ts"],"names":["amountBN","z"],"mappings":"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","file":"index.js","sourcesContent":["import type { PaginationQuery, PaginatedResponse, Currency } from \"@chipi-stack/types\";\nimport { API_ENDPOINTS } from \"../constants\";\n\n/**\n * Utility functions used across Chipi SDK packages\n */\n\nexport function isValidAddress(address: string): boolean {\n // Validate Starknet address format\n return /^0x[0-9a-fA-F]{1,64}$/.test(address);\n}\n\nexport function isValidApiKey(apiKey: string): boolean {\n // Validate API key format (pk_dev_ or pk_prod_)\n return /^pk_(dev|prod)_[a-zA-Z0-9]{32,}$/.test(apiKey);\n}\n\nexport function formatAmount(amount: string, decimals: number = 18): string {\n // If it's an integer, multiply by 10^decimals\n if (!amount.includes(\".\")) {\n const amountBN = BigInt(amount) * BigInt(10) ** BigInt(decimals);\n return amountBN.toString();\n }\n\n // If it has decimals, handle properly\n const [integerPart, decimalPart = \"\"] = amount.split(\".\");\n const paddedDecimal = decimalPart.padEnd(decimals, \"0\").slice(0, decimals);\n const amountBN = BigInt(integerPart + paddedDecimal);\n\n return amountBN.toString();\n}\n\nexport function parseAmount(amount: string, decimals: number = 18): number {\n const amountBN = BigInt(amount);\n const divisor = BigInt(10) ** BigInt(decimals);\n return Number(amountBN) / Number(divisor);\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function retry<T>(\n fn: () => Promise<T>,\n options: {\n maxAttempts?: number;\n delay?: number;\n backoff?: boolean;\n } = {}\n): Promise<T> {\n const { maxAttempts = 3, delay = 1000, backoff = true } = options;\n\n return new Promise((resolve, reject) => {\n let attempt = 0;\n\n const tryFn = async () => {\n try {\n const result = await fn();\n resolve(result);\n } catch (error) {\n attempt++;\n\n if (attempt >= maxAttempts) {\n reject(error);\n return;\n }\n\n const waitTime = backoff ? delay * Math.pow(2, attempt - 1) : delay;\n setTimeout(tryFn, waitTime);\n }\n };\n\n tryFn();\n });\n}\n\nexport function createPaginatedResponse<T>(\n data: T[],\n query: PaginationQuery,\n total: number\n): PaginatedResponse<T> {\n const page = query.page || 1;\n const limit = query.limit || 10;\n const totalPages = Math.ceil(total / limit);\n\n return {\n data,\n total,\n page,\n limit,\n totalPages,\n };\n}\n\nexport function validatePagination(query: PaginationQuery): {\n page: number;\n limit: number;\n} {\n const page = Math.max(1, query.page || 1);\n const limit = Math.min(100, Math.max(1, query.limit || 10));\n\n return { page, limit };\n}\n\nexport function sanitizeUrl(url: string): string {\n try {\n const parsed = new URL(url);\n return parsed.toString();\n } catch (error) {\n throw new Error(`Invalid URL: ${url}`);\n }\n}\n\nexport function deepMerge<T extends Record<string, any>>(target: T, source: Partial<T>): T {\n const result = { ...target };\n\n for (const key in source) {\n if (source[key] !== undefined) {\n const sourceValue = source[key];\n if (\n typeof sourceValue === \"object\" &&\n sourceValue !== null &&\n !Array.isArray(sourceValue) &&\n typeof result[key] === \"object\" &&\n result[key] !== null &&\n !Array.isArray(result[key])\n ) {\n result[key] = deepMerge(result[key], sourceValue);\n } else {\n result[key] = sourceValue as T[Extract<keyof T, string>];\n }\n }\n }\n\n return result;\n}\n","/**\n * Constants used across Chipi SDK packages\n */\n\nimport { WalletType } from \"@chipi-stack/types\";\n\n/**\n * API Versioning\n * - VERSION: Major version for path-based versioning (/v1, /v2, etc.)\n * - VERSION_DATE: Detailed version for tracking breaking changes (YYYY-MM-DD format)\n *\n * Update VERSION_DATE when making API changes.\n * Update VERSION when making major breaking changes (typically 1-2 times per year).\n */\nexport const API_VERSIONING = {\n VERSION: \"1\", // Major version - used in URL path\n VERSION_DATE: \"2025-12-30\", // Detailed version - sent as query param for tracking\n} as const;\n\n// Default RPC URLs — override via STARKNET_RPC_URL / STARKNET_RPC_URL_SEPOLIA env vars.\nconst DEFAULT_MAINNET_RPC =\n \"https://starknet-mainnet.infura.io/v3/4a4a1fdd7d704509aa99154fb29886e2\";\nconst DEFAULT_SEPOLIA_RPC =\n \"https://starknet-sepolia.infura.io/v3/4a4a1fdd7d704509aa99154fb29886e2\";\n\nexport const STARKNET_NETWORKS = {\n MAINNET: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,\n MAINNET_FALLBACK: \"https://rpc.starknet.lava.build\",\n SEPOLIA: process.env.STARKNET_RPC_URL_SEPOLIA ?? DEFAULT_SEPOLIA_RPC,\n} as const;\n\nexport const CONTRACT_ADDRESSES = {\n USDC_MAINNET: \"0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb\", // Changed to Native USDC (was bridged USDC.e)\n VESU_USDC_MAINNET: \"0x017f19582c61479f2fe0b6606300e975c0a8f439102f43eeecc1d0e9b3d84350\",\n} as const;\n\nexport const TOKEN_DECIMALS = {\n USDC: 6,\n USDT: 6,\n ETH: 18,\n STRK: 18,\n DAI: 18,\n} as const;\n\nexport const API_ENDPOINTS = {\n CHIPI_WALLETS: \"/chipi-wallets\",\n TRANSACTIONS: \"/transactions\",\n SKUS: \"/skus\",\n SKU_PURCHASES: \"/sku-purchases\",\n EXCHANGES: \"/exchanges\",\n USERS: \"/users\",\n} as const;\n\nexport const ERRORS = {\n INVALID_API_KEY: \"INVALID_API_KEY\",\n WALLET_NOT_FOUND: \"WALLET_NOT_FOUND\",\n INSUFFICIENT_BALANCE: \"INSUFFICIENT_BALANCE\",\n TRANSACTION_FAILED: \"TRANSACTION_FAILED\",\n INVALID_SIGNATURE: \"INVALID_SIGNATURE\",\n SKU_NOT_FOUND: \"SKU_NOT_FOUND\",\n SKU_UNAVAILABLE: \"SKU_UNAVAILABLE\",\n} as const;\n\nexport const SKU_CONTRACTS = {\n RECHARGER_WITH_STRK_MAINNET: \"0x02d65bb726d2c29e3c97669cf297c5145eac19284fb6f935c05c0bfc68dae2b7\", //changed contract address used to be 0x0f3\n CHIPI_BILL_SERVICE: \"0x4e8150110d580069de26adec9b179023289d55859ea07487aaade5458d7aa8b\",\n} as const;\n\n// Service types\nexport const SERVICE_TYPES = {\n BUY_SERVICE: \"BUY_SERVICE\",\n} as const;\n\n// Carrier IDs\nexport const CARRIER_IDS = {\n CHIPI_PAY: \"chipi_pay\",\n} as const;\n\nexport const CHAIN_TYPES = {\n STARKNET: \"STARKNET\",\n} as const;\n\nexport const CHAIN_TOKEN_TYPES = {\n USDC: \"USDC\", // Changed to Native USDC (was bridged USDC.e)\n USDT: \"USDT\",\n ETH: \"ETH\",\n STRK: \"STRK\",\n DAI: \"DAI\",\n WBTC: \"WBTC\",\n OTHER: \"OTHER\",\n} as const;\n\nexport const WALLET_CLASS_HASHES: Record<WalletType, string> = {\n CHIPI: \"0x53f4f8791ed5bed0fddaa553d180c664e32cfaf8316bb232ae77bb08f459f2a\",\n READY: \"0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f\",\n};\n\n/**\n * Previous CHIPI wallet class hashes that are still deployed on-chain.\n * Used by getWalletTypeFromClassHash() to identify legacy wallets.\n */\nexport const LEGACY_CHIPI_CLASS_HASHES: string[] = [\n \"0x2de1565226d5215a38b68c4d9a4913989b54edff64c68c45e453c417b44cd83\", // v28\n];\n\n/**\n * Determine wallet type from an on-chain class hash.\n * - If it matches the READY hash → READY\n * - If it matches the current CHIPI hash → CHIPI\n * - If it matches a legacy CHIPI hash → CHIPI\n * - Otherwise → CHIPI (safe default since CHIPI wallets have had multiple class hashes)\n */\nexport function getWalletTypeFromClassHash(classHash: string): WalletType {\n const normalized = classHash.toLowerCase().replace(/^0x0+/, \"0x\");\n const normalize = (h: string) => h.toLowerCase().replace(/^0x0+/, \"0x\");\n\n if (normalize(WALLET_CLASS_HASHES.READY) === normalized) {\n return \"READY\";\n }\n // Current or legacy CHIPI hashes\n if (normalize(WALLET_CLASS_HASHES.CHIPI) === normalized) {\n return \"CHIPI\";\n }\n if (LEGACY_CHIPI_CLASS_HASHES.some((h) => normalize(h) === normalized)) {\n return \"CHIPI\";\n }\n // Default to CHIPI — unknown hashes are more likely to be older CHIPI deployments\n return \"CHIPI\";\n}\n\n// RPC endpoints per wallet type — any standard Starknet RPC works for all wallet types.\n// Override via STARKNET_RPC_URL env var; falls back to the default Infura endpoint.\nexport const WALLET_RPC_ENDPOINTS: Record<WalletType, string> = {\n CHIPI: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,\n READY: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,\n};\n\n// Paymaster configuration\nexport const PAYMASTER_CONFIG = {\n URL: \"https://paymaster.chipipay.com\",\n} as const;\n\n// Session key configuration (CHIPI wallets only - SNIP-9 compatible)\nexport const SESSION_DEFAULTS = {\n /** Default session duration: 6 hours in seconds */\n DURATION_SECONDS: 21600,\n /** Default max calls per session */\n MAX_CALLS: 1000,\n} as const;\n\n// Session-specific error codes\nexport const SESSION_ERRORS = {\n /** Session keys only work with CHIPI wallets */\n INVALID_WALLET_TYPE_FOR_SESSION: \"INVALID_WALLET_TYPE_FOR_SESSION\",\n /** Session has expired (validUntil < now) */\n SESSION_EXPIRED: \"SESSION_EXPIRED\",\n /** Session key not registered on contract */\n SESSION_NOT_REGISTERED: \"SESSION_NOT_REGISTERED\",\n /** Session key has been revoked */\n SESSION_REVOKED: \"SESSION_REVOKED\",\n /** Session has exceeded max calls */\n SESSION_MAX_CALLS_EXCEEDED: \"SESSION_MAX_CALLS_EXCEEDED\",\n /** Entrypoint not allowed for this session */\n SESSION_ENTRYPOINT_NOT_ALLOWED: \"SESSION_ENTRYPOINT_NOT_ALLOWED\",\n /** Failed to decrypt session private key */\n SESSION_DECRYPTION_FAILED: \"SESSION_DECRYPTION_FAILED\",\n /** Failed to create session key */\n SESSION_CREATION_FAILED: \"SESSION_CREATION_FAILED\",\n} as const;\n\n// Session contract entrypoint names\nexport const SESSION_ENTRYPOINTS = {\n /** Add or update a session key (owner only) */\n ADD_OR_UPDATE: \"add_or_update_session_key\",\n /** Revoke a session key (owner only) */\n REVOKE: \"revoke_session_key\",\n /** Query session data (public read) */\n GET_DATA: \"get_session_data\",\n} as const;\n","import type { ErrorWithCode } from \"@chipi-stack/types\";\n\n/**\n * Error classes and utilities for Chipi SDK\n */\n\nexport class ChipiError extends Error implements ErrorWithCode {\n public readonly code: string;\n public readonly status?: number;\n\n constructor(message: string, code: string, status?: number) {\n super(message);\n this.name = \"ChipiError\";\n this.code = code;\n this.status = status;\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ChipiError);\n }\n }\n}\n\nexport class ChipiApiError extends ChipiError {\n constructor(message: string, code: string, status: number) {\n super(message, code, status);\n this.name = \"ChipiApiError\";\n }\n}\n\nexport class ChipiWalletError extends ChipiError {\n constructor(message: string, code: string = \"WALLET_ERROR\") {\n super(message, code);\n this.name = \"ChipiWalletError\";\n }\n}\n\nexport class ChipiTransactionError extends ChipiError {\n constructor(message: string, code: string = \"TRANSACTION_ERROR\") {\n super(message, code);\n this.name = \"ChipiTransactionError\";\n }\n}\n\nexport class ChipiSessionError extends ChipiError {\n constructor(message: string, code: string = \"SESSION_ERROR\") {\n super(message, code);\n this.name = \"ChipiSessionError\";\n }\n}\n\nexport class ChipiSkuError extends ChipiError {\n constructor(message: string, code: string = \"SKU_ERROR\") {\n super(message, code);\n this.name = \"ChipiSkuError\";\n }\n}\n\nexport class ChipiValidationError extends ChipiError {\n constructor(message: string, code: string = \"VALIDATION_ERROR\") {\n super(message, code, 400);\n this.name = \"ChipiValidationError\";\n }\n}\n\nexport class ChipiAuthError extends ChipiError {\n constructor(message: string, code: string = \"AUTH_ERROR\") {\n super(message, code, 401);\n this.name = \"ChipiAuthError\";\n }\n}\n\nexport function isChipiError(error: unknown): error is ChipiError {\n return error instanceof ChipiError;\n}\n\n/**\n * Type guard to check if an error has an HTTP status property.\n * Useful for retry logic where you need to distinguish API errors\n * (which have status codes) from network errors (which don't).\n */\nexport function hasHttpStatus(error: unknown): error is { status: number } {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"status\" in error &&\n typeof (error as { status: unknown }).status === \"number\"\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function handleApiError(error: any): ChipiError {\n if (isChipiError(error)) {\n return error;\n }\n\n if (typeof error?.response?.status === \"number\") {\n const status = error.response.status;\n const message = error.response.data?.message || error.message || \"API request failed\";\n const code = error.response.data?.code || `HTTP_${status}`;\n\n return new ChipiApiError(message, code, status);\n }\n\n // Handle errors with direct status property (non-Axios)\n if (error?.status && typeof error.status === \"number\") {\n const message = error?.message || \"API request failed\";\n const code = error?.code || `HTTP_${error.status}`;\n return new ChipiApiError(message, code, error.status);\n }\n\n return new ChipiError(error?.message || \"An unknown error occurred\", \"UNKNOWN_ERROR\");\n}\n","/**\n * Data formatters and transformers for Chipi SDK\n */\n\nexport function formatCurrency(\n amount: number,\n currency: string = \"USD\",\n locale: string = \"en-US\"\n): string {\n return new Intl.NumberFormat(locale, {\n style: \"currency\",\n currency,\n }).format(amount);\n}\n\nexport function formatNumber(\n value: number,\n options: {\n decimals?: number;\n locale?: string;\n compact?: boolean;\n } = {}\n): string {\n const { decimals = 2, locale = \"en-US\", compact = false } = options;\n\n return new Intl.NumberFormat(locale, {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n notation: compact ? \"compact\" : \"standard\",\n }).format(value);\n}\n\nexport function formatDate(\n date: Date | string,\n options: {\n locale?: string;\n dateStyle?: \"full\" | \"long\" | \"medium\" | \"short\";\n timeStyle?: \"full\" | \"long\" | \"medium\" | \"short\";\n } = {}\n): string {\n const { locale = \"en-US\", dateStyle = \"medium\", timeStyle } = options;\n const dateObj = typeof date === \"string\" ? new Date(date) : date;\n\n return new Intl.DateTimeFormat(locale, {\n dateStyle,\n timeStyle,\n }).format(dateObj);\n}\n\nexport function formatAddress(address: string, length: number = 8): string {\n if (address.length <= length * 2) {\n return address;\n }\n\n return `${address.slice(0, length)}...${address.slice(-length)}`;\n}\n\nexport function formatTransactionHash(hash: string): string {\n return formatAddress(hash, 6);\n}\n\nexport function camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\nexport function snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n}\n\nexport function capitalizeFirst(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n","import { z } from \"zod\";\n\n// Base API response schema\nexport const ApiResponseSchema = z.object({\n data: z.unknown(),\n message: z.string().optional(),\n code: z.string().optional(),\n});\n\n// Error response schema\nexport const ErrorResponseSchema = z.object({\n message: z.string(),\n code: z.string().optional(),\n status: z.number().optional(),\n});\n\n// Generic success response schema\nexport const SuccessResponseSchema = <T extends z.ZodTypeAny>(dataSchema: T) =>\n ApiResponseSchema.extend({\n data: dataSchema,\n });\n\n// Type helpers\nexport type ApiResponse<T> = {\n data: T;\n message?: string;\n code?: string;\n};\nexport type ErrorResponse = z.infer<typeof ErrorResponseSchema>;\n\n// Validation functions\n// This is not very good nor useful without passing a data schema\nexport function validateApiResponse<T>(response: unknown, dataSchema: z.ZodType<T>): void {\n // Validate with specific data schema\n const result = SuccessResponseSchema(dataSchema).safeParse(response);\n if (!result.success) {\n throw new Error(`Invalid API response format: ${result.error.message}`);\n }\n}\n\nexport function validateErrorResponse(response: unknown): ErrorResponse {\n const result = ErrorResponseSchema.safeParse(response);\n if (result.success) {\n return result.data;\n }\n\n // Fallback for malformed error responses\n return {\n message: \"Unknown error occurred\",\n code: \"UNKNOWN_ERROR\",\n };\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -93,9 +93,12 @@ var API_VERSIONING = {
|
|
|
93
93
|
VERSION_DATE: "2025-12-30"
|
|
94
94
|
// Detailed version - sent as query param for tracking
|
|
95
95
|
};
|
|
96
|
+
var DEFAULT_MAINNET_RPC = "https://starknet-mainnet.infura.io/v3/4a4a1fdd7d704509aa99154fb29886e2";
|
|
97
|
+
var DEFAULT_SEPOLIA_RPC = "https://starknet-sepolia.infura.io/v3/4a4a1fdd7d704509aa99154fb29886e2";
|
|
96
98
|
var STARKNET_NETWORKS = {
|
|
97
|
-
MAINNET:
|
|
98
|
-
|
|
99
|
+
MAINNET: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,
|
|
100
|
+
MAINNET_FALLBACK: "https://rpc.starknet.lava.build",
|
|
101
|
+
SEPOLIA: process.env.STARKNET_RPC_URL_SEPOLIA ?? DEFAULT_SEPOLIA_RPC
|
|
99
102
|
};
|
|
100
103
|
var CONTRACT_ADDRESSES = {
|
|
101
104
|
USDC_MAINNET: "0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb",
|
|
@@ -152,12 +155,29 @@ var CHAIN_TOKEN_TYPES = {
|
|
|
152
155
|
};
|
|
153
156
|
var WALLET_CLASS_HASHES = {
|
|
154
157
|
CHIPI: "0x53f4f8791ed5bed0fddaa553d180c664e32cfaf8316bb232ae77bb08f459f2a",
|
|
155
|
-
// CHIPI: "0x2de1565226d5215a38b68c4d9a4913989b54edff64c68c45e453c417b44cd83", // Old class Hash
|
|
156
158
|
READY: "0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f"
|
|
157
159
|
};
|
|
160
|
+
var LEGACY_CHIPI_CLASS_HASHES = [
|
|
161
|
+
"0x2de1565226d5215a38b68c4d9a4913989b54edff64c68c45e453c417b44cd83"
|
|
162
|
+
// v28
|
|
163
|
+
];
|
|
164
|
+
function getWalletTypeFromClassHash(classHash) {
|
|
165
|
+
const normalized = classHash.toLowerCase().replace(/^0x0+/, "0x");
|
|
166
|
+
const normalize = (h) => h.toLowerCase().replace(/^0x0+/, "0x");
|
|
167
|
+
if (normalize(WALLET_CLASS_HASHES.READY) === normalized) {
|
|
168
|
+
return "READY";
|
|
169
|
+
}
|
|
170
|
+
if (normalize(WALLET_CLASS_HASHES.CHIPI) === normalized) {
|
|
171
|
+
return "CHIPI";
|
|
172
|
+
}
|
|
173
|
+
if (LEGACY_CHIPI_CLASS_HASHES.some((h) => normalize(h) === normalized)) {
|
|
174
|
+
return "CHIPI";
|
|
175
|
+
}
|
|
176
|
+
return "CHIPI";
|
|
177
|
+
}
|
|
158
178
|
var WALLET_RPC_ENDPOINTS = {
|
|
159
|
-
CHIPI:
|
|
160
|
-
READY:
|
|
179
|
+
CHIPI: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,
|
|
180
|
+
READY: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC
|
|
161
181
|
};
|
|
162
182
|
var PAYMASTER_CONFIG = {
|
|
163
183
|
URL: "https://paymaster.chipipay.com"
|
|
@@ -234,6 +254,7 @@ var ChipiSessionError = class extends ChipiError {
|
|
|
234
254
|
var ChipiSkuError = class extends ChipiError {
|
|
235
255
|
constructor(message, code = "SKU_ERROR") {
|
|
236
256
|
super(message, code);
|
|
257
|
+
this.name = "ChipiSkuError";
|
|
237
258
|
}
|
|
238
259
|
};
|
|
239
260
|
var ChipiValidationError = class extends ChipiError {
|
|
@@ -251,20 +272,25 @@ var ChipiAuthError = class extends ChipiError {
|
|
|
251
272
|
function isChipiError(error) {
|
|
252
273
|
return error instanceof ChipiError;
|
|
253
274
|
}
|
|
275
|
+
function hasHttpStatus(error) {
|
|
276
|
+
return typeof error === "object" && error !== null && "status" in error && typeof error.status === "number";
|
|
277
|
+
}
|
|
254
278
|
function handleApiError(error) {
|
|
255
279
|
if (isChipiError(error)) {
|
|
256
280
|
return error;
|
|
257
281
|
}
|
|
258
|
-
if (error?.response?.status) {
|
|
282
|
+
if (typeof error?.response?.status === "number") {
|
|
259
283
|
const status = error.response.status;
|
|
260
284
|
const message = error.response.data?.message || error.message || "API request failed";
|
|
261
285
|
const code = error.response.data?.code || `HTTP_${status}`;
|
|
262
286
|
return new ChipiApiError(message, code, status);
|
|
263
287
|
}
|
|
264
|
-
|
|
265
|
-
error?.message || "
|
|
266
|
-
|
|
267
|
-
|
|
288
|
+
if (error?.status && typeof error.status === "number") {
|
|
289
|
+
const message = error?.message || "API request failed";
|
|
290
|
+
const code = error?.code || `HTTP_${error.status}`;
|
|
291
|
+
return new ChipiApiError(message, code, error.status);
|
|
292
|
+
}
|
|
293
|
+
return new ChipiError(error?.message || "An unknown error occurred", "UNKNOWN_ERROR");
|
|
268
294
|
}
|
|
269
295
|
|
|
270
296
|
// src/formatters.ts
|
|
@@ -318,18 +344,18 @@ var ErrorResponseSchema = z.object({
|
|
|
318
344
|
code: z.string().optional(),
|
|
319
345
|
status: z.number().optional()
|
|
320
346
|
});
|
|
321
|
-
var SuccessResponseSchema = (dataSchema) =>
|
|
347
|
+
var SuccessResponseSchema = (dataSchema) => ApiResponseSchema.extend({
|
|
322
348
|
data: dataSchema
|
|
323
349
|
});
|
|
324
350
|
function validateApiResponse(response, dataSchema) {
|
|
325
351
|
const result = SuccessResponseSchema(dataSchema).safeParse(response);
|
|
326
|
-
if (!result.
|
|
352
|
+
if (!result.success) {
|
|
327
353
|
throw new Error(`Invalid API response format: ${result.error.message}`);
|
|
328
354
|
}
|
|
329
355
|
}
|
|
330
356
|
function validateErrorResponse(response) {
|
|
331
357
|
const result = ErrorResponseSchema.safeParse(response);
|
|
332
|
-
if (result.
|
|
358
|
+
if (result.success) {
|
|
333
359
|
return result.data;
|
|
334
360
|
}
|
|
335
361
|
return {
|
|
@@ -338,6 +364,6 @@ function validateErrorResponse(response) {
|
|
|
338
364
|
};
|
|
339
365
|
}
|
|
340
366
|
|
|
341
|
-
export { API_ENDPOINTS, API_VERSIONING, ApiResponseSchema, CARRIER_IDS, CHAIN_TOKEN_TYPES, CHAIN_TYPES, CONTRACT_ADDRESSES, ChipiApiError, ChipiAuthError, ChipiError, ChipiSessionError, ChipiSkuError, ChipiTransactionError, ChipiValidationError, ChipiWalletError, ERRORS, ErrorResponseSchema, PAYMASTER_CONFIG, SERVICE_TYPES, SESSION_DEFAULTS, SESSION_ENTRYPOINTS, SESSION_ERRORS, SKU_CONTRACTS, STARKNET_NETWORKS, SuccessResponseSchema, TOKEN_DECIMALS, WALLET_CLASS_HASHES, WALLET_RPC_ENDPOINTS, camelToSnake, capitalizeFirst, createPaginatedResponse, deepMerge, formatAddress, formatAmount, formatCurrency, formatDate, formatNumber, formatTransactionHash, handleApiError, isChipiError, isValidAddress, isValidApiKey, parseAmount, retry, sanitizeUrl, sleep, snakeToCamel, validateApiResponse, validateErrorResponse, validatePagination };
|
|
367
|
+
export { API_ENDPOINTS, API_VERSIONING, ApiResponseSchema, CARRIER_IDS, CHAIN_TOKEN_TYPES, CHAIN_TYPES, CONTRACT_ADDRESSES, ChipiApiError, ChipiAuthError, ChipiError, ChipiSessionError, ChipiSkuError, ChipiTransactionError, ChipiValidationError, ChipiWalletError, ERRORS, ErrorResponseSchema, LEGACY_CHIPI_CLASS_HASHES, PAYMASTER_CONFIG, SERVICE_TYPES, SESSION_DEFAULTS, SESSION_ENTRYPOINTS, SESSION_ERRORS, SKU_CONTRACTS, STARKNET_NETWORKS, SuccessResponseSchema, TOKEN_DECIMALS, WALLET_CLASS_HASHES, WALLET_RPC_ENDPOINTS, camelToSnake, capitalizeFirst, createPaginatedResponse, deepMerge, formatAddress, formatAmount, formatCurrency, formatDate, formatNumber, formatTransactionHash, getWalletTypeFromClassHash, handleApiError, hasHttpStatus, isChipiError, isValidAddress, isValidApiKey, parseAmount, retry, sanitizeUrl, sleep, snakeToCamel, validateApiResponse, validateErrorResponse, validatePagination };
|
|
342
368
|
//# sourceMappingURL=index.mjs.map
|
|
343
369
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/index.ts","../src/constants/index.ts","../src/errors.ts","../src/formatters.ts","../src/validation.ts"],"names":["amountBN"],"mappings":"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","file":"index.mjs","sourcesContent":["import type {\n PaginationQuery,\n PaginatedResponse,\n Currency,\n} from \"@chipi-stack/types\";\nimport { API_ENDPOINTS } from \"../constants\";\n\n/**\n * Utility functions used across Chipi SDK packages\n */\n\nexport function isValidAddress(address: string): boolean {\n // Validate Starknet address format\n return /^0x[0-9a-fA-F]{1,64}$/.test(address);\n}\n\nexport function isValidApiKey(apiKey: string): boolean {\n // Validate API key format (pk_dev_ or pk_prod_)\n return /^pk_(dev|prod)_[a-zA-Z0-9]{32,}$/.test(apiKey);\n}\n\nexport function formatAmount(amount: string, decimals: number = 18): string {\n // If it's an integer, multiply by 10^decimals\n if (!amount.includes(\".\")) {\n const amountBN = BigInt(amount) * BigInt(10) ** BigInt(decimals);\n return amountBN.toString();\n }\n\n // If it has decimals, handle properly\n const [integerPart, decimalPart = \"\"] = amount.split(\".\");\n const paddedDecimal = decimalPart.padEnd(decimals, \"0\").slice(0, decimals);\n const amountBN = BigInt(integerPart + paddedDecimal);\n\n return amountBN.toString();\n}\n\nexport function parseAmount(amount: string, decimals: number = 18): number {\n const amountBN = BigInt(amount);\n const divisor = BigInt(10) ** BigInt(decimals);\n return Number(amountBN) / Number(divisor);\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function retry<T>(\n fn: () => Promise<T>,\n options: {\n maxAttempts?: number;\n delay?: number;\n backoff?: boolean;\n } = {},\n): Promise<T> {\n const { maxAttempts = 3, delay = 1000, backoff = true } = options;\n\n return new Promise((resolve, reject) => {\n let attempt = 0;\n\n const tryFn = async () => {\n try {\n const result = await fn();\n resolve(result);\n } catch (error) {\n attempt++;\n\n if (attempt >= maxAttempts) {\n reject(error);\n return;\n }\n\n const waitTime = backoff ? delay * Math.pow(2, attempt - 1) : delay;\n setTimeout(tryFn, waitTime);\n }\n };\n\n tryFn();\n });\n}\n\nexport function createPaginatedResponse<T>(\n data: T[],\n query: PaginationQuery,\n total: number,\n): PaginatedResponse<T> {\n const page = query.page || 1;\n const limit = query.limit || 10;\n const totalPages = Math.ceil(total / limit);\n\n return {\n data,\n total,\n page,\n limit,\n totalPages,\n };\n}\n\nexport function validatePagination(query: PaginationQuery): {\n page: number;\n limit: number;\n} {\n const page = Math.max(1, query.page || 1);\n const limit = Math.min(100, Math.max(1, query.limit || 10));\n\n return { page, limit };\n}\n\nexport function sanitizeUrl(url: string): string {\n try {\n const parsed = new URL(url);\n return parsed.toString();\n } catch (error) {\n throw new Error(`Invalid URL: ${url}`);\n }\n}\n\nexport function deepMerge<T extends Record<string, any>>(\n target: T,\n source: Partial<T>,\n): T {\n const result = { ...target };\n\n for (const key in source) {\n if (source[key] !== undefined) {\n const sourceValue = source[key];\n if (\n typeof sourceValue === \"object\" &&\n sourceValue !== null &&\n !Array.isArray(sourceValue) &&\n typeof result[key] === \"object\" &&\n result[key] !== null &&\n !Array.isArray(result[key])\n ) {\n result[key] = deepMerge(result[key], sourceValue);\n } else {\n result[key] = sourceValue as T[Extract<keyof T, string>];\n }\n }\n }\n\n return result;\n}\n","/**\n * Constants used across Chipi SDK packages\n */\n\nimport { WalletType } from \"@chipi-stack/types\";\n\n/**\n * API Versioning\n * - VERSION: Major version for path-based versioning (/v1, /v2, etc.)\n * - VERSION_DATE: Detailed version for tracking breaking changes (YYYY-MM-DD format)\n *\n * Update VERSION_DATE when making API changes.\n * Update VERSION when making major breaking changes (typically 1-2 times per year).\n */\nexport const API_VERSIONING = {\n VERSION: \"1\", // Major version - used in URL path\n VERSION_DATE: \"2025-12-30\", // Detailed version - sent as query param for tracking\n} as const;\n\nexport const STARKNET_NETWORKS = {\n MAINNET: \"https://starknet-mainnet.public.blastapi.io/rpc/v0_7\",\n SEPOLIA: \"https://starknet-sepolia.public.blastapi.io/rpc/v0_7\",\n} as const;\n\nexport const CONTRACT_ADDRESSES = {\n USDC_MAINNET:\n \"0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb\", // Changed to Native USDC (was bridged USDC.e)\n VESU_USDC_MAINNET:\n \"0x017f19582c61479f2fe0b6606300e975c0a8f439102f43eeecc1d0e9b3d84350\",\n} as const;\n\nexport const TOKEN_DECIMALS = {\n USDC: 6,\n USDT: 6,\n ETH: 18,\n STRK: 18,\n DAI: 18,\n} as const;\n\nexport const API_ENDPOINTS = {\n CHIPI_WALLETS: \"/chipi-wallets\",\n TRANSACTIONS: \"/transactions\",\n SKUS: \"/skus\",\n SKU_PURCHASES: \"/sku-purchases\",\n EXCHANGES: \"/exchanges\",\n USERS: \"/users\",\n} as const;\n\nexport const ERRORS = {\n INVALID_API_KEY: \"INVALID_API_KEY\",\n WALLET_NOT_FOUND: \"WALLET_NOT_FOUND\",\n INSUFFICIENT_BALANCE: \"INSUFFICIENT_BALANCE\",\n TRANSACTION_FAILED: \"TRANSACTION_FAILED\",\n INVALID_SIGNATURE: \"INVALID_SIGNATURE\",\n SKU_NOT_FOUND: \"SKU_NOT_FOUND\",\n SKU_UNAVAILABLE: \"SKU_UNAVAILABLE\",\n} as const;\n\nexport const SKU_CONTRACTS = {\n RECHARGER_WITH_STRK_MAINNET:\n \"0x02d65bb726d2c29e3c97669cf297c5145eac19284fb6f935c05c0bfc68dae2b7\", //changed contract address used to be 0x0f3\n CHIPI_BILL_SERVICE:\n \"0x4e8150110d580069de26adec9b179023289d55859ea07487aaade5458d7aa8b\",\n} as const;\n\n// Service types\nexport const SERVICE_TYPES = {\n BUY_SERVICE: \"BUY_SERVICE\",\n} as const;\n\n// Carrier IDs\nexport const CARRIER_IDS = {\n CHIPI_PAY: \"chipi_pay\",\n} as const;\n\nexport const CHAIN_TYPES = {\n STARKNET: \"STARKNET\",\n} as const;\n\nexport const CHAIN_TOKEN_TYPES = {\n USDC: \"USDC\", // Changed to Native USDC (was bridged USDC.e)\n USDT: \"USDT\",\n ETH: \"ETH\",\n STRK: \"STRK\",\n DAI: \"DAI\",\n WBTC: \"WBTC\",\n OTHER: \"OTHER\",\n} as const;\n\nexport const WALLET_CLASS_HASHES: Record<WalletType, string> = {\n CHIPI: \"0x53f4f8791ed5bed0fddaa553d180c664e32cfaf8316bb232ae77bb08f459f2a\",\n // CHIPI: \"0x2de1565226d5215a38b68c4d9a4913989b54edff64c68c45e453c417b44cd83\", // Old class Hash\n READY: \"0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f\",\n};\n\n// RPC endpoints per wallet type\nexport const WALLET_RPC_ENDPOINTS: Record<WalletType, string> = {\n CHIPI: \"https://starknet-mainnet.public.blastapi.io/rpc/v0_7\",\n READY: \"https://cloud.argent-api.com/v1/starknet/mainnet/rpc/v0.7\",\n};\n\n// Paymaster configuration\nexport const PAYMASTER_CONFIG = {\n URL: \"https://paymaster.chipipay.com\",\n} as const;\n\n// Session key configuration (CHIPI wallets only - SNIP-9 compatible)\nexport const SESSION_DEFAULTS = {\n /** Default session duration: 6 hours in seconds */\n DURATION_SECONDS: 21600,\n /** Default max calls per session */\n MAX_CALLS: 1000,\n} as const;\n\n// Session-specific error codes\nexport const SESSION_ERRORS = {\n /** Session keys only work with CHIPI wallets */\n INVALID_WALLET_TYPE_FOR_SESSION: \"INVALID_WALLET_TYPE_FOR_SESSION\",\n /** Session has expired (validUntil < now) */\n SESSION_EXPIRED: \"SESSION_EXPIRED\",\n /** Session key not registered on contract */\n SESSION_NOT_REGISTERED: \"SESSION_NOT_REGISTERED\",\n /** Session key has been revoked */\n SESSION_REVOKED: \"SESSION_REVOKED\",\n /** Session has exceeded max calls */\n SESSION_MAX_CALLS_EXCEEDED: \"SESSION_MAX_CALLS_EXCEEDED\",\n /** Entrypoint not allowed for this session */\n SESSION_ENTRYPOINT_NOT_ALLOWED: \"SESSION_ENTRYPOINT_NOT_ALLOWED\",\n /** Failed to decrypt session private key */\n SESSION_DECRYPTION_FAILED: \"SESSION_DECRYPTION_FAILED\",\n /** Failed to create session key */\n SESSION_CREATION_FAILED: \"SESSION_CREATION_FAILED\",\n} as const;\n\n// Session contract entrypoint names\nexport const SESSION_ENTRYPOINTS = {\n /** Add or update a session key (owner only) */\n ADD_OR_UPDATE: \"add_or_update_session_key\",\n /** Revoke a session key (owner only) */\n REVOKE: \"revoke_session_key\",\n /** Query session data (public read) */\n GET_DATA: \"get_session_data\",\n} as const;\n","import type { ErrorWithCode } from '@chipi-stack/types';\n\n/**\n * Error classes and utilities for Chipi SDK\n */\n\nexport class ChipiError extends Error implements ErrorWithCode {\n public readonly code: string;\n public readonly status?: number;\n\n constructor(message: string, code: string, status?: number) {\n super(message);\n this.name = 'ChipiError';\n this.code = code;\n this.status = status;\n \n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ChipiError);\n }\n }\n}\n\nexport class ChipiApiError extends ChipiError {\n constructor(message: string, code: string, status: number) {\n super(message, code, status);\n this.name = 'ChipiApiError';\n }\n}\n\nexport class ChipiWalletError extends ChipiError {\n constructor(message: string, code: string = 'WALLET_ERROR') {\n super(message, code);\n this.name = 'ChipiWalletError';\n }\n}\n\nexport class ChipiTransactionError extends ChipiError {\n constructor(message: string, code: string = 'TRANSACTION_ERROR') {\n super(message, code);\n this.name = 'ChipiTransactionError';\n }\n}\n\nexport class ChipiSessionError extends ChipiError {\n constructor(message: string, code: string = 'SESSION_ERROR') {\n super(message, code);\n this.name = 'ChipiSessionError';\n }\n}\n\nexport class ChipiSkuError extends ChipiError {\n constructor(message: string, code: string = 'SKU_ERROR') {\n super(message, code);\n }\n}\n\nexport class ChipiValidationError extends ChipiError {\n constructor(message: string, code: string = 'VALIDATION_ERROR') {\n super(message, code, 400);\n this.name = 'ChipiValidationError';\n }\n}\n\nexport class ChipiAuthError extends ChipiError {\n constructor(message: string, code: string = 'AUTH_ERROR') {\n super(message, code, 401);\n this.name = 'ChipiAuthError';\n }\n}\n\nexport function isChipiError(error: any): error is ChipiError {\n return error instanceof ChipiError;\n}\n\nexport function handleApiError(error: any): ChipiError {\n if (isChipiError(error)) {\n return error;\n }\n\n if (error?.response?.status) {\n const status = error.response.status;\n const message = error.response.data?.message || error.message || 'API request failed';\n const code = error.response.data?.code || `HTTP_${status}`;\n \n return new ChipiApiError(message, code, status);\n }\n\n return new ChipiError(\n error?.message || 'An unknown error occurred',\n 'UNKNOWN_ERROR'\n );\n}\n","/**\n * Data formatters and transformers for Chipi SDK\n */\n\nexport function formatCurrency(\n amount: number,\n currency: string = 'USD',\n locale: string = 'en-US'\n): string {\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n }).format(amount);\n}\n\nexport function formatNumber(\n value: number,\n options: {\n decimals?: number;\n locale?: string;\n compact?: boolean;\n } = {}\n): string {\n const { decimals = 2, locale = 'en-US', compact = false } = options;\n \n return new Intl.NumberFormat(locale, {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n notation: compact ? 'compact' : 'standard',\n }).format(value);\n}\n\nexport function formatDate(\n date: Date | string,\n options: {\n locale?: string;\n dateStyle?: 'full' | 'long' | 'medium' | 'short';\n timeStyle?: 'full' | 'long' | 'medium' | 'short';\n } = {}\n): string {\n const { locale = 'en-US', dateStyle = 'medium', timeStyle } = options;\n const dateObj = typeof date === 'string' ? new Date(date) : date;\n \n return new Intl.DateTimeFormat(locale, {\n dateStyle,\n timeStyle,\n }).format(dateObj);\n}\n\nexport function formatAddress(address: string, length: number = 8): string {\n if (address.length <= length * 2) {\n return address;\n }\n \n return `${address.slice(0, length)}...${address.slice(-length)}`;\n}\n\nexport function formatTransactionHash(hash: string): string {\n return formatAddress(hash, 6);\n}\n\n\n\nexport function camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);\n}\n\nexport function snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n}\n\nexport function capitalizeFirst(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n","import { z } from \"zod\";\n\n// Base API response schema\nexport const ApiResponseSchema = z.object({\n data: z.unknown(),\n message: z.string().optional(),\n code: z.string().optional(),\n});\n\n// Error response schema\nexport const ErrorResponseSchema = z.object({\n message: z.string(),\n code: z.string().optional(),\n status: z.number().optional(),\n});\n\n// Generic success response schema\nexport const SuccessResponseSchema = <T extends z.ZodTypeAny>(dataSchema: T) =>\n z.object({\n data: dataSchema,\n });\n\n// Type helpers\nexport type ApiResponse<T> = z.infer<\n ReturnType<typeof SuccessResponseSchema<z.ZodType<T>>>\n>;\nexport type ErrorResponse = z.infer<typeof ErrorResponseSchema>;\n\n// Validation functions\n// This is not very good nor useful without passing a data schema\nexport function validateApiResponse<T>(\n response: unknown,\n dataSchema: z.ZodType<T>\n): void {\n // Validate with specific data schema\n const result = SuccessResponseSchema(dataSchema).safeParse(response);\n if (!result.data) {\n throw new Error(`Invalid API response format: ${result.error.message}`);\n }\n}\n\nexport function validateErrorResponse(response: unknown): ErrorResponse {\n const result = ErrorResponseSchema.safeParse(response);\n if (result.data) {\n return result.data;\n }\n\n // Fallback for malformed error responses\n return {\n message: \"Unknown error occurred\",\n code: \"UNKNOWN_ERROR\",\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/index.ts","../src/constants/index.ts","../src/errors.ts","../src/formatters.ts","../src/validation.ts"],"names":["amountBN"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { PaginationQuery, PaginatedResponse, Currency } from \"@chipi-stack/types\";\nimport { API_ENDPOINTS } from \"../constants\";\n\n/**\n * Utility functions used across Chipi SDK packages\n */\n\nexport function isValidAddress(address: string): boolean {\n // Validate Starknet address format\n return /^0x[0-9a-fA-F]{1,64}$/.test(address);\n}\n\nexport function isValidApiKey(apiKey: string): boolean {\n // Validate API key format (pk_dev_ or pk_prod_)\n return /^pk_(dev|prod)_[a-zA-Z0-9]{32,}$/.test(apiKey);\n}\n\nexport function formatAmount(amount: string, decimals: number = 18): string {\n // If it's an integer, multiply by 10^decimals\n if (!amount.includes(\".\")) {\n const amountBN = BigInt(amount) * BigInt(10) ** BigInt(decimals);\n return amountBN.toString();\n }\n\n // If it has decimals, handle properly\n const [integerPart, decimalPart = \"\"] = amount.split(\".\");\n const paddedDecimal = decimalPart.padEnd(decimals, \"0\").slice(0, decimals);\n const amountBN = BigInt(integerPart + paddedDecimal);\n\n return amountBN.toString();\n}\n\nexport function parseAmount(amount: string, decimals: number = 18): number {\n const amountBN = BigInt(amount);\n const divisor = BigInt(10) ** BigInt(decimals);\n return Number(amountBN) / Number(divisor);\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function retry<T>(\n fn: () => Promise<T>,\n options: {\n maxAttempts?: number;\n delay?: number;\n backoff?: boolean;\n } = {}\n): Promise<T> {\n const { maxAttempts = 3, delay = 1000, backoff = true } = options;\n\n return new Promise((resolve, reject) => {\n let attempt = 0;\n\n const tryFn = async () => {\n try {\n const result = await fn();\n resolve(result);\n } catch (error) {\n attempt++;\n\n if (attempt >= maxAttempts) {\n reject(error);\n return;\n }\n\n const waitTime = backoff ? delay * Math.pow(2, attempt - 1) : delay;\n setTimeout(tryFn, waitTime);\n }\n };\n\n tryFn();\n });\n}\n\nexport function createPaginatedResponse<T>(\n data: T[],\n query: PaginationQuery,\n total: number\n): PaginatedResponse<T> {\n const page = query.page || 1;\n const limit = query.limit || 10;\n const totalPages = Math.ceil(total / limit);\n\n return {\n data,\n total,\n page,\n limit,\n totalPages,\n };\n}\n\nexport function validatePagination(query: PaginationQuery): {\n page: number;\n limit: number;\n} {\n const page = Math.max(1, query.page || 1);\n const limit = Math.min(100, Math.max(1, query.limit || 10));\n\n return { page, limit };\n}\n\nexport function sanitizeUrl(url: string): string {\n try {\n const parsed = new URL(url);\n return parsed.toString();\n } catch (error) {\n throw new Error(`Invalid URL: ${url}`);\n }\n}\n\nexport function deepMerge<T extends Record<string, any>>(target: T, source: Partial<T>): T {\n const result = { ...target };\n\n for (const key in source) {\n if (source[key] !== undefined) {\n const sourceValue = source[key];\n if (\n typeof sourceValue === \"object\" &&\n sourceValue !== null &&\n !Array.isArray(sourceValue) &&\n typeof result[key] === \"object\" &&\n result[key] !== null &&\n !Array.isArray(result[key])\n ) {\n result[key] = deepMerge(result[key], sourceValue);\n } else {\n result[key] = sourceValue as T[Extract<keyof T, string>];\n }\n }\n }\n\n return result;\n}\n","/**\n * Constants used across Chipi SDK packages\n */\n\nimport { WalletType } from \"@chipi-stack/types\";\n\n/**\n * API Versioning\n * - VERSION: Major version for path-based versioning (/v1, /v2, etc.)\n * - VERSION_DATE: Detailed version for tracking breaking changes (YYYY-MM-DD format)\n *\n * Update VERSION_DATE when making API changes.\n * Update VERSION when making major breaking changes (typically 1-2 times per year).\n */\nexport const API_VERSIONING = {\n VERSION: \"1\", // Major version - used in URL path\n VERSION_DATE: \"2025-12-30\", // Detailed version - sent as query param for tracking\n} as const;\n\n// Default RPC URLs — override via STARKNET_RPC_URL / STARKNET_RPC_URL_SEPOLIA env vars.\nconst DEFAULT_MAINNET_RPC =\n \"https://starknet-mainnet.infura.io/v3/4a4a1fdd7d704509aa99154fb29886e2\";\nconst DEFAULT_SEPOLIA_RPC =\n \"https://starknet-sepolia.infura.io/v3/4a4a1fdd7d704509aa99154fb29886e2\";\n\nexport const STARKNET_NETWORKS = {\n MAINNET: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,\n MAINNET_FALLBACK: \"https://rpc.starknet.lava.build\",\n SEPOLIA: process.env.STARKNET_RPC_URL_SEPOLIA ?? DEFAULT_SEPOLIA_RPC,\n} as const;\n\nexport const CONTRACT_ADDRESSES = {\n USDC_MAINNET: \"0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb\", // Changed to Native USDC (was bridged USDC.e)\n VESU_USDC_MAINNET: \"0x017f19582c61479f2fe0b6606300e975c0a8f439102f43eeecc1d0e9b3d84350\",\n} as const;\n\nexport const TOKEN_DECIMALS = {\n USDC: 6,\n USDT: 6,\n ETH: 18,\n STRK: 18,\n DAI: 18,\n} as const;\n\nexport const API_ENDPOINTS = {\n CHIPI_WALLETS: \"/chipi-wallets\",\n TRANSACTIONS: \"/transactions\",\n SKUS: \"/skus\",\n SKU_PURCHASES: \"/sku-purchases\",\n EXCHANGES: \"/exchanges\",\n USERS: \"/users\",\n} as const;\n\nexport const ERRORS = {\n INVALID_API_KEY: \"INVALID_API_KEY\",\n WALLET_NOT_FOUND: \"WALLET_NOT_FOUND\",\n INSUFFICIENT_BALANCE: \"INSUFFICIENT_BALANCE\",\n TRANSACTION_FAILED: \"TRANSACTION_FAILED\",\n INVALID_SIGNATURE: \"INVALID_SIGNATURE\",\n SKU_NOT_FOUND: \"SKU_NOT_FOUND\",\n SKU_UNAVAILABLE: \"SKU_UNAVAILABLE\",\n} as const;\n\nexport const SKU_CONTRACTS = {\n RECHARGER_WITH_STRK_MAINNET: \"0x02d65bb726d2c29e3c97669cf297c5145eac19284fb6f935c05c0bfc68dae2b7\", //changed contract address used to be 0x0f3\n CHIPI_BILL_SERVICE: \"0x4e8150110d580069de26adec9b179023289d55859ea07487aaade5458d7aa8b\",\n} as const;\n\n// Service types\nexport const SERVICE_TYPES = {\n BUY_SERVICE: \"BUY_SERVICE\",\n} as const;\n\n// Carrier IDs\nexport const CARRIER_IDS = {\n CHIPI_PAY: \"chipi_pay\",\n} as const;\n\nexport const CHAIN_TYPES = {\n STARKNET: \"STARKNET\",\n} as const;\n\nexport const CHAIN_TOKEN_TYPES = {\n USDC: \"USDC\", // Changed to Native USDC (was bridged USDC.e)\n USDT: \"USDT\",\n ETH: \"ETH\",\n STRK: \"STRK\",\n DAI: \"DAI\",\n WBTC: \"WBTC\",\n OTHER: \"OTHER\",\n} as const;\n\nexport const WALLET_CLASS_HASHES: Record<WalletType, string> = {\n CHIPI: \"0x53f4f8791ed5bed0fddaa553d180c664e32cfaf8316bb232ae77bb08f459f2a\",\n READY: \"0x036078334509b514626504edc9fb252328d1a240e4e948bef8d0c08dff45927f\",\n};\n\n/**\n * Previous CHIPI wallet class hashes that are still deployed on-chain.\n * Used by getWalletTypeFromClassHash() to identify legacy wallets.\n */\nexport const LEGACY_CHIPI_CLASS_HASHES: string[] = [\n \"0x2de1565226d5215a38b68c4d9a4913989b54edff64c68c45e453c417b44cd83\", // v28\n];\n\n/**\n * Determine wallet type from an on-chain class hash.\n * - If it matches the READY hash → READY\n * - If it matches the current CHIPI hash → CHIPI\n * - If it matches a legacy CHIPI hash → CHIPI\n * - Otherwise → CHIPI (safe default since CHIPI wallets have had multiple class hashes)\n */\nexport function getWalletTypeFromClassHash(classHash: string): WalletType {\n const normalized = classHash.toLowerCase().replace(/^0x0+/, \"0x\");\n const normalize = (h: string) => h.toLowerCase().replace(/^0x0+/, \"0x\");\n\n if (normalize(WALLET_CLASS_HASHES.READY) === normalized) {\n return \"READY\";\n }\n // Current or legacy CHIPI hashes\n if (normalize(WALLET_CLASS_HASHES.CHIPI) === normalized) {\n return \"CHIPI\";\n }\n if (LEGACY_CHIPI_CLASS_HASHES.some((h) => normalize(h) === normalized)) {\n return \"CHIPI\";\n }\n // Default to CHIPI — unknown hashes are more likely to be older CHIPI deployments\n return \"CHIPI\";\n}\n\n// RPC endpoints per wallet type — any standard Starknet RPC works for all wallet types.\n// Override via STARKNET_RPC_URL env var; falls back to the default Infura endpoint.\nexport const WALLET_RPC_ENDPOINTS: Record<WalletType, string> = {\n CHIPI: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,\n READY: process.env.STARKNET_RPC_URL ?? DEFAULT_MAINNET_RPC,\n};\n\n// Paymaster configuration\nexport const PAYMASTER_CONFIG = {\n URL: \"https://paymaster.chipipay.com\",\n} as const;\n\n// Session key configuration (CHIPI wallets only - SNIP-9 compatible)\nexport const SESSION_DEFAULTS = {\n /** Default session duration: 6 hours in seconds */\n DURATION_SECONDS: 21600,\n /** Default max calls per session */\n MAX_CALLS: 1000,\n} as const;\n\n// Session-specific error codes\nexport const SESSION_ERRORS = {\n /** Session keys only work with CHIPI wallets */\n INVALID_WALLET_TYPE_FOR_SESSION: \"INVALID_WALLET_TYPE_FOR_SESSION\",\n /** Session has expired (validUntil < now) */\n SESSION_EXPIRED: \"SESSION_EXPIRED\",\n /** Session key not registered on contract */\n SESSION_NOT_REGISTERED: \"SESSION_NOT_REGISTERED\",\n /** Session key has been revoked */\n SESSION_REVOKED: \"SESSION_REVOKED\",\n /** Session has exceeded max calls */\n SESSION_MAX_CALLS_EXCEEDED: \"SESSION_MAX_CALLS_EXCEEDED\",\n /** Entrypoint not allowed for this session */\n SESSION_ENTRYPOINT_NOT_ALLOWED: \"SESSION_ENTRYPOINT_NOT_ALLOWED\",\n /** Failed to decrypt session private key */\n SESSION_DECRYPTION_FAILED: \"SESSION_DECRYPTION_FAILED\",\n /** Failed to create session key */\n SESSION_CREATION_FAILED: \"SESSION_CREATION_FAILED\",\n} as const;\n\n// Session contract entrypoint names\nexport const SESSION_ENTRYPOINTS = {\n /** Add or update a session key (owner only) */\n ADD_OR_UPDATE: \"add_or_update_session_key\",\n /** Revoke a session key (owner only) */\n REVOKE: \"revoke_session_key\",\n /** Query session data (public read) */\n GET_DATA: \"get_session_data\",\n} as const;\n","import type { ErrorWithCode } from \"@chipi-stack/types\";\n\n/**\n * Error classes and utilities for Chipi SDK\n */\n\nexport class ChipiError extends Error implements ErrorWithCode {\n public readonly code: string;\n public readonly status?: number;\n\n constructor(message: string, code: string, status?: number) {\n super(message);\n this.name = \"ChipiError\";\n this.code = code;\n this.status = status;\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ChipiError);\n }\n }\n}\n\nexport class ChipiApiError extends ChipiError {\n constructor(message: string, code: string, status: number) {\n super(message, code, status);\n this.name = \"ChipiApiError\";\n }\n}\n\nexport class ChipiWalletError extends ChipiError {\n constructor(message: string, code: string = \"WALLET_ERROR\") {\n super(message, code);\n this.name = \"ChipiWalletError\";\n }\n}\n\nexport class ChipiTransactionError extends ChipiError {\n constructor(message: string, code: string = \"TRANSACTION_ERROR\") {\n super(message, code);\n this.name = \"ChipiTransactionError\";\n }\n}\n\nexport class ChipiSessionError extends ChipiError {\n constructor(message: string, code: string = \"SESSION_ERROR\") {\n super(message, code);\n this.name = \"ChipiSessionError\";\n }\n}\n\nexport class ChipiSkuError extends ChipiError {\n constructor(message: string, code: string = \"SKU_ERROR\") {\n super(message, code);\n this.name = \"ChipiSkuError\";\n }\n}\n\nexport class ChipiValidationError extends ChipiError {\n constructor(message: string, code: string = \"VALIDATION_ERROR\") {\n super(message, code, 400);\n this.name = \"ChipiValidationError\";\n }\n}\n\nexport class ChipiAuthError extends ChipiError {\n constructor(message: string, code: string = \"AUTH_ERROR\") {\n super(message, code, 401);\n this.name = \"ChipiAuthError\";\n }\n}\n\nexport function isChipiError(error: unknown): error is ChipiError {\n return error instanceof ChipiError;\n}\n\n/**\n * Type guard to check if an error has an HTTP status property.\n * Useful for retry logic where you need to distinguish API errors\n * (which have status codes) from network errors (which don't).\n */\nexport function hasHttpStatus(error: unknown): error is { status: number } {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"status\" in error &&\n typeof (error as { status: unknown }).status === \"number\"\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function handleApiError(error: any): ChipiError {\n if (isChipiError(error)) {\n return error;\n }\n\n if (typeof error?.response?.status === \"number\") {\n const status = error.response.status;\n const message = error.response.data?.message || error.message || \"API request failed\";\n const code = error.response.data?.code || `HTTP_${status}`;\n\n return new ChipiApiError(message, code, status);\n }\n\n // Handle errors with direct status property (non-Axios)\n if (error?.status && typeof error.status === \"number\") {\n const message = error?.message || \"API request failed\";\n const code = error?.code || `HTTP_${error.status}`;\n return new ChipiApiError(message, code, error.status);\n }\n\n return new ChipiError(error?.message || \"An unknown error occurred\", \"UNKNOWN_ERROR\");\n}\n","/**\n * Data formatters and transformers for Chipi SDK\n */\n\nexport function formatCurrency(\n amount: number,\n currency: string = \"USD\",\n locale: string = \"en-US\"\n): string {\n return new Intl.NumberFormat(locale, {\n style: \"currency\",\n currency,\n }).format(amount);\n}\n\nexport function formatNumber(\n value: number,\n options: {\n decimals?: number;\n locale?: string;\n compact?: boolean;\n } = {}\n): string {\n const { decimals = 2, locale = \"en-US\", compact = false } = options;\n\n return new Intl.NumberFormat(locale, {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n notation: compact ? \"compact\" : \"standard\",\n }).format(value);\n}\n\nexport function formatDate(\n date: Date | string,\n options: {\n locale?: string;\n dateStyle?: \"full\" | \"long\" | \"medium\" | \"short\";\n timeStyle?: \"full\" | \"long\" | \"medium\" | \"short\";\n } = {}\n): string {\n const { locale = \"en-US\", dateStyle = \"medium\", timeStyle } = options;\n const dateObj = typeof date === \"string\" ? new Date(date) : date;\n\n return new Intl.DateTimeFormat(locale, {\n dateStyle,\n timeStyle,\n }).format(dateObj);\n}\n\nexport function formatAddress(address: string, length: number = 8): string {\n if (address.length <= length * 2) {\n return address;\n }\n\n return `${address.slice(0, length)}...${address.slice(-length)}`;\n}\n\nexport function formatTransactionHash(hash: string): string {\n return formatAddress(hash, 6);\n}\n\nexport function camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\nexport function snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n}\n\nexport function capitalizeFirst(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n","import { z } from \"zod\";\n\n// Base API response schema\nexport const ApiResponseSchema = z.object({\n data: z.unknown(),\n message: z.string().optional(),\n code: z.string().optional(),\n});\n\n// Error response schema\nexport const ErrorResponseSchema = z.object({\n message: z.string(),\n code: z.string().optional(),\n status: z.number().optional(),\n});\n\n// Generic success response schema\nexport const SuccessResponseSchema = <T extends z.ZodTypeAny>(dataSchema: T) =>\n ApiResponseSchema.extend({\n data: dataSchema,\n });\n\n// Type helpers\nexport type ApiResponse<T> = {\n data: T;\n message?: string;\n code?: string;\n};\nexport type ErrorResponse = z.infer<typeof ErrorResponseSchema>;\n\n// Validation functions\n// This is not very good nor useful without passing a data schema\nexport function validateApiResponse<T>(response: unknown, dataSchema: z.ZodType<T>): void {\n // Validate with specific data schema\n const result = SuccessResponseSchema(dataSchema).safeParse(response);\n if (!result.success) {\n throw new Error(`Invalid API response format: ${result.error.message}`);\n }\n}\n\nexport function validateErrorResponse(response: unknown): ErrorResponse {\n const result = ErrorResponseSchema.safeParse(response);\n if (result.success) {\n return result.data;\n }\n\n // Fallback for malformed error responses\n return {\n message: \"Unknown error occurred\",\n code: \"UNKNOWN_ERROR\",\n };\n}\n"]}
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/index.ts"],"names":["amountBN"],"mappings":";;;
|
|
1
|
+
{"version":3,"sources":["../../src/utils/index.ts"],"names":["amountBN"],"mappings":"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","file":"index.js","sourcesContent":["import type { PaginationQuery, PaginatedResponse, Currency } from \"@chipi-stack/types\";\nimport { API_ENDPOINTS } from \"../constants\";\n\n/**\n * Utility functions used across Chipi SDK packages\n */\n\nexport function isValidAddress(address: string): boolean {\n // Validate Starknet address format\n return /^0x[0-9a-fA-F]{1,64}$/.test(address);\n}\n\nexport function isValidApiKey(apiKey: string): boolean {\n // Validate API key format (pk_dev_ or pk_prod_)\n return /^pk_(dev|prod)_[a-zA-Z0-9]{32,}$/.test(apiKey);\n}\n\nexport function formatAmount(amount: string, decimals: number = 18): string {\n // If it's an integer, multiply by 10^decimals\n if (!amount.includes(\".\")) {\n const amountBN = BigInt(amount) * BigInt(10) ** BigInt(decimals);\n return amountBN.toString();\n }\n\n // If it has decimals, handle properly\n const [integerPart, decimalPart = \"\"] = amount.split(\".\");\n const paddedDecimal = decimalPart.padEnd(decimals, \"0\").slice(0, decimals);\n const amountBN = BigInt(integerPart + paddedDecimal);\n\n return amountBN.toString();\n}\n\nexport function parseAmount(amount: string, decimals: number = 18): number {\n const amountBN = BigInt(amount);\n const divisor = BigInt(10) ** BigInt(decimals);\n return Number(amountBN) / Number(divisor);\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function retry<T>(\n fn: () => Promise<T>,\n options: {\n maxAttempts?: number;\n delay?: number;\n backoff?: boolean;\n } = {}\n): Promise<T> {\n const { maxAttempts = 3, delay = 1000, backoff = true } = options;\n\n return new Promise((resolve, reject) => {\n let attempt = 0;\n\n const tryFn = async () => {\n try {\n const result = await fn();\n resolve(result);\n } catch (error) {\n attempt++;\n\n if (attempt >= maxAttempts) {\n reject(error);\n return;\n }\n\n const waitTime = backoff ? delay * Math.pow(2, attempt - 1) : delay;\n setTimeout(tryFn, waitTime);\n }\n };\n\n tryFn();\n });\n}\n\nexport function createPaginatedResponse<T>(\n data: T[],\n query: PaginationQuery,\n total: number\n): PaginatedResponse<T> {\n const page = query.page || 1;\n const limit = query.limit || 10;\n const totalPages = Math.ceil(total / limit);\n\n return {\n data,\n total,\n page,\n limit,\n totalPages,\n };\n}\n\nexport function validatePagination(query: PaginationQuery): {\n page: number;\n limit: number;\n} {\n const page = Math.max(1, query.page || 1);\n const limit = Math.min(100, Math.max(1, query.limit || 10));\n\n return { page, limit };\n}\n\nexport function sanitizeUrl(url: string): string {\n try {\n const parsed = new URL(url);\n return parsed.toString();\n } catch (error) {\n throw new Error(`Invalid URL: ${url}`);\n }\n}\n\nexport function deepMerge<T extends Record<string, any>>(target: T, source: Partial<T>): T {\n const result = { ...target };\n\n for (const key in source) {\n if (source[key] !== undefined) {\n const sourceValue = source[key];\n if (\n typeof sourceValue === \"object\" &&\n sourceValue !== null &&\n !Array.isArray(sourceValue) &&\n typeof result[key] === \"object\" &&\n result[key] !== null &&\n !Array.isArray(result[key])\n ) {\n result[key] = deepMerge(result[key], sourceValue);\n } else {\n result[key] = sourceValue as T[Extract<keyof T, string>];\n }\n }\n }\n\n return result;\n}\n"]}
|
package/dist/utils/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/index.ts"],"names":["amountBN"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../../src/utils/index.ts"],"names":["amountBN"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { PaginationQuery, PaginatedResponse, Currency } from \"@chipi-stack/types\";\nimport { API_ENDPOINTS } from \"../constants\";\n\n/**\n * Utility functions used across Chipi SDK packages\n */\n\nexport function isValidAddress(address: string): boolean {\n // Validate Starknet address format\n return /^0x[0-9a-fA-F]{1,64}$/.test(address);\n}\n\nexport function isValidApiKey(apiKey: string): boolean {\n // Validate API key format (pk_dev_ or pk_prod_)\n return /^pk_(dev|prod)_[a-zA-Z0-9]{32,}$/.test(apiKey);\n}\n\nexport function formatAmount(amount: string, decimals: number = 18): string {\n // If it's an integer, multiply by 10^decimals\n if (!amount.includes(\".\")) {\n const amountBN = BigInt(amount) * BigInt(10) ** BigInt(decimals);\n return amountBN.toString();\n }\n\n // If it has decimals, handle properly\n const [integerPart, decimalPart = \"\"] = amount.split(\".\");\n const paddedDecimal = decimalPart.padEnd(decimals, \"0\").slice(0, decimals);\n const amountBN = BigInt(integerPart + paddedDecimal);\n\n return amountBN.toString();\n}\n\nexport function parseAmount(amount: string, decimals: number = 18): number {\n const amountBN = BigInt(amount);\n const divisor = BigInt(10) ** BigInt(decimals);\n return Number(amountBN) / Number(divisor);\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function retry<T>(\n fn: () => Promise<T>,\n options: {\n maxAttempts?: number;\n delay?: number;\n backoff?: boolean;\n } = {}\n): Promise<T> {\n const { maxAttempts = 3, delay = 1000, backoff = true } = options;\n\n return new Promise((resolve, reject) => {\n let attempt = 0;\n\n const tryFn = async () => {\n try {\n const result = await fn();\n resolve(result);\n } catch (error) {\n attempt++;\n\n if (attempt >= maxAttempts) {\n reject(error);\n return;\n }\n\n const waitTime = backoff ? delay * Math.pow(2, attempt - 1) : delay;\n setTimeout(tryFn, waitTime);\n }\n };\n\n tryFn();\n });\n}\n\nexport function createPaginatedResponse<T>(\n data: T[],\n query: PaginationQuery,\n total: number\n): PaginatedResponse<T> {\n const page = query.page || 1;\n const limit = query.limit || 10;\n const totalPages = Math.ceil(total / limit);\n\n return {\n data,\n total,\n page,\n limit,\n totalPages,\n };\n}\n\nexport function validatePagination(query: PaginationQuery): {\n page: number;\n limit: number;\n} {\n const page = Math.max(1, query.page || 1);\n const limit = Math.min(100, Math.max(1, query.limit || 10));\n\n return { page, limit };\n}\n\nexport function sanitizeUrl(url: string): string {\n try {\n const parsed = new URL(url);\n return parsed.toString();\n } catch (error) {\n throw new Error(`Invalid URL: ${url}`);\n }\n}\n\nexport function deepMerge<T extends Record<string, any>>(target: T, source: Partial<T>): T {\n const result = { ...target };\n\n for (const key in source) {\n if (source[key] !== undefined) {\n const sourceValue = source[key];\n if (\n typeof sourceValue === \"object\" &&\n sourceValue !== null &&\n !Array.isArray(sourceValue) &&\n typeof result[key] === \"object\" &&\n result[key] !== null &&\n !Array.isArray(result[key])\n ) {\n result[key] = deepMerge(result[key], sourceValue);\n } else {\n result[key] = sourceValue as T[Extract<keyof T, string>];\n }\n }\n }\n\n return result;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chipi-stack/shared",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.0.0",
|
|
4
4
|
"description": "Shared utilities and helpers for Chipi SDK packages",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"starknet": ">=6.23.1",
|
|
53
53
|
"zod": "^4.0.17",
|
|
54
|
-
"@chipi-stack/types": "^
|
|
54
|
+
"@chipi-stack/types": "^14.0.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/node": "^22.15.15",
|