@sudobility/contracts 1.14.1 → 1.14.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 (36) hide show
  1. package/artifacts/contracts/Mailer.sol/Mailer.d.ts +2 -2
  2. package/artifacts/contracts/Mailer.sol/Mailer.dbg.json +1 -1
  3. package/artifacts/contracts/Mailer.sol/Mailer.json +2 -2
  4. package/artifacts/contracts/MockUSDC.sol/MockUSDC.dbg.json +1 -1
  5. package/artifacts/contracts/interfaces/IERC20.sol/IERC20.dbg.json +1 -1
  6. package/dist/evm/src/evm/evm-mailer-client.d.ts +4 -0
  7. package/dist/evm/src/evm/evm-mailer-client.d.ts.map +1 -1
  8. package/dist/evm/src/evm/evm-mailer-client.js +43 -1
  9. package/dist/evm/src/evm/evm-mailer-client.js.map +1 -1
  10. package/dist/evm/typechain-types/factories/Mailer__factory.d.ts +1 -1
  11. package/dist/evm/typechain-types/factories/Mailer__factory.d.ts.map +1 -1
  12. package/dist/evm/typechain-types/factories/Mailer__factory.js +1 -1
  13. package/dist/evm/typechain-types/factories/Mailer__factory.js.map +1 -1
  14. package/dist/solana/solana/solana-mailer-client.d.ts +9 -5
  15. package/dist/solana/solana/solana-mailer-client.d.ts.map +1 -1
  16. package/dist/solana/solana/solana-mailer-client.js +183 -145
  17. package/dist/solana/solana/solana-mailer-client.js.map +1 -1
  18. package/dist/unified/src/evm/evm-mailer-client.d.ts +4 -0
  19. package/dist/unified/src/evm/evm-mailer-client.d.ts.map +1 -1
  20. package/dist/unified/src/evm/evm-mailer-client.js +43 -1
  21. package/dist/unified/src/evm/evm-mailer-client.js.map +1 -1
  22. package/dist/unified/src/solana/solana-mailer-client.d.ts +9 -5
  23. package/dist/unified/src/solana/solana-mailer-client.d.ts.map +1 -1
  24. package/dist/unified/src/solana/solana-mailer-client.js +183 -145
  25. package/dist/unified/src/solana/solana-mailer-client.js.map +1 -1
  26. package/dist/unified/src/unified/onchain-mailer-client.d.ts +8 -0
  27. package/dist/unified/src/unified/onchain-mailer-client.d.ts.map +1 -1
  28. package/dist/unified/src/unified/onchain-mailer-client.js +55 -14
  29. package/dist/unified/src/unified/onchain-mailer-client.js.map +1 -1
  30. package/dist/unified/typechain-types/factories/Mailer__factory.d.ts +1 -1
  31. package/dist/unified/typechain-types/factories/Mailer__factory.d.ts.map +1 -1
  32. package/dist/unified/typechain-types/factories/Mailer__factory.js +1 -1
  33. package/dist/unified/typechain-types/factories/Mailer__factory.js.map +1 -1
  34. package/package.json +1 -1
  35. package/programs/mailer/src/lib.rs +95 -24
  36. package/typechain-types/factories/Mailer__factory.ts +1 -1
@@ -11,22 +11,28 @@ var InstructionType;
11
11
  InstructionType[InstructionType["Initialize"] = 0] = "Initialize";
12
12
  InstructionType[InstructionType["Send"] = 1] = "Send";
13
13
  InstructionType[InstructionType["SendPrepared"] = 2] = "SendPrepared";
14
- InstructionType[InstructionType["SendThroughWebhook"] = 3] = "SendThroughWebhook";
15
- InstructionType[InstructionType["SendToEmail"] = 4] = "SendToEmail";
16
- InstructionType[InstructionType["SendPreparedToEmail"] = 5] = "SendPreparedToEmail";
14
+ InstructionType[InstructionType["SendToEmail"] = 3] = "SendToEmail";
15
+ InstructionType[InstructionType["SendPreparedToEmail"] = 4] = "SendPreparedToEmail";
16
+ InstructionType[InstructionType["SendThroughWebhook"] = 5] = "SendThroughWebhook";
17
17
  InstructionType[InstructionType["ClaimRecipientShare"] = 6] = "ClaimRecipientShare";
18
18
  InstructionType[InstructionType["ClaimOwnerShare"] = 7] = "ClaimOwnerShare";
19
- InstructionType[InstructionType["ClaimExpiredShares"] = 8] = "ClaimExpiredShares";
20
- InstructionType[InstructionType["SetFees"] = 9] = "SetFees";
21
- InstructionType[InstructionType["DelegateTo"] = 10] = "DelegateTo";
22
- InstructionType[InstructionType["RejectDelegation"] = 11] = "RejectDelegation";
19
+ InstructionType[InstructionType["SetFee"] = 8] = "SetFee";
20
+ InstructionType[InstructionType["DelegateTo"] = 9] = "DelegateTo";
21
+ InstructionType[InstructionType["RejectDelegation"] = 10] = "RejectDelegation";
22
+ InstructionType[InstructionType["SetDelegationFee"] = 11] = "SetDelegationFee";
23
23
  InstructionType[InstructionType["SetCustomFeePercentage"] = 12] = "SetCustomFeePercentage";
24
24
  InstructionType[InstructionType["ClearCustomFeePercentage"] = 13] = "ClearCustomFeePercentage";
25
25
  InstructionType[InstructionType["Pause"] = 14] = "Pause";
26
26
  InstructionType[InstructionType["Unpause"] = 15] = "Unpause";
