@chipi-stack/shared 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants/index.d.mts +40 -0
- package/dist/constants/index.d.ts +40 -0
- package/dist/constants/index.js +47 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/constants/index.mjs +40 -0
- package/dist/constants/index.mjs.map +1 -0
- package/dist/crypto/index.d.mts +11 -0
- package/dist/crypto/index.d.ts +11 -0
- package/dist/crypto/index.js +41 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/crypto/index.mjs +30 -0
- package/dist/crypto/index.mjs.map +1 -0
- package/dist/index.d.mts +77 -0
- package/dist/index.d.ts +77 -0
- package/dist/index.js +355 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +305 -0
- package/dist/index.mjs.map +1 -0
- package/dist/utils/index.d.mts +24 -0
- package/dist/utils/index.d.ts +24 -0
- package/dist/utils/index.js +101 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +90 -0
- package/dist/utils/index.mjs.map +1 -0
- package/package.json +94 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var CryptoJS = require('crypto-js');
|
|
4
|
+
var zod = require('zod');
|
|
5
|
+
|
|
6
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
|
|
8
|
+
var CryptoJS__default = /*#__PURE__*/_interopDefault(CryptoJS);
|
|
9
|
+
|
|
10
|
+
// src/utils/index.ts
|
|
11
|
+
function isValidAddress(address) {
|
|
12
|
+
return /^0x[0-9a-fA-F]{1,64}$/.test(address);
|
|
13
|
+
}
|
|
14
|
+
function isValidApiKey(apiKey) {
|
|
15
|
+
return /^pk_(dev|prod)_[a-zA-Z0-9]{32,}$/.test(apiKey);
|
|
16
|
+
}
|
|
17
|
+
function formatAmount(amount, decimals = 18) {
|
|
18
|
+
const amountStr = amount.toString();
|
|
19
|
+
if (!amountStr.includes(".")) {
|
|
20
|
+
const amountBN2 = BigInt(amountStr) * BigInt(10) ** BigInt(decimals);
|
|
21
|
+
return amountBN2.toString();
|
|
22
|
+
}
|
|
23
|
+
const [integerPart, decimalPart = ""] = amountStr.split(".");
|
|
24
|
+
const paddedDecimal = decimalPart.padEnd(decimals, "0").slice(0, decimals);
|
|
25
|
+
const amountBN = BigInt(integerPart + paddedDecimal);
|
|
26
|
+
return amountBN.toString();
|
|
27
|
+
}
|
|
28
|
+
function parseAmount(amount, decimals = 18) {
|
|
29
|
+
const amountBN = BigInt(amount);
|
|
30
|
+
const divisor = BigInt(10) ** BigInt(decimals);
|
|
31
|
+
return Number(amountBN) / Number(divisor);
|
|
32
|
+
}
|
|
33
|
+
function sleep(ms) {
|
|
34
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
35
|
+
}
|
|
36
|
+
function retry(fn, options = {}) {
|
|
37
|
+
const { maxAttempts = 3, delay = 1e3, backoff = true } = options;
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
let attempt = 0;
|
|
40
|
+
const tryFn = async () => {
|
|
41
|
+
try {
|
|
42
|
+
const result = await fn();
|
|
43
|
+
resolve(result);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
attempt++;
|
|
46
|
+
if (attempt >= maxAttempts) {
|
|
47
|
+
reject(error);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const waitTime = backoff ? delay * Math.pow(2, attempt - 1) : delay;
|
|
51
|
+
setTimeout(tryFn, waitTime);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
tryFn();
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function createPaginatedResponse(data, query, total) {
|
|
58
|
+
const page = query.page || 1;
|
|
59
|
+
const limit = query.limit || 10;
|
|
60
|
+
const totalPages = Math.ceil(total / limit);
|
|
61
|
+
return {
|
|
62
|
+
data,
|
|
63
|
+
total,
|
|
64
|
+
page,
|
|
65
|
+
limit,
|
|
66
|
+
totalPages
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function validatePagination(query) {
|
|
70
|
+
const page = Math.max(1, query.page || 1);
|
|
71
|
+
const limit = Math.min(100, Math.max(1, query.limit || 10));
|
|
72
|
+
return { page, limit };
|
|
73
|
+
}
|
|
74
|
+
function sanitizeUrl(url) {
|
|
75
|
+
try {
|
|
76
|
+
const parsed = new URL(url);
|
|
77
|
+
return parsed.toString();
|
|
78
|
+
} catch (error) {
|
|
79
|
+
throw new Error(`Invalid URL: ${url}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function deepMerge(target, source) {
|
|
83
|
+
const result = { ...target };
|
|
84
|
+
for (const key in source) {
|
|
85
|
+
if (source[key] !== void 0) {
|
|
86
|
+
const sourceValue = source[key];
|
|
87
|
+
if (typeof sourceValue === "object" && sourceValue !== null && !Array.isArray(sourceValue) && typeof result[key] === "object" && result[key] !== null && !Array.isArray(result[key])) {
|
|
88
|
+
result[key] = deepMerge(result[key], sourceValue);
|
|
89
|
+
} else {
|
|
90
|
+
result[key] = sourceValue;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
function encryptData(data, key) {
|
|
97
|
+
return CryptoJS__default.default.AES.encrypt(data, key).toString();
|
|
98
|
+
}
|
|
99
|
+
function decryptData(encryptedData, key) {
|
|
100
|
+
const bytes = CryptoJS__default.default.AES.decrypt(encryptedData, key);
|
|
101
|
+
return bytes.toString(CryptoJS__default.default.enc.Utf8);
|
|
102
|
+
}
|
|
103
|
+
function generateSalt() {
|
|
104
|
+
return CryptoJS__default.default.lib.WordArray.random(32).toString();
|
|
105
|
+
}
|
|
106
|
+
function hashData(data) {
|
|
107
|
+
return CryptoJS__default.default.SHA256(data).toString();
|
|
108
|
+
}
|
|
109
|
+
function generateRandomKey() {
|
|
110
|
+
return CryptoJS__default.default.lib.WordArray.random(32).toString();
|
|
111
|
+
}
|
|
112
|
+
function validateSignature(data, signature, publicKey) {
|
|
113
|
+
try {
|
|
114
|
+
return signature.length > 0 && publicKey.length > 0;
|
|
115
|
+
} catch (error) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/constants/index.ts
|
|
121
|
+
var STARKNET_NETWORKS = {
|
|
122
|
+
MAINNET: "https://starknet-mainnet.public.blastapi.io/rpc/v0_7",
|
|
123
|
+
SEPOLIA: "https://starknet-sepolia.public.blastapi.io/rpc/v0_7"
|
|
124
|
+
};
|
|
125
|
+
var CONTRACT_ADDRESSES = {
|
|
126
|
+
USDC_MAINNET: "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8",
|
|
127
|
+
VESU_USDC_MAINNET: "0x017f19582c61479f2fe0b6606300e975c0a8f439102f43eeecc1d0e9b3d84350"
|
|
128
|
+
};
|
|
129
|
+
var TOKEN_DECIMALS = {
|
|
130
|
+
USDC: 6,
|
|
131
|
+
USDT: 6,
|
|
132
|
+
ETH: 18,
|
|
133
|
+
STRK: 18,
|
|
134
|
+
DAI: 18
|
|
135
|
+
};
|
|
136
|
+
var API_ENDPOINTS = {
|
|
137
|
+
CHIPI_WALLETS: "/chipi-wallets",
|
|
138
|
+
TRANSACTIONS: "/transactions",
|
|
139
|
+
SKUS: "/skus",
|
|
140
|
+
SKU_TRANSACTIONS: "/sku-transactions"
|
|
141
|
+
};
|
|
142
|
+
var DEFAULT_PAGINATION = {
|
|
143
|
+
PAGE: 1,
|
|
144
|
+
LIMIT: 10,
|
|
145
|
+
MAX_LIMIT: 100
|
|
146
|
+
};
|
|
147
|
+
var ERRORS = {
|
|
148
|
+
INVALID_API_KEY: "INVALID_API_KEY",
|
|
149
|
+
WALLET_NOT_FOUND: "WALLET_NOT_FOUND",
|
|
150
|
+
INSUFFICIENT_BALANCE: "INSUFFICIENT_BALANCE",
|
|
151
|
+
TRANSACTION_FAILED: "TRANSACTION_FAILED",
|
|
152
|
+
INVALID_SIGNATURE: "INVALID_SIGNATURE",
|
|
153
|
+
SKU_NOT_FOUND: "SKU_NOT_FOUND",
|
|
154
|
+
SKU_UNAVAILABLE: "SKU_UNAVAILABLE"
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// src/errors.ts
|
|
158
|
+
var ChipiError = class _ChipiError extends Error {
|
|
159
|
+
constructor(message, code, status) {
|
|
160
|
+
super(message);
|
|
161
|
+
this.name = "ChipiError";
|
|
162
|
+
this.code = code;
|
|
163
|
+
this.status = status;
|
|
164
|
+
if (Error.captureStackTrace) {
|
|
165
|
+
Error.captureStackTrace(this, _ChipiError);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
var ChipiApiError = class extends ChipiError {
|
|
170
|
+
constructor(message, code, status) {
|
|
171
|
+
super(message, code, status);
|
|
172
|
+
this.name = "ChipiApiError";
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
var ChipiWalletError = class extends ChipiError {
|
|
176
|
+
constructor(message, code = "WALLET_ERROR") {
|
|
177
|
+
super(message, code);
|
|
178
|
+
this.name = "ChipiWalletError";
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
var ChipiTransactionError = class extends ChipiError {
|
|
182
|
+
constructor(message, code = "TRANSACTION_ERROR") {
|
|
183
|
+
super(message, code);
|
|
184
|
+
this.name = "ChipiTransactionError";
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
var ChipiSkuError = class extends ChipiError {
|
|
188
|
+
constructor(message, code = "SKU_ERROR") {
|
|
189
|
+
super(message, code);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
var ChipiValidationError = class extends ChipiError {
|
|
193
|
+
constructor(message, code = "VALIDATION_ERROR") {
|
|
194
|
+
super(message, code, 400);
|
|
195
|
+
this.name = "ChipiValidationError";
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
var ChipiAuthError = class extends ChipiError {
|
|
199
|
+
constructor(message, code = "AUTH_ERROR") {
|
|
200
|
+
super(message, code, 401);
|
|
201
|
+
this.name = "ChipiAuthError";
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
function isChipiError(error) {
|
|
205
|
+
return error instanceof ChipiError;
|
|
206
|
+
}
|
|
207
|
+
function handleApiError(error) {
|
|
208
|
+
if (isChipiError(error)) {
|
|
209
|
+
return error;
|
|
210
|
+
}
|
|
211
|
+
if (error?.response?.status) {
|
|
212
|
+
const status = error.response.status;
|
|
213
|
+
const message = error.response.data?.message || error.message || "API request failed";
|
|
214
|
+
const code = error.response.data?.code || `HTTP_${status}`;
|
|
215
|
+
return new ChipiApiError(message, code, status);
|
|
216
|
+
}
|
|
217
|
+
return new ChipiError(
|
|
218
|
+
error?.message || "An unknown error occurred",
|
|
219
|
+
"UNKNOWN_ERROR"
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// src/formatters.ts
|
|
224
|
+
function formatCurrency(amount, currency = "USD", locale = "en-US") {
|
|
225
|
+
return new Intl.NumberFormat(locale, {
|
|
226
|
+
style: "currency",
|
|
227
|
+
currency
|
|
228
|
+
}).format(amount);
|
|
229
|
+
}
|
|
230
|
+
function formatNumber(value, options = {}) {
|
|
231
|
+
const { decimals = 2, locale = "en-US", compact = false } = options;
|
|
232
|
+
return new Intl.NumberFormat(locale, {
|
|
233
|
+
minimumFractionDigits: decimals,
|
|
234
|
+
maximumFractionDigits: decimals,
|
|
235
|
+
notation: compact ? "compact" : "standard"
|
|
236
|
+
}).format(value);
|
|
237
|
+
}
|
|
238
|
+
function formatDate(date, options = {}) {
|
|
239
|
+
const { locale = "en-US", dateStyle = "medium", timeStyle } = options;
|
|
240
|
+
const dateObj = typeof date === "string" ? new Date(date) : date;
|
|
241
|
+
return new Intl.DateTimeFormat(locale, {
|
|
242
|
+
dateStyle,
|
|
243
|
+
timeStyle
|
|
244
|
+
}).format(dateObj);
|
|
245
|
+
}
|
|
246
|
+
function formatAddress(address, length = 8) {
|
|
247
|
+
if (address.length <= length * 2) {
|
|
248
|
+
return address;
|
|
249
|
+
}
|
|
250
|
+
return `${address.slice(0, length)}...${address.slice(-length)}`;
|
|
251
|
+
}
|
|
252
|
+
function formatTransactionHash(hash) {
|
|
253
|
+
return formatAddress(hash, 6);
|
|
254
|
+
}
|
|
255
|
+
function formatTokenAmount(amount, decimals = 18, displayDecimals = 4) {
|
|
256
|
+
const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
257
|
+
const divisor = Math.pow(10, decimals);
|
|
258
|
+
const formattedAmount = numAmount / divisor;
|
|
259
|
+
return formattedAmount.toFixed(displayDecimals);
|
|
260
|
+
}
|
|
261
|
+
function camelToSnake(str) {
|
|
262
|
+
return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
263
|
+
}
|
|
264
|
+
function snakeToCamel(str) {
|
|
265
|
+
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
266
|
+
}
|
|
267
|
+
function capitalizeFirst(str) {
|
|
268
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
269
|
+
}
|
|
270
|
+
var ApiResponseSchema = zod.z.object({
|
|
271
|
+
success: zod.z.boolean(),
|
|
272
|
+
data: zod.z.unknown(),
|
|
273
|
+
message: zod.z.string().optional(),
|
|
274
|
+
code: zod.z.string().optional()
|
|
275
|
+
});
|
|
276
|
+
var ErrorResponseSchema = zod.z.object({
|
|
277
|
+
message: zod.z.string(),
|
|
278
|
+
code: zod.z.string().optional(),
|
|
279
|
+
status: zod.z.number().optional()
|
|
280
|
+
});
|
|
281
|
+
var SuccessResponseSchema = (dataSchema) => zod.z.object({
|
|
282
|
+
success: zod.z.literal(true),
|
|
283
|
+
data: dataSchema
|
|
284
|
+
});
|
|
285
|
+
function validateApiResponse(response, dataSchema) {
|
|
286
|
+
if (dataSchema) {
|
|
287
|
+
const result2 = SuccessResponseSchema(dataSchema).safeParse(response);
|
|
288
|
+
if (result2.success) {
|
|
289
|
+
return result2.data.data;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
const result = ApiResponseSchema.safeParse(response);
|
|
293
|
+
if (result.success && result.data.success) {
|
|
294
|
+
return result.data.data;
|
|
295
|
+
}
|
|
296
|
+
throw new Error("Invalid API response format");
|
|
297
|
+
}
|
|
298
|
+
function validateErrorResponse(response) {
|
|
299
|
+
const result = ErrorResponseSchema.safeParse(response);
|
|
300
|
+
if (result.success) {
|
|
301
|
+
return result.data;
|
|
302
|
+
}
|
|
303
|
+
return {
|
|
304
|
+
message: "Unknown error occurred",
|
|
305
|
+
code: "UNKNOWN_ERROR"
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
exports.API_ENDPOINTS = API_ENDPOINTS;
|
|
310
|
+
exports.ApiResponseSchema = ApiResponseSchema;
|
|
311
|
+
exports.CONTRACT_ADDRESSES = CONTRACT_ADDRESSES;
|
|
312
|
+
exports.ChipiApiError = ChipiApiError;
|
|
313
|
+
exports.ChipiAuthError = ChipiAuthError;
|
|
314
|
+
exports.ChipiError = ChipiError;
|
|
315
|
+
exports.ChipiSkuError = ChipiSkuError;
|
|
316
|
+
exports.ChipiTransactionError = ChipiTransactionError;
|
|
317
|
+
exports.ChipiValidationError = ChipiValidationError;
|
|
318
|
+
exports.ChipiWalletError = ChipiWalletError;
|
|
319
|
+
exports.DEFAULT_PAGINATION = DEFAULT_PAGINATION;
|
|
320
|
+
exports.ERRORS = ERRORS;
|
|
321
|
+
exports.ErrorResponseSchema = ErrorResponseSchema;
|
|
322
|
+
exports.STARKNET_NETWORKS = STARKNET_NETWORKS;
|
|
323
|
+
exports.SuccessResponseSchema = SuccessResponseSchema;
|
|
324
|
+
exports.TOKEN_DECIMALS = TOKEN_DECIMALS;
|
|
325
|
+
exports.camelToSnake = camelToSnake;
|
|
326
|
+
exports.capitalizeFirst = capitalizeFirst;
|
|
327
|
+
exports.createPaginatedResponse = createPaginatedResponse;
|
|
328
|
+
exports.decryptData = decryptData;
|
|
329
|
+
exports.deepMerge = deepMerge;
|
|
330
|
+
exports.encryptData = encryptData;
|
|
331
|
+
exports.formatAddress = formatAddress;
|
|
332
|
+
exports.formatAmount = formatAmount;
|
|
333
|
+
exports.formatCurrency = formatCurrency;
|
|
334
|
+
exports.formatDate = formatDate;
|
|
335
|
+
exports.formatNumber = formatNumber;
|
|
336
|
+
exports.formatTokenAmount = formatTokenAmount;
|
|
337
|
+
exports.formatTransactionHash = formatTransactionHash;
|
|
338
|
+
exports.generateRandomKey = generateRandomKey;
|
|
339
|
+
exports.generateSalt = generateSalt;
|
|
340
|
+
exports.handleApiError = handleApiError;
|
|
341
|
+
exports.hashData = hashData;
|
|
342
|
+
exports.isChipiError = isChipiError;
|
|
343
|
+
exports.isValidAddress = isValidAddress;
|
|
344
|
+
exports.isValidApiKey = isValidApiKey;
|
|
345
|
+
exports.parseAmount = parseAmount;
|
|
346
|
+
exports.retry = retry;
|
|
347
|
+
exports.sanitizeUrl = sanitizeUrl;
|
|
348
|
+
exports.sleep = sleep;
|
|
349
|
+
exports.snakeToCamel = snakeToCamel;
|
|
350
|
+
exports.validateApiResponse = validateApiResponse;
|
|
351
|
+
exports.validateErrorResponse = validateErrorResponse;
|
|
352
|
+
exports.validatePagination = validatePagination;
|
|
353
|
+
exports.validateSignature = validateSignature;
|
|
354
|
+
//# sourceMappingURL=index.js.map
|
|
355
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/index.ts","../src/crypto/index.ts","../src/constants/index.ts","../src/errors.ts","../src/formatters.ts","../src/validation.ts"],"names":["amountBN","CryptoJS","z","result"],"mappings":"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","file":"index.js","sourcesContent":["import type { PaginationQuery, PaginatedResponse } from '@chipi-stack/types';\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 | number, decimals: number = 18): string {\n const amountStr = amount.toString();\n \n // If it's an integer, multiply by 10^decimals\n if (!amountStr.includes('.')) {\n const amountBN = BigInt(amountStr) * BigInt(10) ** BigInt(decimals);\n return amountBN.toString();\n }\n\n // If it has decimals, handle properly\n const [integerPart, decimalPart = ''] = amountStr.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","import CryptoJS from 'crypto-js';\n\n/**\n * Crypto utilities for Chipi SDK\n */\n\nexport function encryptData(data: string, key: string): string {\n return CryptoJS.AES.encrypt(data, key).toString();\n}\n\nexport function decryptData(encryptedData: string, key: string): string {\n const bytes = CryptoJS.AES.decrypt(encryptedData, key);\n return bytes.toString(CryptoJS.enc.Utf8);\n}\n\nexport function generateSalt(): string {\n return CryptoJS.lib.WordArray.random(32).toString();\n}\n\nexport function hashData(data: string): string {\n return CryptoJS.SHA256(data).toString();\n}\n\nexport function generateRandomKey(): string {\n return CryptoJS.lib.WordArray.random(32).toString();\n}\n\nexport function validateSignature(data: string, signature: string, publicKey: string): boolean {\n // Implementation depends on the signature scheme used\n // This is a placeholder for signature validation logic\n try {\n // Add actual signature validation logic here\n return signature.length > 0 && publicKey.length > 0;\n } catch (error) {\n return false;\n }\n}\n","/**\n * Constants used across Chipi SDK packages\n */\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: '0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8',\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_TRANSACTIONS: '/sku-transactions',\n} as const;\n\nexport const DEFAULT_PAGINATION = {\n PAGE: 1,\n LIMIT: 10,\n MAX_LIMIT: 100,\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","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 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\nexport function formatTokenAmount(\n amount: string | number,\n decimals: number = 18,\n displayDecimals: number = 4\n): string {\n const numAmount = typeof amount === 'string' ? parseFloat(amount) : amount;\n const divisor = Math.pow(10, decimals);\n const formattedAmount = numAmount / divisor;\n \n return formattedAmount.toFixed(displayDecimals);\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 success: z.boolean(),\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 success: z.literal(true),\n data: dataSchema,\n });\n\n// Type helpers\nexport type ApiResponse<T> = z.infer<ReturnType<typeof SuccessResponseSchema<z.ZodType<T>>>>;\nexport type ErrorResponse = z.infer<typeof ErrorResponseSchema>;\n\n// Validation functions\nexport function validateApiResponse<T>(\n response: unknown,\n dataSchema?: z.ZodType<T>\n): T {\n if (dataSchema) {\n // Validate with specific data schema\n const result = SuccessResponseSchema(dataSchema).safeParse(response);\n if (result.success) {\n return result.data.data;\n }\n }\n \n // Fallback to basic validation\n const result = ApiResponseSchema.safeParse(response);\n if (result.success && result.data.success) {\n return result.data.data as T;\n }\n \n throw new Error('Invalid API response format');\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"]}
|