@sudobility/contracts 0.15.1 → 1.10.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 (166) hide show
  1. package/README.md +2 -3
  2. package/artifacts/contracts/Mailer.sol/Mailer.d.ts +2 -185
  3. package/artifacts/contracts/Mailer.sol/Mailer.dbg.json +1 -1
  4. package/artifacts/contracts/Mailer.sol/Mailer.json +2 -185
  5. package/artifacts/contracts/MockUSDC.sol/MockUSDC.dbg.json +1 -1
  6. package/artifacts/contracts/interfaces/IERC20.sol/IERC20.dbg.json +1 -1
  7. package/dist/evm/src/evm/index.d.ts +1 -1
  8. package/dist/evm/src/evm/index.d.ts.map +1 -1
  9. package/dist/evm/src/evm/index.js +4 -4
  10. package/dist/evm/src/evm/index.js.map +1 -1
  11. package/dist/evm/src/evm/mailer-client.d.ts +210 -0
  12. package/dist/evm/src/evm/mailer-client.d.ts.map +1 -0
  13. package/dist/evm/src/evm/mailer-client.js +417 -0
  14. package/dist/evm/src/evm/mailer-client.js.map +1 -0
  15. package/dist/evm/typechain-types/Mailer.d.ts +10 -128
  16. package/dist/evm/typechain-types/Mailer.d.ts.map +1 -1
  17. package/dist/evm/typechain-types/factories/Mailer__factory.d.ts +1 -145
  18. package/dist/evm/typechain-types/factories/Mailer__factory.d.ts.map +1 -1
  19. package/dist/evm/typechain-types/factories/Mailer__factory.js +1 -184
  20. package/dist/evm/typechain-types/factories/Mailer__factory.js.map +1 -1
  21. package/dist/solana/solana/index.d.ts +1 -1
  22. package/dist/solana/solana/index.d.ts.map +1 -1
  23. package/dist/solana/solana/index.js +1 -4
  24. package/dist/solana/solana/index.js.map +1 -1
  25. package/dist/solana/solana/mailer-client.d.ts +209 -0
  26. package/dist/solana/solana/mailer-client.d.ts.map +1 -0
  27. package/dist/solana/solana/mailer-client.js +728 -0
  28. package/dist/solana/solana/mailer-client.js.map +1 -0
  29. package/dist/solana/solana/types.d.ts +2 -3
  30. package/dist/solana/solana/types.d.ts.map +1 -1
  31. package/dist/solana/solana/types.js.map +1 -1
  32. package/dist/unified/src/evm/index.d.ts +1 -1
  33. package/dist/unified/src/evm/index.d.ts.map +1 -1
  34. package/dist/unified/src/evm/index.js +4 -4
  35. package/dist/unified/src/evm/index.js.map +1 -1
  36. package/dist/unified/src/evm/mailer-client.d.ts +210 -0
  37. package/dist/unified/src/evm/mailer-client.d.ts.map +1 -0
  38. package/dist/unified/src/evm/mailer-client.js +417 -0
  39. package/dist/unified/src/evm/mailer-client.js.map +1 -0
  40. package/dist/unified/src/react/context/MailerProvider.d.ts +20 -26
  41. package/dist/unified/src/react/context/MailerProvider.d.ts.map +1 -1
  42. package/dist/unified/src/react/context/MailerProvider.js +26 -26
  43. package/dist/unified/src/react/context/MailerProvider.js.map +1 -1
  44. package/dist/unified/src/react/hooks/useMailerMutations.d.ts +192 -225
  45. package/dist/unified/src/react/hooks/useMailerMutations.d.ts.map +1 -1
  46. package/dist/unified/src/react/hooks/useMailerMutations.js +266 -263
  47. package/dist/unified/src/react/hooks/useMailerMutations.js.map +1 -1
  48. package/dist/unified/src/react/hooks/useMailerQueries.d.ts +63 -117
  49. package/dist/unified/src/react/hooks/useMailerQueries.d.ts.map +1 -1
  50. package/dist/unified/src/react/hooks/useMailerQueries.js +104 -239
  51. package/dist/unified/src/react/hooks/useMailerQueries.js.map +1 -1
  52. package/dist/unified/src/react/index.d.ts +3 -5
  53. package/dist/unified/src/react/index.d.ts.map +1 -1
  54. package/dist/unified/src/react/index.js +26 -41
  55. package/dist/unified/src/react/index.js.map +1 -1
  56. package/dist/unified/src/solana/index.d.ts +1 -1
  57. package/dist/unified/src/solana/index.d.ts.map +1 -1
  58. package/dist/unified/src/solana/index.js +1 -4
  59. package/dist/unified/src/solana/index.js.map +1 -1
  60. package/dist/unified/src/solana/mailer-client.d.ts +209 -0
  61. package/dist/unified/src/solana/mailer-client.d.ts.map +1 -0
  62. package/dist/unified/src/solana/mailer-client.js +728 -0
  63. package/dist/unified/src/solana/mailer-client.js.map +1 -0
  64. package/dist/unified/src/solana/types.d.ts +2 -3
  65. package/dist/unified/src/solana/types.d.ts.map +1 -1
  66. package/dist/unified/src/solana/types.js.map +1 -1
  67. package/dist/unified/src/unified/index.d.ts +1 -1
  68. package/dist/unified/src/unified/index.d.ts.map +1 -1
  69. package/dist/unified/src/unified/onchain-mailer-client.d.ts +247 -192
  70. package/dist/unified/src/unified/onchain-mailer-client.d.ts.map +1 -1
  71. package/dist/unified/src/unified/onchain-mailer-client.js +1462 -551
  72. package/dist/unified/src/unified/onchain-mailer-client.js.map +1 -1
  73. package/dist/unified/src/unified/types.d.ts +6 -23
  74. package/dist/unified/src/unified/types.d.ts.map +1 -1
  75. package/dist/unified/src/utils/chain-config.d.ts +2 -4
  76. package/dist/unified/src/utils/chain-config.d.ts.map +1 -1
  77. package/dist/unified/src/utils/chain-config.js +36 -46
  78. package/dist/unified/src/utils/chain-config.js.map +1 -1
  79. package/dist/unified/typechain-types/Mailer.d.ts +10 -128
  80. package/dist/unified/typechain-types/Mailer.d.ts.map +1 -1
  81. package/dist/unified/typechain-types/factories/Mailer__factory.d.ts +1 -145
  82. package/dist/unified/typechain-types/factories/Mailer__factory.d.ts.map +1 -1
  83. package/dist/unified/typechain-types/factories/Mailer__factory.js +1 -184
  84. package/dist/unified/typechain-types/factories/Mailer__factory.js.map +1 -1
  85. package/dist/unified-esm/src/evm/index.d.ts +1 -1
  86. package/dist/unified-esm/src/evm/index.d.ts.map +1 -1
  87. package/dist/unified-esm/src/evm/index.js +2 -2
  88. package/dist/unified-esm/src/evm/index.js.map +1 -1
  89. package/dist/unified-esm/src/evm/mailer-client.d.ts +210 -0
  90. package/dist/unified-esm/src/evm/mailer-client.d.ts.map +1 -0
  91. package/dist/unified-esm/src/evm/mailer-client.js +413 -0
  92. package/dist/unified-esm/src/evm/mailer-client.js.map +1 -0
  93. package/dist/unified-esm/src/react/context/MailerProvider.d.ts +20 -26
  94. package/dist/unified-esm/src/react/context/MailerProvider.d.ts.map +1 -1
  95. package/dist/unified-esm/src/react/context/MailerProvider.js +26 -25
  96. package/dist/unified-esm/src/react/context/MailerProvider.js.map +1 -1
  97. package/dist/unified-esm/src/react/hooks/useMailerMutations.d.ts +192 -225
  98. package/dist/unified-esm/src/react/hooks/useMailerMutations.d.ts.map +1 -1
  99. package/dist/unified-esm/src/react/hooks/useMailerMutations.js +262 -254
  100. package/dist/unified-esm/src/react/hooks/useMailerMutations.js.map +1 -1
  101. package/dist/unified-esm/src/react/hooks/useMailerQueries.d.ts +63 -117
  102. package/dist/unified-esm/src/react/hooks/useMailerQueries.d.ts.map +1 -1
  103. package/dist/unified-esm/src/react/hooks/useMailerQueries.js +102 -232
  104. package/dist/unified-esm/src/react/hooks/useMailerQueries.js.map +1 -1
  105. package/dist/unified-esm/src/react/index.d.ts +3 -5
  106. package/dist/unified-esm/src/react/index.d.ts.map +1 -1
  107. package/dist/unified-esm/src/react/index.js +5 -9
  108. package/dist/unified-esm/src/react/index.js.map +1 -1
  109. package/dist/unified-esm/src/solana/index.d.ts +1 -1
  110. package/dist/unified-esm/src/solana/index.d.ts.map +1 -1
  111. package/dist/unified-esm/src/solana/index.js +1 -2
  112. package/dist/unified-esm/src/solana/index.js.map +1 -1
  113. package/dist/unified-esm/src/solana/mailer-client.d.ts +209 -0
  114. package/dist/unified-esm/src/solana/mailer-client.d.ts.map +1 -0
  115. package/dist/unified-esm/src/solana/mailer-client.js +724 -0
  116. package/dist/unified-esm/src/solana/mailer-client.js.map +1 -0
  117. package/dist/unified-esm/src/solana/types.d.ts +2 -3
  118. package/dist/unified-esm/src/solana/types.d.ts.map +1 -1
  119. package/dist/unified-esm/src/solana/types.js.map +1 -1
  120. package/dist/unified-esm/src/unified/index.d.ts +1 -1
  121. package/dist/unified-esm/src/unified/index.d.ts.map +1 -1
  122. package/dist/unified-esm/src/unified/onchain-mailer-client.d.ts +247 -192
  123. package/dist/unified-esm/src/unified/onchain-mailer-client.d.ts.map +1 -1
  124. package/dist/unified-esm/src/unified/onchain-mailer-client.js +1462 -551
  125. package/dist/unified-esm/src/unified/onchain-mailer-client.js.map +1 -1
  126. package/dist/unified-esm/src/unified/types.d.ts +6 -23
  127. package/dist/unified-esm/src/unified/types.d.ts.map +1 -1
  128. package/dist/unified-esm/src/utils/chain-config.d.ts +2 -4
  129. package/dist/unified-esm/src/utils/chain-config.d.ts.map +1 -1
  130. package/dist/unified-esm/src/utils/chain-config.js +35 -46
  131. package/dist/unified-esm/src/utils/chain-config.js.map +1 -1
  132. package/dist/unified-esm/typechain-types/Mailer.d.ts +10 -128
  133. package/dist/unified-esm/typechain-types/Mailer.d.ts.map +1 -1
  134. package/dist/unified-esm/typechain-types/factories/Mailer__factory.d.ts +1 -145
  135. package/dist/unified-esm/typechain-types/factories/Mailer__factory.d.ts.map +1 -1
  136. package/dist/unified-esm/typechain-types/factories/Mailer__factory.js +1 -184
  137. package/dist/unified-esm/typechain-types/factories/Mailer__factory.js.map +1 -1
  138. package/package.json +10 -17
  139. package/programs/mailer/src/lib.rs +145 -764
  140. package/programs/mailer/tests/integration_tests.rs +65 -586
  141. package/typechain-types/Mailer.ts +8 -215
  142. package/typechain-types/factories/Mailer__factory.ts +1 -184
  143. package/dist/evm/src/evm/evm-mailer-client.d.ts +0 -1062
  144. package/dist/evm/src/evm/evm-mailer-client.d.ts.map +0 -1
  145. package/dist/evm/src/evm/evm-mailer-client.js +0 -924
  146. package/dist/evm/src/evm/evm-mailer-client.js.map +0 -1
  147. package/dist/solana/solana/solana-mailer-client.d.ts +0 -209
  148. package/dist/solana/solana/solana-mailer-client.d.ts.map +0 -1
  149. package/dist/solana/solana/solana-mailer-client.js +0 -1004
  150. package/dist/solana/solana/solana-mailer-client.js.map +0 -1
  151. package/dist/unified/src/evm/evm-mailer-client.d.ts +0 -1062
  152. package/dist/unified/src/evm/evm-mailer-client.d.ts.map +0 -1
  153. package/dist/unified/src/evm/evm-mailer-client.js +0 -924
  154. package/dist/unified/src/evm/evm-mailer-client.js.map +0 -1
  155. package/dist/unified/src/solana/solana-mailer-client.d.ts +0 -209
  156. package/dist/unified/src/solana/solana-mailer-client.d.ts.map +0 -1
  157. package/dist/unified/src/solana/solana-mailer-client.js +0 -1004
  158. package/dist/unified/src/solana/solana-mailer-client.js.map +0 -1
  159. package/dist/unified-esm/src/evm/evm-mailer-client.d.ts +0 -1062
  160. package/dist/unified-esm/src/evm/evm-mailer-client.d.ts.map +0 -1
  161. package/dist/unified-esm/src/evm/evm-mailer-client.js +0 -920
  162. package/dist/unified-esm/src/evm/evm-mailer-client.js.map +0 -1
  163. package/dist/unified-esm/src/solana/solana-mailer-client.d.ts +0 -209
  164. package/dist/unified-esm/src/solana/solana-mailer-client.d.ts.map +0 -1
  165. package/dist/unified-esm/src/solana/solana-mailer-client.js +0 -1000
  166. package/dist/unified-esm/src/solana/solana-mailer-client.js.map +0 -1
