@sudobility/contracts 1.14.1 → 1.14.2
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/dist/evm/src/evm/evm-mailer-client.d.ts.map +1 -1
- package/dist/evm/src/evm/evm-mailer-client.js +14 -1
- package/dist/evm/src/evm/evm-mailer-client.js.map +1 -1
- package/dist/solana/solana/solana-mailer-client.d.ts +5 -5
- package/dist/solana/solana/solana-mailer-client.d.ts.map +1 -1
- package/dist/solana/solana/solana-mailer-client.js +138 -142
- package/dist/solana/solana/solana-mailer-client.js.map +1 -1
- package/dist/unified/src/evm/evm-mailer-client.d.ts.map +1 -1
- package/dist/unified/src/evm/evm-mailer-client.js +14 -1
- package/dist/unified/src/evm/evm-mailer-client.js.map +1 -1
- package/dist/unified/src/solana/solana-mailer-client.d.ts +5 -5
- package/dist/unified/src/solana/solana-mailer-client.d.ts.map +1 -1
- package/dist/unified/src/solana/solana-mailer-client.js +138 -142
- package/dist/unified/src/solana/solana-mailer-client.js.map +1 -1
- package/dist/unified/src/unified/onchain-mailer-client.d.ts +1 -0
- package/dist/unified/src/unified/onchain-mailer-client.d.ts.map +1 -1
- package/dist/unified/src/unified/onchain-mailer-client.js +31 -14
- package/dist/unified/src/unified/onchain-mailer-client.js.map +1 -1
- package/package.json +1 -1
|
@@ -8,22 +8,27 @@ 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";
|
|
26
27
|
})(InstructionType || (InstructionType = {}));
|
|
28
|
+
const CLAIM_PDA_SEED = Buffer.from('claim');
|
|
29
|
+
const DELEGATION_PDA_SEED = Buffer.from('delegation');
|
|
30
|
+
const DISCOUNT_PDA_SEED = Buffer.from('discount');
|
|
31
|
+
const CLAIM_PERIOD_SECONDS = 60 * 24 * 60 * 60;
|
|
27
32
|
// Instruction data encoding functions
|
|
28
33
|
function encodeInitialize(usdcMint) {
|
|
29
34
|
const data = Buffer.alloc(1 + 32);
|
|
@@ -70,43 +75,35 @@ function encodeSendPrepared(to, mailId, revenueShareToReceiver, resolveSenderToN
|
|
|
70
75
|
data.writeUInt8(resolveSenderToName ? 1 : 0, offset);
|
|
71
76
|
return data;
|
|
72
77
|
}
|
|
73
|
-
function encodeSendThroughWebhook(to,
|
|
74
|
-
const subjectBytes = Buffer.from(subject, 'utf8');
|
|
75
|
-
const bodyBytes = Buffer.from(body, 'utf8');
|
|
78
|
+
function encodeSendThroughWebhook(to, webhookId, revenueShareToReceiver, resolveSenderToName = false) {
|
|
76
79
|
const webhookIdBytes = Buffer.from(webhookId, 'utf8');
|
|
77
|
-
const data = Buffer.alloc(1 + 32 + 4 +
|
|
80
|
+
const data = Buffer.alloc(1 + 32 + 4 + webhookIdBytes.length + 1 + 1);
|
|
78
81
|
let offset = 0;
|
|
79
82
|
data.writeUInt8(InstructionType.SendThroughWebhook, offset);
|
|
80
83
|
offset += 1;
|
|
81
84
|
to.toBuffer().copy(data, offset);
|
|
82
85
|
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
86
|
data.writeUInt32LE(webhookIdBytes.length, offset);
|
|
92
87
|
offset += 4;
|
|
93
88
|
webhookIdBytes.copy(data, offset);
|
|
94
89
|
offset += webhookIdBytes.length;
|
|
95
90
|
data.writeUInt8(revenueShareToReceiver ? 1 : 0, offset);
|
|
91
|
+
offset += 1;
|
|
92
|
+
data.writeUInt8(resolveSenderToName ? 1 : 0, offset);
|
|
96
93
|
return data;
|
|
97
94
|
}
|
|
98
|
-
function encodeSendToEmail(
|
|
99
|
-
const
|
|
95
|
+
function encodeSendToEmail(toEmail, subject, body) {
|
|
96
|
+
const emailBytes = Buffer.from(toEmail, 'utf8');
|
|
100
97
|
const subjectBytes = Buffer.from(subject, 'utf8');
|
|
101
98
|
const bodyBytes = Buffer.from(body, 'utf8');
|
|
102
|
-
const data = Buffer.alloc(1 + 4 +
|
|
99
|
+
const data = Buffer.alloc(1 + 4 + emailBytes.length + 4 + subjectBytes.length + 4 + bodyBytes.length);
|
|
103
100
|
let offset = 0;
|
|
104
101
|
data.writeUInt8(InstructionType.SendToEmail, offset);
|
|
105
102
|
offset += 1;
|
|
106
|
-
data.writeUInt32LE(
|
|
103
|
+
data.writeUInt32LE(emailBytes.length, offset);
|
|
107
104
|
offset += 4;
|
|
108
|
-
|
|
109
|
-
offset +=
|
|
105
|
+
emailBytes.copy(data, offset);
|
|
106
|
+
offset += emailBytes.length;
|
|
110
107
|
data.writeUInt32LE(subjectBytes.length, offset);
|
|
111
108
|
offset += 4;
|
|
112
109
|
subjectBytes.copy(data, offset);
|
|
@@ -115,36 +112,35 @@ function encodeSendToEmail(emailHash, subject, body, payer, revenueShareToReceiv
|
|
|
115
112
|
offset += 4;
|
|
116
113
|
bodyBytes.copy(data, offset);
|
|
117
114
|
offset += bodyBytes.length;
|
|
118
|
-
payer.toBuffer().copy(data, offset);
|
|
119
|
-
offset += 32;
|
|
120
|
-
data.writeUInt8(revenueShareToReceiver ? 1 : 0, offset);
|
|
121
115
|
return data;
|
|
122
116
|
}
|
|
123
|
-
function encodeSendPreparedToEmail(
|
|
124
|
-
const
|
|
117
|
+
function encodeSendPreparedToEmail(toEmail, mailId) {
|
|
118
|
+
const emailBytes = Buffer.from(toEmail, 'utf8');
|
|
125
119
|
const mailIdBytes = Buffer.from(mailId, 'utf8');
|
|
126
|
-
const data = Buffer.alloc(1 + 4 +
|
|
120
|
+
const data = Buffer.alloc(1 + 4 + emailBytes.length + 4 + mailIdBytes.length);
|
|
127
121
|
let offset = 0;
|
|
128
122
|
data.writeUInt8(InstructionType.SendPreparedToEmail, offset);
|
|
129
123
|
offset += 1;
|
|
130
|
-
data.writeUInt32LE(
|
|
124
|
+
data.writeUInt32LE(emailBytes.length, offset);
|
|
131
125
|
offset += 4;
|
|
132
|
-
|
|
133
|
-
offset +=
|
|
126
|
+
emailBytes.copy(data, offset);
|
|
127
|
+
offset += emailBytes.length;
|
|
134
128
|
data.writeUInt32LE(mailIdBytes.length, offset);
|
|
135
129
|
offset += 4;
|
|
136
130
|
mailIdBytes.copy(data, offset);
|
|
137
131
|
offset += mailIdBytes.length;
|
|
138
|
-
payer.toBuffer().copy(data, offset);
|
|
139
|
-
offset += 32;
|
|
140
|
-
data.writeUInt8(revenueShareToReceiver ? 1 : 0, offset);
|
|
141
132
|
return data;
|
|
142
133
|
}
|
|
143
|
-
function
|
|
144
|
-
const data = Buffer.alloc(1 + 8
|
|
145
|
-
data.writeUInt8(InstructionType.
|
|
134
|
+
function encodeSetFee(sendFee) {
|
|
135
|
+
const data = Buffer.alloc(1 + 8);
|
|
136
|
+
data.writeUInt8(InstructionType.SetFee, 0);
|
|
146
137
|
data.writeBigUInt64LE(sendFee, 1);
|
|
147
|
-
data
|
|
138
|
+
return data;
|
|
139
|
+
}
|
|
140
|
+
function encodeSetDelegationFee(delegationFee) {
|
|
141
|
+
const data = Buffer.alloc(1 + 8);
|
|
142
|
+
data.writeUInt8(InstructionType.SetDelegationFee, 0);
|
|
143
|
+
data.writeBigUInt64LE(delegationFee, 1);
|
|
148
144
|
return data;
|
|
149
145
|
}
|
|
150
146
|
function encodeDelegateTo(delegate) {
|
|
@@ -156,10 +152,9 @@ function encodeDelegateTo(delegate) {
|
|
|
156
152
|
}
|
|
157
153
|
return data;
|
|
158
154
|
}
|
|
159
|
-
function encodeRejectDelegation(
|
|
160
|
-
const data = Buffer.alloc(1
|
|
155
|
+
function encodeRejectDelegation() {
|
|
156
|
+
const data = Buffer.alloc(1);
|
|
161
157
|
data.writeUInt8(InstructionType.RejectDelegation, 0);
|
|
162
|
-
delegatingAddress.toBuffer().copy(data, 1);
|
|
163
158
|
return data;
|
|
164
159
|
}
|
|
165
160
|
function encodeSetCustomFeePercentage(account, percentage) {
|
|
@@ -184,18 +179,10 @@ function encodeClaimExpiredShares(recipient) {
|
|
|
184
179
|
recipient.toBuffer().copy(data, 1);
|
|
185
180
|
return data;
|
|
186
181
|
}
|
|
187
|
-
function encodeDistributeClaimableFunds(
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
}
|
|
182
|
+
function encodeDistributeClaimableFunds(recipient) {
|
|
183
|
+
const data = Buffer.alloc(1 + 32);
|
|
184
|
+
data.writeUInt8(InstructionType.DistributeClaimableFunds, 0);
|
|
185
|
+
recipient.toBuffer().copy(data, 1);
|
|
199
186
|
return data;
|
|
200
187
|
}
|
|
201
188
|
/**
|
|
@@ -394,7 +381,7 @@ export class SolanaMailerClient {
|
|
|
394
381
|
/**
|
|
395
382
|
* Send a message with optional revenue sharing
|
|
396
383
|
*/
|
|
397
|
-
async send(connectedWallet, chainInfo, to, subject, body, revenueShareToReceiver, computeOptions) {
|
|
384
|
+
async send(connectedWallet, chainInfo, to, subject, body, revenueShareToReceiver, resolveSenderToName = false, computeOptions) {
|
|
398
385
|
const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
|
|
399
386
|
const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
|
|
400
387
|
if (!chainInfo.usdcAddress) {
|
|
@@ -402,24 +389,22 @@ export class SolanaMailerClient {
|
|
|
402
389
|
}
|
|
403
390
|
const usdcMint = new PublicKey(chainInfo.usdcAddress);
|
|
404
391
|
const toPubkey = typeof to === 'string' ? new PublicKey(to) : to;
|
|
405
|
-
// Get token accounts
|
|
406
392
|
const senderTokenAccount = getAssociatedTokenAddressSync(usdcMint, connectedWallet.wallet.publicKey, false, TOKEN_PROGRAM_ID);
|
|
407
393
|
const mailerTokenAccount = getAssociatedTokenAddressSync(usdcMint, mailerStatePda, true, TOKEN_PROGRAM_ID);
|
|
408
|
-
const [
|
|
394
|
+
const [recipientClaimPda] = PublicKey.findProgramAddressSync([CLAIM_PDA_SEED, toPubkey.toBuffer()], programId);
|
|
409
395
|
const keys = [
|
|
410
396
|
{ pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
|
|
411
|
-
{ pubkey:
|
|
397
|
+
{ pubkey: recipientClaimPda, isSigner: false, isWritable: true },
|
|
412
398
|
{ pubkey: mailerStatePda, isSigner: false, isWritable: true },
|
|
413
399
|
{ pubkey: senderTokenAccount, isSigner: false, isWritable: true },
|
|
414
400
|
{ pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
|
|
415
|
-
{ pubkey: recipientInfo, isSigner: false, isWritable: true },
|
|
416
401
|
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
417
402
|
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
418
403
|
];
|
|
419
404
|
const instruction = new TransactionInstruction({
|
|
420
405
|
programId,
|
|
421
406
|
keys,
|
|
422
|
-
data: encodeSend(toPubkey, subject, body, revenueShareToReceiver),
|
|
407
|
+
data: encodeSend(toPubkey, subject, body, revenueShareToReceiver, resolveSenderToName),
|
|
423
408
|
});
|
|
424
409
|
const transaction = new Transaction().add(instruction);
|
|
425
410
|
// Check if mailer token account exists, create if not
|
|
@@ -432,7 +417,7 @@ export class SolanaMailerClient {
|
|
|
432
417
|
/**
|
|
433
418
|
* Send a prepared message
|
|
434
419
|
*/
|
|
435
|
-
async sendPrepared(connectedWallet, chainInfo, to, mailId, revenueShareToReceiver, computeOptions) {
|
|
420
|
+
async sendPrepared(connectedWallet, chainInfo, to, mailId, revenueShareToReceiver, resolveSenderToName = false, computeOptions) {
|
|
436
421
|
const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
|
|
437
422
|
const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
|
|
438
423
|
if (!chainInfo.usdcAddress) {
|
|
@@ -442,21 +427,20 @@ export class SolanaMailerClient {
|
|
|
442
427
|
const toPubkey = typeof to === 'string' ? new PublicKey(to) : to;
|
|
443
428
|
const senderTokenAccount = getAssociatedTokenAddressSync(usdcMint, connectedWallet.wallet.publicKey, false, TOKEN_PROGRAM_ID);
|
|
444
429
|
const mailerTokenAccount = getAssociatedTokenAddressSync(usdcMint, mailerStatePda, true, TOKEN_PROGRAM_ID);
|
|
445
|
-
const [
|
|
430
|
+
const [recipientClaimPda] = PublicKey.findProgramAddressSync([CLAIM_PDA_SEED, toPubkey.toBuffer()], programId);
|
|
446
431
|
const keys = [
|
|
447
432
|
{ pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
|
|
448
|
-
{ pubkey:
|
|
433
|
+
{ pubkey: recipientClaimPda, isSigner: false, isWritable: true },
|
|
449
434
|
{ pubkey: mailerStatePda, isSigner: false, isWritable: true },
|
|
450
435
|
{ pubkey: senderTokenAccount, isSigner: false, isWritable: true },
|
|
451
436
|
{ pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
|
|
452
|
-
{ pubkey: recipientInfo, isSigner: false, isWritable: true },
|
|
453
437
|
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
454
438
|
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
455
439
|
];
|
|
456
440
|
const instruction = new TransactionInstruction({
|
|
457
441
|
programId,
|
|
458
442
|
keys,
|
|
459
|
-
data: encodeSendPrepared(toPubkey, mailId, revenueShareToReceiver),
|
|
443
|
+
data: encodeSendPrepared(toPubkey, mailId, revenueShareToReceiver, resolveSenderToName),
|
|
460
444
|
});
|
|
461
445
|
const transaction = new Transaction().add(instruction);
|
|
462
446
|
// Check if mailer token account exists, create if not
|
|
@@ -469,7 +453,7 @@ export class SolanaMailerClient {
|
|
|
469
453
|
/**
|
|
470
454
|
* Send through webhook
|
|
471
455
|
*/
|
|
472
|
-
async sendThroughWebhook(connectedWallet, chainInfo, to,
|
|
456
|
+
async sendThroughWebhook(connectedWallet, chainInfo, to, webhookId, revenueShareToReceiver, resolveSenderToName = false, computeOptions) {
|
|
473
457
|
const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
|
|
474
458
|
const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
|
|
475
459
|
if (!chainInfo.usdcAddress) {
|
|
@@ -479,21 +463,20 @@ export class SolanaMailerClient {
|
|
|
479
463
|
const toPubkey = typeof to === 'string' ? new PublicKey(to) : to;
|
|
480
464
|
const senderTokenAccount = getAssociatedTokenAddressSync(usdcMint, connectedWallet.wallet.publicKey, false, TOKEN_PROGRAM_ID);
|
|
481
465
|
const mailerTokenAccount = getAssociatedTokenAddressSync(usdcMint, mailerStatePda, true, TOKEN_PROGRAM_ID);
|
|
482
|
-
const [
|
|
466
|
+
const [recipientClaimPda] = PublicKey.findProgramAddressSync([CLAIM_PDA_SEED, toPubkey.toBuffer()], programId);
|
|
483
467
|
const keys = [
|
|
484
468
|
{ pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
|
|
485
|
-
{ pubkey:
|
|
469
|
+
{ pubkey: recipientClaimPda, isSigner: false, isWritable: true },
|
|
486
470
|
{ pubkey: mailerStatePda, isSigner: false, isWritable: true },
|
|
487
471
|
{ pubkey: senderTokenAccount, isSigner: false, isWritable: true },
|
|
488
472
|
{ pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
|
|
489
|
-
{ pubkey: recipientInfo, isSigner: false, isWritable: true },
|
|
490
473
|
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
491
474
|
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
492
475
|
];
|
|
493
476
|
const instruction = new TransactionInstruction({
|
|
494
477
|
programId,
|
|
495
478
|
keys,
|
|
496
|
-
data: encodeSendThroughWebhook(toPubkey,
|
|
479
|
+
data: encodeSendThroughWebhook(toPubkey, webhookId, revenueShareToReceiver, resolveSenderToName),
|
|
497
480
|
});
|
|
498
481
|
const transaction = new Transaction().add(instruction);
|
|
499
482
|
const accountInfo = await connection.getAccountInfo(mailerTokenAccount);
|
|
@@ -505,14 +488,13 @@ export class SolanaMailerClient {
|
|
|
505
488
|
/**
|
|
506
489
|
* Send to email address
|
|
507
490
|
*/
|
|
508
|
-
async sendToEmail(emailHash, subject, body,
|
|
491
|
+
async sendToEmail(emailHash, subject, body, _payer, _revenueShareToReceiver, connectedWallet, chainInfo, computeOptions) {
|
|
509
492
|
const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
|
|
510
493
|
const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
|
|
511
494
|
if (!chainInfo.usdcAddress) {
|
|
512
495
|
throw new Error(`No USDC mint configured for ${chainInfo.name}`);
|
|
513
496
|
}
|
|
514
497
|
const usdcMint = new PublicKey(chainInfo.usdcAddress);
|
|
515
|
-
const payerPubkey = typeof payer === 'string' ? new PublicKey(payer) : payer;
|
|
516
498
|
const senderTokenAccount = getAssociatedTokenAddressSync(usdcMint, connectedWallet.wallet.publicKey, false, TOKEN_PROGRAM_ID);
|
|
517
499
|
const mailerTokenAccount = getAssociatedTokenAddressSync(usdcMint, mailerStatePda, true, TOKEN_PROGRAM_ID);
|
|
518
500
|
const keys = [
|
|
@@ -521,12 +503,11 @@ export class SolanaMailerClient {
|
|
|
521
503
|
{ pubkey: senderTokenAccount, isSigner: false, isWritable: true },
|
|
522
504
|
{ pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
|
|
523
505
|
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
524
|
-
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
525
506
|
];
|
|
526
507
|
const instruction = new TransactionInstruction({
|
|
527
508
|
programId,
|
|
528
509
|
keys,
|
|
529
|
-
data: encodeSendToEmail(emailHash, subject, body
|
|
510
|
+
data: encodeSendToEmail(emailHash, subject, body),
|
|
530
511
|
});
|
|
531
512
|
const transaction = new Transaction().add(instruction);
|
|
532
513
|
const accountInfo = await connection.getAccountInfo(mailerTokenAccount);
|
|
@@ -538,14 +519,13 @@ export class SolanaMailerClient {
|
|
|
538
519
|
/**
|
|
539
520
|
* Send prepared to email address
|
|
540
521
|
*/
|
|
541
|
-
async sendPreparedToEmail(emailHash, mailId,
|
|
522
|
+
async sendPreparedToEmail(emailHash, mailId, _payer, _revenueShareToReceiver, connectedWallet, chainInfo, computeOptions) {
|
|
542
523
|
const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
|
|
543
524
|
const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
|
|
544
525
|
if (!chainInfo.usdcAddress) {
|
|
545
526
|
throw new Error(`No USDC mint configured for ${chainInfo.name}`);
|
|
546
527
|
}
|
|
547
528
|
const usdcMint = new PublicKey(chainInfo.usdcAddress);
|
|
548
|
-
const payerPubkey = typeof payer === 'string' ? new PublicKey(payer) : payer;
|
|
549
529
|
const senderTokenAccount = getAssociatedTokenAddressSync(usdcMint, connectedWallet.wallet.publicKey, false, TOKEN_PROGRAM_ID);
|
|
550
530
|
const mailerTokenAccount = getAssociatedTokenAddressSync(usdcMint, mailerStatePda, true, TOKEN_PROGRAM_ID);
|
|
551
531
|
const keys = [
|
|
@@ -554,12 +534,11 @@ export class SolanaMailerClient {
|
|
|
554
534
|
{ pubkey: senderTokenAccount, isSigner: false, isWritable: true },
|
|
555
535
|
{ pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
|
|
556
536
|
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
557
|
-
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
558
537
|
];
|
|
559
538
|
const instruction = new TransactionInstruction({
|
|
560
539
|
programId,
|
|
561
540
|
keys,
|
|
562
|
-
data: encodeSendPreparedToEmail(emailHash, mailId
|
|
541
|
+
data: encodeSendPreparedToEmail(emailHash, mailId),
|
|
563
542
|
});
|
|
564
543
|
const transaction = new Transaction().add(instruction);
|
|
565
544
|
const accountInfo = await connection.getAccountInfo(mailerTokenAccount);
|
|
@@ -580,13 +559,13 @@ export class SolanaMailerClient {
|
|
|
580
559
|
const usdcMint = new PublicKey(chainInfo.usdcAddress);
|
|
581
560
|
const recipientTokenAccount = getAssociatedTokenAddressSync(usdcMint, connectedWallet.wallet.publicKey, false, TOKEN_PROGRAM_ID);
|
|
582
561
|
const mailerTokenAccount = getAssociatedTokenAddressSync(usdcMint, mailerStatePda, true, TOKEN_PROGRAM_ID);
|
|
583
|
-
const [
|
|
562
|
+
const [recipientClaimPda] = PublicKey.findProgramAddressSync([CLAIM_PDA_SEED, connectedWallet.wallet.publicKey.toBuffer()], programId);
|
|
584
563
|
const keys = [
|
|
585
564
|
{ pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
|
|
565
|
+
{ pubkey: recipientClaimPda, isSigner: false, isWritable: true },
|
|
586
566
|
{ pubkey: mailerStatePda, isSigner: false, isWritable: true },
|
|
587
567
|
{ pubkey: recipientTokenAccount, isSigner: false, isWritable: true },
|
|
588
568
|
{ pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
|
|
589
|
-
{ pubkey: recipientInfo, isSigner: false, isWritable: true },
|
|
590
569
|
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
591
570
|
];
|
|
592
571
|
const instruction = new TransactionInstruction({
|
|
@@ -631,11 +610,11 @@ export class SolanaMailerClient {
|
|
|
631
610
|
const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
|
|
632
611
|
const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
|
|
633
612
|
const recipientPubkey = typeof recipient === 'string' ? new PublicKey(recipient) : recipient;
|
|
634
|
-
const [
|
|
613
|
+
const [recipientClaimPda] = PublicKey.findProgramAddressSync([CLAIM_PDA_SEED, recipientPubkey.toBuffer()], programId);
|
|
635
614
|
const keys = [
|
|
636
615
|
{ pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
|
|
637
616
|
{ pubkey: mailerStatePda, isSigner: false, isWritable: true },
|
|
638
|
-
{ pubkey:
|
|
617
|
+
{ pubkey: recipientClaimPda, isSigner: false, isWritable: true },
|
|
639
618
|
];
|
|
640
619
|
const instruction = new TransactionInstruction({
|
|
641
620
|
programId,
|
|
@@ -660,13 +639,13 @@ export class SolanaMailerClient {
|
|
|
660
639
|
: null;
|
|
661
640
|
const senderTokenAccount = getAssociatedTokenAddressSync(usdcMint, connectedWallet.wallet.publicKey, false, TOKEN_PROGRAM_ID);
|
|
662
641
|
const mailerTokenAccount = getAssociatedTokenAddressSync(usdcMint, mailerStatePda, true, TOKEN_PROGRAM_ID);
|
|
663
|
-
const [
|
|
642
|
+
const [delegationPda] = PublicKey.findProgramAddressSync([DELEGATION_PDA_SEED, connectedWallet.wallet.publicKey.toBuffer()], programId);
|
|
664
643
|
const keys = [
|
|
665
644
|
{ pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: true },
|
|
645
|
+
{ pubkey: delegationPda, isSigner: false, isWritable: true },
|
|
666
646
|
{ pubkey: mailerStatePda, isSigner: false, isWritable: true },
|
|
667
647
|
{ pubkey: senderTokenAccount, isSigner: false, isWritable: true },
|
|
668
648
|
{ pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
|
|
669
|
-
{ pubkey: delegatorInfo, isSigner: false, isWritable: true },
|
|
670
649
|
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
671
650
|
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
672
651
|
];
|
|
@@ -687,17 +666,18 @@ export class SolanaMailerClient {
|
|
|
687
666
|
*/
|
|
688
667
|
async rejectDelegation(connectedWallet, chainInfo, delegatingAddress, computeOptions) {
|
|
689
668
|
const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
|
|
690
|
-
const { programId } = this.getProgramAddresses(chainInfo);
|
|
669
|
+
const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
|
|
691
670
|
const delegatorPubkey = typeof delegatingAddress === 'string' ? new PublicKey(delegatingAddress) : delegatingAddress;
|
|
692
|
-
const [
|
|
671
|
+
const [delegationPda] = PublicKey.findProgramAddressSync([DELEGATION_PDA_SEED, delegatorPubkey.toBuffer()], programId);
|
|
693
672
|
const keys = [
|
|
694
673
|
{ pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
|
|
695
|
-
{ pubkey:
|
|
674
|
+
{ pubkey: delegationPda, isSigner: false, isWritable: true },
|
|
675
|
+
{ pubkey: mailerStatePda, isSigner: false, isWritable: false },
|
|
696
676
|
];
|
|
697
677
|
const instruction = new TransactionInstruction({
|
|
698
678
|
programId,
|
|
699
679
|
keys,
|
|
700
|
-
data: encodeRejectDelegation(
|
|
680
|
+
data: encodeRejectDelegation(),
|
|
701
681
|
});
|
|
702
682
|
const transaction = new Transaction().add(instruction);
|
|
703
683
|
return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
|
|
@@ -708,16 +688,24 @@ export class SolanaMailerClient {
|
|
|
708
688
|
async setFees(connectedWallet, chainInfo, sendFee, delegationFee, computeOptions) {
|
|
709
689
|
const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
|
|
710
690
|
const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
|
|
711
|
-
const
|
|
712
|
-
|
|
713
|
-
{ pubkey: mailerStatePda, isSigner: false, isWritable: true },
|
|
714
|
-
];
|
|
715
|
-
const instruction = new TransactionInstruction({
|
|
691
|
+
const ownerKey = connectedWallet.wallet.publicKey;
|
|
692
|
+
const setSendFeeIx = new TransactionInstruction({
|
|
716
693
|
programId,
|
|
717
|
-
keys
|
|
718
|
-
|
|
694
|
+
keys: [
|
|
695
|
+
{ pubkey: ownerKey, isSigner: true, isWritable: false },
|
|
696
|
+
{ pubkey: mailerStatePda, isSigner: false, isWritable: true },
|
|
697
|
+
],
|
|
698
|
+
data: encodeSetFee(BigInt(sendFee)),
|
|
719
699
|
});
|
|
720
|
-
const
|
|
700
|
+
const setDelegationFeeIx = new TransactionInstruction({
|
|
701
|
+
programId,
|
|
702
|
+
keys: [
|
|
703
|
+
{ pubkey: ownerKey, isSigner: true, isWritable: false },
|
|
704
|
+
{ pubkey: mailerStatePda, isSigner: false, isWritable: true },
|
|
705
|
+
],
|
|
706
|
+
data: encodeSetDelegationFee(BigInt(delegationFee)),
|
|
707
|
+
});
|
|
708
|
+
const transaction = new Transaction().add(setSendFeeIx, setDelegationFeeIx);
|
|
721
709
|
return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
|
|
722
710
|
}
|
|
723
711
|
/**
|
|
@@ -727,11 +715,14 @@ export class SolanaMailerClient {
|
|
|
727
715
|
const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
|
|
728
716
|
const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
|
|
729
717
|
const accountPubkey = typeof account === 'string' ? new PublicKey(account) : account;
|
|
730
|
-
const [
|
|
718
|
+
const [discountPda] = PublicKey.findProgramAddressSync([DISCOUNT_PDA_SEED, accountPubkey.toBuffer()], programId);
|
|
719
|
+
const ownerKey = connectedWallet.wallet.publicKey;
|
|
731
720
|
const keys = [
|
|
732
|
-
{ pubkey:
|
|
721
|
+
{ pubkey: ownerKey, isSigner: true, isWritable: false },
|
|
733
722
|
{ pubkey: mailerStatePda, isSigner: false, isWritable: false },
|
|
734
|
-
{ pubkey:
|
|
723
|
+
{ pubkey: discountPda, isSigner: false, isWritable: true },
|
|
724
|
+
{ pubkey: accountPubkey, isSigner: false, isWritable: false },
|
|
725
|
+
{ pubkey: ownerKey, isSigner: true, isWritable: true },
|
|
735
726
|
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
736
727
|
];
|
|
737
728
|
const instruction = new TransactionInstruction({
|
|
@@ -749,11 +740,11 @@ export class SolanaMailerClient {
|
|
|
749
740
|
const connection = await this.getOrCreateConnection(chainInfo, connectedWallet.connection);
|
|
750
741
|
const { programId, mailerStatePda } = this.getProgramAddresses(chainInfo);
|
|
751
742
|
const accountPubkey = typeof account === 'string' ? new PublicKey(account) : account;
|
|
752
|
-
const [
|
|
743
|
+
const [discountPda] = PublicKey.findProgramAddressSync([DISCOUNT_PDA_SEED, accountPubkey.toBuffer()], programId);
|
|
753
744
|
const keys = [
|
|
754
745
|
{ pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
|
|
755
746
|
{ pubkey: mailerStatePda, isSigner: false, isWritable: false },
|
|
756
|
-
{ pubkey:
|
|
747
|
+
{ pubkey: discountPda, isSigner: false, isWritable: true },
|
|
757
748
|
];
|
|
758
749
|
const instruction = new TransactionInstruction({
|
|
759
750
|
programId,
|
|
@@ -829,26 +820,31 @@ export class SolanaMailerClient {
|
|
|
829
820
|
const usdcMint = new PublicKey(chainInfo.usdcAddress);
|
|
830
821
|
const recipientPubkeys = recipients.map(r => typeof r === 'string' ? new PublicKey(r) : r);
|
|
831
822
|
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
|
|
823
|
+
const transaction = new Transaction();
|
|
824
|
+
const mailerTokenInfo = await connection.getAccountInfo(mailerTokenAccount);
|
|
825
|
+
if (!mailerTokenInfo) {
|
|
826
|
+
transaction.add(createAssociatedTokenAccountInstruction(connectedWallet.wallet.publicKey, mailerTokenAccount, mailerStatePda, usdcMint));
|
|
827
|
+
}
|
|
840
828
|
for (const recipient of recipientPubkeys) {
|
|
841
|
-
const [
|
|
829
|
+
const [recipientClaimPda] = PublicKey.findProgramAddressSync([CLAIM_PDA_SEED, recipient.toBuffer()], programId);
|
|
842
830
|
const recipientTokenAccount = getAssociatedTokenAddressSync(usdcMint, recipient, false, TOKEN_PROGRAM_ID);
|
|
843
|
-
|
|
844
|
-
|
|
831
|
+
const recipientTokenInfo = await connection.getAccountInfo(recipientTokenAccount);
|
|
832
|
+
if (!recipientTokenInfo) {
|
|
833
|
+
transaction.add(createAssociatedTokenAccountInstruction(connectedWallet.wallet.publicKey, recipientTokenAccount, recipient, usdcMint));
|
|
834
|
+
}
|
|
835
|
+
transaction.add(new TransactionInstruction({
|
|
836
|
+
programId,
|
|
837
|
+
keys: [
|
|
838
|
+
{ pubkey: connectedWallet.wallet.publicKey, isSigner: true, isWritable: false },
|
|
839
|
+
{ pubkey: mailerStatePda, isSigner: false, isWritable: true },
|
|
840
|
+
{ pubkey: recipientClaimPda, isSigner: false, isWritable: true },
|
|
841
|
+
{ pubkey: recipientTokenAccount, isSigner: false, isWritable: true },
|
|
842
|
+
{ pubkey: mailerTokenAccount, isSigner: false, isWritable: true },
|
|
843
|
+
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
|
|
844
|
+
],
|
|
845
|
+
data: encodeDistributeClaimableFunds(recipient),
|
|
846
|
+
}));
|
|
845
847
|
}
|
|
846
|
-
const instruction = new TransactionInstruction({
|
|
847
|
-
programId,
|
|
848
|
-
keys,
|
|
849
|
-
data: encodeDistributeClaimableFunds(recipientPubkeys),
|
|
850
|
-
});
|
|
851
|
-
const transaction = new Transaction().add(instruction);
|
|
852
848
|
return await this.sendTransaction(transaction, connectedWallet.wallet, connection, undefined, computeOptions);
|
|
853
849
|
}
|
|
854
850
|
// ============= Read Methods =============
|
|
@@ -864,8 +860,8 @@ export class SolanaMailerClient {
|
|
|
864
860
|
}
|
|
865
861
|
// Parse the state data
|
|
866
862
|
const data = accountInfo.data;
|
|
867
|
-
const sendFee = data.readBigUInt64LE(
|
|
868
|
-
const delegationFee = data.readBigUInt64LE(
|
|
863
|
+
const sendFee = data.readBigUInt64LE(8 + 32 + 32); // After discriminator + owner + mint
|
|
864
|
+
const delegationFee = data.readBigUInt64LE(8 + 32 + 32 + 8);
|
|
869
865
|
return {
|
|
870
866
|
sendFee,
|
|
871
867
|
delegationFee,
|
|
@@ -892,22 +888,22 @@ export class SolanaMailerClient {
|
|
|
892
888
|
const conn = await this.getOrCreateConnection(chainInfo, connection);
|
|
893
889
|
const { programId } = this.getProgramAddresses(chainInfo);
|
|
894
890
|
const recipientPubkey = typeof recipient === 'string' ? new PublicKey(recipient) : recipient;
|
|
895
|
-
const [
|
|
896
|
-
const accountInfo = await conn.getAccountInfo(
|
|
891
|
+
const [recipientClaimPda] = PublicKey.findProgramAddressSync([CLAIM_PDA_SEED, recipientPubkey.toBuffer()], programId);
|
|
892
|
+
const accountInfo = await conn.getAccountInfo(recipientClaimPda);
|
|
897
893
|
if (!accountInfo || !accountInfo.data) {
|
|
898
894
|
return null;
|
|
899
895
|
}
|
|
900
896
|
// Parse the recipient info data
|
|
901
897
|
const data = accountInfo.data;
|
|
902
|
-
const amount = data.readBigUInt64LE(8); //
|
|
903
|
-
const
|
|
904
|
-
|
|
898
|
+
const amount = data.readBigUInt64LE(8 + 32); // discriminator + recipient
|
|
899
|
+
const timestamp = Number(data.readBigInt64LE(8 + 32 + 8)); // after amount
|
|
900
|
+
const expiresAt = timestamp + CLAIM_PERIOD_SECONDS;
|
|
905
901
|
const now = Math.floor(Date.now() / 1000);
|
|
906
|
-
const isExpired =
|
|
902
|
+
const isExpired = timestamp > 0 && now > expiresAt;
|
|
907
903
|
return {
|
|
908
904
|
amount: Number(amount),
|
|
909
|
-
timestamp
|
|
910
|
-
expiresAt
|
|
905
|
+
timestamp,
|
|
906
|
+
expiresAt,
|
|
911
907
|
recipient: recipient instanceof PublicKey ? recipient.toBase58() : recipient,
|
|
912
908
|
isExpired,
|
|
913
909
|
};
|
|
@@ -924,7 +920,7 @@ export class SolanaMailerClient {
|
|
|
924
920
|
}
|
|
925
921
|
// Parse the state data
|
|
926
922
|
const data = accountInfo.data;
|
|
927
|
-
const ownerClaimable = data.readBigUInt64LE(
|
|
923
|
+
const ownerClaimable = data.readBigUInt64LE(8 + 32 + 32 + 8 + 8); // After discriminator + owner + mint + sendFee + delegationFee
|
|
928
924
|
return Number(ownerClaimable);
|
|
929
925
|
}
|
|
930
926
|
/**
|
|
@@ -934,19 +930,19 @@ export class SolanaMailerClient {
|
|
|
934
930
|
const conn = await this.getOrCreateConnection(chainInfo, connection);
|
|
935
931
|
const { programId } = this.getProgramAddresses(chainInfo);
|
|
936
932
|
const addressPubkey = typeof address === 'string' ? new PublicKey(address) : address;
|
|
937
|
-
const [
|
|
938
|
-
const accountInfo = await conn.getAccountInfo(
|
|
933
|
+
const [delegationPda] = PublicKey.findProgramAddressSync([DELEGATION_PDA_SEED, addressPubkey.toBuffer()], programId);
|
|
934
|
+
const accountInfo = await conn.getAccountInfo(delegationPda);
|
|
939
935
|
if (!accountInfo || !accountInfo.data) {
|
|
940
936
|
return null;
|
|
941
937
|
}
|
|
942
938
|
// Parse the delegatingAddress info data
|
|
943
939
|
const data = accountInfo.data;
|
|
944
|
-
const hasDelegate = data.readUInt8(8) === 1; // After discriminator
|
|
940
|
+
const hasDelegate = data.readUInt8(8 + 32) === 1; // After discriminator + delegator
|
|
945
941
|
if (!hasDelegate) {
|
|
946
942
|
return null;
|
|
947
943
|
}
|
|
948
944
|
// Read delegate pubkey
|
|
949
|
-
const delegateBytes = data.slice(
|
|
945
|
+
const delegateBytes = data.slice(8 + 32 + 1, 8 + 32 + 1 + 32); // 32 bytes for pubkey
|
|
950
946
|
return new PublicKey(delegateBytes);
|
|
951
947
|
}
|
|
952
948
|
/**
|
|
@@ -956,15 +952,15 @@ export class SolanaMailerClient {
|
|
|
956
952
|
const conn = await this.getOrCreateConnection(chainInfo, connection);
|
|
957
953
|
const { programId } = this.getProgramAddresses(chainInfo);
|
|
958
954
|
const accountPubkey = typeof account === 'string' ? new PublicKey(account) : account;
|
|
959
|
-
const [
|
|
960
|
-
const accountInfo = await conn.getAccountInfo(
|
|
955
|
+
const [discountPda] = PublicKey.findProgramAddressSync([DISCOUNT_PDA_SEED, accountPubkey.toBuffer()], programId);
|
|
956
|
+
const accountInfo = await conn.getAccountInfo(discountPda);
|
|
961
957
|
if (!accountInfo || !accountInfo.data) {
|
|
962
958
|
return 100; // Default to 100% if no custom fee set
|
|
963
959
|
}
|
|
964
960
|
// Parse the custom fee data
|
|
965
961
|
const data = accountInfo.data;
|
|
966
|
-
const
|
|
967
|
-
return
|
|
962
|
+
const discount = data.readUInt8(8 + 32); // After discriminator + account pubkey
|
|
963
|
+
return 100 - discount;
|
|
968
964
|
}
|
|
969
965
|
/**
|
|
970
966
|
* Check if the program is paused
|
|
@@ -978,7 +974,7 @@ export class SolanaMailerClient {
|
|
|
978
974
|
}
|
|
979
975
|
// Parse the state data
|
|
980
976
|
const data = accountInfo.data;
|
|
981
|
-
const paused = data.readUInt8(
|
|
977
|
+
const paused = data.readUInt8(8 + 32 + 32 + 8 + 8 + 8); // After all state fields up to owner_claimable
|
|
982
978
|
return paused === 1;
|
|
983
979
|
}
|
|
984
980
|
/**
|