@sudobility/contracts 1.13.1 → 1.13.3

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 (198) hide show
  1. package/dist/evm/src/evm/evm-mailer-client.js +3 -3
  2. package/dist/evm/src/evm/evm-mailer-client.js.map +1 -1
  3. package/dist/evm/src/evm/index.d.ts +3 -3
  4. package/dist/evm/src/evm/index.d.ts.map +1 -1
  5. package/dist/evm/src/evm/index.js +4 -4
  6. package/dist/evm/src/evm/index.js.map +1 -1
  7. package/dist/solana/solana/index.d.ts +2 -2
  8. package/dist/solana/solana/index.d.ts.map +1 -1
  9. package/dist/solana/solana/index.js +3 -3
  10. package/dist/solana/solana/index.js.map +1 -1
  11. package/dist/solana/solana/solana-mailer-client.d.ts +1 -1
  12. package/dist/solana/solana/solana-mailer-client.d.ts.map +1 -1
  13. package/dist/solana/solana/solana-mailer-client.js +1 -1
  14. package/dist/solana/solana/solana-mailer-client.js.map +1 -1
  15. package/dist/solana/solana/types.d.ts +1 -1
  16. package/dist/solana/solana/types.d.ts.map +1 -1
  17. package/dist/solana/solana/types.js +5 -5
  18. package/dist/solana/solana/types.js.map +1 -1
  19. package/dist/unified/src/evm/evm-mailer-client.js +7 -11
  20. package/dist/unified/src/evm/evm-mailer-client.js.map +1 -1
  21. package/dist/unified/src/evm/index.d.ts +3 -3
  22. package/dist/unified/src/evm/index.d.ts.map +1 -1
  23. package/dist/unified/src/evm/index.js +2 -7
  24. package/dist/unified/src/evm/index.js.map +1 -1
  25. package/dist/unified/src/react/context/MailerProvider.js +14 -55
  26. package/dist/unified/src/react/context/MailerProvider.js.map +1 -1
  27. package/dist/unified/src/react/hooks/useMailerMutations.js +76 -98
  28. package/dist/unified/src/react/hooks/useMailerMutations.js.map +1 -1
  29. package/dist/unified/src/react/hooks/useMailerQueries.js +52 -68
  30. package/dist/unified/src/react/hooks/useMailerQueries.js.map +1 -1
  31. package/dist/unified/src/react/index.js +5 -47
  32. package/dist/unified/src/react/index.js.map +1 -1
  33. package/dist/unified/src/solana/index.d.ts +2 -2
  34. package/dist/unified/src/solana/index.d.ts.map +1 -1
  35. package/dist/unified/src/solana/index.js +2 -20
  36. package/dist/unified/src/solana/index.js.map +1 -1
  37. package/dist/unified/src/solana/solana-mailer-client.d.ts +1 -1
  38. package/dist/unified/src/solana/solana-mailer-client.d.ts.map +1 -1
  39. package/dist/unified/src/solana/solana-mailer-client.js +129 -133
  40. package/dist/unified/src/solana/solana-mailer-client.js.map +1 -1
  41. package/dist/unified/src/solana/types.d.ts +1 -1
  42. package/dist/unified/src/solana/types.d.ts.map +1 -1
  43. package/dist/unified/src/solana/types.js +6 -13
  44. package/dist/unified/src/solana/types.js.map +1 -1
  45. package/dist/unified/src/unified/index.d.ts +3 -3
  46. package/dist/unified/src/unified/index.d.ts.map +1 -1
  47. package/dist/unified/src/unified/index.js +2 -7
  48. package/dist/unified/src/unified/index.js.map +1 -1
  49. package/dist/unified/src/unified/onchain-mailer-client.d.ts +35 -35
  50. package/dist/unified/src/unified/onchain-mailer-client.d.ts.map +1 -1
  51. package/dist/unified/src/unified/onchain-mailer-client.js +88 -125
  52. package/dist/unified/src/unified/onchain-mailer-client.js.map +1 -1
  53. package/dist/unified/src/unified/types.js +1 -2
  54. package/dist/unified/src/unified/wallet-detector.js +10 -14
  55. package/dist/unified/src/unified/wallet-detector.js.map +1 -1
  56. package/dist/unified/src/utils/chain-config.d.ts +1 -1
  57. package/dist/unified/src/utils/chain-config.d.ts.map +1 -1
  58. package/dist/unified/src/utils/chain-config.js +9 -13
  59. package/dist/unified/src/utils/chain-config.js.map +1 -1
  60. package/dist/unified/src/utils/currency.js +6 -11
  61. package/dist/unified/src/utils/currency.js.map +1 -1
  62. package/dist/unified/src/utils/index.d.ts +3 -3
  63. package/dist/unified/src/utils/index.d.ts.map +1 -1
  64. package/dist/unified/src/utils/index.js +3 -19
  65. package/dist/unified/src/utils/index.js.map +1 -1
  66. package/dist/unified/src/utils/validation.js +11 -17
  67. package/dist/unified/src/utils/validation.js.map +1 -1
  68. package/dist/unified/typechain-types/Mailer.js +1 -2
  69. package/dist/unified/typechain-types/MockUSDC.js +1 -2
  70. package/dist/unified/typechain-types/common.js +1 -2
  71. package/dist/unified/typechain-types/factories/Mailer__factory.js +4 -8
  72. package/dist/unified/typechain-types/factories/Mailer__factory.js.map +1 -1
  73. package/dist/unified/typechain-types/factories/MockUSDC__factory.js +4 -8
  74. package/dist/unified/typechain-types/factories/MockUSDC__factory.js.map +1 -1
  75. package/dist/unified/typechain-types/factories/index.js +3 -41
  76. package/dist/unified/typechain-types/factories/index.js.map +1 -1
  77. package/dist/unified/typechain-types/factories/interfaces/IERC20__factory.js +4 -8
  78. package/dist/unified/typechain-types/factories/interfaces/IERC20__factory.js.map +1 -1
  79. package/dist/unified/typechain-types/factories/interfaces/index.js +1 -5
  80. package/dist/unified/typechain-types/factories/interfaces/index.js.map +1 -1
  81. package/dist/unified/typechain-types/index.js +4 -43
  82. package/dist/unified/typechain-types/index.js.map +1 -1
  83. package/dist/unified/typechain-types/interfaces/IERC20.js +1 -2
  84. package/dist/unified/typechain-types/interfaces/index.js +1 -2
  85. package/package.json +12 -18
  86. package/dist/unified/package.json +0 -3
  87. package/dist/unified-esm/src/evm/evm-mailer-client.d.ts +0 -1062
  88. package/dist/unified-esm/src/evm/evm-mailer-client.d.ts.map +0 -1
  89. package/dist/unified-esm/src/evm/evm-mailer-client.js +0 -920
  90. package/dist/unified-esm/src/evm/evm-mailer-client.js.map +0 -1
  91. package/dist/unified-esm/src/evm/index.d.ts +0 -4
  92. package/dist/unified-esm/src/evm/index.d.ts.map +0 -1
  93. package/dist/unified-esm/src/evm/index.js +0 -5
  94. package/dist/unified-esm/src/evm/index.js.map +0 -1
  95. package/dist/unified-esm/src/react/context/MailerProvider.d.ts +0 -108
  96. package/dist/unified-esm/src/react/context/MailerProvider.d.ts.map +0 -1
  97. package/dist/unified-esm/src/react/context/MailerProvider.js +0 -119
  98. package/dist/unified-esm/src/react/context/MailerProvider.js.map +0 -1
  99. package/dist/unified-esm/src/react/hooks/useMailerMutations.d.ts +0 -334
  100. package/dist/unified-esm/src/react/hooks/useMailerMutations.d.ts.map +0 -1
  101. package/dist/unified-esm/src/react/hooks/useMailerMutations.js +0 -392
  102. package/dist/unified-esm/src/react/hooks/useMailerMutations.js.map +0 -1
  103. package/dist/unified-esm/src/react/hooks/useMailerQueries.d.ts +0 -184
  104. package/dist/unified-esm/src/react/hooks/useMailerQueries.d.ts.map +0 -1
  105. package/dist/unified-esm/src/react/hooks/useMailerQueries.js +0 -316
  106. package/dist/unified-esm/src/react/hooks/useMailerQueries.js.map +0 -1
  107. package/dist/unified-esm/src/react/index.d.ts +0 -39
  108. package/dist/unified-esm/src/react/index.d.ts.map +0 -1
  109. package/dist/unified-esm/src/react/index.js +0 -43
  110. package/dist/unified-esm/src/react/index.js.map +0 -1
  111. package/dist/unified-esm/src/solana/index.d.ts +0 -3
  112. package/dist/unified-esm/src/solana/index.d.ts.map +0 -1
  113. package/dist/unified-esm/src/solana/index.js +0 -4
  114. package/dist/unified-esm/src/solana/index.js.map +0 -1
  115. package/dist/unified-esm/src/solana/solana-mailer-client.d.ts +0 -209
  116. package/dist/unified-esm/src/solana/solana-mailer-client.d.ts.map +0 -1
  117. package/dist/unified-esm/src/solana/solana-mailer-client.js +0 -1000
  118. package/dist/unified-esm/src/solana/solana-mailer-client.js.map +0 -1
  119. package/dist/unified-esm/src/solana/types.d.ts +0 -29
  120. package/dist/unified-esm/src/solana/types.d.ts.map +0 -1
  121. package/dist/unified-esm/src/solana/types.js +0 -16
  122. package/dist/unified-esm/src/solana/types.js.map +0 -1
  123. package/dist/unified-esm/src/unified/index.d.ts +0 -4
  124. package/dist/unified-esm/src/unified/index.d.ts.map +0 -1
  125. package/dist/unified-esm/src/unified/index.js +0 -4
  126. package/dist/unified-esm/src/unified/index.js.map +0 -1
  127. package/dist/unified-esm/src/unified/onchain-mailer-client.d.ts +0 -258
  128. package/dist/unified-esm/src/unified/onchain-mailer-client.d.ts.map +0 -1
  129. package/dist/unified-esm/src/unified/onchain-mailer-client.js +0 -731
  130. package/dist/unified-esm/src/unified/onchain-mailer-client.js.map +0 -1
  131. package/dist/unified-esm/src/unified/types.d.ts +0 -54
  132. package/dist/unified-esm/src/unified/types.d.ts.map +0 -1
  133. package/dist/unified-esm/src/unified/types.js +0 -2
  134. package/dist/unified-esm/src/unified/types.js.map +0 -1
  135. package/dist/unified-esm/src/unified/wallet-detector.d.ts +0 -28
  136. package/dist/unified-esm/src/unified/wallet-detector.d.ts.map +0 -1
  137. package/dist/unified-esm/src/unified/wallet-detector.js +0 -59
  138. package/dist/unified-esm/src/unified/wallet-detector.js.map +0 -1
  139. package/dist/unified-esm/src/utils/chain-config.d.ts +0 -75
  140. package/dist/unified-esm/src/utils/chain-config.d.ts.map +0 -1
  141. package/dist/unified-esm/src/utils/chain-config.js +0 -199
  142. package/dist/unified-esm/src/utils/chain-config.js.map +0 -1
  143. package/dist/unified-esm/src/utils/currency.d.ts +0 -26
  144. package/dist/unified-esm/src/utils/currency.d.ts.map +0 -1
  145. package/dist/unified-esm/src/utils/currency.js +0 -31
  146. package/dist/unified-esm/src/utils/currency.js.map +0 -1
  147. package/dist/unified-esm/src/utils/index.d.ts +0 -4
  148. package/dist/unified-esm/src/utils/index.d.ts.map +0 -1
  149. package/dist/unified-esm/src/utils/index.js +0 -4
  150. package/dist/unified-esm/src/utils/index.js.map +0 -1
  151. package/dist/unified-esm/src/utils/validation.d.ts +0 -10
  152. package/dist/unified-esm/src/utils/validation.d.ts.map +0 -1
  153. package/dist/unified-esm/src/utils/validation.js +0 -96
  154. package/dist/unified-esm/src/utils/validation.js.map +0 -1
  155. package/dist/unified-esm/typechain-types/Mailer.d.ts +0 -698
  156. package/dist/unified-esm/typechain-types/Mailer.d.ts.map +0 -1
  157. package/dist/unified-esm/typechain-types/Mailer.js +0 -2
  158. package/dist/unified-esm/typechain-types/Mailer.js.map +0 -1
  159. package/dist/unified-esm/typechain-types/MockUSDC.d.ts +0 -118
  160. package/dist/unified-esm/typechain-types/MockUSDC.d.ts.map +0 -1
  161. package/dist/unified-esm/typechain-types/MockUSDC.js +0 -2
  162. package/dist/unified-esm/typechain-types/MockUSDC.js.map +0 -1
  163. package/dist/unified-esm/typechain-types/common.d.ts +0 -51
  164. package/dist/unified-esm/typechain-types/common.d.ts.map +0 -1
  165. package/dist/unified-esm/typechain-types/common.js +0 -2
  166. package/dist/unified-esm/typechain-types/common.js.map +0 -1
  167. package/dist/unified-esm/typechain-types/factories/Mailer__factory.d.ts +0 -875
  168. package/dist/unified-esm/typechain-types/factories/Mailer__factory.d.ts.map +0 -1
  169. package/dist/unified-esm/typechain-types/factories/Mailer__factory.js +0 -1121
  170. package/dist/unified-esm/typechain-types/factories/Mailer__factory.js.map +0 -1
  171. package/dist/unified-esm/typechain-types/factories/MockUSDC__factory.d.ts +0 -193
  172. package/dist/unified-esm/typechain-types/factories/MockUSDC__factory.d.ts.map +0 -1
  173. package/dist/unified-esm/typechain-types/factories/MockUSDC__factory.js +0 -259
  174. package/dist/unified-esm/typechain-types/factories/MockUSDC__factory.js.map +0 -1
  175. package/dist/unified-esm/typechain-types/factories/index.d.ts +0 -4
  176. package/dist/unified-esm/typechain-types/factories/index.d.ts.map +0 -1
  177. package/dist/unified-esm/typechain-types/factories/index.js +0 -7
  178. package/dist/unified-esm/typechain-types/factories/index.js.map +0 -1
  179. package/dist/unified-esm/typechain-types/factories/interfaces/IERC20__factory.d.ts +0 -80
  180. package/dist/unified-esm/typechain-types/factories/interfaces/IERC20__factory.d.ts.map +0 -1
  181. package/dist/unified-esm/typechain-types/factories/interfaces/IERC20__factory.js +0 -112
  182. package/dist/unified-esm/typechain-types/factories/interfaces/IERC20__factory.js.map +0 -1
  183. package/dist/unified-esm/typechain-types/factories/interfaces/index.d.ts +0 -2
  184. package/dist/unified-esm/typechain-types/factories/interfaces/index.d.ts.map +0 -1
  185. package/dist/unified-esm/typechain-types/factories/interfaces/index.js +0 -5
  186. package/dist/unified-esm/typechain-types/factories/interfaces/index.js.map +0 -1
  187. package/dist/unified-esm/typechain-types/index.d.ts +0 -10
  188. package/dist/unified-esm/typechain-types/index.d.ts.map +0 -1
  189. package/dist/unified-esm/typechain-types/index.js +0 -5
  190. package/dist/unified-esm/typechain-types/index.js.map +0 -1
  191. package/dist/unified-esm/typechain-types/interfaces/IERC20.d.ts +0 -70
  192. package/dist/unified-esm/typechain-types/interfaces/IERC20.d.ts.map +0 -1
  193. package/dist/unified-esm/typechain-types/interfaces/IERC20.js +0 -2
  194. package/dist/unified-esm/typechain-types/interfaces/IERC20.js.map +0 -1
  195. package/dist/unified-esm/typechain-types/interfaces/index.d.ts +0 -2
  196. package/dist/unified-esm/typechain-types/interfaces/index.d.ts.map +0 -1
  197. package/dist/unified-esm/typechain-types/interfaces/index.js +0 -2
  198. package/dist/unified-esm/typechain-types/interfaces/index.js.map +0 -1