@@ -37,732 +37,1643 @@ 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 - Stateless multi-chain messaging client
42
+ * OnchainMailerClient - Multi-chain messaging client for Mailer protocol
42
43
  *
43
- * This version uses stateless EVM and Solana clients underneath.
44
- * All wallet connections and chain information are passed as parameters to each method.
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
48
+ * @example Basic Usage
47
49
  * ```typescript
48
- * import { createWalletClient, createPublicClient, http } from 'viem';
49
- * import { RpcHelpers } from '@sudobility/configs';
50
- * import { Chain } from '@sudobility/types';
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);
51
63
  *
52
- * const chainInfo = RpcHelpers.getChainInfo(Chain.ETH_MAINNET);
53
- * const walletClient = createWalletClient({
54
- * chain: mainnet,
55
- * transport: http()
56
- * });
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);
57
76
  *
58
- * const client = new OnchainMailerClient();
59
- * await client.sendMessage(
60
- * 'Subject',
61
- * 'Body',
62
- * { walletClient },
63
- * chainInfo,
64
- * { priority: true }
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
82
+ * @example Error Handling
69
83
  * ```typescript
70
- * import { useWallet } from '@solana/wallet-adapter-react';
71
- * import { Connection } from '@solana/web3.js';
72
- * import { RpcHelpers } from '@sudobility/configs';
73
- * import { Chain } from '@sudobility/types';
74
- *
75
- * const chainInfo = RpcHelpers.getChainInfo(Chain.SOLANA_MAINNET);
76
- * const wallet = useWallet();
77
- *
78
- * const client = new OnchainMailerClient();
79
- * await client.sendMessage(
80
- * 'Subject',
81
- * 'Body',
82
- * { wallet },
83
- * chainInfo,
84
- * { priority: true }
85
- * );
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
+ * }
86
96
  * ```
97
+ *
98
+ * @author Mailer Protocol Team
99
+ * @version 1.5.2
100
+ * @since 1.0.0
87
101
  */
88
102
  class OnchainMailerClient {
89
103
  /**
90
- * Create a new stateless OnchainMailerClient
91
- * No configuration needed in constructor
104
+ * Initialize OnchainMailerClient with wallet and chain configuration
105
+ *
106
+ * @param wallet - Wallet instance (EVM or Solana compatible)
107
+ * @param config - Chain configuration for EVM and/or Solana networks
108
+ *
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
+ * ```
92
122
  */
