@sudobility/contracts 1.11.1 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/artifacts/contracts/Mailer.sol/Mailer.d.ts +120 -2
  2. package/artifacts/contracts/Mailer.sol/Mailer.dbg.json +1 -1
  3. package/artifacts/contracts/Mailer.sol/Mailer.json +120 -2
  4. package/artifacts/contracts/MockUSDC.sol/MockUSDC.dbg.json +1 -1
  5. package/artifacts/contracts/interfaces/IERC20.sol/IERC20.dbg.json +1 -1
  6. package/dist/evm/src/evm/index.d.ts +1 -1
  7. package/dist/evm/src/evm/index.d.ts.map +1 -1
  8. package/dist/evm/src/evm/index.js +1 -1
  9. package/dist/evm/src/evm/index.js.map +1 -1
  10. package/dist/evm/src/evm/mailer-client.d.ts +936 -180
  11. package/dist/evm/src/evm/mailer-client.d.ts.map +1 -1
  12. package/dist/evm/src/evm/mailer-client.js +451 -249
  13. package/dist/evm/src/evm/mailer-client.js.map +1 -1
  14. package/dist/evm/typechain-types/Mailer.d.ts +81 -11
  15. package/dist/evm/typechain-types/Mailer.d.ts.map +1 -1
  16. package/dist/evm/typechain-types/factories/Mailer__factory.d.ts +93 -1
  17. package/dist/evm/typechain-types/factories/Mailer__factory.d.ts.map +1 -1
  18. package/dist/evm/typechain-types/factories/Mailer__factory.js +119 -1
  19. package/dist/evm/typechain-types/factories/Mailer__factory.js.map +1 -1
  20. package/dist/solana/solana/index.d.ts +1 -1
  21. package/dist/solana/solana/index.d.ts.map +1 -1
  22. package/dist/solana/solana/index.js +3 -1
  23. package/dist/solana/solana/index.js.map +1 -1
  24. package/dist/solana/solana/mailer-client.d.ts +86 -20
  25. package/dist/solana/solana/mailer-client.d.ts.map +1 -1
  26. package/dist/solana/solana/mailer-client.js +290 -58
  27. package/dist/solana/solana/mailer-client.js.map +1 -1
  28. package/dist/unified/src/evm/index.d.ts +1 -1
  29. package/dist/unified/src/evm/index.d.ts.map +1 -1
  30. package/dist/unified/src/evm/index.js +1 -1
  31. package/dist/unified/src/evm/index.js.map +1 -1
  32. package/dist/unified/src/evm/mailer-client.d.ts +936 -180
  33. package/dist/unified/src/evm/mailer-client.d.ts.map +1 -1
  34. package/dist/unified/src/evm/mailer-client.js +451 -249
  35. package/dist/unified/src/evm/mailer-client.js.map +1 -1
  36. package/dist/unified/src/solana/index.d.ts +1 -1
  37. package/dist/unified/src/solana/index.d.ts.map +1 -1
  38. package/dist/unified/src/solana/index.js +3 -1
  39. package/dist/unified/src/solana/index.js.map +1 -1
  40. package/dist/unified/src/solana/mailer-client.d.ts +86 -20
  41. package/dist/unified/src/solana/mailer-client.d.ts.map +1 -1
  42. package/dist/unified/src/solana/mailer-client.js +290 -58
  43. package/dist/unified/src/solana/mailer-client.js.map +1 -1
  44. package/dist/unified/src/unified/onchain-mailer-client.d.ts +25 -0
  45. package/dist/unified/src/unified/onchain-mailer-client.d.ts.map +1 -1
  46. package/dist/unified/src/unified/onchain-mailer-client.js +147 -4
  47. package/dist/unified/src/unified/onchain-mailer-client.js.map +1 -1
  48. package/dist/unified/typechain-types/Mailer.d.ts +81 -11
  49. package/dist/unified/typechain-types/Mailer.d.ts.map +1 -1
  50. package/dist/unified/typechain-types/factories/Mailer__factory.d.ts +93 -1
  51. package/dist/unified/typechain-types/factories/Mailer__factory.d.ts.map +1 -1
  52. package/dist/unified/typechain-types/factories/Mailer__factory.js +119 -1
  53. package/dist/unified/typechain-types/factories/Mailer__factory.js.map +1 -1
  54. package/dist/unified-esm/src/evm/index.d.ts +1 -1
  55. package/dist/unified-esm/src/evm/index.d.ts.map +1 -1
  56. package/dist/unified-esm/src/evm/index.js +1 -1
  57. package/dist/unified-esm/src/evm/index.js.map +1 -1
  58. package/dist/unified-esm/src/evm/mailer-client.d.ts +936 -180
  59. package/dist/unified-esm/src/evm/mailer-client.d.ts.map +1 -1
  60. package/dist/unified-esm/src/evm/mailer-client.js +453 -251
  61. package/dist/unified-esm/src/evm/mailer-client.js.map +1 -1
  62. package/dist/unified-esm/src/solana/index.d.ts +1 -1
  63. package/dist/unified-esm/src/solana/index.d.ts.map +1 -1
  64. package/dist/unified-esm/src/solana/index.js +1 -1
  65. package/dist/unified-esm/src/solana/index.js.map +1 -1
  66. package/dist/unified-esm/src/solana/mailer-client.d.ts +86 -20
  67. package/dist/unified-esm/src/solana/mailer-client.d.ts.map +1 -1
  68. package/dist/unified-esm/src/solana/mailer-client.js +291 -59
  69. package/dist/unified-esm/src/solana/mailer-client.js.map +1 -1
  70. package/dist/unified-esm/src/unified/onchain-mailer-client.d.ts +25 -0
  71. package/dist/unified-esm/src/unified/onchain-mailer-client.d.ts.map +1 -1
  72. package/dist/unified-esm/src/unified/onchain-mailer-client.js +147 -4
  73. package/dist/unified-esm/src/unified/onchain-mailer-client.js.map +1 -1
  74. package/dist/unified-esm/typechain-types/Mailer.d.ts +81 -11
  75. package/dist/unified-esm/typechain-types/Mailer.d.ts.map +1 -1
  76. package/dist/unified-esm/typechain-types/factories/Mailer__factory.d.ts +93 -1
  77. package/dist/unified-esm/typechain-types/factories/Mailer__factory.d.ts.map +1 -1
  78. package/dist/unified-esm/typechain-types/factories/Mailer__factory.js +119 -1
  79. package/dist/unified-esm/typechain-types/factories/Mailer__factory.js.map +1 -1
  80. package/package.json +1 -1
  81. package/typechain-types/Mailer.ts +137 -9
  82. package/typechain-types/factories/Mailer__factory.ts +119 -1
