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