93
- constructor() {
94
- // Stateless - no initialization needed
123
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
124
+ constructor(wallet, config) {
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
+ }
95
144
  }
96
- // Performance optimization: cache client imports
97
- async getEVMClient() {
98
- if (!OnchainMailerClient.evmClient) {
99
- const { EVMMailerClient } = await Promise.resolve().then(() => __importStar(require('../evm/evm-mailer-client.js')));
100
- OnchainMailerClient.evmClient = new EVMMailerClient();
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)');
156
+ }
157
+ if (!this.config.evm.contracts || !this.config.evm.contracts.mailer) {
158
+ console.warn('EVM contract addresses not configured - some functionality may fail');
159
+ }
160
+ }
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)');
165
+ }
166
+ if (!this.config.solana.programs || !this.config.solana.programs.mailer) {
167
+ console.warn('Solana program addresses not configured - some functionality may fail');
168
+ }
101
169
  }
102
- return OnchainMailerClient.evmClient;
103
170
  }
104
- async getSolanaClient() {
105
- if (!OnchainMailerClient.solanaClient) {
106
- const { SolanaMailerClient } = await Promise.resolve().then(() => __importStar(require('../solana/solana-mailer-client.js')));
107
- OnchainMailerClient.solanaClient = new SolanaMailerClient();
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');
108
181
  }
109
- return OnchainMailerClient.solanaClient;
110
182
  }
111
183
  /**
112
- * Send a message on the blockchain
184
+ * Send a message using the appropriate chain implementation
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
+ *
113
189
  * @param subject - Message subject (1-200 characters)
114
190
  * @param body - Message body (1-10000 characters)
115
- * @param wallet - Wallet connection (EVM or Solana)
116
- * @param chainInfo - Chain information including RPC endpoints and contract addresses
117
- * @param options - Optional parameters
118
- * @returns Transaction result
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
+ * ```
119
224
  */
120
- async sendMessage(connectedWallet, chainInfo, subject, body, options) {
121
- // Validate message
122
- if (!subject || subject.length > 200) {
123
- throw new Error('Subject must be 1-200 characters');
124
- }
125
- if (!body || body.length > 10000) {
126
- throw new Error('Body must be 1-10000 characters');
127
- }
128
- // Route to appropriate implementation based on chain type
129
- if (chainInfo.chainType === types_1.ChainType.EVM) {
130
- const evmClient = await this.getEVMClient();
131
- const evmWallet = connectedWallet;
132
- const [account] = await evmWallet.walletClient.getAddresses();
133
- const to = options?.to || account;
134
- const priority = options?.priority ?? false;
135
- const resolveSenderToName = options?.resolveSenderToName ?? false;
136
- const result = await evmClient.send(evmWallet, chainInfo, to, subject, body, account, // payer
137
- priority, // revenueShareToReceiver
138
- resolveSenderToName, options?.gasOptions);
139
- return {
140
- transactionHash: result.hash,
141
- chainType: types_1.ChainType.EVM,
142
- fee: BigInt(priority ? '100000' : '10000'),
143
- gasUsed: result.gasUsed,
144
- isPriority: priority,
145
- success: true
146
- };
147
- }
148
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
149
- const solanaClient = await this.getSolanaClient();
150
- const solanaWallet = connectedWallet;
151
- const to = options?.to || solanaWallet.wallet.publicKey.toBase58();
152
- const priority = options?.priority ?? false;
153
- const result = await solanaClient.send(solanaWallet, chainInfo, to, subject, body, priority, // revenueShareToReceiver
154
- options?.computeOptions);
155
- return {
156
- transactionHash: result.transactionHash,
157
- chainType: types_1.ChainType.SOLANA,
158
- fee: BigInt(priority ? '100000' : '10000'),
159
- isPriority: priority,
160
- success: true
161
- };
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);
162
229
  }
163
230
  else {
164
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
231
+ return this.sendSolanaMessage(subject, body, priority, resolveSenderToName);
165
232
  }
166
233
  }
167
234
  /**
168
- * Send a prepared message
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
169
239
  */