@@ -3,415 +3,617 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MailerClient = void 0;
4
4
  const viem_1 = require("viem");
5
5
  const Mailer__factory_js_1 = require("../../typechain-types/factories/Mailer__factory.js");
6
- // Get ABI from typechain-generated factories
7
6
  const MAILER_ABI = Mailer__factory_js_1.Mailer__factory.abi;
8
- // Get bytecode from typechain-generated factories
9
7
  const MAILER_BYTECODE = Mailer__factory_js_1.Mailer__factory.bytecode;
10
8
  /**
11
- * @class MailerClient
12
- * @description High-level TypeScript client for the Mailer contract using viem
13
- * @notice Provides easy-to-use methods for sending messages with USDC fees and revenue sharing
14
- *
15
- * ## Key Features:
16
- * - **Delegation Management**: Delegate mail handling with rejection capability
17
- * - **Priority Messages**: Full fee (0.1 USDC) with 90% revenue share to recipient
18
- * - **Standard Messages**: 10% fee only (0.01 USDC) with no revenue share
19
- * - **Revenue Claims**: 60-day claim period for priority message revenue shares
20
- *
21
- * ## Usage Examples:
22
- * ```typescript
23
- * // Connect to existing contract
24
- * import { createPublicClient, createWalletClient, http } from 'viem';
25
- * import { mainnet } from 'viem/chains';
26
- *
27
- * const publicClient = createPublicClient({
28
- * chain: mainnet,
29
- * transport: http()
30
- * });
31
- *
32
- * const mailer = new MailerClient('CONTRACT_ADDRESS', publicClient);
33
- *
34
- * // Send message with revenue sharing to recipient
35
- * const walletClient = createWalletClient({
36
- * chain: mainnet,
37
- * transport: http()
38
- * });
39
- *
40
- * await mailer.send('0x...', 'Subject', 'Body', true, walletClient, account);
41
- *
42
- * // Claim your revenue share (as recipient)
43
- * await mailer.claimRecipientShare(walletClient, account);
44
- * ```
9
+ * Normalize any Address-like input (string with checksum or lowercase) to checksum format.
10
+ */
11
+ function normalizeAddress(value) {
12
+ return (0, viem_1.getAddress)(value);
13
+ }
14
+ /**
15
+ * High-level client for interacting with the EVM Mailer contract.
16
+ * Exposes every callable contract function with type-safe wrappers.
17
+ * Includes automatic gas estimation with configurable buffer for all transactions.
45
18
  */
