@sudobility/contracts 0.14.0 → 1.9.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 (110) hide show
  1. package/README.md +2 -3
  2. package/artifacts/contracts/Mailer.sol/Mailer.dbg.json +1 -1
  3. package/artifacts/contracts/Mailer.sol/Mailer.json +2 -278
  4. package/artifacts/contracts/MockUSDC.sol/MockUSDC.dbg.json +1 -1
  5. package/artifacts/contracts/interfaces/IERC20.sol/IERC20.dbg.json +1 -1
  6. package/dist/evm/src/evm/index.d.ts +1 -1
  7. package/dist/evm/src/evm/index.d.ts.map +1 -1
  8. package/dist/evm/src/evm/index.js +1 -1
  9. package/dist/evm/src/evm/index.js.map +1 -1
  10. package/dist/evm/src/evm/mailer-client.d.ts +180 -936
  11. package/dist/evm/src/evm/mailer-client.d.ts.map +1 -1
  12. package/dist/evm/src/evm/mailer-client.js +249 -451
  13. package/dist/evm/src/evm/mailer-client.js.map +1 -1
  14. package/dist/evm/typechain-types/Mailer.d.ts +10 -177
  15. package/dist/evm/typechain-types/Mailer.d.ts.map +1 -1
  16. package/dist/evm/typechain-types/factories/Mailer__factory.d.ts +1 -216
  17. package/dist/evm/typechain-types/factories/Mailer__factory.d.ts.map +1 -1
  18. package/dist/evm/typechain-types/factories/Mailer__factory.js +1 -277
  19. package/dist/evm/typechain-types/factories/Mailer__factory.js.map +1 -1
  20. package/dist/solana/solana/index.d.ts +1 -1
  21. package/dist/solana/solana/index.d.ts.map +1 -1
  22. package/dist/solana/solana/index.js +1 -3
  23. package/dist/solana/solana/index.js.map +1 -1
  24. package/dist/solana/solana/mailer-client.d.ts +18 -91
  25. package/dist/solana/solana/mailer-client.d.ts.map +1 -1
  26. package/dist/solana/solana/mailer-client.js +55 -316
  27. package/dist/solana/solana/mailer-client.js.map +1 -1
  28. package/dist/unified/src/evm/index.d.ts +1 -1
  29. package/dist/unified/src/evm/index.d.ts.map +1 -1
  30. package/dist/unified/src/evm/index.js +1 -1
  31. package/dist/unified/src/evm/index.js.map +1 -1
  32. package/dist/unified/src/evm/mailer-client.d.ts +180 -936
  33. package/dist/unified/src/evm/mailer-client.d.ts.map +1 -1
  34. package/dist/unified/src/evm/mailer-client.js +249 -451
  35. package/dist/unified/src/evm/mailer-client.js.map +1 -1
  36. package/dist/unified/src/react/hooks/useMailerMutations.d.ts +1 -1
  37. package/dist/unified/src/react/hooks/useMailerMutations.js +1 -1
  38. package/dist/unified/src/solana/index.d.ts +1 -1
  39. package/dist/unified/src/solana/index.d.ts.map +1 -1
  40. package/dist/unified/src/solana/index.js +1 -3
  41. package/dist/unified/src/solana/index.js.map +1 -1
  42. package/dist/unified/src/solana/mailer-client.d.ts +18 -91
  43. package/dist/unified/src/solana/mailer-client.d.ts.map +1 -1
  44. package/dist/unified/src/solana/mailer-client.js +55 -316
  45. package/dist/unified/src/solana/mailer-client.js.map +1 -1
  46. package/dist/unified/src/unified/index.d.ts +1 -1
  47. package/dist/unified/src/unified/index.d.ts.map +1 -1
  48. package/dist/unified/src/unified/onchain-mailer-client.d.ts +251 -111
  49. package/dist/unified/src/unified/onchain-mailer-client.d.ts.map +1 -1
  50. package/dist/unified/src/unified/onchain-mailer-client.js +1375 -744
  51. package/dist/unified/src/unified/onchain-mailer-client.js.map +1 -1
  52. package/dist/unified/src/unified/types.d.ts +6 -16
  53. package/dist/unified/src/unified/types.d.ts.map +1 -1
  54. package/dist/unified/src/utils/chain-config.d.ts +2 -4
  55. package/dist/unified/src/utils/chain-config.d.ts.map +1 -1
  56. package/dist/unified/src/utils/chain-config.js +36 -46
  57. package/dist/unified/src/utils/chain-config.js.map +1 -1
  58. package/dist/unified/typechain-types/Mailer.d.ts +10 -177
  59. package/dist/unified/typechain-types/Mailer.d.ts.map +1 -1
  60. package/dist/unified/typechain-types/factories/Mailer__factory.d.ts +1 -216
  61. package/dist/unified/typechain-types/factories/Mailer__factory.d.ts.map +1 -1
  62. package/dist/unified/typechain-types/factories/Mailer__factory.js +1 -277
  63. package/dist/unified/typechain-types/factories/Mailer__factory.js.map +1 -1
  64. package/dist/unified-esm/src/evm/index.d.ts +1 -1
  65. package/dist/unified-esm/src/evm/index.d.ts.map +1 -1
  66. package/dist/unified-esm/src/evm/index.js +1 -1
  67. package/dist/unified-esm/src/evm/index.js.map +1 -1
  68. package/dist/unified-esm/src/evm/mailer-client.d.ts +180 -936
  69. package/dist/unified-esm/src/evm/mailer-client.d.ts.map +1 -1
  70. package/dist/unified-esm/src/evm/mailer-client.js +251 -453
  71. package/dist/unified-esm/src/evm/mailer-client.js.map +1 -1
  72. package/dist/unified-esm/src/react/hooks/useMailerMutations.d.ts +1 -1
  73. package/dist/unified-esm/src/react/hooks/useMailerMutations.js +1 -1
  74. package/dist/unified-esm/src/solana/index.d.ts +1 -1
  75. package/dist/unified-esm/src/solana/index.d.ts.map +1 -1
  76. package/dist/unified-esm/src/solana/index.js +1 -1
  77. package/dist/unified-esm/src/solana/index.js.map +1 -1
  78. package/dist/unified-esm/src/solana/mailer-client.d.ts +18 -91
  79. package/dist/unified-esm/src/solana/mailer-client.d.ts.map +1 -1
  80. package/dist/unified-esm/src/solana/mailer-client.js +56 -317
  81. package/dist/unified-esm/src/solana/mailer-client.js.map +1 -1
  82. package/dist/unified-esm/src/unified/index.d.ts +1 -1
  83. package/dist/unified-esm/src/unified/index.d.ts.map +1 -1
  84. package/dist/unified-esm/src/unified/onchain-mailer-client.d.ts +251 -111
  85. package/dist/unified-esm/src/unified/onchain-mailer-client.d.ts.map +1 -1
  86. package/dist/unified-esm/src/unified/onchain-mailer-client.js +1379 -748
  87. package/dist/unified-esm/src/unified/onchain-mailer-client.js.map +1 -1
  88. package/dist/unified-esm/src/unified/types.d.ts +6 -16
  89. package/dist/unified-esm/src/unified/types.d.ts.map +1 -1
  90. package/dist/unified-esm/src/utils/chain-config.d.ts +2 -4
  91. package/dist/unified-esm/src/utils/chain-config.d.ts.map +1 -1
  92. package/dist/unified-esm/src/utils/chain-config.js +35 -46
  93. package/dist/unified-esm/src/utils/chain-config.js.map +1 -1
  94. package/dist/unified-esm/typechain-types/Mailer.d.ts +10 -177
  95. package/dist/unified-esm/typechain-types/Mailer.d.ts.map +1 -1
  96. package/dist/unified-esm/typechain-types/factories/Mailer__factory.d.ts +1 -216
  97. package/dist/unified-esm/typechain-types/factories/Mailer__factory.d.ts.map +1 -1
  98. package/dist/unified-esm/typechain-types/factories/Mailer__factory.js +1 -277
  99. package/dist/unified-esm/typechain-types/factories/Mailer__factory.js.map +1 -1
  100. package/package.json +9 -20
  101. package/programs/mailer/src/lib.rs +171 -1026
  102. package/programs/mailer/tests/integration_tests.rs +65 -586
  103. package/typechain-types/Mailer.ts +8 -319
  104. package/typechain-types/factories/Mailer__factory.ts +1 -277
  105. package/artifacts/contracts/Mailer.sol/Mailer.d.ts +0 -1146
  106. package/artifacts/contracts/Mailer.sol/artifacts.d.ts +0 -21
  107. package/artifacts/contracts/MockUSDC.sol/MockUSDC.d.ts +0 -284
  108. package/artifacts/contracts/MockUSDC.sol/artifacts.d.ts +0 -21
  109. package/artifacts/contracts/interfaces/IERC20.sol/IERC20.d.ts +0 -157
  110. package/artifacts/contracts/interfaces/IERC20.sol/artifacts.d.ts +0 -21
@@ -37,157 +37,226 @@ exports.OnchainMailerClient = void 0;
37
37
  /* eslint-disable @typescript-eslint/ban-ts-comment */
38
38
  // @ts-nocheck - Suppress false TypeScript errors with ESNext modules accessing class properties
39
39
  const types_1 = require("@sudobility/types");
40
+ const wallet_detector_js_1 = require("./wallet-detector");
40
41
  /**
41
- * OnchainMailerClient v2 - Refactored to use standard wallet libraries
42
+ * OnchainMailerClient - Multi-chain messaging client for Mailer protocol
42
43
  *
43
- * This version removes the UnifiedWallet abstraction and instead accepts
44
- * standard wallet clients from wagmi (EVM) or wallet-adapter (Solana).
44
+ * This class provides a unified interface for interacting with Mailer contracts
45
+ * across different blockchain networks (EVM and Solana). It automatically detects
46
+ * wallet types and routes operations to the appropriate chain implementation.
45
47
  *
46
- * @example EVM Usage with wagmi
48
+ * @example Basic Usage
47
49
  * ```typescript
48
- * import { createWalletClient, createPublicClient, http } from 'viem';
49
- * import { mainnet } from 'viem/chains';
50
+ * // EVM wallet (MetaMask, etc.)
51
+ * const evmWallet = window.ethereum;
52
+ * const evmConfig = {
53
+ * evm: {
54
+ * rpc: 'https://eth-mainnet.alchemyapi.io/v2/your-key',
55
+ * chainId: 1,
56
+ * contracts: {
57
+ * mailer: '0x456...',
58
+ * usdc: '0x789...'
59
+ * }
60
+ * }
61
+ * };
62
+ * const evmClient = new OnchainMailerClient(evmWallet, evmConfig);
50
63
  *
51
- * const walletClient = createWalletClient({
52
- * chain: mainnet,
53
- * transport: http()
54
- * });
55
- * const publicClient = createPublicClient({
56
- * chain: mainnet,
57
- * transport: http()
58
- * });
64
+ * // Solana wallet (Phantom, etc.)
65
+ * const solanaWallet = window.solana;
66
+ * const solanaConfig = {
67
+ * solana: {
68
+ * rpc: 'https://api.mainnet-beta.solana.com',
69
+ * programs: {
70
+ * mailer: '9FLkBDGpZBcR8LMsQ7MwwV6X9P4TDFgN3DeRh5qYyHJF'
71
+ * },
72
+ * usdcMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'
73
+ * }
74
+ * };
75
+ * const solanaClient = new OnchainMailerClient(solanaWallet, solanaConfig);
59
76
  *
60
- * const client = OnchainMailerClient.forEVM(
61
- * walletClient,
62
- * publicClient,
63
- * '0xMailerContractAddress',
64
- * '0xUSDCAddress'
65
- * );
77
+ * // Send messages
78
+ * const result = await client.sendMessage("Hello", "World!", false);
79
+ * console.log('Transaction:', result.transactionHash);
66
80
  * ```
67
81
  *
68
- * @example Solana Usage with wallet-adapter
82
+ * @example Error Handling
69
83
  * ```typescript
70
- * import { useWallet } from '@solana/wallet-adapter-react';
71
- * import { Connection } from '@solana/web3.js';
72
- *
73
- * const wallet = useWallet();
74
- * const connection = new Connection('https://api.mainnet-beta.solana.com');
75
- *
76
- * const client = OnchainMailerClient.forSolana(
77
- * wallet,
78
- * connection,
79
- * 'MailerProgramId',
80
- * 'USDCMintAddress'
81
- * );
84
+ * try {
85
+ * const result = await client.sendMessage("Subject", "Body", true);
86
+ * console.log('Success:', result);
87
+ * } catch (error) {
88
+ * if (error.message.includes('insufficient funds')) {
89
+ * console.log('User needs more USDC');
90
+ * } else if (error.message.includes('user rejected')) {
91
+ * console.log('User cancelled transaction');
92
+ * } else {
93
+ * console.log('Unknown error:', error);
94
+ * }
95
+ * }
82
96
  * ```
97
+ *
98
+ * @author Mailer Protocol Team
99
+ * @version 1.5.2
100
+ * @since 1.0.0
83
101
  */
