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