46
19
  class MailerClient {
47
- /**
48
- * @description Creates a new MailerClient instance
49
- * @param contractAddress The deployed Mailer contract address
50
- * @param publicClient Viem public client for reading blockchain state
51
- */
52
20
  constructor(contractAddress, publicClient) {
53
- this.contractAddress = (0, viem_1.getAddress)(contractAddress);
21
+ this.defaultGasMultiplier = 1.2; // 20% buffer by default
22
+ this.contractAddress = normalizeAddress(contractAddress);
54
23
  this.publicClient = publicClient;
55
24
  }
56
25
  /**
57
- * @description Deploy a new Mailer contract and return a client instance
58
- * @param walletClient Viem wallet client with deployment permissions
59
- * @param account Account to deploy from
60
- * @param usdcTokenAddress Address of the USDC token contract
61
- * @param ownerAddress Address that will own the deployed contract
62
- * @returns Promise resolving to a MailerClient instance
26
+ * Helper method to estimate gas for a transaction with optional buffer
27
+ */
28
+ async estimateGasWithBuffer(estimateFn, gasOptions) {
29
+ // If gas limit is explicitly provided, use it
30
+ if (gasOptions?.gasLimit) {
31
+ return gasOptions.gasLimit;
32
+ }
33
+ try {
34
+ // Estimate gas for the transaction
35
+ const estimatedGas = await estimateFn();
36
+ // Apply multiplier for safety buffer
37
+ const multiplier = gasOptions?.gasMultiplier ?? this.defaultGasMultiplier;
38
+ const gasWithBuffer = BigInt(Math.ceil(Number(estimatedGas) * multiplier));
39
+ // Apply max gas limit if specified
40
+ if (gasOptions?.maxGasLimit) {
41
+ return gasWithBuffer > gasOptions.maxGasLimit ? gasOptions.maxGasLimit : gasWithBuffer;
42
+ }
43
+ return gasWithBuffer;
44
+ }
45
+ catch (error) {
46
+ // If estimation fails, throw with helpful message
47
+ if (error instanceof viem_1.EstimateGasExecutionError) {
48
+ throw new Error(`Gas estimation failed: ${error.message}`);
49
+ }
50
+ throw error;
51
+ }
52
+ }
53
+ /**
54
+ * Helper method to build transaction parameters with gas options
55
+ */
56
+ buildTxParams(gasLimit, gasOptions) {
57
+ const params = { gas: gasLimit };
58
+ if (gasOptions?.maxFeePerGas) {
59
+ params.maxFeePerGas = gasOptions.maxFeePerGas;
60
+ }
61
+ if (gasOptions?.maxPriorityFeePerGas) {
62
+ params.maxPriorityFeePerGas = gasOptions.maxPriorityFeePerGas;
63
+ }
64
+ return params;
65
+ }
66
+ /**
67
+ * Deploy a fresh Mailer contract instance with gas estimation.
63
68
  */
64
- static async deploy(walletClient, publicClient, account, usdcTokenAddress, ownerAddress) {
69
+ static async deploy(walletClient, publicClient, account, usdcTokenAddress, ownerAddress, gasOptions) {
70
+ // For deployment, we need to estimate gas differently
71
+ // Use a reasonable default for deployment gas
72
+ const estimatedGas = BigInt(3000000); // Default deployment gas
73
+ // Apply gas buffer
74
+ const multiplier = gasOptions?.gasMultiplier ?? 1.5; // Higher multiplier for deployment
75
+ const gasLimit = gasOptions?.gasLimit ?? BigInt(Math.ceil(Number(estimatedGas) * multiplier));
76
+ // Deploy with estimated gas
65
77
  const hash = await walletClient.deployContract({
66
78
  abi: MAILER_ABI,
67
79
  bytecode: MAILER_BYTECODE,
68
- args: [(0, viem_1.getAddress)(usdcTokenAddress), (0, viem_1.getAddress)(ownerAddress)],
80
+ args: [normalizeAddress(usdcTokenAddress), normalizeAddress(ownerAddress)],
69
81
  account,
70
82
  chain: walletClient.chain,
83
+ gas: gasLimit,
84
+ ...(gasOptions?.maxFeePerGas && { maxFeePerGas: gasOptions.maxFeePerGas }),
85
+ ...(gasOptions?.maxPriorityFeePerGas && { maxPriorityFeePerGas: gasOptions.maxPriorityFeePerGas }),
71
86
  });
72
87
  const receipt = await publicClient.waitForTransactionReceipt({ hash });
73
88
  if (!receipt.contractAddress) {
74
- throw new Error("Contract deployment failed");
89
+ throw new Error('Contract deployment failed');
75
90
  }
76
- return new MailerClient(receipt.contractAddress, publicClient);
91
+ return {
92
+ client: new MailerClient(receipt.contractAddress, publicClient),
93
+ result: { hash, estimatedGas, gasLimit }
94
+ };
95
+ }
96
+ getAddress() {
97
+ return this.contractAddress;
77
98
  }
78
99
  /**
79
- * @description Send a message with optional revenue sharing
80
- * @notice Two modes:
81
- * - revenueShareToReceiver=true: Sender pays 0.1 USDC, recipient gets 90% claimable
82
- * - revenueShareToReceiver=false: Sender pays 0.01 USDC only
83
- * @param to Recipient address who receives the message and potential revenue share
84
- * @param subject Message subject line
85
- * @param body Message content
86
- * @param revenueShareToReceiver If true, recipient gets 90% revenue share; if false, no revenue share
87
- * @param resolveSenderToName If true, resolve sender address to name via off-chain service
88
- * @param walletClient Viem wallet client for transaction
89
- * @param account Account to send from
90
- * @returns Promise resolving to transaction hash
91
- * @example
92
- * ```typescript
93
- * // Send with revenue share to recipient
94
- * const hash = await mailer.send('0x...', 'Subject', 'Priority message', true, false, walletClient, account);
95
- * // Send standard message (no revenue share)
96
- * const hash2 = await mailer.send('0x...', 'Subject', 'Standard message', false, false, walletClient, account);
97
- * await publicClient.waitForTransactionReceipt({ hash });
98
- * ```
100
+ * Core message send with explicit payer control and gas estimation.
99
101
  */
100
- async send(to, subject, body, revenueShareToReceiver, resolveSenderToName = false, walletClient, account) {
101
- return await walletClient.writeContract({
102
+ async send(to, subject, body, payer, revenueShareToReceiver, resolveSenderToName, walletClient, account, gasOptions) {
103
+ // Estimate gas for the transaction
104
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
102
105
  address: this.contractAddress,
103
106
  abi: MAILER_ABI,
104
107
  functionName: 'send',
105
- args: [to, subject, body, revenueShareToReceiver, resolveSenderToName],
108
+ args: [
109
+ normalizeAddress(to),
110
+ subject,
111
+ body,
112
+ normalizeAddress(payer),
113
+ revenueShareToReceiver,
114
+ resolveSenderToName,
115
+ ],
116
+ account,
117
+ }), gasOptions);
118
+ const hash = await walletClient.writeContract({
119
+ address: this.contractAddress,
120
+ abi: MAILER_ABI,
121
+ functionName: 'send',
122
+ args: [
123
+ normalizeAddress(to),
124
+ subject,
125
+ body,
126
+ normalizeAddress(payer),
127
+ revenueShareToReceiver,
128
+ resolveSenderToName,
129
+ ],
106
130
  account,
107
131
  chain: walletClient.chain,
132
+ ...this.buildTxParams(gasLimit, gasOptions),
108
133
  });
134
+ return { hash, estimatedGas: gasLimit, gasLimit };
109
135
  }
110
- /**
111
- * @description Send a message using a pre-prepared mail ID with optional revenue sharing
112
- * @notice Two modes:
113
- * - revenueShareToReceiver=true: Sender pays 0.1 USDC, recipient gets 90% claimable
114
- * - revenueShareToReceiver=false: Sender pays 0.01 USDC only
115
- * @param to Recipient address who receives the message and potential revenue share
116
- * @param mailId Pre-prepared message identifier
117
- * @param revenueShareToReceiver If true, recipient gets 90% revenue share; if false, no revenue share
118
- * @param resolveSenderToName If true, resolve sender address to name via off-chain service
119
- * @param walletClient Viem wallet client for transaction
120
- * @param account Account to send from
121
- * @returns Promise resolving to transaction hash
122
- */
123
- async sendPrepared(to, mailId, revenueShareToReceiver, resolveSenderToName = false, walletClient, account) {
124
- return await walletClient.writeContract({
136
+ async sendPrepared(to, mailId, payer, revenueShareToReceiver, resolveSenderToName, walletClient, account, gasOptions) {
137
+ // Estimate gas for the transaction
138
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
139
+ address: this.contractAddress,
140
+ abi: MAILER_ABI,
141
+ functionName: 'sendPrepared',
142
+ args: [
143
+ normalizeAddress(to),
144
+ mailId,
145
+ normalizeAddress(payer),
146
+ revenueShareToReceiver,
147
+ resolveSenderToName,
148
+ ],
149
+ account,
150
+ }), gasOptions);
151
+ const hash = await walletClient.writeContract({
125
152
  address: this.contractAddress,
126
153
  abi: MAILER_ABI,
127
154
  functionName: 'sendPrepared',
128
- args: [to, mailId, revenueShareToReceiver, resolveSenderToName],
155
+ args: [
156
+ normalizeAddress(to),
157
+ mailId,
158
+ normalizeAddress(payer),
159
+ revenueShareToReceiver,
160
+ resolveSenderToName,
161
+ ],
129
162
  account,
130
163
  chain: walletClient.chain,
164
+ ...this.buildTxParams(gasLimit, gasOptions),
131
165
  });
166
+ return { hash, estimatedGas: gasLimit, gasLimit };
167
+ }
168
+ async sendThroughWebhook(to, webhookId, payer, revenueShareToReceiver, resolveSenderToName, walletClient, account, gasOptions) {
169
+ // Estimate gas for the transaction
170
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
171
+ address: this.contractAddress,
172
+ abi: MAILER_ABI,
173
+ functionName: 'sendThroughWebhook',
174
+ args: [
175
+ normalizeAddress(to),
176
+ webhookId,
177
+ normalizeAddress(payer),
178
+ revenueShareToReceiver,
179
+ resolveSenderToName,
180
+ ],
181
+ account,
182
+ }), gasOptions);
183
+ const hash = await walletClient.writeContract({
184
+ address: this.contractAddress,
185
+ abi: MAILER_ABI,
186
+ functionName: 'sendThroughWebhook',
187
+ args: [
188
+ normalizeAddress(to),
189
+ webhookId,
190
+ normalizeAddress(payer),
191
+ revenueShareToReceiver,
192
+ resolveSenderToName,
193
+ ],
194
+ account,
195
+ chain: walletClient.chain,
196
+ ...this.buildTxParams(gasLimit, gasOptions),
197
+ });
198
+ return { hash, estimatedGas: gasLimit, gasLimit };
199
+ }
200
+ async sendToEmailAddress(toEmail, subject, body, payer, walletClient, account, gasOptions) {
201
+ // Estimate gas for the transaction
202
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
203
+ address: this.contractAddress,
204
+ abi: MAILER_ABI,
205
+ functionName: 'sendToEmailAddress',
206
+ args: [toEmail, subject, body, normalizeAddress(payer)],
207
+ account,
208
+ }), gasOptions);
209
+ const hash = await walletClient.writeContract({
210
+ address: this.contractAddress,
211
+ abi: MAILER_ABI,
212
+ functionName: 'sendToEmailAddress',
213
+ args: [toEmail, subject, body, normalizeAddress(payer)],
214
+ account,
215
+ chain: walletClient.chain,
216
+ ...this.buildTxParams(gasLimit, gasOptions),
217
+ });
218
+ return { hash, estimatedGas: gasLimit, gasLimit };
219
+ }
220
+ async sendPreparedToEmailAddress(toEmail, mailId, payer, walletClient, account, gasOptions) {
221
+ // Estimate gas for the transaction
222
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
223
+ address: this.contractAddress,
224
+ abi: MAILER_ABI,
225
+ functionName: 'sendPreparedToEmailAddress',
226
+ args: [toEmail, mailId, normalizeAddress(payer)],
227
+ account,
228
+ }), gasOptions);
229
+ const hash = await walletClient.writeContract({
230
+ address: this.contractAddress,
231
+ abi: MAILER_ABI,
232
+ functionName: 'sendPreparedToEmailAddress',
233
+ args: [toEmail, mailId, normalizeAddress(payer)],
234
+ account,
235
+ chain: walletClient.chain,
236
+ ...this.buildTxParams(gasLimit, gasOptions),
237
+ });
238
+ return { hash, estimatedGas: gasLimit, gasLimit };
239
+ }
240
+ async getFee() {
241
+ return (await this.publicClient.readContract({
242
+ address: this.contractAddress,
243
+ abi: MAILER_ABI,
244
+ functionName: 'getFee',
245
+ }));
132
246
  }
