@straton/utils 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +237 -0
- package/dist/index.d.ts +237 -0
- package/dist/index.js +365 -0
- package/dist/index.mjs +303 -0
- package/package.json +48 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { ClassValue } from 'clsx';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Utility function to merge Tailwind CSS classes with clsx
|
|
6
|
+
*/
|
|
7
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Format a number as currency
|
|
11
|
+
*/
|
|
12
|
+
declare function formatCurrency(value: number, currency?: string, locale?: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Format a number as percentage
|
|
15
|
+
*/
|
|
16
|
+
declare function formatPercentage(value: number, decimals?: number): string;
|
|
17
|
+
/**
|
|
18
|
+
* Format a bigint token amount with decimals
|
|
19
|
+
*/
|
|
20
|
+
declare function formatTokenAmount(amount: bigint, decimals: number, displayDecimals?: number): string;
|
|
21
|
+
/**
|
|
22
|
+
* Format an address for display (truncated)
|
|
23
|
+
*/
|
|
24
|
+
declare function formatAddress(address: string, chars?: number): string;
|
|
25
|
+
/**
|
|
26
|
+
* Format a date relative to now
|
|
27
|
+
*/
|
|
28
|
+
declare function formatRelativeTime(date: Date, locale?: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Format APY for display
|
|
31
|
+
*/
|
|
32
|
+
declare function formatAPY(apy: number): string;
|
|
33
|
+
/**
|
|
34
|
+
* Format large numbers with abbreviations
|
|
35
|
+
*/
|
|
36
|
+
declare function formatCompactNumber(value: number, locale?: string): string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Ethereum address validation
|
|
40
|
+
*/
|
|
41
|
+
declare const addressSchema: z.ZodString;
|
|
42
|
+
/**
|
|
43
|
+
* Transaction hash validation
|
|
44
|
+
*/
|
|
45
|
+
declare const txHashSchema: z.ZodString;
|
|
46
|
+
/**
|
|
47
|
+
* UUID validation
|
|
48
|
+
*/
|
|
49
|
+
declare const uuidSchema: z.ZodString;
|
|
50
|
+
/**
|
|
51
|
+
* Email validation
|
|
52
|
+
*/
|
|
53
|
+
declare const emailSchema: z.ZodString;
|
|
54
|
+
/**
|
|
55
|
+
* Brazilian CPF validation
|
|
56
|
+
*/
|
|
57
|
+
declare const cpfSchema: z.ZodString;
|
|
58
|
+
/**
|
|
59
|
+
* Brazilian CNPJ validation
|
|
60
|
+
*/
|
|
61
|
+
declare const cnpjSchema: z.ZodString;
|
|
62
|
+
/**
|
|
63
|
+
* Positive number validation
|
|
64
|
+
*/
|
|
65
|
+
declare const positiveNumberSchema: z.ZodNumber;
|
|
66
|
+
/**
|
|
67
|
+
* BigInt string validation (for token amounts)
|
|
68
|
+
*/
|
|
69
|
+
declare const bigIntStringSchema: z.ZodString;
|
|
70
|
+
/**
|
|
71
|
+
* ISO country code validation
|
|
72
|
+
*/
|
|
73
|
+
declare const countryCodeSchema: z.ZodString;
|
|
74
|
+
/**
|
|
75
|
+
* Pagination params schema
|
|
76
|
+
*/
|
|
77
|
+
declare const paginationSchema: z.ZodObject<{
|
|
78
|
+
page: z.ZodDefault<z.ZodNumber>;
|
|
79
|
+
perPage: z.ZodDefault<z.ZodNumber>;
|
|
80
|
+
sortBy: z.ZodOptional<z.ZodString>;
|
|
81
|
+
sortOrder: z.ZodDefault<z.ZodEnum<["asc", "desc"]>>;
|
|
82
|
+
}, "strip", z.ZodTypeAny, {
|
|
83
|
+
page: number;
|
|
84
|
+
perPage: number;
|
|
85
|
+
sortOrder: "asc" | "desc";
|
|
86
|
+
sortBy?: string | undefined;
|
|
87
|
+
}, {
|
|
88
|
+
page?: number | undefined;
|
|
89
|
+
perPage?: number | undefined;
|
|
90
|
+
sortBy?: string | undefined;
|
|
91
|
+
sortOrder?: "asc" | "desc" | undefined;
|
|
92
|
+
}>;
|
|
93
|
+
type PaginationParams = z.infer<typeof paginationSchema>;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Supported chain IDs
|
|
97
|
+
*/
|
|
98
|
+
declare const CHAIN_IDS: {
|
|
99
|
+
readonly ETHEREUM: 1;
|
|
100
|
+
readonly ETHEREUM_SEPOLIA: 11155111;
|
|
101
|
+
readonly POLYGON: 137;
|
|
102
|
+
readonly ARBITRUM: 42161;
|
|
103
|
+
readonly AVALANCHE: 43114;
|
|
104
|
+
readonly AVALANCHE_FUJI: 43113;
|
|
105
|
+
readonly BASE: 8453;
|
|
106
|
+
readonly POLYGON_AMOY: 80002;
|
|
107
|
+
readonly ARBITRUM_SEPOLIA: 421614;
|
|
108
|
+
readonly BASE_SEPOLIA: 84532;
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Chain names
|
|
112
|
+
*/
|
|
113
|
+
declare const CHAIN_NAMES: Record<number, string>;
|
|
114
|
+
/**
|
|
115
|
+
* Chain metadata for multi-chain support
|
|
116
|
+
*/
|
|
117
|
+
declare const CHAIN_METADATA: Record<number, {
|
|
118
|
+
isEvm: boolean;
|
|
119
|
+
isTestnet: boolean;
|
|
120
|
+
explorerUrl: string;
|
|
121
|
+
nativeCurrency: string;
|
|
122
|
+
}>;
|
|
123
|
+
/**
|
|
124
|
+
* Token decimals
|
|
125
|
+
*/
|
|
126
|
+
declare const TOKEN_DECIMALS: {
|
|
127
|
+
readonly DEFAULT: 18;
|
|
128
|
+
readonly USDC: 6;
|
|
129
|
+
readonly USDT: 6;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Common token addresses (mainnet)
|
|
133
|
+
*/
|
|
134
|
+
declare const TOKEN_ADDRESSES: {
|
|
135
|
+
readonly USDC: {
|
|
136
|
+
readonly 1: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
|
|
137
|
+
readonly 137: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359";
|
|
138
|
+
readonly 42161: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831";
|
|
139
|
+
readonly 8453: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Risk parameters by asset type
|
|
144
|
+
*/
|
|
145
|
+
declare const RISK_PARAMETERS: {
|
|
146
|
+
readonly REAL_ESTATE: {
|
|
147
|
+
readonly maxLTV: 0.7;
|
|
148
|
+
readonly liquidationThreshold: 0.8;
|
|
149
|
+
readonly interestBase: 0.12;
|
|
150
|
+
};
|
|
151
|
+
readonly CREDIT: {
|
|
152
|
+
readonly maxLTV: 0.6;
|
|
153
|
+
readonly liquidationThreshold: 0.75;
|
|
154
|
+
readonly interestBase: 0.15;
|
|
155
|
+
};
|
|
156
|
+
readonly COMMODITY: {
|
|
157
|
+
readonly maxLTV: 0.5;
|
|
158
|
+
readonly liquidationThreshold: 0.65;
|
|
159
|
+
readonly interestBase: 0.18;
|
|
160
|
+
};
|
|
161
|
+
readonly EQUITY: {
|
|
162
|
+
readonly maxLTV: 0.5;
|
|
163
|
+
readonly liquidationThreshold: 0.65;
|
|
164
|
+
readonly interestBase: 0.16;
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* KYC status labels
|
|
169
|
+
*/
|
|
170
|
+
declare const KYC_STATUS_LABELS: {
|
|
171
|
+
readonly PENDING: "Pendente";
|
|
172
|
+
readonly IN_REVIEW: "Em análise";
|
|
173
|
+
readonly VERIFIED: "Verificado";
|
|
174
|
+
readonly REJECTED: "Rejeitado";
|
|
175
|
+
readonly EXPIRED: "Expirado";
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* Accreditation level labels
|
|
179
|
+
*/
|
|
180
|
+
declare const ACCREDITATION_LABELS: {
|
|
181
|
+
readonly RETAIL: "Varejo";
|
|
182
|
+
readonly QUALIFIED: "Qualificado";
|
|
183
|
+
readonly PROFESSIONAL: "Profissional";
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Asset type labels
|
|
187
|
+
*/
|
|
188
|
+
declare const ASSET_TYPE_LABELS: {
|
|
189
|
+
readonly REAL_ESTATE: "Imobiliário";
|
|
190
|
+
readonly CREDIT: "Crédito";
|
|
191
|
+
readonly COMMODITY: "Commodity";
|
|
192
|
+
readonly EQUITY: "Equity";
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Sleep for a given number of milliseconds
|
|
197
|
+
*/
|
|
198
|
+
declare function sleep(ms: number): Promise<void>;
|
|
199
|
+
/**
|
|
200
|
+
* Retry a function with exponential backoff
|
|
201
|
+
*/
|
|
202
|
+
declare function retry<T>(fn: () => Promise<T>, options?: {
|
|
203
|
+
maxRetries?: number;
|
|
204
|
+
initialDelay?: number;
|
|
205
|
+
maxDelay?: number;
|
|
206
|
+
backoffFactor?: number;
|
|
207
|
+
}): Promise<T>;
|
|
208
|
+
/**
|
|
209
|
+
* Check if a value is defined (not null or undefined)
|
|
210
|
+
*/
|
|
211
|
+
declare function isDefined<T>(value: T | null | undefined): value is T;
|
|
212
|
+
/**
|
|
213
|
+
* Create a debounced function
|
|
214
|
+
*/
|
|
215
|
+
declare function debounce<T extends (...args: unknown[]) => unknown>(fn: T, delay: number): (...args: Parameters<T>) => void;
|
|
216
|
+
/**
|
|
217
|
+
* Create a throttled function
|
|
218
|
+
*/
|
|
219
|
+
declare function throttle<T extends (...args: unknown[]) => unknown>(fn: T, limit: number): (...args: Parameters<T>) => void;
|
|
220
|
+
/**
|
|
221
|
+
* Parse a bigint from various input types
|
|
222
|
+
*/
|
|
223
|
+
declare function parseBigInt(value: string | number | bigint): bigint;
|
|
224
|
+
/**
|
|
225
|
+
* Calculate percentage change
|
|
226
|
+
*/
|
|
227
|
+
declare function percentageChange(oldValue: number, newValue: number): number;
|
|
228
|
+
/**
|
|
229
|
+
* Chunk an array into smaller arrays
|
|
230
|
+
*/
|
|
231
|
+
declare function chunk<T>(array: T[], size: number): T[][];
|
|
232
|
+
/**
|
|
233
|
+
* Generate a unique ID
|
|
234
|
+
*/
|
|
235
|
+
declare function generateId(): string;
|
|
236
|
+
|
|
237
|
+
export { ACCREDITATION_LABELS, ASSET_TYPE_LABELS, CHAIN_IDS, CHAIN_METADATA, CHAIN_NAMES, KYC_STATUS_LABELS, type PaginationParams, RISK_PARAMETERS, TOKEN_ADDRESSES, TOKEN_DECIMALS, addressSchema, bigIntStringSchema, chunk, cn, cnpjSchema, countryCodeSchema, cpfSchema, debounce, emailSchema, formatAPY, formatAddress, formatCompactNumber, formatCurrency, formatPercentage, formatRelativeTime, formatTokenAmount, generateId, isDefined, paginationSchema, parseBigInt, percentageChange, positiveNumberSchema, retry, sleep, throttle, txHashSchema, uuidSchema };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { ClassValue } from 'clsx';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Utility function to merge Tailwind CSS classes with clsx
|
|
6
|
+
*/
|
|
7
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Format a number as currency
|
|
11
|
+
*/
|
|
12
|
+
declare function formatCurrency(value: number, currency?: string, locale?: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Format a number as percentage
|
|
15
|
+
*/
|
|
16
|
+
declare function formatPercentage(value: number, decimals?: number): string;
|
|
17
|
+
/**
|
|
18
|
+
* Format a bigint token amount with decimals
|
|
19
|
+
*/
|
|
20
|
+
declare function formatTokenAmount(amount: bigint, decimals: number, displayDecimals?: number): string;
|
|
21
|
+
/**
|
|
22
|
+
* Format an address for display (truncated)
|
|
23
|
+
*/
|
|
24
|
+
declare function formatAddress(address: string, chars?: number): string;
|
|
25
|
+
/**
|
|
26
|
+
* Format a date relative to now
|
|
27
|
+
*/
|
|
28
|
+
declare function formatRelativeTime(date: Date, locale?: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Format APY for display
|
|
31
|
+
*/
|
|
32
|
+
declare function formatAPY(apy: number): string;
|
|
33
|
+
/**
|
|
34
|
+
* Format large numbers with abbreviations
|
|
35
|
+
*/
|
|
36
|
+
declare function formatCompactNumber(value: number, locale?: string): string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Ethereum address validation
|
|
40
|
+
*/
|
|
41
|
+
declare const addressSchema: z.ZodString;
|
|
42
|
+
/**
|
|
43
|
+
* Transaction hash validation
|
|
44
|
+
*/
|
|
45
|
+
declare const txHashSchema: z.ZodString;
|
|
46
|
+
/**
|
|
47
|
+
* UUID validation
|
|
48
|
+
*/
|
|
49
|
+
declare const uuidSchema: z.ZodString;
|
|
50
|
+
/**
|
|
51
|
+
* Email validation
|
|
52
|
+
*/
|
|
53
|
+
declare const emailSchema: z.ZodString;
|
|
54
|
+
/**
|
|
55
|
+
* Brazilian CPF validation
|
|
56
|
+
*/
|
|
57
|
+
declare const cpfSchema: z.ZodString;
|
|
58
|
+
/**
|
|
59
|
+
* Brazilian CNPJ validation
|
|
60
|
+
*/
|
|
61
|
+
declare const cnpjSchema: z.ZodString;
|
|
62
|
+
/**
|
|
63
|
+
* Positive number validation
|
|
64
|
+
*/
|
|
65
|
+
declare const positiveNumberSchema: z.ZodNumber;
|
|
66
|
+
/**
|
|
67
|
+
* BigInt string validation (for token amounts)
|
|
68
|
+
*/
|
|
69
|
+
declare const bigIntStringSchema: z.ZodString;
|
|
70
|
+
/**
|
|
71
|
+
* ISO country code validation
|
|
72
|
+
*/
|
|
73
|
+
declare const countryCodeSchema: z.ZodString;
|
|
74
|
+
/**
|
|
75
|
+
* Pagination params schema
|
|
76
|
+
*/
|
|
77
|
+
declare const paginationSchema: z.ZodObject<{
|
|
78
|
+
page: z.ZodDefault<z.ZodNumber>;
|
|
79
|
+
perPage: z.ZodDefault<z.ZodNumber>;
|
|
80
|
+
sortBy: z.ZodOptional<z.ZodString>;
|
|
81
|
+
sortOrder: z.ZodDefault<z.ZodEnum<["asc", "desc"]>>;
|
|
82
|
+
}, "strip", z.ZodTypeAny, {
|
|
83
|
+
page: number;
|
|
84
|
+
perPage: number;
|
|
85
|
+
sortOrder: "asc" | "desc";
|
|
86
|
+
sortBy?: string | undefined;
|
|
87
|
+
}, {
|
|
88
|
+
page?: number | undefined;
|
|
89
|
+
perPage?: number | undefined;
|
|
90
|
+
sortBy?: string | undefined;
|
|
91
|
+
sortOrder?: "asc" | "desc" | undefined;
|
|
92
|
+
}>;
|
|
93
|
+
type PaginationParams = z.infer<typeof paginationSchema>;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Supported chain IDs
|
|
97
|
+
*/
|
|
98
|
+
declare const CHAIN_IDS: {
|
|
99
|
+
readonly ETHEREUM: 1;
|
|
100
|
+
readonly ETHEREUM_SEPOLIA: 11155111;
|
|
101
|
+
readonly POLYGON: 137;
|
|
102
|
+
readonly ARBITRUM: 42161;
|
|
103
|
+
readonly AVALANCHE: 43114;
|
|
104
|
+
readonly AVALANCHE_FUJI: 43113;
|
|
105
|
+
readonly BASE: 8453;
|
|
106
|
+
readonly POLYGON_AMOY: 80002;
|
|
107
|
+
readonly ARBITRUM_SEPOLIA: 421614;
|
|
108
|
+
readonly BASE_SEPOLIA: 84532;
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Chain names
|
|
112
|
+
*/
|
|
113
|
+
declare const CHAIN_NAMES: Record<number, string>;
|
|
114
|
+
/**
|
|
115
|
+
* Chain metadata for multi-chain support
|
|
116
|
+
*/
|
|
117
|
+
declare const CHAIN_METADATA: Record<number, {
|
|
118
|
+
isEvm: boolean;
|
|
119
|
+
isTestnet: boolean;
|
|
120
|
+
explorerUrl: string;
|
|
121
|
+
nativeCurrency: string;
|
|
122
|
+
}>;
|
|
123
|
+
/**
|
|
124
|
+
* Token decimals
|
|
125
|
+
*/
|
|
126
|
+
declare const TOKEN_DECIMALS: {
|
|
127
|
+
readonly DEFAULT: 18;
|
|
128
|
+
readonly USDC: 6;
|
|
129
|
+
readonly USDT: 6;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Common token addresses (mainnet)
|
|
133
|
+
*/
|
|
134
|
+
declare const TOKEN_ADDRESSES: {
|
|
135
|
+
readonly USDC: {
|
|
136
|
+
readonly 1: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
|
|
137
|
+
readonly 137: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359";
|
|
138
|
+
readonly 42161: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831";
|
|
139
|
+
readonly 8453: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Risk parameters by asset type
|
|
144
|
+
*/
|
|
145
|
+
declare const RISK_PARAMETERS: {
|
|
146
|
+
readonly REAL_ESTATE: {
|
|
147
|
+
readonly maxLTV: 0.7;
|
|
148
|
+
readonly liquidationThreshold: 0.8;
|
|
149
|
+
readonly interestBase: 0.12;
|
|
150
|
+
};
|
|
151
|
+
readonly CREDIT: {
|
|
152
|
+
readonly maxLTV: 0.6;
|
|
153
|
+
readonly liquidationThreshold: 0.75;
|
|
154
|
+
readonly interestBase: 0.15;
|
|
155
|
+
};
|
|
156
|
+
readonly COMMODITY: {
|
|
157
|
+
readonly maxLTV: 0.5;
|
|
158
|
+
readonly liquidationThreshold: 0.65;
|
|
159
|
+
readonly interestBase: 0.18;
|
|
160
|
+
};
|
|
161
|
+
readonly EQUITY: {
|
|
162
|
+
readonly maxLTV: 0.5;
|
|
163
|
+
readonly liquidationThreshold: 0.65;
|
|
164
|
+
readonly interestBase: 0.16;
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* KYC status labels
|
|
169
|
+
*/
|
|
170
|
+
declare const KYC_STATUS_LABELS: {
|
|
171
|
+
readonly PENDING: "Pendente";
|
|
172
|
+
readonly IN_REVIEW: "Em análise";
|
|
173
|
+
readonly VERIFIED: "Verificado";
|
|
174
|
+
readonly REJECTED: "Rejeitado";
|
|
175
|
+
readonly EXPIRED: "Expirado";
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* Accreditation level labels
|
|
179
|
+
*/
|
|
180
|
+
declare const ACCREDITATION_LABELS: {
|
|
181
|
+
readonly RETAIL: "Varejo";
|
|
182
|
+
readonly QUALIFIED: "Qualificado";
|
|
183
|
+
readonly PROFESSIONAL: "Profissional";
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Asset type labels
|
|
187
|
+
*/
|
|
188
|
+
declare const ASSET_TYPE_LABELS: {
|
|
189
|
+
readonly REAL_ESTATE: "Imobiliário";
|
|
190
|
+
readonly CREDIT: "Crédito";
|
|
191
|
+
readonly COMMODITY: "Commodity";
|
|
192
|
+
readonly EQUITY: "Equity";
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Sleep for a given number of milliseconds
|
|
197
|
+
*/
|
|
198
|
+
declare function sleep(ms: number): Promise<void>;
|
|
199
|
+
/**
|
|
200
|
+
* Retry a function with exponential backoff
|
|
201
|
+
*/
|
|
202
|
+
declare function retry<T>(fn: () => Promise<T>, options?: {
|
|
203
|
+
maxRetries?: number;
|
|
204
|
+
initialDelay?: number;
|
|
205
|
+
maxDelay?: number;
|
|
206
|
+
backoffFactor?: number;
|
|
207
|
+
}): Promise<T>;
|
|
208
|
+
/**
|
|
209
|
+
* Check if a value is defined (not null or undefined)
|
|
210
|
+
*/
|
|
211
|
+
declare function isDefined<T>(value: T | null | undefined): value is T;
|
|
212
|
+
/**
|
|
213
|
+
* Create a debounced function
|
|
214
|
+
*/
|
|
215
|
+
declare function debounce<T extends (...args: unknown[]) => unknown>(fn: T, delay: number): (...args: Parameters<T>) => void;
|
|
216
|
+
/**
|
|
217
|
+
* Create a throttled function
|
|
218
|
+
*/
|
|
219
|
+
declare function throttle<T extends (...args: unknown[]) => unknown>(fn: T, limit: number): (...args: Parameters<T>) => void;
|
|
220
|
+
/**
|
|
221
|
+
* Parse a bigint from various input types
|
|
222
|
+
*/
|
|
223
|
+
declare function parseBigInt(value: string | number | bigint): bigint;
|
|
224
|
+
/**
|
|
225
|
+
* Calculate percentage change
|
|
226
|
+
*/
|
|
227
|
+
declare function percentageChange(oldValue: number, newValue: number): number;
|
|
228
|
+
/**
|
|
229
|
+
* Chunk an array into smaller arrays
|
|
230
|
+
*/
|
|
231
|
+
declare function chunk<T>(array: T[], size: number): T[][];
|
|
232
|
+
/**
|
|
233
|
+
* Generate a unique ID
|
|
234
|
+
*/
|
|
235
|
+
declare function generateId(): string;
|
|
236
|
+
|
|
237
|
+
export { ACCREDITATION_LABELS, ASSET_TYPE_LABELS, CHAIN_IDS, CHAIN_METADATA, CHAIN_NAMES, KYC_STATUS_LABELS, type PaginationParams, RISK_PARAMETERS, TOKEN_ADDRESSES, TOKEN_DECIMALS, addressSchema, bigIntStringSchema, chunk, cn, cnpjSchema, countryCodeSchema, cpfSchema, debounce, emailSchema, formatAPY, formatAddress, formatCompactNumber, formatCurrency, formatPercentage, formatRelativeTime, formatTokenAmount, generateId, isDefined, paginationSchema, parseBigInt, percentageChange, positiveNumberSchema, retry, sleep, throttle, txHashSchema, uuidSchema };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ACCREDITATION_LABELS: () => ACCREDITATION_LABELS,
|
|
24
|
+
ASSET_TYPE_LABELS: () => ASSET_TYPE_LABELS,
|
|
25
|
+
CHAIN_IDS: () => CHAIN_IDS,
|
|
26
|
+
CHAIN_METADATA: () => CHAIN_METADATA,
|
|
27
|
+
CHAIN_NAMES: () => CHAIN_NAMES,
|
|
28
|
+
KYC_STATUS_LABELS: () => KYC_STATUS_LABELS,
|
|
29
|
+
RISK_PARAMETERS: () => RISK_PARAMETERS,
|
|
30
|
+
TOKEN_ADDRESSES: () => TOKEN_ADDRESSES,
|
|
31
|
+
TOKEN_DECIMALS: () => TOKEN_DECIMALS,
|
|
32
|
+
addressSchema: () => addressSchema,
|
|
33
|
+
bigIntStringSchema: () => bigIntStringSchema,
|
|
34
|
+
chunk: () => chunk,
|
|
35
|
+
cn: () => cn,
|
|
36
|
+
cnpjSchema: () => cnpjSchema,
|
|
37
|
+
countryCodeSchema: () => countryCodeSchema,
|
|
38
|
+
cpfSchema: () => cpfSchema,
|
|
39
|
+
debounce: () => debounce,
|
|
40
|
+
emailSchema: () => emailSchema,
|
|
41
|
+
formatAPY: () => formatAPY,
|
|
42
|
+
formatAddress: () => formatAddress,
|
|
43
|
+
formatCompactNumber: () => formatCompactNumber,
|
|
44
|
+
formatCurrency: () => formatCurrency,
|
|
45
|
+
formatPercentage: () => formatPercentage,
|
|
46
|
+
formatRelativeTime: () => formatRelativeTime,
|
|
47
|
+
formatTokenAmount: () => formatTokenAmount,
|
|
48
|
+
generateId: () => generateId,
|
|
49
|
+
isDefined: () => isDefined,
|
|
50
|
+
paginationSchema: () => paginationSchema,
|
|
51
|
+
parseBigInt: () => parseBigInt,
|
|
52
|
+
percentageChange: () => percentageChange,
|
|
53
|
+
positiveNumberSchema: () => positiveNumberSchema,
|
|
54
|
+
retry: () => retry,
|
|
55
|
+
sleep: () => sleep,
|
|
56
|
+
throttle: () => throttle,
|
|
57
|
+
txHashSchema: () => txHashSchema,
|
|
58
|
+
uuidSchema: () => uuidSchema
|
|
59
|
+
});
|
|
60
|
+
module.exports = __toCommonJS(index_exports);
|
|
61
|
+
|
|
62
|
+
// src/cn.ts
|
|
63
|
+
var import_clsx = require("clsx");
|
|
64
|
+
var import_tailwind_merge = require("tailwind-merge");
|
|
65
|
+
function cn(...inputs) {
|
|
66
|
+
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/format.ts
|
|
70
|
+
function formatCurrency(value, currency = "USD", locale = "en-US") {
|
|
71
|
+
return new Intl.NumberFormat(locale, {
|
|
72
|
+
style: "currency",
|
|
73
|
+
currency,
|
|
74
|
+
minimumFractionDigits: 2,
|
|
75
|
+
maximumFractionDigits: 2
|
|
76
|
+
}).format(value);
|
|
77
|
+
}
|
|
78
|
+
function formatPercentage(value, decimals = 2) {
|
|
79
|
+
return `${(value * 100).toFixed(decimals)}%`;
|
|
80
|
+
}
|
|
81
|
+
function formatTokenAmount(amount, decimals, displayDecimals = 4) {
|
|
82
|
+
const divisor = BigInt(10 ** decimals);
|
|
83
|
+
const integerPart = amount / divisor;
|
|
84
|
+
const fractionalPart = amount % divisor;
|
|
85
|
+
const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
|
|
86
|
+
const displayFractional = fractionalStr.slice(0, displayDecimals);
|
|
87
|
+
return `${integerPart}.${displayFractional}`;
|
|
88
|
+
}
|
|
89
|
+
function formatAddress(address, chars = 4) {
|
|
90
|
+
if (address.length < chars * 2 + 2) return address;
|
|
91
|
+
return `${address.slice(0, chars + 2)}...${address.slice(-chars)}`;
|
|
92
|
+
}
|
|
93
|
+
function formatRelativeTime(date, locale = "en-US") {
|
|
94
|
+
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
|
|
95
|
+
const diff = date.getTime() - Date.now();
|
|
96
|
+
const diffDays = Math.round(diff / (1e3 * 60 * 60 * 24));
|
|
97
|
+
if (Math.abs(diffDays) < 1) {
|
|
98
|
+
const diffHours = Math.round(diff / (1e3 * 60 * 60));
|
|
99
|
+
if (Math.abs(diffHours) < 1) {
|
|
100
|
+
const diffMinutes = Math.round(diff / (1e3 * 60));
|
|
101
|
+
return rtf.format(diffMinutes, "minute");
|
|
102
|
+
}
|
|
103
|
+
return rtf.format(diffHours, "hour");
|
|
104
|
+
}
|
|
105
|
+
if (Math.abs(diffDays) < 30) {
|
|
106
|
+
return rtf.format(diffDays, "day");
|
|
107
|
+
}
|
|
108
|
+
if (Math.abs(diffDays) < 365) {
|
|
109
|
+
return rtf.format(Math.round(diffDays / 30), "month");
|
|
110
|
+
}
|
|
111
|
+
return rtf.format(Math.round(diffDays / 365), "year");
|
|
112
|
+
}
|
|
113
|
+
function formatAPY(apy) {
|
|
114
|
+
return `${(apy * 100).toFixed(2)}% APY`;
|
|
115
|
+
}
|
|
116
|
+
function formatCompactNumber(value, locale = "en-US") {
|
|
117
|
+
return new Intl.NumberFormat(locale, {
|
|
118
|
+
notation: "compact",
|
|
119
|
+
compactDisplay: "short",
|
|
120
|
+
maximumFractionDigits: 2
|
|
121
|
+
}).format(value);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// src/validation.ts
|
|
125
|
+
var import_zod = require("zod");
|
|
126
|
+
var addressSchema = import_zod.z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid Ethereum address");
|
|
127
|
+
var txHashSchema = import_zod.z.string().regex(/^0x[a-fA-F0-9]{64}$/, "Invalid transaction hash");
|
|
128
|
+
var uuidSchema = import_zod.z.string().uuid();
|
|
129
|
+
var emailSchema = import_zod.z.string().email();
|
|
130
|
+
var cpfSchema = import_zod.z.string().regex(/^\d{3}\.\d{3}\.\d{3}-\d{2}$/, "Invalid CPF format");
|
|
131
|
+
var cnpjSchema = import_zod.z.string().regex(/^\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}$/, "Invalid CNPJ format");
|
|
132
|
+
var positiveNumberSchema = import_zod.z.number().positive();
|
|
133
|
+
var bigIntStringSchema = import_zod.z.string().regex(/^\d+$/, "Must be a valid integer string");
|
|
134
|
+
var countryCodeSchema = import_zod.z.string().length(2).toUpperCase();
|
|
135
|
+
var paginationSchema = import_zod.z.object({
|
|
136
|
+
page: import_zod.z.number().int().positive().default(1),
|
|
137
|
+
perPage: import_zod.z.number().int().positive().max(100).default(20),
|
|
138
|
+
sortBy: import_zod.z.string().optional(),
|
|
139
|
+
sortOrder: import_zod.z.enum(["asc", "desc"]).default("desc")
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// src/constants.ts
|
|
143
|
+
var CHAIN_IDS = {
|
|
144
|
+
ETHEREUM: 1,
|
|
145
|
+
ETHEREUM_SEPOLIA: 11155111,
|
|
146
|
+
POLYGON: 137,
|
|
147
|
+
ARBITRUM: 42161,
|
|
148
|
+
AVALANCHE: 43114,
|
|
149
|
+
AVALANCHE_FUJI: 43113,
|
|
150
|
+
BASE: 8453,
|
|
151
|
+
POLYGON_AMOY: 80002,
|
|
152
|
+
ARBITRUM_SEPOLIA: 421614,
|
|
153
|
+
BASE_SEPOLIA: 84532
|
|
154
|
+
};
|
|
155
|
+
var CHAIN_NAMES = {
|
|
156
|
+
[CHAIN_IDS.ETHEREUM]: "Ethereum",
|
|
157
|
+
[CHAIN_IDS.ETHEREUM_SEPOLIA]: "Ethereum Sepolia",
|
|
158
|
+
[CHAIN_IDS.POLYGON]: "Polygon",
|
|
159
|
+
[CHAIN_IDS.ARBITRUM]: "Arbitrum",
|
|
160
|
+
[CHAIN_IDS.AVALANCHE]: "Avalanche",
|
|
161
|
+
[CHAIN_IDS.AVALANCHE_FUJI]: "Avalanche Fuji",
|
|
162
|
+
[CHAIN_IDS.BASE]: "Base",
|
|
163
|
+
[CHAIN_IDS.POLYGON_AMOY]: "Polygon Amoy",
|
|
164
|
+
[CHAIN_IDS.ARBITRUM_SEPOLIA]: "Arbitrum Sepolia",
|
|
165
|
+
[CHAIN_IDS.BASE_SEPOLIA]: "Base Sepolia"
|
|
166
|
+
};
|
|
167
|
+
var CHAIN_METADATA = {
|
|
168
|
+
[CHAIN_IDS.ETHEREUM]: {
|
|
169
|
+
isEvm: true,
|
|
170
|
+
isTestnet: false,
|
|
171
|
+
explorerUrl: "https://etherscan.io",
|
|
172
|
+
nativeCurrency: "ETH"
|
|
173
|
+
},
|
|
174
|
+
[CHAIN_IDS.ETHEREUM_SEPOLIA]: {
|
|
175
|
+
isEvm: true,
|
|
176
|
+
isTestnet: true,
|
|
177
|
+
explorerUrl: "https://sepolia.etherscan.io",
|
|
178
|
+
nativeCurrency: "ETH"
|
|
179
|
+
},
|
|
180
|
+
[CHAIN_IDS.POLYGON]: {
|
|
181
|
+
isEvm: true,
|
|
182
|
+
isTestnet: false,
|
|
183
|
+
explorerUrl: "https://polygonscan.com",
|
|
184
|
+
nativeCurrency: "MATIC"
|
|
185
|
+
},
|
|
186
|
+
[CHAIN_IDS.ARBITRUM]: {
|
|
187
|
+
isEvm: true,
|
|
188
|
+
isTestnet: false,
|
|
189
|
+
explorerUrl: "https://arbiscan.io",
|
|
190
|
+
nativeCurrency: "ETH"
|
|
191
|
+
},
|
|
192
|
+
[CHAIN_IDS.AVALANCHE]: {
|
|
193
|
+
isEvm: true,
|
|
194
|
+
isTestnet: false,
|
|
195
|
+
explorerUrl: "https://snowtrace.io",
|
|
196
|
+
nativeCurrency: "AVAX"
|
|
197
|
+
},
|
|
198
|
+
[CHAIN_IDS.AVALANCHE_FUJI]: {
|
|
199
|
+
isEvm: true,
|
|
200
|
+
isTestnet: true,
|
|
201
|
+
explorerUrl: "https://testnet.snowtrace.io",
|
|
202
|
+
nativeCurrency: "AVAX"
|
|
203
|
+
},
|
|
204
|
+
[CHAIN_IDS.BASE]: {
|
|
205
|
+
isEvm: true,
|
|
206
|
+
isTestnet: false,
|
|
207
|
+
explorerUrl: "https://basescan.org",
|
|
208
|
+
nativeCurrency: "ETH"
|
|
209
|
+
},
|
|
210
|
+
[CHAIN_IDS.POLYGON_AMOY]: {
|
|
211
|
+
isEvm: true,
|
|
212
|
+
isTestnet: true,
|
|
213
|
+
explorerUrl: "https://amoy.polygonscan.com",
|
|
214
|
+
nativeCurrency: "MATIC"
|
|
215
|
+
},
|
|
216
|
+
[CHAIN_IDS.ARBITRUM_SEPOLIA]: {
|
|
217
|
+
isEvm: true,
|
|
218
|
+
isTestnet: true,
|
|
219
|
+
explorerUrl: "https://sepolia.arbiscan.io",
|
|
220
|
+
nativeCurrency: "ETH"
|
|
221
|
+
},
|
|
222
|
+
[CHAIN_IDS.BASE_SEPOLIA]: {
|
|
223
|
+
isEvm: true,
|
|
224
|
+
isTestnet: true,
|
|
225
|
+
explorerUrl: "https://sepolia.basescan.org",
|
|
226
|
+
nativeCurrency: "ETH"
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
var TOKEN_DECIMALS = {
|
|
230
|
+
DEFAULT: 18,
|
|
231
|
+
USDC: 6,
|
|
232
|
+
USDT: 6
|
|
233
|
+
};
|
|
234
|
+
var TOKEN_ADDRESSES = {
|
|
235
|
+
USDC: {
|
|
236
|
+
[CHAIN_IDS.ETHEREUM]: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
237
|
+
[CHAIN_IDS.POLYGON]: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
|
238
|
+
[CHAIN_IDS.ARBITRUM]: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
|
|
239
|
+
[CHAIN_IDS.BASE]: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
var RISK_PARAMETERS = {
|
|
243
|
+
REAL_ESTATE: { maxLTV: 0.7, liquidationThreshold: 0.8, interestBase: 0.12 },
|
|
244
|
+
CREDIT: { maxLTV: 0.6, liquidationThreshold: 0.75, interestBase: 0.15 },
|
|
245
|
+
COMMODITY: { maxLTV: 0.5, liquidationThreshold: 0.65, interestBase: 0.18 },
|
|
246
|
+
EQUITY: { maxLTV: 0.5, liquidationThreshold: 0.65, interestBase: 0.16 }
|
|
247
|
+
};
|
|
248
|
+
var KYC_STATUS_LABELS = {
|
|
249
|
+
PENDING: "Pendente",
|
|
250
|
+
IN_REVIEW: "Em an\xE1lise",
|
|
251
|
+
VERIFIED: "Verificado",
|
|
252
|
+
REJECTED: "Rejeitado",
|
|
253
|
+
EXPIRED: "Expirado"
|
|
254
|
+
};
|
|
255
|
+
var ACCREDITATION_LABELS = {
|
|
256
|
+
RETAIL: "Varejo",
|
|
257
|
+
QUALIFIED: "Qualificado",
|
|
258
|
+
PROFESSIONAL: "Profissional"
|
|
259
|
+
};
|
|
260
|
+
var ASSET_TYPE_LABELS = {
|
|
261
|
+
REAL_ESTATE: "Imobili\xE1rio",
|
|
262
|
+
CREDIT: "Cr\xE9dito",
|
|
263
|
+
COMMODITY: "Commodity",
|
|
264
|
+
EQUITY: "Equity"
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
// src/helpers.ts
|
|
268
|
+
function sleep(ms) {
|
|
269
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
270
|
+
}
|
|
271
|
+
async function retry(fn, options = {}) {
|
|
272
|
+
const { maxRetries = 3, initialDelay = 1e3, maxDelay = 1e4, backoffFactor = 2 } = options;
|
|
273
|
+
let lastError;
|
|
274
|
+
let delay = initialDelay;
|
|
275
|
+
for (let i = 0; i <= maxRetries; i++) {
|
|
276
|
+
try {
|
|
277
|
+
return await fn();
|
|
278
|
+
} catch (error) {
|
|
279
|
+
lastError = error;
|
|
280
|
+
if (i < maxRetries) {
|
|
281
|
+
await sleep(delay);
|
|
282
|
+
delay = Math.min(delay * backoffFactor, maxDelay);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
throw lastError;
|
|
287
|
+
}
|
|
288
|
+
function isDefined(value) {
|
|
289
|
+
return value !== null && value !== void 0;
|
|
290
|
+
}
|
|
291
|
+
function debounce(fn, delay) {
|
|
292
|
+
let timeoutId;
|
|
293
|
+
return (...args) => {
|
|
294
|
+
clearTimeout(timeoutId);
|
|
295
|
+
timeoutId = setTimeout(() => fn(...args), delay);
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
function throttle(fn, limit) {
|
|
299
|
+
let inThrottle = false;
|
|
300
|
+
return (...args) => {
|
|
301
|
+
if (!inThrottle) {
|
|
302
|
+
fn(...args);
|
|
303
|
+
inThrottle = true;
|
|
304
|
+
setTimeout(() => inThrottle = false, limit);
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function parseBigInt(value) {
|
|
309
|
+
if (typeof value === "bigint") return value;
|
|
310
|
+
if (typeof value === "number") return BigInt(Math.floor(value));
|
|
311
|
+
return BigInt(value);
|
|
312
|
+
}
|
|
313
|
+
function percentageChange(oldValue, newValue) {
|
|
314
|
+
if (oldValue === 0) return newValue > 0 ? 100 : 0;
|
|
315
|
+
return (newValue - oldValue) / oldValue * 100;
|
|
316
|
+
}
|
|
317
|
+
function chunk(array, size) {
|
|
318
|
+
const result = [];
|
|
319
|
+
for (let i = 0; i < array.length; i += size) {
|
|
320
|
+
result.push(array.slice(i, i + size));
|
|
321
|
+
}
|
|
322
|
+
return result;
|
|
323
|
+
}
|
|
324
|
+
function generateId() {
|
|
325
|
+
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
326
|
+
}
|
|
327
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
328
|
+
0 && (module.exports = {
|
|
329
|
+
ACCREDITATION_LABELS,
|
|
330
|
+
ASSET_TYPE_LABELS,
|
|
331
|
+
CHAIN_IDS,
|
|
332
|
+
CHAIN_METADATA,
|
|
333
|
+
CHAIN_NAMES,
|
|
334
|
+
KYC_STATUS_LABELS,
|
|
335
|
+
RISK_PARAMETERS,
|
|
336
|
+
TOKEN_ADDRESSES,
|
|
337
|
+
TOKEN_DECIMALS,
|
|
338
|
+
addressSchema,
|
|
339
|
+
bigIntStringSchema,
|
|
340
|
+
chunk,
|
|
341
|
+
cn,
|
|
342
|
+
cnpjSchema,
|
|
343
|
+
countryCodeSchema,
|
|
344
|
+
cpfSchema,
|
|
345
|
+
debounce,
|
|
346
|
+
emailSchema,
|
|
347
|
+
formatAPY,
|
|
348
|
+
formatAddress,
|
|
349
|
+
formatCompactNumber,
|
|
350
|
+
formatCurrency,
|
|
351
|
+
formatPercentage,
|
|
352
|
+
formatRelativeTime,
|
|
353
|
+
formatTokenAmount,
|
|
354
|
+
generateId,
|
|
355
|
+
isDefined,
|
|
356
|
+
paginationSchema,
|
|
357
|
+
parseBigInt,
|
|
358
|
+
percentageChange,
|
|
359
|
+
positiveNumberSchema,
|
|
360
|
+
retry,
|
|
361
|
+
sleep,
|
|
362
|
+
throttle,
|
|
363
|
+
txHashSchema,
|
|
364
|
+
uuidSchema
|
|
365
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
// src/cn.ts
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import { twMerge } from "tailwind-merge";
|
|
4
|
+
function cn(...inputs) {
|
|
5
|
+
return twMerge(clsx(inputs));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// src/format.ts
|
|
9
|
+
function formatCurrency(value, currency = "USD", locale = "en-US") {
|
|
10
|
+
return new Intl.NumberFormat(locale, {
|
|
11
|
+
style: "currency",
|
|
12
|
+
currency,
|
|
13
|
+
minimumFractionDigits: 2,
|
|
14
|
+
maximumFractionDigits: 2
|
|
15
|
+
}).format(value);
|
|
16
|
+
}
|
|
17
|
+
function formatPercentage(value, decimals = 2) {
|
|
18
|
+
return `${(value * 100).toFixed(decimals)}%`;
|
|
19
|
+
}
|
|
20
|
+
function formatTokenAmount(amount, decimals, displayDecimals = 4) {
|
|
21
|
+
const divisor = BigInt(10 ** decimals);
|
|
22
|
+
const integerPart = amount / divisor;
|
|
23
|
+
const fractionalPart = amount % divisor;
|
|
24
|
+
const fractionalStr = fractionalPart.toString().padStart(decimals, "0");
|
|
25
|
+
const displayFractional = fractionalStr.slice(0, displayDecimals);
|
|
26
|
+
return `${integerPart}.${displayFractional}`;
|
|
27
|
+
}
|
|
28
|
+
function formatAddress(address, chars = 4) {
|
|
29
|
+
if (address.length < chars * 2 + 2) return address;
|
|
30
|
+
return `${address.slice(0, chars + 2)}...${address.slice(-chars)}`;
|
|
31
|
+
}
|
|
32
|
+
function formatRelativeTime(date, locale = "en-US") {
|
|
33
|
+
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
|
|
34
|
+
const diff = date.getTime() - Date.now();
|
|
35
|
+
const diffDays = Math.round(diff / (1e3 * 60 * 60 * 24));
|
|
36
|
+
if (Math.abs(diffDays) < 1) {
|
|
37
|
+
const diffHours = Math.round(diff / (1e3 * 60 * 60));
|
|
38
|
+
if (Math.abs(diffHours) < 1) {
|
|
39
|
+
const diffMinutes = Math.round(diff / (1e3 * 60));
|
|
40
|
+
return rtf.format(diffMinutes, "minute");
|
|
41
|
+
}
|
|
42
|
+
return rtf.format(diffHours, "hour");
|
|
43
|
+
}
|
|
44
|
+
if (Math.abs(diffDays) < 30) {
|
|
45
|
+
return rtf.format(diffDays, "day");
|
|
46
|
+
}
|
|
47
|
+
if (Math.abs(diffDays) < 365) {
|
|
48
|
+
return rtf.format(Math.round(diffDays / 30), "month");
|
|
49
|
+
}
|
|
50
|
+
return rtf.format(Math.round(diffDays / 365), "year");
|
|
51
|
+
}
|
|
52
|
+
function formatAPY(apy) {
|
|
53
|
+
return `${(apy * 100).toFixed(2)}% APY`;
|
|
54
|
+
}
|
|
55
|
+
function formatCompactNumber(value, locale = "en-US") {
|
|
56
|
+
return new Intl.NumberFormat(locale, {
|
|
57
|
+
notation: "compact",
|
|
58
|
+
compactDisplay: "short",
|
|
59
|
+
maximumFractionDigits: 2
|
|
60
|
+
}).format(value);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/validation.ts
|
|
64
|
+
import { z } from "zod";
|
|
65
|
+
var addressSchema = z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid Ethereum address");
|
|
66
|
+
var txHashSchema = z.string().regex(/^0x[a-fA-F0-9]{64}$/, "Invalid transaction hash");
|
|
67
|
+
var uuidSchema = z.string().uuid();
|
|
68
|
+
var emailSchema = z.string().email();
|
|
69
|
+
var cpfSchema = z.string().regex(/^\d{3}\.\d{3}\.\d{3}-\d{2}$/, "Invalid CPF format");
|
|
70
|
+
var cnpjSchema = z.string().regex(/^\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2}$/, "Invalid CNPJ format");
|
|
71
|
+
var positiveNumberSchema = z.number().positive();
|
|
72
|
+
var bigIntStringSchema = z.string().regex(/^\d+$/, "Must be a valid integer string");
|
|
73
|
+
var countryCodeSchema = z.string().length(2).toUpperCase();
|
|
74
|
+
var paginationSchema = z.object({
|
|
75
|
+
page: z.number().int().positive().default(1),
|
|
76
|
+
perPage: z.number().int().positive().max(100).default(20),
|
|
77
|
+
sortBy: z.string().optional(),
|
|
78
|
+
sortOrder: z.enum(["asc", "desc"]).default("desc")
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// src/constants.ts
|
|
82
|
+
var CHAIN_IDS = {
|
|
83
|
+
ETHEREUM: 1,
|
|
84
|
+
ETHEREUM_SEPOLIA: 11155111,
|
|
85
|
+
POLYGON: 137,
|
|
86
|
+
ARBITRUM: 42161,
|
|
87
|
+
AVALANCHE: 43114,
|
|
88
|
+
AVALANCHE_FUJI: 43113,
|
|
89
|
+
BASE: 8453,
|
|
90
|
+
POLYGON_AMOY: 80002,
|
|
91
|
+
ARBITRUM_SEPOLIA: 421614,
|
|
92
|
+
BASE_SEPOLIA: 84532
|
|
93
|
+
};
|
|
94
|
+
var CHAIN_NAMES = {
|
|
95
|
+
[CHAIN_IDS.ETHEREUM]: "Ethereum",
|
|
96
|
+
[CHAIN_IDS.ETHEREUM_SEPOLIA]: "Ethereum Sepolia",
|
|
97
|
+
[CHAIN_IDS.POLYGON]: "Polygon",
|
|
98
|
+
[CHAIN_IDS.ARBITRUM]: "Arbitrum",
|
|
99
|
+
[CHAIN_IDS.AVALANCHE]: "Avalanche",
|
|
100
|
+
[CHAIN_IDS.AVALANCHE_FUJI]: "Avalanche Fuji",
|
|
101
|
+
[CHAIN_IDS.BASE]: "Base",
|
|
102
|
+
[CHAIN_IDS.POLYGON_AMOY]: "Polygon Amoy",
|
|
103
|
+
[CHAIN_IDS.ARBITRUM_SEPOLIA]: "Arbitrum Sepolia",
|
|
104
|
+
[CHAIN_IDS.BASE_SEPOLIA]: "Base Sepolia"
|
|
105
|
+
};
|
|
106
|
+
var CHAIN_METADATA = {
|
|
107
|
+
[CHAIN_IDS.ETHEREUM]: {
|
|
108
|
+
isEvm: true,
|
|
109
|
+
isTestnet: false,
|
|
110
|
+
explorerUrl: "https://etherscan.io",
|
|
111
|
+
nativeCurrency: "ETH"
|
|
112
|
+
},
|
|
113
|
+
[CHAIN_IDS.ETHEREUM_SEPOLIA]: {
|
|
114
|
+
isEvm: true,
|
|
115
|
+
isTestnet: true,
|
|
116
|
+
explorerUrl: "https://sepolia.etherscan.io",
|
|
117
|
+
nativeCurrency: "ETH"
|
|
118
|
+
},
|
|
119
|
+
[CHAIN_IDS.POLYGON]: {
|
|
120
|
+
isEvm: true,
|
|
121
|
+
isTestnet: false,
|
|
122
|
+
explorerUrl: "https://polygonscan.com",
|
|
123
|
+
nativeCurrency: "MATIC"
|
|
124
|
+
},
|
|
125
|
+
[CHAIN_IDS.ARBITRUM]: {
|
|
126
|
+
isEvm: true,
|
|
127
|
+
isTestnet: false,
|
|
128
|
+
explorerUrl: "https://arbiscan.io",
|
|
129
|
+
nativeCurrency: "ETH"
|
|
130
|
+
},
|
|
131
|
+
[CHAIN_IDS.AVALANCHE]: {
|
|
132
|
+
isEvm: true,
|
|
133
|
+
isTestnet: false,
|
|
134
|
+
explorerUrl: "https://snowtrace.io",
|
|
135
|
+
nativeCurrency: "AVAX"
|
|
136
|
+
},
|
|
137
|
+
[CHAIN_IDS.AVALANCHE_FUJI]: {
|
|
138
|
+
isEvm: true,
|
|
139
|
+
isTestnet: true,
|
|
140
|
+
explorerUrl: "https://testnet.snowtrace.io",
|
|
141
|
+
nativeCurrency: "AVAX"
|
|
142
|
+
},
|
|
143
|
+
[CHAIN_IDS.BASE]: {
|
|
144
|
+
isEvm: true,
|
|
145
|
+
isTestnet: false,
|
|
146
|
+
explorerUrl: "https://basescan.org",
|
|
147
|
+
nativeCurrency: "ETH"
|
|
148
|
+
},
|
|
149
|
+
[CHAIN_IDS.POLYGON_AMOY]: {
|
|
150
|
+
isEvm: true,
|
|
151
|
+
isTestnet: true,
|
|
152
|
+
explorerUrl: "https://amoy.polygonscan.com",
|
|
153
|
+
nativeCurrency: "MATIC"
|
|
154
|
+
},
|
|
155
|
+
[CHAIN_IDS.ARBITRUM_SEPOLIA]: {
|
|
156
|
+
isEvm: true,
|
|
157
|
+
isTestnet: true,
|
|
158
|
+
explorerUrl: "https://sepolia.arbiscan.io",
|
|
159
|
+
nativeCurrency: "ETH"
|
|
160
|
+
},
|
|
161
|
+
[CHAIN_IDS.BASE_SEPOLIA]: {
|
|
162
|
+
isEvm: true,
|
|
163
|
+
isTestnet: true,
|
|
164
|
+
explorerUrl: "https://sepolia.basescan.org",
|
|
165
|
+
nativeCurrency: "ETH"
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
var TOKEN_DECIMALS = {
|
|
169
|
+
DEFAULT: 18,
|
|
170
|
+
USDC: 6,
|
|
171
|
+
USDT: 6
|
|
172
|
+
};
|
|
173
|
+
var TOKEN_ADDRESSES = {
|
|
174
|
+
USDC: {
|
|
175
|
+
[CHAIN_IDS.ETHEREUM]: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
176
|
+
[CHAIN_IDS.POLYGON]: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
|
|
177
|
+
[CHAIN_IDS.ARBITRUM]: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
|
|
178
|
+
[CHAIN_IDS.BASE]: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
var RISK_PARAMETERS = {
|
|
182
|
+
REAL_ESTATE: { maxLTV: 0.7, liquidationThreshold: 0.8, interestBase: 0.12 },
|
|
183
|
+
CREDIT: { maxLTV: 0.6, liquidationThreshold: 0.75, interestBase: 0.15 },
|
|
184
|
+
COMMODITY: { maxLTV: 0.5, liquidationThreshold: 0.65, interestBase: 0.18 },
|
|
185
|
+
EQUITY: { maxLTV: 0.5, liquidationThreshold: 0.65, interestBase: 0.16 }
|
|
186
|
+
};
|
|
187
|
+
var KYC_STATUS_LABELS = {
|
|
188
|
+
PENDING: "Pendente",
|
|
189
|
+
IN_REVIEW: "Em an\xE1lise",
|
|
190
|
+
VERIFIED: "Verificado",
|
|
191
|
+
REJECTED: "Rejeitado",
|
|
192
|
+
EXPIRED: "Expirado"
|
|
193
|
+
};
|
|
194
|
+
var ACCREDITATION_LABELS = {
|
|
195
|
+
RETAIL: "Varejo",
|
|
196
|
+
QUALIFIED: "Qualificado",
|
|
197
|
+
PROFESSIONAL: "Profissional"
|
|
198
|
+
};
|
|
199
|
+
var ASSET_TYPE_LABELS = {
|
|
200
|
+
REAL_ESTATE: "Imobili\xE1rio",
|
|
201
|
+
CREDIT: "Cr\xE9dito",
|
|
202
|
+
COMMODITY: "Commodity",
|
|
203
|
+
EQUITY: "Equity"
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
// src/helpers.ts
|
|
207
|
+
function sleep(ms) {
|
|
208
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
209
|
+
}
|
|
210
|
+
async function retry(fn, options = {}) {
|
|
211
|
+
const { maxRetries = 3, initialDelay = 1e3, maxDelay = 1e4, backoffFactor = 2 } = options;
|
|
212
|
+
let lastError;
|
|
213
|
+
let delay = initialDelay;
|
|
214
|
+
for (let i = 0; i <= maxRetries; i++) {
|
|
215
|
+
try {
|
|
216
|
+
return await fn();
|
|
217
|
+
} catch (error) {
|
|
218
|
+
lastError = error;
|
|
219
|
+
if (i < maxRetries) {
|
|
220
|
+
await sleep(delay);
|
|
221
|
+
delay = Math.min(delay * backoffFactor, maxDelay);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
throw lastError;
|
|
226
|
+
}
|
|
227
|
+
function isDefined(value) {
|
|
228
|
+
return value !== null && value !== void 0;
|
|
229
|
+
}
|
|
230
|
+
function debounce(fn, delay) {
|
|
231
|
+
let timeoutId;
|
|
232
|
+
return (...args) => {
|
|
233
|
+
clearTimeout(timeoutId);
|
|
234
|
+
timeoutId = setTimeout(() => fn(...args), delay);
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
function throttle(fn, limit) {
|
|
238
|
+
let inThrottle = false;
|
|
239
|
+
return (...args) => {
|
|
240
|
+
if (!inThrottle) {
|
|
241
|
+
fn(...args);
|
|
242
|
+
inThrottle = true;
|
|
243
|
+
setTimeout(() => inThrottle = false, limit);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
function parseBigInt(value) {
|
|
248
|
+
if (typeof value === "bigint") return value;
|
|
249
|
+
if (typeof value === "number") return BigInt(Math.floor(value));
|
|
250
|
+
return BigInt(value);
|
|
251
|
+
}
|
|
252
|
+
function percentageChange(oldValue, newValue) {
|
|
253
|
+
if (oldValue === 0) return newValue > 0 ? 100 : 0;
|
|
254
|
+
return (newValue - oldValue) / oldValue * 100;
|
|
255
|
+
}
|
|
256
|
+
function chunk(array, size) {
|
|
257
|
+
const result = [];
|
|
258
|
+
for (let i = 0; i < array.length; i += size) {
|
|
259
|
+
result.push(array.slice(i, i + size));
|
|
260
|
+
}
|
|
261
|
+
return result;
|
|
262
|
+
}
|
|
263
|
+
function generateId() {
|
|
264
|
+
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
265
|
+
}
|
|
266
|
+
export {
|
|
267
|
+
ACCREDITATION_LABELS,
|
|
268
|
+
ASSET_TYPE_LABELS,
|
|
269
|
+
CHAIN_IDS,
|
|
270
|
+
CHAIN_METADATA,
|
|
271
|
+
CHAIN_NAMES,
|
|
272
|
+
KYC_STATUS_LABELS,
|
|
273
|
+
RISK_PARAMETERS,
|
|
274
|
+
TOKEN_ADDRESSES,
|
|
275
|
+
TOKEN_DECIMALS,
|
|
276
|
+
addressSchema,
|
|
277
|
+
bigIntStringSchema,
|
|
278
|
+
chunk,
|
|
279
|
+
cn,
|
|
280
|
+
cnpjSchema,
|
|
281
|
+
countryCodeSchema,
|
|
282
|
+
cpfSchema,
|
|
283
|
+
debounce,
|
|
284
|
+
emailSchema,
|
|
285
|
+
formatAPY,
|
|
286
|
+
formatAddress,
|
|
287
|
+
formatCompactNumber,
|
|
288
|
+
formatCurrency,
|
|
289
|
+
formatPercentage,
|
|
290
|
+
formatRelativeTime,
|
|
291
|
+
formatTokenAmount,
|
|
292
|
+
generateId,
|
|
293
|
+
isDefined,
|
|
294
|
+
paginationSchema,
|
|
295
|
+
parseBigInt,
|
|
296
|
+
percentageChange,
|
|
297
|
+
positiveNumberSchema,
|
|
298
|
+
retry,
|
|
299
|
+
sleep,
|
|
300
|
+
throttle,
|
|
301
|
+
txHashSchema,
|
|
302
|
+
uuidSchema
|
|
303
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@straton/utils",
|
|
3
|
+
"version": "1.1.2",
|
|
4
|
+
"description": "Shared utilities for the Straton RWAFi platform",
|
|
5
|
+
"private": false,
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/Straton-Finance/Straton-Packages.git",
|
|
12
|
+
"directory": "packages/utils"
|
|
13
|
+
},
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.mjs",
|
|
20
|
+
"require": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./*": {
|
|
23
|
+
"types": "./dist/*.d.ts",
|
|
24
|
+
"import": "./dist/*.mjs",
|
|
25
|
+
"require": "./dist/*.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist"
|
|
30
|
+
],
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"clsx": "^2.1.1",
|
|
33
|
+
"tailwind-merge": "^2.6.0",
|
|
34
|
+
"zod": "^3.24.1"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"tsup": "^8.3.5",
|
|
38
|
+
"typescript": "^5.7.2",
|
|
39
|
+
"vitest": "^2.1.8"
|
|
40
|
+
},
|
|
41
|
+
"module": "./dist/index.mjs",
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsup src/index.ts --format esm,cjs --dts",
|
|
44
|
+
"typecheck": "tsc --noEmit",
|
|
45
|
+
"test": "vitest run --passWithNoTests",
|
|
46
|
+
"clean": "rm -rf dist"
|
|
47
|
+
}
|
|
48
|
+
}
|