@mantle-rwa/react 0.1.0 → 0.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/LICENSE +0 -0
- package/dist/cjs/components/ConnectWalletPrompt.js +13 -0
- package/dist/cjs/components/ConnectWalletPrompt.js.map +1 -0
- package/dist/cjs/components/ErrorDisplay.js +42 -0
- package/dist/cjs/components/ErrorDisplay.js.map +1 -0
- package/dist/cjs/components/InvestorDashboard.js +156 -0
- package/dist/cjs/components/InvestorDashboard.js.map +1 -0
- package/dist/cjs/components/KYCFlow.js +146 -0
- package/dist/cjs/components/KYCFlow.js.map +1 -0
- package/dist/cjs/components/LoadingSpinner.js +18 -0
- package/dist/cjs/components/LoadingSpinner.js.map +1 -0
- package/dist/cjs/components/TokenMintForm.js +163 -0
- package/dist/cjs/components/TokenMintForm.js.map +1 -0
- package/dist/cjs/components/YieldCalculator.js +97 -0
- package/dist/cjs/components/YieldCalculator.js.map +1 -0
- package/dist/cjs/hooks/useRWA.js +87 -40
- package/dist/cjs/hooks/useRWA.js.map +1 -1
- package/dist/cjs/index.js +11 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/index.js +2 -2
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/esm/components/ConnectWalletPrompt.js +10 -0
- package/dist/esm/components/ConnectWalletPrompt.js.map +1 -0
- package/dist/esm/components/ErrorDisplay.js +38 -0
- package/dist/esm/components/ErrorDisplay.js.map +1 -0
- package/dist/esm/components/InvestorDashboard.js +153 -0
- package/dist/esm/components/InvestorDashboard.js.map +1 -0
- package/dist/esm/components/KYCFlow.js +143 -0
- package/dist/esm/components/KYCFlow.js.map +1 -0
- package/dist/esm/components/LoadingSpinner.js +15 -0
- package/dist/esm/components/LoadingSpinner.js.map +1 -0
- package/dist/esm/components/TokenMintForm.js +158 -0
- package/dist/esm/components/TokenMintForm.js.map +1 -0
- package/dist/esm/components/YieldCalculator.js +94 -0
- package/dist/esm/components/YieldCalculator.js.map +1 -0
- package/dist/esm/hooks/useRWA.js +86 -39
- package/dist/esm/hooks/useRWA.js.map +1 -1
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/index.js +3 -3
- package/dist/esm/types/index.js.map +1 -1
- package/dist/styles.css +3 -1
- package/dist/types/components/ConnectWalletPrompt.d.ts +15 -0
- package/dist/types/components/ConnectWalletPrompt.d.ts.map +1 -0
- package/dist/types/components/ErrorDisplay.d.ts +16 -0
- package/dist/types/components/ErrorDisplay.d.ts.map +1 -0
- package/dist/types/components/InvestorDashboard.d.ts +7 -0
- package/dist/types/components/InvestorDashboard.d.ts.map +1 -0
- package/dist/types/components/KYCFlow.d.ts +7 -0
- package/dist/types/components/KYCFlow.d.ts.map +1 -0
- package/dist/types/components/LoadingSpinner.d.ts +10 -0
- package/dist/types/components/LoadingSpinner.d.ts.map +1 -0
- package/dist/types/components/TokenMintForm.d.ts +15 -0
- package/dist/types/components/TokenMintForm.d.ts.map +1 -0
- package/dist/types/components/YieldCalculator.d.ts +7 -0
- package/dist/types/components/YieldCalculator.d.ts.map +1 -0
- package/dist/types/hooks/useRWA.d.ts +7 -19
- package/dist/types/hooks/useRWA.d.ts.map +1 -1
- package/dist/types/index.d.ts +5 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types/index.d.ts +113 -131
- package/dist/types/types/index.d.ts.map +1 -1
- package/package.json +65 -63
- package/src/components/ConnectWalletPrompt.tsx +47 -0
- package/src/components/ErrorDisplay.tsx +90 -0
- package/src/components/InvestorDashboard.tsx +315 -0
- package/src/components/KYCFlow.tsx +267 -0
- package/src/components/LoadingSpinner.tsx +33 -0
- package/src/components/TokenMintForm.tsx +291 -0
- package/src/components/YieldCalculator.tsx +250 -0
- package/src/hooks/useRWA.ts +90 -50
- package/src/index.ts +5 -17
- package/src/styles/index.css +60 -175
- package/src/types/index.ts +142 -135
- package/src/components/InvestorDashboard/index.tsx +0 -359
- package/src/components/KYCFlow/index.tsx +0 -434
- package/src/components/TokenMintForm/index.tsx +0 -590
- package/src/components/YieldCalculator/index.tsx +0 -541
- package/src/components/index.ts +0 -8
- package/src/hooks/index.ts +0 -5
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* YieldCalculator - Calculator for previewing yield distributions
|
|
5
|
+
*
|
|
6
|
+
* Shows how yields will be allocated to token holders before creating a distribution.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { useState, useCallback, useEffect, useRef } from 'react';
|
|
10
|
+
import { formatUnits } from 'viem';
|
|
11
|
+
import { useRWA } from '../hooks/useRWA';
|
|
12
|
+
import type { YieldCalculatorProps } from '../types';
|
|
13
|
+
import type { DistributionPreview, HolderDistribution } from '@mantle-rwa/sdk';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Format address for display
|
|
17
|
+
*/
|
|
18
|
+
function formatAddress(address: string): string {
|
|
19
|
+
return `${address.slice(0, 6)}...${address.slice(-4)}`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Format token amount for display
|
|
24
|
+
*/
|
|
25
|
+
function formatAmount(amount: bigint, decimals: number = 18): string {
|
|
26
|
+
const formatted = formatUnits(amount, decimals);
|
|
27
|
+
const num = parseFloat(formatted);
|
|
28
|
+
return num.toLocaleString(undefined, { maximumFractionDigits: 4 });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* YieldCalculator component
|
|
33
|
+
*/
|
|
34
|
+
export function YieldCalculator({
|
|
35
|
+
tokenAddress,
|
|
36
|
+
yieldDistributorAddress: _yieldDistributorAddress,
|
|
37
|
+
holderAddresses,
|
|
38
|
+
onCalculate,
|
|
39
|
+
onError,
|
|
40
|
+
className = '',
|
|
41
|
+
}: YieldCalculatorProps): JSX.Element {
|
|
42
|
+
const { client, isInitialized } = useRWA();
|
|
43
|
+
|
|
44
|
+
const [amount, setAmount] = useState<string>('');
|
|
45
|
+
const [preview, setPreview] = useState<DistributionPreview | null>(null);
|
|
46
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
47
|
+
const [error, setError] = useState<Error | null>(null);
|
|
48
|
+
|
|
49
|
+
// Debounce timer ref
|
|
50
|
+
const debounceRef = useRef<NodeJS.Timeout | null>(null);
|
|
51
|
+
|
|
52
|
+
// Calculate preview
|
|
53
|
+
const calculatePreview = useCallback(async (distributionAmount: string) => {
|
|
54
|
+
if (!client || !isInitialized || !distributionAmount || parseFloat(distributionAmount) <= 0) {
|
|
55
|
+
setPreview(null);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
setIsLoading(true);
|
|
60
|
+
setError(null);
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
const result = await client.yield.previewDistribution(
|
|
64
|
+
tokenAddress,
|
|
65
|
+
distributionAmount,
|
|
66
|
+
undefined, // snapshotId
|
|
67
|
+
holderAddresses
|
|
68
|
+
);
|
|
69
|
+
setPreview(result);
|
|
70
|
+
onCalculate?.(result);
|
|
71
|
+
} catch (err) {
|
|
72
|
+
const errorObj = err instanceof Error ? err : new Error('Failed to calculate preview');
|
|
73
|
+
setError(errorObj);
|
|
74
|
+
onError?.(errorObj);
|
|
75
|
+
setPreview(null);
|
|
76
|
+
} finally {
|
|
77
|
+
setIsLoading(false);
|
|
78
|
+
}
|
|
79
|
+
}, [client, isInitialized, tokenAddress, holderAddresses, onCalculate, onError]);
|
|
80
|
+
|
|
81
|
+
// Handle amount change with debounce
|
|
82
|
+
const handleAmountChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
|
83
|
+
const value = e.target.value;
|
|
84
|
+
setAmount(value);
|
|
85
|
+
|
|
86
|
+
// Clear previous debounce
|
|
87
|
+
if (debounceRef.current) {
|
|
88
|
+
clearTimeout(debounceRef.current);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Debounce the calculation
|
|
92
|
+
debounceRef.current = setTimeout(() => {
|
|
93
|
+
calculatePreview(value);
|
|
94
|
+
}, 500);
|
|
95
|
+
}, [calculatePreview]);
|
|
96
|
+
|
|
97
|
+
// Cleanup debounce on unmount
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
return () => {
|
|
100
|
+
if (debounceRef.current) {
|
|
101
|
+
clearTimeout(debounceRef.current);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}, []);
|
|
105
|
+
|
|
106
|
+
// Recalculate when holder addresses change
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
if (amount && parseFloat(amount) > 0) {
|
|
109
|
+
calculatePreview(amount);
|
|
110
|
+
}
|
|
111
|
+
}, [holderAddresses]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
112
|
+
|
|
113
|
+
// Handle manual calculate button
|
|
114
|
+
const handleCalculate = useCallback(() => {
|
|
115
|
+
calculatePreview(amount);
|
|
116
|
+
}, [amount, calculatePreview]);
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<div className={`rwa-yield-calculator ${className}`}>
|
|
120
|
+
<div className="space-y-6">
|
|
121
|
+
{/* Amount Input */}
|
|
122
|
+
<div>
|
|
123
|
+
<label htmlFor="distribution-amount" className="block text-sm font-medium text-gray-700 dark:text-gray-300">
|
|
124
|
+
Total Distribution Amount
|
|
125
|
+
</label>
|
|
126
|
+
<div className="mt-1 flex rounded-md shadow-sm">
|
|
127
|
+
<input
|
|
128
|
+
type="text"
|
|
129
|
+
id="distribution-amount"
|
|
130
|
+
value={amount}
|
|
131
|
+
onChange={handleAmountChange}
|
|
132
|
+
placeholder="Enter amount to distribute"
|
|
133
|
+
className="flex-1 block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-l-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-800 dark:text-white"
|
|
134
|
+
/>
|
|
135
|
+
<button
|
|
136
|
+
type="button"
|
|
137
|
+
onClick={handleCalculate}
|
|
138
|
+
disabled={isLoading || !amount}
|
|
139
|
+
className="px-4 py-2 bg-blue-600 hover:bg-blue-700 disabled:bg-gray-400 text-white rounded-r-md transition-colors"
|
|
140
|
+
>
|
|
141
|
+
{isLoading ? 'Calculating...' : 'Calculate'}
|
|
142
|
+
</button>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
|
|
146
|
+
{/* Loading State */}
|
|
147
|
+
{isLoading && (
|
|
148
|
+
<div className="flex items-center justify-center p-4">
|
|
149
|
+
<div className="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600" />
|
|
150
|
+
<span className="ml-2 text-gray-600 dark:text-gray-300">Calculating distribution...</span>
|
|
151
|
+
</div>
|
|
152
|
+
)}
|
|
153
|
+
|
|
154
|
+
{/* Error State */}
|
|
155
|
+
{error && (
|
|
156
|
+
<div className="p-4 bg-red-50 dark:bg-red-900/20 rounded-lg border border-red-200 dark:border-red-800">
|
|
157
|
+
<p className="text-red-700 dark:text-red-300">{error.message}</p>
|
|
158
|
+
<button
|
|
159
|
+
onClick={handleCalculate}
|
|
160
|
+
className="mt-2 text-sm text-red-600 dark:text-red-400 underline hover:no-underline"
|
|
161
|
+
>
|
|
162
|
+
Retry
|
|
163
|
+
</button>
|
|
164
|
+
</div>
|
|
165
|
+
)}
|
|
166
|
+
|
|
167
|
+
{/* Preview Results */}
|
|
168
|
+
{preview && !isLoading && (
|
|
169
|
+
<div className="space-y-4">
|
|
170
|
+
{/* Summary */}
|
|
171
|
+
<div className="p-4 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700">
|
|
172
|
+
<h4 className="text-sm font-medium text-gray-700 dark:text-gray-300">Distribution Summary</h4>
|
|
173
|
+
<div className="mt-2 grid grid-cols-2 gap-4">
|
|
174
|
+
<div>
|
|
175
|
+
<p className="text-xs text-gray-500 dark:text-gray-400">Total Holders</p>
|
|
176
|
+
<p className="text-lg font-semibold text-gray-900 dark:text-white">{preview.totalHolders}</p>
|
|
177
|
+
</div>
|
|
178
|
+
<div>
|
|
179
|
+
<p className="text-xs text-gray-500 dark:text-gray-400">Total Supply</p>
|
|
180
|
+
<p className="text-lg font-semibold text-gray-900 dark:text-white">
|
|
181
|
+
{formatAmount(preview.totalSupplyAtSnapshot)}
|
|
182
|
+
</p>
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
|
|
187
|
+
{/* Holder Distributions Table */}
|
|
188
|
+
{preview.distributions.length > 0 && (
|
|
189
|
+
<div className="overflow-hidden rounded-lg border border-gray-200 dark:border-gray-700">
|
|
190
|
+
<table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
|
191
|
+
<thead className="bg-gray-50 dark:bg-gray-800">
|
|
192
|
+
<tr>
|
|
193
|
+
<th className="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
194
|
+
Address
|
|
195
|
+
</th>
|
|
196
|
+
<th className="px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
197
|
+
Balance
|
|
198
|
+
</th>
|
|
199
|
+
<th className="px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
200
|
+
Yield Amount
|
|
201
|
+
</th>
|
|
202
|
+
<th className="px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
203
|
+
Share
|
|
204
|
+
</th>
|
|
205
|
+
</tr>
|
|
206
|
+
</thead>
|
|
207
|
+
<tbody className="bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700">
|
|
208
|
+
{preview.distributions.map((dist: HolderDistribution) => (
|
|
209
|
+
<tr key={dist.address}>
|
|
210
|
+
<td className="px-4 py-3 whitespace-nowrap text-sm font-mono text-gray-900 dark:text-white">
|
|
211
|
+
{formatAddress(dist.address)}
|
|
212
|
+
</td>
|
|
213
|
+
<td className="px-4 py-3 whitespace-nowrap text-sm text-right text-gray-600 dark:text-gray-300">
|
|
214
|
+
{formatAmount(dist.balance)}
|
|
215
|
+
</td>
|
|
216
|
+
<td className="px-4 py-3 whitespace-nowrap text-sm text-right font-medium text-green-600 dark:text-green-400">
|
|
217
|
+
{formatAmount(dist.yieldAmount)}
|
|
218
|
+
</td>
|
|
219
|
+
<td className="px-4 py-3 whitespace-nowrap text-sm text-right text-gray-600 dark:text-gray-300">
|
|
220
|
+
{dist.percentage.toFixed(2)}%
|
|
221
|
+
</td>
|
|
222
|
+
</tr>
|
|
223
|
+
))}
|
|
224
|
+
</tbody>
|
|
225
|
+
</table>
|
|
226
|
+
</div>
|
|
227
|
+
)}
|
|
228
|
+
|
|
229
|
+
{preview.distributions.length === 0 && (
|
|
230
|
+
<div className="p-4 bg-yellow-50 dark:bg-yellow-900/20 rounded-lg border border-yellow-200 dark:border-yellow-800">
|
|
231
|
+
<p className="text-yellow-700 dark:text-yellow-300">
|
|
232
|
+
No holder addresses provided or no holders have balances.
|
|
233
|
+
</p>
|
|
234
|
+
</div>
|
|
235
|
+
)}
|
|
236
|
+
</div>
|
|
237
|
+
)}
|
|
238
|
+
|
|
239
|
+
{/* Empty State */}
|
|
240
|
+
{!preview && !isLoading && !error && (
|
|
241
|
+
<div className="p-6 text-center text-gray-500 dark:text-gray-400">
|
|
242
|
+
<p>Enter a distribution amount to preview how yields will be allocated.</p>
|
|
243
|
+
</div>
|
|
244
|
+
)}
|
|
245
|
+
</div>
|
|
246
|
+
</div>
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export default YieldCalculator;
|
package/src/hooks/useRWA.ts
CHANGED
|
@@ -1,70 +1,110 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
|
-
* useRWA hook for accessing RWA SDK
|
|
4
|
+
* useRWA - Core hook for accessing the RWA SDK client
|
|
5
|
+
*
|
|
6
|
+
* Provides access to the @mantle-rwa/sdk RWAClient instance with
|
|
7
|
+
* automatic wagmi wallet integration.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { useRWA } from '@mantle-rwa/react';
|
|
12
|
+
*
|
|
13
|
+
* function MyComponent() {
|
|
14
|
+
* const { client, isInitialized, hasSigner } = useRWA();
|
|
15
|
+
*
|
|
16
|
+
* if (!isInitialized) return <div>Loading...</div>;
|
|
17
|
+
*
|
|
18
|
+
* // Use client.token, client.kyc, client.yield, client.compliance
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
3
21
|
*/
|
|
4
22
|
|
|
5
|
-
import { useState, useEffect } from 'react';
|
|
6
|
-
import
|
|
23
|
+
import { useState, useEffect, useCallback, useMemo } from 'react';
|
|
24
|
+
import { useAccount, useWalletClient } from 'wagmi';
|
|
25
|
+
import { BrowserProvider } from 'ethers';
|
|
26
|
+
import { RWAClient } from '@mantle-rwa/sdk';
|
|
27
|
+
import type { UseRWAConfig, UseRWAReturn, ContractAddresses } from '../types';
|
|
28
|
+
|
|
29
|
+
// Default contract addresses (can be overridden via config)
|
|
30
|
+
const DEFAULT_CONTRACTS: ContractAddresses = {
|
|
31
|
+
token: undefined,
|
|
32
|
+
kycRegistry: undefined,
|
|
33
|
+
yieldDistributor: undefined,
|
|
34
|
+
assetVault: undefined,
|
|
35
|
+
factory: undefined,
|
|
36
|
+
};
|
|
7
37
|
|
|
8
38
|
/**
|
|
9
|
-
* Hook for
|
|
10
|
-
*
|
|
39
|
+
* Hook for initializing and managing the RWA SDK client
|
|
40
|
+
*
|
|
41
|
+
* @param config - Optional configuration for network and contract addresses
|
|
42
|
+
* @returns UseRWAReturn object with client, state, and utilities
|
|
11
43
|
*/
|
|
12
|
-
export function useRWA(): UseRWAReturn {
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
const [
|
|
44
|
+
export function useRWA(config?: UseRWAConfig): UseRWAReturn {
|
|
45
|
+
const { isConnected } = useAccount();
|
|
46
|
+
const { data: walletClient } = useWalletClient();
|
|
47
|
+
|
|
48
|
+
const [client, setClient] = useState<RWAClient | null>(null);
|
|
49
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
17
50
|
const [error, setError] = useState<Error | null>(null);
|
|
18
51
|
|
|
19
|
-
|
|
20
|
-
// Initialize SDK client
|
|
21
|
-
const initializeSDK = async () => {
|
|
22
|
-
try {
|
|
23
|
-
// Check if window.ethereum is available (browser wallet)
|
|
24
|
-
if (typeof window !== 'undefined' && window.ethereum) {
|
|
25
|
-
const accounts = await window.ethereum.request?.({
|
|
26
|
-
method: 'eth_accounts',
|
|
27
|
-
}) as string[] | undefined;
|
|
52
|
+
const network = config?.network ?? 'mantle-sepolia';
|
|
28
53
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
54
|
+
// Initialize or reinitialize the client
|
|
55
|
+
const initializeClient = useCallback(async () => {
|
|
56
|
+
setIsLoading(true);
|
|
57
|
+
setError(null);
|
|
33
58
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}) as string | undefined;
|
|
59
|
+
try {
|
|
60
|
+
let rwaClient: RWAClient;
|
|
37
61
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
62
|
+
if (walletClient && isConnected) {
|
|
63
|
+
// Create client with wallet signer for write operations
|
|
64
|
+
const provider = new BrowserProvider(walletClient.transport);
|
|
65
|
+
const signer = await provider.getSigner();
|
|
42
66
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
67
|
+
rwaClient = new RWAClient({
|
|
68
|
+
network,
|
|
69
|
+
signer,
|
|
70
|
+
});
|
|
71
|
+
} else {
|
|
72
|
+
// Create read-only client (no signer)
|
|
73
|
+
rwaClient = new RWAClient({
|
|
74
|
+
network,
|
|
75
|
+
});
|
|
46
76
|
}
|
|
47
|
-
};
|
|
48
77
|
|
|
49
|
-
|
|
50
|
-
|
|
78
|
+
setClient(rwaClient);
|
|
79
|
+
} catch (err) {
|
|
80
|
+
const errorMessage = err instanceof Error ? err.message : 'Failed to initialize RWA client';
|
|
81
|
+
setError(new Error(errorMessage));
|
|
82
|
+
setClient(null);
|
|
83
|
+
} finally {
|
|
84
|
+
setIsLoading(false);
|
|
85
|
+
}
|
|
86
|
+
}, [walletClient, isConnected, network]);
|
|
87
|
+
|
|
88
|
+
// Initialize client on mount and when wallet changes
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
initializeClient();
|
|
91
|
+
}, [initializeClient]);
|
|
92
|
+
|
|
93
|
+
// Memoized contract addresses
|
|
94
|
+
const contracts = useMemo<ContractAddresses>(() => ({
|
|
95
|
+
...DEFAULT_CONTRACTS,
|
|
96
|
+
...config?.contracts,
|
|
97
|
+
}), [config?.contracts]);
|
|
51
98
|
|
|
52
99
|
return {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
isConnected,
|
|
100
|
+
client,
|
|
101
|
+
isInitialized: client !== null && !isLoading,
|
|
102
|
+
isLoading,
|
|
57
103
|
error,
|
|
104
|
+
hasSigner: client?.hasSigner ?? false,
|
|
105
|
+
contracts,
|
|
106
|
+
reinitialize: initializeClient,
|
|
58
107
|
};
|
|
59
108
|
}
|
|
60
109
|
|
|
61
|
-
|
|
62
|
-
declare global {
|
|
63
|
-
interface Window {
|
|
64
|
-
ethereum?: {
|
|
65
|
-
request?: (args: { method: string; params?: unknown[] }) => Promise<unknown>;
|
|
66
|
-
on?: (event: string, callback: (...args: unknown[]) => void) => void;
|
|
67
|
-
removeListener?: (event: string, callback: (...args: unknown[]) => void) => void;
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
}
|
|
110
|
+
export default useRWA;
|
package/src/index.ts
CHANGED
|
@@ -7,26 +7,14 @@
|
|
|
7
7
|
export { KYCFlow } from './components/KYCFlow';
|
|
8
8
|
export { InvestorDashboard } from './components/InvestorDashboard';
|
|
9
9
|
export { TokenMintForm } from './components/TokenMintForm';
|
|
10
|
+
export { isValidAddress, isValidAmount } from './components/TokenMintForm';
|
|
10
11
|
export { YieldCalculator } from './components/YieldCalculator';
|
|
12
|
+
export { ErrorDisplay, formatErrorMessage } from './components/ErrorDisplay';
|
|
13
|
+
export { LoadingSpinner } from './components/LoadingSpinner';
|
|
14
|
+
export { ConnectWalletPrompt } from './components/ConnectWalletPrompt';
|
|
11
15
|
|
|
12
16
|
// Hooks
|
|
13
17
|
export { useRWA } from './hooks/useRWA';
|
|
14
18
|
|
|
15
19
|
// Types
|
|
16
|
-
export type
|
|
17
|
-
Theme,
|
|
18
|
-
KYCProviderType,
|
|
19
|
-
KYCRequiredField,
|
|
20
|
-
KYCResult,
|
|
21
|
-
KYCFlowProps,
|
|
22
|
-
KYCFlowStyles,
|
|
23
|
-
InvestorDashboardProps,
|
|
24
|
-
YieldHistoryEntry,
|
|
25
|
-
TokenMintFormProps,
|
|
26
|
-
BatchMintEntry,
|
|
27
|
-
YieldCalculatorProps,
|
|
28
|
-
PaymentToken,
|
|
29
|
-
DistributionConfig,
|
|
30
|
-
DistributionPreviewEntry,
|
|
31
|
-
UseRWAReturn,
|
|
32
|
-
} from './types';
|
|
20
|
+
export type * from './types';
|