@sudobility/contracts 1.11.2 → 1.13.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 (128) hide show
  1. package/dist/evm/src/evm/{mailer-client.d.ts → evm-mailer-client.d.ts} +199 -47
  2. package/dist/evm/src/evm/evm-mailer-client.d.ts.map +1 -0
  3. package/dist/evm/src/evm/evm-mailer-client.js +924 -0
  4. package/dist/evm/src/evm/evm-mailer-client.js.map +1 -0
  5. package/dist/evm/src/evm/index.d.ts +1 -1
  6. package/dist/evm/src/evm/index.d.ts.map +1 -1
  7. package/dist/evm/src/evm/index.js +4 -4
  8. package/dist/evm/src/evm/index.js.map +1 -1
  9. package/dist/solana/solana/index.d.ts +1 -1
  10. package/dist/solana/solana/index.d.ts.map +1 -1
  11. package/dist/solana/solana/index.js +4 -1
  12. package/dist/solana/solana/index.js.map +1 -1
  13. package/dist/solana/solana/solana-mailer-client.d.ts +209 -0
  14. package/dist/solana/solana/solana-mailer-client.d.ts.map +1 -0
  15. package/dist/solana/solana/solana-mailer-client.js +1004 -0
  16. package/dist/solana/solana/solana-mailer-client.js.map +1 -0
  17. package/dist/solana/solana/types.d.ts +3 -2
  18. package/dist/solana/solana/types.d.ts.map +1 -1
  19. package/dist/solana/solana/types.js.map +1 -1
  20. package/dist/{unified-esm/src/evm/mailer-client.d.ts → unified/src/evm/evm-mailer-client.d.ts} +199 -47
  21. package/dist/unified/src/evm/evm-mailer-client.d.ts.map +1 -0
  22. package/dist/unified/src/evm/evm-mailer-client.js +924 -0
  23. package/dist/unified/src/evm/evm-mailer-client.js.map +1 -0
  24. package/dist/unified/src/evm/index.d.ts +1 -1
  25. package/dist/unified/src/evm/index.d.ts.map +1 -1
  26. package/dist/unified/src/evm/index.js +4 -4
  27. package/dist/unified/src/evm/index.js.map +1 -1
  28. package/dist/unified/src/react/context/MailerProvider.d.ts +26 -20
  29. package/dist/unified/src/react/context/MailerProvider.d.ts.map +1 -1
  30. package/dist/unified/src/react/context/MailerProvider.js +26 -26
  31. package/dist/unified/src/react/context/MailerProvider.js.map +1 -1
  32. package/dist/unified/src/react/hooks/useMailerMutations.d.ts +225 -192
  33. package/dist/unified/src/react/hooks/useMailerMutations.d.ts.map +1 -1
  34. package/dist/unified/src/react/hooks/useMailerMutations.js +263 -266
  35. package/dist/unified/src/react/hooks/useMailerMutations.js.map +1 -1
  36. package/dist/unified/src/react/hooks/useMailerQueries.d.ts +117 -63
  37. package/dist/unified/src/react/hooks/useMailerQueries.d.ts.map +1 -1
  38. package/dist/unified/src/react/hooks/useMailerQueries.js +239 -104
  39. package/dist/unified/src/react/hooks/useMailerQueries.js.map +1 -1
  40. package/dist/unified/src/react/index.d.ts +5 -3
  41. package/dist/unified/src/react/index.d.ts.map +1 -1
  42. package/dist/unified/src/react/index.js +41 -26
  43. package/dist/unified/src/react/index.js.map +1 -1
  44. package/dist/unified/src/solana/index.d.ts +1 -1
  45. package/dist/unified/src/solana/index.d.ts.map +1 -1
  46. package/dist/unified/src/solana/index.js +4 -1
  47. package/dist/unified/src/solana/index.js.map +1 -1
  48. package/dist/unified/src/solana/solana-mailer-client.d.ts +209 -0
  49. package/dist/unified/src/solana/solana-mailer-client.d.ts.map +1 -0
  50. package/dist/unified/src/solana/solana-mailer-client.js +1004 -0
  51. package/dist/unified/src/solana/solana-mailer-client.js.map +1 -0
  52. package/dist/unified/src/solana/types.d.ts +3 -2
  53. package/dist/unified/src/solana/types.d.ts.map +1 -1
  54. package/dist/unified/src/solana/types.js.map +1 -1
  55. package/dist/unified/src/unified/index.d.ts +1 -1
  56. package/dist/unified/src/unified/index.d.ts.map +1 -1
  57. package/dist/unified/src/unified/onchain-mailer-client.d.ts +187 -268
  58. package/dist/unified/src/unified/onchain-mailer-client.d.ts.map +1 -1
  59. package/dist/unified/src/unified/onchain-mailer-client.js +539 -1614
  60. package/dist/unified/src/unified/onchain-mailer-client.js.map +1 -1
  61. package/dist/unified/src/unified/types.d.ts +23 -6
  62. package/dist/unified/src/unified/types.d.ts.map +1 -1
  63. package/dist/{unified/src/evm/mailer-client.d.ts → unified-esm/src/evm/evm-mailer-client.d.ts} +199 -47
  64. package/dist/unified-esm/src/evm/evm-mailer-client.d.ts.map +1 -0
  65. package/dist/unified-esm/src/evm/evm-mailer-client.js +920 -0
  66. package/dist/unified-esm/src/evm/evm-mailer-client.js.map +1 -0
  67. package/dist/unified-esm/src/evm/index.d.ts +1 -1
  68. package/dist/unified-esm/src/evm/index.d.ts.map +1 -1
  69. package/dist/unified-esm/src/evm/index.js +2 -2
  70. package/dist/unified-esm/src/evm/index.js.map +1 -1
  71. package/dist/unified-esm/src/react/context/MailerProvider.d.ts +26 -20
  72. package/dist/unified-esm/src/react/context/MailerProvider.d.ts.map +1 -1
  73. package/dist/unified-esm/src/react/context/MailerProvider.js +25 -26
  74. package/dist/unified-esm/src/react/context/MailerProvider.js.map +1 -1
  75. package/dist/unified-esm/src/react/hooks/useMailerMutations.d.ts +225 -192
  76. package/dist/unified-esm/src/react/hooks/useMailerMutations.d.ts.map +1 -1
  77. package/dist/unified-esm/src/react/hooks/useMailerMutations.js +254 -262
  78. package/dist/unified-esm/src/react/hooks/useMailerMutations.js.map +1 -1
  79. package/dist/unified-esm/src/react/hooks/useMailerQueries.d.ts +117 -63
  80. package/dist/unified-esm/src/react/hooks/useMailerQueries.d.ts.map +1 -1
  81. package/dist/unified-esm/src/react/hooks/useMailerQueries.js +232 -102
  82. package/dist/unified-esm/src/react/hooks/useMailerQueries.js.map +1 -1
  83. package/dist/unified-esm/src/react/index.d.ts +5 -3
  84. package/dist/unified-esm/src/react/index.d.ts.map +1 -1
  85. package/dist/unified-esm/src/react/index.js +9 -5
  86. package/dist/unified-esm/src/react/index.js.map +1 -1
  87. package/dist/unified-esm/src/solana/index.d.ts +1 -1
  88. package/dist/unified-esm/src/solana/index.d.ts.map +1 -1
  89. package/dist/unified-esm/src/solana/index.js +2 -1
  90. package/dist/unified-esm/src/solana/index.js.map +1 -1
  91. package/dist/unified-esm/src/solana/solana-mailer-client.d.ts +209 -0
  92. package/dist/unified-esm/src/solana/solana-mailer-client.d.ts.map +1 -0
  93. package/dist/unified-esm/src/solana/solana-mailer-client.js +1000 -0
  94. package/dist/unified-esm/src/solana/solana-mailer-client.js.map +1 -0
  95. package/dist/unified-esm/src/solana/types.d.ts +3 -2
  96. package/dist/unified-esm/src/solana/types.d.ts.map +1 -1
  97. package/dist/unified-esm/src/solana/types.js.map +1 -1
  98. package/dist/unified-esm/src/unified/index.d.ts +1 -1
  99. package/dist/unified-esm/src/unified/index.d.ts.map +1 -1
  100. package/dist/unified-esm/src/unified/onchain-mailer-client.d.ts +187 -268
  101. package/dist/unified-esm/src/unified/onchain-mailer-client.d.ts.map +1 -1
  102. package/dist/unified-esm/src/unified/onchain-mailer-client.js +539 -1614
  103. package/dist/unified-esm/src/unified/onchain-mailer-client.js.map +1 -1
  104. package/dist/unified-esm/src/unified/types.d.ts +23 -6
  105. package/dist/unified-esm/src/unified/types.d.ts.map +1 -1
  106. package/package.json +5 -4
  107. package/programs/mailer/Cargo.toml +1 -1
  108. package/dist/evm/src/evm/mailer-client.d.ts.map +0 -1
  109. package/dist/evm/src/evm/mailer-client.js +0 -349
  110. package/dist/evm/src/evm/mailer-client.js.map +0 -1
  111. package/dist/solana/solana/mailer-client.d.ts +0 -220
  112. package/dist/solana/solana/mailer-client.d.ts.map +0 -1
  113. package/dist/solana/solana/mailer-client.js +0 -920
  114. package/dist/solana/solana/mailer-client.js.map +0 -1
  115. package/dist/unified/src/evm/mailer-client.d.ts.map +0 -1
  116. package/dist/unified/src/evm/mailer-client.js +0 -349
  117. package/dist/unified/src/evm/mailer-client.js.map +0 -1
  118. package/dist/unified/src/solana/mailer-client.d.ts +0 -220
  119. package/dist/unified/src/solana/mailer-client.d.ts.map +0 -1
  120. package/dist/unified/src/solana/mailer-client.js +0 -920
  121. package/dist/unified/src/solana/mailer-client.js.map +0 -1
  122. package/dist/unified-esm/src/evm/mailer-client.d.ts.map +0 -1
  123. package/dist/unified-esm/src/evm/mailer-client.js +0 -345
  124. package/dist/unified-esm/src/evm/mailer-client.js.map +0 -1
  125. package/dist/unified-esm/src/solana/mailer-client.d.ts +0 -220
  126. package/dist/unified-esm/src/solana/mailer-client.d.ts.map +0 -1
  127. package/dist/unified-esm/src/solana/mailer-client.js +0 -916
  128. package/dist/unified-esm/src/solana/mailer-client.js.map +0 -1
