@mantle-rwa/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/cjs/client.js +198 -0
  2. package/dist/cjs/client.js.map +1 -0
  3. package/dist/cjs/constants/index.js +211 -0
  4. package/dist/cjs/constants/index.js.map +1 -0
  5. package/dist/cjs/errors/index.js +218 -0
  6. package/dist/cjs/errors/index.js.map +1 -0
  7. package/dist/cjs/index.js +51 -0
  8. package/dist/cjs/index.js.map +1 -0
  9. package/dist/cjs/modules/compliance.js +202 -0
  10. package/dist/cjs/modules/compliance.js.map +1 -0
  11. package/dist/cjs/modules/index.js +18 -0
  12. package/dist/cjs/modules/index.js.map +1 -0
  13. package/dist/cjs/modules/kyc.js +278 -0
  14. package/dist/cjs/modules/kyc.js.map +1 -0
  15. package/dist/cjs/modules/token.js +365 -0
  16. package/dist/cjs/modules/token.js.map +1 -0
  17. package/dist/cjs/modules/yield.js +406 -0
  18. package/dist/cjs/modules/yield.js.map +1 -0
  19. package/dist/cjs/package.json +3 -0
  20. package/dist/cjs/types/index.js +20 -0
  21. package/dist/cjs/types/index.js.map +1 -0
  22. package/dist/cjs/utils/index.js +206 -0
  23. package/dist/cjs/utils/index.js.map +1 -0
  24. package/dist/esm/client.js +194 -0
  25. package/dist/esm/client.js.map +1 -0
  26. package/dist/esm/constants/index.js +208 -0
  27. package/dist/esm/constants/index.js.map +1 -0
  28. package/dist/esm/errors/index.js +209 -0
  29. package/dist/esm/errors/index.js.map +1 -0
  30. package/dist/esm/index.js +17 -0
  31. package/dist/esm/index.js.map +1 -0
  32. package/dist/esm/modules/compliance.js +198 -0
  33. package/dist/esm/modules/compliance.js.map +1 -0
  34. package/dist/esm/modules/index.js +8 -0
  35. package/dist/esm/modules/index.js.map +1 -0
  36. package/dist/esm/modules/kyc.js +273 -0
  37. package/dist/esm/modules/kyc.js.map +1 -0
  38. package/dist/esm/modules/token.js +360 -0
  39. package/dist/esm/modules/token.js.map +1 -0
  40. package/dist/esm/modules/yield.js +401 -0
  41. package/dist/esm/modules/yield.js.map +1 -0
  42. package/dist/esm/types/index.js +17 -0
  43. package/dist/esm/types/index.js.map +1 -0
  44. package/dist/esm/utils/index.js +188 -0
  45. package/dist/esm/utils/index.js.map +1 -0
  46. package/dist/types/client.d.ts +93 -0
  47. package/dist/types/client.d.ts.map +1 -0
  48. package/dist/types/constants/index.d.ts +83 -0
  49. package/dist/types/constants/index.d.ts.map +1 -0
  50. package/dist/types/errors/index.d.ts +83 -0
  51. package/dist/types/errors/index.d.ts.map +1 -0
  52. package/dist/types/index.d.ts +13 -0
  53. package/dist/types/index.d.ts.map +1 -0
  54. package/dist/types/modules/compliance.d.ts +29 -0
  55. package/dist/types/modules/compliance.d.ts.map +1 -0
  56. package/dist/types/modules/index.d.ts +8 -0
  57. package/dist/types/modules/index.d.ts.map +1 -0
  58. package/dist/types/modules/kyc.d.ts +131 -0
  59. package/dist/types/modules/kyc.d.ts.map +1 -0
  60. package/dist/types/modules/token.d.ts +145 -0
  61. package/dist/types/modules/token.d.ts.map +1 -0
  62. package/dist/types/modules/yield.d.ts +143 -0
  63. package/dist/types/modules/yield.d.ts.map +1 -0
  64. package/dist/types/types/index.d.ts +254 -0
  65. package/dist/types/types/index.d.ts.map +1 -0
  66. package/dist/types/utils/index.d.ts +80 -0
  67. package/dist/types/utils/index.d.ts.map +1 -0
  68. package/package.json +52 -0
  69. package/src/client.ts +258 -0
  70. package/src/constants/index.ts +226 -0
  71. package/src/errors/index.ts +291 -0
  72. package/src/index.ts +42 -0
  73. package/src/modules/compliance.ts +252 -0
  74. package/src/modules/index.ts +8 -0
  75. package/src/modules/kyc.ts +446 -0
  76. package/src/modules/token.ts +488 -0
  77. package/src/modules/yield.ts +566 -0
  78. package/src/types/index.ts +326 -0
  79. package/src/utils/index.ts +240 -0