170
- async sendPrepared(connectedWallet, chainInfo, to, mailId, options) {
171
- if (chainInfo.chainType === types_1.ChainType.EVM) {
172
- const evmClient = await this.getEVMClient();
173
- const evmWallet = connectedWallet;
174
- const [account] = await evmWallet.walletClient.getAddresses();
175
- const priority = options?.priority ?? false;
176
- const resolveSenderToName = options?.resolveSenderToName ?? false;
177
- const result = await evmClient.sendPrepared(evmWallet, chainInfo, to, mailId, account, // payer
178
- priority, // revenueShareToReceiver
179
- resolveSenderToName, options?.gasOptions);
180
- return {
181
- transactionHash: result.hash,
182
- chainType: types_1.ChainType.EVM,
183
- fee: BigInt(priority ? '100000' : '10000'),
184
- gasUsed: result.gasUsed,
185
- isPriority: priority,
186
- success: true
187
- };
188
- }
189
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
190
- const solanaClient = await this.getSolanaClient();
191
- const solanaWallet = connectedWallet;
192
- const priority = options?.priority ?? false;
193
- const result = await solanaClient.sendPrepared(solanaWallet, chainInfo, to, mailId, priority, options?.computeOptions);
194
- return {
195
- transactionHash: result.transactionHash,
196
- chainType: types_1.ChainType.SOLANA,
197
- fee: BigInt(priority ? '100000' : '10000'),
198
- isPriority: priority,
199
- success: true
200
- };
240
+ async registerDomain(domain, isExtension = false) {
241
+ if (this.chainType === 'evm') {
242
+ return this.registerEVMDomain(domain, isExtension);
201
243
  }
202
244
  else {
203
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
245
+ return this.registerSolanaDomain(domain, isExtension);
204
246
  }
205
247
  }
206
248
  /**
207
- * Send through webhook
249
+ * Delegate to another address using the appropriate chain implementation
250
+ * @param delegate - Address to delegate to
251
+ * @returns Delegation result
208
252
  */
209
- async sendThroughWebhook(connectedWallet, chainInfo, to, webhookId, options) {
210
- if (chainInfo.chainType === types_1.ChainType.EVM) {
211
- const evmClient = await this.getEVMClient();
212
- const evmWallet = connectedWallet;
213
- const [account] = await evmWallet.walletClient.getAddresses();
214
- const priority = options?.priority ?? false;
215
- const result = await evmClient.sendThroughWebhook(to, subject, body, webhookId, account, // payer
216
- priority, evmWallet, chainInfo, options?.gasOptions);
217
- return {
218
- transactionHash: result.hash,
219
- chainType: types_1.ChainType.EVM,
220
- fee: BigInt(priority ? '100000' : '10000'),
221
- gasUsed: result.gasUsed,
222
- isPriority: priority,
223
- success: true
224
- };
253
+ async delegateTo(delegate) {
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})`);
225
258
  }
226
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
227
- const solanaClient = await this.getSolanaClient();
228
- const solanaWallet = connectedWallet;
229
- const priority = options?.priority ?? false;
230
- const result = await solanaClient.sendThroughWebhook(solanaWallet, chainInfo, to, webhookId, priority, options?.computeOptions);
231
- return {
232
- transactionHash: result.transactionHash,
233
- chainType: types_1.ChainType.SOLANA,
234
- fee: BigInt(priority ? '100000' : '10000'),
235
- isPriority: priority,
236
- success: true
237
- };
259
+ if (this.chainType === 'evm') {
260
+ return this.delegateEVM(delegate);
238
261
  }
239
262
  else {
240
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
263
+ return this.delegateSolana(delegate);
241
264
  }
242
265
  }
243
266
  /**
244
- * Delegate to another address
245
- * @param delegate - Address to delegate to
246
- * @param wallet - Wallet connection
247
- * @param chainInfo - Chain information
267
+ * Claim revenue share using the appropriate chain implementation
248
268
  * @returns Transaction result
249
269
  */
250
- async delegateTo(connectedWallet, chainInfo, delegate, options) {
251
- if (chainInfo.chainType === types_1.ChainType.EVM) {
252
- const evmClient = await this.getEVMClient();
253
- const result = await evmClient.delegateTo(delegate, connectedWallet, chainInfo, options?.gasOptions);
254
- return {
255
- transactionHash: result.hash,
256
- chainType: types_1.ChainType.EVM,
257
- delegate,
258
- success: true
259
- };
260
- }
261
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
262
- const solanaClient = await this.getSolanaClient();
263
- const result = await solanaClient.delegateTo(delegate, connectedWallet, chainInfo, options?.computeOptions);
264
- return {
265
- transactionHash: result.transactionHash,
266
- chainType: types_1.ChainType.SOLANA,
267
- delegate,
268
- success: true
269
- };
270
+ async claimRevenue() {
271
+ if (this.chainType === 'evm') {
272
+ return this.claimEVMRevenue();
270
273
  }
271
274
  else {
272
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
275
+ return this.claimSolanaRevenue();
273
276
  }
274
277
  }
275
- /**
276
- * Reject delegation
277
- */
278
- async rejectDelegation(connectedWallet, chainInfo, delegatingAddress, options) {
279
- if (chainInfo.chainType === types_1.ChainType.EVM) {
280
- const evmClient = await this.getEVMClient();
281
- const result = await evmClient.rejectDelegation(connectedWallet, chainInfo, delegatingAddress, options?.gasOptions);
282
- return {
283
- hash: result.hash,
284
- chainType: types_1.ChainType.EVM
285
- };
286
- }
287
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
288
- const solanaClient = await this.getSolanaClient();
289
- const result = await solanaClient.rejectDelegation(connectedWallet, chainInfo, delegatingAddress, options?.computeOptions);
278
+ // Performance optimization: cache module imports
279
+ async getEVMModules() {
280
+ if (!OnchainMailerClient.evmModules) {
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
+ }
294
+ }
295
+ return OnchainMailerClient.evmModules;
296
+ }
297
+ async getSolanaModules() {
298
+ if (!OnchainMailerClient.solanaModules) {
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
+ }
313
+ }
314
+ return OnchainMailerClient.solanaModules;
315
+ }
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
+ ]);
290
386
  return {
291
- hash: result.transactionHash,
292
- chainType: types_1.ChainType.SOLANA
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
293
394
  };
294
395
  }
295
- else {
296
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
396
+ catch (error) {
397
+ throw new Error(`EVM message sending failed: ${error instanceof Error ? error.message : String(error)}`);
297
398
  }
298
399
  }
299
- /**
300
- * Claim revenue share
301
- * @param wallet - Wallet connection
302
- * @param chainInfo - Chain information
303
- * @returns Transaction result
304
- */
305
- async claimRevenue(connectedWallet, chainInfo, options) {
306
- if (chainInfo.chainType === types_1.ChainType.EVM) {
307
- const evmClient = await this.getEVMClient();
308
- const result = await evmClient.claimRecipientShare(connectedWallet, chainInfo, options?.gasOptions);
309
- return {
310
- hash: result.hash,
311
- chainType: types_1.ChainType.EVM
312
- };
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');
403
+ }
404
+ async delegateEVM(delegate) {
405
+ const { viem } = await this.getEVMModules();
406
+ if (!this.config.evm) {
407
+ throw new Error('EVM configuration not provided');
313
408
  }
314
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
315
- const solanaClient = await this.getSolanaClient();
316
- const result = await solanaClient.claimRecipientShare(connectedWallet, chainInfo, options?.computeOptions);
317
- return {
318
- hash: result.transactionHash,
319
- chainType: types_1.ChainType.SOLANA
320
- };
321
- }
322
- else {
323
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
409
+ // Validate EVM address format
410
+ if (!viem.isAddress(delegate)) {
411
+ throw new Error('Invalid EVM address format for delegate');
324
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');
325
415
  }
326
- /**
327
- * Claim owner share (owner only)
328
- */
329
- async claimOwnerShare(connectedWallet, chainInfo, options) {
330
- if (chainInfo.chainType === types_1.ChainType.EVM) {
331
- const evmClient = await this.getEVMClient();
332
- const result = await evmClient.claimOwnerShare(connectedWallet, chainInfo, options?.gasOptions);
416
+ async claimEVMRevenue() {
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 });
447
+ return {
448
+ hash: txHash,
449
+ chainType: types_1.ChainType.EVM,
450
+ blockNumber: receipt.blockNumber,
451
+ timestamp: Number(block.timestamp) * 1000
452
+ };
453
+ }
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();
333
491
  return {
334
- hash: result.hash,
335
- chainType: types_1.ChainType.EVM
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
336
502
  };
337
503
  }
338
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
339
- const solanaClient = await this.getSolanaClient();
340
- const result = await solanaClient.claimOwnerShare(connectedWallet, chainInfo, options?.computeOptions);
341
- return {
342
- hash: result.transactionHash,
343
- chainType: types_1.ChainType.SOLANA
344
- };
504
+ catch (error) {
505
+ throw new Error(`Solana message sending failed: ${error instanceof Error ? error.message : String(error)}`);
345
506
  }
346
- else {
347
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
507
+ }
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');
348
515
  }
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');
518
+ }
519
+ async claimSolanaRevenue() {
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();
532
+ return {
533
+ hash: txHash,
534
+ chainType: types_1.ChainType.SOLANA,
535
+ slot,
536
+ timestamp: Date.now()
537
+ };
349
538
  }
350
539
  /**
351
- * Claim expired shares (owner only)
540
+ * Get send fee using the appropriate chain implementation
541
+ * @returns Send fee in USDC micro-units (6 decimals)
352
542
  */
353
- async claimExpiredShares(connectedWallet, chainInfo, recipient, options) {
354
- if (chainInfo.chainType === types_1.ChainType.EVM) {
355
- const evmClient = await this.getEVMClient();
356
- const result = await evmClient.claimExpiredShares(recipient, connectedWallet, chainInfo, options?.gasOptions);
357
- return {
358
- hash: result.hash,
359
- chainType: types_1.ChainType.EVM
360
- };
361
- }
362
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
363
- const solanaClient = await this.getSolanaClient();
364
- const result = await solanaClient.claimExpiredShares(recipient, connectedWallet, chainInfo, options?.computeOptions);
365
- return {
366
- hash: result.transactionHash,
367
- chainType: types_1.ChainType.SOLANA
368
- };
543
+ async getSendFee() {
544
+ if (this.chainType === 'evm') {
545
+ return this.getEVMSendFee();
369
546
  }
370
547
  else {
371
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
548
+ return this.getSolanaSendFee();
372
549
  }
373
550
  }
374
551
  /**
375
- * Set fees (owner only)
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
376
555
  */
377
- async setFees(connectedWallet, chainInfo, sendFee, delegationFee, options) {
378
- if (chainInfo.chainType === types_1.ChainType.EVM) {
379
- const evmClient = await this.getEVMClient();
380
- // EVM client uses separate methods
381
- await evmClient.setFee(connectedWallet, chainInfo, sendFee, options?.gasOptions);
382
- const result2 = await evmClient.setDelegationFee(connectedWallet, chainInfo, delegationFee, options?.gasOptions);
383
- return {
384
- hash: result2.hash, // Return last transaction
385
- chainType: types_1.ChainType.EVM
386
- };
387
- }
388
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
389
- const solanaClient = await this.getSolanaClient();
390
- const result = await solanaClient.setFees(connectedWallet, chainInfo, sendFee, delegationFee, options?.computeOptions);
391
- return {
392
- hash: result.transactionHash,
393
- chainType: types_1.ChainType.SOLANA
394
- };
556
+ async getClaimableAmount(address) {
557
+ const targetAddress = address || this.wallet.address;
558
+ if (this.chainType === 'evm') {
559
+ return this.getEVMClaimableAmount(targetAddress);
395
560
  }
396
561
  else {
397
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
562
+ return this.getSolanaClaimableAmount(targetAddress);
398
563
  }
399
564
  }
400
565
  /**
401
- * Set custom fee percentage
566
+ * Get owner's claimable fee balance
567
+ * @returns Owner claimable amount in USDC micro-units
402
568
  */
403
- async setCustomFeePercentage(connectedWallet, chainInfo, target, percentage, options) {
404
- if (chainInfo.chainType === types_1.ChainType.EVM) {
405
- const evmClient = await this.getEVMClient();
406
- const result = await evmClient.setCustomFeePercentage(connectedWallet, chainInfo, target, percentage, options?.gasOptions);
407
- return {
408
- hash: result.hash,
409
- chainType: types_1.ChainType.EVM
410
- };
411
- }
412
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
413
- const solanaClient = await this.getSolanaClient();
414
- const result = await solanaClient.setCustomFeePercentage(connectedWallet, chainInfo, target, percentage, options?.computeOptions);
415
- return {
416
- hash: result.transactionHash,
417
- chainType: types_1.ChainType.SOLANA
418
- };
569
+ async getOwnerClaimable() {
570
+ if (this.chainType === 'evm') {
571
+ return this.getEVMOwnerClaimable();
419
572
  }
420
573
  else {
421
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
574
+ return this.getSolanaOwnerClaimable();
422
575
  }
423
576
  }
424
577
  /**
425
- * Clear custom fee percentage
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
426
581
  */
427
- async clearCustomFeePercentage(connectedWallet, chainInfo, target, options) {
428
- if (chainInfo.chainType === types_1.ChainType.EVM) {
429
- const evmClient = await this.getEVMClient();
430
- const result = await evmClient.clearCustomFeePercentage(connectedWallet, chainInfo, target, options?.gasOptions);
431
- return {
432
- hash: result.hash,
433
- chainType: types_1.ChainType.EVM
434
- };
435
- }
436
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
437
- const solanaClient = await this.getSolanaClient();
438
- const result = await solanaClient.clearCustomFeePercentage(connectedWallet, chainInfo, target, options?.computeOptions);
439
- return {
440
- hash: result.transactionHash,
441
- chainType: types_1.ChainType.SOLANA
442
- };
582
+ async getDelegation(address) {
583
+ const targetAddress = address || this.wallet.address;
584
+ if (this.chainType === 'evm') {
585
+ return this.getEVMDelegation(targetAddress);
443
586
  }
444
587
  else {
445
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
588
+ return this.getSolanaDelegation(targetAddress);
446
589
  }
447
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
+ }
650
+ async getEVMDelegation(_address) {
651
+ // Delegation read not implemented in EVM client yet
652
+ // Would need to add getDelegation method to EVM MailerClient
653
+ throw new Error('getDelegation not yet implemented for EVM');
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
+ }
699
+ async getSolanaDelegation(address) {
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);
710
+ const delegatorKey = new PublicKey(address);
711
+ const delegationInfo = await client.getDelegation(delegatorKey);
712
+ return delegationInfo?.delegate || null;
713
+ }
448
714
  /**
449
- * Pause the contract/program (owner only)
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
450
721
  */
451
- async pause(connectedWallet, chainInfo, options) {
452
- if (chainInfo.chainType === types_1.ChainType.EVM) {
453
- const evmClient = await this.getEVMClient();
454
- const result = await evmClient.pause(connectedWallet, chainInfo, options?.gasOptions);
455
- return {
456
- hash: result.hash,
457
- chainType: types_1.ChainType.EVM
458
- };
459
- }
460
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
461
- const solanaClient = await this.getSolanaClient();
462
- const result = await solanaClient.pause(connectedWallet, chainInfo, options?.computeOptions);
463
- return {
464
- hash: result.transactionHash,
465
- chainType: types_1.ChainType.SOLANA
466
- };
722
+ async sendPrepared(to, mailId, priority = false, resolveSenderToName = false) {
723
+ if (this.chainType === 'evm') {
724
+ return this.sendPreparedEVM(to, mailId, priority, resolveSenderToName);
467
725
  }
468
726
  else {
469
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
727
+ return this.sendPreparedSolana(to, mailId, priority, resolveSenderToName);
470
728
  }
471
729
  }
472
730
  /**
473
- * Unpause the contract/program (owner only)
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
474
736
  */
475
- async unpause(connectedWallet, chainInfo, options) {
476
- if (chainInfo.chainType === types_1.ChainType.EVM) {
477
- const evmClient = await this.getEVMClient();
478
- const result = await evmClient.unpause(connectedWallet, chainInfo, options?.gasOptions);
479
- return {
480
- hash: result.hash,
481
- chainType: types_1.ChainType.EVM
482
- };
483
- }
484
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
485
- const solanaClient = await this.getSolanaClient();
486
- const result = await solanaClient.unpause(connectedWallet, chainInfo, options?.computeOptions);
487
- return {
488
- hash: result.transactionHash,
489
- chainType: types_1.ChainType.SOLANA
490
- };
737
+ async sendToEmail(toEmail, subject, body) {
738
+ if (this.chainType === 'evm') {
739
+ return this.sendToEmailEVM(toEmail, subject, body);
491
740
  }
492
741
  else {
493
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
742
+ return this.sendToEmailSolana(toEmail, subject, body);
494
743
  }
495
744
  }
496
745
  /**
497
- * Emergency unpause (owner only)
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
498
750
  */
499
- async emergencyUnpause(connectedWallet, chainInfo, options) {
500
- if (chainInfo.chainType === types_1.ChainType.EVM) {
501
- const evmClient = await this.getEVMClient();
502
- const result = await evmClient.emergencyUnpause(connectedWallet, chainInfo, options?.gasOptions);
503
- return {
504
- hash: result.hash,
505
- chainType: types_1.ChainType.EVM
506
- };
507
- }
508
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
509
- const solanaClient = await this.getSolanaClient();
510
- const result = await solanaClient.emergencyUnpause(connectedWallet, chainInfo, options?.computeOptions);
511
- return {
512
- hash: result.transactionHash,
513
- chainType: types_1.ChainType.SOLANA
514
- };
751
+ async sendPreparedToEmail(toEmail, mailId) {
752
+ if (this.chainType === 'evm') {
753
+ return this.sendPreparedToEmailEVM(toEmail, mailId);
515
754
  }
516
755
  else {
517
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
756
+ return this.sendPreparedToEmailSolana(toEmail, mailId);
518
757
  }
519
758
  }
520
759
  /**
521
- * Distribute claimable funds when paused
522
- * Note: EVM supports single recipient, Solana supports multiple
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
523
763
  */
524
- async distributeClaimableFunds(connectedWallet, chainInfo, recipient, options) {
525
- if (chainInfo.chainType === types_1.ChainType.EVM) {
526
- const evmClient = await this.getEVMClient();
527
- // EVM only supports single recipient
528
- const singleRecipient = Array.isArray(recipient) ? recipient[0] : recipient;
529
- const result = await evmClient.distributeClaimableFunds(connectedWallet, chainInfo, singleRecipient, options?.gasOptions);
530
- return {
531
- hash: result.hash,
532
- chainType: types_1.ChainType.EVM
533
- };
534
- }
535
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
536
- const solanaClient = await this.getSolanaClient();
537
- // Solana supports multiple recipients
538
- const recipients = Array.isArray(recipient) ? recipient : [recipient];
539
- const result = await solanaClient.distributeClaimableFunds(connectedWallet, chainInfo, recipients, options?.computeOptions);
540
- return {
541
- hash: result.transactionHash,
542
- chainType: types_1.ChainType.SOLANA
543
- };
764
+ async setFee(newFee) {
765
+ if (this.chainType === 'evm') {
766
+ return this.setFeeEVM(newFee);
544
767
  }
545
768
  else {
546
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
769
+ return this.setFeeSolana(newFee);
547
770
  }
548
771
  }
549
772
  /**
550
- * Set permission for a contract to use caller's USDC for sending messages
551
- * Note: Only supported on EVM chains
773
+ * Get the current send fee
774
+ * @returns Current send fee in USDC micro-units (6 decimals)
552
775
  */
553
- async setPermission(connectedWallet, chainInfo, contractAddress, options) {
554
- if (chainInfo.chainType === types_1.ChainType.EVM) {
555
- const evmClient = await this.getEVMClient();
556
- const result = await evmClient.setPermission(connectedWallet, chainInfo, contractAddress, options?.gasOptions);
557
- return {
558
- hash: result.hash,
559
- chainType: types_1.ChainType.EVM
560
- };
561
- }
562
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
563
- throw new Error('Permission system is not supported on Solana');
564
- }
565
- else {
566
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
567
- }
776
+ async getFee() {
777
+ return this.getSendFee();
568
778
  }
569
779
  /**
570
- * Remove permission from a contract
571
- * Note: Only supported on EVM chains
780
+ * Set the delegation fee (owner only)
781
+ * @param newFee - New delegation fee in USDC micro-units
782
+ * @returns Promise resolving to transaction details
572
783
  */
573
- async removePermission(connectedWallet, chainInfo, contractAddress, options) {
574
- if (chainInfo.chainType === types_1.ChainType.EVM) {
575
- const evmClient = await this.getEVMClient();
576
- const result = await evmClient.removePermission(connectedWallet, chainInfo, contractAddress, options?.gasOptions);
577
- return {
578
- hash: result.hash,
579
- chainType: types_1.ChainType.EVM
580
- };
581
- }
582
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
583
- throw new Error('Permission system is not supported on Solana');
784
+ async setDelegationFee(newFee) {
785
+ if (this.chainType === 'evm') {
786
+ return this.setDelegationFeeEVM(newFee);
584
787
  }
585
788
  else {
586
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
789
+ return this.setDelegationFeeSolana(newFee);
587
790
  }
588
791
  }
589
792
  /**
590
- * Check if permission exists for a contract/wallet pair
591
- * Note: Only supported on EVM chains
793
+ * Get the current delegation fee
794
+ * @returns Current delegation fee in USDC micro-units
592
795
  */
593
- async hasPermission(chainInfo, contractAddress, walletAddress, publicClient) {
594
- if (chainInfo.chainType === types_1.ChainType.EVM) {
595
- const evmClient = await this.getEVMClient();
596
- return await evmClient.hasPermission(chainInfo, contractAddress, walletAddress, publicClient);
597
- }
598
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
599
- // Solana doesn't have permission system, always return false
600
- return false;
796
+ async getDelegationFee() {
797
+ if (this.chainType === 'evm') {
798
+ return this.getDelegationFeeEVM();
601
799
  }
602
800
  else {
603
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
801
+ return this.getDelegationFeeSolana();
604
802
  }
605
803
  }
606
- // ============= Read Methods =============
607
804
  /**
608
- * Get the send fee for messages
609
- * @param chainInfo - Chain information with RPC endpoint
610
- * @param publicClient - Optional public client for EVM (will create if not provided)
611
- * @param connection - Optional connection for Solana (will create if not provided)
612
- * @returns Fee amount in USDC micro-units
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
613
808
  */
614
- async getSendFee(chainInfo, publicClient, connection) {
615
- if (chainInfo.chainType === types_1.ChainType.EVM) {
616
- const evmClient = await this.getEVMClient();
617
- return await evmClient.getSendFee(chainInfo, publicClient);
618
- }
619
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
620
- const solanaClient = await this.getSolanaClient();
621
- return await solanaClient.getSendFee(chainInfo, connection);
809
+ async rejectDelegation(delegatorAddress) {
810
+ if (this.chainType === 'evm') {
811
+ return this.rejectDelegationEVM(delegatorAddress);
622
812
  }
623
813
  else {
624
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
814
+ return this.rejectDelegationSolana(delegatorAddress);
625
815
  }
626
816
  }
627
817
  /**
628
- * Get delegation fee
818
+ * Claim owner share of fees (owner only)
819
+ * @returns Promise resolving to transaction details
629
820
  */
630
- async getDelegationFee(chainInfo, publicClient, connection) {
631
- if (chainInfo.chainType === types_1.ChainType.EVM) {
632
- const evmClient = await this.getEVMClient();
633
- return await evmClient.getDelegationFee(chainInfo, publicClient);
634
- }
635
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
636
- const solanaClient = await this.getSolanaClient();
637
- return await solanaClient.getDelegationFee(chainInfo, connection);
821
+ async claimOwnerShare() {
822
+ if (this.chainType === 'evm') {
823
+ return this.claimOwnerShareEVM();
638
824
  }
639
825
  else {
640
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
826
+ return this.claimOwnerShareSolana();
641
827
  }
642
828
  }
643
829
  /**
644
- * Get delegation for an address
645
- * @param address - Address to check
646
- * @param chainInfo - Chain information with RPC endpoint
647
- * @param publicClient - Optional public client for EVM
648
- * @param connection - Optional connection for Solana
649
- * @returns Delegated address or null
830
+ * Claim expired shares (owner only, EVM only)
831
+ * @param recipient - Address to claim expired shares for
832
+ * @returns Promise resolving to transaction details
650
833
  */
651
- async getDelegation(address, chainInfo, publicClient, connection) {
652
- if (chainInfo.chainType === types_1.ChainType.EVM) {
653
- const evmClient = await this.getEVMClient();
654
- const delegation = await evmClient.getDelegation(address, chainInfo, publicClient);
655
- return delegation === '0x0000000000000000000000000000000000000000' ? null : delegation;
656
- }
657
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
658
- const solanaClient = await this.getSolanaClient();
659
- const delegation = await solanaClient.getDelegation(address, chainInfo, connection);
660
- return delegation ? delegation.toBase58() : null;
834
+ async claimExpiredShares(recipient) {
835
+ if (this.chainType === 'evm') {
836
+ return this.claimExpiredSharesEVM(recipient);
661
837
  }
662
838
  else {
663
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
839
+ throw new Error('claimExpiredShares not available on Solana');
664
840
  }
665
841
  }
666
842
  /**
667
- * Get recipient claimable info
843
+ * Pause the contract and distribute funds (owner only)
844
+ * @returns Promise resolving to transaction details
668
845
  */
669
- async getRecipientClaimable(recipient, chainInfo, publicClient, connection) {
670
- if (chainInfo.chainType === types_1.ChainType.EVM) {
671
- const evmClient = await this.getEVMClient();
672
- return await evmClient.getRecipientClaimable(recipient, chainInfo, publicClient);
673
- }
674
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
675
- const solanaClient = await this.getSolanaClient();
676
- const info = await solanaClient.getRecipientClaimable(recipient, chainInfo, connection);
677
- if (!info)
678
- return null;
679
- return {
680
- amount: BigInt(info.amount),
681
- expiresAt: BigInt(info.expiresAt),
682
- isExpired: info.isExpired
683
- };
846
+ async pause() {
847
+ if (this.chainType === 'evm') {
848
+ return this.pauseEVM();
684
849
  }
685
850
  else {
686
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
851
+ return this.pauseSolana();
687
852
  }
688
853
  }
689
854
  /**
690
- * Get owner claimable amount
855
+ * Unpause the contract (owner only)
856
+ * @returns Promise resolving to transaction details
691
857
  */
692
- async getOwnerClaimable(chainInfo, publicClient, connection) {
693
- if (chainInfo.chainType === types_1.ChainType.EVM) {
694
- const evmClient = await this.getEVMClient();
695
- return await evmClient.getOwnerClaimable(chainInfo, publicClient);
696
- }
697
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
698
- const solanaClient = await this.getSolanaClient();
699
- const amount = await solanaClient.getOwnerClaimable(chainInfo, connection);
700
- return BigInt(amount);
858
+ async unpause() {
859
+ if (this.chainType === 'evm') {
860
+ return this.unpauseEVM();
701
861
  }
702
862
  else {
703
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
863
+ return this.unpauseSolana();
704
864
  }
705
865
  }
706
866
  /**
707
- * Get custom fee percentage
867
+ * Emergency unpause without fund distribution (owner only)
868
+ * @returns Promise resolving to transaction details
708
869
  */
709
- async getCustomFeePercentage(target, chainInfo, publicClient, connection) {
710
- if (chainInfo.chainType === types_1.ChainType.EVM) {
711
- const evmClient = await this.getEVMClient();
712
- return await evmClient.getCustomFeePercentage(target, chainInfo, publicClient);
713
- }
714
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
715
- const solanaClient = await this.getSolanaClient();
716
- return await solanaClient.getCustomFeePercentage(target, chainInfo, connection);
870
+ async emergencyUnpause() {
871
+ if (this.chainType === 'evm') {
872
+ return this.emergencyUnpauseEVM();
717
873
  }
718
874
  else {
719
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
875
+ return this.emergencyUnpauseSolana();
720
876
  }
721
877
  }
722
878
  /**
723
- * Check if contract/program is paused
879
+ * Check if contract is currently paused
880
+ * @returns True if contract is paused, false otherwise
724
881
  */
725
- async isPaused(chainInfo, publicClient, connection) {
726
- if (chainInfo.chainType === types_1.ChainType.EVM) {
727
- const evmClient = await this.getEVMClient();
728
- return await evmClient.isPaused(chainInfo, publicClient);
729
- }
730
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
731
- const solanaClient = await this.getSolanaClient();
732
- return await solanaClient.isPaused(chainInfo, connection);
882
+ async isPaused() {
883
+ if (this.chainType === 'evm') {
884
+ return this.isPausedEVM();
733
885
  }
734
886
  else {
735
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
887
+ return this.isPausedSolana();
736
888
  }
737
889
  }
738
890
  /**
739
- * Get contract/program owner
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
740
894
  */
741
- async getOwner(chainInfo, publicClient, connection) {
742
- if (chainInfo.chainType === types_1.ChainType.EVM) {
743
- const evmClient = await this.getEVMClient();
744
- return await evmClient.getOwner(chainInfo, publicClient);
745
- }
746
- else if (chainInfo.chainType === types_1.ChainType.SOLANA) {
747
- const solanaClient = await this.getSolanaClient();
748
- const owner = await solanaClient.getOwner(chainInfo, connection);
749
- return owner.toBase58();
895
+ async distributeClaimableFunds(recipient) {
896
+ if (this.chainType === 'evm') {
897
+ return this.distributeClaimableFundsEVM(recipient);
750
898
  }
751
899
  else {
752
- throw new Error(`Unsupported chain type: ${chainInfo.chainType}`);
900
+ return this.distributeClaimableFundsSolana(recipient);
753
901
  }
754
902
  }
755
- /**
756
- * Register a domain (not implemented - for backward compatibility)
757
- */
758
- async registerDomain(_domain) {
759
- throw new Error('Domain registration not yet implemented');
903
+ // EVM Implementation Methods
904
+ async sendPreparedEVM(to, mailId, priority, resolveSenderToName) {
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 });
934
+ return {
935
+ transactionHash: txHash,
936
+ chainType: types_1.ChainType.EVM,
937
+ fee: BigInt(priority ? '100000' : '10000'),
938
+ gasUsed: receipt.gasUsed,
939
+ isPriority: priority,
940
+ success: true
941
+ };
942
+ }
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 });
973
+ return {
974
+ transactionHash: txHash,
975
+ chainType: types_1.ChainType.EVM,
976
+ fee: BigInt('10000'), // 10% fee only
977
+ gasUsed: receipt.gasUsed,
978
+ isPriority: false,
979
+ success: true
980
+ };
981
+ }
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 });
1012
+ return {
1013
+ transactionHash: txHash,
1014
+ chainType: types_1.ChainType.EVM,
1015
+ fee: BigInt('10000'), // 10% fee only
1016
+ gasUsed: receipt.gasUsed,
1017
+ isPriority: false,
1018
+ success: true
1019
+ };
1020
+ }
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 });
1052
+ return {
1053
+ hash: txHash,
1054
+ chainType: types_1.ChainType.EVM,
1055
+ blockNumber: receipt.blockNumber,
1056
+ timestamp: Number(block.timestamp) * 1000
1057
+ };
1058
+ }
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
+ };
1096
+ }
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 });
1147
+ return {
1148
+ hash: txHash,
1149
+ chainType: types_1.ChainType.EVM,
1150
+ blockNumber: receipt.blockNumber,
1151
+ timestamp: Number(block.timestamp) * 1000
1152
+ };
1153
+ }
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 });
1185
+ return {
1186
+ hash: txHash,
1187
+ chainType: types_1.ChainType.EVM,
1188
+ blockNumber: receipt.blockNumber,
1189
+ timestamp: Number(block.timestamp) * 1000
1190
+ };
1191
+ }
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
+ };
1229
+ }
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 });
1261
+ return {
1262
+ hash: txHash,
1263
+ chainType: types_1.ChainType.EVM,
1264
+ blockNumber: receipt.blockNumber,
1265
+ timestamp: Number(block.timestamp) * 1000
1266
+ };
1267
+ }
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 });
1299
+ return {
1300
+ hash: txHash,
1301
+ chainType: types_1.ChainType.EVM,
1302
+ blockNumber: receipt.blockNumber,
1303
+ timestamp: Number(block.timestamp) * 1000
1304
+ };
1305
+ }
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
+ };
1343
+ }
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 });
1394
+ return {
1395
+ hash: txHash,
1396
+ chainType: types_1.ChainType.EVM,
1397
+ blockNumber: receipt.blockNumber,
1398
+ timestamp: Number(block.timestamp) * 1000
1399
+ };
1400
+ }
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 });
1418
+ return {
1419
+ transactionHash: txHash,
1420
+ chainType: types_1.ChainType.SOLANA,
1421
+ fee: priority ? fees.sendFee : fees.sendFee / 10,
1422
+ slot,
1423
+ timestamp: tx?.blockTime ? tx.blockTime * 1000 : Date.now(),
1424
+ isPriority: priority,
1425
+ success: true
1426
+ };
1427
+ }
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
+ };
1452
+ }
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 });
1468
+ return {
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,
1495
+ timestamp: Date.now()
1496
+ };
1497
+ }
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();
1511
+ return {
1512
+ hash: txHash,
1513
+ chainType: types_1.ChainType.SOLANA,
1514
+ slot,
1515
+ timestamp: Date.now()
1516
+ };
1517
+ }
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);
1531
+ }
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();
1545
+ return {
1546
+ hash: txHash,
1547
+ chainType: types_1.ChainType.SOLANA,
1548
+ slot,
1549
+ timestamp: Date.now()
1550
+ };
1551
+ }
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();
1565
+ return {
1566
+ hash: txHash,
1567
+ chainType: types_1.ChainType.SOLANA,
1568
+ slot,
1569
+ timestamp: Date.now()
1570
+ };
1571
+ }
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();
1585
+ return {
1586
+ hash: txHash,
1587
+ chainType: types_1.ChainType.SOLANA,
1588
+ slot,
1589
+ timestamp: Date.now()
1590
+ };
1591
+ }
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();
1605
+ return {
1606
+ hash: txHash,
1607
+ chainType: types_1.ChainType.SOLANA,
1608
+ slot,
1609
+ timestamp: Date.now()
1610
+ };
1611
+ }
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();
1625
+ return {
1626
+ hash: txHash,
1627
+ chainType: types_1.ChainType.SOLANA,
1628
+ slot,
1629
+ timestamp: Date.now()
1630
+ };
1631
+ }
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();
1658
+ return {
1659
+ hash: txHash,
1660
+ chainType: types_1.ChainType.SOLANA,
1661
+ slot,
1662
+ timestamp: Date.now()
1663
+ };
1664
+ }
1665
+ // Utility methods
1666
+ getChainType() {
1667
+ return this.chainType;
1668
+ }
1669
+ getWalletAddress() {
1670
+ return this.wallet.address;
760
1671
  }
761
1672
  }
762
1673
  exports.OnchainMailerClient = OnchainMailerClient;
763
- // Cache for dynamic imports
1674
+ // Performance optimization: cache imported modules
764
1675
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
765
- OnchainMailerClient.evmClient = null;
1676
+ OnchainMailerClient.evmModules = null;
766
1677
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
767
- OnchainMailerClient.solanaClient = null;
1678
+ OnchainMailerClient.solanaModules = null;
768
1679
  //# sourceMappingURL=onchain-mailer-client.js.map