@hivemindhq/core 0.4.0 → 0.5.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/README.md +16 -16
- package/dist/{chunk-2RGM3KJL.js → chunk-K2544PJ5.js} +42 -20
- package/dist/chunk-K2544PJ5.js.map +1 -0
- package/dist/{chunk-P5E2XNDI.js → chunk-K4XDMY2V.js} +3 -3
- package/dist/{chunk-P5E2XNDI.js.map → chunk-K4XDMY2V.js.map} +1 -1
- package/dist/{chunk-ERZSVDIB.js → chunk-RW4JXOAM.js} +11 -3
- package/dist/chunk-RW4JXOAM.js.map +1 -0
- package/dist/chunk-VU3OPG32.js +907 -0
- package/dist/chunk-VU3OPG32.js.map +1 -0
- package/dist/components/index.d.ts +28 -3
- package/dist/components/index.js +2 -2
- package/dist/components/ui/index.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -6
- package/dist/utils/index.d.ts +312 -6
- package/dist/utils/index.js +2 -2
- package/package.json +15 -11
- package/src/components/AtomIcon.tsx +21 -0
- package/src/components/CryptoAmount.tsx +447 -0
- package/src/components/ErrorBanner.tsx +35 -0
- package/src/components/IpfsImage.tsx +21 -0
- package/src/components/LoadingDots.tsx +55 -0
- package/src/components/TripleAreaChart.tsx +108 -0
- package/src/components/TriplePositionsTornadoMinGraph.tsx +71 -0
- package/src/components/UnknownImage.tsx +55 -0
- package/src/components/index.ts +24 -0
- package/src/components/ui/alert.tsx +59 -0
- package/src/components/ui/avatar.tsx +47 -0
- package/src/components/ui/badge.tsx +35 -0
- package/src/components/ui/breadcrumb.tsx +108 -0
- package/src/components/ui/button.tsx +56 -0
- package/src/components/ui/card.tsx +75 -0
- package/src/components/ui/carousel.tsx +239 -0
- package/src/components/ui/chart.tsx +350 -0
- package/src/components/ui/checkbox.tsx +28 -0
- package/src/components/ui/collapsible.tsx +10 -0
- package/src/components/ui/command.tsx +177 -0
- package/src/components/ui/dialog.tsx +119 -0
- package/src/components/ui/dropdown-menu.tsx +202 -0
- package/src/components/ui/form.tsx +175 -0
- package/src/components/ui/index.ts +183 -0
- package/src/components/ui/input.tsx +21 -0
- package/src/components/ui/label.tsx +25 -0
- package/src/components/ui/loader.tsx +20 -0
- package/src/components/ui/pagination.tsx +104 -0
- package/src/components/ui/popover.tsx +45 -0
- package/src/components/ui/progress.tsx +25 -0
- package/src/components/ui/radio-group.tsx +42 -0
- package/src/components/ui/scroll-area.tsx +45 -0
- package/src/components/ui/select.tsx +178 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/sheet.tsx +139 -0
- package/src/components/ui/sidebar.tsx +723 -0
- package/src/components/ui/skeleton.tsx +15 -0
- package/src/components/ui/sonner.tsx +27 -0
- package/src/components/ui/spinner.tsx +67 -0
- package/src/components/ui/switch.tsx +26 -0
- package/src/components/ui/table.tsx +113 -0
- package/src/components/ui/tabs.tsx +63 -0
- package/src/components/ui/textarea.tsx +21 -0
- package/src/components/ui/toast.tsx +146 -0
- package/src/components/ui/toaster.tsx +33 -0
- package/src/components/ui/toggle-group.tsx +58 -0
- package/src/components/ui/toggle.tsx +44 -0
- package/src/components/ui/tooltip.tsx +61 -0
- package/src/hooks/index.ts +7 -0
- package/src/hooks/use-mobile.ts +20 -0
- package/src/hooks/use-toast.ts +190 -0
- package/src/index.ts +25 -0
- package/src/types/index.ts +17 -0
- package/src/utils/atom-label-detection.ts +689 -0
- package/src/utils/atom.ts +279 -0
- package/src/utils/cn.ts +18 -0
- package/src/utils/formatting.ts +624 -0
- package/src/utils/index.ts +11 -0
- package/src/utils/multivault-errors.ts +581 -0
- package/src/utils/search/formatting.tsx +95 -0
- package/src/utils/search/index.ts +28 -0
- package/src/utils/search/ranking.ts +203 -0
- package/src/utils/search/types.ts +114 -0
- package/tailwind.config.js +3 -3
- package/dist/chunk-2RGM3KJL.js.map +0 -1
- package/dist/chunk-ERZSVDIB.js.map +0 -1
- package/dist/chunk-H4RMZQ2Z.js +0 -213
- package/dist/chunk-H4RMZQ2Z.js.map +0 -1
|
@@ -0,0 +1,581 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MultiVault Contract Error Mappings
|
|
3
|
+
*
|
|
4
|
+
* Maps Solidity error names from the MultiVault contract to user-friendly messages.
|
|
5
|
+
* These errors are thrown by the Intuition Protocol's MultiVault contract.
|
|
6
|
+
*
|
|
7
|
+
* @see intuition-contracts-v2/src/protocol/MultiVault.sol
|
|
8
|
+
* @see intuition-contracts-v2/src/protocol/MultiVaultCore.sol
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export interface MultiVaultErrorInfo {
|
|
12
|
+
/** The Solidity error name as it appears in the contract */
|
|
13
|
+
errorName: string
|
|
14
|
+
/** User-friendly message to display in the UI */
|
|
15
|
+
userMessage: string
|
|
16
|
+
/** More detailed explanation for tooltips or error details */
|
|
17
|
+
description: string
|
|
18
|
+
/** Category for grouping/filtering errors */
|
|
19
|
+
category:
|
|
20
|
+
| 'atom'
|
|
21
|
+
| 'triple'
|
|
22
|
+
| 'deposit'
|
|
23
|
+
| 'redeem'
|
|
24
|
+
| 'balance'
|
|
25
|
+
| 'limits'
|
|
26
|
+
| 'batch'
|
|
27
|
+
| 'approval'
|
|
28
|
+
| 'existence'
|
|
29
|
+
| 'epoch'
|
|
30
|
+
| 'wallet'
|
|
31
|
+
| 'internal'
|
|
32
|
+
/** Whether this error is commonly encountered by users */
|
|
33
|
+
isCommon: boolean
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Result of parsing a MultiVault error
|
|
38
|
+
*/
|
|
39
|
+
export interface ParsedMultiVaultError {
|
|
40
|
+
/** User-friendly message to display in the UI */
|
|
41
|
+
userMessage: string
|
|
42
|
+
/** More detailed explanation for tooltips or error details */
|
|
43
|
+
description: string
|
|
44
|
+
/** Whether this error is commonly encountered by users */
|
|
45
|
+
isCommon: boolean
|
|
46
|
+
/** The original error name if matched, undefined if fallback */
|
|
47
|
+
errorName?: string
|
|
48
|
+
/** The error category if matched */
|
|
49
|
+
category?: MultiVaultErrorInfo['category']
|
|
50
|
+
/** Whether this was a known MultiVault error */
|
|
51
|
+
isMultiVaultError: boolean
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Complete mapping of MultiVault contract errors to user-friendly messages.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const errorInfo = MULTIVAULT_ERRORS['MultiVault_AtomExists']
|
|
60
|
+
* toast.error(errorInfo.userMessage)
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export const MULTIVAULT_ERRORS: Record<string, MultiVaultErrorInfo> = {
|
|
64
|
+
// ============================================
|
|
65
|
+
// ATOM CREATION ERRORS
|
|
66
|
+
// ============================================
|
|
67
|
+
|
|
68
|
+
MultiVault_AtomExists: {
|
|
69
|
+
errorName: 'MultiVault_AtomExists',
|
|
70
|
+
userMessage: 'This entity already exists on-chain',
|
|
71
|
+
description:
|
|
72
|
+
'An atom with this exact data has already been created. You can stake on the existing atom instead.',
|
|
73
|
+
category: 'atom',
|
|
74
|
+
isCommon: true,
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
MultiVault_AtomDoesNotExist: {
|
|
78
|
+
errorName: 'MultiVault_AtomDoesNotExist',
|
|
79
|
+
userMessage: "This entity hasn't been created yet",
|
|
80
|
+
description:
|
|
81
|
+
'The atom you are trying to reference does not exist on-chain. It may need to be created first.',
|
|
82
|
+
category: 'atom',
|
|
83
|
+
isCommon: true,
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
MultiVault_NoAtomDataProvided: {
|
|
87
|
+
errorName: 'MultiVault_NoAtomDataProvided',
|
|
88
|
+
userMessage: 'No data provided for entity creation',
|
|
89
|
+
description:
|
|
90
|
+
'Atom creation requires data (URL, IPFS URI, or other identifier) to be provided.',
|
|
91
|
+
category: 'atom',
|
|
92
|
+
isCommon: false,
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
MultiVault_AtomDataTooLong: {
|
|
96
|
+
errorName: 'MultiVault_AtomDataTooLong',
|
|
97
|
+
userMessage: 'Entity data is too large',
|
|
98
|
+
description:
|
|
99
|
+
'The provided atom data exceeds the maximum allowed length. Consider using an IPFS URI instead.',
|
|
100
|
+
category: 'atom',
|
|
101
|
+
isCommon: false,
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
// ============================================
|
|
105
|
+
// TRIPLE CREATION ERRORS
|
|
106
|
+
// ============================================
|
|
107
|
+
|
|
108
|
+
MultiVault_TripleExists: {
|
|
109
|
+
errorName: 'MultiVault_TripleExists',
|
|
110
|
+
userMessage: 'This claim already exists',
|
|
111
|
+
description:
|
|
112
|
+
'A triple with this exact subject-predicate-object combination has already been created. You can stake on the existing claim instead.',
|
|
113
|
+
category: 'triple',
|
|
114
|
+
isCommon: true,
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
MultiVault_TermNotTriple: {
|
|
118
|
+
errorName: 'MultiVault_TermNotTriple',
|
|
119
|
+
userMessage: 'This is not a claim',
|
|
120
|
+
description:
|
|
121
|
+
'The specified term ID refers to an atom, not a triple. Triple-specific operations cannot be performed on atoms.',
|
|
122
|
+
category: 'triple',
|
|
123
|
+
isCommon: false,
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
MultiVault_CannotDirectlyInitializeCounterTriple: {
|
|
127
|
+
errorName: 'MultiVault_CannotDirectlyInitializeCounterTriple',
|
|
128
|
+
userMessage: 'Cannot initialize counter position directly',
|
|
129
|
+
description:
|
|
130
|
+
'Counter-triple vaults are automatically created when the main triple is created. You cannot deposit directly into a counter vault that has not been initialized.',
|
|
131
|
+
category: 'triple',
|
|
132
|
+
isCommon: false,
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
// ============================================
|
|
136
|
+
// DEPOSIT/STAKING ERRORS
|
|
137
|
+
// ============================================
|
|
138
|
+
|
|
139
|
+
MultiVault_HasCounterStake: {
|
|
140
|
+
errorName: 'MultiVault_HasCounterStake',
|
|
141
|
+
userMessage: 'You already have an opposing position. Unstake first.',
|
|
142
|
+
description:
|
|
143
|
+
'You cannot stake on both sides of a claim simultaneously. Please remove your existing position before staking on the opposite side.',
|
|
144
|
+
category: 'deposit',
|
|
145
|
+
isCommon: true,
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
MultiVault_DepositBelowMinimumDeposit: {
|
|
149
|
+
errorName: 'MultiVault_DepositBelowMinimumDeposit',
|
|
150
|
+
userMessage: 'Deposit amount is below minimum',
|
|
151
|
+
description:
|
|
152
|
+
'The amount you are trying to deposit is less than the protocol minimum. Please increase your deposit amount.',
|
|
153
|
+
category: 'deposit',
|
|
154
|
+
isCommon: true,
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
MultiVault_DepositOrRedeemZeroShares: {
|
|
158
|
+
errorName: 'MultiVault_DepositOrRedeemZeroShares',
|
|
159
|
+
userMessage: 'Transaction would result in zero shares',
|
|
160
|
+
description:
|
|
161
|
+
'The deposit amount is too small to mint any shares, or you are trying to redeem zero shares.',
|
|
162
|
+
category: 'deposit',
|
|
163
|
+
isCommon: false,
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
MultiVault_DepositTooSmallToCoverMinShares: {
|
|
167
|
+
errorName: 'MultiVault_DepositTooSmallToCoverMinShares',
|
|
168
|
+
userMessage: 'Deposit too small to initialize vault',
|
|
169
|
+
description:
|
|
170
|
+
'When initializing a new vault on a non-default bonding curve, the deposit must cover the minimum share cost.',
|
|
171
|
+
category: 'deposit',
|
|
172
|
+
isCommon: false,
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
MultiVault_DefaultCurveMustBeInitializedViaCreatePaths: {
|
|
176
|
+
errorName: 'MultiVault_DefaultCurveMustBeInitializedViaCreatePaths',
|
|
177
|
+
userMessage: 'Vault must be created before depositing',
|
|
178
|
+
description:
|
|
179
|
+
'Default curve vaults must be initialized through createAtoms or createTriples, not through direct deposits.',
|
|
180
|
+
category: 'deposit',
|
|
181
|
+
isCommon: false,
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
MultiVault_SenderNotApproved: {
|
|
185
|
+
errorName: 'MultiVault_SenderNotApproved',
|
|
186
|
+
userMessage: 'Not authorized to deposit for this account',
|
|
187
|
+
description:
|
|
188
|
+
'You do not have approval to deposit on behalf of the specified receiver address.',
|
|
189
|
+
category: 'deposit',
|
|
190
|
+
isCommon: false,
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
MultiVault_SlippageExceeded: {
|
|
194
|
+
errorName: 'MultiVault_SlippageExceeded',
|
|
195
|
+
userMessage: 'Price changed. Try again with updated amount.',
|
|
196
|
+
description:
|
|
197
|
+
'The share price moved unfavorably between when you submitted and when the transaction executed. The actual shares received would be less than your minimum.',
|
|
198
|
+
category: 'deposit',
|
|
199
|
+
isCommon: true,
|
|
200
|
+
},
|
|
201
|
+
|
|
202
|
+
// ============================================
|
|
203
|
+
// REDEMPTION/UNSTAKING ERRORS
|
|
204
|
+
// ============================================
|
|
205
|
+
|
|
206
|
+
MultiVault_InsufficientSharesInVault: {
|
|
207
|
+
errorName: 'MultiVault_InsufficientSharesInVault',
|
|
208
|
+
userMessage: 'Insufficient shares to redeem',
|
|
209
|
+
description:
|
|
210
|
+
'You are trying to redeem more shares than you currently own in this vault.',
|
|
211
|
+
category: 'redeem',
|
|
212
|
+
isCommon: true,
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
MultiVault_InsufficientRemainingSharesInVault: {
|
|
216
|
+
errorName: 'MultiVault_InsufficientRemainingSharesInVault',
|
|
217
|
+
userMessage: 'Cannot redeem: would leave vault below minimum',
|
|
218
|
+
description:
|
|
219
|
+
'This redemption would leave the vault with fewer shares than the protocol minimum. You may need to redeem a smaller amount.',
|
|
220
|
+
category: 'redeem',
|
|
221
|
+
isCommon: false,
|
|
222
|
+
},
|
|
223
|
+
|
|
224
|
+
MultiVault_RedeemerNotApproved: {
|
|
225
|
+
errorName: 'MultiVault_RedeemerNotApproved',
|
|
226
|
+
userMessage: 'Not authorized to redeem for this account',
|
|
227
|
+
description:
|
|
228
|
+
'You do not have approval to redeem shares on behalf of the specified receiver address.',
|
|
229
|
+
category: 'redeem',
|
|
230
|
+
isCommon: false,
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
// ============================================
|
|
234
|
+
// BALANCE/ASSET ERRORS
|
|
235
|
+
// ============================================
|
|
236
|
+
|
|
237
|
+
MultiVault_InsufficientBalance: {
|
|
238
|
+
errorName: 'MultiVault_InsufficientBalance',
|
|
239
|
+
userMessage: 'Insufficient TRUST balance',
|
|
240
|
+
description:
|
|
241
|
+
'You do not have enough TRUST tokens to complete this transaction. Please add more funds to your wallet.',
|
|
242
|
+
category: 'balance',
|
|
243
|
+
isCommon: true,
|
|
244
|
+
},
|
|
245
|
+
|
|
246
|
+
MultiVault_InsufficientAssets: {
|
|
247
|
+
errorName: 'MultiVault_InsufficientAssets',
|
|
248
|
+
userMessage: 'Not enough funds for this operation',
|
|
249
|
+
description:
|
|
250
|
+
'The assets provided are less than the required cost for this operation (atom/triple creation cost + deposit).',
|
|
251
|
+
category: 'balance',
|
|
252
|
+
isCommon: true,
|
|
253
|
+
},
|
|
254
|
+
|
|
255
|
+
MultiVault_BurnFromZeroAddress: {
|
|
256
|
+
errorName: 'MultiVault_BurnFromZeroAddress',
|
|
257
|
+
userMessage: 'Transaction failed',
|
|
258
|
+
description:
|
|
259
|
+
'Internal error: attempted to burn shares from the zero address.',
|
|
260
|
+
category: 'internal',
|
|
261
|
+
isCommon: false,
|
|
262
|
+
},
|
|
263
|
+
|
|
264
|
+
MultiVault_BurnInsufficientBalance: {
|
|
265
|
+
errorName: 'MultiVault_BurnInsufficientBalance',
|
|
266
|
+
userMessage: 'Transaction failed',
|
|
267
|
+
description:
|
|
268
|
+
'Internal error: attempted to burn more shares than the account holds.',
|
|
269
|
+
category: 'internal',
|
|
270
|
+
isCommon: false,
|
|
271
|
+
},
|
|
272
|
+
|
|
273
|
+
// ============================================
|
|
274
|
+
// LIMIT/BOUNDS ERRORS
|
|
275
|
+
// ============================================
|
|
276
|
+
|
|
277
|
+
MultiVault_ActionExceedsMaxAssets: {
|
|
278
|
+
errorName: 'MultiVault_ActionExceedsMaxAssets',
|
|
279
|
+
userMessage: 'Vault is at maximum capacity',
|
|
280
|
+
description:
|
|
281
|
+
'This deposit would cause the vault to exceed its maximum allowed assets. The vault cannot accept more deposits.',
|
|
282
|
+
category: 'limits',
|
|
283
|
+
isCommon: false,
|
|
284
|
+
},
|
|
285
|
+
|
|
286
|
+
MultiVault_ActionExceedsMaxShares: {
|
|
287
|
+
errorName: 'MultiVault_ActionExceedsMaxShares',
|
|
288
|
+
userMessage: 'Vault is at maximum capacity',
|
|
289
|
+
description:
|
|
290
|
+
'This deposit would cause the vault to exceed its maximum allowed shares. The vault cannot accept more deposits.',
|
|
291
|
+
category: 'limits',
|
|
292
|
+
isCommon: false,
|
|
293
|
+
},
|
|
294
|
+
|
|
295
|
+
// ============================================
|
|
296
|
+
// ARRAY/BATCH ERRORS
|
|
297
|
+
// ============================================
|
|
298
|
+
|
|
299
|
+
MultiVault_ArraysNotSameLength: {
|
|
300
|
+
errorName: 'MultiVault_ArraysNotSameLength',
|
|
301
|
+
userMessage: 'Invalid batch operation',
|
|
302
|
+
description:
|
|
303
|
+
'The arrays provided for this batch operation have different lengths. All arrays must have the same number of elements.',
|
|
304
|
+
category: 'batch',
|
|
305
|
+
isCommon: false,
|
|
306
|
+
},
|
|
307
|
+
|
|
308
|
+
MultiVault_InvalidArrayLength: {
|
|
309
|
+
errorName: 'MultiVault_InvalidArrayLength',
|
|
310
|
+
userMessage: 'Invalid number of items in batch',
|
|
311
|
+
description:
|
|
312
|
+
'The batch operation contains either zero items or exceeds the maximum batch size of 150 items.',
|
|
313
|
+
category: 'batch',
|
|
314
|
+
isCommon: false,
|
|
315
|
+
},
|
|
316
|
+
|
|
317
|
+
// ============================================
|
|
318
|
+
// APPROVAL ERRORS
|
|
319
|
+
// ============================================
|
|
320
|
+
|
|
321
|
+
MultiVault_CannotApproveOrRevokeSelf: {
|
|
322
|
+
errorName: 'MultiVault_CannotApproveOrRevokeSelf',
|
|
323
|
+
userMessage: 'Cannot modify own approval',
|
|
324
|
+
description:
|
|
325
|
+
'You cannot approve or revoke approval for yourself. Approval is only for allowing other addresses to act on your behalf.',
|
|
326
|
+
category: 'approval',
|
|
327
|
+
isCommon: false,
|
|
328
|
+
},
|
|
329
|
+
|
|
330
|
+
// ============================================
|
|
331
|
+
// TERM EXISTENCE ERRORS
|
|
332
|
+
// ============================================
|
|
333
|
+
|
|
334
|
+
MultiVault_TermDoesNotExist: {
|
|
335
|
+
errorName: 'MultiVault_TermDoesNotExist',
|
|
336
|
+
userMessage: "This entity or claim doesn't exist",
|
|
337
|
+
description:
|
|
338
|
+
'The specified term (atom or triple) has not been created on-chain. It may have been deleted or never existed.',
|
|
339
|
+
category: 'existence',
|
|
340
|
+
isCommon: true,
|
|
341
|
+
},
|
|
342
|
+
|
|
343
|
+
// ============================================
|
|
344
|
+
// EPOCH/UTILIZATION ERRORS
|
|
345
|
+
// ============================================
|
|
346
|
+
|
|
347
|
+
MultiVault_EpochNotTracked: {
|
|
348
|
+
errorName: 'MultiVault_EpochNotTracked',
|
|
349
|
+
userMessage: 'No activity recorded for this period',
|
|
350
|
+
description:
|
|
351
|
+
'There is no recorded activity for the specified epoch in the user history.',
|
|
352
|
+
category: 'epoch',
|
|
353
|
+
isCommon: false,
|
|
354
|
+
},
|
|
355
|
+
|
|
356
|
+
MultiVault_InvalidEpoch: {
|
|
357
|
+
errorName: 'MultiVault_InvalidEpoch',
|
|
358
|
+
userMessage: 'Invalid time period',
|
|
359
|
+
description: 'The specified epoch is in the future or otherwise invalid.',
|
|
360
|
+
category: 'epoch',
|
|
361
|
+
isCommon: false,
|
|
362
|
+
},
|
|
363
|
+
|
|
364
|
+
// ============================================
|
|
365
|
+
// WALLET ERRORS
|
|
366
|
+
// ============================================
|
|
367
|
+
|
|
368
|
+
MultiVault_OnlyAssociatedAtomWallet: {
|
|
369
|
+
errorName: 'MultiVault_OnlyAssociatedAtomWallet',
|
|
370
|
+
userMessage: "Only the entity's wallet can claim fees",
|
|
371
|
+
description:
|
|
372
|
+
'Atom wallet deposit fees can only be claimed by the associated atom wallet contract.',
|
|
373
|
+
category: 'wallet',
|
|
374
|
+
isCommon: false,
|
|
375
|
+
},
|
|
376
|
+
|
|
377
|
+
// ============================================
|
|
378
|
+
// MULTIVAULTCORE ERRORS
|
|
379
|
+
// ============================================
|
|
380
|
+
|
|
381
|
+
MultiVaultCore_InvalidAdmin: {
|
|
382
|
+
errorName: 'MultiVaultCore_InvalidAdmin',
|
|
383
|
+
userMessage: 'Invalid admin address',
|
|
384
|
+
description:
|
|
385
|
+
'The contract cannot be initialized with a zero address admin.',
|
|
386
|
+
category: 'internal',
|
|
387
|
+
isCommon: false,
|
|
388
|
+
},
|
|
389
|
+
|
|
390
|
+
MultiVaultCore_AtomDoesNotExist: {
|
|
391
|
+
errorName: 'MultiVaultCore_AtomDoesNotExist',
|
|
392
|
+
userMessage: 'Entity not found',
|
|
393
|
+
description:
|
|
394
|
+
'The specified atom ID does not correspond to any existing atom on-chain.',
|
|
395
|
+
category: 'existence',
|
|
396
|
+
isCommon: true,
|
|
397
|
+
},
|
|
398
|
+
|
|
399
|
+
MultiVaultCore_TripleDoesNotExist: {
|
|
400
|
+
errorName: 'MultiVaultCore_TripleDoesNotExist',
|
|
401
|
+
userMessage: 'Claim not found',
|
|
402
|
+
description:
|
|
403
|
+
'The specified triple ID does not correspond to any existing triple on-chain.',
|
|
404
|
+
category: 'existence',
|
|
405
|
+
isCommon: true,
|
|
406
|
+
},
|
|
407
|
+
|
|
408
|
+
MultiVaultCore_TermDoesNotExist: {
|
|
409
|
+
errorName: 'MultiVaultCore_TermDoesNotExist',
|
|
410
|
+
userMessage: 'Entity or claim not found',
|
|
411
|
+
description:
|
|
412
|
+
'The specified term ID does not correspond to any existing atom or triple on-chain.',
|
|
413
|
+
category: 'existence',
|
|
414
|
+
isCommon: true,
|
|
415
|
+
},
|
|
416
|
+
} as const
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* All error categories for filtering/grouping
|
|
420
|
+
*/
|
|
421
|
+
export const ERROR_CATEGORIES = [
|
|
422
|
+
'atom',
|
|
423
|
+
'triple',
|
|
424
|
+
'deposit',
|
|
425
|
+
'redeem',
|
|
426
|
+
'balance',
|
|
427
|
+
'limits',
|
|
428
|
+
'batch',
|
|
429
|
+
'approval',
|
|
430
|
+
'existence',
|
|
431
|
+
'epoch',
|
|
432
|
+
'wallet',
|
|
433
|
+
'internal',
|
|
434
|
+
] as const
|
|
435
|
+
|
|
436
|
+
export type ErrorCategory = (typeof ERROR_CATEGORIES)[number]
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Get all errors marked as commonly encountered by users
|
|
440
|
+
*/
|
|
441
|
+
export const COMMON_ERRORS = Object.entries(MULTIVAULT_ERRORS)
|
|
442
|
+
.filter(([, info]) => info.isCommon)
|
|
443
|
+
.reduce(
|
|
444
|
+
(acc, [key, value]) => {
|
|
445
|
+
acc[key] = value
|
|
446
|
+
return acc
|
|
447
|
+
},
|
|
448
|
+
{} as Record<string, MultiVaultErrorInfo>
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Total count of mapped errors
|
|
453
|
+
*/
|
|
454
|
+
export const TOTAL_ERROR_COUNT = Object.keys(MULTIVAULT_ERRORS).length // 31 errors
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Extract error name from various error formats
|
|
458
|
+
*
|
|
459
|
+
* Handles:
|
|
460
|
+
* - Viem ContractFunctionRevertedError with error.name
|
|
461
|
+
* - Error messages containing error names (e.g., "MultiVault_AtomExists")
|
|
462
|
+
* - Nested error.cause structures
|
|
463
|
+
*
|
|
464
|
+
* @param error - The error object from a contract call
|
|
465
|
+
* @returns The extracted error name or undefined if not found
|
|
466
|
+
*/
|
|
467
|
+
function extractErrorName(error: unknown): string | undefined {
|
|
468
|
+
if (!error) return undefined
|
|
469
|
+
|
|
470
|
+
// Type guard for error-like objects
|
|
471
|
+
const isErrorLike = (e: unknown): e is { message?: string; name?: string; cause?: unknown; data?: { errorName?: string } } =>
|
|
472
|
+
typeof e === 'object' && e !== null
|
|
473
|
+
|
|
474
|
+
if (!isErrorLike(error)) return undefined
|
|
475
|
+
|
|
476
|
+
// Check for viem's ContractFunctionRevertedError structure
|
|
477
|
+
// These have error.data.errorName
|
|
478
|
+
if (error.data?.errorName) {
|
|
479
|
+
return error.data.errorName
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// Check for error.name that matches MultiVault pattern
|
|
483
|
+
if (error.name?.startsWith('MultiVault')) {
|
|
484
|
+
return error.name
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Search error message for known error names
|
|
488
|
+
if (error.message) {
|
|
489
|
+
for (const errorName of Object.keys(MULTIVAULT_ERRORS)) {
|
|
490
|
+
if (error.message.includes(errorName)) {
|
|
491
|
+
return errorName
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// Check nested cause
|
|
497
|
+
if (error.cause) {
|
|
498
|
+
return extractErrorName(error.cause)
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
return undefined
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Parse a contract error and return user-friendly error information
|
|
506
|
+
*
|
|
507
|
+
* This function attempts to match the error against known MultiVault errors
|
|
508
|
+
* and returns structured information for display in the UI.
|
|
509
|
+
*
|
|
510
|
+
* @param error - The error object from a contract call
|
|
511
|
+
* @returns Parsed error information with user-friendly message
|
|
512
|
+
*
|
|
513
|
+
* @example
|
|
514
|
+
* ```typescript
|
|
515
|
+
* try {
|
|
516
|
+
* await createAtom(...)
|
|
517
|
+
* } catch (err) {
|
|
518
|
+
* const parsed = parseMultiVaultError(err)
|
|
519
|
+
* toast.error(parsed.userMessage)
|
|
520
|
+
* if (parsed.isMultiVaultError) {
|
|
521
|
+
* console.log('Contract error:', parsed.errorName)
|
|
522
|
+
* }
|
|
523
|
+
* }
|
|
524
|
+
* ```
|
|
525
|
+
*/
|
|
526
|
+
export function parseMultiVaultError(error: unknown): ParsedMultiVaultError {
|
|
527
|
+
const errorName = extractErrorName(error)
|
|
528
|
+
|
|
529
|
+
if (errorName && MULTIVAULT_ERRORS[errorName]) {
|
|
530
|
+
const errorInfo = MULTIVAULT_ERRORS[errorName]
|
|
531
|
+
return {
|
|
532
|
+
userMessage: errorInfo.userMessage,
|
|
533
|
+
description: errorInfo.description,
|
|
534
|
+
isCommon: errorInfo.isCommon,
|
|
535
|
+
errorName: errorInfo.errorName,
|
|
536
|
+
category: errorInfo.category,
|
|
537
|
+
isMultiVaultError: true,
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// Fallback for unknown errors
|
|
542
|
+
return {
|
|
543
|
+
userMessage: 'Transaction failed',
|
|
544
|
+
description: 'An unexpected error occurred. Please try again.',
|
|
545
|
+
isCommon: false,
|
|
546
|
+
isMultiVaultError: false,
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Check if an error is a specific MultiVault error
|
|
552
|
+
*
|
|
553
|
+
* @param error - The error to check
|
|
554
|
+
* @param errorName - The specific error name to check for
|
|
555
|
+
* @returns True if the error matches the specified error name
|
|
556
|
+
*
|
|
557
|
+
* @example
|
|
558
|
+
* ```typescript
|
|
559
|
+
* if (isMultiVaultError(err, 'MultiVault_AtomExists')) {
|
|
560
|
+
* // Handle atom already exists case
|
|
561
|
+
* }
|
|
562
|
+
* ```
|
|
563
|
+
*/
|
|
564
|
+
export function isMultiVaultError(
|
|
565
|
+
error: unknown,
|
|
566
|
+
errorName: keyof typeof MULTIVAULT_ERRORS
|
|
567
|
+
): boolean {
|
|
568
|
+
const extracted = extractErrorName(error)
|
|
569
|
+
return extracted === errorName
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Check if an error is any known MultiVault error
|
|
574
|
+
*
|
|
575
|
+
* @param error - The error to check
|
|
576
|
+
* @returns True if the error is a known MultiVault error
|
|
577
|
+
*/
|
|
578
|
+
export function isKnownMultiVaultError(error: unknown): boolean {
|
|
579
|
+
const extracted = extractErrorName(error)
|
|
580
|
+
return extracted !== undefined && extracted in MULTIVAULT_ERRORS
|
|
581
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Format stake amount for display (converts from wei to TRUST with suffixes)
|
|
5
|
+
*
|
|
6
|
+
* @param marketCap - The market cap in wei (18 decimals)
|
|
7
|
+
* @returns Formatted string like "1.5K", "2.3M", etc.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* formatStake('1000000000000000000') // "1"
|
|
11
|
+
* formatStake('1500000000000000000000') // "1.5K"
|
|
12
|
+
* formatStake('2300000000000000000000000') // "2.3M"
|
|
13
|
+
*/
|
|
14
|
+
export function formatStake(marketCap: string | number | undefined): string {
|
|
15
|
+
if (!marketCap) return '0'
|
|
16
|
+
|
|
17
|
+
// Convert from wei (18 decimals) to TRUST
|
|
18
|
+
const trustValue = Number(BigInt(marketCap)) / 1e18
|
|
19
|
+
|
|
20
|
+
if (trustValue === 0) return '0'
|
|
21
|
+
|
|
22
|
+
// Helper to format with proper decimals and remove trailing zeros
|
|
23
|
+
const formatWithDecimals = (value: number, decimals: number = 2): string => {
|
|
24
|
+
return value.toFixed(decimals).replace(/\.?0+$/, '')
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Format in TRUST with K/M/B suffixes
|
|
28
|
+
if (trustValue >= 1e9) {
|
|
29
|
+
return `${formatWithDecimals(trustValue / 1e9, 2)}B`
|
|
30
|
+
} else if (trustValue >= 1e6) {
|
|
31
|
+
return `${formatWithDecimals(trustValue / 1e6, 2)}M`
|
|
32
|
+
} else if (trustValue >= 1e3) {
|
|
33
|
+
return `${formatWithDecimals(trustValue / 1e3, 2)}K`
|
|
34
|
+
} else {
|
|
35
|
+
// For smaller values, show up to 2 decimals
|
|
36
|
+
return formatWithDecimals(trustValue, 2)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Highlight matching text in search results
|
|
42
|
+
* Returns React elements with highlighted portions
|
|
43
|
+
*
|
|
44
|
+
* @param text - The text to highlight
|
|
45
|
+
* @param searchTerm - The search term to highlight
|
|
46
|
+
* @returns React elements with matching text highlighted
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* highlightMatch('Vitalik Buterin', 'vitalik')
|
|
50
|
+
* // Returns: [<strong>Vitalik</strong>, ' Buterin']
|
|
51
|
+
*/
|
|
52
|
+
export function highlightMatch(
|
|
53
|
+
text: string,
|
|
54
|
+
searchTerm: string
|
|
55
|
+
): React.ReactNode {
|
|
56
|
+
if (!text || !searchTerm) return text
|
|
57
|
+
|
|
58
|
+
const regex = new RegExp(`(${escapeRegExp(searchTerm)})`, 'gi')
|
|
59
|
+
const parts = text.split(regex)
|
|
60
|
+
|
|
61
|
+
return parts.map((part, i) =>
|
|
62
|
+
part.toLowerCase() === searchTerm.toLowerCase() ? (
|
|
63
|
+
<strong key={i} className="bg-yellow-500/20 text-yellow-500">
|
|
64
|
+
{part}
|
|
65
|
+
</strong>
|
|
66
|
+
) : (
|
|
67
|
+
part
|
|
68
|
+
)
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Escape special regex characters in a string
|
|
74
|
+
*/
|
|
75
|
+
function escapeRegExp(string: string): string {
|
|
76
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Format a term_id for display (first 5 characters after 0x)
|
|
81
|
+
*
|
|
82
|
+
* @param termId - The full term_id (e.g., "0x123456789...")
|
|
83
|
+
* @returns Shortened display format (e.g., "12345")
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* formatTermId('0x123456789098765432') // "12345"
|
|
87
|
+
*/
|
|
88
|
+
export function formatTermId(termId: string): string {
|
|
89
|
+
if (!termId) return ''
|
|
90
|
+
if (termId.startsWith('0x')) {
|
|
91
|
+
return termId.slice(2, 7)
|
|
92
|
+
}
|
|
93
|
+
return termId.slice(0, 5)
|
|
94
|
+
}
|
|
95
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search utilities for atom search functionality
|
|
3
|
+
* Shared between hivemind-explorer and intuition-extension
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Ranking
|
|
7
|
+
export {
|
|
8
|
+
calculateMatchScore,
|
|
9
|
+
rankAtoms,
|
|
10
|
+
getAtomDisplayName,
|
|
11
|
+
getAtomDescription,
|
|
12
|
+
getAtomImage,
|
|
13
|
+
} from './ranking'
|
|
14
|
+
|
|
15
|
+
// Formatting
|
|
16
|
+
export { formatStake, highlightMatch, formatTermId } from './formatting'
|
|
17
|
+
|
|
18
|
+
// Types
|
|
19
|
+
export type {
|
|
20
|
+
AtomVault,
|
|
21
|
+
AtomValue,
|
|
22
|
+
AtomCreator,
|
|
23
|
+
GraphQLAtom,
|
|
24
|
+
RankedAtom,
|
|
25
|
+
SearchSummary,
|
|
26
|
+
SearchResult,
|
|
27
|
+
} from './types'
|
|
28
|
+
|