27
- InstructionType[InstructionType["EmergencyUnpause"] = 16] = "EmergencyUnpause";
28
- InstructionType[InstructionType["DistributeClaimableFunds"] = 17] = "DistributeClaimableFunds";
27
+ InstructionType[InstructionType["DistributeClaimableFunds"] = 16] = "DistributeClaimableFunds";
28
+ InstructionType[InstructionType["ClaimExpiredShares"] = 17] = "ClaimExpiredShares";
29
+ InstructionType[InstructionType["EmergencyUnpause"] = 18] = "EmergencyUnpause";
30
+ InstructionType[InstructionType["SetFeePaused"] = 19] = "SetFeePaused";
29
31
  })(InstructionType || (InstructionType = {}));
32
+ const CLAIM_PDA_SEED = Buffer.from('claim');
33
+ const DELEGATION_PDA_SEED = Buffer.from('delegation');
34
+ const DISCOUNT_PDA_SEED = Buffer.from('discount');
35
+ const CLAIM_PERIOD_SECONDS = 60 * 24 * 60 * 60;
30
36
  // Instruction data encoding functions
31
37
  function encodeInitialize(usdcMint) {
32
38
  const data = Buffer.alloc(1 + 32);
@@ -73,43 +79,35 @@ function encodeSendPrepared(to, mailId, revenueShareToReceiver, resolveSenderToN
73
79
  data.writeUInt8(resolveSenderToName ? 1 : 0, offset);
74
80
  return data;
75
81
  }
76
- function encodeSendThroughWebhook(to, subject, body, webhookId, revenueShareToReceiver) {
77
- const subjectBytes = Buffer.from(subject, 'utf8');
78
- const bodyBytes = Buffer.from(body, 'utf8');
82
+ function encodeSendThroughWebhook(to, webhookId, revenueShareToReceiver, resolveSenderToName = false) {
79
83
  const webhookIdBytes = Buffer.from(webhookId, 'utf8');
80
- const data = Buffer.alloc(1 + 32 + 4 + subjectBytes.length + 4 + bodyBytes.length + 4 + webhookIdBytes.length + 1);
84
+ const data = Buffer.alloc(1 + 32 + 4 + webhookIdBytes.length + 1 + 1);
81
85
  let offset = 0;
82
86
  data.writeUInt8(InstructionType.SendThroughWebhook, offset);
83
87
  offset += 1;
84
88
  to.toBuffer().copy(data, offset);
85
89
  offset += 32;
86
- data.writeUInt32LE(subjectBytes.length, offset);
87
- offset += 4;
88
- subjectBytes.copy(data, offset);
89
- offset += subjectBytes.length;
90
- data.writeUInt32LE(bodyBytes.length, offset);
91
- offset += 4;
92
- bodyBytes.copy(data, offset);
93
- offset += bodyBytes.length;
94
90
  data.writeUInt32LE(webhookIdBytes.length, offset);
95
91
  offset += 4;
96
92
  webhookIdBytes.copy(data, offset);
97
93
  offset += webhookIdBytes.length;
98
94
  data.writeUInt8(revenueShareToReceiver ? 1 : 0, offset);
95
+ offset += 1;
96
+ data.writeUInt8(resolveSenderToName ? 1 : 0, offset);
99
97
  return data;
100
98
  }
101
- function encodeSendToEmail(emailHash, subject, body, payer, revenueShareToReceiver) {
102
- const emailHashBytes = Buffer.from(emailHash, 'utf8');
99
+ function encodeSendToEmail(toEmail, subject, body) {
100
+ const emailBytes = Buffer.from(toEmail, 'utf8');
103
101
  const subjectBytes = Buffer.from(subject, 'utf8');
104
102
  const bodyBytes = Buffer.from(body, 'utf8');
105
- const data = Buffer.alloc(1 + 4 + emailHashBytes.length + 4 + subjectBytes.length + 4 + bodyBytes.length + 32 + 1);
103
+ const data = Buffer.alloc(1 + 4 + emailBytes.length + 4 + subjectBytes.length + 4 + bodyBytes.length);
106
104
  let offset = 0;
107
105
  data.writeUInt8(InstructionType.SendToEmail, offset);
108
106
  offset += 1;
109
- data.writeUInt32LE(emailHashBytes.length, offset);
107
+ data.writeUInt32LE(emailBytes.length, offset);
110
108
  offset += 4;
111
- emailHashBytes.copy(data, offset);
112
- offset += emailHashBytes.length;
109
+ emailBytes.copy(data, offset);
110
+ offset += emailBytes.length;
113
111
  data.writeUInt32LE(subjectBytes.length, offset);
114
112
  offset += 4;
115
113
  subjectBytes.copy(data, offset);
@@ -118,36 +116,35 @@ function encodeSendToEmail(emailHash, subject, body, payer, revenueShareToReceiv
118
116
  offset += 4;
119
117
  bodyBytes.copy(data, offset);
120
118
  offset += bodyBytes.length;
121
- payer.toBuffer().copy(data, offset);
122
- offset += 32;
123
- data.writeUInt8(revenueShareToReceiver ? 1 : 0, offset);
124
119
  return data;
125
120
  }
126
- function encodeSendPreparedToEmail(emailHash, mailId, payer, revenueShareToReceiver) {
127
- const emailHashBytes = Buffer.from(emailHash, 'utf8');
121
+ function encodeSendPreparedToEmail(toEmail, mailId) {
122
+ const emailBytes = Buffer.from(toEmail, 'utf8');
128
123
  const mailIdBytes = Buffer.from(mailId, 'utf8');
129
- const data = Buffer.alloc(1 + 4 + emailHashBytes.length + 4 + mailIdBytes.length + 32 + 1);
124
+ const data = Buffer.alloc(1 + 4 + emailBytes.length + 4 + mailIdBytes.length);
130
125
  let offset = 0;
131
126
  data.writeUInt8(InstructionType.SendPreparedToEmail, offset);
132
127
  offset += 1;
133
- data.writeUInt32LE(emailHashBytes.length, offset);
128
+ data.writeUInt32LE(emailBytes.length, offset);
134
129
  offset += 4;
135
- emailHashBytes.copy(data, offset);
136
- offset += emailHashBytes.length;
130
+ emailBytes.copy(data, offset);
131
+ offset += emailBytes.length;
137
132
  data.writeUInt32LE(mailIdBytes.length, offset);
138
133
  offset += 4;
139
134
  mailIdBytes.copy(data, offset);
140
135
  offset += mailIdBytes.length;
141
- payer.toBuffer().copy(data, offset);
142
- offset += 32;
143
- data.writeUInt8(revenueShareToReceiver ? 1 : 0, offset);
144
136
  return data;
145
137
  }
146
- function encodeSetFees(sendFee, delegationFee) {
147
- const data = Buffer.alloc(1 + 8 + 8);
148
- data.writeUInt8(InstructionType.SetFees, 0);
138
+ function encodeSetFee(sendFee) {
139
+ const data = Buffer.alloc(1 + 8);
140
+ data.writeUInt8(InstructionType.SetFee, 0);
149
141
  data.writeBigUInt64LE(sendFee, 1);
150
- data.writeBigUInt64LE(delegationFee, 9);
142
+ return data;
143
+ }
144
+ function encodeSetDelegationFee(delegationFee) {
145
+ const data = Buffer.alloc(1 + 8);
146
+ data.writeUInt8(InstructionType.SetDelegationFee, 0);
147
+ data.writeBigUInt64LE(delegationFee, 1);
151
148
  return data;
152
149
  }
153
150
  function encodeDelegateTo(delegate) {
@@ -159,10 +156,9 @@ function encodeDelegateTo(delegate) {
159
156
  }
160
157
  return data;
161
158
  }
162
- function encodeRejectDelegation(delegatingAddress) {
163
- const data = Buffer.alloc(1 + 32);
159
+ function encodeRejectDelegation() {
160
+ const data = Buffer.alloc(1);
164
161
  data.writeUInt8(InstructionType.RejectDelegation, 0);
165
- delegatingAddress.toBuffer().copy(data, 1);
166
162
  return data;
167
163
  }
168
164
  function encodeSetCustomFeePercentage(account, percentage) {
@@ -187,18 +183,16 @@ function encodeClaimExpiredShares(recipient) {
187
183
  recipient.toBuffer().copy(data, 1);
188
184
  return data;
189
185
  }
190
- function encodeDistributeClaimableFunds(recipients) {
191
- const recipientCount = recipients.length;
192
- const data = Buffer.alloc(1 + 4 + recipientCount * 32);
193
- let offset = 0;
194
- data.writeUInt8(InstructionType.DistributeClaimableFunds, offset);
195
- offset += 1;
196
- data.writeUInt32LE(recipientCount, offset);
197
- offset += 4;
198
- for (const recipient of recipients) {
199
- recipient.toBuffer().copy(data, offset);
200
- offset += 32;
201
- }
186
+ function encodeDistributeClaimableFunds(recipient) {
187
+ const data = Buffer.alloc(1 + 32);
188
+ data.writeUInt8(InstructionType.DistributeClaimableFunds, 0);
189
+ recipient.toBuffer().copy(data, 1);
190
+ return data;
191
+ }
192
+ function encodeSetFeePaused(feePaused) {
193
+ const data = Buffer.alloc(1 + 1);
194
+ data.writeUInt8(InstructionType.SetFeePaused, 0);
195
+ data.writeUInt8(feePaused ? 1 : 0, 1);
202
196
  return data;
203
197
  }
204
198
  /**
@@ -397,7 +391,7 @@ class SolanaMailerClient {
397
391
  /**
398
392
  * Send a message with optional revenue sharing
399
393
  */
400
- async send(connectedWallet, chainInfo, to, subject, body, revenueShareToReceiver, computeOptions) {
394
+ async send(connectedWallet, chainInfo, to, subject, body, revenueShareToReceiver, resolveSenderToName = false, computeOptions) {
401
395
  const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
402
396
  const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
403
397
  if (!chainInfo.usdcAddress) {
@@ -405,24 +399,22 @@ class SolanaMailerClient {
405
399
  }
406
400
  const usdcMint = new web3_js_1.PublicKey(chainInfo.usdcAddress);
407
401
  const toPubkey = typeof to === 'string' ? new web3_js_1.PublicKey(to) : to;
408
- // Get token accounts
409
402
  const senderTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, connectedWallet.wallet.publicKey, false, spl_token_1.TOKEN_PROGRAM_ID);
410
403
  const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, mailerStatePda, true, spl_token_1.TOKEN_PROGRAM_ID);
411
- const [recipientInfo] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('recipient_info'), toPubkey.toBuffer()], programId);
404
+ const [recipientClaimPda] = web3_js_1.PublicKey.findProgramAddressSync([CLAIM_PDA_SEED, toPubkey.toBuffer()], programId);
412
405
  const keys = [
413
406
  { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
414
- { pubkey: toPubkey, isSigner: false, isWritable: false },
407
+ { pubkey: recipientClaimPda, isSigner: false, isWritable: true },
415
408
  { pubkey: mailerStatePda, isSigner: false, isWritable: true },
416
409
  { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
417
410
  { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
418
- { pubkey: recipientInfo, isSigner: false, isWritable: true },
419
411
  { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
420
412
  { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
421
413
  ];
422
414
  const instruction = new web3_js_1.TransactionInstruction({
423
415
  programId,
424
416
  keys,
425
- data: encodeSend(toPubkey, subject, body, revenueShareToReceiver),
417
+ data: encodeSend(toPubkey, subject, body, revenueShareToReceiver, resolveSenderToName),
426
418
  });
427
419
  const transaction = new web3_js_1.Transaction().add(instruction);
428
420
  // Check if mailer token account exists, create if not
@@ -435,7 +427,7 @@ class SolanaMailerClient {
435
427
  /**
436
428
  * Send a prepared message
437
429
  */
438
- async sendPrepared(connectedWallet, chainInfo, to, mailId, revenueShareToReceiver, computeOptions) {
430
+ async sendPrepared(connectedWallet, chainInfo, to, mailId, revenueShareToReceiver, resolveSenderToName = false, computeOptions) {
439
431
  const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
440
432
  const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
441
433
  if (!chainInfo.usdcAddress) {
@@ -445,21 +437,20 @@ class SolanaMailerClient {
445
437
  const toPubkey = typeof to === 'string' ? new web3_js_1.PublicKey(to) : to;
446
438
  const senderTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, connectedWallet.wallet.publicKey, false, spl_token_1.TOKEN_PROGRAM_ID);
447
439
  const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, mailerStatePda, true, spl_token_1.TOKEN_PROGRAM_ID);
448
- const [recipientInfo] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('recipient_info'), toPubkey.toBuffer()], programId);
440
+ const [recipientClaimPda] = web3_js_1.PublicKey.findProgramAddressSync([CLAIM_PDA_SEED, toPubkey.toBuffer()], programId);
449
441
  const keys = [
450
442
  { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
451
- { pubkey: toPubkey, isSigner: false, isWritable: false },
443
+ { pubkey: recipientClaimPda, isSigner: false, isWritable: true },
452
444
  { pubkey: mailerStatePda, isSigner: false, isWritable: true },
453
445
  { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
454
446
  { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
455
- { pubkey: recipientInfo, isSigner: false, isWritable: true },
456
447
  { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
457
448
  { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
458
449
  ];
459
450
  const instruction = new web3_js_1.TransactionInstruction({
460
451
  programId,
461
452
  keys,
462
- data: encodeSendPrepared(toPubkey, mailId, revenueShareToReceiver),
453
+ data: encodeSendPrepared(toPubkey, mailId, revenueShareToReceiver, resolveSenderToName),
463
454
  });
464
455
  const transaction = new web3_js_1.Transaction().add(instruction);
465
456
  // Check if mailer token account exists, create if not
@@ -472,7 +463,7 @@ class SolanaMailerClient {
472
463
  /**
473
464
  * Send through webhook
474
465
  */
475
- async sendThroughWebhook(connectedWallet, chainInfo, to, subject, body, webhookId, revenueShareToReceiver, computeOptions) {
466
+ async sendThroughWebhook(connectedWallet, chainInfo, to, webhookId, revenueShareToReceiver, resolveSenderToName = false, computeOptions) {
476
467
  const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
477
468
  const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
478
469
  if (!chainInfo.usdcAddress) {
@@ -482,21 +473,20 @@ class SolanaMailerClient {
482
473
  const toPubkey = typeof to === 'string' ? new web3_js_1.PublicKey(to) : to;
483
474
  const senderTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, connectedWallet.wallet.publicKey, false, spl_token_1.TOKEN_PROGRAM_ID);
484
475
  const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, mailerStatePda, true, spl_token_1.TOKEN_PROGRAM_ID);
485
- const [recipientInfo] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('recipient_info'), toPubkey.toBuffer()], programId);
476
+ const [recipientClaimPda] = web3_js_1.PublicKey.findProgramAddressSync([CLAIM_PDA_SEED, toPubkey.toBuffer()], programId);
486
477
  const keys = [
487
478
  { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
488
- { pubkey: toPubkey, isSigner: false, isWritable: false },
479
+ { pubkey: recipientClaimPda, isSigner: false, isWritable: true },
489
480
  { pubkey: mailerStatePda, isSigner: false, isWritable: true },
490
481
  { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
491
482
  { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
492
- { pubkey: recipientInfo, isSigner: false, isWritable: true },
493
483
  { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
494
484
  { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
495
485
  ];
496
486
  const instruction = new web3_js_1.TransactionInstruction({
497
487
  programId,
498
488
  keys,
499
- data: encodeSendThroughWebhook(toPubkey, subject, body, webhookId, revenueShareToReceiver),
489
+ data: encodeSendThroughWebhook(toPubkey, webhookId, revenueShareToReceiver, resolveSenderToName),
500
490
  });
501
491
  const transaction = new web3_js_1.Transaction().add(instruction);
502
492
  const accountInfo = await connection.getAccountInfo(mailerTokenAccount);
@@ -508,14 +498,13 @@ class SolanaMailerClient {
508
498
  /**
509
499
  * Send to email address
510
500
  */
511
- async sendToEmail(emailHash, subject, body, payer, revenueShareToReceiver, connectedWallet, chainInfo, computeOptions) {
501
+ async sendToEmail(emailHash, subject, body, _payer, _revenueShareToReceiver, connectedWallet, chainInfo, computeOptions) {
512
502
  const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
513
503
  const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
514
504
  if (!chainInfo.usdcAddress) {
515
505
  throw new Error(`No USDC mint configured for ${chainInfo.name}`);
516
506
  }
517
507
  const usdcMint = new web3_js_1.PublicKey(chainInfo.usdcAddress);
518
- const payerPubkey = typeof payer === 'string' ? new web3_js_1.PublicKey(payer) : payer;
519
508
  const senderTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, connectedWallet.wallet.publicKey, false, spl_token_1.TOKEN_PROGRAM_ID);
520
509
  const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, mailerStatePda, true, spl_token_1.TOKEN_PROGRAM_ID);
521
510
  const keys = [
@@ -524,12 +513,11 @@ class SolanaMailerClient {
524
513
  { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
525
514
  { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
526
515
  { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
527
- { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
528
516
  ];
529
517
  const instruction = new web3_js_1.TransactionInstruction({
530
518
  programId,
531
519
  keys,
532
- data: encodeSendToEmail(emailHash, subject, body, payerPubkey, revenueShareToReceiver),
520
+ data: encodeSendToEmail(emailHash, subject, body),
533
521
  });
534
522
  const transaction = new web3_js_1.Transaction().add(instruction);
535
523
  const accountInfo = await connection.getAccountInfo(mailerTokenAccount);
@@ -541,14 +529,13 @@ class SolanaMailerClient {
541
529
  /**
542
530
  * Send prepared to email address
543
531
  */
544
- async sendPreparedToEmail(emailHash, mailId, payer, revenueShareToReceiver, connectedWallet, chainInfo, computeOptions) {
532
+ async sendPreparedToEmail(emailHash, mailId, _payer, _revenueShareToReceiver, connectedWallet, chainInfo, computeOptions) {
545
533
  const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
546
534
  const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
547
535
  if (!chainInfo.usdcAddress) {
548
536
  throw new Error(`No USDC mint configured for ${chainInfo.name}`);
549
537
  }
550
538
  const usdcMint = new web3_js_1.PublicKey(chainInfo.usdcAddress);
551
- const payerPubkey = typeof payer === 'string' ? new web3_js_1.PublicKey(payer) : payer;
552
539
  const senderTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, connectedWallet.wallet.publicKey, false, spl_token_1.TOKEN_PROGRAM_ID);
553
540
  const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, mailerStatePda, true, spl_token_1.TOKEN_PROGRAM_ID);
554
541
  const keys = [
@@ -557,12 +544,11 @@ class SolanaMailerClient {
557
544
  { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
558
545
  { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
559
546
  { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
560
- { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
561
547
  ];
562
548
  const instruction = new web3_js_1.TransactionInstruction({
563
549
  programId,
564
550
  keys,
565
- data: encodeSendPreparedToEmail(emailHash, mailId, payerPubkey, revenueShareToReceiver),
551
+ data: encodeSendPreparedToEmail(emailHash, mailId),
566
552
  });
567
553
  const transaction = new web3_js_1.Transaction().add(instruction);
568
554
  const accountInfo = await connection.getAccountInfo(mailerTokenAccount);
@@ -583,13 +569,13 @@ class SolanaMailerClient {
583
569
  const usdcMint = new web3_js_1.PublicKey(chainInfo.usdcAddress);
584
570
  const recipientTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, connectedWallet.wallet.publicKey, false, spl_token_1.TOKEN_PROGRAM_ID);
585
571
  const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, mailerStatePda, true, spl_token_1.TOKEN_PROGRAM_ID);
586
- const [recipientInfo] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('recipient_info'), connectedWallet.wallet.publicKey.toBuffer()], programId);
572
+ const [recipientClaimPda] = web3_js_1.PublicKey.findProgramAddressSync([CLAIM_PDA_SEED, connectedWallet.wallet.publicKey.toBuffer()], programId);
587
573
  const keys = [
588
574
  { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
575
+ { pubkey: recipientClaimPda, isSigner: false, isWritable: true },
589
576
  { pubkey: mailerStatePda, isSigner: false, isWritable: true },
590
577
  { pubkey: recipientTokenAccount, isSigner: false, isWritable: true },
591
578
  { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
592
- { pubkey: recipientInfo, isSigner: false, isWritable: true },
593
579
  { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
594
580
  ];
595
581
  const instruction = new web3_js_1.TransactionInstruction({
@@ -634,11 +620,11 @@ class SolanaMailerClient {
634
620
  const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
635
621
  const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
636
622
  const recipientPubkey = typeof recipient === 'string' ? new web3_js_1.PublicKey(recipient) : recipient;
637
- const [recipientInfo] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('recipient_info'), recipientPubkey.toBuffer()], programId);
623
+ const [recipientClaimPda] = web3_js_1.PublicKey.findProgramAddressSync([CLAIM_PDA_SEED, recipientPubkey.toBuffer()], programId);
638
624
  const keys = [
639
625
  { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
640
626
  { pubkey: mailerStatePda, isSigner: false, isWritable: true },
641
- { pubkey: recipientInfo, isSigner: false, isWritable: true },
627
+ { pubkey: recipientClaimPda, isSigner: false, isWritable: true },
642
628
  ];
643
629
  const instruction = new web3_js_1.TransactionInstruction({
644
630
  programId,
@@ -663,13 +649,13 @@ class SolanaMailerClient {
663
649
  : null;
664
650
  const senderTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, connectedWallet.wallet.publicKey, false, spl_token_1.TOKEN_PROGRAM_ID);
665
651
  const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, mailerStatePda, true, spl_token_1.TOKEN_PROGRAM_ID);
666
- const [delegatorInfo] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('delegator_info'), connectedWallet.wallet.publicKey.toBuffer()], programId);
652
+ const [delegationPda] = web3_js_1.PublicKey.findProgramAddressSync([DELEGATION_PDA_SEED, connectedWallet.wallet.publicKey.toBuffer()], programId);
667
653
  const keys = [
668
654
  { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
655
+ { pubkey: delegationPda, isSigner: false, isWritable: true },
669
656
  { pubkey: mailerStatePda, isSigner: false, isWritable: true },
670
657
  { pubkey: senderTokenAccount, isSigner: false, isWritable: true },
671
658
  { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
672
- { pubkey: delegatorInfo, isSigner: false, isWritable: true },
673
659
  { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
674
660
  { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
675
661
  ];
@@ -690,17 +676,18 @@ class SolanaMailerClient {
690
676
  */
691
677
  async rejectDelegation(connectedWallet, chainInfo, delegatingAddress, computeOptions) {
692
678
  const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
693
- const { programId } = this.getProgramAddresses(chainInfo);
679
+ const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
694
680
  const delegatorPubkey = typeof delegatingAddress === 'string' ? new web3_js_1.PublicKey(delegatingAddress) : delegatingAddress;
695
- const [delegatorInfo] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('delegator_info'), delegatorPubkey.toBuffer()], programId);
681
+ const [delegationPda] = web3_js_1.PublicKey.findProgramAddressSync([DELEGATION_PDA_SEED, delegatorPubkey.toBuffer()], programId);
696
682
  const keys = [
697
683
  { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
698
- { pubkey: delegatorInfo, isSigner: false, isWritable: true },
684
+ { pubkey: delegationPda, isSigner: false, isWritable: true },
685
+ { pubkey: mailerStatePda, isSigner: false, isWritable: false },
699
686
  ];
700
687
  const instruction = new web3_js_1.TransactionInstruction({
701
688
  programId,
702
689
  keys,
703
- data: encodeRejectDelegation(delegatorPubkey),
690
+ data: encodeRejectDelegation(),
704
691
  });
705
692
  const transaction = new web3_js_1.Transaction().add(instruction);
706
693
  return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
@@ -711,16 +698,24 @@ class SolanaMailerClient {
711
698
  async setFees(connectedWallet, chainInfo, sendFee, delegationFee, computeOptions) {
712
699
  const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
713
700
  const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
714
- const keys = [
715
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
716
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
717
- ];
718
- const instruction = new web3_js_1.TransactionInstruction({
701
+ const ownerKey = connectedWallet.wallet.publicKey;
702
+ const setSendFeeIx = new web3_js_1.TransactionInstruction({
719
703
  programId,
720
- keys,
721
- data: encodeSetFees(BigInt(sendFee), BigInt(delegationFee)),
704
+ keys: [
705
+ { pubkey: ownerKey, isSigner: true, isWritable: false },
706
+ { pubkey: mailerStatePda, isSigner: false, isWritable: true },
707
+ ],
708
+ data: encodeSetFee(BigInt(sendFee)),
722
709
  });
723
- const transaction = new web3_js_1.Transaction().add(instruction);
710
+ const setDelegationFeeIx = new web3_js_1.TransactionInstruction({
711
+ programId,
712
+ keys: [
713
+ { pubkey: ownerKey, isSigner: true, isWritable: false },
714
+ { pubkey: mailerStatePda, isSigner: false, isWritable: true },
715
+ ],
716
+ data: encodeSetDelegationFee(BigInt(delegationFee)),
717
+ });
718
+ const transaction = new web3_js_1.Transaction().add(setSendFeeIx, setDelegationFeeIx);
724
719
  return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
725
720
  }
726
721
  /**
@@ -730,11 +725,14 @@ class SolanaMailerClient {
730
725
  const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
731
726
  const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
732
727
  const accountPubkey = typeof account === 'string' ? new web3_js_1.PublicKey(account) : account;
733
- const [customFeeInfo] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('custom_fee'), accountPubkey.toBuffer()], programId);
728
+ const [discountPda] = web3_js_1.PublicKey.findProgramAddressSync([DISCOUNT_PDA_SEED, accountPubkey.toBuffer()], programId);
729
+ const ownerKey = connectedWallet.wallet.publicKey;
734
730
  const keys = [
735
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
731
+ { pubkey: ownerKey, isSigner: true, isWritable: false },
736
732
  { pubkey: mailerStatePda, isSigner: false, isWritable: false },
737
- { pubkey: customFeeInfo, isSigner: false, isWritable: true },
733
+ { pubkey: discountPda, isSigner: false, isWritable: true },
734
+ { pubkey: accountPubkey, isSigner: false, isWritable: false },
735
+ { pubkey: ownerKey, isSigner: true, isWritable: true },
738
736
  { pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
739
737
  ];
740
738
  const instruction = new web3_js_1.TransactionInstruction({
@@ -752,11 +750,11 @@ class SolanaMailerClient {
752
750
  const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
753
751
  const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
754
752
  const accountPubkey = typeof account === 'string' ? new web3_js_1.PublicKey(account) : account;
755
- const [customFeeInfo] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('custom_fee'), accountPubkey.toBuffer()], programId);
753
+ const [discountPda] = web3_js_1.PublicKey.findProgramAddressSync([DISCOUNT_PDA_SEED, accountPubkey.toBuffer()], programId);
756
754
  const keys = [
757
755
  { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
758
756
  { pubkey: mailerStatePda, isSigner: false, isWritable: false },
759
- { pubkey: customFeeInfo, isSigner: false, isWritable: true },
757
+ { pubkey: discountPda, isSigner: false, isWritable: true },
760
758
  ];
761
759
  const instruction = new web3_js_1.TransactionInstruction({
762
760
  programId,
@@ -772,16 +770,33 @@ class SolanaMailerClient {
772
770
  async pause(connectedWallet, chainInfo, computeOptions) {
773
771
  const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
774
772
  const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
773
+ if (!chainInfo.usdcAddress) {
774
+ throw new Error(`No USDC mint configured for ${chainInfo.name}`);
775
+ }
776
+ const usdcMint = new web3_js_1.PublicKey(chainInfo.usdcAddress);
777
+ const ownerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, connectedWallet.wallet.publicKey, false, spl_token_1.TOKEN_PROGRAM_ID);
778
+ const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, mailerStatePda, true, spl_token_1.TOKEN_PROGRAM_ID);
779
+ const transaction = new web3_js_1.Transaction();
780
+ const mailerTokenInfo = await connection.getAccountInfo(mailerTokenAccount);
781
+ if (!mailerTokenInfo) {
782
+ transaction.add((0, spl_token_1.createAssociatedTokenAccountInstruction)(connectedWallet.wallet.publicKey, mailerTokenAccount, mailerStatePda, usdcMint));
783
+ }
784
+ const ownerTokenInfo = await connection.getAccountInfo(ownerTokenAccount);
785
+ if (!ownerTokenInfo) {
786
+ transaction.add((0, spl_token_1.createAssociatedTokenAccountInstruction)(connectedWallet.wallet.publicKey, ownerTokenAccount, connectedWallet.wallet.publicKey, usdcMint));
787
+ }
775
788
  const keys = [
776
789
  { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
777
790
  { pubkey: mailerStatePda, isSigner: false, isWritable: true },
791
+ { pubkey: ownerTokenAccount, isSigner: false, isWritable: true },
792
+ { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
793
+ { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
778
794
  ];
779
- const instruction = new web3_js_1.TransactionInstruction({
795
+ transaction.add(new web3_js_1.TransactionInstruction({
780
796
  programId,
781
797
  keys,
782
798
  data: Buffer.from([InstructionType.Pause]),
783
- });
784
- const transaction = new web3_js_1.Transaction().add(instruction);
799
+ }));
785
800
  return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
786
801
  }
787
802
  /**
@@ -820,6 +835,24 @@ class SolanaMailerClient {
820
835
  const transaction = new web3_js_1.Transaction().add(instruction);
821
836
  return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
822
837
  }
838
+ /**
839
+ * Set fee paused state (owner only)
840
+ */
841
+ async setFeePaused(feePaused, connectedWallet, chainInfo, computeOptions) {
842
+ const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
843
+ const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
844
+ const keys = [
845
+ { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
846
+ { pubkey: mailerStatePda, isSigner: false, isWritable: true },
847
+ ];
848
+ const instruction = new web3_js_1.TransactionInstruction({
849
+ programId,
850
+ keys,
851
+ data: encodeSetFeePaused(feePaused),
852
+ });
853
+ const transaction = new web3_js_1.Transaction().add(instruction);
854
+ return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
855
+ }
823
856
  /**
824
857
  * Distribute claimable funds when paused
825
858
  */
@@ -832,26 +865,31 @@ class SolanaMailerClient {
832
865
  const usdcMint = new web3_js_1.PublicKey(chainInfo.usdcAddress);
833
866
  const recipientPubkeys = recipients.map(r => typeof r === 'string' ? new web3_js_1.PublicKey(r) : r);
834
867
  const mailerTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, mailerStatePda, true, spl_token_1.TOKEN_PROGRAM_ID);
835
- // Build keys array
836
- const keys = [
837
- { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
838
- { pubkey: mailerStatePda, isSigner: false, isWritable: true },
839
- { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
840
- { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
841
- ];
842
- // Add recipient info and token accounts
868
+ const transaction = new web3_js_1.Transaction();
869
+ const mailerTokenInfo = await connection.getAccountInfo(mailerTokenAccount);
870
+ if (!mailerTokenInfo) {
871
+ transaction.add((0, spl_token_1.createAssociatedTokenAccountInstruction)(connectedWallet.wallet.publicKey, mailerTokenAccount, mailerStatePda, usdcMint));
872
+ }
843
873
  for (const recipient of recipientPubkeys) {
844
- const [recipientInfo] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('recipient_info'), recipient.toBuffer()], programId);
874
+ const [recipientClaimPda] = web3_js_1.PublicKey.findProgramAddressSync([CLAIM_PDA_SEED, recipient.toBuffer()], programId);
845
875
  const recipientTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(usdcMint, recipient, false, spl_token_1.TOKEN_PROGRAM_ID);
846
- keys.push({ pubkey: recipientInfo, isSigner: false, isWritable: true });
847
- keys.push({ pubkey: recipientTokenAccount, isSigner: false, isWritable: true });
876
+ const recipientTokenInfo = await connection.getAccountInfo(recipientTokenAccount);
877
+ if (!recipientTokenInfo) {
878
+ transaction.add((0, spl_token_1.createAssociatedTokenAccountInstruction)(connectedWallet.wallet.publicKey, recipientTokenAccount, recipient, usdcMint));
879
+ }
880
+ transaction.add(new web3_js_1.TransactionInstruction({
881
+ programId,
882
+ keys: [
883
+ { pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
884
+ { pubkey: mailerStatePda, isSigner: false, isWritable: true },
885
+ { pubkey: recipientClaimPda, isSigner: false, isWritable: true },
886
+ { pubkey: recipientTokenAccount, isSigner: false, isWritable: true },
887
+ { pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
888
+ { pubkey: spl_token_1.TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
889
+ ],
890
+ data: encodeDistributeClaimableFunds(recipient),
891
+ }));
848
892
  }
849
- const instruction = new web3_js_1.TransactionInstruction({
850
- programId,
851
- keys,
852
- data: encodeDistributeClaimableFunds(recipientPubkeys),
853
- });
854
- const transaction = new web3_js_1.Transaction().add(instruction);
855
893
  return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
856
894
  }
857
895
  // ============= Read Methods =============
@@ -867,8 +905,8 @@ class SolanaMailerClient {
867
905
  }
868
906
  // Parse the state data
869
907
  const data = accountInfo.data;
870
- const sendFee = data.readBigUInt64LE(41); // After discriminator(8) + owner(32) + paused(1)
871
- const delegationFee = data.readBigUInt64LE(49);
908
+ const sendFee = data.readBigUInt64LE(8 + 32 + 32); // After discriminator + owner + mint
909
+ const delegationFee = data.readBigUInt64LE(8 + 32 + 32 + 8);
872
910
  return {
873
911
  sendFee,
874
912
  delegationFee,
@@ -895,22 +933,22 @@ class SolanaMailerClient {
895
933
  const conn = await this.getOrCreateConnection(chainInfo, connection);
896
934
  const { programId } = this.getProgramAddresses(chainInfo);
897
935
  const recipientPubkey = typeof recipient === 'string' ? new web3_js_1.PublicKey(recipient) : recipient;
898
- const [recipientInfo] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('recipient_info'), recipientPubkey.toBuffer()], programId);
899
- const accountInfo = await conn.getAccountInfo(recipientInfo);
936
+ const [recipientClaimPda] = web3_js_1.PublicKey.findProgramAddressSync([CLAIM_PDA_SEED, recipientPubkey.toBuffer()], programId);
937
+ const accountInfo = await conn.getAccountInfo(recipientClaimPda);
900
938
  if (!accountInfo || !accountInfo.data) {
901
939
  return null;
902
940
  }
903
941
  // Parse the recipient info data
904
942
  const data = accountInfo.data;
905
- const amount = data.readBigUInt64LE(8); // After discriminator
906
- const expiresAt = data.readBigInt64LE(16);
907
- // Check if expired
943
+ const amount = data.readBigUInt64LE(8 + 32); // discriminator + recipient
944
+ const timestamp = Number(data.readBigInt64LE(8 + 32 + 8)); // after amount
945
+ const expiresAt = timestamp + CLAIM_PERIOD_SECONDS;
908
946
  const now = Math.floor(Date.now() / 1000);
909
- const isExpired = Number(expiresAt) > 0 && Number(expiresAt) < now;
947
+ const isExpired = timestamp > 0 && now > expiresAt;
910
948
  return {
911
949
  amount: Number(amount),
912
- timestamp: Number(expiresAt), // Using expiresAt as timestamp
913
- expiresAt: Number(expiresAt),
950
+ timestamp,
951
+ expiresAt,
914
952
  recipient: recipient instanceof web3_js_1.PublicKey ? recipient.toBase58() : recipient,
915
953
  isExpired,
916
954
  };
@@ -927,7 +965,7 @@ class SolanaMailerClient {
927
965
  }
928
966
  // Parse the state data
929
967
  const data = accountInfo.data;
930
- const ownerClaimable = data.readBigUInt64LE(57); // After discriminator(8) + owner(32) + paused(1) + sendFee(8) + delegationFee(8)
968
+ const ownerClaimable = data.readBigUInt64LE(8 + 32 + 32 + 8 + 8); // After discriminator + owner + mint + sendFee + delegationFee
931
969
  return Number(ownerClaimable);
932
970
  }
933
971
  /**
@@ -937,19 +975,19 @@ class SolanaMailerClient {
937
975
  const conn = await this.getOrCreateConnection(chainInfo, connection);
938
976
  const { programId } = this.getProgramAddresses(chainInfo);
939
977
  const addressPubkey = typeof address === 'string' ? new web3_js_1.PublicKey(address) : address;
940
- const [delegatorInfo] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('delegator_info'), addressPubkey.toBuffer()], programId);
941
- const accountInfo = await conn.getAccountInfo(delegatorInfo);
978
+ const [delegationPda] = web3_js_1.PublicKey.findProgramAddressSync([DELEGATION_PDA_SEED, addressPubkey.toBuffer()], programId);
979
+ const accountInfo = await conn.getAccountInfo(delegationPda);
942
980
  if (!accountInfo || !accountInfo.data) {
943
981
  return null;
944
982
  }
945
983
  // Parse the delegatingAddress info data
946
984
  const data = accountInfo.data;
947
- const hasDelegate = data.readUInt8(8) === 1; // After discriminator
985
+ const hasDelegate = data.readUInt8(8 + 32) === 1; // After discriminator + delegator
948
986
  if (!hasDelegate) {
949
987
  return null;
950
988
  }
951
989
  // Read delegate pubkey
952
- const delegateBytes = data.slice(9, 41); // 32 bytes for pubkey
990
+ const delegateBytes = data.slice(8 + 32 + 1, 8 + 32 + 1 + 32); // 32 bytes for pubkey
953
991
  return new web3_js_1.PublicKey(delegateBytes);
954
992
  }
955
993
  /**
@@ -959,15 +997,15 @@ class SolanaMailerClient {
959
997
  const conn = await this.getOrCreateConnection(chainInfo, connection);
960
998
  const { programId } = this.getProgramAddresses(chainInfo);
961
999
  const accountPubkey = typeof account === 'string' ? new web3_js_1.PublicKey(account) : account;
962
- const [customFeeInfo] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('custom_fee'), accountPubkey.toBuffer()], programId);
963
- const accountInfo = await conn.getAccountInfo(customFeeInfo);
1000
+ const [discountPda] = web3_js_1.PublicKey.findProgramAddressSync([DISCOUNT_PDA_SEED, accountPubkey.toBuffer()], programId);
1001
+ const accountInfo = await conn.getAccountInfo(discountPda);
964
1002
  if (!accountInfo || !accountInfo.data) {
965
1003
  return 100; // Default to 100% if no custom fee set
966
1004
  }
967
1005
  // Parse the custom fee data
968
1006
  const data = accountInfo.data;
969
- const percentage = data.readUInt8(8); // After discriminator
970
- return percentage;
1007
+ const discount = data.readUInt8(8 + 32); // After discriminator + account pubkey
1008
+ return 100 - discount;
971
1009
  }
972
1010
  /**
973
1011
  * Check if the program is paused
@@ -981,7 +1019,7 @@ class SolanaMailerClient {
981
1019
  }
982
1020
  // Parse the state data
983
1021
  const data = accountInfo.data;
984
- const paused = data.readUInt8(40); // After discriminator(8) + owner(32)
1022
+ const paused = data.readUInt8(8 + 32 + 32 + 8 + 8 + 8); // After all state fields up to owner_claimable
985
1023
  return paused === 1;
986
1024
  }
987
1025
  /**