@mantle-rwa/react 0.1.1 → 0.1.3
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/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 +5 -3
- 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 +110 -0
- package/src/index.ts +4 -0
- package/src/styles/index.css +68 -14
- package/src/types/index.ts +200 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* KYCFlow - Multi-step KYC verification flow component
|
|
5
|
+
*
|
|
6
|
+
* Guides users through the KYC verification process and displays
|
|
7
|
+
* their current verification status and accreditation tier.
|
|
8
|
+
*/
|
|
9
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
10
|
+
import { useAccount } from 'wagmi';
|
|
11
|
+
import { useRWA } from '../hooks/useRWA';
|
|
12
|
+
import { AccreditationTier } from '@mantle-rwa/sdk';
|
|
13
|
+
/**
|
|
14
|
+
* Get display name for accreditation tier
|
|
15
|
+
*/
|
|
16
|
+
function getTierName(tier) {
|
|
17
|
+
switch (tier) {
|
|
18
|
+
case AccreditationTier.None:
|
|
19
|
+
return 'None';
|
|
20
|
+
case AccreditationTier.Retail:
|
|
21
|
+
return 'Retail';
|
|
22
|
+
case AccreditationTier.Accredited:
|
|
23
|
+
return 'Accredited';
|
|
24
|
+
case AccreditationTier.Institutional:
|
|
25
|
+
return 'Institutional';
|
|
26
|
+
default:
|
|
27
|
+
return 'Unknown';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Format date for display
|
|
32
|
+
*/
|
|
33
|
+
function formatDate(date) {
|
|
34
|
+
return date.toLocaleDateString('en-US', {
|
|
35
|
+
year: 'numeric',
|
|
36
|
+
month: 'long',
|
|
37
|
+
day: 'numeric',
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* KYCFlow component for guiding users through KYC verification
|
|
42
|
+
*/
|
|
43
|
+
export function KYCFlow({ registryAddress, investorAddress, onStatusChange, onComplete, onError, className = '', }) {
|
|
44
|
+
const { client, isInitialized, hasSigner } = useRWA();
|
|
45
|
+
const { address: connectedAddress } = useAccount();
|
|
46
|
+
const targetAddress = investorAddress || connectedAddress;
|
|
47
|
+
const [status, setStatus] = useState('idle');
|
|
48
|
+
const [investorInfo, setInvestorInfo] = useState(null);
|
|
49
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
50
|
+
const [error, setError] = useState(null);
|
|
51
|
+
// Update status and notify callback
|
|
52
|
+
const updateStatus = useCallback((newStatus) => {
|
|
53
|
+
setStatus(newStatus);
|
|
54
|
+
onStatusChange?.(newStatus);
|
|
55
|
+
}, [onStatusChange]);
|
|
56
|
+
// Fetch investor KYC data
|
|
57
|
+
const fetchKYCData = useCallback(async () => {
|
|
58
|
+
if (!client || !isInitialized || !registryAddress || !targetAddress) {
|
|
59
|
+
setIsLoading(false);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
setIsLoading(true);
|
|
63
|
+
setError(null);
|
|
64
|
+
try {
|
|
65
|
+
const registry = client.kyc.connect(registryAddress);
|
|
66
|
+
const info = await registry.getInvestorInfo(targetAddress);
|
|
67
|
+
setInvestorInfo(info);
|
|
68
|
+
// Determine status based on investor info
|
|
69
|
+
if (info.verified) {
|
|
70
|
+
updateStatus('completed');
|
|
71
|
+
onComplete?.(info.tier);
|
|
72
|
+
}
|
|
73
|
+
else if (info.tier !== AccreditationTier.None) {
|
|
74
|
+
updateStatus('in_progress');
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
updateStatus('pending');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
const errorObj = err instanceof Error ? err : new Error('Failed to fetch KYC data');
|
|
82
|
+
setError(errorObj);
|
|
83
|
+
updateStatus('failed');
|
|
84
|
+
onError?.(errorObj);
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
setIsLoading(false);
|
|
88
|
+
}
|
|
89
|
+
}, [client, isInitialized, registryAddress, targetAddress, updateStatus, onComplete, onError]);
|
|
90
|
+
// Fetch data on mount and when dependencies change
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
fetchKYCData();
|
|
93
|
+
}, [fetchKYCData]);
|
|
94
|
+
// Handle start verification
|
|
95
|
+
const handleStartVerification = useCallback(async () => {
|
|
96
|
+
if (!client || !targetAddress)
|
|
97
|
+
return;
|
|
98
|
+
updateStatus('in_progress');
|
|
99
|
+
try {
|
|
100
|
+
// Initiate verification through the KYC provider
|
|
101
|
+
const session = await client.kyc.verifyInvestor(targetAddress);
|
|
102
|
+
// If there's a redirect URL, open it
|
|
103
|
+
if (session.redirectUrl) {
|
|
104
|
+
window.open(session.redirectUrl, '_blank');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
const errorObj = err instanceof Error ? err : new Error('Failed to start verification');
|
|
109
|
+
setError(errorObj);
|
|
110
|
+
updateStatus('failed');
|
|
111
|
+
onError?.(errorObj);
|
|
112
|
+
}
|
|
113
|
+
}, [client, targetAddress, updateStatus, onError]);
|
|
114
|
+
// Handle retry
|
|
115
|
+
const handleRetry = useCallback(() => {
|
|
116
|
+
setError(null);
|
|
117
|
+
fetchKYCData();
|
|
118
|
+
}, [fetchKYCData]);
|
|
119
|
+
// Render loading state
|
|
120
|
+
if (isLoading) {
|
|
121
|
+
return (_jsx("div", { className: `rwa-kyc-flow rwa-kyc-flow--loading ${className}`, children: _jsxs("div", { className: "flex items-center justify-center p-8", children: [_jsx("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600" }), _jsx("span", { className: "ml-3 text-gray-600 dark:text-gray-300", children: "Loading KYC status..." })] }) }));
|
|
122
|
+
}
|
|
123
|
+
// Render no wallet connected state
|
|
124
|
+
if (!targetAddress) {
|
|
125
|
+
return (_jsx("div", { className: `rwa-kyc-flow rwa-kyc-flow--no-wallet ${className}`, children: _jsxs("div", { className: "p-6 bg-yellow-50 dark:bg-yellow-900/20 rounded-lg border border-yellow-200 dark:border-yellow-800", children: [_jsx("h3", { className: "text-lg font-semibold text-yellow-800 dark:text-yellow-200", children: "Wallet Not Connected" }), _jsx("p", { className: "mt-2 text-yellow-700 dark:text-yellow-300", children: "Please connect your wallet to view your KYC status." })] }) }));
|
|
126
|
+
}
|
|
127
|
+
// Render error state
|
|
128
|
+
if (status === 'failed' && error) {
|
|
129
|
+
return (_jsx("div", { className: `rwa-kyc-flow rwa-kyc-flow--error ${className}`, children: _jsxs("div", { className: "p-6 bg-red-50 dark:bg-red-900/20 rounded-lg border border-red-200 dark:border-red-800", children: [_jsx("h3", { className: "text-lg font-semibold text-red-800 dark:text-red-200", children: "Verification Failed" }), _jsx("p", { className: "mt-2 text-red-700 dark:text-red-300", children: error.message }), _jsx("button", { onClick: handleRetry, className: "mt-4 px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded-md transition-colors", children: "Retry" })] }) }));
|
|
130
|
+
}
|
|
131
|
+
// Render completed state
|
|
132
|
+
if (status === 'completed' && investorInfo) {
|
|
133
|
+
return (_jsx("div", { className: `rwa-kyc-flow rwa-kyc-flow--completed ${className}`, children: _jsxs("div", { className: "p-6 bg-green-50 dark:bg-green-900/20 rounded-lg border border-green-200 dark:border-green-800", children: [_jsxs("div", { className: "flex items-center", children: [_jsx("svg", { className: "w-8 h-8 text-green-600 dark:text-green-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" }) }), _jsx("h3", { className: "ml-3 text-lg font-semibold text-green-800 dark:text-green-200", children: "Verification Complete" })] }), _jsxs("div", { className: "mt-4 space-y-2", children: [_jsxs("p", { className: "text-green-700 dark:text-green-300", children: [_jsx("span", { className: "font-medium", children: "Accreditation Tier:" }), " ", getTierName(investorInfo.tier)] }), investorInfo.expiry && (_jsxs("p", { className: "text-green-700 dark:text-green-300", children: [_jsx("span", { className: "font-medium", children: "Valid Until:" }), " ", formatDate(investorInfo.expiry)] }))] })] }) }));
|
|
134
|
+
}
|
|
135
|
+
// Render in progress state
|
|
136
|
+
if (status === 'in_progress') {
|
|
137
|
+
return (_jsx("div", { className: `rwa-kyc-flow rwa-kyc-flow--in-progress ${className}`, children: _jsxs("div", { className: "p-6 bg-blue-50 dark:bg-blue-900/20 rounded-lg border border-blue-200 dark:border-blue-800", children: [_jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600" }), _jsx("h3", { className: "ml-3 text-lg font-semibold text-blue-800 dark:text-blue-200", children: "Verification In Progress" })] }), _jsx("p", { className: "mt-4 text-blue-700 dark:text-blue-300", children: "Your identity verification is being processed. This may take a few minutes." }), _jsx("button", { onClick: fetchKYCData, className: "mt-4 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-md transition-colors", children: "Check Status" })] }) }));
|
|
138
|
+
}
|
|
139
|
+
// Render pending state (default)
|
|
140
|
+
return (_jsx("div", { className: `rwa-kyc-flow rwa-kyc-flow--pending ${className}`, children: _jsxs("div", { className: "p-6 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700", children: [_jsx("h3", { className: "text-lg font-semibold text-gray-800 dark:text-gray-200", children: "KYC Verification Required" }), _jsx("p", { className: "mt-2 text-gray-600 dark:text-gray-400", children: "Complete identity verification to participate in RWA token offerings." }), !hasSigner ? (_jsx("p", { className: "mt-4 text-yellow-600 dark:text-yellow-400 text-sm", children: "Connect your wallet to start verification." })) : (_jsx("button", { onClick: handleStartVerification, className: "mt-4 px-6 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-md transition-colors", children: "Start Verification" }))] }) }));
|
|
141
|
+
}
|
|
142
|
+
export default KYCFlow;
|
|
143
|
+
//# sourceMappingURL=KYCFlow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KYCFlow.js","sourceRoot":"","sources":["../../../src/components/KYCFlow.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
const sizeClasses = {
|
|
4
|
+
sm: 'h-4 w-4',
|
|
5
|
+
md: 'h-6 w-6',
|
|
6
|
+
lg: 'h-8 w-8',
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* LoadingSpinner component
|
|
10
|
+
*/
|
|
11
|
+
export function LoadingSpinner({ size = 'md', className = '', }) {
|
|
12
|
+
return (_jsx("div", { className: `rwa-loading-spinner ${className}`, children: _jsx("div", { className: `animate-spin rounded-full border-b-2 border-blue-600 dark:border-blue-400 ${sizeClasses[size]}`, role: "status", "aria-label": "Loading" }) }));
|
|
13
|
+
}
|
|
14
|
+
export default LoadingSpinner;
|
|
15
|
+
//# sourceMappingURL=LoadingSpinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoadingSpinner.js","sourceRoot":"","sources":["../../../src/components/LoadingSpinner.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAQb,MAAM,WAAW,GAAG;IAChB,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;CAChB,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,EAC3B,IAAI,GAAG,IAAI,EACX,SAAS,GAAG,EAAE,GACI;IAClB,OAAO,CACH,cAAK,SAAS,EAAE,uBAAuB,SAAS,EAAE,YAC9C,cACI,SAAS,EAAE,6EAA6E,WAAW,CAAC,IAAI,CAAC,EAAE,EAC3G,IAAI,EAAC,QAAQ,gBACF,SAAS,GACtB,GACA,CACT,CAAC;AACN,CAAC;AAED,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* TokenMintForm - Form for minting RWA tokens to verified investors
|
|
5
|
+
*
|
|
6
|
+
* Validates recipient address and KYC status before allowing mint.
|
|
7
|
+
*/
|
|
8
|
+
import { useState, useCallback } from 'react';
|
|
9
|
+
import { useRWA } from '../hooks/useRWA';
|
|
10
|
+
import { AccreditationTier } from '@mantle-rwa/sdk';
|
|
11
|
+
/**
|
|
12
|
+
* Validate Ethereum address format
|
|
13
|
+
*/
|
|
14
|
+
export function isValidAddress(address) {
|
|
15
|
+
return /^0x[a-fA-F0-9]{40}$/.test(address);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Validate amount is positive
|
|
19
|
+
*/
|
|
20
|
+
export function isValidAmount(amount) {
|
|
21
|
+
const num = parseFloat(amount);
|
|
22
|
+
return !isNaN(num) && num > 0 && isFinite(num);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get display name for accreditation tier
|
|
26
|
+
*/
|
|
27
|
+
function getTierName(tier) {
|
|
28
|
+
switch (tier) {
|
|
29
|
+
case AccreditationTier.None:
|
|
30
|
+
return 'None';
|
|
31
|
+
case AccreditationTier.Retail:
|
|
32
|
+
return 'Retail';
|
|
33
|
+
case AccreditationTier.Accredited:
|
|
34
|
+
return 'Accredited';
|
|
35
|
+
case AccreditationTier.Institutional:
|
|
36
|
+
return 'Institutional';
|
|
37
|
+
default:
|
|
38
|
+
return 'Unknown';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* TokenMintForm component
|
|
43
|
+
*/
|
|
44
|
+
export function TokenMintForm({ tokenAddress, kycRegistryAddress, onSuccess, onError, className = '', }) {
|
|
45
|
+
const { client, isInitialized, hasSigner } = useRWA();
|
|
46
|
+
const [form, setForm] = useState({ recipient: '', amount: '' });
|
|
47
|
+
const [validation, setValidation] = useState({ recipientError: null, amountError: null });
|
|
48
|
+
const [kycCheck, setKycCheck] = useState({ isChecking: false, isVerified: null, tier: null });
|
|
49
|
+
const [isPending, setIsPending] = useState(false);
|
|
50
|
+
const [error, setError] = useState(null);
|
|
51
|
+
const [txResult, setTxResult] = useState(null);
|
|
52
|
+
// Validate recipient address
|
|
53
|
+
const validateRecipient = useCallback((address) => {
|
|
54
|
+
if (!address)
|
|
55
|
+
return 'Recipient address is required';
|
|
56
|
+
if (!isValidAddress(address))
|
|
57
|
+
return 'Invalid Ethereum address format';
|
|
58
|
+
return null;
|
|
59
|
+
}, []);
|
|
60
|
+
// Validate amount
|
|
61
|
+
const validateAmount = useCallback((amount) => {
|
|
62
|
+
if (!amount)
|
|
63
|
+
return 'Amount is required';
|
|
64
|
+
if (!isValidAmount(amount))
|
|
65
|
+
return 'Amount must be a positive number';
|
|
66
|
+
return null;
|
|
67
|
+
}, []);
|
|
68
|
+
// Handle recipient change
|
|
69
|
+
const handleRecipientChange = useCallback((e) => {
|
|
70
|
+
const value = e.target.value;
|
|
71
|
+
setForm(prev => ({ ...prev, recipient: value }));
|
|
72
|
+
setValidation(prev => ({ ...prev, recipientError: validateRecipient(value) }));
|
|
73
|
+
setKycCheck({ isChecking: false, isVerified: null, tier: null });
|
|
74
|
+
setTxResult(null);
|
|
75
|
+
}, [validateRecipient]);
|
|
76
|
+
// Handle amount change
|
|
77
|
+
const handleAmountChange = useCallback((e) => {
|
|
78
|
+
const value = e.target.value;
|
|
79
|
+
setForm(prev => ({ ...prev, amount: value }));
|
|
80
|
+
setValidation(prev => ({ ...prev, amountError: validateAmount(value) }));
|
|
81
|
+
setTxResult(null);
|
|
82
|
+
}, [validateAmount]);
|
|
83
|
+
// Check KYC status
|
|
84
|
+
const checkKYC = useCallback(async () => {
|
|
85
|
+
if (!client || !isInitialized || !form.recipient || !isValidAddress(form.recipient)) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
setKycCheck({ isChecking: true, isVerified: null, tier: null });
|
|
89
|
+
try {
|
|
90
|
+
const registry = client.kyc.connect(kycRegistryAddress);
|
|
91
|
+
const info = await registry.getInvestorInfo(form.recipient);
|
|
92
|
+
setKycCheck({
|
|
93
|
+
isChecking: false,
|
|
94
|
+
isVerified: info.verified,
|
|
95
|
+
tier: info.tier,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
setKycCheck({ isChecking: false, isVerified: false, tier: null });
|
|
100
|
+
}
|
|
101
|
+
}, [client, isInitialized, form.recipient, kycRegistryAddress]);
|
|
102
|
+
// Handle form submission
|
|
103
|
+
const handleSubmit = useCallback(async (e) => {
|
|
104
|
+
e.preventDefault();
|
|
105
|
+
// Validate all fields
|
|
106
|
+
const recipientError = validateRecipient(form.recipient);
|
|
107
|
+
const amountError = validateAmount(form.amount);
|
|
108
|
+
setValidation({ recipientError, amountError });
|
|
109
|
+
if (recipientError || amountError) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
// Check KYC if not already checked
|
|
113
|
+
if (kycCheck.isVerified === null) {
|
|
114
|
+
await checkKYC();
|
|
115
|
+
return; // User needs to submit again after KYC check
|
|
116
|
+
}
|
|
117
|
+
// Block if not verified
|
|
118
|
+
if (!kycCheck.isVerified) {
|
|
119
|
+
setError(new Error('Recipient is not KYC verified. Cannot mint tokens to unverified addresses.'));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (!client || !hasSigner) {
|
|
123
|
+
setError(new Error('Wallet not connected'));
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
setIsPending(true);
|
|
127
|
+
setError(null);
|
|
128
|
+
setTxResult(null);
|
|
129
|
+
try {
|
|
130
|
+
const token = client.token.connect(tokenAddress);
|
|
131
|
+
const result = await token.mint(form.recipient, form.amount);
|
|
132
|
+
setTxResult(result);
|
|
133
|
+
onSuccess?.(result);
|
|
134
|
+
// Clear form on success
|
|
135
|
+
setForm({ recipient: '', amount: '' });
|
|
136
|
+
setKycCheck({ isChecking: false, isVerified: null, tier: null });
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
const errorObj = err instanceof Error ? err : new Error('Mint failed');
|
|
140
|
+
setError(errorObj);
|
|
141
|
+
onError?.(errorObj);
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
setIsPending(false);
|
|
145
|
+
}
|
|
146
|
+
}, [form, validation, kycCheck, client, hasSigner, tokenAddress, validateRecipient, validateAmount, checkKYC, onSuccess, onError]);
|
|
147
|
+
const isFormValid = !validation.recipientError && !validation.amountError && form.recipient && form.amount;
|
|
148
|
+
const canSubmit = isFormValid && hasSigner && !isPending && (kycCheck.isVerified === null || kycCheck.isVerified);
|
|
149
|
+
return (_jsx("div", { className: `rwa-token-mint-form ${className}`, children: _jsxs("form", { onSubmit: handleSubmit, className: "space-y-6", children: [_jsxs("div", { children: [_jsx("label", { htmlFor: "recipient", className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: "Recipient Address" }), _jsx("input", { type: "text", id: "recipient", value: form.recipient, onChange: handleRecipientChange, onBlur: checkKYC, placeholder: "0x...", className: `mt-1 block w-full px-3 py-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-800 dark:text-white ${validation.recipientError
|
|
150
|
+
? 'border-red-500 focus:border-red-500'
|
|
151
|
+
: 'border-gray-300 dark:border-gray-600 focus:border-blue-500'}` }), validation.recipientError && (_jsx("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: validation.recipientError })), kycCheck.isChecking && (_jsx("p", { className: "mt-2 text-sm text-gray-500 dark:text-gray-400", children: "Checking KYC status..." })), kycCheck.isVerified === true && (_jsxs("p", { className: "mt-2 text-sm text-green-600 dark:text-green-400", children: ["\u2713 Verified (", getTierName(kycCheck.tier), ")"] })), kycCheck.isVerified === false && (_jsx("p", { className: "mt-2 text-sm text-red-600 dark:text-red-400", children: "\u2717 Not KYC verified - cannot mint to this address" }))] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "amount", className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: "Amount" }), _jsx("input", { type: "text", id: "amount", value: form.amount, onChange: handleAmountChange, placeholder: "0.00", className: `mt-1 block w-full px-3 py-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-800 dark:text-white ${validation.amountError
|
|
152
|
+
? 'border-red-500 focus:border-red-500'
|
|
153
|
+
: 'border-gray-300 dark:border-gray-600 focus:border-blue-500'}` }), validation.amountError && (_jsx("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: validation.amountError }))] }), !hasSigner && (_jsx("div", { className: "p-3 bg-yellow-50 dark:bg-yellow-900/20 rounded-md border border-yellow-200 dark:border-yellow-800", children: _jsx("p", { className: "text-sm text-yellow-700 dark:text-yellow-300", children: "Connect your wallet to mint tokens." }) })), error && (_jsx("div", { className: "p-3 bg-red-50 dark:bg-red-900/20 rounded-md border border-red-200 dark:border-red-800", children: _jsx("p", { className: "text-sm text-red-700 dark:text-red-300", children: error.message }) })), txResult && (_jsx("div", { className: "p-3 bg-green-50 dark:bg-green-900/20 rounded-md border border-green-200 dark:border-green-800", children: _jsxs("p", { className: "text-sm text-green-700 dark:text-green-300", children: ["\u2713 Mint successful! Transaction: ", txResult.hash.slice(0, 10), "..."] }) })), _jsx("button", { type: "submit", disabled: !canSubmit, className: `w-full py-2 px-4 rounded-md font-medium transition-colors ${canSubmit
|
|
154
|
+
? 'bg-blue-600 hover:bg-blue-700 text-white'
|
|
155
|
+
: 'bg-gray-300 dark:bg-gray-700 text-gray-500 dark:text-gray-400 cursor-not-allowed'}`, children: isPending ? 'Minting...' : kycCheck.isVerified === null && form.recipient ? 'Check KYC & Mint' : 'Mint Tokens' })] }) }));
|
|
156
|
+
}
|
|
157
|
+
export default TokenMintForm;
|
|
158
|
+
//# sourceMappingURL=TokenMintForm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenMintForm.js","sourceRoot":"","sources":["../../../src/components/TokenMintForm.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
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
|
+
import { useState, useCallback, useEffect, useRef } from 'react';
|
|
9
|
+
import { formatUnits } from 'viem';
|
|
10
|
+
import { useRWA } from '../hooks/useRWA';
|
|
11
|
+
/**
|
|
12
|
+
* Format address for display
|
|
13
|
+
*/
|
|
14
|
+
function formatAddress(address) {
|
|
15
|
+
return `${address.slice(0, 6)}...${address.slice(-4)}`;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Format token amount for display
|
|
19
|
+
*/
|
|
20
|
+
function formatAmount(amount, decimals = 18) {
|
|
21
|
+
const formatted = formatUnits(amount, decimals);
|
|
22
|
+
const num = parseFloat(formatted);
|
|
23
|
+
return num.toLocaleString(undefined, { maximumFractionDigits: 4 });
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* YieldCalculator component
|
|
27
|
+
*/
|
|
28
|
+
export function YieldCalculator({ tokenAddress, yieldDistributorAddress: _yieldDistributorAddress, holderAddresses, onCalculate, onError, className = '', }) {
|
|
29
|
+
const { client, isInitialized } = useRWA();
|
|
30
|
+
const [amount, setAmount] = useState('');
|
|
31
|
+
const [preview, setPreview] = useState(null);
|
|
32
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
33
|
+
const [error, setError] = useState(null);
|
|
34
|
+
// Debounce timer ref
|
|
35
|
+
const debounceRef = useRef(null);
|
|
36
|
+
// Calculate preview
|
|
37
|
+
const calculatePreview = useCallback(async (distributionAmount) => {
|
|
38
|
+
if (!client || !isInitialized || !distributionAmount || parseFloat(distributionAmount) <= 0) {
|
|
39
|
+
setPreview(null);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
setIsLoading(true);
|
|
43
|
+
setError(null);
|
|
44
|
+
try {
|
|
45
|
+
const result = await client.yield.previewDistribution(tokenAddress, distributionAmount, undefined, // snapshotId
|
|
46
|
+
holderAddresses);
|
|
47
|
+
setPreview(result);
|
|
48
|
+
onCalculate?.(result);
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
const errorObj = err instanceof Error ? err : new Error('Failed to calculate preview');
|
|
52
|
+
setError(errorObj);
|
|
53
|
+
onError?.(errorObj);
|
|
54
|
+
setPreview(null);
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
setIsLoading(false);
|
|
58
|
+
}
|
|
59
|
+
}, [client, isInitialized, tokenAddress, holderAddresses, onCalculate, onError]);
|
|
60
|
+
// Handle amount change with debounce
|
|
61
|
+
const handleAmountChange = useCallback((e) => {
|
|
62
|
+
const value = e.target.value;
|
|
63
|
+
setAmount(value);
|
|
64
|
+
// Clear previous debounce
|
|
65
|
+
if (debounceRef.current) {
|
|
66
|
+
clearTimeout(debounceRef.current);
|
|
67
|
+
}
|
|
68
|
+
// Debounce the calculation
|
|
69
|
+
debounceRef.current = setTimeout(() => {
|
|
70
|
+
calculatePreview(value);
|
|
71
|
+
}, 500);
|
|
72
|
+
}, [calculatePreview]);
|
|
73
|
+
// Cleanup debounce on unmount
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
return () => {
|
|
76
|
+
if (debounceRef.current) {
|
|
77
|
+
clearTimeout(debounceRef.current);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}, []);
|
|
81
|
+
// Recalculate when holder addresses change
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
if (amount && parseFloat(amount) > 0) {
|
|
84
|
+
calculatePreview(amount);
|
|
85
|
+
}
|
|
86
|
+
}, [holderAddresses]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
87
|
+
// Handle manual calculate button
|
|
88
|
+
const handleCalculate = useCallback(() => {
|
|
89
|
+
calculatePreview(amount);
|
|
90
|
+
}, [amount, calculatePreview]);
|
|
91
|
+
return (_jsx("div", { className: `rwa-yield-calculator ${className}`, children: _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { children: [_jsx("label", { htmlFor: "distribution-amount", className: "block text-sm font-medium text-gray-700 dark:text-gray-300", children: "Total Distribution Amount" }), _jsxs("div", { className: "mt-1 flex rounded-md shadow-sm", children: [_jsx("input", { type: "text", id: "distribution-amount", value: amount, onChange: handleAmountChange, placeholder: "Enter amount to distribute", 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" }), _jsx("button", { type: "button", onClick: handleCalculate, disabled: isLoading || !amount, className: "px-4 py-2 bg-blue-600 hover:bg-blue-700 disabled:bg-gray-400 text-white rounded-r-md transition-colors", children: isLoading ? 'Calculating...' : 'Calculate' })] })] }), isLoading && (_jsxs("div", { className: "flex items-center justify-center p-4", children: [_jsx("div", { className: "animate-spin rounded-full h-6 w-6 border-b-2 border-blue-600" }), _jsx("span", { className: "ml-2 text-gray-600 dark:text-gray-300", children: "Calculating distribution..." })] })), error && (_jsxs("div", { className: "p-4 bg-red-50 dark:bg-red-900/20 rounded-lg border border-red-200 dark:border-red-800", children: [_jsx("p", { className: "text-red-700 dark:text-red-300", children: error.message }), _jsx("button", { onClick: handleCalculate, className: "mt-2 text-sm text-red-600 dark:text-red-400 underline hover:no-underline", children: "Retry" })] })), preview && !isLoading && (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "p-4 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700", children: [_jsx("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: "Distribution Summary" }), _jsxs("div", { className: "mt-2 grid grid-cols-2 gap-4", children: [_jsxs("div", { children: [_jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Total Holders" }), _jsx("p", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: preview.totalHolders })] }), _jsxs("div", { children: [_jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Total Supply" }), _jsx("p", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: formatAmount(preview.totalSupplyAtSnapshot) })] })] })] }), preview.distributions.length > 0 && (_jsx("div", { className: "overflow-hidden rounded-lg border border-gray-200 dark:border-gray-700", children: _jsxs("table", { className: "min-w-full divide-y divide-gray-200 dark:divide-gray-700", children: [_jsx("thead", { className: "bg-gray-50 dark:bg-gray-800", children: _jsxs("tr", { children: [_jsx("th", { className: "px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider", children: "Address" }), _jsx("th", { className: "px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider", children: "Balance" }), _jsx("th", { className: "px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider", children: "Yield Amount" }), _jsx("th", { className: "px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider", children: "Share" })] }) }), _jsx("tbody", { className: "bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700", children: preview.distributions.map((dist) => (_jsxs("tr", { children: [_jsx("td", { className: "px-4 py-3 whitespace-nowrap text-sm font-mono text-gray-900 dark:text-white", children: formatAddress(dist.address) }), _jsx("td", { className: "px-4 py-3 whitespace-nowrap text-sm text-right text-gray-600 dark:text-gray-300", children: formatAmount(dist.balance) }), _jsx("td", { className: "px-4 py-3 whitespace-nowrap text-sm text-right font-medium text-green-600 dark:text-green-400", children: formatAmount(dist.yieldAmount) }), _jsxs("td", { className: "px-4 py-3 whitespace-nowrap text-sm text-right text-gray-600 dark:text-gray-300", children: [dist.percentage.toFixed(2), "%"] })] }, dist.address))) })] }) })), preview.distributions.length === 0 && (_jsx("div", { className: "p-4 bg-yellow-50 dark:bg-yellow-900/20 rounded-lg border border-yellow-200 dark:border-yellow-800", children: _jsx("p", { className: "text-yellow-700 dark:text-yellow-300", children: "No holder addresses provided or no holders have balances." }) }))] })), !preview && !isLoading && !error && (_jsx("div", { className: "p-6 text-center text-gray-500 dark:text-gray-400", children: _jsx("p", { children: "Enter a distribution amount to preview how yields will be allocated." }) }))] }) }));
|
|
92
|
+
}
|
|
93
|
+
export default YieldCalculator;
|
|
94
|
+
//# sourceMappingURL=YieldCalculator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"YieldCalculator.js","sourceRoot":"","sources":["../../../src/components/YieldCalculator.tsx"],"names":[],"mappings":"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"}
|
package/dist/esm/hooks/useRWA.js
CHANGED
|
@@ -1,51 +1,98 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
/**
|
|
2
|
-
* useRWA hook for accessing RWA SDK
|
|
3
|
+
* useRWA - Core hook for accessing the RWA SDK client
|
|
4
|
+
*
|
|
5
|
+
* Provides access to the @mantle-rwa/sdk RWAClient instance with
|
|
6
|
+
* automatic wagmi wallet integration.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { useRWA } from '@mantle-rwa/react';
|
|
11
|
+
*
|
|
12
|
+
* function MyComponent() {
|
|
13
|
+
* const { client, isInitialized, hasSigner } = useRWA();
|
|
14
|
+
*
|
|
15
|
+
* if (!isInitialized) return <div>Loading...</div>;
|
|
16
|
+
*
|
|
17
|
+
* // Use client.token, client.kyc, client.yield, client.compliance
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
3
20
|
*/
|
|
4
|
-
import { useState, useEffect } from 'react';
|
|
21
|
+
import { useState, useEffect, useCallback, useMemo } from 'react';
|
|
22
|
+
import { useAccount, useWalletClient } from 'wagmi';
|
|
23
|
+
import { BrowserProvider } from 'ethers';
|
|
24
|
+
import { RWAClient } from '@mantle-rwa/sdk';
|
|
25
|
+
// Default contract addresses (can be overridden via config)
|
|
26
|
+
const DEFAULT_CONTRACTS = {
|
|
27
|
+
token: undefined,
|
|
28
|
+
kycRegistry: undefined,
|
|
29
|
+
yieldDistributor: undefined,
|
|
30
|
+
assetVault: undefined,
|
|
31
|
+
factory: undefined,
|
|
32
|
+
};
|
|
5
33
|
/**
|
|
6
|
-
* Hook for
|
|
7
|
-
*
|
|
34
|
+
* Hook for initializing and managing the RWA SDK client
|
|
35
|
+
*
|
|
36
|
+
* @param config - Optional configuration for network and contract addresses
|
|
37
|
+
* @returns UseRWAReturn object with client, state, and utilities
|
|
8
38
|
*/
|
|
9
|
-
export function useRWA() {
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const [
|
|
13
|
-
const [
|
|
39
|
+
export function useRWA(config) {
|
|
40
|
+
const { isConnected } = useAccount();
|
|
41
|
+
const { data: walletClient } = useWalletClient();
|
|
42
|
+
const [client, setClient] = useState(null);
|
|
43
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
14
44
|
const [error, setError] = useState(null);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
31
|
-
if (chainIdHex) {
|
|
32
|
-
setChainId(parseInt(chainIdHex, 16));
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
setIsInitialized(true);
|
|
45
|
+
const network = config?.network ?? 'mantle-sepolia';
|
|
46
|
+
// Initialize or reinitialize the client
|
|
47
|
+
const initializeClient = useCallback(async () => {
|
|
48
|
+
setIsLoading(true);
|
|
49
|
+
setError(null);
|
|
50
|
+
try {
|
|
51
|
+
let rwaClient;
|
|
52
|
+
if (walletClient && isConnected) {
|
|
53
|
+
// Create client with wallet signer for write operations
|
|
54
|
+
const provider = new BrowserProvider(walletClient.transport);
|
|
55
|
+
const signer = await provider.getSigner();
|
|
56
|
+
rwaClient = new RWAClient({
|
|
57
|
+
network,
|
|
58
|
+
signer,
|
|
59
|
+
});
|
|
36
60
|
}
|
|
37
|
-
|
|
38
|
-
|
|
61
|
+
else {
|
|
62
|
+
// Create read-only client (no signer)
|
|
63
|
+
rwaClient = new RWAClient({
|
|
64
|
+
network,
|
|
65
|
+
});
|
|
39
66
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
67
|
+
setClient(rwaClient);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
const errorMessage = err instanceof Error ? err.message : 'Failed to initialize RWA client';
|
|
71
|
+
setError(new Error(errorMessage));
|
|
72
|
+
setClient(null);
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
setIsLoading(false);
|
|
76
|
+
}
|
|
77
|
+
}, [walletClient, isConnected, network]);
|
|
78
|
+
// Initialize client on mount and when wallet changes
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
initializeClient();
|
|
81
|
+
}, [initializeClient]);
|
|
82
|
+
// Memoized contract addresses
|
|
83
|
+
const contracts = useMemo(() => ({
|
|
84
|
+
...DEFAULT_CONTRACTS,
|
|
85
|
+
...config?.contracts,
|
|
86
|
+
}), [config?.contracts]);
|
|
43
87
|
return {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
isConnected,
|
|
88
|
+
client,
|
|
89
|
+
isInitialized: client !== null && !isLoading,
|
|
90
|
+
isLoading,
|
|
48
91
|
error,
|
|
92
|
+
hasSigner: client?.hasSigner ?? false,
|
|
93
|
+
contracts,
|
|
94
|
+
reinitialize: initializeClient,
|
|
49
95
|
};
|
|
50
96
|
}
|
|
97
|
+
export default useRWA;
|
|
51
98
|
//# sourceMappingURL=useRWA.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRWA.js","sourceRoot":"","sources":["../../../src/hooks/useRWA.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"useRWA.js","sourceRoot":"","sources":["../../../src/hooks/useRWA.ts"],"names":[],"mappings":"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"}
|