133
247
  async getSendFee() {
134
- return await this.publicClient.readContract({
248
+ return (await this.publicClient.readContract({
135
249
  address: this.contractAddress,
136
250
  abi: MAILER_ABI,
137
251
  functionName: 'sendFee',
138
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
252
+ }));
253
+ }
254
+ async setFee(newFee, walletClient, account, gasOptions) {
255
+ // Estimate gas for the transaction
256
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
257
+ address: this.contractAddress,
258
+ abi: MAILER_ABI,
259
+ functionName: 'setFee',
260
+ args: [newFee],
261
+ account,
262
+ }), gasOptions);
263
+ const hash = await walletClient.writeContract({
264
+ address: this.contractAddress,
265
+ abi: MAILER_ABI,
266
+ functionName: 'setFee',
267
+ args: [newFee],
268
+ account,
269
+ chain: walletClient.chain,
270
+ ...this.buildTxParams(gasLimit, gasOptions),
139
271
  });
272
+ return { hash, estimatedGas: gasLimit, gasLimit };
140
273
  }
141
274
  async getUsdcToken() {
142
- return await this.publicClient.readContract({
275
+ return (await this.publicClient.readContract({
143
276
  address: this.contractAddress,
144
277
  abi: MAILER_ABI,
145
278
  functionName: 'usdcToken',
146
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
147
- });
279
+ }));
148
280
  }