@@ -1,920 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MailerClient = void 0;
4
- const web3_js_1 = require("@solana/web3.js");
5
- const spl_token_1 = require("@solana/spl-token");
6
- /**
7
- * Native Solana Program instruction data structures
8
- */
9
- // Instruction data encoding functions
10
- function encodeInitialize(usdcMint) {
11
- const data = Buffer.alloc(1 + 32);
12
- data.writeUInt8(InstructionType.Initialize, 0);
13
- usdcMint.toBuffer().copy(data, 1);
14
- return data;
15
- }
16
- function encodeSend(to, subject, body, revenueShareToReceiver, resolveSenderToName = false) {
17
- const subjectBytes = Buffer.from(subject, 'utf8');
18
- const bodyBytes = Buffer.from(body, 'utf8');
19
- const data = Buffer.alloc(1 + 32 + 4 + subjectBytes.length + 4 + bodyBytes.length + 1 + 1);
20
- let offset = 0;
21
- data.writeUInt8(InstructionType.Send, offset);
22
- offset += 1;
23
- to.toBuffer().copy(data, offset);
24
- offset += 32;
25
- data.writeUInt32LE(subjectBytes.length, offset);
26
- offset += 4;
27
- subjectBytes.copy(data, offset);
28
- offset += subjectBytes.length;
29
- data.writeUInt32LE(bodyBytes.length, offset);
30
- offset += 4;
31
- bodyBytes.copy(data, offset);
32
- offset += bodyBytes.length;
33
- data.writeUInt8(revenueShareToReceiver ? 1 : 0, offset);
34
- offset += 1;
35
- data.writeUInt8(resolveSenderToName ? 1 : 0, offset);
36
- return data;
37
- }
38
- function encodeSendPrepared(to, mailId, revenueShareToReceiver, resolveSenderToName = false) {
39
- const mailIdBytes = Buffer.from(mailId, 'utf8');
40
- const data = Buffer.alloc(1 + 32 + 4 + mailIdBytes.length + 1 + 1);
41
- let offset = 0;
42
- data.writeUInt8(InstructionType.SendPrepared, offset);
43
- offset += 1;
44
- to.toBuffer().copy(data, offset);
45
- offset += 32;
46
- data.writeUInt32LE(mailIdBytes.length, offset);
47
- offset += 4;
48
- mailIdBytes.copy(data, offset);
49
- offset += mailIdBytes.length;
50
- data.writeUInt8(revenueShareToReceiver ? 1 : 0, offset);
51
- offset += 1;
52
- data.writeUInt8(resolveSenderToName ? 1 : 0, offset);
53
- return data;
54
- }
55
- function encodeSendToEmail(toEmail, subject, body) {
56
- const emailBytes = Buffer.from(toEmail, 'utf8');
57
- const subjectBytes = Buffer.from(subject, 'utf8');
58
- const bodyBytes = Buffer.from(body, 'utf8');
59
- const data = Buffer.alloc(1 + 4 + emailBytes.length + 4 + subjectBytes.length + 4 + bodyBytes.length);
60
- let offset = 0;
61
- data.writeUInt8(InstructionType.SendToEmail, offset);
62
- offset += 1;
63
- data.writeUInt32LE(emailBytes.length, offset);
64
- offset += 4;
65
- emailBytes.copy(data, offset);
66
- offset += emailBytes.length;
67
- data.writeUInt32LE(subjectBytes.length, offset);
68
- offset += 4;
69
- subjectBytes.copy(data, offset);
70
- offset += subjectBytes.length;
71
- data.writeUInt32LE(bodyBytes.length, offset);
72
- offset += 4;
73
- bodyBytes.copy(data, offset);
74
- return data;
75
- }
76
- function encodeSendPreparedToEmail(toEmail, mailId) {
77
- const emailBytes = Buffer.from(toEmail, 'utf8');
78
- const mailIdBytes = Buffer.from(mailId, 'utf8');
79
- const data = Buffer.alloc(1 + 4 + emailBytes.length + 4 + mailIdBytes.length);
80
- let offset = 0;
81
- data.writeUInt8(InstructionType.SendPreparedToEmail, offset);
82
- offset += 1;
83
- data.writeUInt32LE(emailBytes.length, offset);
84
- offset += 4;
85
- emailBytes.copy(data, offset);
86
- offset += emailBytes.length;
87
- data.writeUInt32LE(mailIdBytes.length, offset);
88
- offset += 4;
89
- mailIdBytes.copy(data, offset);
90
- return data;
91
- }
92
- function encodeSendThroughWebhook(to, webhookId, revenueShareToReceiver, resolveSenderToName = false) {
93
- const webhookBytes = Buffer.from(webhookId, 'utf8');
94
- const data = Buffer.alloc(1 + 32 + 4 + webhookBytes.length + 1 + 1);
95
- let offset = 0;
96
- data.writeUInt8(InstructionType.SendThroughWebhook, offset);
97
- offset += 1;
98
- to.toBuffer().copy(data, offset);
99
- offset += 32;
100
- data.writeUInt32LE(webhookBytes.length, offset);
101
- offset += 4;
102
- webhookBytes.copy(data, offset);
103
- offset += webhookBytes.length;
104
- data.writeUInt8(revenueShareToReceiver ? 1 : 0, offset);
105
- offset += 1;
106
- data.writeUInt8(resolveSenderToName ? 1 : 0, offset);
107
- return data;
108
- }
109
- function encodeSimpleInstruction(instructionType) {
110
- const data = Buffer.alloc(1);
111
- data.writeUInt8(instructionType, 0);
112
- return data;
113
- }
114
- function encodeSetFee(newFee) {
115
- const data = Buffer.alloc(1 + 8);
116
- data.writeUInt8(InstructionType.SetFee, 0);
117
- data.writeBigUInt64LE(newFee, 1);
118
- return data;
119
- }
120
- function encodeSetDelegationFee(newFee) {
121
- const data = Buffer.alloc(1 + 8);
122
- data.writeUInt8(InstructionType.SetDelegationFee, 0);
123
- data.writeBigUInt64LE(newFee, 1);
124
- return data;
125
- }
126
- function encodeSetCustomFeePercentage(account, percentage) {
127
- const data = Buffer.alloc(1 + 32 + 1);
128
- data.writeUInt8(InstructionType.SetCustomFeePercentage, 0);
129
- account.toBuffer().copy(data, 1);
130
- data.writeUInt8(percentage, 33);
131
- return data;
132
- }
133
- function encodeClearCustomFeePercentage(account) {
134
- const data = Buffer.alloc(1 + 32);
135
- data.writeUInt8(InstructionType.ClearCustomFeePercentage, 0);
136
- account.toBuffer().copy(data, 1);
137
- return data;
138
- }
139
- function encodeDelegateTo(delegate) {
140
- if (!delegate) {
141
- // Clear delegation - just send the instruction type and a null option
142
- const data = Buffer.alloc(1 + 1);
143
- data.writeUInt8(InstructionType.DelegateTo, 0);
144
- data.writeUInt8(0, 1); // Option::None
145
- return data;
146
- }
147
- else {
148
- // Set delegation - send instruction type, Some option, and pubkey
149
- const data = Buffer.alloc(1 + 1 + 32);
150
- data.writeUInt8(InstructionType.DelegateTo, 0);
151
- data.writeUInt8(1, 1); // Option::Some
152
- delegate.toBuffer().copy(data, 2);
153
- return data;
154
- }
155
- }
156
- function encodeClaimExpiredShares(recipient) {
157
- const data = Buffer.alloc(1 + 32);
158
- data.writeUInt8(InstructionType.ClaimExpiredShares, 0);
159
- recipient.toBuffer().copy(data, 1);
160
- return data;
161
- }
162
- // Account data parsing functions
163
- function parseMailerState(data) {
164
- let offset = 0;
165
- const owner = new web3_js_1.PublicKey(data.slice(offset, offset + 32));
166
- offset += 32;
167
- const usdcMint = new web3_js_1.PublicKey(data.slice(offset, offset + 32));
168
- offset += 32;
169
- const sendFee = data.readBigUInt64LE(offset);
170
- offset += 8;
171
- const delegationFee = data.readBigUInt64LE(offset);
172
- offset += 8;
173
- const ownerClaimable = data.readBigUInt64LE(offset);
174
- offset += 8;
175
- const paused = data.readUInt8(offset) === 1;
176
- offset += 1;
177
- const bump = data.readUInt8(offset);
178
- return {
179
- owner,
180
- usdc_mint: usdcMint,
181
- send_fee: sendFee,
182
- delegation_fee: delegationFee,
183
- owner_claimable: ownerClaimable,
184
- paused,
185
- bump,
186
- };
187
- }
188
- function parseRecipientClaim(data) {
189
- let offset = 0;
190
- const recipient = new web3_js_1.PublicKey(data.slice(offset, offset + 32));
191
- offset += 32;
192
- const amount = data.readBigUInt64LE(offset);
193
- offset += 8;
194
- const timestamp = data.readBigInt64LE(offset);
195
- offset += 8;
196
- const bump = data.readUInt8(offset);
197
- return {
198
- recipient,
199
- amount,
200
- timestamp,
201
- bump,
202
- };
203
- }
204
- function parseDelegation(data) {
205
- let offset = 0;
206
- const delegator = new web3_js_1.PublicKey(data.slice(offset, offset + 32));
207
- offset += 32;
208
- const hasDelegate = data.readUInt8(offset) === 1;
209
- offset += 1;
210
- const delegate = hasDelegate
211
- ? new web3_js_1.PublicKey(data.slice(offset, offset + 32))
212
- : null;
213
- if (hasDelegate)
214
- offset += 32;
215
- const bump = data.readUInt8(offset);
216
- return {
217
- delegator,
218
- delegate,
219
- bump,
220
- };
221
- }
222
- function parseFeeDiscount(data) {
223
- let offset = 0;
224
- const account = new web3_js_1.PublicKey(data.slice(offset, offset + 32));
225
- offset += 32;
226
- const discount = data.readUInt8(offset);
227
- offset += 1;
228
- const bump = data.readUInt8(offset);
229
- return {
230
- account,
231
- discount,
232
- bump,
233
- };
234
- }
235
- var InstructionType;
236
- (function (InstructionType) {
237
- InstructionType[InstructionType["Initialize"] = 0] = "Initialize";
238
- InstructionType[InstructionType["Send"] = 1] = "Send";
239
- InstructionType[InstructionType["SendPrepared"] = 2] = "SendPrepared";
240
- InstructionType[InstructionType["SendToEmail"] = 3] = "SendToEmail";
241
- InstructionType[InstructionType["SendPreparedToEmail"] = 4] = "SendPreparedToEmail";
242
- InstructionType[InstructionType["SendThroughWebhook"] = 5] = "SendThroughWebhook";
243
- InstructionType[InstructionType["ClaimRecipientShare"] = 6] = "ClaimRecipientShare";
244
- InstructionType[InstructionType["ClaimOwnerShare"] = 7] = "ClaimOwnerShare";
245
- InstructionType[InstructionType["SetFee"] = 8] = "SetFee";
246
- InstructionType[InstructionType["DelegateTo"] = 9] = "DelegateTo";
247
- InstructionType[InstructionType["RejectDelegation"] = 10] = "RejectDelegation";
248
- InstructionType[InstructionType["SetDelegationFee"] = 11] = "SetDelegationFee";
249
- InstructionType[InstructionType["SetCustomFeePercentage"] = 12] = "SetCustomFeePercentage";
250
- InstructionType[InstructionType["ClearCustomFeePercentage"] = 13] = "ClearCustomFeePercentage";
251
- InstructionType[InstructionType["Pause"] = 14] = "Pause";
252
- InstructionType[InstructionType["Unpause"] = 15] = "Unpause";
253
- InstructionType[InstructionType["DistributeClaimableFunds"] = 16] = "DistributeClaimableFunds";
254
- InstructionType[InstructionType["ClaimExpiredShares"] = 17] = "ClaimExpiredShares";
255
- InstructionType[InstructionType["EmergencyUnpause"] = 18] = "EmergencyUnpause";
256
- })(InstructionType || (InstructionType = {}));
257
- /**
258
- * @class MailerClient
259
- * @description Native Solana program client for the Mailer program
260
- * @notice Provides easy-to-use methods for sending messages with USDC fees and revenue sharing
261
- *
262
- * ## Key Features:
263
- * - **Priority Messages**: Full fee (0.1 USDC) with 90% revenue share to recipient
264
- * - **Standard Messages**: 10% fee only (0.01 USDC) with no revenue share
265
- * - **Revenue Claims**: 60-day claim period for priority message revenue shares
266
- * - **Delegation Management**: Delegate message handling with rejection capability
267
- *
268
- * ## Usage Examples:
269
- * ```typescript
270
- * // Connect to existing deployed program
271
- * const connection = new Connection('https://api.devnet.solana.com');
272
- * const wallet = new WalletAdapter(keypair);
273
- * const programId = new PublicKey('9FLkBDGpZBcR8LMsQ7MwwV6X9P4TDFgN3DeRh5qYyHJF');
274
- * const usdcMint = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');
275
- * const client = new MailerClient(connection, wallet, programId, usdcMint);
276
- *
277
- * // Send message with revenue sharing to recipient
278
- * await client.send('recipient-address', 'Subject', 'Message body', true);
279
- *
280
- * // Claim your revenue share within 60 days (as recipient)
281
- * await client.claimRecipientShare();
282
- *
283
- * // Check claimable amount
284
- * const info = await client.getRecipientClaimable();
285
- * if (info) console.log(`Claimable: ${formatUSDC(info.amount)} USDC`);
286
- * ```
287
- *
288
- * @author Mailer Team
289
- * @version 2.0.0 - Native Solana Program (no Anchor)
290
- */
291
- class MailerClient {
292
- constructor(connection, wallet, programId, usdcMint) {
293
- this.connection = connection;
294
- this.wallet = wallet;
295
- this.programId = programId;
296
- this.usdcMint = usdcMint;
297
- // Derive the mailer state PDA
298
- const [mailerPda, bump] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('mailer')], this.programId);
299
- this.mailerStatePda = mailerPda;
300
- this.mailerBump = bump;
301
- }
302
- /**
303
- * Initialize the mailer program (owner only)
304
- */
305
- async initialize() {
306
- const instruction = new web3_js_1.TransactionInstruction({
307
- keys: [
308
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
309
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: true },
310
- { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
311
- ],
312
- programId: this.programId,
313
- data: encodeInitialize(this.usdcMint),
314
- });
315
- const transaction = new web3_js_1.Transaction().add(instruction);
316
- return await this.sendTransaction(transaction);
317
- }
318
- /**
319
- * Send a message with optional revenue sharing
320
- * @param to Recipient's public key or address string who receives message and potential revenue share
321
- * @param subject Message subject
322
- * @param body Message body
323
- * @param revenueShareToReceiver If true, recipient gets 90% revenue share; if false, no revenue share
324
- * @param resolveSenderToName If true, resolve sender address to name via off-chain service
325
- * @returns Transaction signature
326
- */
327
- async send(to, subject, body, revenueShareToReceiver = false, resolveSenderToName = false) {
328
- const recipientKey = typeof to === 'string' ? new web3_js_1.PublicKey(to) : to;
329
- // Derive recipient claim PDA
330
- const [recipientClaimPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('claim'), recipientKey.toBuffer()], this.programId);
331
- // Get associated token accounts
332
- const senderTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.wallet.publicKey);
333
- const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.mailerStatePda, true);
334
- // Check if accounts need to be created
335
- const instructions = [];
336
- // Check if mailer token account exists
337
- const mailerTokenInfo = await this.connection.getAccountInfo(mailerTokenAccount);
338
- if (!mailerTokenInfo) {
339
- instructions.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(this.wallet.publicKey, mailerTokenAccount, this.mailerStatePda, this.usdcMint));
340
- }
341
- // Add the send instruction
342
- const sendInstruction = new web3_js_1.TransactionInstruction({
343
- keys: [
344
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
345
- { pubkey: recipientClaimPda, isSigner: false, isWritable: true },
346
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: false },
347
- { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
348
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
349
- { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
350
- { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
351
- ],
352
- programId: this.programId,
353
- data: encodeSend(recipientKey, subject, body, revenueShareToReceiver, resolveSenderToName),
354
- });
355
- instructions.push(sendInstruction);
356
- const transaction = new web3_js_1.Transaction().add(...instructions);
357
- return await this.sendTransaction(transaction);
358
- }
359
- /**
360
- * Claim recipient share of revenue
361
- * @returns Transaction signature
362
- */
363
- async claimRecipientShare() {
364
- const [recipientClaimPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('claim'), this.wallet.publicKey.toBuffer()], this.programId);
365
- const recipientTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.wallet.publicKey);
366
- const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.mailerStatePda, true);
367
- const instruction = new web3_js_1.TransactionInstruction({
368
- keys: [
369
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
370
- { pubkey: recipientClaimPda, isSigner: false, isWritable: true },
371
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: false },
372
- { pubkey: recipientTokenAccount, isSigner: false, isWritable: true },
373
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
374
- { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
375
- ],
376
- programId: this.programId,
377
- data: encodeSimpleInstruction(InstructionType.ClaimRecipientShare),
378
- });
379
- const transaction = new web3_js_1.Transaction().add(instruction);
380
- return await this.sendTransaction(transaction);
381
- }
382
- /**
383
- * Claim owner share of fees (owner only)
384
- * @returns Transaction signature
385
- */
386
- async claimOwnerShare() {
387
- const ownerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.wallet.publicKey);
388
- const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.mailerStatePda, true);
389
- const instruction = new web3_js_1.TransactionInstruction({
390
- keys: [
391
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
392
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: true },
393
- { pubkey: ownerTokenAccount, isSigner: false, isWritable: true },
394
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
395
- { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
396
- ],
397
- programId: this.programId,
398
- data: encodeSimpleInstruction(InstructionType.ClaimOwnerShare),
399
- });
400
- const transaction = new web3_js_1.Transaction().add(instruction);
401
- return await this.sendTransaction(transaction);
402
- }
403
- /**
404
- * Claim expired recipient shares and move them under owner control
405
- * @param recipient Recipient whose expired shares to reclaim
406
- * @param options Transaction confirm options
407
- * @returns Transaction signature
408
- */
409
- async claimExpiredShares(recipient, options) {
410
- const recipientKey = typeof recipient === 'string' ? new web3_js_1.PublicKey(recipient) : recipient;
411
- const [recipientClaimPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('claim'), recipientKey.toBuffer()], this.programId);
412
- const instruction = new web3_js_1.TransactionInstruction({
413
- keys: [
414
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
415
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: true },
416
- { pubkey: recipientClaimPda, isSigner: false, isWritable: true },
417
- ],
418
- programId: this.programId,
419
- data: encodeClaimExpiredShares(recipientKey),
420
- });
421
- const transaction = new web3_js_1.Transaction().add(instruction);
422
- return await this.sendTransaction(transaction, options);
423
- }
424
- /**
425
- * Delegate message handling to another address
426
- * @param delegate Address to delegate to, or null to clear delegation
427
- * @returns Transaction signature
428
- */
429
- async delegateTo(delegate) {
430
- const delegateKey = delegate
431
- ? typeof delegate === 'string'
432
- ? new web3_js_1.PublicKey(delegate)
433
- : delegate
434
- : null;
435
- const [delegationPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('delegation'), this.wallet.publicKey.toBuffer()], this.programId);
436
- const delegatorTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.wallet.publicKey);
437
- const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.mailerStatePda, true);
438
- const instruction = new web3_js_1.TransactionInstruction({
439
- keys: [
440
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
441
- { pubkey: delegationPda, isSigner: false, isWritable: true },
442
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: false },
443
- { pubkey: delegatorTokenAccount, isSigner: false, isWritable: true },
444
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
445
- { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
446
- { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
447
- ],
448
- programId: this.programId,
449
- data: encodeDelegateTo(delegateKey),
450
- });
451
- const transaction = new web3_js_1.Transaction().add(instruction);
452
- return await this.sendTransaction(transaction);
453
- }
454
- /**
455
- * Reject a delegation made to you
456
- * @param delegator Address that delegated to you
457
- * @returns Transaction signature
458
- */
459
- async rejectDelegation(delegator) {
460
- const delegatorKey = typeof delegator === 'string' ? new web3_js_1.PublicKey(delegator) : delegator;
461
- const [delegationPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('delegation'), delegatorKey.toBuffer()], this.programId);
462
- const instruction = new web3_js_1.TransactionInstruction({
463
- keys: [
464
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
465
- { pubkey: delegationPda, isSigner: false, isWritable: true },
466
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: false },
467
- ],
468
- programId: this.programId,
469
- data: encodeSimpleInstruction(InstructionType.RejectDelegation),
470
- });
471
- const transaction = new web3_js_1.Transaction().add(instruction);
472
- return await this.sendTransaction(transaction);
473
- }
474
- /**
475
- * Set the send fee (owner only)
476
- * @param newFee New fee in USDC micro-units (6 decimals)
477
- * @returns Transaction signature
478
- */
479
- async setFee(newFee) {
480
- const instruction = new web3_js_1.TransactionInstruction({
481
- keys: [
482
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
483
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: true },
484
- ],
485
- programId: this.programId,
486
- data: encodeSetFee(typeof newFee === 'bigint' ? newFee : BigInt(newFee)),
487
- });
488
- const transaction = new web3_js_1.Transaction().add(instruction);
489
- return await this.sendTransaction(transaction);
490
- }
491
- /**
492
- * Set the delegation fee (owner only)
493
- * @param newFee New delegation fee in USDC micro-units (6 decimals)
494
- * @returns Transaction signature
495
- */
496
- async setDelegationFee(newFee) {
497
- const instruction = new web3_js_1.TransactionInstruction({
498
- keys: [
499
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
500
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: true },
501
- ],
502
- programId: this.programId,
503
- data: encodeSetDelegationFee(typeof newFee === 'bigint' ? newFee : BigInt(newFee)),
504
- });
505
- const transaction = new web3_js_1.Transaction().add(instruction);
506
- return await this.sendTransaction(transaction);
507
- }
508
- async setCustomFeePercentage(account, percentage, payer) {
509
- const normalizedPercentage = Math.trunc(percentage);
510
- if (normalizedPercentage < 0 || normalizedPercentage > 100) {
511
- throw new Error('Percentage must be between 0 and 100');
512
- }
513
- const accountKey = typeof account === 'string' ? new web3_js_1.PublicKey(account) : account;
514
- const payerKey = payer
515
- ? typeof payer === 'string'
516
- ? new web3_js_1.PublicKey(payer)
517
- : payer
518
- : this.wallet.publicKey;
519
- const [discountPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('discount'), accountKey.toBuffer()], this.programId);
520
- const instruction = new web3_js_1.TransactionInstruction({
521
- keys: [
522
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
523
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: false },
524
- { pubkey: discountPda, isSigner: false, isWritable: true },
525
- { pubkey: accountKey, isSigner: false, isWritable: false },
526
- { pubkey: payerKey, isSigner: true, isWritable: true },
527
- { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
528
- ],
529
- programId: this.programId,
530
- data: encodeSetCustomFeePercentage(accountKey, normalizedPercentage),
531
- });
532
- const transaction = new web3_js_1.Transaction().add(instruction);
533
- return this.sendTransaction(transaction);
534
- }
535
- async clearCustomFeePercentage(account) {
536
- const accountKey = typeof account === 'string' ? new web3_js_1.PublicKey(account) : account;
537
- const [discountPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('discount'), accountKey.toBuffer()], this.programId);
538
- const instruction = new web3_js_1.TransactionInstruction({
539
- keys: [
540
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
541
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: false },
542
- { pubkey: discountPda, isSigner: false, isWritable: true },
543
- ],
544
- programId: this.programId,
545
- data: encodeClearCustomFeePercentage(accountKey),
546
- });
547
- const transaction = new web3_js_1.Transaction().add(instruction);
548
- return this.sendTransaction(transaction);
549
- }
550
- async getCustomFeePercentage(account) {
551
- const accountKey = typeof account === 'string' ? new web3_js_1.PublicKey(account) : account;
552
- const [discountPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('discount'), accountKey.toBuffer()], this.programId);
553
- const accountInfo = await this.connection.getAccountInfo(discountPda);
554
- if (!accountInfo) {
555
- return 100;
556
- }
557
- const discountState = parseFeeDiscount(accountInfo.data);
558
- return 100 - discountState.discount;
559
- }
560
- /**
561
- * Get current fees from the mailer state
562
- * @returns MailerFees object with current fees
563
- */
564
- async getFees() {
565
- const accountInfo = await this.connection.getAccountInfo(this.mailerStatePda);
566
- if (!accountInfo) {
567
- throw new Error('Mailer state account not found - program not initialized');
568
- }
569
- const stateData = parseMailerState(accountInfo.data);
570
- return {
571
- sendFee: Number(stateData.send_fee),
572
- delegationFee: Number(stateData.delegation_fee),
573
- };
574
- }
575
- /**
576
- * Get recipient claimable information
577
- * @param recipient Optional recipient address, defaults to wallet address
578
- * @returns ClaimableInfo or null if no claimable amount
579
- */
580
- async getRecipientClaimable(recipient) {
581
- const recipientKey = recipient || this.wallet.publicKey;
582
- const [recipientClaimPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('claim'), recipientKey.toBuffer()], this.programId);
583
- const accountInfo = await this.connection.getAccountInfo(recipientClaimPda);
584
- if (!accountInfo) {
585
- return null;
586
- }
587
- const claimData = parseRecipientClaim(accountInfo.data);
588
- // Check if claim period has expired (60 days)
589
- const now = Math.floor(Date.now() / 1000);
590
- const isExpired = now > Number(claimData.timestamp) + 60 * 24 * 60 * 60;
591
- return {
592
- amount: Number(claimData.amount),
593
- timestamp: Number(claimData.timestamp),
594
- recipient: recipientKey.toBase58(),
595
- isExpired,
596
- };
597
- }
598
- /**
599
- * Get owner claimable amount
600
- * @returns Owner claimable amount in USDC micro-units
601
- */
602
- async getOwnerClaimable() {
603
- const accountInfo = await this.connection.getAccountInfo(this.mailerStatePda);
604
- if (!accountInfo) {
605
- throw new Error('Mailer state account not found');
606
- }
607
- const stateData = parseMailerState(accountInfo.data);
608
- return Number(stateData.owner_claimable);
609
- }
610
- /**
611
- * Get delegation information for an address
612
- * @param delegator Address to check delegation for, defaults to wallet address
613
- * @returns Delegation info or null if no delegation
614
- */
615
- async getDelegation(delegator) {
616
- const delegatorKey = delegator || this.wallet.publicKey;
617
- const [delegationPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('delegation'), delegatorKey.toBuffer()], this.programId);
618
- const accountInfo = await this.connection.getAccountInfo(delegationPda);
619
- if (!accountInfo) {
620
- return null;
621
- }
622
- const delegationData = parseDelegation(accountInfo.data);
623
- return {
624
- delegator: delegatorKey.toBase58(),
625
- delegate: delegationData.delegate
626
- ? delegationData.delegate.toBase58()
627
- : null,
628
- };
629
- }
630
- /**
631
- * Get the mailer state PDA address
632
- * @returns PublicKey of the mailer state PDA
633
- */
634
- getMailerStatePda() {
635
- return this.mailerStatePda;
636
- }
637
- /**
638
- * Send a message to an email address (no wallet known)
639
- * Charges only 10% owner fee since recipient wallet is unknown
640
- * @param toEmail Email address of the recipient
641
- * @param subject Message subject
642
- * @param body Message body
643
- * @param options Transaction confirm options
644
- * @returns Transaction signature
645
- */
646
- async sendToEmail(toEmail, subject, body, options) {
647
- // Get associated token accounts
648
- const senderTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.wallet.publicKey);
649
- const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.mailerStatePda, true);
650
- // Check if accounts need to be created
651
- const instructions = [];
652
- // Check if mailer token account exists
653
- const mailerTokenInfo = await this.connection.getAccountInfo(mailerTokenAccount);
654
- if (!mailerTokenInfo) {
655
- instructions.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(this.wallet.publicKey, mailerTokenAccount, this.mailerStatePda, this.usdcMint));
656
- }
657
- // Encode instruction data for SendToEmail
658
- const instructionData = encodeSendToEmail(toEmail, subject, body);
659
- // Create send instruction
660
- instructions.push(new web3_js_1.TransactionInstruction({
661
- keys: [
662
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
663
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: true },
664
- { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
665
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
666
- { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
667
- ],
668
- programId: this.programId,
669
- data: instructionData,
670
- }));
671
- const transaction = new web3_js_1.Transaction().add(...instructions);
672
- return this.sendTransaction(transaction, options);
673
- }
674
- /**
675
- * Send a prepared message to an email address (no wallet known)
676
- * Charges only 10% owner fee since recipient wallet is unknown
677
- * @param toEmail Email address of the recipient
678
- * @param mailId Pre-prepared message ID
679
- * @param options Transaction confirm options
680
- * @returns Transaction signature
681
- */
682
- async sendPreparedToEmail(toEmail, mailId, options) {
683
- // Get associated token accounts
684
- const senderTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.wallet.publicKey);
685
- const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.mailerStatePda, true);
686
- // Check if accounts need to be created
687
- const instructions = [];
688
- // Check if mailer token account exists
689
- const mailerTokenInfo = await this.connection.getAccountInfo(mailerTokenAccount);
690
- if (!mailerTokenInfo) {
691
- instructions.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(this.wallet.publicKey, mailerTokenAccount, this.mailerStatePda, this.usdcMint));
692
- }
693
- // Encode instruction data for SendPreparedToEmail
694
- const instructionData = encodeSendPreparedToEmail(toEmail, mailId);
695
- // Create send instruction
696
- instructions.push(new web3_js_1.TransactionInstruction({
697
- keys: [
698
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
699
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: true },
700
- { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
701
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
702
- { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
703
- ],
704
- programId: this.programId,
705
- data: instructionData,
706
- }));
707
- const transaction = new web3_js_1.Transaction().add(...instructions);
708
- return this.sendTransaction(transaction, options);
709
- }
710
- /**
711
- * Send a prepared message using a mailId (to match EVM behavior)
712
- * @param to Recipient's public key or address string
713
- * @param mailId Pre-prepared message identifier
714
- * @param revenueShareToReceiver If true, recipient gets 90% revenue share
715
- * @param resolveSenderToName If true, resolve sender address to name
716
- * @returns Transaction signature
717
- */
718
- async sendPrepared(to, mailId, revenueShareToReceiver = false, resolveSenderToName = false) {
719
- const recipientKey = typeof to === 'string' ? new web3_js_1.PublicKey(to) : to;
720
- const [recipientClaimPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('claim'), recipientKey.toBuffer()], this.programId);
721
- const senderTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.wallet.publicKey);
722
- const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.mailerStatePda, true);
723
- const instructions = [];
724
- const mailerTokenInfo = await this.connection.getAccountInfo(mailerTokenAccount);
725
- if (!mailerTokenInfo) {
726
- instructions.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(this.wallet.publicKey, mailerTokenAccount, this.mailerStatePda, this.usdcMint));
727
- }
728
- const sendInstruction = new web3_js_1.TransactionInstruction({
729
- keys: [
730
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
731
- { pubkey: recipientClaimPda, isSigner: false, isWritable: true },
732
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: false },
733
- { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
734
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
735
- { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
736
- { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
737
- ],
738
- programId: this.programId,
739
- data: encodeSendPrepared(recipientKey, mailId, revenueShareToReceiver, resolveSenderToName),
740
- });
741
- instructions.push(sendInstruction);
742
- const transaction = new web3_js_1.Transaction().add(...instructions);
743
- return this.sendTransaction(transaction);
744
- }
745
- async sendThroughWebhook(to, webhookId, revenueShareToReceiver = false, resolveSenderToName = false) {
746
- const recipientKey = typeof to === 'string' ? new web3_js_1.PublicKey(to) : to;
747
- const [recipientClaimPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('claim'), recipientKey.toBuffer()], this.programId);
748
- const senderTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.wallet.publicKey);
749
- const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.mailerStatePda, true);
750
- const instructions = [];
751
- const mailerTokenInfo = await this.connection.getAccountInfo(mailerTokenAccount);
752
- if (!mailerTokenInfo) {
753
- instructions.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(this.wallet.publicKey, mailerTokenAccount, this.mailerStatePda, this.usdcMint));
754
- }
755
- const sendInstruction = new web3_js_1.TransactionInstruction({
756
- keys: [
757
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
758
- { pubkey: recipientClaimPda, isSigner: false, isWritable: true },
759
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: false },
760
- { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
761
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
762
- { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
763
- { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
764
- ],
765
- programId: this.programId,
766
- data: encodeSendThroughWebhook(recipientKey, webhookId, revenueShareToReceiver, resolveSenderToName),
767
- });
768
- instructions.push(sendInstruction);
769
- const transaction = new web3_js_1.Transaction().add(...instructions);
770
- return this.sendTransaction(transaction);
771
- }
772
- /**
773
- * Pause the contract and distribute owner claimable funds (owner only)
774
- * @param options Transaction confirm options
775
- * @returns Transaction signature
776
- */
777
- async pause(options) {
778
- const ownerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.wallet.publicKey);
779
- const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.mailerStatePda, true);
780
- const instruction = new web3_js_1.TransactionInstruction({
781
- keys: [
782
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
783
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: true },
784
- { pubkey: ownerTokenAccount, isSigner: false, isWritable: true },
785
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
786
- { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
787
- ],
788
- programId: this.programId,
789
- data: encodeSimpleInstruction(InstructionType.Pause),
790
- });
791
- const transaction = new web3_js_1.Transaction().add(instruction);
792
- return await this.sendTransaction(transaction, options);
793
- }
794
- /**
795
- * Unpause the contract (owner only)
796
- * @param options Transaction confirm options
797
- * @returns Transaction signature
798
- */
799
- async unpause(options) {
800
- const instruction = new web3_js_1.TransactionInstruction({
801
- keys: [
802
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
803
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: true },
804
- ],
805
- programId: this.programId,
806
- data: encodeSimpleInstruction(InstructionType.Unpause),
807
- });
808
- const transaction = new web3_js_1.Transaction().add(instruction);
809
- return await this.sendTransaction(transaction, options);
810
- }
811
- /**
812
- * Emergency unpause without fund distribution (owner only)
813
- * @param options Transaction confirm options
814
- * @returns Transaction signature
815
- */
816
- async emergencyUnpause(options) {
817
- const instruction = new web3_js_1.TransactionInstruction({
818
- keys: [
819
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
820
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: true },
821
- ],
822
- programId: this.programId,
823
- data: encodeSimpleInstruction(InstructionType.EmergencyUnpause),
824
- });
825
- const transaction = new web3_js_1.Transaction().add(instruction);
826
- return await this.sendTransaction(transaction, options);
827
- }
828
- /**
829
- * Distribute claimable funds to a recipient when contract is paused
830
- * @param recipient Recipient address to distribute funds for
831
- * @param options Transaction confirm options
832
- * @returns Transaction signature
833
- */
834
- async distributeClaimableFunds(recipient, options) {
835
- const recipientKey = typeof recipient === 'string' ? new web3_js_1.PublicKey(recipient) : recipient;
836
- const [recipientClaimPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('claim'), recipientKey.toBuffer()], this.programId);
837
- const recipientTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, recipientKey);
838
- const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(this.usdcMint, this.mailerStatePda, true);
839
- // Encode the recipient parameter
840
- const data = Buffer.alloc(1 + 32);
841
- data.writeUInt8(InstructionType.DistributeClaimableFunds, 0);
842
- recipientKey.toBuffer().copy(data, 1);
843
- const instruction = new web3_js_1.TransactionInstruction({
844
- keys: [
845
- { pubkey: this.wallet.publicKey, isSigner: true, isWritable: false },
846
- { pubkey: this.mailerStatePda, isSigner: false, isWritable: false },
847
- { pubkey: recipientClaimPda, isSigner: false, isWritable: true },
848
- { pubkey: recipientTokenAccount, isSigner: false, isWritable: true },
849
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
850
- { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
851
- ],
852
- programId: this.programId,
853
- data,
854
- });
855
- const transaction = new web3_js_1.Transaction().add(instruction);
856
- return await this.sendTransaction(transaction, options);
857
- }
858
- /**
859
- * Get the current send fee
860
- * @returns Send fee in USDC micro-units (6 decimals)
861
- */
862
- async getSendFee() {
863
- const fees = await this.getFees();
864
- return BigInt(fees.sendFee);
865
- }
866
- /**
867
- * Check if contract is currently paused
868
- * @returns True if contract is paused, false otherwise
869
- */
870
- async isPaused() {
871
- const accountInfo = await this.connection.getAccountInfo(this.mailerStatePda);
872
- if (!accountInfo) {
873
- throw new Error('Mailer state account not found - program not initialized');
874
- }
875
- const stateData = parseMailerState(accountInfo.data);
876
- // paused field is at offset: 32 + 32 + 8 + 8 + 8 = 88 bytes
877
- return stateData.paused;
878
- }
879
- /**
880
- * Send and confirm a transaction
881
- * @param transaction Transaction to send
882
- * @param options Confirm options
883
- * @returns Transaction signature
884
- */
885
- async sendTransaction(transaction, options) {
886
- // Get recent blockhash
887
- const { blockhash } = await this.connection.getLatestBlockhash();
888
- transaction.recentBlockhash = blockhash;
889
- transaction.feePayer = this.wallet.publicKey;
890
- // Sign transaction
891
- const signedTx = await this.wallet.signTransaction(transaction);
892
- // Send and confirm
893
- const signature = await this.connection.sendRawTransaction(signedTx.serialize());
894
- await this.connection.confirmTransaction(signature, options?.commitment || 'confirmed');
895
- return signature;
896
- }
897
- /**
898
- * Create a simple wallet from a keypair for testing
899
- * @param keypair Solana keypair
900
- * @returns Wallet interface implementation
901
- */
902
- static createWallet(keypair) {
903
- return {
904
- publicKey: keypair.publicKey,
905
- async signTransaction(transaction) {
906
- transaction.partialSign(keypair);
907
- return transaction;
908
- },
909
- async signAllTransactions(transactions) {
910
- return transactions.map((tx) => {
911
- tx.partialSign(keypair);
912
- return tx;
913
- });
914
- },
915
- };
916
- }
917
- }
918
- exports.MailerClient = MailerClient;
919
- // Wallet interface is exported above
920
- //# sourceMappingURL=mailer-client.js.map