84
102
  class OnchainMailerClient {
85
103
  /**
86
- * Create an OnchainMailerClient for EVM chains using wagmi clients
104
+ * Initialize OnchainMailerClient with wallet and chain configuration
87
105
  *
88
- * @param walletClient - wagmi WalletClient for signing transactions
89
- * @param publicClient - wagmi PublicClient for reading chain data
90
- * @param mailerAddress - Deployed Mailer contract address
91
- * @param usdcAddress - USDC token contract address
92
- * @returns Configured OnchainMailerClient for EVM
93
- */
94
- static forEVM(walletClient, publicClient, mailerAddress, usdcAddress) {
95
- const client = new OnchainMailerClient({}, { evm: undefined, solana: undefined });
96
- client.chainType = types_1.ChainType.EVM;
97
- client.evmWalletClient = walletClient;
98
- client.evmPublicClient = publicClient;
99
- client.evmContractAddress = mailerAddress;
100
- client.evmUsdcAddress = usdcAddress;
101
- return client;
102
- }
103
- /**
104
- * Create an OnchainMailerClient for Solana using wallet-adapter
106
+ * @param wallet - Wallet instance (EVM or Solana compatible)
107
+ * @param config - Chain configuration for EVM and/or Solana networks
105
108
  *
106
- * @param wallet - Solana wallet adapter
107
- * @param connection - Solana connection
108
- * @param programId - Deployed Mailer program ID
109
- * @param usdcMint - USDC mint address
110
- * @returns Configured OnchainMailerClient for Solana
111
- */
112
- static forSolana(
113
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
114
- wallet, // Wallet adapter interface
115
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
116
- connection, // Connection
117
- programId, usdcMint) {
118
- const client = new OnchainMailerClient({}, { evm: undefined, solana: undefined });
119
- client.chainType = types_1.ChainType.SOLANA;
120
- client.solanaWallet = wallet;
121
- client.solanaConnection = connection;
122
- client.solanaProgramId = programId;
123
- client.solanaUsdcMint = usdcMint;
124
- return client;
125
- }
126
- /**
127
- * Create an OnchainMailerClient from a generic config (backward compatibility)
128
- * This constructor is provided for backward compatibility with React provider
109
+ * @throws {Error} When wallet type cannot be detected
110
+ * @throws {Error} When required configuration is missing
111
+ * @throws {Error} When wallet doesn't implement required methods
112
+ *
113
+ * @example
114
+ * ```typescript
115
+ * // EVM wallet initialization
116
+ * const wallet = window.ethereum;
117
+ * const config = {
118
+ * evm: { rpc: '...', chainId: 1, contracts: {...} }
119
+ * };
120
+ * const client = new OnchainMailerClient(wallet, config);
121
+ * ```
129
122
  */
130
123
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
131
124
  constructor(wallet, config) {
132
- // Simple chain detection based on wallet properties
133
- const hasEthereumProperties = wallet && (wallet.address || wallet.request || wallet.selectedAddress);
134
- const hasSolanaProperties = wallet && wallet.publicKey && typeof wallet.signTransaction === 'function';
135
- if (hasEthereumProperties) {
136
- this.chainType = types_1.ChainType.EVM;
137
- if (config.evm) {
138
- // Store config for lazy initialization
139
- this.evmContractAddress = config.evm.contracts.mailer;
140
- this.evmUsdcAddress = config.evm.contracts.usdc;
141
- // Wallet and public clients will be created on first use
142
- // Store raw wallet for backward compatibility
143
- // @ts-ignore
144
- this._rawEvmWallet = wallet;
125
+ try {
126
+ // Automatically detect whether this is an EVM or Solana wallet
127
+ this.chainType = wallet_detector_js_1.WalletDetector.detectWalletType(wallet);
128
+ // Normalize wallet interface for internal use
129
+ this.wallet = {
130
+ address: wallet.address || wallet.publicKey?.toString() || '',
131
+ chainType: this.chainType,
132
+ signTransaction: wallet.signTransaction?.bind(wallet),
133
+ publicKey: wallet.publicKey?.toString()
134
+ };
135
+ this.config = config;
136
+ // Ensure we have valid configuration for the detected chain type
137
+ this.validateConfiguration();
138
+ // Ensure wallet implements required methods for its chain type
139
+ this.validateWallet(wallet);
140
+ }
141
+ catch (error) {
142
+ throw new Error(`OnchainMailerClient initialization failed: ${error instanceof Error ? error.message : String(error)}`);
143
+ }
144
+ }
145
+ validateConfiguration() {
146
+ if (this.chainType === 'evm' && !this.config.evm) {
147
+ throw new Error('EVM configuration required for EVM wallet');
148
+ }
149
+ if (this.chainType === 'solana' && !this.config.solana) {
150
+ throw new Error('Solana configuration required for Solana wallet');
151
+ }
152
+ // Validate EVM configuration
153
+ if (this.config.evm) {
154
+ if (!this.config.evm.rpc || !this.config.evm.chainId) {
155
+ throw new Error('EVM configuration missing required fields (rpc, chainId)');
145
156
  }
146
- else {
147
- throw new Error('EVM configuration required for EVM wallet');
157
+ if (!this.config.evm.contracts || !this.config.evm.contracts.mailer) {
158
+ console.warn('EVM contract addresses not configured - some functionality may fail');
148
159
  }
149
160
  }
150
- else if (hasSolanaProperties) {
151
- this.chainType = types_1.ChainType.SOLANA;
152
- if (config.solana) {
153
- this.solanaWallet = wallet;
154
- // Connection will be created on first use
155
- this.solanaProgramId = config.solana.programs.mailer;
156
- this.solanaUsdcMint = config.solana.usdcMint;
161
+ // Validate Solana configuration
162
+ if (this.config.solana) {
163
+ if (!this.config.solana.rpc || !this.config.solana.usdcMint) {
164
+ throw new Error('Solana configuration missing required fields (rpc, usdcMint)');
157
165
  }
158
- else {
159
- throw new Error('Solana configuration required for Solana wallet');
166
+ if (!this.config.solana.programs || !this.config.solana.programs.mailer) {
167
+ console.warn('Solana program addresses not configured - some functionality may fail');
160
168
  }
161
169
  }
162
- else {
163
- throw new Error('Unable to detect wallet type from provided wallet object');
170
+ }
171
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
172
+ validateWallet(wallet) {
173
+ if (!wallet.signTransaction && typeof wallet.signTransaction !== 'function') {
174
+ throw new Error('Wallet must have signTransaction method');
175
+ }
176
+ if (this.chainType === 'evm' && !wallet.address) {
177
+ throw new Error('EVM wallet must have address property');
178
+ }
179
+ if (this.chainType === 'solana' && !wallet.publicKey) {
180
+ throw new Error('Solana wallet must have publicKey property');
164
181
  }
165
182
  }
166
183
  /**
167
184
  * Send a message using the appropriate chain implementation
168
- * Note: For backward compatibility, 'to' defaults to sender's own address
185
+ *
186
+ * This method automatically routes to EVM or Solana based on the detected wallet type.
187
+ * Priority messages cost more but include revenue sharing for recipients.
188
+ *
189
+ * @param subject - Message subject (1-200 characters)
190
+ * @param body - Message body (1-10000 characters)
191
+ * @param priority - Whether to use priority sending with revenue share
192
+ * - Priority: Full fee paid, 90% claimable by recipient
193
+ * - Standard: 10% fee only, no revenue share
194
+ * @param resolveSenderToName - If true, resolve sender address to name via off-chain service
195
+ *
196
+ * @returns Promise resolving to MessageResult with transaction details
197
+ *
198
+ * @throws {Error} When subject/body validation fails
199
+ * @throws {Error} When insufficient USDC balance
200
+ * @throws {Error} When user rejects transaction
201
+ * @throws {Error} When network connection fails
202
+ *
203
+ * @example Standard Message
204
+ * ```typescript
205
+ * const result = await client.sendMessage(
206
+ * "Meeting Reminder",
207
+ * "Don't forget our 3pm call today!",
208
+ * false, // Standard fee (10% of sendFee)
209
+ * false // Don't resolve sender to name
210
+ * );
211
+ * console.log('Sent in tx:', result.transactionHash);
212
+ * ```
213
+ *
214
+ * @example Priority Message with Revenue Share
215
+ * ```typescript
216
+ * const result = await client.sendMessage(
217
+ * "Important Update",
218
+ * "Urgent: Please review the attached proposal",
219
+ * true, // Priority fee (100% paid, 90% claimable by recipient)
220
+ * true // Resolve sender to name
221
+ * );
222
+ * console.log('Priority message fee:', result.fee);
223
+ * ```
169
224
  */
170
- async sendMessage(subject, body, priority = false, resolveSenderToName = false, to) {
171
- // For backward compatibility, default to sending to self
172
- const recipient = to || await this.getWalletAddressAsync();
173
- if (this.chainType === types_1.ChainType.EVM) {
174
- return this.sendEVMMessage(recipient, subject, body, priority, resolveSenderToName);
225
+ async sendMessage(subject, body, priority = false, resolveSenderToName = false) {
226
+ // Route to appropriate chain implementation based on wallet type
227
+ if (this.chainType === 'evm') {
228
+ return this.sendEVMMessage(subject, body, priority, resolveSenderToName);
175
229
  }
176
230
  else {
177
- return this.sendSolanaMessage(recipient, subject, body, priority, resolveSenderToName);
231
+ return this.sendSolanaMessage(subject, body, priority, resolveSenderToName);
178
232
  }
179
233
  }
180
234
  /**
181
- * Register a domain (not implemented - for backward compatibility)
235
+ * Register a domain using the appropriate chain implementation
236
+ * @param domain - Domain name to register
237
+ * @param isExtension - Whether this is extending an existing domain
238
+ * @returns Domain registration result
182
239
  */
183
- async registerDomain(_domain) {
184
- throw new Error('Domain registration not yet implemented');
240
+ async registerDomain(domain, isExtension = false) {
241
+ if (this.chainType === 'evm') {
242
+ return this.registerEVMDomain(domain, isExtension);
243
+ }
244
+ else {
245
+ return this.registerSolanaDomain(domain, isExtension);
246
+ }
185
247
  }
186
248
  /**
187
- * Delegate to another address
249
+ * Delegate to another address using the appropriate chain implementation
250
+ * @param delegate - Address to delegate to
251
+ * @returns Delegation result
188
252
  */
189
253
  async delegateTo(delegate) {
190
- if (this.chainType === types_1.ChainType.EVM) {
254
+ // Validate delegate address format
255
+ const delegateChainType = wallet_detector_js_1.WalletDetector.detectChainFromAddress(delegate);
256
+ if (delegateChainType !== this.chainType) {
257
+ throw new Error(`Delegate address format doesn't match wallet chain type (${this.chainType})`);
258
+ }
259
+ if (this.chainType === 'evm') {
191
260
  return this.delegateEVM(delegate);
192
261
  }
193
262
  else {
@@ -195,10 +264,11 @@ class OnchainMailerClient {
195
264
  }
196
265
  }
197
266
  /**
198
- * Claim revenue share
267
+ * Claim revenue share using the appropriate chain implementation
268
+ * @returns Transaction result
199
269
  */
200
270
  async claimRevenue() {
201
- if (this.chainType === types_1.ChainType.EVM) {
271
+ if (this.chainType === 'evm') {
202
272
  return this.claimEVMRevenue();
203
273
  }
204
274
  else {
@@ -208,799 +278,1385 @@ class OnchainMailerClient {
208
278
  // Performance optimization: cache module imports
209
279
  async getEVMModules() {
210
280
  if (!OnchainMailerClient.evmModules) {
211
- const evmModule = await Promise.resolve().then(() => __importStar(require('../evm/index.js')));
212
- OnchainMailerClient.evmModules = {
213
- MailerClient: evmModule.MailerClient
214
- };
281
+ try {
282
+ const [viemModule, evmModule] = await Promise.all([
283
+ Promise.resolve().then(() => __importStar(require('viem'))),
284
+ Promise.resolve().then(() => __importStar(require('../evm')))
285
+ ]);
286
+ OnchainMailerClient.evmModules = {
287
+ viem: viemModule,
288
+ MailerClient: evmModule.MailerClient
289
+ };
290
+ }
291
+ catch (error) {
292
+ throw new Error(`Failed to load EVM modules: ${error instanceof Error ? error.message : String(error)}`);
293
+ }
215
294
  }
216
295
  return OnchainMailerClient.evmModules;
217
296
  }
218
297
  async getSolanaModules() {
219
298
  if (!OnchainMailerClient.solanaModules) {
220
- const [solanaModule, web3Module] = await Promise.all([
221
- Promise.resolve().then(() => __importStar(require('../solana/index.js'))),
222
- Promise.resolve().then(() => __importStar(require('@solana/web3.js')))
223
- ]);
224
- OnchainMailerClient.solanaModules = {
225
- MailerClient: solanaModule.MailerClient,
226
- PublicKey: web3Module.PublicKey,
227
- Connection: web3Module.Connection
228
- };
299
+ try {
300
+ const [solanaModule, web3Module] = await Promise.all([
301
+ Promise.resolve().then(() => __importStar(require('../solana'))),
302
+ Promise.resolve().then(() => __importStar(require('@solana/web3.js')))
303
+ ]);
304
+ OnchainMailerClient.solanaModules = {
305
+ MailerClient: solanaModule.MailerClient,
306
+ PublicKey: web3Module.PublicKey,
307
+ Connection: web3Module.Connection
308
+ };
309
+ }
310
+ catch (error) {
311
+ throw new Error(`Failed to load Solana modules: ${error instanceof Error ? error.message : String(error)}`);
312
+ }
229
313
  }
230
314
  return OnchainMailerClient.solanaModules;
231
315
  }
232
- // EVM implementation methods
233
- async sendEVMMessage(to, subject, body, priority, resolveSenderToName) {
234
- if (!this.evmWalletClient || !this.evmPublicClient || !this.evmContractAddress) {
235
- throw new Error('EVM client not properly initialized');
236
- }
237
- const { MailerClient } = await this.getEVMModules();
238
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
239
- // Validate message
240
- if (!subject || subject.length > 200) {
241
- throw new Error('Subject must be 1-200 characters');
316
+ // Private methods for EVM implementation
317
+ async sendEVMMessage(subject, body, priority, resolveSenderToName = false) {
318
+ try {
319
+ const { viem, MailerClient } = await this.getEVMModules();
320
+ if (!this.config.evm) {
321
+ throw new Error('EVM configuration not provided');
322
+ }
323
+ if (!this.config.evm.contracts.mailer) {
324
+ throw new Error('EVM Mailer contract address not configured');
325
+ }
326
+ // Create clients
327
+ const publicClient = viem.createPublicClient({
328
+ transport: viem.http(this.config.evm.rpc),
329
+ chain: {
330
+ id: this.config.evm.chainId,
331
+ name: 'Custom Chain',
332
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
333
+ rpcUrls: {
334
+ default: { http: [this.config.evm.rpc] }
335
+ }
336
+ }
337
+ });
338
+ const walletClient = viem.createWalletClient({
339
+ transport: viem.http(this.config.evm.rpc),
340
+ chain: {
341
+ id: this.config.evm.chainId,
342
+ name: 'Custom Chain',
343
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
344
+ rpcUrls: {
345
+ default: { http: [this.config.evm.rpc] }
346
+ }
347
+ }
348
+ });
349
+ // Test connection
350
+ try {
351
+ await Promise.race([
352
+ publicClient.getChainId(),
353
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Connection timeout')), 10000))
354
+ ]);
355
+ }
356
+ catch (error) {
357
+ throw new Error(`Failed to connect to EVM network: ${error instanceof Error ? error.message : String(error)}`);
358
+ }
359
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
360
+ // Validate message before sending
361
+ if (!subject || subject.length > 200) {
362
+ throw new Error('Subject must be 1-200 characters');
363
+ }
364
+ if (!body || body.length > 10000) {
365
+ throw new Error('Body must be 1-10000 characters');
366
+ }
367
+ let txHash;
368
+ try {
369
+ txHash = await client.send(this.wallet.address, subject, body, priority, resolveSenderToName, walletClient, this.wallet.address);
370
+ }
371
+ catch (error) {
372
+ const errorMessage = error instanceof Error ? error.message : String(error);
373
+ if (errorMessage.includes('insufficient funds')) {
374
+ throw new Error('Insufficient USDC balance to send message');
375
+ }
376
+ if (errorMessage.includes('user rejected')) {
377
+ throw new Error('Transaction rejected by user');
378
+ }
379
+ throw new Error(`Transaction failed: ${errorMessage}`);
380
+ }
381
+ // Wait for confirmation with timeout
382
+ const receipt = await Promise.race([
383
+ publicClient.waitForTransactionReceipt({ hash: txHash }),
384
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Transaction confirmation timeout')), 60000))
385
+ ]);
386
+ return {
387
+ transactionHash: txHash,
388
+ chainType: types_1.ChainType.EVM,
389
+ messageId: undefined, // Could extract from logs if needed
390
+ fee: BigInt(priority ? '100000' : '10000'), // 0.1 or 0.01 USDC in micro-USDC
391
+ gasUsed: receipt.gasUsed,
392
+ isPriority: priority,
393
+ success: true
394
+ };
242
395
  }
243
- if (!body || body.length > 10000) {
244
- throw new Error('Body must be 1-10000 characters');
396
+ catch (error) {
397
+ throw new Error(`EVM message sending failed: ${error instanceof Error ? error.message : String(error)}`);
245
398
  }
246
- const [account] = await this.evmWalletClient.getAddresses();
247
- const payer = account;
248
- const result = await client.send(to, subject, body, payer, priority, resolveSenderToName, this.evmWalletClient, account);
249
- // Convert to MessageResult format
250
- return {
251
- transactionHash: result.hash,
252
- chainType: types_1.ChainType.EVM,
253
- fee: BigInt(priority ? '100000' : '10000'),
254
- gasUsed: result.gasUsed,
255
- isPriority: priority,
256
- success: true
257
- };
399
+ }
400
+ async registerEVMDomain(_domain, _isExtension) {
401
+ // Domain registration not implemented in current EVM version (delegation-only)
402
+ throw new Error('Domain registration not yet implemented in EVM version - use delegation instead');
258
403
  }
259
404
  async delegateEVM(delegate) {
260
- if (!this.evmWalletClient || !this.evmPublicClient || !this.evmContractAddress) {
261
- throw new Error('EVM client not properly initialized');
405
+ const { viem } = await this.getEVMModules();
406
+ if (!this.config.evm) {
407
+ throw new Error('EVM configuration not provided');
262
408
  }
263
- const { MailerClient } = await this.getEVMModules();
264
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
265
- const [account] = await this.evmWalletClient.getAddresses();
266
- const result = await client.delegateTo(delegate, this.evmWalletClient, account);
267
- return {
268
- transactionHash: result.hash,
269
- chainType: types_1.ChainType.EVM,
270
- delegate,
271
- success: true
272
- };
409
+ // Validate EVM address format
410
+ if (!viem.isAddress(delegate)) {
411
+ throw new Error('Invalid EVM address format for delegate');
412
+ }
413
+ // Note: Domain functionality is now integrated into the Mailer contract
414
+ throw new Error('Domain delegation is now handled through the Mailer contract - use MailerClient instead');
273
415
  }
274
416
  async claimEVMRevenue() {
275
- if (!this.evmWalletClient || !this.evmPublicClient || !this.evmContractAddress) {
276
- throw new Error('EVM client not properly initialized');
277
- }
278
- const { MailerClient } = await this.getEVMModules();
279
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
280
- const [account] = await this.evmWalletClient.getAddresses();
281
- const result = await client.claimRecipientShare(this.evmWalletClient, account);
417
+ const { viem, MailerClient } = await this.getEVMModules();
418
+ if (!this.config.evm) {
419
+ throw new Error('EVM configuration not provided');
420
+ }
421
+ const publicClient = viem.createPublicClient({
422
+ transport: viem.http(this.config.evm.rpc),
423
+ chain: {
424
+ id: this.config.evm.chainId,
425
+ name: 'Custom Chain',
426
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
427
+ rpcUrls: {
428
+ default: { http: [this.config.evm.rpc] }
429
+ }
430
+ }
431
+ });
432
+ const walletClient = viem.createWalletClient({
433
+ transport: viem.http(this.config.evm.rpc),
434
+ chain: {
435
+ id: this.config.evm.chainId,
436
+ name: 'Custom Chain',
437
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
438
+ rpcUrls: {
439
+ default: { http: [this.config.evm.rpc] }
440
+ }
441
+ }
442
+ });
443
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
444
+ const txHash = await client.claimRecipientShare(walletClient, this.wallet.address);
445
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
446
+ const block = await publicClient.getBlock({ blockNumber: receipt.blockNumber });
282
447
  return {
283
- hash: result.hash,
448
+ hash: txHash,
284
449
  chainType: types_1.ChainType.EVM,
285
- blockNumber: result.blockNumber,
286
- timestamp: Date.now()
450
+ blockNumber: receipt.blockNumber,
451
+ timestamp: Number(block.timestamp) * 1000
287
452
  };
288
453
  }
289
- // Solana implementation methods
290
- async sendSolanaMessage(to, subject, body, priority, resolveSenderToName) {
291
- if (!this.solanaWallet || !this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
292
- throw new Error('Solana client not properly initialized');
293
- }
294
- const { MailerClient, PublicKey } = await this.getSolanaModules();
295
- const programId = new PublicKey(this.solanaProgramId);
296
- const usdcMint = new PublicKey(this.solanaUsdcMint);
297
- const client = new MailerClient(this.solanaConnection, this.solanaWallet, programId, usdcMint);
298
- const result = await client.send(to, subject, body, priority, resolveSenderToName);
299
- // Get current fees
300
- const fees = await client.getFees();
301
- return {
302
- transactionHash: result.signature,
303
- chainType: types_1.ChainType.SOLANA,
304
- fee: priority ? fees.sendFee : fees.sendFee / 10,
305
- isPriority: priority,
306
- success: true
307
- };
454
+ // Private methods for Solana implementation
455
+ async sendSolanaMessage(subject, body, priority, resolveSenderToName = false) {
456
+ try {
457
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
458
+ if (!this.config.solana) {
459
+ throw new Error('Solana configuration not provided');
460
+ }
461
+ if (!this.config.solana.programs.mailer) {
462
+ throw new Error('Solana Mailer program address not configured');
463
+ }
464
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
465
+ // Test connection
466
+ try {
467
+ await Promise.race([
468
+ connection.getSlot(),
469
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Connection timeout')), 10000))
470
+ ]);
471
+ }
472
+ catch (error) {
473
+ throw new Error(`Failed to connect to Solana RPC: ${error instanceof Error ? error.message : String(error)}`);
474
+ }
475
+ // Create wallet adapter for native client
476
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
477
+ const wallet = MailerClient.createWallet(this.wallet);
478
+ const programId = new PublicKey(this.config.solana.programs.mailer);
479
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
480
+ // For now, send to the wallet itself (self-messaging)
481
+ const recipientKey = new PublicKey(this.wallet.address);
482
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
483
+ // Get current fees
484
+ const fees = await client.getFees();
485
+ let txHash;
486
+ txHash = await client.send(recipientKey.toBase58(), subject, body, priority, resolveSenderToName);
487
+ // Get transaction details
488
+ const tx = await connection.getTransaction(txHash, { commitment: 'confirmed', maxSupportedTransactionVersion: 0 });
489
+ // Get current slot for transaction info
490
+ const slot = await connection.getSlot();
491
+ return {
492
+ transactionHash: txHash,
493
+ chainType: types_1.ChainType.SOLANA,
494
+ fee: priority ? fees.sendFee : fees.sendFee / 10,
495
+ recipient: recipientKey.toBase58(),
496
+ subject,
497
+ body,
498
+ slot,
499
+ timestamp: tx?.blockTime ? tx.blockTime * 1000 : Date.now(),
500
+ isPriority: priority,
501
+ success: true
502
+ };
503
+ }
504
+ catch (error) {
505
+ throw new Error(`Solana message sending failed: ${error instanceof Error ? error.message : String(error)}`);
506
+ }
308
507
  }
309
- async delegateSolana(delegate) {
310
- if (!this.solanaWallet || !this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
311
- throw new Error('Solana client not properly initialized');
508
+ async registerSolanaDomain(_domain, _isExtension) {
509
+ // Domain registration not implemented in current Solana version
510
+ throw new Error('Domain registration not yet implemented in Solana version - use delegation instead');
511
+ }
512
+ async delegateSolana(_delegate) {
513
+ if (!this.config.solana) {
514
+ throw new Error('Solana configuration not provided');
312
515
  }
313
- const { MailerClient, PublicKey } = await this.getSolanaModules();
314
- const programId = new PublicKey(this.solanaProgramId);
315
- const usdcMint = new PublicKey(this.solanaUsdcMint);
316
- const client = new MailerClient(this.solanaConnection, this.solanaWallet, programId, usdcMint);
317
- const result = await client.delegateTo(delegate);
318
- return {
319
- transactionHash: result.signature,
320
- chainType: types_1.ChainType.SOLANA,
321
- delegate,
322
- success: true
323
- };
516
+ // Note: Domain functionality is now integrated into the Mailer contract
517
+ throw new Error('Domain delegation is now handled through the Mailer contract - use MailerClient instead');
324
518
  }
325
519
  async claimSolanaRevenue() {
326
- if (!this.solanaWallet || !this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
327
- throw new Error('Solana client not properly initialized');
328
- }
329
- const { MailerClient, PublicKey } = await this.getSolanaModules();
330
- const programId = new PublicKey(this.solanaProgramId);
331
- const usdcMint = new PublicKey(this.solanaUsdcMint);
332
- const client = new MailerClient(this.solanaConnection, this.solanaWallet, programId, usdcMint);
333
- const result = await client.claimRecipientShare();
334
- const slot = await this.solanaConnection.getSlot();
520
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
521
+ if (!this.config.solana) {
522
+ throw new Error('Solana configuration not provided');
523
+ }
524
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
525
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
526
+ const wallet = MailerClient.createWallet(this.wallet);
527
+ const programId = new PublicKey(this.config.solana.programs.mailer);
528
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
529
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
530
+ const txHash = await client.claimRecipientShare();
531
+ const slot = await connection.getSlot();
335
532
  return {
336
- hash: result.signature,
533
+ hash: txHash,
337
534
  chainType: types_1.ChainType.SOLANA,
338
535
  slot,
339
536
  timestamp: Date.now()
340
537
  };
341
538
  }
342
- // Read methods
539
+ /**
540
+ * Get send fee using the appropriate chain implementation
541
+ * @returns Send fee in USDC micro-units (6 decimals)
542
+ */
343
543
  async getSendFee() {
344
- if (this.chainType === types_1.ChainType.EVM) {
544
+ if (this.chainType === 'evm') {
345
545
  return this.getEVMSendFee();
346
546
  }
347
547
  else {
348
548
  return this.getSolanaSendFee();
349
549
  }
350
550
  }
351
- async getEVMSendFee() {
352
- if (!this.evmPublicClient || !this.evmContractAddress) {
353
- throw new Error('EVM client not properly initialized');
354
- }
355
- const { MailerClient } = await this.getEVMModules();
356
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
357
- return client.getSendFee();
358
- }
359
- async getSolanaSendFee() {
360
- if (!this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
361
- throw new Error('Solana client not properly initialized');
362
- }
363
- const { MailerClient, PublicKey } = await this.getSolanaModules();
364
- const programId = new PublicKey(this.solanaProgramId);
365
- const usdcMint = new PublicKey(this.solanaUsdcMint);
366
- // Create a minimal wallet object for reading
367
- const wallet = { publicKey: PublicKey.default, signTransaction: async (tx) => tx };
368
- const client = new MailerClient(this.solanaConnection, wallet, programId, usdcMint);
369
- const fees = await client.getFees();
370
- return BigInt(fees.sendFee);
371
- }
372
- // Additional read methods
551
+ /**
552
+ * Get claimable amount for an address
553
+ * @param address - Address to check claimable balance for (defaults to connected wallet)
554
+ * @returns Claimable amount in USDC micro-units
555
+ */
373
556
  async getClaimableAmount(address) {
374
- const targetAddress = address || await this.getWalletAddressAsync();
375
- if (this.chainType === types_1.ChainType.EVM) {
557
+ const targetAddress = address || this.wallet.address;
558
+ if (this.chainType === 'evm') {
376
559
  return this.getEVMClaimableAmount(targetAddress);
377
560
  }
378
561
  else {
379
562
  return this.getSolanaClaimableAmount(targetAddress);
380
563
  }
381
564
  }
382
- async getEVMClaimableAmount(address) {
383
- if (!this.evmPublicClient || !this.evmContractAddress) {
384
- throw new Error('EVM client not properly initialized');
385
- }
386
- const { MailerClient } = await this.getEVMModules();
387
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
388
- const result = await client.getRecipientClaimable(address);
389
- return result.amount;
390
- }
391
- async getSolanaClaimableAmount(address) {
392
- if (!this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
393
- throw new Error('Solana client not properly initialized');
394
- }
395
- const { MailerClient, PublicKey } = await this.getSolanaModules();
396
- const programId = new PublicKey(this.solanaProgramId);
397
- const usdcMint = new PublicKey(this.solanaUsdcMint);
398
- const wallet = { publicKey: PublicKey.default, signTransaction: async (tx) => tx };
399
- const client = new MailerClient(this.solanaConnection, wallet, programId, usdcMint);
400
- const recipientKey = new PublicKey(address);
401
- const claimInfo = await client.getRecipientClaimable(recipientKey);
402
- return claimInfo ? BigInt(claimInfo.amount) : 0n;
403
- }
565
+ /**
566
+ * Get owner's claimable fee balance
567
+ * @returns Owner claimable amount in USDC micro-units
568
+ */
404
569
  async getOwnerClaimable() {
405
- if (this.chainType === types_1.ChainType.EVM) {
570
+ if (this.chainType === 'evm') {
406
571
  return this.getEVMOwnerClaimable();
407
572
  }
408
573
  else {
409
574
  return this.getSolanaOwnerClaimable();
410
575
  }
411
576
  }
412
- async getEVMOwnerClaimable() {
413
- if (!this.evmPublicClient || !this.evmContractAddress) {
414
- throw new Error('EVM client not properly initialized');
415
- }
416
- const { MailerClient } = await this.getEVMModules();
417
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
418
- return client.getOwnerClaimable();
419
- }
420
- async getSolanaOwnerClaimable() {
421
- if (!this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
422
- throw new Error('Solana client not properly initialized');
423
- }
424
- const { MailerClient, PublicKey } = await this.getSolanaModules();
425
- const programId = new PublicKey(this.solanaProgramId);
426
- const usdcMint = new PublicKey(this.solanaUsdcMint);
427
- const wallet = { publicKey: PublicKey.default, signTransaction: async (tx) => tx };
428
- const client = new MailerClient(this.solanaConnection, wallet, programId, usdcMint);
429
- const amount = await client.getOwnerClaimable();
430
- return BigInt(amount);
431
- }
577
+ /**
578
+ * Get delegation information for an address
579
+ * @param address - Address to check delegation for (defaults to connected wallet)
580
+ * @returns Delegation address or null if no delegation
581
+ */
432
582
  async getDelegation(address) {
433
- const targetAddress = address || await this.getWalletAddressAsync();
434
- if (this.chainType === types_1.ChainType.EVM) {
583
+ const targetAddress = address || this.wallet.address;
584
+ if (this.chainType === 'evm') {
435
585
  return this.getEVMDelegation(targetAddress);
436
586
  }
437
587
  else {
438
588
  return this.getSolanaDelegation(targetAddress);
439
589
  }
440
590
  }
591
+ // EVM read methods
592
+ async getEVMSendFee() {
593
+ const { viem, MailerClient } = await this.getEVMModules();
594
+ if (!this.config.evm?.contracts.mailer) {
595
+ throw new Error('EVM Mailer contract address not configured');
596
+ }
597
+ const publicClient = viem.createPublicClient({
598
+ transport: viem.http(this.config.evm.rpc),
599
+ chain: {
600
+ id: this.config.evm.chainId,
601
+ name: 'Custom Chain',
602
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
603
+ rpcUrls: {
604
+ default: { http: [this.config.evm.rpc] }
605
+ }
606
+ }
607
+ });
608
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
609
+ return client.getSendFee();
610
+ }
611
+ async getEVMClaimableAmount(address) {
612
+ const { viem, MailerClient } = await this.getEVMModules();
613
+ if (!this.config.evm?.contracts.mailer) {
614
+ throw new Error('EVM Mailer contract address not configured');
615
+ }
616
+ const publicClient = viem.createPublicClient({
617
+ transport: viem.http(this.config.evm.rpc),
618
+ chain: {
619
+ id: this.config.evm.chainId,
620
+ name: 'Custom Chain',
621
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
622
+ rpcUrls: {
623
+ default: { http: [this.config.evm.rpc] }
624
+ }
625
+ }
626
+ });
627
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
628
+ const result = await client.getRecipientClaimable(address);
629
+ return result.amount;
630
+ }
631
+ async getEVMOwnerClaimable() {
632
+ const { viem, MailerClient } = await this.getEVMModules();
633
+ if (!this.config.evm?.contracts.mailer) {
634
+ throw new Error('EVM Mailer contract address not configured');
635
+ }
636
+ const publicClient = viem.createPublicClient({
637
+ transport: viem.http(this.config.evm.rpc),
638
+ chain: {
639
+ id: this.config.evm.chainId,
640
+ name: 'Custom Chain',
641
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
642
+ rpcUrls: {
643
+ default: { http: [this.config.evm.rpc] }
644
+ }
645
+ }
646
+ });
647
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
648
+ return client.getOwnerClaimable();
649
+ }
441
650
  async getEVMDelegation(_address) {
442
651
  // Delegation read not implemented in EVM client yet
652
+ // Would need to add getDelegation method to EVM MailerClient
443
653
  throw new Error('getDelegation not yet implemented for EVM');
444
654
  }
655
+ // Solana read methods
656
+ async getSolanaSendFee() {
657
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
658
+ if (!this.config.solana?.programs.mailer) {
659
+ throw new Error('Solana Mailer program address not configured');
660
+ }
661
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
662
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
663
+ const wallet = MailerClient.createWallet(this.wallet);
664
+ const programId = new PublicKey(this.config.solana.programs.mailer);
665
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
666
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
667
+ const fees = await client.getFees();
668
+ return BigInt(fees.sendFee);
669
+ }
670
+ async getSolanaClaimableAmount(address) {
671
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
672
+ if (!this.config.solana?.programs.mailer) {
673
+ throw new Error('Solana Mailer program address not configured');
674
+ }
675
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
676
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
677
+ const wallet = MailerClient.createWallet(this.wallet);
678
+ const programId = new PublicKey(this.config.solana.programs.mailer);
679
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
680
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
681
+ const recipientKey = new PublicKey(address);
682
+ const claimInfo = await client.getRecipientClaimable(recipientKey);
683
+ return claimInfo ? BigInt(claimInfo.amount) : 0n;
684
+ }
685
+ async getSolanaOwnerClaimable() {
686
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
687
+ if (!this.config.solana?.programs.mailer) {
688
+ throw new Error('Solana Mailer program address not configured');
689
+ }
690
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
691
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
692
+ const wallet = MailerClient.createWallet(this.wallet);
693
+ const programId = new PublicKey(this.config.solana.programs.mailer);
694
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
695
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
696
+ const amount = await client.getOwnerClaimable();
697
+ return BigInt(amount);
698
+ }
445
699
  async getSolanaDelegation(address) {
446
- if (!this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
447
- throw new Error('Solana client not properly initialized');
448
- }
449
- const { MailerClient, PublicKey } = await this.getSolanaModules();
450
- const programId = new PublicKey(this.solanaProgramId);
451
- const usdcMint = new PublicKey(this.solanaUsdcMint);
452
- const wallet = { publicKey: PublicKey.default, signTransaction: async (tx) => tx };
453
- const client = new MailerClient(this.solanaConnection, wallet, programId, usdcMint);
700
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
701
+ if (!this.config.solana?.programs.mailer) {
702
+ throw new Error('Solana Mailer program address not configured');
703
+ }
704
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
705
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
706
+ const wallet = MailerClient.createWallet(this.wallet);
707
+ const programId = new PublicKey(this.config.solana.programs.mailer);
708
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
709
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
454
710
  const delegatorKey = new PublicKey(address);
455
711
  const delegationInfo = await client.getDelegation(delegatorKey);
456
712
  return delegationInfo?.delegate || null;
457
713
  }
458
- async getDelegationFee() {
459
- if (this.chainType === types_1.ChainType.EVM) {
460
- return this.getEVMDelegationFee();
714
+ /**
715
+ * Send a prepared message using mail ID (to match cross-chain behavior)
716
+ * @param to - Recipient address
717
+ * @param mailId - Pre-prepared message identifier
718
+ * @param priority - Whether to use priority sending with revenue share
719
+ * @param resolveSenderToName - If true, resolve sender address to name
720
+ * @returns Promise resolving to MessageResult
721
+ */
722
+ async sendPrepared(to, mailId, priority = false, resolveSenderToName = false) {
723
+ if (this.chainType === 'evm') {
724
+ return this.sendPreparedEVM(to, mailId, priority, resolveSenderToName);
461
725
  }
462
726
  else {
463
- return this.getSolanaDelegationFee();
727
+ return this.sendPreparedSolana(to, mailId, priority, resolveSenderToName);
464
728
  }
465
729
  }
466
- async getEVMDelegationFee() {
467
- if (!this.evmPublicClient || !this.evmContractAddress) {
468
- throw new Error('EVM client not properly initialized');
730
+ /**
731
+ * Send message to email address (no wallet known)
732
+ * @param toEmail - Email address of the recipient
733
+ * @param subject - Message subject
734
+ * @param body - Message body
735
+ * @returns Promise resolving to MessageResult
736
+ */
737
+ async sendToEmail(toEmail, subject, body) {
738
+ if (this.chainType === 'evm') {
739
+ return this.sendToEmailEVM(toEmail, subject, body);
469
740
  }
470
- const { MailerClient } = await this.getEVMModules();
471
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
472
- return client.getDelegationFee();
473
- }
474
- async getSolanaDelegationFee() {
475
- if (!this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
476
- throw new Error('Solana client not properly initialized');
741
+ else {
742
+ return this.sendToEmailSolana(toEmail, subject, body);
477
743
  }
478
- const { MailerClient, PublicKey } = await this.getSolanaModules();
479
- const programId = new PublicKey(this.solanaProgramId);
480
- const usdcMint = new PublicKey(this.solanaUsdcMint);
481
- const wallet = { publicKey: PublicKey.default, signTransaction: async (tx) => tx };
482
- const client = new MailerClient(this.solanaConnection, wallet, programId, usdcMint);
483
- const fees = await client.getFees();
484
- return BigInt(fees.delegationFee);
485
744
  }
486
- async isPaused() {
487
- if (this.chainType === types_1.ChainType.EVM) {
488
- return this.isPausedEVM();
745
+ /**
746
+ * Send prepared message to email address (no wallet known)
747
+ * @param toEmail - Email address of the recipient
748
+ * @param mailId - Pre-prepared message identifier
749
+ * @returns Promise resolving to MessageResult
750
+ */
751
+ async sendPreparedToEmail(toEmail, mailId) {
752
+ if (this.chainType === 'evm') {
753
+ return this.sendPreparedToEmailEVM(toEmail, mailId);
489
754
  }
490
755
  else {
491
- return this.isPausedSolana();
756
+ return this.sendPreparedToEmailSolana(toEmail, mailId);
492
757
  }
493
758
  }
494
- async isPausedEVM() {
495
- if (!this.evmPublicClient || !this.evmContractAddress) {
496
- throw new Error('EVM client not properly initialized');
759
+ /**
760
+ * Set the send fee (owner only)
761
+ * @param newFee - New fee amount in USDC micro-units (6 decimals)
762
+ * @returns Promise resolving to transaction details
763
+ */
764
+ async setFee(newFee) {
765
+ if (this.chainType === 'evm') {
766
+ return this.setFeeEVM(newFee);
767
+ }
768
+ else {
769
+ return this.setFeeSolana(newFee);
497
770
  }
498
- const { MailerClient } = await this.getEVMModules();
499
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
500
- return client.isPaused();
501
771
  }
502
- async isPausedSolana() {
503
- if (!this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
504
- throw new Error('Solana client not properly initialized');
505
- }
506
- const { MailerClient, PublicKey } = await this.getSolanaModules();
507
- const programId = new PublicKey(this.solanaProgramId);
508
- const usdcMint = new PublicKey(this.solanaUsdcMint);
509
- const wallet = { publicKey: PublicKey.default, signTransaction: async (tx) => tx };
510
- const client = new MailerClient(this.solanaConnection, wallet, programId, usdcMint);
511
- return client.isPaused();
772
+ /**
773
+ * Get the current send fee
774
+ * @returns Current send fee in USDC micro-units (6 decimals)
775
+ */
776
+ async getFee() {
777
+ return this.getSendFee();
512
778
  }
513
- // Write methods for contract management
514
- async unpause() {
515
- if (this.chainType === types_1.ChainType.EVM) {
516
- return this.unpauseEVM();
779
+ /**
780
+ * Set the delegation fee (owner only)
781
+ * @param newFee - New delegation fee in USDC micro-units
782
+ * @returns Promise resolving to transaction details
783
+ */
784
+ async setDelegationFee(newFee) {
785
+ if (this.chainType === 'evm') {
786
+ return this.setDelegationFeeEVM(newFee);
517
787
  }
518
788
  else {
519
- return this.unpauseSolana();
789
+ return this.setDelegationFeeSolana(newFee);
520
790
  }
521
791
  }
522
- async unpauseEVM() {
523
- if (!this.evmWalletClient || !this.evmPublicClient || !this.evmContractAddress) {
524
- throw new Error('EVM client not properly initialized');
792
+ /**
793
+ * Get the current delegation fee
794
+ * @returns Current delegation fee in USDC micro-units
795
+ */
796
+ async getDelegationFee() {
797
+ if (this.chainType === 'evm') {
798
+ return this.getDelegationFeeEVM();
799
+ }
800
+ else {
801
+ return this.getDelegationFeeSolana();
525
802
  }
526
- const { MailerClient } = await this.getEVMModules();
527
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
528
- const [account] = await this.evmWalletClient.getAddresses();
529
- const result = await client.unpause(this.evmWalletClient, account);
530
- return {
531
- hash: result.hash,
532
- chainType: types_1.ChainType.EVM,
533
- blockNumber: result.blockNumber,
534
- timestamp: Date.now()
535
- };
536
803
  }
537
- async unpauseSolana() {
538
- if (!this.solanaWallet || !this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
539
- throw new Error('Solana client not properly initialized');
540
- }
541
- const { MailerClient, PublicKey } = await this.getSolanaModules();
542
- const programId = new PublicKey(this.solanaProgramId);
543
- const usdcMint = new PublicKey(this.solanaUsdcMint);
544
- const client = new MailerClient(this.solanaConnection, this.solanaWallet, programId, usdcMint);
545
- const result = await client.unpause();
546
- const slot = await this.solanaConnection.getSlot();
547
- return {
548
- hash: result.signature,
549
- chainType: types_1.ChainType.SOLANA,
550
- slot,
551
- timestamp: Date.now()
552
- };
804
+ /**
805
+ * Reject a delegation made to you by another address
806
+ * @param delegatorAddress - Address that delegated to you
807
+ * @returns Promise resolving to transaction details
808
+ */
809
+ async rejectDelegation(delegatorAddress) {
810
+ if (this.chainType === 'evm') {
811
+ return this.rejectDelegationEVM(delegatorAddress);
812
+ }
813
+ else {
814
+ return this.rejectDelegationSolana(delegatorAddress);
815
+ }
553
816
  }
554
- async emergencyUnpause() {
555
- if (this.chainType === types_1.ChainType.EVM) {
556
- return this.emergencyUnpauseEVM();
817
+ /**
818
+ * Claim owner share of fees (owner only)
819
+ * @returns Promise resolving to transaction details
820
+ */
821
+ async claimOwnerShare() {
822
+ if (this.chainType === 'evm') {
823
+ return this.claimOwnerShareEVM();
557
824
  }
558
825
  else {
559
- return this.emergencyUnpauseSolana();
826
+ return this.claimOwnerShareSolana();
560
827
  }
561
828
  }
562
- async emergencyUnpauseEVM() {
563
- if (!this.evmWalletClient || !this.evmPublicClient || !this.evmContractAddress) {
564
- throw new Error('EVM client not properly initialized');
829
+ /**
830
+ * Claim expired shares (owner only, EVM only)
831
+ * @param recipient - Address to claim expired shares for
832
+ * @returns Promise resolving to transaction details
833
+ */
834
+ async claimExpiredShares(recipient) {
835
+ if (this.chainType === 'evm') {
836
+ return this.claimExpiredSharesEVM(recipient);
837
+ }
838
+ else {
839
+ throw new Error('claimExpiredShares not available on Solana');
565
840
  }
566
- const { MailerClient } = await this.getEVMModules();
567
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
568
- const [account] = await this.evmWalletClient.getAddresses();
569
- const result = await client.emergencyUnpause(this.evmWalletClient, account);
570
- return {
571
- hash: result.hash,
572
- chainType: types_1.ChainType.EVM,
573
- blockNumber: result.blockNumber,
574
- timestamp: Date.now()
575
- };
576
841
  }
577
- async emergencyUnpauseSolana() {
578
- if (!this.solanaWallet || !this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
579
- throw new Error('Solana client not properly initialized');
580
- }
581
- const { MailerClient, PublicKey } = await this.getSolanaModules();
582
- const programId = new PublicKey(this.solanaProgramId);
583
- const usdcMint = new PublicKey(this.solanaUsdcMint);
584
- const client = new MailerClient(this.solanaConnection, this.solanaWallet, programId, usdcMint);
585
- const result = await client.emergencyUnpause();
586
- const slot = await this.solanaConnection.getSlot();
587
- return {
588
- hash: result.signature,
589
- chainType: types_1.ChainType.SOLANA,
590
- slot,
591
- timestamp: Date.now()
592
- };
842
+ /**
843
+ * Pause the contract and distribute funds (owner only)
844
+ * @returns Promise resolving to transaction details
845
+ */
846
+ async pause() {
847
+ if (this.chainType === 'evm') {
848
+ return this.pauseEVM();
849
+ }
850
+ else {
851
+ return this.pauseSolana();
852
+ }
593
853
  }
594
- async distributeClaimableFunds(recipient) {
595
- if (this.chainType === types_1.ChainType.EVM) {
596
- return this.distributeClaimableFundsEVM(recipient);
854
+ /**
855
+ * Unpause the contract (owner only)
856
+ * @returns Promise resolving to transaction details
857
+ */
858
+ async unpause() {
859
+ if (this.chainType === 'evm') {
860
+ return this.unpauseEVM();
597
861
  }
598
862
  else {
599
- return this.distributeClaimableFundsSolana(recipient);
863
+ return this.unpauseSolana();
600
864
  }
601
865
  }
602
- async distributeClaimableFundsEVM(recipient) {
603
- if (!this.evmWalletClient || !this.evmPublicClient || !this.evmContractAddress) {
604
- throw new Error('EVM client not properly initialized');
866
+ /**
867
+ * Emergency unpause without fund distribution (owner only)
868
+ * @returns Promise resolving to transaction details
869
+ */
870
+ async emergencyUnpause() {
871
+ if (this.chainType === 'evm') {
872
+ return this.emergencyUnpauseEVM();
873
+ }
874
+ else {
875
+ return this.emergencyUnpauseSolana();
605
876
  }
606
- const { MailerClient } = await this.getEVMModules();
607
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
608
- const [account] = await this.evmWalletClient.getAddresses();
609
- const result = await client.distributeClaimableFunds(recipient, this.evmWalletClient, account);
610
- return {
611
- hash: result.hash,
612
- chainType: types_1.ChainType.EVM,
613
- blockNumber: result.blockNumber,
614
- timestamp: Date.now()
615
- };
616
877
  }
617
- async distributeClaimableFundsSolana(recipient) {
618
- if (!this.solanaWallet || !this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
619
- throw new Error('Solana client not properly initialized');
620
- }
621
- const { MailerClient, PublicKey } = await this.getSolanaModules();
622
- const programId = new PublicKey(this.solanaProgramId);
623
- const usdcMint = new PublicKey(this.solanaUsdcMint);
624
- const client = new MailerClient(this.solanaConnection, this.solanaWallet, programId, usdcMint);
625
- const result = await client.distributeClaimableFunds(recipient);
626
- const slot = await this.solanaConnection.getSlot();
627
- return {
628
- hash: result.signature,
629
- chainType: types_1.ChainType.SOLANA,
630
- slot,
631
- timestamp: Date.now()
632
- };
878
+ /**
879
+ * Check if contract is currently paused
880
+ * @returns True if contract is paused, false otherwise
881
+ */
882
+ async isPaused() {
883
+ if (this.chainType === 'evm') {
884
+ return this.isPausedEVM();
885
+ }
886
+ else {
887
+ return this.isPausedSolana();
888
+ }
633
889
  }
634
- // Additional methods for complete API compatibility
635
- async sendPrepared(to, mailId, priority = false, resolveSenderToName = false) {
636
- if (this.chainType === types_1.ChainType.EVM) {
637
- return this.sendPreparedEVM(to, mailId, priority, resolveSenderToName);
890
+ /**
891
+ * Distribute claimable funds to a recipient when contract is paused
892
+ * @param recipient - Address to distribute funds for
893
+ * @returns Promise resolving to transaction details
894
+ */
895
+ async distributeClaimableFunds(recipient) {
896
+ if (this.chainType === 'evm') {
897
+ return this.distributeClaimableFundsEVM(recipient);
638
898
  }
639
899
  else {
640
- return this.sendPreparedSolana(to, mailId, priority, resolveSenderToName);
900
+ return this.distributeClaimableFundsSolana(recipient);
641
901
  }
642
902
  }
903
+ // EVM Implementation Methods
643
904
  async sendPreparedEVM(to, mailId, priority, resolveSenderToName) {
644
- if (!this.evmWalletClient || !this.evmPublicClient || !this.evmContractAddress) {
645
- throw new Error('EVM client not properly initialized');
646
- }
647
- const { MailerClient } = await this.getEVMModules();
648
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
649
- const [account] = await this.evmWalletClient.getAddresses();
650
- const payer = account;
651
- const result = await client.sendPrepared(to, mailId, payer, priority, resolveSenderToName, this.evmWalletClient, account);
905
+ const { viem, MailerClient } = await this.getEVMModules();
906
+ if (!this.config.evm?.contracts.mailer) {
907
+ throw new Error('EVM Mailer contract address not configured');
908
+ }
909
+ const publicClient = viem.createPublicClient({
910
+ transport: viem.http(this.config.evm.rpc),
911
+ chain: {
912
+ id: this.config.evm.chainId,
913
+ name: 'Custom Chain',
914
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
915
+ rpcUrls: {
916
+ default: { http: [this.config.evm.rpc] }
917
+ }
918
+ }
919
+ });
920
+ const walletClient = viem.createWalletClient({
921
+ transport: viem.http(this.config.evm.rpc),
922
+ chain: {
923
+ id: this.config.evm.chainId,
924
+ name: 'Custom Chain',
925
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
926
+ rpcUrls: {
927
+ default: { http: [this.config.evm.rpc] }
928
+ }
929
+ }
930
+ });
931
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
932
+ const txHash = await client.sendPrepared(to, mailId, priority, resolveSenderToName, walletClient, this.wallet.address);
933
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
652
934
  return {
653
- transactionHash: result.hash,
935
+ transactionHash: txHash,
654
936
  chainType: types_1.ChainType.EVM,
655
937
  fee: BigInt(priority ? '100000' : '10000'),
656
- gasUsed: result.gasUsed,
938
+ gasUsed: receipt.gasUsed,
657
939
  isPriority: priority,
658
940
  success: true
659
941
  };
660
942
  }
661
- async sendPreparedSolana(to, mailId, priority, resolveSenderToName) {
662
- if (!this.solanaWallet || !this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
663
- throw new Error('Solana client not properly initialized');
664
- }
665
- const { MailerClient, PublicKey } = await this.getSolanaModules();
666
- const programId = new PublicKey(this.solanaProgramId);
667
- const usdcMint = new PublicKey(this.solanaUsdcMint);
668
- const recipientKey = new PublicKey(to);
669
- const client = new MailerClient(this.solanaConnection, this.solanaWallet, programId, usdcMint);
670
- const result = await client.sendPrepared(recipientKey, mailId, priority, resolveSenderToName);
671
- const fees = await client.getFees();
943
+ async sendToEmailEVM(toEmail, subject, body) {
944
+ const { viem, MailerClient } = await this.getEVMModules();
945
+ if (!this.config.evm?.contracts.mailer) {
946
+ throw new Error('EVM Mailer contract address not configured');
947
+ }
948
+ const publicClient = viem.createPublicClient({
949
+ transport: viem.http(this.config.evm.rpc),
950
+ chain: {
951
+ id: this.config.evm.chainId,
952
+ name: 'Custom Chain',
953
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
954
+ rpcUrls: {
955
+ default: { http: [this.config.evm.rpc] }
956
+ }
957
+ }
958
+ });
959
+ const walletClient = viem.createWalletClient({
960
+ transport: viem.http(this.config.evm.rpc),
961
+ chain: {
962
+ id: this.config.evm.chainId,
963
+ name: 'Custom Chain',
964
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
965
+ rpcUrls: {
966
+ default: { http: [this.config.evm.rpc] }
967
+ }
968
+ }
969
+ });
970
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
971
+ const txHash = await client.sendToEmailAddress(toEmail, subject, body, walletClient, this.wallet.address);
972
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
672
973
  return {
673
- transactionHash: result.signature,
674
- chainType: types_1.ChainType.SOLANA,
675
- fee: priority ? fees.sendFee : fees.sendFee / 10,
676
- isPriority: priority,
974
+ transactionHash: txHash,
975
+ chainType: types_1.ChainType.EVM,
976
+ fee: BigInt('10000'), // 10% fee only
977
+ gasUsed: receipt.gasUsed,
978
+ isPriority: false,
677
979
  success: true
678
980
  };
679
981
  }
680
- async sendToEmail(toEmail, subject, body) {
681
- if (this.chainType === types_1.ChainType.EVM) {
682
- return this.sendToEmailEVM(toEmail, subject, body);
683
- }
684
- else {
685
- return this.sendToEmailSolana(toEmail, subject, body);
686
- }
687
- }
688
- async sendToEmailEVM(toEmail, subject, body) {
689
- if (!this.evmWalletClient || !this.evmPublicClient || !this.evmContractAddress) {
690
- throw new Error('EVM client not properly initialized');
691
- }
692
- const { MailerClient } = await this.getEVMModules();
693
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
694
- const [account] = await this.evmWalletClient.getAddresses();
695
- const payer = account;
696
- const result = await client.sendToEmailAddress(toEmail, subject, body, payer, this.evmWalletClient, account);
982
+ async sendPreparedToEmailEVM(toEmail, mailId) {
983
+ const { viem, MailerClient } = await this.getEVMModules();
984
+ if (!this.config.evm?.contracts.mailer) {
985
+ throw new Error('EVM Mailer contract address not configured');
986
+ }
987
+ const publicClient = viem.createPublicClient({
988
+ transport: viem.http(this.config.evm.rpc),
989
+ chain: {
990
+ id: this.config.evm.chainId,
991
+ name: 'Custom Chain',
992
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
993
+ rpcUrls: {
994
+ default: { http: [this.config.evm.rpc] }
995
+ }
996
+ }
997
+ });
998
+ const walletClient = viem.createWalletClient({
999
+ transport: viem.http(this.config.evm.rpc),
1000
+ chain: {
1001
+ id: this.config.evm.chainId,
1002
+ name: 'Custom Chain',
1003
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1004
+ rpcUrls: {
1005
+ default: { http: [this.config.evm.rpc] }
1006
+ }
1007
+ }
1008
+ });
1009
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
1010
+ const txHash = await client.sendPreparedToEmailAddress(toEmail, mailId, walletClient, this.wallet.address);
1011
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
697
1012
  return {
698
- transactionHash: result.hash,
1013
+ transactionHash: txHash,
699
1014
  chainType: types_1.ChainType.EVM,
700
1015
  fee: BigInt('10000'), // 10% fee only
701
- gasUsed: result.gasUsed,
1016
+ gasUsed: receipt.gasUsed,
702
1017
  isPriority: false,
703
1018
  success: true
704
1019
  };
705
1020
  }
706
- async sendToEmailSolana(toEmail, subject, body) {
707
- if (!this.solanaWallet || !this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
708
- throw new Error('Solana client not properly initialized');
709
- }
710
- const { MailerClient, PublicKey } = await this.getSolanaModules();
711
- const programId = new PublicKey(this.solanaProgramId);
712
- const usdcMint = new PublicKey(this.solanaUsdcMint);
713
- const client = new MailerClient(this.solanaConnection, this.solanaWallet, programId, usdcMint);
714
- const result = await client.sendToEmail(toEmail, subject, body);
715
- const fees = await client.getFees();
1021
+ async setFeeEVM(newFee) {
1022
+ const { viem, MailerClient } = await this.getEVMModules();
1023
+ if (!this.config.evm?.contracts.mailer) {
1024
+ throw new Error('EVM Mailer contract address not configured');
1025
+ }
1026
+ const publicClient = viem.createPublicClient({
1027
+ transport: viem.http(this.config.evm.rpc),
1028
+ chain: {
1029
+ id: this.config.evm.chainId,
1030
+ name: 'Custom Chain',
1031
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1032
+ rpcUrls: {
1033
+ default: { http: [this.config.evm.rpc] }
1034
+ }
1035
+ }
1036
+ });
1037
+ const walletClient = viem.createWalletClient({
1038
+ transport: viem.http(this.config.evm.rpc),
1039
+ chain: {
1040
+ id: this.config.evm.chainId,
1041
+ name: 'Custom Chain',
1042
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1043
+ rpcUrls: {
1044
+ default: { http: [this.config.evm.rpc] }
1045
+ }
1046
+ }
1047
+ });
1048
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
1049
+ const txHash = await client.setFee(newFee, walletClient, this.wallet.address);
1050
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
1051
+ const block = await publicClient.getBlock({ blockNumber: receipt.blockNumber });
716
1052
  return {
717
- transactionHash: result.signature,
718
- chainType: types_1.ChainType.SOLANA,
719
- fee: fees.sendFee / 10, // 10% fee only
720
- isPriority: false,
721
- success: true
1053
+ hash: txHash,
1054
+ chainType: types_1.ChainType.EVM,
1055
+ blockNumber: receipt.blockNumber,
1056
+ timestamp: Number(block.timestamp) * 1000
722
1057
  };
723
1058
  }
724
- async sendPreparedToEmail(toEmail, mailId) {
725
- if (this.chainType === types_1.ChainType.EVM) {
726
- return this.sendPreparedToEmailEVM(toEmail, mailId);
727
- }
728
- else {
729
- return this.sendPreparedToEmailSolana(toEmail, mailId);
730
- }
1059
+ async setDelegationFeeEVM(newFee) {
1060
+ const { viem, MailerClient } = await this.getEVMModules();
1061
+ if (!this.config.evm?.contracts.mailer) {
1062
+ throw new Error('EVM Mailer contract address not configured');
1063
+ }
1064
+ const publicClient = viem.createPublicClient({
1065
+ transport: viem.http(this.config.evm.rpc),
1066
+ chain: {
1067
+ id: this.config.evm.chainId,
1068
+ name: 'Custom Chain',
1069
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1070
+ rpcUrls: {
1071
+ default: { http: [this.config.evm.rpc] }
1072
+ }
1073
+ }
1074
+ });
1075
+ const walletClient = viem.createWalletClient({
1076
+ transport: viem.http(this.config.evm.rpc),
1077
+ chain: {
1078
+ id: this.config.evm.chainId,
1079
+ name: 'Custom Chain',
1080
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1081
+ rpcUrls: {
1082
+ default: { http: [this.config.evm.rpc] }
1083
+ }
1084
+ }
1085
+ });
1086
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
1087
+ const txHash = await client.setDelegationFee(newFee, walletClient, this.wallet.address);
1088
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
1089
+ const block = await publicClient.getBlock({ blockNumber: receipt.blockNumber });
1090
+ return {
1091
+ hash: txHash,
1092
+ chainType: types_1.ChainType.EVM,
1093
+ blockNumber: receipt.blockNumber,
1094
+ timestamp: Number(block.timestamp) * 1000
1095
+ };
731
1096
  }
732
- async sendPreparedToEmailEVM(toEmail, mailId) {
733
- if (!this.evmWalletClient || !this.evmPublicClient || !this.evmContractAddress) {
734
- throw new Error('EVM client not properly initialized');
735
- }
736
- const { MailerClient } = await this.getEVMModules();
737
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
738
- const [account] = await this.evmWalletClient.getAddresses();
739
- const payer = account;
740
- const result = await client.sendPreparedToEmailAddress(toEmail, mailId, payer, this.evmWalletClient, account);
1097
+ async getDelegationFeeEVM() {
1098
+ const { viem, MailerClient } = await this.getEVMModules();
1099
+ if (!this.config.evm?.contracts.mailer) {
1100
+ throw new Error('EVM Mailer contract address not configured');
1101
+ }
1102
+ const publicClient = viem.createPublicClient({
1103
+ transport: viem.http(this.config.evm.rpc),
1104
+ chain: {
1105
+ id: this.config.evm.chainId,
1106
+ name: 'Custom Chain',
1107
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1108
+ rpcUrls: {
1109
+ default: { http: [this.config.evm.rpc] }
1110
+ }
1111
+ }
1112
+ });
1113
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
1114
+ return client.getDelegationFee();
1115
+ }
1116
+ async rejectDelegationEVM(delegatorAddress) {
1117
+ const { viem, MailerClient } = await this.getEVMModules();
1118
+ if (!this.config.evm?.contracts.mailer) {
1119
+ throw new Error('EVM Mailer contract address not configured');
1120
+ }
1121
+ const publicClient = viem.createPublicClient({
1122
+ transport: viem.http(this.config.evm.rpc),
1123
+ chain: {
1124
+ id: this.config.evm.chainId,
1125
+ name: 'Custom Chain',
1126
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1127
+ rpcUrls: {
1128
+ default: { http: [this.config.evm.rpc] }
1129
+ }
1130
+ }
1131
+ });
1132
+ const walletClient = viem.createWalletClient({
1133
+ transport: viem.http(this.config.evm.rpc),
1134
+ chain: {
1135
+ id: this.config.evm.chainId,
1136
+ name: 'Custom Chain',
1137
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1138
+ rpcUrls: {
1139
+ default: { http: [this.config.evm.rpc] }
1140
+ }
1141
+ }
1142
+ });
1143
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
1144
+ const txHash = await client.rejectDelegation(delegatorAddress, walletClient, this.wallet.address);
1145
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
1146
+ const block = await publicClient.getBlock({ blockNumber: receipt.blockNumber });
741
1147
  return {
742
- transactionHash: result.hash,
1148
+ hash: txHash,
743
1149
  chainType: types_1.ChainType.EVM,
744
- fee: BigInt('10000'), // 10% fee only
745
- gasUsed: result.gasUsed,
746
- isPriority: false,
747
- success: true
1150
+ blockNumber: receipt.blockNumber,
1151
+ timestamp: Number(block.timestamp) * 1000
748
1152
  };
749
1153
  }
750
- async sendPreparedToEmailSolana(toEmail, mailId) {
751
- if (!this.solanaWallet || !this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
752
- throw new Error('Solana client not properly initialized');
753
- }
754
- const { MailerClient, PublicKey } = await this.getSolanaModules();
755
- const programId = new PublicKey(this.solanaProgramId);
756
- const usdcMint = new PublicKey(this.solanaUsdcMint);
757
- const client = new MailerClient(this.solanaConnection, this.solanaWallet, programId, usdcMint);
758
- const result = await client.sendPreparedToEmail(toEmail, mailId);
759
- const fees = await client.getFees();
1154
+ async claimOwnerShareEVM() {
1155
+ const { viem, MailerClient } = await this.getEVMModules();
1156
+ if (!this.config.evm?.contracts.mailer) {
1157
+ throw new Error('EVM Mailer contract address not configured');
1158
+ }
1159
+ const publicClient = viem.createPublicClient({
1160
+ transport: viem.http(this.config.evm.rpc),
1161
+ chain: {
1162
+ id: this.config.evm.chainId,
1163
+ name: 'Custom Chain',
1164
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1165
+ rpcUrls: {
1166
+ default: { http: [this.config.evm.rpc] }
1167
+ }
1168
+ }
1169
+ });
1170
+ const walletClient = viem.createWalletClient({
1171
+ transport: viem.http(this.config.evm.rpc),
1172
+ chain: {
1173
+ id: this.config.evm.chainId,
1174
+ name: 'Custom Chain',
1175
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1176
+ rpcUrls: {
1177
+ default: { http: [this.config.evm.rpc] }
1178
+ }
1179
+ }
1180
+ });
1181
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
1182
+ const txHash = await client.claimOwnerShare(walletClient, this.wallet.address);
1183
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
1184
+ const block = await publicClient.getBlock({ blockNumber: receipt.blockNumber });
760
1185
  return {
761
- transactionHash: result.signature,
762
- chainType: types_1.ChainType.SOLANA,
763
- fee: fees.sendFee / 10, // 10% fee only
764
- isPriority: false,
765
- success: true
1186
+ hash: txHash,
1187
+ chainType: types_1.ChainType.EVM,
1188
+ blockNumber: receipt.blockNumber,
1189
+ timestamp: Number(block.timestamp) * 1000
766
1190
  };
767
1191
  }
768
- async claimOwnerShare() {
769
- if (this.chainType === types_1.ChainType.EVM) {
770
- return this.claimOwnerShareEVM();
771
- }
772
- else {
773
- return this.claimOwnerShareSolana();
774
- }
1192
+ async claimExpiredSharesEVM(recipient) {
1193
+ const { viem, MailerClient } = await this.getEVMModules();
1194
+ if (!this.config.evm?.contracts.mailer) {
1195
+ throw new Error('EVM Mailer contract address not configured');
1196
+ }
1197
+ const publicClient = viem.createPublicClient({
1198
+ transport: viem.http(this.config.evm.rpc),
1199
+ chain: {
1200
+ id: this.config.evm.chainId,
1201
+ name: 'Custom Chain',
1202
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1203
+ rpcUrls: {
1204
+ default: { http: [this.config.evm.rpc] }
1205
+ }
1206
+ }
1207
+ });
1208
+ const walletClient = viem.createWalletClient({
1209
+ transport: viem.http(this.config.evm.rpc),
1210
+ chain: {
1211
+ id: this.config.evm.chainId,
1212
+ name: 'Custom Chain',
1213
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1214
+ rpcUrls: {
1215
+ default: { http: [this.config.evm.rpc] }
1216
+ }
1217
+ }
1218
+ });
1219
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
1220
+ const txHash = await client.claimExpiredShares(recipient, walletClient, this.wallet.address);
1221
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
1222
+ const block = await publicClient.getBlock({ blockNumber: receipt.blockNumber });
1223
+ return {
1224
+ hash: txHash,
1225
+ chainType: types_1.ChainType.EVM,
1226
+ blockNumber: receipt.blockNumber,
1227
+ timestamp: Number(block.timestamp) * 1000
1228
+ };
775
1229
  }
776
- async claimOwnerShareEVM() {
777
- if (!this.evmWalletClient || !this.evmPublicClient || !this.evmContractAddress) {
778
- throw new Error('EVM client not properly initialized');
779
- }
780
- const { MailerClient } = await this.getEVMModules();
781
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
782
- const [account] = await this.evmWalletClient.getAddresses();
783
- const result = await client.claimOwnerShare(this.evmWalletClient, account);
1230
+ async pauseEVM() {
1231
+ const { viem, MailerClient } = await this.getEVMModules();
1232
+ if (!this.config.evm?.contracts.mailer) {
1233
+ throw new Error('EVM Mailer contract address not configured');
1234
+ }
1235
+ const publicClient = viem.createPublicClient({
1236
+ transport: viem.http(this.config.evm.rpc),
1237
+ chain: {
1238
+ id: this.config.evm.chainId,
1239
+ name: 'Custom Chain',
1240
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1241
+ rpcUrls: {
1242
+ default: { http: [this.config.evm.rpc] }
1243
+ }
1244
+ }
1245
+ });
1246
+ const walletClient = viem.createWalletClient({
1247
+ transport: viem.http(this.config.evm.rpc),
1248
+ chain: {
1249
+ id: this.config.evm.chainId,
1250
+ name: 'Custom Chain',
1251
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1252
+ rpcUrls: {
1253
+ default: { http: [this.config.evm.rpc] }
1254
+ }
1255
+ }
1256
+ });
1257
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
1258
+ const txHash = await client.pause(walletClient, this.wallet.address);
1259
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
1260
+ const block = await publicClient.getBlock({ blockNumber: receipt.blockNumber });
784
1261
  return {
785
- hash: result.hash,
1262
+ hash: txHash,
786
1263
  chainType: types_1.ChainType.EVM,
787
- blockNumber: result.blockNumber,
788
- timestamp: Date.now()
1264
+ blockNumber: receipt.blockNumber,
1265
+ timestamp: Number(block.timestamp) * 1000
789
1266
  };
790
1267
  }
791
- async claimOwnerShareSolana() {
792
- if (!this.solanaWallet || !this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
793
- throw new Error('Solana client not properly initialized');
794
- }
795
- const { MailerClient, PublicKey } = await this.getSolanaModules();
796
- const programId = new PublicKey(this.solanaProgramId);
797
- const usdcMint = new PublicKey(this.solanaUsdcMint);
798
- const client = new MailerClient(this.solanaConnection, this.solanaWallet, programId, usdcMint);
799
- const result = await client.claimOwnerShare();
800
- const slot = await this.solanaConnection.getSlot();
1268
+ async unpauseEVM() {
1269
+ const { viem, MailerClient } = await this.getEVMModules();
1270
+ if (!this.config.evm?.contracts.mailer) {
1271
+ throw new Error('EVM Mailer contract address not configured');
1272
+ }
1273
+ const publicClient = viem.createPublicClient({
1274
+ transport: viem.http(this.config.evm.rpc),
1275
+ chain: {
1276
+ id: this.config.evm.chainId,
1277
+ name: 'Custom Chain',
1278
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1279
+ rpcUrls: {
1280
+ default: { http: [this.config.evm.rpc] }
1281
+ }
1282
+ }
1283
+ });
1284
+ const walletClient = viem.createWalletClient({
1285
+ transport: viem.http(this.config.evm.rpc),
1286
+ chain: {
1287
+ id: this.config.evm.chainId,
1288
+ name: 'Custom Chain',
1289
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1290
+ rpcUrls: {
1291
+ default: { http: [this.config.evm.rpc] }
1292
+ }
1293
+ }
1294
+ });
1295
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
1296
+ const txHash = await client.unpause(walletClient, this.wallet.address);
1297
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
1298
+ const block = await publicClient.getBlock({ blockNumber: receipt.blockNumber });
801
1299
  return {
802
- hash: result.signature,
803
- chainType: types_1.ChainType.SOLANA,
804
- slot,
805
- timestamp: Date.now()
1300
+ hash: txHash,
1301
+ chainType: types_1.ChainType.EVM,
1302
+ blockNumber: receipt.blockNumber,
1303
+ timestamp: Number(block.timestamp) * 1000
806
1304
  };
807
1305
  }
808
- async claimExpiredShares(recipient) {
809
- if (this.chainType === types_1.ChainType.EVM) {
810
- return this.claimExpiredSharesEVM(recipient);
811
- }
812
- else {
813
- return this.claimExpiredSharesSolana(recipient);
814
- }
1306
+ async emergencyUnpauseEVM() {
1307
+ const { viem, MailerClient } = await this.getEVMModules();
1308
+ if (!this.config.evm?.contracts.mailer) {
1309
+ throw new Error('EVM Mailer contract address not configured');
1310
+ }
1311
+ const publicClient = viem.createPublicClient({
1312
+ transport: viem.http(this.config.evm.rpc),
1313
+ chain: {
1314
+ id: this.config.evm.chainId,
1315
+ name: 'Custom Chain',
1316
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1317
+ rpcUrls: {
1318
+ default: { http: [this.config.evm.rpc] }
1319
+ }
1320
+ }
1321
+ });
1322
+ const walletClient = viem.createWalletClient({
1323
+ transport: viem.http(this.config.evm.rpc),
1324
+ chain: {
1325
+ id: this.config.evm.chainId,
1326
+ name: 'Custom Chain',
1327
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1328
+ rpcUrls: {
1329
+ default: { http: [this.config.evm.rpc] }
1330
+ }
1331
+ }
1332
+ });
1333
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
1334
+ const txHash = await client.emergencyUnpause(walletClient, this.wallet.address);
1335
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
1336
+ const block = await publicClient.getBlock({ blockNumber: receipt.blockNumber });
1337
+ return {
1338
+ hash: txHash,
1339
+ chainType: types_1.ChainType.EVM,
1340
+ blockNumber: receipt.blockNumber,
1341
+ timestamp: Number(block.timestamp) * 1000
1342
+ };
815
1343
  }
816
- async claimExpiredSharesEVM(recipient) {
817
- if (!this.evmWalletClient || !this.evmPublicClient || !this.evmContractAddress) {
818
- throw new Error('EVM client not properly initialized');
819
- }
820
- const { MailerClient } = await this.getEVMModules();
821
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
822
- const [account] = await this.evmWalletClient.getAddresses();
823
- const result = await client.claimExpiredShares(recipient, this.evmWalletClient, account);
1344
+ async isPausedEVM() {
1345
+ const { viem, MailerClient } = await this.getEVMModules();
1346
+ if (!this.config.evm?.contracts.mailer) {
1347
+ throw new Error('EVM Mailer contract address not configured');
1348
+ }
1349
+ const publicClient = viem.createPublicClient({
1350
+ transport: viem.http(this.config.evm.rpc),
1351
+ chain: {
1352
+ id: this.config.evm.chainId,
1353
+ name: 'Custom Chain',
1354
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1355
+ rpcUrls: {
1356
+ default: { http: [this.config.evm.rpc] }
1357
+ }
1358
+ }
1359
+ });
1360
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
1361
+ return client.isPaused();
1362
+ }
1363
+ async distributeClaimableFundsEVM(recipient) {
1364
+ const { viem, MailerClient } = await this.getEVMModules();
1365
+ if (!this.config.evm?.contracts.mailer) {
1366
+ throw new Error('EVM Mailer contract address not configured');
1367
+ }
1368
+ const publicClient = viem.createPublicClient({
1369
+ transport: viem.http(this.config.evm.rpc),
1370
+ chain: {
1371
+ id: this.config.evm.chainId,
1372
+ name: 'Custom Chain',
1373
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1374
+ rpcUrls: {
1375
+ default: { http: [this.config.evm.rpc] }
1376
+ }
1377
+ }
1378
+ });
1379
+ const walletClient = viem.createWalletClient({
1380
+ transport: viem.http(this.config.evm.rpc),
1381
+ chain: {
1382
+ id: this.config.evm.chainId,
1383
+ name: 'Custom Chain',
1384
+ nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
1385
+ rpcUrls: {
1386
+ default: { http: [this.config.evm.rpc] }
1387
+ }
1388
+ }
1389
+ });
1390
+ const client = new MailerClient(this.config.evm.contracts.mailer, publicClient);
1391
+ const txHash = await client.distributeClaimableFunds(recipient, walletClient, this.wallet.address);
1392
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
1393
+ const block = await publicClient.getBlock({ blockNumber: receipt.blockNumber });
824
1394
  return {
825
- hash: result.hash,
1395
+ hash: txHash,
826
1396
  chainType: types_1.ChainType.EVM,
827
- blockNumber: result.blockNumber,
828
- timestamp: Date.now()
1397
+ blockNumber: receipt.blockNumber,
1398
+ timestamp: Number(block.timestamp) * 1000
829
1399
  };
830
1400
  }
831
- async claimExpiredSharesSolana(recipient) {
832
- if (!this.solanaWallet || !this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
833
- throw new Error('Solana client not properly initialized');
834
- }
835
- const { MailerClient, PublicKey } = await this.getSolanaModules();
836
- const programId = new PublicKey(this.solanaProgramId);
837
- const usdcMint = new PublicKey(this.solanaUsdcMint);
838
- const recipientKey = new PublicKey(recipient);
839
- const client = new MailerClient(this.solanaConnection, this.solanaWallet, programId, usdcMint);
840
- const result = await client.claimExpiredShares(recipientKey);
841
- const slot = await this.solanaConnection.getSlot();
1401
+ // Solana Implementation Methods
1402
+ async sendPreparedSolana(to, mailId, priority, resolveSenderToName) {
1403
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
1404
+ if (!this.config.solana?.programs.mailer) {
1405
+ throw new Error('Solana Mailer program address not configured');
1406
+ }
1407
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
1408
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1409
+ const wallet = MailerClient.createWallet(this.wallet);
1410
+ const programId = new PublicKey(this.config.solana.programs.mailer);
1411
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
1412
+ const recipientKey = new PublicKey(to);
1413
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
1414
+ const txHash = await client.sendPrepared(recipientKey, mailId, priority, resolveSenderToName);
1415
+ const fees = await client.getFees();
1416
+ const slot = await connection.getSlot();
1417
+ const tx = await connection.getTransaction(txHash, { commitment: 'confirmed', maxSupportedTransactionVersion: 0 });
842
1418
  return {
843
- hash: result.signature,
1419
+ transactionHash: txHash,
844
1420
  chainType: types_1.ChainType.SOLANA,
1421
+ fee: priority ? fees.sendFee : fees.sendFee / 10,
845
1422
  slot,
846
- timestamp: Date.now()
1423
+ timestamp: tx?.blockTime ? tx.blockTime * 1000 : Date.now(),
1424
+ isPriority: priority,
1425
+ success: true
847
1426
  };
848
1427
  }
849
- async rejectDelegation(delegatorAddress) {
850
- if (this.chainType === types_1.ChainType.EVM) {
851
- return this.rejectDelegationEVM(delegatorAddress);
852
- }
853
- else {
854
- return this.rejectDelegationSolana(delegatorAddress);
855
- }
1428
+ async sendToEmailSolana(toEmail, subject, body) {
1429
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
1430
+ if (!this.config.solana?.programs.mailer) {
1431
+ throw new Error('Solana Mailer program address not configured');
1432
+ }
1433
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
1434
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1435
+ const wallet = MailerClient.createWallet(this.wallet);
1436
+ const programId = new PublicKey(this.config.solana.programs.mailer);
1437
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
1438
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
1439
+ const txHash = await client.sendToEmail(toEmail, subject, body);
1440
+ const fees = await client.getFees();
1441
+ const slot = await connection.getSlot();
1442
+ const tx = await connection.getTransaction(txHash, { commitment: 'confirmed', maxSupportedTransactionVersion: 0 });
1443
+ return {
1444
+ transactionHash: txHash,
1445
+ chainType: types_1.ChainType.SOLANA,
1446
+ fee: fees.sendFee / 10, // 10% fee only
1447
+ slot,
1448
+ timestamp: tx?.blockTime ? tx.blockTime * 1000 : Date.now(),
1449
+ isPriority: false,
1450
+ success: true
1451
+ };
856
1452
  }
857
- async rejectDelegationEVM(delegatorAddress) {
858
- if (!this.evmWalletClient || !this.evmPublicClient || !this.evmContractAddress) {
859
- throw new Error('EVM client not properly initialized');
860
- }
861
- const { MailerClient } = await this.getEVMModules();
862
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
863
- const [account] = await this.evmWalletClient.getAddresses();
864
- const result = await client.rejectDelegation(delegatorAddress, this.evmWalletClient, account);
1453
+ async sendPreparedToEmailSolana(toEmail, mailId) {
1454
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
1455
+ if (!this.config.solana?.programs.mailer) {
1456
+ throw new Error('Solana Mailer program address not configured');
1457
+ }
1458
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
1459
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1460
+ const wallet = MailerClient.createWallet(this.wallet);
1461
+ const programId = new PublicKey(this.config.solana.programs.mailer);
1462
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
1463
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
1464
+ const txHash = await client.sendPreparedToEmail(toEmail, mailId);
1465
+ const fees = await client.getFees();
1466
+ const slot = await connection.getSlot();
1467
+ const tx = await connection.getTransaction(txHash, { commitment: 'confirmed', maxSupportedTransactionVersion: 0 });
865
1468
  return {
866
- hash: result.hash,
867
- chainType: types_1.ChainType.EVM,
868
- blockNumber: result.blockNumber,
1469
+ transactionHash: txHash,
1470
+ chainType: types_1.ChainType.SOLANA,
1471
+ fee: fees.sendFee / 10, // 10% fee only
1472
+ slot,
1473
+ timestamp: tx?.blockTime ? tx.blockTime * 1000 : Date.now(),
1474
+ isPriority: false,
1475
+ success: true
1476
+ };
1477
+ }
1478
+ async setFeeSolana(newFee) {
1479
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
1480
+ if (!this.config.solana?.programs.mailer) {
1481
+ throw new Error('Solana Mailer program address not configured');
1482
+ }
1483
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
1484
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1485
+ const wallet = MailerClient.createWallet(this.wallet);
1486
+ const programId = new PublicKey(this.config.solana.programs.mailer);
1487
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
1488
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
1489
+ const txHash = await client.setFee(newFee);
1490
+ const slot = await connection.getSlot();
1491
+ return {
1492
+ hash: txHash,
1493
+ chainType: types_1.ChainType.SOLANA,
1494
+ slot,
869
1495
  timestamp: Date.now()
870
1496
  };
871
1497
  }
872
- async rejectDelegationSolana(delegatorAddress) {
873
- if (!this.solanaWallet || !this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
874
- throw new Error('Solana client not properly initialized');
875
- }
876
- const { MailerClient, PublicKey } = await this.getSolanaModules();
877
- const programId = new PublicKey(this.solanaProgramId);
878
- const usdcMint = new PublicKey(this.solanaUsdcMint);
879
- const client = new MailerClient(this.solanaConnection, this.solanaWallet, programId, usdcMint);
880
- const result = await client.rejectDelegation(delegatorAddress);
881
- const slot = await this.solanaConnection.getSlot();
1498
+ async setDelegationFeeSolana(newFee) {
1499
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
1500
+ if (!this.config.solana?.programs.mailer) {
1501
+ throw new Error('Solana Mailer program address not configured');
1502
+ }
1503
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
1504
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1505
+ const wallet = MailerClient.createWallet(this.wallet);
1506
+ const programId = new PublicKey(this.config.solana.programs.mailer);
1507
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
1508
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
1509
+ const txHash = await client.setDelegationFee(newFee);
1510
+ const slot = await connection.getSlot();
882
1511
  return {
883
- hash: result.signature,
1512
+ hash: txHash,
884
1513
  chainType: types_1.ChainType.SOLANA,
885
1514
  slot,
886
1515
  timestamp: Date.now()
887
1516
  };
888
1517
  }
889
- async setFee(newFee) {
890
- if (this.chainType === types_1.ChainType.EVM) {
891
- return this.setFeeEVM(newFee);
892
- }
893
- else {
894
- return this.setFeeSolana(newFee);
895
- }
1518
+ async getDelegationFeeSolana() {
1519
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
1520
+ if (!this.config.solana?.programs.mailer) {
1521
+ throw new Error('Solana Mailer program address not configured');
1522
+ }
1523
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
1524
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1525
+ const wallet = MailerClient.createWallet(this.wallet);
1526
+ const programId = new PublicKey(this.config.solana.programs.mailer);
1527
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
1528
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
1529
+ const fees = await client.getFees();
1530
+ return BigInt(fees.delegationFee);
896
1531
  }
897
- async setFeeEVM(newFee) {
898
- if (!this.evmWalletClient || !this.evmPublicClient || !this.evmContractAddress) {
899
- throw new Error('EVM client not properly initialized');
900
- }
901
- const { MailerClient } = await this.getEVMModules();
902
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
903
- const [account] = await this.evmWalletClient.getAddresses();
904
- const result = await client.setFee(newFee, this.evmWalletClient, account);
1532
+ async rejectDelegationSolana(delegatorAddress) {
1533
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
1534
+ if (!this.config.solana?.programs.mailer) {
1535
+ throw new Error('Solana Mailer program address not configured');
1536
+ }
1537
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
1538
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1539
+ const wallet = MailerClient.createWallet(this.wallet);
1540
+ const programId = new PublicKey(this.config.solana.programs.mailer);
1541
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
1542
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
1543
+ const txHash = await client.rejectDelegation(delegatorAddress);
1544
+ const slot = await connection.getSlot();
905
1545
  return {
906
- hash: result.hash,
907
- chainType: types_1.ChainType.EVM,
908
- blockNumber: result.blockNumber,
1546
+ hash: txHash,
1547
+ chainType: types_1.ChainType.SOLANA,
1548
+ slot,
909
1549
  timestamp: Date.now()
910
1550
  };
911
1551
  }
912
- async setFeeSolana(newFee) {
913
- if (!this.solanaWallet || !this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
914
- throw new Error('Solana client not properly initialized');
915
- }
916
- const { MailerClient, PublicKey } = await this.getSolanaModules();
917
- const programId = new PublicKey(this.solanaProgramId);
918
- const usdcMint = new PublicKey(this.solanaUsdcMint);
919
- const client = new MailerClient(this.solanaConnection, this.solanaWallet, programId, usdcMint);
920
- const result = await client.setFee(newFee);
921
- const slot = await this.solanaConnection.getSlot();
1552
+ async claimOwnerShareSolana() {
1553
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
1554
+ if (!this.config.solana?.programs.mailer) {
1555
+ throw new Error('Solana Mailer program address not configured');
1556
+ }
1557
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
1558
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1559
+ const wallet = MailerClient.createWallet(this.wallet);
1560
+ const programId = new PublicKey(this.config.solana.programs.mailer);
1561
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
1562
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
1563
+ const txHash = await client.claimOwnerShare();
1564
+ const slot = await connection.getSlot();
922
1565
  return {
923
- hash: result.signature,
1566
+ hash: txHash,
924
1567
  chainType: types_1.ChainType.SOLANA,
925
1568
  slot,
926
1569
  timestamp: Date.now()
927
1570
  };
928
1571
  }
929
- async setDelegationFee(newFee) {
930
- if (this.chainType === types_1.ChainType.EVM) {
931
- return this.setDelegationFeeEVM(newFee);
932
- }
933
- else {
934
- return this.setDelegationFeeSolana(newFee);
935
- }
936
- }
937
- async setDelegationFeeEVM(newFee) {
938
- if (!this.evmWalletClient || !this.evmPublicClient || !this.evmContractAddress) {
939
- throw new Error('EVM client not properly initialized');
940
- }
941
- const { MailerClient } = await this.getEVMModules();
942
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
943
- const [account] = await this.evmWalletClient.getAddresses();
944
- const result = await client.setDelegationFee(newFee, this.evmWalletClient, account);
1572
+ async pauseSolana() {
1573
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
1574
+ if (!this.config.solana?.programs.mailer) {
1575
+ throw new Error('Solana Mailer program address not configured');
1576
+ }
1577
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
1578
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1579
+ const wallet = MailerClient.createWallet(this.wallet);
1580
+ const programId = new PublicKey(this.config.solana.programs.mailer);
1581
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
1582
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
1583
+ const txHash = await client.pause();
1584
+ const slot = await connection.getSlot();
945
1585
  return {
946
- hash: result.hash,
947
- chainType: types_1.ChainType.EVM,
948
- blockNumber: result.blockNumber,
1586
+ hash: txHash,
1587
+ chainType: types_1.ChainType.SOLANA,
1588
+ slot,
949
1589
  timestamp: Date.now()
950
1590
  };
951
1591
  }
952
- async setDelegationFeeSolana(newFee) {
953
- if (!this.solanaWallet || !this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
954
- throw new Error('Solana client not properly initialized');
955
- }
956
- const { MailerClient, PublicKey } = await this.getSolanaModules();
957
- const programId = new PublicKey(this.solanaProgramId);
958
- const usdcMint = new PublicKey(this.solanaUsdcMint);
959
- const client = new MailerClient(this.solanaConnection, this.solanaWallet, programId, usdcMint);
960
- const result = await client.setDelegationFee(newFee);
961
- const slot = await this.solanaConnection.getSlot();
1592
+ async unpauseSolana() {
1593
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
1594
+ if (!this.config.solana?.programs.mailer) {
1595
+ throw new Error('Solana Mailer program address not configured');
1596
+ }
1597
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
1598
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1599
+ const wallet = MailerClient.createWallet(this.wallet);
1600
+ const programId = new PublicKey(this.config.solana.programs.mailer);
1601
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
1602
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
1603
+ const txHash = await client.unpause();
1604
+ const slot = await connection.getSlot();
962
1605
  return {
963
- hash: result.signature,
1606
+ hash: txHash,
964
1607
  chainType: types_1.ChainType.SOLANA,
965
1608
  slot,
966
1609
  timestamp: Date.now()
967
1610
  };
968
1611
  }
969
- async pause() {
970
- if (this.chainType === types_1.ChainType.EVM) {
971
- return this.pauseEVM();
972
- }
973
- else {
974
- return this.pauseSolana();
975
- }
976
- }
977
- async pauseEVM() {
978
- if (!this.evmWalletClient || !this.evmPublicClient || !this.evmContractAddress) {
979
- throw new Error('EVM client not properly initialized');
980
- }
981
- const { MailerClient } = await this.getEVMModules();
982
- const client = new MailerClient(this.evmContractAddress, this.evmPublicClient);
983
- const [account] = await this.evmWalletClient.getAddresses();
984
- const result = await client.pause(this.evmWalletClient, account);
1612
+ async emergencyUnpauseSolana() {
1613
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
1614
+ if (!this.config.solana?.programs.mailer) {
1615
+ throw new Error('Solana Mailer program address not configured');
1616
+ }
1617
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
1618
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1619
+ const wallet = MailerClient.createWallet(this.wallet);
1620
+ const programId = new PublicKey(this.config.solana.programs.mailer);
1621
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
1622
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
1623
+ const txHash = await client.emergencyUnpause();
1624
+ const slot = await connection.getSlot();
985
1625
  return {
986
- hash: result.hash,
987
- chainType: types_1.ChainType.EVM,
988
- blockNumber: result.blockNumber,
1626
+ hash: txHash,
1627
+ chainType: types_1.ChainType.SOLANA,
1628
+ slot,
989
1629
  timestamp: Date.now()
990
1630
  };
991
1631
  }
992
- async pauseSolana() {
993
- if (!this.solanaWallet || !this.solanaConnection || !this.solanaProgramId || !this.solanaUsdcMint) {
994
- throw new Error('Solana client not properly initialized');
995
- }
996
- const { MailerClient, PublicKey } = await this.getSolanaModules();
997
- const programId = new PublicKey(this.solanaProgramId);
998
- const usdcMint = new PublicKey(this.solanaUsdcMint);
999
- const client = new MailerClient(this.solanaConnection, this.solanaWallet, programId, usdcMint);
1000
- const result = await client.pause();
1001
- const slot = await this.solanaConnection.getSlot();
1632
+ async isPausedSolana() {
1633
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
1634
+ if (!this.config.solana?.programs.mailer) {
1635
+ throw new Error('Solana Mailer program address not configured');
1636
+ }
1637
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
1638
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1639
+ const wallet = MailerClient.createWallet(this.wallet);
1640
+ const programId = new PublicKey(this.config.solana.programs.mailer);
1641
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
1642
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
1643
+ return client.isPaused();
1644
+ }
1645
+ async distributeClaimableFundsSolana(recipient) {
1646
+ const { MailerClient, PublicKey, Connection } = await this.getSolanaModules();
1647
+ if (!this.config.solana?.programs.mailer) {
1648
+ throw new Error('Solana Mailer program address not configured');
1649
+ }
1650
+ const connection = new Connection(this.config.solana.rpc, 'confirmed');
1651
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1652
+ const wallet = MailerClient.createWallet(this.wallet);
1653
+ const programId = new PublicKey(this.config.solana.programs.mailer);
1654
+ const usdcMint = new PublicKey(this.config.solana.usdcMint);
1655
+ const client = new MailerClient(connection, wallet, programId, usdcMint);
1656
+ const txHash = await client.distributeClaimableFunds(recipient);
1657
+ const slot = await connection.getSlot();
1002
1658
  return {
1003
- hash: result.signature,
1659
+ hash: txHash,
1004
1660
  chainType: types_1.ChainType.SOLANA,
1005
1661
  slot,
1006
1662
  timestamp: Date.now()
@@ -1011,36 +1667,11 @@ class OnchainMailerClient {
1011
1667
  return this.chainType;
1012
1668
  }
1013
1669
  getWalletAddress() {
1014
- if (this.chainType === types_1.ChainType.EVM) {
1015
- // Try to get address from raw wallet for backward compatibility
1016
- // @ts-ignore
1017
- if (this._rawEvmWallet) {
1018
- // @ts-ignore
1019
- return this._rawEvmWallet.address || this._rawEvmWallet.selectedAddress || '';
1020
- }
1021
- return ''; // Caller should use getWalletAddressAsync() for accurate address
1022
- }
1023
- else if (this.chainType === types_1.ChainType.SOLANA && this.solanaWallet) {
1024
- return this.solanaWallet.publicKey?.toString() || '';
1025
- }
1026
- return '';
1027
- }
1028
- /**
1029
- * Get wallet address asynchronously
1030
- */
1031
- async getWalletAddressAsync() {
1032
- if (this.chainType === types_1.ChainType.EVM && this.evmWalletClient) {
1033
- const [address] = await this.evmWalletClient.getAddresses();
1034
- return address;
1035
- }
1036
- else if (this.chainType === types_1.ChainType.SOLANA && this.solanaWallet) {
1037
- return this.solanaWallet.publicKey?.toString() || '';
1038
- }
1039
- throw new Error('Wallet not initialized');
1670
+ return this.wallet.address;
1040
1671
  }
1041
1672
  }
1042
1673
  exports.OnchainMailerClient = OnchainMailerClient;
1043
- // Cache for dynamic imports
1674
+ // Performance optimization: cache imported modules
1044
1675
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1045
1676
  OnchainMailerClient.evmModules = null;
1046
1677
  // eslint-disable-next-line @typescript-eslint/no-explicit-any