149
- getAddress() {
150
- return this.contractAddress;
281
+ async getOwner() {
282
+ return (await this.publicClient.readContract({
283
+ address: this.contractAddress,
284
+ abi: MAILER_ABI,
285
+ functionName: 'owner',
286
+ }));
151
287
  }
152
- async claimRecipientShare(walletClient, account) {
153
- return await walletClient.writeContract({
288
+ async claimRecipientShare(walletClient, account, gasOptions) {
289
+ // Estimate gas for the transaction
290
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
291
+ address: this.contractAddress,
292
+ abi: MAILER_ABI,
293
+ functionName: 'claimRecipientShare',
294
+ account,
295
+ }), gasOptions);
296
+ const hash = await walletClient.writeContract({
154
297
  address: this.contractAddress,
155
298
  abi: MAILER_ABI,
156
299
  functionName: 'claimRecipientShare',
157
300
  account,
158
301
  chain: walletClient.chain,
302
+ ...this.buildTxParams(gasLimit, gasOptions),
159
303
  });
304
+ return { hash, estimatedGas: gasLimit, gasLimit };
160
305
  }
161
- async claimOwnerShare(walletClient, account) {
162
- return await walletClient.writeContract({
306
+ async claimOwnerShare(walletClient, account, gasOptions) {
307
+ // Estimate gas for the transaction
308
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
309
+ address: this.contractAddress,
310
+ abi: MAILER_ABI,
311
+ functionName: 'claimOwnerShare',
312
+ account,
313
+ }), gasOptions);
314
+ const hash = await walletClient.writeContract({
163
315
  address: this.contractAddress,
164
316
  abi: MAILER_ABI,
165
317
  functionName: 'claimOwnerShare',
166
318
  account,
167
319
  chain: walletClient.chain,
320
+ ...this.buildTxParams(gasLimit, gasOptions),
168
321
  });
322
+ return { hash, estimatedGas: gasLimit, gasLimit };
169
323
  }
170
- async claimExpiredShares(recipient, walletClient, account) {
171
- return await walletClient.writeContract({
324
+ async claimExpiredShares(recipient, walletClient, account, gasOptions) {
325
+ // Estimate gas for the transaction
326
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
327
+ address: this.contractAddress,
328
+ abi: MAILER_ABI,
329
+ functionName: 'claimExpiredShares',
330
+ args: [normalizeAddress(recipient)],
331
+ account,
332
+ }), gasOptions);
333
+ const hash = await walletClient.writeContract({
172
334
  address: this.contractAddress,
173
335
  abi: MAILER_ABI,
174
336
  functionName: 'claimExpiredShares',
175
- args: [(0, viem_1.getAddress)(recipient)],
337
+ args: [normalizeAddress(recipient)],
176
338
  account,
177
339
  chain: walletClient.chain,
340
+ ...this.buildTxParams(gasLimit, gasOptions),
178
341
  });
342
+ return { hash, estimatedGas: gasLimit, gasLimit };
179
343
  }
180
344
  async getRecipientClaimable(recipient) {
181
- const result = await this.publicClient.readContract({
345
+ const [amount, expiresAt, isExpired] = (await this.publicClient.readContract({
182
346
  address: this.contractAddress,
183
347
  abi: MAILER_ABI,
184
348
  functionName: 'getRecipientClaimable',
185
- args: [(0, viem_1.getAddress)(recipient)],
186
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
187
- });
188
- return {
189
- amount: result[0],
190
- expiresAt: result[1],
191
- isExpired: result[2]
192
- };
349
+ args: [normalizeAddress(recipient)],
350
+ }));
351
+ return { amount, expiresAt, isExpired };
193
352
  }
194
353
  async getOwnerClaimable() {
195
- return await this.publicClient.readContract({
354
+ return (await this.publicClient.readContract({
196
355
  address: this.contractAddress,
197
356
  abi: MAILER_ABI,
198
- functionName: 'getOwnerClaimable'
199
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
200
- });
357
+ functionName: 'getOwnerClaimable',
358
+ }));
201
359
  }
202
- // Delegation functionality
203
- /**
204
- * Delegate mail handling to another address
205
- * @param delegate Address to delegate to (or 0x0 to clear delegation)
206
- * @param walletClient Connected wallet client
207
- * @param account Account to send transaction from
208
- * @returns Transaction hash
209
- */
210
- async delegateTo(delegate, walletClient, account) {
211
- return await walletClient.writeContract({
360
+ async delegateTo(delegate, walletClient, account, gasOptions) {
361
+ // Estimate gas for the transaction
362
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
363
+ address: this.contractAddress,
364
+ abi: MAILER_ABI,
365
+ functionName: 'delegateTo',
366
+ args: [normalizeAddress(delegate)],
367
+ account,
368
+ }), gasOptions);
369
+ const hash = await walletClient.writeContract({
212
370
  address: this.contractAddress,
213
371
  abi: MAILER_ABI,
214
372
  functionName: 'delegateTo',
215
- args: [(0, viem_1.getAddress)(delegate)],
373
+ args: [normalizeAddress(delegate)],
216
374
  account,
217
375
  chain: walletClient.chain,
376
+ ...this.buildTxParams(gasLimit, gasOptions),
218
377
  });
378
+ return { hash, estimatedGas: gasLimit, gasLimit };
219
379
  }
220
- /**
221
- * Reject a delegation made to you by another address
222
- * @param delegatingAddress Address that delegated to you
223
- * @param walletClient Connected wallet client
224
- * @param account Account to send transaction from
225
- * @returns Transaction hash
226
- */
227
- async rejectDelegation(delegatingAddress, walletClient, account) {
228
- return await walletClient.writeContract({
380
+ async rejectDelegation(delegatingAddress, walletClient, account, gasOptions) {
381
+ // Estimate gas for the transaction
382
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
383
+ address: this.contractAddress,
384
+ abi: MAILER_ABI,
385
+ functionName: 'rejectDelegation',
386
+ args: [normalizeAddress(delegatingAddress)],
387
+ account,
388
+ }), gasOptions);
389
+ const hash = await walletClient.writeContract({
229
390
  address: this.contractAddress,
230
391
  abi: MAILER_ABI,
231
392
  functionName: 'rejectDelegation',
232
- args: [(0, viem_1.getAddress)(delegatingAddress)],
393
+ args: [normalizeAddress(delegatingAddress)],
233
394
  account,
234
395
  chain: walletClient.chain,
396
+ ...this.buildTxParams(gasLimit, gasOptions),
235
397
  });
398
+ return { hash, estimatedGas: gasLimit, gasLimit };
236
399
  }
237
- /**
238
- * Get current delegation fee in USDC (6 decimals)
239
- * @returns Delegation fee amount
240
- */
241
400
  async getDelegationFee() {
242
- return await this.publicClient.readContract({
401
+ return (await this.publicClient.readContract({
243
402
  address: this.contractAddress,
244
403
  abi: MAILER_ABI,
245
404
  functionName: 'getDelegationFee',
246
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
247
- });
405
+ }));
248
406
  }
249
- /**
250
- * Update delegation fee (owner only)
251
- * @param newFee New fee amount in USDC (6 decimals)
252
- * @param walletClient Connected wallet client
253
- * @param account Account to send transaction from
254
- * @returns Transaction hash
255
- */
256
- async setDelegationFee(newFee, walletClient, account) {
257
- return await walletClient.writeContract({
407
+ async setDelegationFee(newFee, walletClient, account, gasOptions) {
408
+ // Estimate gas for the transaction
409
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
410
+ address: this.contractAddress,
411
+ abi: MAILER_ABI,
412
+ functionName: 'setDelegationFee',
413
+ args: [newFee],
414
+ account,
415
+ }), gasOptions);
416
+ const hash = await walletClient.writeContract({
258
417
  address: this.contractAddress,
259
418
  abi: MAILER_ABI,
260
419
  functionName: 'setDelegationFee',
261
420
  args: [newFee],
262
421
  account,
263
422
  chain: walletClient.chain,
423
+ ...this.buildTxParams(gasLimit, gasOptions),
264
424
  });
425
+ return { hash, estimatedGas: gasLimit, gasLimit };
265
426
  }
266
- /**
267
- * @description Send a message to an email address (no wallet known)
268
- * @notice Charges only 10% owner fee since recipient wallet is unknown
269
- * @param toEmail Email address of the recipient
270
- * @param subject Message subject line
271
- * @param body Message content
272
- * @param walletClient Viem wallet client for transaction
273
- * @param account Account to send from
274
- * @returns Promise resolving to transaction hash
275
- * @example
276
- * ```typescript
277
- * // Send to email address
278
- * const hash = await mailer.sendToEmailAddress('user@example.com', 'Subject', 'Body', walletClient, account);
279
- * await publicClient.waitForTransactionReceipt({ hash });
280
- * ```
281
- */
282
- async sendToEmailAddress(toEmail, subject, body, walletClient, account) {
283
- return await walletClient.writeContract({
427
+ async setCustomFeePercentage(target, percentage, walletClient, account, gasOptions) {
428
+ // Estimate gas for the transaction
429
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
284
430
  address: this.contractAddress,
285
431
  abi: MAILER_ABI,
286
- functionName: 'sendToEmailAddress',
287
- args: [toEmail, subject, body],
432
+ functionName: 'setCustomFeePercentage',
433
+ args: [normalizeAddress(target), BigInt(percentage)],
434
+ account,
435
+ }), gasOptions);
436
+ const hash = await walletClient.writeContract({
437
+ address: this.contractAddress,
438
+ abi: MAILER_ABI,
439
+ functionName: 'setCustomFeePercentage',
440
+ args: [normalizeAddress(target), BigInt(percentage)],
288
441
  account,
289
442
  chain: walletClient.chain,
443
+ ...this.buildTxParams(gasLimit, gasOptions),
290
444
  });
445
+ return { hash, estimatedGas: gasLimit, gasLimit };
291
446
  }
292
- /**
293
- * @description Send a pre-prepared message to an email address (no wallet known)
294
- * @notice Charges only 10% owner fee since recipient wallet is unknown
295
- * @param toEmail Email address of the recipient
296
- * @param mailId Pre-prepared message identifier
297
- * @param walletClient Viem wallet client for transaction
298
- * @param account Account to send from
299
- * @returns Promise resolving to transaction hash
300
- */
301
- async sendPreparedToEmailAddress(toEmail, mailId, walletClient, account) {
302
- return await walletClient.writeContract({
447
+ async clearCustomFeePercentage(target, walletClient, account, gasOptions) {
448
+ // Estimate gas for the transaction
449
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
303
450
  address: this.contractAddress,
304
451
  abi: MAILER_ABI,
305
- functionName: 'sendPreparedToEmailAddress',
306
- args: [toEmail, mailId],
452
+ functionName: 'clearCustomFeePercentage',
453
+ args: [normalizeAddress(target)],
454
+ account,
455
+ }), gasOptions);
456
+ const hash = await walletClient.writeContract({
457
+ address: this.contractAddress,
458
+ abi: MAILER_ABI,
459
+ functionName: 'clearCustomFeePercentage',
460
+ args: [normalizeAddress(target)],
307
461
  account,
308
462
  chain: walletClient.chain,
463
+ ...this.buildTxParams(gasLimit, gasOptions),
309
464
  });
465
+ return { hash, estimatedGas: gasLimit, gasLimit };
310
466
  }
311
- /**
312
- * Set the send fee (owner only)
313
- * @param newFee New fee amount in USDC (6 decimals)
314
- * @param walletClient Viem wallet client for transaction
315
- * @param account Account to send from (must be owner)
316
- * @returns Promise resolving to transaction hash
317
- */
318
- async setFee(newFee, walletClient, account) {
319
- return await walletClient.writeContract({
467
+ async getCustomFeePercentage(target) {
468
+ const percentage = (await this.publicClient.readContract({
320
469
  address: this.contractAddress,
321
470
  abi: MAILER_ABI,
322
- functionName: 'setFee',
323
- args: [newFee],
471
+ functionName: 'getCustomFeePercentage',
472
+ args: [normalizeAddress(target)],
473
+ }));
474
+ return Number(percentage);
475
+ }
476
+ async getCustomFeeDiscount(target) {
477
+ const discount = (await this.publicClient.readContract({
478
+ address: this.contractAddress,
479
+ abi: MAILER_ABI,
480
+ functionName: 'customFeeDiscount',
481
+ args: [normalizeAddress(target)],
482
+ }));
483
+ return Number(discount);
484
+ }
485
+ async setPermission(contractAddress, walletClient, account, gasOptions) {
486
+ // Estimate gas for the transaction
487
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
488
+ address: this.contractAddress,
489
+ abi: MAILER_ABI,
490
+ functionName: 'setPermission',
491
+ args: [normalizeAddress(contractAddress)],
492
+ account,
493
+ }), gasOptions);
494
+ const hash = await walletClient.writeContract({
495
+ address: this.contractAddress,
496
+ abi: MAILER_ABI,
497
+ functionName: 'setPermission',
498
+ args: [normalizeAddress(contractAddress)],
324
499
  account,
325
500
  chain: walletClient.chain,
501
+ ...this.buildTxParams(gasLimit, gasOptions),
326
502
  });
503
+ return { hash, estimatedGas: gasLimit, gasLimit };
327
504
  }
328
- /**
329
- * Get the current send fee
330
- * @returns Current send fee in USDC (6 decimals)
331
- */
332
- async getFee() {
333
- return await this.publicClient.readContract({
505
+ async removePermission(contractAddress, walletClient, account, gasOptions) {
506
+ // Estimate gas for the transaction
507
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
334
508
  address: this.contractAddress,
335
509
  abi: MAILER_ABI,
336
- functionName: 'getFee',
337
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
510
+ functionName: 'removePermission',
511
+ args: [normalizeAddress(contractAddress)],
512
+ account,
513
+ }), gasOptions);
514
+ const hash = await walletClient.writeContract({
515
+ address: this.contractAddress,
516
+ abi: MAILER_ABI,
517
+ functionName: 'removePermission',
518
+ args: [normalizeAddress(contractAddress)],
519
+ account,
520
+ chain: walletClient.chain,
521
+ ...this.buildTxParams(gasLimit, gasOptions),
338
522
  });
523
+ return { hash, estimatedGas: gasLimit, gasLimit };
339
524
  }
340
- /**
341
- * Pause the contract and distribute all claimable funds (owner only)
342
- * @param walletClient Viem wallet client for transaction
343
- * @param account Account to send from (must be owner)
344
- * @returns Promise resolving to transaction hash
345
- */
346
- async pause(walletClient, account) {
347
- return await walletClient.writeContract({
525
+ async hasPermission(contractAddress, wallet) {
526
+ const permitted = (await this.publicClient.readContract({
527
+ address: this.contractAddress,
528
+ abi: MAILER_ABI,
529
+ functionName: 'permissions',
530
+ args: [normalizeAddress(contractAddress), normalizeAddress(wallet)],
531
+ }));
532
+ return permitted;
533
+ }
534
+ async pause(walletClient, account, gasOptions) {
535
+ // Estimate gas for the transaction
536
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
537
+ address: this.contractAddress,
538
+ abi: MAILER_ABI,
539
+ functionName: 'pause',
540
+ account,
541
+ }), gasOptions);
542
+ const hash = await walletClient.writeContract({
348
543
  address: this.contractAddress,
349
544
  abi: MAILER_ABI,
350
545
  functionName: 'pause',
351
546
  account,
352
547
  chain: walletClient.chain,
548
+ ...this.buildTxParams(gasLimit, gasOptions),
353
549
  });
550
+ return { hash, estimatedGas: gasLimit, gasLimit };
354
551
  }
355
- /**
356
- * Unpause the contract (owner only)
357
- * @param walletClient Viem wallet client for transaction
358
- * @param account Account to send from (must be owner)
359
- * @returns Promise resolving to transaction hash
360
- */
361
- async unpause(walletClient, account) {
362
- return await walletClient.writeContract({
552
+ async unpause(walletClient, account, gasOptions) {
553
+ // Estimate gas for the transaction
554
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
555
+ address: this.contractAddress,
556
+ abi: MAILER_ABI,
557
+ functionName: 'unpause',
558
+ account,
559
+ }), gasOptions);
560
+ const hash = await walletClient.writeContract({
363
561
  address: this.contractAddress,
364
562
  abi: MAILER_ABI,
365
563
  functionName: 'unpause',
366
564
  account,
367
565
  chain: walletClient.chain,
566
+ ...this.buildTxParams(gasLimit, gasOptions),
368
567
  });
568
+ return { hash, estimatedGas: gasLimit, gasLimit };
369
569
  }
370
- /**
371
- * Emergency unpause without fund distribution (owner only)
372
- * @param walletClient Viem wallet client for transaction
373
- * @param account Account to send from (must be owner)
374
- * @returns Promise resolving to transaction hash
375
- */
376
- async emergencyUnpause(walletClient, account) {
377
- return await walletClient.writeContract({
570
+ async emergencyUnpause(walletClient, account, gasOptions) {
571
+ // Estimate gas for the transaction
572
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
573
+ address: this.contractAddress,
574
+ abi: MAILER_ABI,
575
+ functionName: 'emergencyUnpause',
576
+ account,
577
+ }), gasOptions);
578
+ const hash = await walletClient.writeContract({
378
579
  address: this.contractAddress,
379
580
  abi: MAILER_ABI,
380
581
  functionName: 'emergencyUnpause',
381
582
  account,
382
583
  chain: walletClient.chain,
584
+ ...this.buildTxParams(gasLimit, gasOptions),
383
585
  });
586
+ return { hash, estimatedGas: gasLimit, gasLimit };
384
587
  }
385
- /**
386
- * Check if contract is currently paused
387
- * @returns True if contract is paused, false otherwise
388
- */
389
588
  async isPaused() {
390
- return await this.publicClient.readContract({
589
+ return (await this.publicClient.readContract({
391
590
  address: this.contractAddress,
392
591
  abi: MAILER_ABI,
393
592
  functionName: 'isPaused',
394
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
395
- });
593
+ }));
396
594
  }
397
- /**
398
- * Distribute a specific recipient's claimable funds during pause
399
- * Anyone can call this function when contract is paused
400
- * @param recipient Address to distribute funds for
401
- * @param walletClient Viem wallet client for transaction
402
- * @param account Account to send from
403
- * @returns Promise resolving to transaction hash
404
- */
405
- async distributeClaimableFunds(recipient, walletClient, account) {
406
- return await walletClient.writeContract({
595
+ async distributeClaimableFunds(recipient, walletClient, account, gasOptions) {
596
+ // Estimate gas for the transaction
597
+ const gasLimit = await this.estimateGasWithBuffer(() => this.publicClient.estimateContractGas({
598
+ address: this.contractAddress,
599
+ abi: MAILER_ABI,
600
+ functionName: 'distributeClaimableFunds',
601
+ args: [normalizeAddress(recipient)],
602
+ account,
603
+ }), gasOptions);
604
+ const hash = await walletClient.writeContract({
407
605
  address: this.contractAddress,
408
606
  abi: MAILER_ABI,
409
607
  functionName: 'distributeClaimableFunds',
410
- args: [(0, viem_1.getAddress)(recipient)],
608
+ args: [normalizeAddress(recipient)],
411
609
  account,
412
610
  chain: walletClient.chain,
611
+ ...this.buildTxParams(gasLimit, gasOptions),
413
612
  });
613
+ return { hash, estimatedGas: gasLimit, gasLimit };
414
614
  }
415
615
  }
416
616
  exports.MailerClient = MailerClient;
617
+ MailerClient.abi = MAILER_ABI;
618
+ MailerClient.bytecode = MAILER_BYTECODE;
417
619
  //# sourceMappingURL=mailer-client.js.map