package/src/client.ts ADDED
@@ -0,0 +1,258 @@
1
+ /**
2
+ * RWAClient - Main entry point for the Mantle RWA SDK
3
+ */
4
+
5
+ import { ethers, type Provider, type Signer } from 'ethers';
6
+ import { TokenModule } from './modules/token';
7
+ import { KYCModule } from './modules/kyc';
8
+ import { YieldModule } from './modules/yield';
9
+ import { ComplianceModule } from './modules/compliance';
10
+ import type { NetworkConfig, CustomNetwork, DeploymentConfig, DeployedContracts } from './types';
11
+ import { NETWORKS, RWA_FACTORY_ABI, DEFAULTS } from './constants';
12
+ import { RWAError, ErrorCode, parseContractError } from './errors';
13
+ import { isValidAddress, parseAmount, parseEvents, retry } from './utils';
14
+
15
+ /**
16
+ * Configuration for RWAClient
17
+ */
18
+ export interface RWAClientConfig {
19
+ /** Network to connect to */
20
+ network: 'mantle' | 'mantle-sepolia' | CustomNetwork;
21
+ /** Private key for signing transactions (optional if signer provided) */
22
+ privateKey?: string;
23
+ /** Ethers signer instance (optional if privateKey provided) */
24
+ signer?: Signer;
25
+ /** Factory contract address (optional, uses default if not provided) */
26
+ factoryAddress?: string;
27
+ /** Number of transaction retries */
28
+ retries?: number;
29
+ /** Retry delay in milliseconds */
30
+ retryDelay?: number;
31
+ }
32
+
33
+ /**
34
+ * Main client for interacting with Mantle RWA contracts
35
+ */
36
+ export class RWAClient {
37
+ private readonly _provider: Provider;
38
+ private readonly _signer: Signer | null;
39
+ private readonly _networkConfig: NetworkConfig;
40
+ private readonly _factoryAddress?: string;
41
+ private readonly _retries: number;
42
+ private readonly _retryDelay: number;
43
+
44
+ /** Token module for RWA token operations */
45
+ readonly token: TokenModule;
46
+ /** KYC module for investor verification */
47
+ readonly kyc: KYCModule;
48
+ /** Yield module for distribution management */
49
+ readonly yield: YieldModule;
50
+ /** Compliance module for transfer eligibility */
51
+ readonly compliance: ComplianceModule;
52
+
53
+ constructor(config: RWAClientConfig) {
54
+ // Resolve network configuration
55
+ if (typeof config.network === 'string') {
56
+ const networkConfig = NETWORKS[config.network];
57
+ if (!networkConfig) {
58
+ throw new RWAError(
59
+ ErrorCode.INVALID_CONFIGURATION,
60
+ `Unknown network: ${config.network}. Use 'mantle', 'mantle-sepolia', or provide custom network config.`
61
+ );
62
+ }
63
+ this._networkConfig = networkConfig;
64
+ } else {
65
+ this._networkConfig = {
66
+ name: config.network.name || 'Custom Network',
67
+ chainId: config.network.chainId,
68
+ rpcUrl: config.network.rpcUrl,
69
+ explorerUrl: config.network.explorerUrl || '',
70
+ };
71
+ }
72
+
73
+ // Create provider
74
+ this._provider = new ethers.JsonRpcProvider(this._networkConfig.rpcUrl);
75
+
76
+ // Create signer if private key provided
77
+ if (config.signer) {
78
+ this._signer = config.signer;
79
+ } else if (config.privateKey) {
80
+ this._signer = new ethers.Wallet(config.privateKey, this._provider);
81
+ } else {
82
+ this._signer = null;
83
+ }
84
+
85
+ // Store configuration
86
+ this._factoryAddress = config.factoryAddress || this._networkConfig.contracts?.factory;
87
+ this._retries = config.retries ?? DEFAULTS.TRANSACTION_RETRIES;
88
+ this._retryDelay = config.retryDelay ?? DEFAULTS.RETRY_DELAY_MS;
89
+
90
+ // Initialize modules
91
+ this.token = new TokenModule(this._provider, this._signer, this._retries, this._retryDelay);
92
+ this.kyc = new KYCModule(this._provider, this._signer, this._retries, this._retryDelay);
93
+ this.yield = new YieldModule(this._provider, this._signer, this._retries, this._retryDelay);
94
+ this.compliance = new ComplianceModule(this._provider, this._signer);
95
+ }
96
+
97
+ /**
98
+ * Get the provider instance
99
+ */
100
+ get provider(): Provider {
101
+ return this._provider;
102
+ }
103
+
104
+ /**
105
+ * Get the signer instance (throws if not available)
106
+ */
107
+ get signer(): Signer {
108
+ if (!this._signer) {
109
+ throw new RWAError(
110
+ ErrorCode.SIGNER_REQUIRED,
111
+ 'A signer is required for this operation. Provide a privateKey or signer in the client configuration.'
112
+ );
113
+ }
114
+ return this._signer;
115
+ }
116
+
117
+ /**
118
+ * Check if a signer is available
119
+ */
120
+ get hasSigner(): boolean {
121
+ return this._signer !== null;
122
+ }
123
+
124
+ /**
125
+ * Get the network configuration
126
+ */
127
+ get network(): NetworkConfig {
128
+ return this._networkConfig;
129
+ }
130
+
131
+ /**
132
+ * Deploy a complete RWA system using the factory contract
133
+ * @param config Deployment configuration
134
+ * @returns Addresses of all deployed contracts
135
+ */
136
+ async deployRWASystem(config: DeploymentConfig): Promise<DeployedContracts> {
137
+ if (!this._factoryAddress) {
138
+ throw new RWAError(
139
+ ErrorCode.INVALID_CONFIGURATION,
140
+ 'Factory address not configured. Provide factoryAddress in client config or use a network with a deployed factory.'
141
+ );
142
+ }
143
+
144
+ // Validate configuration
145
+ this._validateDeploymentConfig(config);
146
+
147
+ const factory = new ethers.Contract(
148
+ this._factoryAddress,
149
+ RWA_FACTORY_ABI,
150
+ this.signer
151
+ );
152
+
153
+ const deployConfig = {
154
+ tokenName: config.tokenName,
155
+ tokenSymbol: config.tokenSymbol,
156
+ initialSupply: parseAmount(config.initialSupply),
157
+ complianceModules: config.complianceModules || [],
158
+ yieldClaimWindowDays: config.yieldClaimWindowDays ?? DEFAULTS.YIELD_CLAIM_WINDOW_DAYS,
159
+ vaultSigners: config.vaultSigners,
160
+ vaultThreshold: config.vaultThreshold,
161
+ vaultWithdrawalThreshold: parseAmount(
162
+ config.vaultWithdrawalThreshold || DEFAULTS.VAULT_WITHDRAWAL_THRESHOLD
163
+ ),
164
+ };
165
+
166
+ try {
167
+ const tx = await retry(
168
+ () => factory.deploy(deployConfig),
169
+ { retries: this._retries, delay: this._retryDelay }
170
+ );
171
+
172
+ const receipt = await tx.wait();
173
+ const iface = new ethers.Interface(RWA_FACTORY_ABI);
174
+ const events = parseEvents(receipt, iface);
175
+
176
+ const deployedEvent = events.find((e) => e.name === 'RWASystemDeployed');
177
+ if (!deployedEvent) {
178
+ throw new RWAError(
179
+ ErrorCode.UNKNOWN,
180
+ 'Deployment succeeded but RWASystemDeployed event not found'
181
+ );
182
+ }
183
+
184
+ return {
185
+ token: deployedEvent.args.token as string,
186
+ vault: deployedEvent.args.vault as string,
187
+ yieldDistributor: deployedEvent.args.yieldDistributor as string,
188
+ kycRegistry: deployedEvent.args.kycRegistry as string,
189
+ };
190
+ } catch (error) {
191
+ throw parseContractError(error, this._factoryAddress, 'deploy');
192
+ }
193
+ }
194
+
195
+ /**
196
+ * Connect to an existing RWA token
197
+ */
198
+ connectToken(address: string) {
199
+ return this.token.connect(address);
200
+ }
201
+
202
+ /**
203
+ * Connect to an existing KYC registry
204
+ */
205
+ connectKYCRegistry(address: string) {
206
+ return this.kyc.connect(address);
207
+ }
208
+
209
+ /**
210
+ * Connect to an existing yield distributor
211
+ */
212
+ connectYieldDistributor(address: string) {
213
+ return this.yield.connect(address);
214
+ }
215
+
216
+ /**
217
+ * Get the current block number
218
+ */
219
+ async getBlockNumber(): Promise<number> {
220
+ return this._provider.getBlockNumber();
221
+ }
222
+
223
+ /**
224
+ * Get the balance of an address
225
+ */
226
+ async getBalance(address: string): Promise<bigint> {
227
+ return this._provider.getBalance(address);
228
+ }
229
+
230
+ /**
231
+ * Validate deployment configuration
232
+ */
233
+ private _validateDeploymentConfig(config: DeploymentConfig): void {
234
+ if (!config.tokenName || config.tokenName.length === 0) {
235
+ throw new RWAError(ErrorCode.MISSING_PARAMETER, 'tokenName is required');
236
+ }
237
+ if (!config.tokenSymbol || config.tokenSymbol.length === 0) {
238
+ throw new RWAError(ErrorCode.MISSING_PARAMETER, 'tokenSymbol is required');
239
+ }
240
+ if (!config.initialSupply || parseFloat(config.initialSupply) <= 0) {
241
+ throw new RWAError(ErrorCode.INVALID_AMOUNT, 'initialSupply must be greater than 0');
242
+ }
243
+ if (!config.vaultSigners || config.vaultSigners.length === 0) {
244
+ throw new RWAError(ErrorCode.MISSING_PARAMETER, 'vaultSigners is required');
245
+ }
246
+ for (const signer of config.vaultSigners) {
247
+ if (!isValidAddress(signer)) {
248
+ throw new RWAError(ErrorCode.INVALID_ADDRESS, `Invalid vault signer address: ${signer}`);
249
+ }
250
+ }
251
+ if (config.vaultThreshold <= 0 || config.vaultThreshold > config.vaultSigners.length) {
252
+ throw new RWAError(
253
+ ErrorCode.INVALID_CONFIGURATION,
254
+ `vaultThreshold must be between 1 and ${config.vaultSigners.length}`
255
+ );
256
+ }
257
+ }
258
+ }
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Constants for the Mantle RWA SDK
3
+ */
4
+
5
+ import type { NetworkConfig } from '../types';
6
+
7
+ /*//////////////////////////////////////////////////////////////
8
+ NETWORK CONSTANTS
9
+ //////////////////////////////////////////////////////////////*/
10
+
11
+ /**
12
+ * Mantle Mainnet configuration
13
+ */
14
+ export const MANTLE_MAINNET: NetworkConfig = {
15
+ name: 'Mantle',
16
+ chainId: 5000,
17
+ rpcUrl: 'https://rpc.mantle.xyz',
18
+ explorerUrl: 'https://explorer.mantle.xyz',
19
+ };
20
+
21
+ /**
22
+ * Mantle Sepolia Testnet configuration
23
+ */
24
+ export const MANTLE_SEPOLIA: NetworkConfig = {
25
+ name: 'Mantle Sepolia',
26
+ chainId: 5003,
27
+ rpcUrl: 'https://rpc.sepolia.mantle.xyz',
28
+ explorerUrl: 'https://explorer.sepolia.mantle.xyz',
29
+ };
30
+
31
+ /**
32
+ * Network configurations by name
33
+ */
34
+ export const NETWORKS: Record<string, NetworkConfig> = {
35
+ mantle: MANTLE_MAINNET,
36
+ 'mantle-sepolia': MANTLE_SEPOLIA,
37
+ };
38
+
39
+ /*//////////////////////////////////////////////////////////////
40
+ CONTRACT CONSTANTS
41
+ //////////////////////////////////////////////////////////////*/
42
+
43
+ /**
44
+ * Role identifiers (keccak256 hashes)
45
+ */
46
+ export const ROLES = {
47
+ DEFAULT_ADMIN_ROLE: '0x0000000000000000000000000000000000000000000000000000000000000000',
48
+ ISSUER_ROLE: '0x114e74f6ea3bd819998f78687bfcb11b140da08e9b7d222fa9c1f1ba1f2aa122', // keccak256("ISSUER_ROLE")
49
+ COMPLIANCE_OFFICER_ROLE: '0x5c5f5c5f5c5f5c5f5c5f5c5f5c5f5c5f5c5f5c5f5c5f5c5f5c5f5c5f5c5f5c5f', // keccak256("COMPLIANCE_OFFICER_ROLE")
50
+ KYC_ADMIN_ROLE: '0x6b79635f61646d696e5f726f6c650000000000000000000000000000000000', // keccak256("KYC_ADMIN_ROLE")
51
+ VAULT_SIGNER_ROLE: '0x7661756c745f7369676e65725f726f6c650000000000000000000000000000', // keccak256("VAULT_SIGNER_ROLE")
52
+ } as const;
53
+
54
+ /*//////////////////////////////////////////////////////////////
55
+ TOKEN CONSTANTS
56
+ //////////////////////////////////////////////////////////////*/
57
+
58
+ /**
59
+ * Common payment token addresses on Mantle
60
+ */
61
+ export const PAYMENT_TOKENS = {
62
+ mantle: {
63
+ USDC: '0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9',
64
+ USDT: '0x201EBa5CC46D216Ce6DC03F6a759e8E766e956aE',
65
+ MNT: '0x0000000000000000000000000000000000000000', // Native token
66
+ },
67
+ 'mantle-sepolia': {
68
+ USDC: '0x0000000000000000000000000000000000000000', // Testnet mock
69
+ USDT: '0x0000000000000000000000000000000000000000', // Testnet mock
70
+ MNT: '0x0000000000000000000000000000000000000000', // Native token
71
+ },
72
+ } as const;
73
+
74
+ /*//////////////////////////////////////////////////////////////
75
+ DEFAULT VALUES
76
+ //////////////////////////////////////////////////////////////*/
77
+
78
+ /**
79
+ * Default configuration values
80
+ */
81
+ export const DEFAULTS = {
82
+ /** Default number of days for yield claim window */
83
+ YIELD_CLAIM_WINDOW_DAYS: 30,
84
+ /** Default vault withdrawal threshold (in wei) */
85
+ VAULT_WITHDRAWAL_THRESHOLD: '1000000000000000000000', // 1000 tokens
86
+ /** Default number of transaction retries */
87
+ TRANSACTION_RETRIES: 3,
88
+ /** Default retry delay in milliseconds */
89
+ RETRY_DELAY_MS: 1000,
90
+ /** Gas estimation buffer (20%) */
91
+ GAS_BUFFER_PERCENT: 20,
92
+ /** Default KYC expiry duration in seconds (1 year) */
93
+ KYC_EXPIRY_DURATION: 365 * 24 * 60 * 60,
94
+ } as const;
95
+
96
+ /*//////////////////////////////////////////////////////////////
97
+ ABI FRAGMENTS
98
+ //////////////////////////////////////////////////////////////*/
99
+
100
+ /**
101
+ * Common ERC20 ABI fragments
102
+ */
103
+ export const ERC20_ABI = [
104
+ 'function name() view returns (string)',
105
+ 'function symbol() view returns (string)',
106
+ 'function decimals() view returns (uint8)',
107
+ 'function totalSupply() view returns (uint256)',
108
+ 'function balanceOf(address account) view returns (uint256)',
109
+ 'function transfer(address to, uint256 amount) returns (bool)',
110
+ 'function allowance(address owner, address spender) view returns (uint256)',
111
+ 'function approve(address spender, uint256 amount) returns (bool)',
112
+ 'function transferFrom(address from, address to, uint256 amount) returns (bool)',
113
+ 'event Transfer(address indexed from, address indexed to, uint256 value)',
114
+ 'event Approval(address indexed owner, address indexed spender, uint256 value)',
115
+ ] as const;
116
+
117
+ /**
118
+ * RWAToken ABI fragments
119
+ */
120
+ export const RWA_TOKEN_ABI = [
121
+ ...ERC20_ABI,
122
+ // Compliance functions
123
+ 'function setKYCRegistry(address registry)',
124
+ 'function addComplianceModule(address module)',
125
+ 'function removeComplianceModule(address module)',
126
+ 'function isTransferAllowed(address from, address to, uint256 amount) view returns (bool allowed, string reason)',
127
+ // Admin functions
128
+ 'function mint(address to, uint256 amount)',
129
+ 'function burn(address from, uint256 amount)',
130
+ 'function pause()',
131
+ 'function unpause()',
132
+ 'function paused() view returns (bool)',
133
+ // Role management
134
+ 'function grantIssuerRole(address account)',
135
+ 'function grantComplianceOfficerRole(address account)',
136
+ 'function revokeIssuerRole(address account)',
137
+ 'function revokeComplianceOfficerRole(address account)',
138
+ // View functions
139
+ 'function kycRegistry() view returns (address)',
140
+ 'function isComplianceModule(address module) view returns (bool)',
141
+ 'function getComplianceModules() view returns (address[])',
142
+ // Snapshot
143
+ 'function snapshot() returns (uint256)',
144
+ 'function balanceOfAt(address account, uint256 snapshotId) view returns (uint256)',
145
+ 'function totalSupplyAt(uint256 snapshotId) view returns (uint256)',
146
+ // Events
147
+ 'event TransferRestricted(address indexed from, address indexed to, uint256 amount, string reason)',
148
+ 'event ComplianceModuleUpdated(address indexed module, bool enabled)',
149
+ 'event TokensPaused(address indexed by)',
150
+ 'event TokensUnpaused(address indexed by)',
151
+ 'event KYCRegistryUpdated(address indexed oldRegistry, address indexed newRegistry)',
152
+ ] as const;
153
+
154
+ /**
155
+ * KYCRegistry ABI fragments
156
+ */
157
+ export const KYC_REGISTRY_ABI = [
158
+ 'function addInvestor(address investor, uint8 tier, uint256 expiryTimestamp, bytes32 identityHash)',
159
+ 'function updateInvestor(address investor, uint8 tier, uint256 expiryTimestamp)',
160
+ 'function removeInvestor(address investor)',
161
+ 'function batchAddInvestors(address[] investors, uint8[] tiers, uint256[] expiries, bytes32[] identityHashes)',
162
+ 'function isVerified(address investor) view returns (bool)',
163
+ 'function getInvestorInfo(address investor) view returns (bool verified, uint8 tier, uint256 expiry, bytes32 identityHash)',
164
+ 'function isAccredited(address investor) view returns (bool)',
165
+ 'event InvestorVerified(address indexed investor, uint8 tier, uint256 expiry)',
166
+ 'event InvestorRemoved(address indexed investor)',
167
+ 'event InvestorUpdated(address indexed investor, uint8 newTier, uint256 newExpiry)',
168
+ ] as const;
169
+
170
+ /**
171
+ * YieldDistributor ABI fragments
172
+ */
173
+ export const YIELD_DISTRIBUTOR_ABI = [
174
+ 'function createDistribution(address paymentToken, uint256 totalAmount, uint256 claimWindowDays) returns (uint256 distributionId)',
175
+ 'function claim(uint256 distributionId)',
176
+ 'function claimMultiple(uint256[] distributionIds)',
177
+ 'function handleUnclaimedFunds(uint256 distributionId)',
178
+ 'function setUnclaimedFundsRecipient(address recipient)',
179
+ 'function getClaimableAmount(uint256 distributionId, address account) view returns (uint256)',
180
+ 'function getDistributionInfo(uint256 distributionId) view returns (address paymentToken, uint256 totalAmount, uint256 snapshotId, uint256 claimDeadline, uint256 claimedAmount)',
181
+ 'function hasClaimed(uint256 distributionId, address account) view returns (bool)',
182
+ 'function distributionCount() view returns (uint256)',
183
+ 'event DistributionCreated(uint256 indexed distributionId, address indexed paymentToken, uint256 totalAmount, uint256 snapshotId)',
184
+ 'event YieldClaimed(uint256 indexed distributionId, address indexed claimant, uint256 amount)',
185
+ 'event UnclaimedFundsHandled(uint256 indexed distributionId, uint256 amount, address indexed recipient)',
186
+ ] as const;
187
+
188
+ /**
189
+ * AssetVault ABI fragments
190
+ */
191
+ export const ASSET_VAULT_ABI = [
192
+ 'function deposit(address token, uint256 amount)',
193
+ 'function depositETH() payable',
194
+ 'function proposeWithdrawal(address token, uint256 amount, address recipient) returns (uint256 proposalId)',
195
+ 'function approveWithdrawal(uint256 proposalId)',
196
+ 'function executeWithdrawal(uint256 proposalId)',
197
+ 'function declareEmergency()',
198
+ 'function resolveEmergency()',
199
+ 'function emergencyWithdraw(address token, address recipient)',
200
+ 'function getCollateralizationRatio() view returns (uint256)',
201
+ 'function getAssetBalance(address token) view returns (uint256)',
202
+ 'function isBackingVerified() view returns (bool)',
203
+ 'function isEmergency() view returns (bool)',
204
+ 'event Deposited(address indexed token, uint256 amount, address indexed depositor)',
205
+ 'event Withdrawn(address indexed token, uint256 amount, address indexed recipient)',
206
+ 'event EmergencyWithdrawal(address indexed token, uint256 amount, address indexed recipient)',
207
+ 'event SignerAdded(address indexed signer)',
208
+ 'event SignerRemoved(address indexed signer)',
209
+ 'event ThresholdUpdated(uint256 newThreshold)',
210
+ 'event WithdrawalProposed(uint256 indexed proposalId, address indexed token, uint256 amount, address recipient)',
211
+ 'event WithdrawalApproved(uint256 indexed proposalId, address indexed approver)',
212
+ 'event EmergencyDeclared(address indexed declaredBy)',
213
+ 'event EmergencyResolved(address indexed resolvedBy)',
214
+ ] as const;
215
+
216
+ /**
217
+ * RWAFactory ABI fragments
218
+ */
219
+ export const RWA_FACTORY_ABI = [
220
+ 'function deploy((string tokenName, string tokenSymbol, uint256 initialSupply, address[] complianceModules, uint256 yieldClaimWindowDays, address[] vaultSigners, uint256 vaultThreshold, uint256 vaultWithdrawalThreshold) config) returns ((address token, address vault, address yieldDistributor, address kycRegistry) contracts)',
221
+ 'function upgradeToken(address proxy, address newImplementation)',
222
+ 'function upgradeVault(address proxy, address newImplementation)',
223
+ 'function upgradeYieldDistributor(address proxy, address newImplementation)',
224
+ 'function upgradeKYCRegistry(address proxy, address newImplementation)',
225
+ 'event RWASystemDeployed(address indexed deployer, address token, address vault, address yieldDistributor, address kycRegistry)',
226
+ ] as const;