@@ -1,1000 +0,0 @@
1
- import { Connection, PublicKey, Transaction, TransactionInstruction, SystemProgram, ComputeBudgetProgram, } from '@solana/web3.js';
2
- import { TOKEN_PROGRAM_ID, getAssociatedTokenAddressSync, createAssociatedTokenAccountInstruction, } from '@solana/spl-token';
3
- /**
4
- * Native Solana Program instruction types
5
- */
6
- var InstructionType;
7
- (function (InstructionType) {
8
- InstructionType[InstructionType["Initialize"] = 0] = "Initialize";
9
- InstructionType[InstructionType["Send"] = 1] = "Send";
10
- InstructionType[InstructionType["SendPrepared"] = 2] = "SendPrepared";
11
- InstructionType[InstructionType["SendThroughWebhook"] = 3] = "SendThroughWebhook";
12
- InstructionType[InstructionType["SendToEmail"] = 4] = "SendToEmail";
13
- InstructionType[InstructionType["SendPreparedToEmail"] = 5] = "SendPreparedToEmail";
14
- InstructionType[InstructionType["ClaimRecipientShare"] = 6] = "ClaimRecipientShare";
15
- InstructionType[InstructionType["ClaimOwnerShare"] = 7] = "ClaimOwnerShare";
16
- InstructionType[InstructionType["ClaimExpiredShares"] = 8] = "ClaimExpiredShares";
17
- InstructionType[InstructionType["SetFees"] = 9] = "SetFees";
18
- InstructionType[InstructionType["DelegateTo"] = 10] = "DelegateTo";
19
- InstructionType[InstructionType["RejectDelegation"] = 11] = "RejectDelegation";
20
- InstructionType[InstructionType["SetCustomFeePercentage"] = 12] = "SetCustomFeePercentage";
21
- InstructionType[InstructionType["ClearCustomFeePercentage"] = 13] = "ClearCustomFeePercentage";
22
- InstructionType[InstructionType["Pause"] = 14] = "Pause";
23
- InstructionType[InstructionType["Unpause"] = 15] = "Unpause";
24
- InstructionType[InstructionType["EmergencyUnpause"] = 16] = "EmergencyUnpause";
25
- InstructionType[InstructionType["DistributeClaimableFunds"] = 17] = "DistributeClaimableFunds";
26
- })(InstructionType || (InstructionType = {}));
27
- // Instruction data encoding functions
28
- function encodeInitialize(usdcMint) {
29
- const data = Buffer.alloc(1 + 32);
30
- data.writeUInt8(InstructionType.Initialize, 0);
31
- usdcMint.toBuffer().copy(data, 1);
32
- return data;
33
- }
34
- function encodeSend(to, subject, body, revenueShareToReceiver, resolveSenderToName = false) {
35
- const subjectBytes = Buffer.from(subject, 'utf8');
36
- const bodyBytes = Buffer.from(body, 'utf8');
37
- const data = Buffer.alloc(1 + 32 + 4 + subjectBytes.length + 4 + bodyBytes.length + 1 + 1);
38
- let offset = 0;
39
- data.writeUInt8(InstructionType.Send, offset);
40
- offset += 1;
41
- to.toBuffer().copy(data, offset);
42
- offset += 32;
43
- data.writeUInt32LE(subjectBytes.length, offset);
44
- offset += 4;
45
- subjectBytes.copy(data, offset);
46
- offset += subjectBytes.length;
47
- data.writeUInt32LE(bodyBytes.length, offset);
48
- offset += 4;
49
- bodyBytes.copy(data, offset);
50
- offset += bodyBytes.length;
51
- data.writeUInt8(revenueShareToReceiver ? 1 : 0, offset);
52
- offset += 1;
53
- data.writeUInt8(resolveSenderToName ? 1 : 0, offset);
54
- return data;
55
- }
56
- function encodeSendPrepared(to, mailId, revenueShareToReceiver, resolveSenderToName = false) {
57
- const mailIdBytes = Buffer.from(mailId, 'utf8');
58
- const data = Buffer.alloc(1 + 32 + 4 + mailIdBytes.length + 1 + 1);
59
- let offset = 0;
60
- data.writeUInt8(InstructionType.SendPrepared, offset);
61
- offset += 1;
62
- to.toBuffer().copy(data, offset);
63
- offset += 32;
64
- data.writeUInt32LE(mailIdBytes.length, offset);
65
- offset += 4;
66
- mailIdBytes.copy(data, offset);
67
- offset += mailIdBytes.length;
68
- data.writeUInt8(revenueShareToReceiver ? 1 : 0, offset);
69
- offset += 1;
70
- data.writeUInt8(resolveSenderToName ? 1 : 0, offset);
71
- return data;
72
- }
73
- function encodeSendThroughWebhook(to, subject, body, webhookId, revenueShareToReceiver) {
74
- const subjectBytes = Buffer.from(subject, 'utf8');
75
- const bodyBytes = Buffer.from(body, 'utf8');
76
- const webhookIdBytes = Buffer.from(webhookId, 'utf8');
77
- const data = Buffer.alloc(1 + 32 + 4 + subjectBytes.length + 4 + bodyBytes.length + 4 + webhookIdBytes.length + 1);
78
- let offset = 0;
79
- data.writeUInt8(InstructionType.SendThroughWebhook, offset);
80
- offset += 1;
81
- to.toBuffer().copy(data, offset);
82
- offset += 32;
83
- data.writeUInt32LE(subjectBytes.length, offset);
84
- offset += 4;
85
- subjectBytes.copy(data, offset);
86
- offset += subjectBytes.length;
87
- data.writeUInt32LE(bodyBytes.length, offset);
88
- offset += 4;
89
- bodyBytes.copy(data, offset);
90
- offset += bodyBytes.length;
91
- data.writeUInt32LE(webhookIdBytes.length, offset);
92
- offset += 4;
93
- webhookIdBytes.copy(data, offset);
94
- offset += webhookIdBytes.length;
95
- data.writeUInt8(revenueShareToReceiver ? 1 : 0, offset);
96
- return data;
97
- }
98
- function encodeSendToEmail(emailHash, subject, body, payer, revenueShareToReceiver) {
99
- const emailHashBytes = Buffer.from(emailHash, 'utf8');
100
- const subjectBytes = Buffer.from(subject, 'utf8');
101
- const bodyBytes = Buffer.from(body, 'utf8');
102
- const data = Buffer.alloc(1 + 4 + emailHashBytes.length + 4 + subjectBytes.length + 4 + bodyBytes.length + 32 + 1);
103
- let offset = 0;
104
- data.writeUInt8(InstructionType.SendToEmail, offset);
105
- offset += 1;
106
- data.writeUInt32LE(emailHashBytes.length, offset);
107
- offset += 4;
108
- emailHashBytes.copy(data, offset);
109
- offset += emailHashBytes.length;
110
- data.writeUInt32LE(subjectBytes.length, offset);
111
- offset += 4;
112
- subjectBytes.copy(data, offset);
113
- offset += subjectBytes.length;
114
- data.writeUInt32LE(bodyBytes.length, offset);
115
- offset += 4;
116
- bodyBytes.copy(data, offset);
117
- offset += bodyBytes.length;
118
- payer.toBuffer().copy(data, offset);
119
- offset += 32;
120
- data.writeUInt8(revenueShareToReceiver ? 1 : 0, offset);
121
- return data;
122
- }
123
- function encodeSendPreparedToEmail(emailHash, mailId, payer, revenueShareToReceiver) {
124
- const emailHashBytes = Buffer.from(emailHash, 'utf8');
125
- const mailIdBytes = Buffer.from(mailId, 'utf8');
126
- const data = Buffer.alloc(1 + 4 + emailHashBytes.length + 4 + mailIdBytes.length + 32 + 1);
127
- let offset = 0;
128
- data.writeUInt8(InstructionType.SendPreparedToEmail, offset);
129
- offset += 1;
130
- data.writeUInt32LE(emailHashBytes.length, offset);
131
- offset += 4;
132
- emailHashBytes.copy(data, offset);
133
- offset += emailHashBytes.length;
134
- data.writeUInt32LE(mailIdBytes.length, offset);
135
- offset += 4;
136
- mailIdBytes.copy(data, offset);
137
- offset += mailIdBytes.length;
138
- payer.toBuffer().copy(data, offset);
139
- offset += 32;
140
- data.writeUInt8(revenueShareToReceiver ? 1 : 0, offset);
141
- return data;
142
- }
143
- function encodeSetFees(sendFee, delegationFee) {
144
- const data = Buffer.alloc(1 + 8 + 8);
145
- data.writeUInt8(InstructionType.SetFees, 0);
146
- data.writeBigUInt64LE(sendFee, 1);
147
- data.writeBigUInt64LE(delegationFee, 9);
148
- return data;
149
- }
150
- function encodeDelegateTo(delegate) {
151
- const data = Buffer.alloc(1 + 1 + (delegate ? 32 : 0));
152
- data.writeUInt8(InstructionType.DelegateTo, 0);
153
- data.writeUInt8(delegate ? 1 : 0, 1);
154
- if (delegate) {
155
- delegate.toBuffer().copy(data, 2);
156
- }
157
- return data;
158
- }
159
- function encodeRejectDelegation(delegatingAddress) {
160
- const data = Buffer.alloc(1 + 32);
161
- data.writeUInt8(InstructionType.RejectDelegation, 0);
162
- delegatingAddress.toBuffer().copy(data, 1);
163
- return data;
164
- }
165
- function encodeSetCustomFeePercentage(account, percentage) {
166
- if (percentage < 0 || percentage > 100) {
167
- throw new Error('Percentage must be between 0 and 100');
168
- }
169
- const data = Buffer.alloc(1 + 32 + 1);
170
- data.writeUInt8(InstructionType.SetCustomFeePercentage, 0);
171
- account.toBuffer().copy(data, 1);
172
- data.writeUInt8(percentage, 33);
173
- return data;
174
- }
175
- function encodeClearCustomFeePercentage(account) {
176
- const data = Buffer.alloc(1 + 32);
177
- data.writeUInt8(InstructionType.ClearCustomFeePercentage, 0);
178
- account.toBuffer().copy(data, 1);
179
- return data;
180
- }
181
- function encodeClaimExpiredShares(recipient) {
182
- const data = Buffer.alloc(1 + 32);
183
- data.writeUInt8(InstructionType.ClaimExpiredShares, 0);
184
- recipient.toBuffer().copy(data, 1);
185
- return data;
186
- }
187
- function encodeDistributeClaimableFunds(recipients) {
188
- const recipientCount = recipients.length;
189
- const data = Buffer.alloc(1 + 4 + recipientCount * 32);
190
- let offset = 0;
191
- data.writeUInt8(InstructionType.DistributeClaimableFunds, offset);
192
- offset += 1;
193
- data.writeUInt32LE(recipientCount, offset);
194
- offset += 4;
195
- for (const recipient of recipients) {
196
- recipient.toBuffer().copy(data, offset);
197
- offset += 32;
198
- }
199
- return data;
200
- }
201
- /**
202
- * Stateless Solana Mailer client.
203
- * All methods take wallet and chainInfo as parameters.
204
- * No state is stored in the instance.
205
- */
206
- export class SolanaMailerClient {
207
- constructor() {
208
- this.defaultComputeUnitMultiplier = 1.2; // 20% buffer by default
209
- // Default compute unit limits for common operations
210
- this.defaultComputeUnits = {
211
- send: 200000,
212
- sendPrepared: 150000,
213
- sendToEmail: 250000,
214
- claimRevenue: 100000,
215
- claimOwnerShare: 100000,
216
- delegateTo: 80000,
217
- setFees: 60000,
218
- pause: 50000,
219
- unpause: 50000,
220
- initialize: 100000,
221
- distributeClaimableFunds: 150000,
222
- };
223
- // Priority fee recommendations based on network congestion
224
- this.priorityFeeRecommendations = {
225
- low: 1000, // 1,000 microLamports - for low priority transactions
226
- normal: 10000, // 10,000 microLamports - for normal priority
227
- high: 50000, // 50,000 microLamports - for high priority
228
- urgent: 100000, // 100,000 microLamports - for urgent transactions
229
- };
230
- }
231
- /**
232
- * Create or get connection from wallet/chainInfo
233
- */
234
- async getOrCreateConnection(chainInfo, connection) {
235
- if (connection) {
236
- return connection;
237
- }
238
- // Build RPC URL from ChainInfo
239
- let rpcUrl;
240
- if (chainInfo.alchemyNetwork) {
241
- rpcUrl = `https://${chainInfo.alchemyNetwork}.g.alchemy.com/v2/demo`;
242
- }
243
- else if (chainInfo.ankrNetwork) {
244
- rpcUrl = `https://rpc.ankr.com/${chainInfo.ankrNetwork}`;
245
- }
246
- else {
247
- // Default Solana endpoints
248
- rpcUrl = chainInfo.isDev
249
- ? 'https://api.devnet.solana.com'
250
- : 'https://api.mainnet-beta.solana.com';
251
- }
252
- return new Connection(rpcUrl, 'confirmed');
253
- }
254
- /**
255
- * Get program and state PDAs from chainInfo
256
- */
257
- getProgramAddresses(chainInfo) {
258
- if (!chainInfo.mailerAddress) {
259
- throw new Error(`No mailer program deployed on ${chainInfo.name}`);
260
- }
261
- const programId = new PublicKey(chainInfo.mailerAddress);
262
- const [mailerPda, bump] = PublicKey.findProgramAddressSync([Buffer.from('mailer')], programId);
263
- return {
264
- programId,
265
- mailerStatePda: mailerPda,
266
- mailerBump: bump,
267
- };
268
- }
269
- /**
270
- * Optimize compute units for a transaction
271
- */
272
- async optimizeComputeUnits(transaction, wallet, connection, options, defaultComputeUnits) {
273
- // Skip if explicitly disabled
274
- if (options?.skipComputeUnits) {
275
- return { transaction };
276
- }
277
- let simulatedUnits;
278
- let computeUnitLimit = options?.computeUnitLimit;
279
- // Auto-optimize by simulating transaction
280
- if (options?.autoOptimize && !computeUnitLimit) {
281
- let retryCount = 0;
282
- const maxRetries = 2;
283
- while (retryCount <= maxRetries) {
284
- try {
285
- // Set a high limit for simulation
286
- const simTransaction = new Transaction().add(...transaction.instructions);
287
- simTransaction.add(ComputeBudgetProgram.setComputeUnitLimit({
288
- units: 1400000, // Max for simulation
289
- }));
290
- simTransaction.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
291
- simTransaction.feePayer = wallet.publicKey;
292
- const simulation = await connection.simulateTransaction(simTransaction);
293
- if (simulation.value.err === null && simulation.value.unitsConsumed) {
294
- simulatedUnits = simulation.value.unitsConsumed;
295
- const multiplier = options.computeUnitMultiplier ?? this.defaultComputeUnitMultiplier;
296
- computeUnitLimit = Math.min(Math.ceil(simulatedUnits * multiplier), 1400000);
297
- break; // Success
298
- }
299
- else if (simulation.value.err) {
300
- throw new Error(`Simulation failed: ${JSON.stringify(simulation.value.err)}`);
301
- }
302
- }
303
- catch (error) {
304
- retryCount++;
305
- if (retryCount > maxRetries) {
306
- console.warn(`Failed to auto-optimize compute units after ${maxRetries} retries:`, error);
307
- // Use default if provided
308
- if (defaultComputeUnits) {
309
- computeUnitLimit = defaultComputeUnits;
310
- }
311
- }
312
- else {
313
- // Wait before retry
314
- await new Promise(resolve => setTimeout(resolve, 1000 * retryCount));
315
- }
316
- }
317
- }
318
- }
319
- // Use default compute units if no limit is set yet
320
- if (!computeUnitLimit && defaultComputeUnits) {
321
- computeUnitLimit = defaultComputeUnits;
322
- }
323
- // Apply compute budget instructions
324
- const optimizedTx = new Transaction();
325
- // Add compute unit limit if specified
326
- if (computeUnitLimit) {
327
- optimizedTx.add(ComputeBudgetProgram.setComputeUnitLimit({
328
- units: computeUnitLimit,
329
- }));
330
- }
331
- // Add priority fee if specified (or use recommended normal priority)
332
- const priorityFee = options?.computeUnitPrice ??
333
- (options?.autoOptimize ? this.priorityFeeRecommendations.normal : undefined);
334
- if (priorityFee) {
335
- optimizedTx.add(ComputeBudgetProgram.setComputeUnitPrice({
336
- microLamports: priorityFee,
337
- }));
338
- }
339
- // Add original instructions
340
- optimizedTx.add(...transaction.instructions);
341
- return {
342
- transaction: optimizedTx,
343
- simulatedUnits,
344
- };
345
- }
346
- /**
347
- * Send and confirm transaction
348
- */
349
- async sendTransaction(transaction, wallet, connection, options, computeOptions, defaultComputeUnits) {
350
- // Optimize compute units
351
- const { transaction: optimizedTx, simulatedUnits } = await this.optimizeComputeUnits(transaction, wallet, connection, computeOptions, defaultComputeUnits);
352
- // Get latest blockhash
353
- const { blockhash } = await connection.getLatestBlockhash();
354
- optimizedTx.recentBlockhash = blockhash;
355
- optimizedTx.feePayer = wallet.publicKey;
356
- // Sign transaction
357
- const signed = await wallet.signTransaction(optimizedTx);
358
- // Send and confirm
359
- const signature = await connection.sendRawTransaction(signed.serialize(), {
360
- skipPreflight: options?.skipPreflight ?? false,
361
- preflightCommitment: options?.preflightCommitment ?? 'confirmed',
362
- });
363
- await connection.confirmTransaction(signature, options?.commitment ?? 'confirmed');
364
- return {
365
- signature,
366
- transactionHash: signature,
367
- simulatedUnits,
368
- computeUnitLimit: computeOptions?.computeUnitLimit,
369
- computeUnitPrice: computeOptions?.computeUnitPrice,
370
- };
371
- }
372
- /**
373
- * Initialize the mailer program (owner only)
374
- */
375
- async initialize(connectedWallet, chainInfo, computeOptions) {
376
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
377
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
378
- if (!chainInfo.usdcAddress) {
379
- throw new Error(`No USDC mint configured for ${chainInfo.name}`);
380
- }
381
- const usdcMint = new PublicKey(chainInfo.usdcAddress);
382
- const instruction = new TransactionInstruction({
383
- programId,
384
- keys: [
385
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
386
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
387
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
388
- ],
389
- data: encodeInitialize(usdcMint),
390
- });
391
- const transaction = new Transaction().add(instruction);
392
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
393
- }
394
- /**
395
- * Send a message with optional revenue sharing
396
- */
397
- async send(connectedWallet, chainInfo, to, subject, body, revenueShareToReceiver, computeOptions) {
398
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
399
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
400
- if (!chainInfo.usdcAddress) {
401
- throw new Error(`No USDC mint configured for ${chainInfo.name}`);
402
- }
403
- const usdcMint = new PublicKey(chainInfo.usdcAddress);
404
- const toPubkey = typeof to === 'string' ? new PublicKey(to) : to;
405
- // Get token accounts
406
- const senderTokenAccount = getAssociatedTokenAddressSync(usdcMint, connectedWallet.wallet.publicKey, false, TOKEN_PROGRAM_ID);
407
- const mailerTokenAccount = getAssociatedTokenAddressSync(usdcMint, mailerStatePda, true, TOKEN_PROGRAM_ID);
408
- const [recipientInfo] = PublicKey.findProgramAddressSync([Buffer.from('recipient_info'), toPubkey.toBuffer()], programId);
409
- const keys = [
410
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
411
- { pubkey: toPubkey, isSigner: false, isWritable: false },
412
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
413
- { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
414
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
415
- { pubkey: recipientInfo, isSigner: false, isWritable: true },
416
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
417
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
418
- ];
419
- const instruction = new TransactionInstruction({
420
- programId,
421
- keys,
422
- data: encodeSend(toPubkey, subject, body, revenueShareToReceiver),
423
- });
424
- const transaction = new Transaction().add(instruction);
425
- // Check if mailer token account exists, create if not
426
- const accountInfo = await connection.getAccountInfo(mailerTokenAccount);
427
- if (!accountInfo) {
428
- transaction.add(createAssociatedTokenAccountInstruction(connectedWallet.wallet.publicKey, mailerTokenAccount, mailerStatePda, usdcMint));
429
- }
430
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
431
- }
432
- /**
433
- * Send a prepared message
434
- */
435
- async sendPrepared(connectedWallet, chainInfo, to, mailId, revenueShareToReceiver, computeOptions) {
436
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
437
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
438
- if (!chainInfo.usdcAddress) {
439
- throw new Error(`No USDC mint configured for ${chainInfo.name}`);
440
- }
441
- const usdcMint = new PublicKey(chainInfo.usdcAddress);
442
- const toPubkey = typeof to === 'string' ? new PublicKey(to) : to;
443
- const senderTokenAccount = getAssociatedTokenAddressSync(usdcMint, connectedWallet.wallet.publicKey, false, TOKEN_PROGRAM_ID);
444
- const mailerTokenAccount = getAssociatedTokenAddressSync(usdcMint, mailerStatePda, true, TOKEN_PROGRAM_ID);
445
- const [recipientInfo] = PublicKey.findProgramAddressSync([Buffer.from('recipient_info'), toPubkey.toBuffer()], programId);
446
- const keys = [
447
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
448
- { pubkey: toPubkey, isSigner: false, isWritable: false },
449
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
450
- { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
451
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
452
- { pubkey: recipientInfo, isSigner: false, isWritable: true },
453
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
454
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
455
- ];
456
- const instruction = new TransactionInstruction({
457
- programId,
458
- keys,
459
- data: encodeSendPrepared(toPubkey, mailId, revenueShareToReceiver),
460
- });
461
- const transaction = new Transaction().add(instruction);
462
- // Check if mailer token account exists, create if not
463
- const accountInfo = await connection.getAccountInfo(mailerTokenAccount);
464
- if (!accountInfo) {
465
- transaction.add(createAssociatedTokenAccountInstruction(connectedWallet.wallet.publicKey, mailerTokenAccount, mailerStatePda, usdcMint));
466
- }
467
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
468
- }
469
- /**
470
- * Send through webhook
471
- */
472
- async sendThroughWebhook(connectedWallet, chainInfo, to, subject, body, webhookId, revenueShareToReceiver, computeOptions) {
473
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
474
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
475
- if (!chainInfo.usdcAddress) {
476
- throw new Error(`No USDC mint configured for ${chainInfo.name}`);
477
- }
478
- const usdcMint = new PublicKey(chainInfo.usdcAddress);
479
- const toPubkey = typeof to === 'string' ? new PublicKey(to) : to;
480
- const senderTokenAccount = getAssociatedTokenAddressSync(usdcMint, connectedWallet.wallet.publicKey, false, TOKEN_PROGRAM_ID);
481
- const mailerTokenAccount = getAssociatedTokenAddressSync(usdcMint, mailerStatePda, true, TOKEN_PROGRAM_ID);
482
- const [recipientInfo] = PublicKey.findProgramAddressSync([Buffer.from('recipient_info'), toPubkey.toBuffer()], programId);
483
- const keys = [
484
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
485
- { pubkey: toPubkey, isSigner: false, isWritable: false },
486
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
487
- { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
488
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
489
- { pubkey: recipientInfo, isSigner: false, isWritable: true },
490
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
491
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
492
- ];
493
- const instruction = new TransactionInstruction({
494
- programId,
495
- keys,
496
- data: encodeSendThroughWebhook(toPubkey, subject, body, webhookId, revenueShareToReceiver),
497
- });
498
- const transaction = new Transaction().add(instruction);
499
- const accountInfo = await connection.getAccountInfo(mailerTokenAccount);
500
- if (!accountInfo) {
501
- transaction.add(createAssociatedTokenAccountInstruction(connectedWallet.wallet.publicKey, mailerTokenAccount, mailerStatePda, usdcMint));
502
- }
503
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
504
- }
505
- /**
506
- * Send to email address
507
- */
508
- async sendToEmail(emailHash, subject, body, payer, revenueShareToReceiver, connectedWallet, chainInfo, computeOptions) {
509
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
510
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
511
- if (!chainInfo.usdcAddress) {
512
- throw new Error(`No USDC mint configured for ${chainInfo.name}`);
513
- }
514
- const usdcMint = new PublicKey(chainInfo.usdcAddress);
515
- const payerPubkey = typeof payer === 'string' ? new PublicKey(payer) : payer;
516
- const senderTokenAccount = getAssociatedTokenAddressSync(usdcMint, connectedWallet.wallet.publicKey, false, TOKEN_PROGRAM_ID);
517
- const mailerTokenAccount = getAssociatedTokenAddressSync(usdcMint, mailerStatePda, true, TOKEN_PROGRAM_ID);
518
- const keys = [
519
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
520
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
521
- { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
522
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
523
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
524
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
525
- ];
526
- const instruction = new TransactionInstruction({
527
- programId,
528
- keys,
529
- data: encodeSendToEmail(emailHash, subject, body, payerPubkey, revenueShareToReceiver),
530
- });
531
- const transaction = new Transaction().add(instruction);
532
- const accountInfo = await connection.getAccountInfo(mailerTokenAccount);
533
- if (!accountInfo) {
534
- transaction.add(createAssociatedTokenAccountInstruction(connectedWallet.wallet.publicKey, mailerTokenAccount, mailerStatePda, usdcMint));
535
- }
536
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
537
- }
538
- /**
539
- * Send prepared to email address
540
- */
541
- async sendPreparedToEmail(emailHash, mailId, payer, revenueShareToReceiver, connectedWallet, chainInfo, computeOptions) {
542
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
543
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
544
- if (!chainInfo.usdcAddress) {
545
- throw new Error(`No USDC mint configured for ${chainInfo.name}`);
546
- }
547
- const usdcMint = new PublicKey(chainInfo.usdcAddress);
548
- const payerPubkey = typeof payer === 'string' ? new PublicKey(payer) : payer;
549
- const senderTokenAccount = getAssociatedTokenAddressSync(usdcMint, connectedWallet.wallet.publicKey, false, TOKEN_PROGRAM_ID);
550
- const mailerTokenAccount = getAssociatedTokenAddressSync(usdcMint, mailerStatePda, true, TOKEN_PROGRAM_ID);
551
- const keys = [
552
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
553
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
554
- { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
555
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
556
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
557
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
558
- ];
559
- const instruction = new TransactionInstruction({
560
- programId,
561
- keys,
562
- data: encodeSendPreparedToEmail(emailHash, mailId, payerPubkey, revenueShareToReceiver),
563
- });
564
- const transaction = new Transaction().add(instruction);
565
- const accountInfo = await connection.getAccountInfo(mailerTokenAccount);
566
- if (!accountInfo) {
567
- transaction.add(createAssociatedTokenAccountInstruction(connectedWallet.wallet.publicKey, mailerTokenAccount, mailerStatePda, usdcMint));
568
- }
569
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
570
- }
571
- /**
572
- * Claim recipient share
573
- */
574
- async claimRecipientShare(connectedWallet, chainInfo, computeOptions) {
575
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
576
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
577
- if (!chainInfo.usdcAddress) {
578
- throw new Error(`No USDC mint configured for ${chainInfo.name}`);
579
- }
580
- const usdcMint = new PublicKey(chainInfo.usdcAddress);
581
- const recipientTokenAccount = getAssociatedTokenAddressSync(usdcMint, connectedWallet.wallet.publicKey, false, TOKEN_PROGRAM_ID);
582
- const mailerTokenAccount = getAssociatedTokenAddressSync(usdcMint, mailerStatePda, true, TOKEN_PROGRAM_ID);
583
- const [recipientInfo] = PublicKey.findProgramAddressSync([Buffer.from('recipient_info'), connectedWallet.wallet.publicKey.toBuffer()], programId);
584
- const keys = [
585
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
586
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
587
- { pubkey: recipientTokenAccount, isSigner: false, isWritable: true },
588
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
589
- { pubkey: recipientInfo, isSigner: false, isWritable: true },
590
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
591
- ];
592
- const instruction = new TransactionInstruction({
593
- programId,
594
- keys,
595
- data: Buffer.from([InstructionType.ClaimRecipientShare]),
596
- });
597
- const transaction = new Transaction().add(instruction);
598
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
599
- }
600
- /**
601
- * Claim owner share (owner only)
602
- */
603
- async claimOwnerShare(connectedWallet, chainInfo, computeOptions) {
604
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
605
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
606
- if (!chainInfo.usdcAddress) {
607
- throw new Error(`No USDC mint configured for ${chainInfo.name}`);
608
- }
609
- const usdcMint = new PublicKey(chainInfo.usdcAddress);
610
- const ownerTokenAccount = getAssociatedTokenAddressSync(usdcMint, connectedWallet.wallet.publicKey, false, TOKEN_PROGRAM_ID);
611
- const mailerTokenAccount = getAssociatedTokenAddressSync(usdcMint, mailerStatePda, true, TOKEN_PROGRAM_ID);
612
- const keys = [
613
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
614
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
615
- { pubkey: ownerTokenAccount, isSigner: false, isWritable: true },
616
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
617
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
618
- ];
619
- const instruction = new TransactionInstruction({
620
- programId,
621
- keys,
622
- data: Buffer.from([InstructionType.ClaimOwnerShare]),
623
- });
624
- const transaction = new Transaction().add(instruction);
625
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
626
- }
627
- /**
628
- * Claim expired shares (owner only)
629
- */
630
- async claimExpiredShares(connectedWallet, chainInfo, recipient, computeOptions) {
631
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
632
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
633
- const recipientPubkey = typeof recipient === 'string' ? new PublicKey(recipient) : recipient;
634
- const [recipientInfo] = PublicKey.findProgramAddressSync([Buffer.from('recipient_info'), recipientPubkey.toBuffer()], programId);
635
- const keys = [
636
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
637
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
638
- { pubkey: recipientInfo, isSigner: false, isWritable: true },
639
- ];
640
- const instruction = new TransactionInstruction({
641
- programId,
642
- keys,
643
- data: encodeClaimExpiredShares(recipientPubkey),
644
- });
645
- const transaction = new Transaction().add(instruction);
646
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
647
- }
648
- /**
649
- * Delegate to another address
650
- */
651
- async delegateTo(connectedWallet, chainInfo, delegate, computeOptions) {
652
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
653
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
654
- if (!chainInfo.usdcAddress) {
655
- throw new Error(`No USDC mint configured for ${chainInfo.name}`);
656
- }
657
- const usdcMint = new PublicKey(chainInfo.usdcAddress);
658
- const delegatePubkey = delegate
659
- ? (typeof delegate === 'string' ? new PublicKey(delegate) : delegate)
660
- : null;
661
- const senderTokenAccount = getAssociatedTokenAddressSync(usdcMint, connectedWallet.wallet.publicKey, false, TOKEN_PROGRAM_ID);
662
- const mailerTokenAccount = getAssociatedTokenAddressSync(usdcMint, mailerStatePda, true, TOKEN_PROGRAM_ID);
663
- const [delegatorInfo] = PublicKey.findProgramAddressSync([Buffer.from('delegator_info'), connectedWallet.wallet.publicKey.toBuffer()], programId);
664
- const keys = [
665
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
666
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
667
- { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
668
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
669
- { pubkey: delegatorInfo, isSigner: false, isWritable: true },
670
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
671
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
672
- ];
673
- const instruction = new TransactionInstruction({
674
- programId,
675
- keys,
676
- data: encodeDelegateTo(delegatePubkey),
677
- });
678
- const transaction = new Transaction().add(instruction);
679
- const accountInfo = await connection.getAccountInfo(mailerTokenAccount);
680
- if (!accountInfo) {
681
- transaction.add(createAssociatedTokenAccountInstruction(connectedWallet.wallet.publicKey, mailerTokenAccount, mailerStatePda, usdcMint));
682
- }
683
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
684
- }
685
- /**
686
- * Reject delegation
687
- */
688
- async rejectDelegation(connectedWallet, chainInfo, delegatingAddress, computeOptions) {
689
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
690
- const { programId } = this.getProgramAddresses(chainInfo);
691
- const delegatorPubkey = typeof delegatingAddress === 'string' ? new PublicKey(delegatingAddress) : delegatingAddress;
692
- const [delegatorInfo] = PublicKey.findProgramAddressSync([Buffer.from('delegator_info'), delegatorPubkey.toBuffer()], programId);
693
- const keys = [
694
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
695
- { pubkey: delegatorInfo, isSigner: false, isWritable: true },
696
- ];
697
- const instruction = new TransactionInstruction({
698
- programId,
699
- keys,
700
- data: encodeRejectDelegation(delegatorPubkey),
701
- });
702
- const transaction = new Transaction().add(instruction);
703
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
704
- }
705
- /**
706
- * Set fees (owner only)
707
- */
708
- async setFees(connectedWallet, chainInfo, sendFee, delegationFee, computeOptions) {
709
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
710
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
711
- const keys = [
712
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
713
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
714
- ];
715
- const instruction = new TransactionInstruction({
716
- programId,
717
- keys,
718
- data: encodeSetFees(BigInt(sendFee), BigInt(delegationFee)),
719
- });
720
- const transaction = new Transaction().add(instruction);
721
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
722
- }
723
- /**
724
- * Set custom fee percentage
725
- */
726
- async setCustomFeePercentage(account, percentage, connectedWallet, chainInfo, computeOptions) {
727
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
728
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
729
- const accountPubkey = typeof account === 'string' ? new PublicKey(account) : account;
730
- const [customFeeInfo] = PublicKey.findProgramAddressSync([Buffer.from('custom_fee'), accountPubkey.toBuffer()], programId);
731
- const keys = [
732
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
733
- { pubkey: mailerStatePda, isSigner: false, isWritable: false },
734
- { pubkey: customFeeInfo, isSigner: false, isWritable: true },
735
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
736
- ];
737
- const instruction = new TransactionInstruction({
738
- programId,
739
- keys,
740
- data: encodeSetCustomFeePercentage(accountPubkey, percentage),
741
- });
742
- const transaction = new Transaction().add(instruction);
743
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
744
- }
745
- /**
746
- * Clear custom fee percentage
747
- */
748
- async clearCustomFeePercentage(account, connectedWallet, chainInfo, computeOptions) {
749
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
750
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
751
- const accountPubkey = typeof account === 'string' ? new PublicKey(account) : account;
752
- const [customFeeInfo] = PublicKey.findProgramAddressSync([Buffer.from('custom_fee'), accountPubkey.toBuffer()], programId);
753
- const keys = [
754
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
755
- { pubkey: mailerStatePda, isSigner: false, isWritable: false },
756
- { pubkey: customFeeInfo, isSigner: false, isWritable: true },
757
- ];
758
- const instruction = new TransactionInstruction({
759
- programId,
760
- keys,
761
- data: encodeClearCustomFeePercentage(accountPubkey),
762
- });
763
- const transaction = new Transaction().add(instruction);
764
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
765
- }
766
- /**
767
- * Pause the program (owner only)
768
- */
769
- async pause(connectedWallet, chainInfo, computeOptions) {
770
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
771
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
772
- const keys = [
773
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
774
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
775
- ];
776
- const instruction = new TransactionInstruction({
777
- programId,
778
- keys,
779
- data: Buffer.from([InstructionType.Pause]),
780
- });
781
- const transaction = new Transaction().add(instruction);
782
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
783
- }
784
- /**
785
- * Unpause the program (owner only)
786
- */
787
- async unpause(connectedWallet, chainInfo, computeOptions) {
788
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
789
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
790
- const keys = [
791
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
792
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
793
- ];
794
- const instruction = new TransactionInstruction({
795
- programId,
796
- keys,
797
- data: Buffer.from([InstructionType.Unpause]),
798
- });
799
- const transaction = new Transaction().add(instruction);
800
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
801
- }
802
- /**
803
- * Emergency unpause (owner only)
804
- */
805
- async emergencyUnpause(connectedWallet, chainInfo, computeOptions) {
806
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
807
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
808
- const keys = [
809
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
810
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
811
- ];
812
- const instruction = new TransactionInstruction({
813
- programId,
814
- keys,
815
- data: Buffer.from([InstructionType.EmergencyUnpause]),
816
- });
817
- const transaction = new Transaction().add(instruction);
818
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
819
- }
820
- /**
821
- * Distribute claimable funds when paused
822
- */
823
- async distributeClaimableFunds(connectedWallet, chainInfo, recipients, computeOptions) {
824
- const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
825
- const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
826
- if (!chainInfo.usdcAddress) {
827
- throw new Error(`No USDC mint configured for ${chainInfo.name}`);
828
- }
829
- const usdcMint = new PublicKey(chainInfo.usdcAddress);
830
- const recipientPubkeys = recipients.map(r => typeof r === 'string' ? new PublicKey(r) : r);
831
- const mailerTokenAccount = getAssociatedTokenAddressSync(usdcMint, mailerStatePda, true, TOKEN_PROGRAM_ID);
832
- // Build keys array
833
- const keys = [
834
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
835
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
836
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
837
- { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
838
- ];
839
- // Add recipient info and token accounts
840
- for (const recipient of recipientPubkeys) {
841
- const [recipientInfo] = PublicKey.findProgramAddressSync([Buffer.from('recipient_info'), recipient.toBuffer()], programId);
842
- const recipientTokenAccount = getAssociatedTokenAddressSync(usdcMint, recipient, false, TOKEN_PROGRAM_ID);
843
- keys.push({ pubkey: recipientInfo, isSigner: false, isWritable: true });
844
- keys.push({ pubkey: recipientTokenAccount, isSigner: false, isWritable: true });
845
- }
846
- const instruction = new TransactionInstruction({
847
- programId,
848
- keys,
849
- data: encodeDistributeClaimableFunds(recipientPubkeys),
850
- });
851
- const transaction = new Transaction().add(instruction);
852
- return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
853
- }
854
- // ============= Read Methods =============
855
- /**
856
- * Get fees configuration
857
- */
858
- async getFees(chainInfo, connection) {
859
- const conn = await this.getOrCreateConnection(chainInfo, connection);
860
- const { mailerStatePda } = this.getProgramAddresses(chainInfo);
861
- const accountInfo = await conn.getAccountInfo(mailerStatePda);
862
- if (!accountInfo || !accountInfo.data) {
863
- throw new Error('Mailer not initialized');
864
- }
865
- // Parse the state data
866
- const data = accountInfo.data;
867
- const sendFee = data.readBigUInt64LE(41); // After discriminator(8) + owner(32) + paused(1)
868
- const delegationFee = data.readBigUInt64LE(49);
869
- return {
870
- sendFee,
871
- delegationFee,
872
- };
873
- }
874
- /**
875
- * Get send fee only
876
- */
877
- async getSendFee(chainInfo, connection) {
878
- const fees = await this.getFees(chainInfo, connection);
879
- return fees.sendFee;
880
- }
881
- /**
882
- * Get delegation fee only
883
- */
884
- async getDelegationFee(chainInfo, connection) {
885
- const fees = await this.getFees(chainInfo, connection);
886
- return fees.delegationFee;
887
- }
888
- /**
889
- * Get recipient claimable info
890
- */
891
- async getRecipientClaimable(recipient, chainInfo, connection) {
892
- const conn = await this.getOrCreateConnection(chainInfo, connection);
893
- const { programId } = this.getProgramAddresses(chainInfo);
894
- const recipientPubkey = typeof recipient === 'string' ? new PublicKey(recipient) : recipient;
895
- const [recipientInfo] = PublicKey.findProgramAddressSync([Buffer.from('recipient_info'), recipientPubkey.toBuffer()], programId);
896
- const accountInfo = await conn.getAccountInfo(recipientInfo);
897
- if (!accountInfo || !accountInfo.data) {
898
- return null;
899
- }
900
- // Parse the recipient info data
901
- const data = accountInfo.data;
902
- const amount = data.readBigUInt64LE(8); // After discriminator
903
- const expiresAt = data.readBigInt64LE(16);
904
- // Check if expired
905
- const now = Math.floor(Date.now() / 1000);
906
- const isExpired = Number(expiresAt) > 0 && Number(expiresAt) < now;
907
- return {
908
- amount: Number(amount),
909
- timestamp: Number(expiresAt), // Using expiresAt as timestamp
910
- expiresAt: Number(expiresAt),
911
- recipient: recipient instanceof PublicKey ? recipient.toBase58() : recipient,
912
- isExpired,
913
- };
914
- }
915
- /**
916
- * Get owner claimable amount
917
- */
918
- async getOwnerClaimable(chainInfo, connection) {
919
- const conn = await this.getOrCreateConnection(chainInfo, connection);
920
- const { mailerStatePda } = this.getProgramAddresses(chainInfo);
921
- const accountInfo = await conn.getAccountInfo(mailerStatePda);
922
- if (!accountInfo || !accountInfo.data) {
923
- throw new Error('Mailer not initialized');
924
- }
925
- // Parse the state data
926
- const data = accountInfo.data;
927
- const ownerClaimable = data.readBigUInt64LE(57); // After discriminator(8) + owner(32) + paused(1) + sendFee(8) + delegationFee(8)
928
- return Number(ownerClaimable);
929
- }
930
- /**
931
- * Get delegation for an address
932
- */
933
- async getDelegation(address, chainInfo, connection) {
934
- const conn = await this.getOrCreateConnection(chainInfo, connection);
935
- const { programId } = this.getProgramAddresses(chainInfo);
936
- const addressPubkey = typeof address === 'string' ? new PublicKey(address) : address;
937
- const [delegatorInfo] = PublicKey.findProgramAddressSync([Buffer.from('delegator_info'), addressPubkey.toBuffer()], programId);
938
- const accountInfo = await conn.getAccountInfo(delegatorInfo);
939
- if (!accountInfo || !accountInfo.data) {
940
- return null;
941
- }
942
- // Parse the delegatingAddress info data
943
- const data = accountInfo.data;
944
- const hasDelegate = data.readUInt8(8) === 1; // After discriminator
945
- if (!hasDelegate) {
946
- return null;
947
- }
948
- // Read delegate pubkey
949
- const delegateBytes = data.slice(9, 41); // 32 bytes for pubkey
950
- return new PublicKey(delegateBytes);
951
- }
952
- /**
953
- * Get custom fee percentage for an account
954
- */
955
- async getCustomFeePercentage(account, chainInfo, connection) {
956
- const conn = await this.getOrCreateConnection(chainInfo, connection);
957
- const { programId } = this.getProgramAddresses(chainInfo);
958
- const accountPubkey = typeof account === 'string' ? new PublicKey(account) : account;
959
- const [customFeeInfo] = PublicKey.findProgramAddressSync([Buffer.from('custom_fee'), accountPubkey.toBuffer()], programId);
960
- const accountInfo = await conn.getAccountInfo(customFeeInfo);
961
- if (!accountInfo || !accountInfo.data) {
962
- return 100; // Default to 100% if no custom fee set
963
- }
964
- // Parse the custom fee data
965
- const data = accountInfo.data;
966
- const percentage = data.readUInt8(8); // After discriminator
967
- return percentage;
968
- }
969
- /**
970
- * Check if the program is paused
971
- */
972
- async isPaused(chainInfo, connection) {
973
- const conn = await this.getOrCreateConnection(chainInfo, connection);
974
- const { mailerStatePda } = this.getProgramAddresses(chainInfo);
975
- const accountInfo = await conn.getAccountInfo(mailerStatePda);
976
- if (!accountInfo || !accountInfo.data) {
977
- throw new Error('Mailer not initialized');
978
- }
979
- // Parse the state data
980
- const data = accountInfo.data;
981
- const paused = data.readUInt8(40); // After discriminator(8) + owner(32)
982
- return paused === 1;
983
- }
984
- /**
985
- * Get the contract owner
986
- */
987
- async getOwner(chainInfo, connection) {
988
- const conn = await this.getOrCreateConnection(chainInfo, connection);
989
- const { mailerStatePda } = this.getProgramAddresses(chainInfo);
990
- const accountInfo = await conn.getAccountInfo(mailerStatePda);
991
- if (!accountInfo || !accountInfo.data) {
992
- throw new Error('Mailer not initialized');
993
- }
994
- // Parse the state data
995
- const data = accountInfo.data;
996
- const ownerBytes = data.slice(8, 40); // After discriminator(8)
997
- return new PublicKey(ownerBytes);
998
- }
999
- }
1000
- //# sourceMappingURL=solana-mailer-client.js.map