@sudobility/contracts 1.10.0 → 1.10.1
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/solana/solana/mailer-client.d.ts +7 -0
- package/dist/solana/solana/mailer-client.d.ts.map +1 -1
- package/dist/solana/solana/mailer-client.js +30 -1
- package/dist/solana/solana/mailer-client.js.map +1 -1
- package/dist/unified/src/react/hooks/useMailerMutations.d.ts +1 -1
- package/dist/unified/src/react/hooks/useMailerMutations.js +1 -1
- package/dist/unified/src/solana/mailer-client.d.ts +7 -0
- package/dist/unified/src/solana/mailer-client.d.ts.map +1 -1
- package/dist/unified/src/solana/mailer-client.js +30 -1
- package/dist/unified/src/solana/mailer-client.js.map +1 -1
- package/dist/unified/src/unified/onchain-mailer-client.d.ts +2 -1
- package/dist/unified/src/unified/onchain-mailer-client.d.ts.map +1 -1
- package/dist/unified/src/unified/onchain-mailer-client.js +23 -2
- package/dist/unified/src/unified/onchain-mailer-client.js.map +1 -1
- package/dist/unified-esm/src/react/hooks/useMailerMutations.d.ts +1 -1
- package/dist/unified-esm/src/react/hooks/useMailerMutations.js +1 -1
- package/dist/unified-esm/src/solana/mailer-client.d.ts +7 -0
- package/dist/unified-esm/src/solana/mailer-client.d.ts.map +1 -1
- package/dist/unified-esm/src/solana/mailer-client.js +30 -1
- package/dist/unified-esm/src/solana/mailer-client.js.map +1 -1
- package/dist/unified-esm/src/unified/onchain-mailer-client.d.ts +2 -1
- package/dist/unified-esm/src/unified/onchain-mailer-client.d.ts.map +1 -1
- package/dist/unified-esm/src/unified/onchain-mailer-client.js +23 -2
- package/dist/unified-esm/src/unified/onchain-mailer-client.js.map +1 -1
- package/package.json +1 -1
- package/programs/mailer/src/lib.rs +429 -102
- package/programs/mailer/tests/integration_tests.rs +383 -65
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
use borsh::BorshDeserialize;
|
|
1
2
|
use solana_program::{
|
|
2
3
|
instruction::{AccountMeta, Instruction},
|
|
3
4
|
program_pack::Pack,
|
|
@@ -13,11 +14,10 @@ use spl_token::{
|
|
|
13
14
|
instruction as spl_instruction,
|
|
14
15
|
state::{Account as TokenAccount, Mint},
|
|
15
16
|
};
|
|
16
|
-
use borsh::BorshDeserialize;
|
|
17
17
|
use std::str::FromStr;
|
|
18
18
|
|
|
19
19
|
// Import our program
|
|
20
|
-
use mailer::{MailerInstruction, MailerState, RecipientClaim
|
|
20
|
+
use mailer::{Delegation, MailerInstruction, MailerState, RecipientClaim};
|
|
21
21
|
|
|
22
22
|
// Program ID for tests
|
|
23
23
|
const PROGRAM_ID_STR: &str = "9FLkBDGpZBcR8LMsQ7MwwV6X9P4TDFgN3DeRh5qYyHJF";
|
|
@@ -51,7 +51,8 @@ async fn create_usdc_mint(
|
|
|
51
51
|
&payer.pubkey(),
|
|
52
52
|
None,
|
|
53
53
|
6, // USDC has 6 decimals
|
|
54
|
-
)
|
|
54
|
+
)
|
|
55
|
+
.unwrap(),
|
|
55
56
|
],
|
|
56
57
|
Some(&payer.pubkey()),
|
|
57
58
|
);
|
|
@@ -82,12 +83,8 @@ async fn create_token_account(
|
|
|
82
83
|
TokenAccount::LEN as u64,
|
|
83
84
|
&spl_token::id(),
|
|
84
85
|
),
|
|
85
|
-
spl_instruction::initialize_account(
|
|
86
|
-
|
|
87
|
-
&account.pubkey(),
|
|
88
|
-
mint,
|
|
89
|
-
owner,
|
|
90
|
-
).unwrap(),
|
|
86
|
+
spl_instruction::initialize_account(&spl_token::id(), &account.pubkey(), mint, owner)
|
|
87
|
+
.unwrap(),
|
|
91
88
|
],
|
|
92
89
|
Some(&payer.pubkey()),
|
|
93
90
|
);
|
|
@@ -114,7 +111,8 @@ async fn mint_to(
|
|
|
114
111
|
&payer.pubkey(),
|
|
115
112
|
&[],
|
|
116
113
|
amount,
|
|
117
|
-
)
|
|
114
|
+
)
|
|
115
|
+
.unwrap()],
|
|
118
116
|
Some(&payer.pubkey()),
|
|
119
117
|
);
|
|
120
118
|
transaction.sign(&[payer], recent_blockhash);
|
|
@@ -170,7 +168,7 @@ async fn test_initialize_program() {
|
|
|
170
168
|
// Verify the mailer state was initialized correctly
|
|
171
169
|
let account = banks_client.get_account(mailer_pda).await.unwrap().unwrap();
|
|
172
170
|
let mailer_state: MailerState = BorshDeserialize::deserialize(&mut &account.data[8..]).unwrap();
|
|
173
|
-
|
|
171
|
+
|
|
174
172
|
assert_eq!(mailer_state.owner, payer.pubkey());
|
|
175
173
|
assert_eq!(mailer_state.usdc_mint, usdc_mint);
|
|
176
174
|
assert_eq!(mailer_state.send_fee, 100_000); // 0.1 USDC
|
|
@@ -190,7 +188,7 @@ async fn test_send_priority_message() {
|
|
|
190
188
|
// Create USDC mint and accounts
|
|
191
189
|
let usdc_mint = create_usdc_mint(&mut banks_client, &payer, recent_blockhash).await;
|
|
192
190
|
let (mailer_pda, _) = get_mailer_pda();
|
|
193
|
-
|
|
191
|
+
|
|
194
192
|
// Initialize the program first
|
|
195
193
|
let init_instruction = Instruction::new_with_borsh(
|
|
196
194
|
program_id(),
|
|
@@ -207,11 +205,33 @@ async fn test_send_priority_message() {
|
|
|
207
205
|
banks_client.process_transaction(transaction).await.unwrap();
|
|
208
206
|
|
|
209
207
|
// Create token accounts
|
|
210
|
-
let sender_usdc = create_token_account(
|
|
211
|
-
|
|
212
|
-
|
|
208
|
+
let sender_usdc = create_token_account(
|
|
209
|
+
&mut banks_client,
|
|
210
|
+
&payer,
|
|
211
|
+
recent_blockhash,
|
|
212
|
+
&usdc_mint,
|
|
213
|
+
&payer.pubkey(),
|
|
214
|
+
)
|
|
215
|
+
.await;
|
|
216
|
+
let mailer_usdc = create_token_account(
|
|
217
|
+
&mut banks_client,
|
|
218
|
+
&payer,
|
|
219
|
+
recent_blockhash,
|
|
220
|
+
&usdc_mint,
|
|
221
|
+
&mailer_pda,
|
|
222
|
+
)
|
|
223
|
+
.await;
|
|
224
|
+
|
|
213
225
|
// Mint USDC to sender
|
|
214
|
-
mint_to(
|
|
226
|
+
mint_to(
|
|
227
|
+
&mut banks_client,
|
|
228
|
+
&payer,
|
|
229
|
+
recent_blockhash,
|
|
230
|
+
&usdc_mint,
|
|
231
|
+
&sender_usdc,
|
|
232
|
+
1_000_000,
|
|
233
|
+
)
|
|
234
|
+
.await; // 1 USDC
|
|
215
235
|
|
|
216
236
|
// Get recipient claim PDA
|
|
217
237
|
let (recipient_claim_pda, _) = get_claim_pda(&payer.pubkey());
|
|
@@ -247,16 +267,22 @@ async fn test_send_priority_message() {
|
|
|
247
267
|
let _recent_blockhash = banks_client.get_latest_blockhash().await.unwrap();
|
|
248
268
|
|
|
249
269
|
// Verify recipient claim was created with correct amount
|
|
250
|
-
let claim_account = banks_client
|
|
251
|
-
|
|
252
|
-
|
|
270
|
+
let claim_account = banks_client
|
|
271
|
+
.get_account(recipient_claim_pda)
|
|
272
|
+
.await
|
|
273
|
+
.unwrap()
|
|
274
|
+
.unwrap();
|
|
275
|
+
let recipient_claim: RecipientClaim =
|
|
276
|
+
BorshDeserialize::deserialize(&mut &claim_account.data[8..]).unwrap();
|
|
277
|
+
|
|
253
278
|
assert_eq!(recipient_claim.recipient, payer.pubkey());
|
|
254
279
|
assert_eq!(recipient_claim.amount, 90_000); // 90% of send_fee (100,000)
|
|
255
280
|
|
|
256
281
|
// Verify mailer state was updated with owner share
|
|
257
282
|
let mailer_account = banks_client.get_account(mailer_pda).await.unwrap().unwrap();
|
|
258
|
-
let mailer_state: MailerState =
|
|
259
|
-
|
|
283
|
+
let mailer_state: MailerState =
|
|
284
|
+
BorshDeserialize::deserialize(&mut &mailer_account.data[8..]).unwrap();
|
|
285
|
+
|
|
260
286
|
// Debug output
|
|
261
287
|
println!("Debug - Mailer state:");
|
|
262
288
|
println!(" owner: {}", mailer_state.owner);
|
|
@@ -265,7 +291,7 @@ async fn test_send_priority_message() {
|
|
|
265
291
|
println!(" delegation_fee: {}", mailer_state.delegation_fee);
|
|
266
292
|
println!(" owner_claimable: {}", mailer_state.owner_claimable);
|
|
267
293
|
println!(" bump: {}", mailer_state.bump);
|
|
268
|
-
|
|
294
|
+
|
|
269
295
|
assert_eq!(mailer_state.owner_claimable, 10_000); // 10% of send_fee
|
|
270
296
|
}
|
|
271
297
|
|
|
@@ -281,7 +307,7 @@ async fn test_send_standard_message() {
|
|
|
281
307
|
// Setup similar to priority test
|
|
282
308
|
let usdc_mint = create_usdc_mint(&mut banks_client, &payer, recent_blockhash).await;
|
|
283
309
|
let (mailer_pda, _) = get_mailer_pda();
|
|
284
|
-
|
|
310
|
+
|
|
285
311
|
// Initialize the program
|
|
286
312
|
let init_instruction = Instruction::new_with_borsh(
|
|
287
313
|
program_id(),
|
|
@@ -298,11 +324,33 @@ async fn test_send_standard_message() {
|
|
|
298
324
|
banks_client.process_transaction(transaction).await.unwrap();
|
|
299
325
|
|
|
300
326
|
// Create token accounts
|
|
301
|
-
let sender_usdc = create_token_account(
|
|
302
|
-
|
|
303
|
-
|
|
327
|
+
let sender_usdc = create_token_account(
|
|
328
|
+
&mut banks_client,
|
|
329
|
+
&payer,
|
|
330
|
+
recent_blockhash,
|
|
331
|
+
&usdc_mint,
|
|
332
|
+
&payer.pubkey(),
|
|
333
|
+
)
|
|
334
|
+
.await;
|
|
335
|
+
let mailer_usdc = create_token_account(
|
|
336
|
+
&mut banks_client,
|
|
337
|
+
&payer,
|
|
338
|
+
recent_blockhash,
|
|
339
|
+
&usdc_mint,
|
|
340
|
+
&mailer_pda,
|
|
341
|
+
)
|
|
342
|
+
.await;
|
|
343
|
+
|
|
304
344
|
// Mint USDC to sender
|
|
305
|
-
mint_to(
|
|
345
|
+
mint_to(
|
|
346
|
+
&mut banks_client,
|
|
347
|
+
&payer,
|
|
348
|
+
recent_blockhash,
|
|
349
|
+
&usdc_mint,
|
|
350
|
+
&sender_usdc,
|
|
351
|
+
1_000_000,
|
|
352
|
+
)
|
|
353
|
+
.await;
|
|
306
354
|
|
|
307
355
|
// Get recipient claim PDA (needed even if not used for standard send)
|
|
308
356
|
let (recipient_claim_pda, _) = get_claim_pda(&payer.pubkey());
|
|
@@ -336,7 +384,8 @@ async fn test_send_standard_message() {
|
|
|
336
384
|
|
|
337
385
|
// Verify only owner fee was charged (10% of send_fee = 10,000)
|
|
338
386
|
let mailer_account = banks_client.get_account(mailer_pda).await.unwrap().unwrap();
|
|
339
|
-
let mailer_state: MailerState =
|
|
387
|
+
let mailer_state: MailerState =
|
|
388
|
+
BorshDeserialize::deserialize(&mut &mailer_account.data[8..]).unwrap();
|
|
340
389
|
assert_eq!(mailer_state.owner_claimable, 10_000); // Only 10% fee
|
|
341
390
|
}
|
|
342
391
|
|
|
@@ -352,7 +401,7 @@ async fn test_claim_recipient_share() {
|
|
|
352
401
|
// Setup and send priority message first (similar to previous test)
|
|
353
402
|
let usdc_mint = create_usdc_mint(&mut banks_client, &payer, recent_blockhash).await;
|
|
354
403
|
let (mailer_pda, _) = get_mailer_pda();
|
|
355
|
-
|
|
404
|
+
|
|
356
405
|
// Initialize
|
|
357
406
|
let init_instruction = Instruction::new_with_borsh(
|
|
358
407
|
program_id(),
|
|
@@ -369,11 +418,33 @@ async fn test_claim_recipient_share() {
|
|
|
369
418
|
banks_client.process_transaction(transaction).await.unwrap();
|
|
370
419
|
|
|
371
420
|
// Create token accounts
|
|
372
|
-
let sender_usdc = create_token_account(
|
|
373
|
-
|
|
374
|
-
|
|
421
|
+
let sender_usdc = create_token_account(
|
|
422
|
+
&mut banks_client,
|
|
423
|
+
&payer,
|
|
424
|
+
recent_blockhash,
|
|
425
|
+
&usdc_mint,
|
|
426
|
+
&payer.pubkey(),
|
|
427
|
+
)
|
|
428
|
+
.await;
|
|
429
|
+
let mailer_usdc = create_token_account(
|
|
430
|
+
&mut banks_client,
|
|
431
|
+
&payer,
|
|
432
|
+
recent_blockhash,
|
|
433
|
+
&usdc_mint,
|
|
434
|
+
&mailer_pda,
|
|
435
|
+
)
|
|
436
|
+
.await;
|
|
437
|
+
|
|
375
438
|
// Mint USDC
|
|
376
|
-
mint_to(
|
|
439
|
+
mint_to(
|
|
440
|
+
&mut banks_client,
|
|
441
|
+
&payer,
|
|
442
|
+
recent_blockhash,
|
|
443
|
+
&usdc_mint,
|
|
444
|
+
&sender_usdc,
|
|
445
|
+
1_000_000,
|
|
446
|
+
)
|
|
447
|
+
.await;
|
|
377
448
|
|
|
378
449
|
let (recipient_claim_pda, _) = get_claim_pda(&payer.pubkey());
|
|
379
450
|
|
|
@@ -385,7 +456,7 @@ async fn test_claim_recipient_share() {
|
|
|
385
456
|
subject: "Test".to_string(),
|
|
386
457
|
_body: "Test".to_string(),
|
|
387
458
|
revenue_share_to_receiver: true,
|
|
388
|
-
|
|
459
|
+
resolve_sender_to_name: false,
|
|
389
460
|
},
|
|
390
461
|
vec![
|
|
391
462
|
AccountMeta::new(payer.pubkey(), true),
|
|
@@ -403,7 +474,14 @@ async fn test_claim_recipient_share() {
|
|
|
403
474
|
banks_client.process_transaction(transaction).await.unwrap();
|
|
404
475
|
|
|
405
476
|
// Create recipient's own USDC account to receive the claim
|
|
406
|
-
let recipient_usdc = create_token_account(
|
|
477
|
+
let recipient_usdc = create_token_account(
|
|
478
|
+
&mut banks_client,
|
|
479
|
+
&payer,
|
|
480
|
+
recent_blockhash,
|
|
481
|
+
&usdc_mint,
|
|
482
|
+
&payer.pubkey(),
|
|
483
|
+
)
|
|
484
|
+
.await;
|
|
407
485
|
|
|
408
486
|
// Now claim the recipient share
|
|
409
487
|
let claim_instruction = Instruction::new_with_borsh(
|
|
@@ -424,12 +502,21 @@ async fn test_claim_recipient_share() {
|
|
|
424
502
|
banks_client.process_transaction(transaction).await.unwrap();
|
|
425
503
|
|
|
426
504
|
// Verify the claim was processed
|
|
427
|
-
let claim_account = banks_client
|
|
428
|
-
|
|
505
|
+
let claim_account = banks_client
|
|
506
|
+
.get_account(recipient_claim_pda)
|
|
507
|
+
.await
|
|
508
|
+
.unwrap()
|
|
509
|
+
.unwrap();
|
|
510
|
+
let recipient_claim: RecipientClaim =
|
|
511
|
+
BorshDeserialize::deserialize(&mut &claim_account.data[8..]).unwrap();
|
|
429
512
|
assert_eq!(recipient_claim.amount, 0); // Should be zero after claiming
|
|
430
513
|
|
|
431
514
|
// Verify tokens were transferred to recipient
|
|
432
|
-
let recipient_token_account = banks_client
|
|
515
|
+
let recipient_token_account = banks_client
|
|
516
|
+
.get_account(recipient_usdc)
|
|
517
|
+
.await
|
|
518
|
+
.unwrap()
|
|
519
|
+
.unwrap();
|
|
433
520
|
let token_account_data = TokenAccount::unpack(&recipient_token_account.data).unwrap();
|
|
434
521
|
assert_eq!(token_account_data.amount, 90_000); // 90% of 100,000
|
|
435
522
|
}
|
|
@@ -446,7 +533,7 @@ async fn test_claim_owner_share() {
|
|
|
446
533
|
// Setup and send a message to accumulate owner fees
|
|
447
534
|
let usdc_mint = create_usdc_mint(&mut banks_client, &payer, recent_blockhash).await;
|
|
448
535
|
let (mailer_pda, _) = get_mailer_pda();
|
|
449
|
-
|
|
536
|
+
|
|
450
537
|
// Initialize
|
|
451
538
|
let init_instruction = Instruction::new_with_borsh(
|
|
452
539
|
program_id(),
|
|
@@ -463,11 +550,40 @@ async fn test_claim_owner_share() {
|
|
|
463
550
|
banks_client.process_transaction(transaction).await.unwrap();
|
|
464
551
|
|
|
465
552
|
// Setup token accounts and send standard message to accumulate owner fees
|
|
466
|
-
let sender_usdc = create_token_account(
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
553
|
+
let sender_usdc = create_token_account(
|
|
554
|
+
&mut banks_client,
|
|
555
|
+
&payer,
|
|
556
|
+
recent_blockhash,
|
|
557
|
+
&usdc_mint,
|
|
558
|
+
&payer.pubkey(),
|
|
559
|
+
)
|
|
560
|
+
.await;
|
|
561
|
+
let mailer_usdc = create_token_account(
|
|
562
|
+
&mut banks_client,
|
|
563
|
+
&payer,
|
|
564
|
+
recent_blockhash,
|
|
565
|
+
&usdc_mint,
|
|
566
|
+
&mailer_pda,
|
|
567
|
+
)
|
|
568
|
+
.await;
|
|
569
|
+
let owner_usdc = create_token_account(
|
|
570
|
+
&mut banks_client,
|
|
571
|
+
&payer,
|
|
572
|
+
recent_blockhash,
|
|
573
|
+
&usdc_mint,
|
|
574
|
+
&payer.pubkey(),
|
|
575
|
+
)
|
|
576
|
+
.await;
|
|
577
|
+
|
|
578
|
+
mint_to(
|
|
579
|
+
&mut banks_client,
|
|
580
|
+
&payer,
|
|
581
|
+
recent_blockhash,
|
|
582
|
+
&usdc_mint,
|
|
583
|
+
&sender_usdc,
|
|
584
|
+
1_000_000,
|
|
585
|
+
)
|
|
586
|
+
.await;
|
|
471
587
|
|
|
472
588
|
let (recipient_claim_pda, _) = get_claim_pda(&payer.pubkey());
|
|
473
589
|
|
|
@@ -479,7 +595,7 @@ async fn test_claim_owner_share() {
|
|
|
479
595
|
subject: "Test".to_string(),
|
|
480
596
|
_body: "Test".to_string(),
|
|
481
597
|
revenue_share_to_receiver: false,
|
|
482
|
-
|
|
598
|
+
resolve_sender_to_name: false,
|
|
483
599
|
},
|
|
484
600
|
vec![
|
|
485
601
|
AccountMeta::new(payer.pubkey(), true),
|
|
@@ -515,7 +631,8 @@ async fn test_claim_owner_share() {
|
|
|
515
631
|
|
|
516
632
|
// Verify owner claimable was reset
|
|
517
633
|
let mailer_account = banks_client.get_account(mailer_pda).await.unwrap().unwrap();
|
|
518
|
-
let mailer_state: MailerState =
|
|
634
|
+
let mailer_state: MailerState =
|
|
635
|
+
BorshDeserialize::deserialize(&mut &mailer_account.data[8..]).unwrap();
|
|
519
636
|
assert_eq!(mailer_state.owner_claimable, 0);
|
|
520
637
|
|
|
521
638
|
// Verify tokens were transferred to owner
|
|
@@ -535,7 +652,7 @@ async fn test_set_fees() {
|
|
|
535
652
|
|
|
536
653
|
let usdc_mint = create_usdc_mint(&mut banks_client, &payer, recent_blockhash).await;
|
|
537
654
|
let (mailer_pda, _) = get_mailer_pda();
|
|
538
|
-
|
|
655
|
+
|
|
539
656
|
// Initialize
|
|
540
657
|
let init_instruction = Instruction::new_with_borsh(
|
|
541
658
|
program_id(),
|
|
@@ -561,32 +678,38 @@ async fn test_set_fees() {
|
|
|
561
678
|
],
|
|
562
679
|
);
|
|
563
680
|
|
|
564
|
-
let mut transaction =
|
|
681
|
+
let mut transaction =
|
|
682
|
+
Transaction::new_with_payer(&[set_fee_instruction], Some(&payer.pubkey()));
|
|
565
683
|
transaction.sign(&[&payer], recent_blockhash);
|
|
566
684
|
banks_client.process_transaction(transaction).await.unwrap();
|
|
567
685
|
|
|
568
686
|
// Verify fee was updated
|
|
569
687
|
let mailer_account = banks_client.get_account(mailer_pda).await.unwrap().unwrap();
|
|
570
|
-
let mailer_state: MailerState =
|
|
688
|
+
let mailer_state: MailerState =
|
|
689
|
+
BorshDeserialize::deserialize(&mut &mailer_account.data[8..]).unwrap();
|
|
571
690
|
assert_eq!(mailer_state.send_fee, 200_000);
|
|
572
691
|
|
|
573
692
|
// Test setting delegation fee
|
|
574
693
|
let set_delegation_fee_instruction = Instruction::new_with_borsh(
|
|
575
694
|
program_id(),
|
|
576
|
-
&MailerInstruction::SetDelegationFee {
|
|
695
|
+
&MailerInstruction::SetDelegationFee {
|
|
696
|
+
new_fee: 20_000_000,
|
|
697
|
+
},
|
|
577
698
|
vec![
|
|
578
699
|
AccountMeta::new(payer.pubkey(), true),
|
|
579
700
|
AccountMeta::new(mailer_pda, false),
|
|
580
701
|
],
|
|
581
702
|
);
|
|
582
703
|
|
|
583
|
-
let mut transaction =
|
|
704
|
+
let mut transaction =
|
|
705
|
+
Transaction::new_with_payer(&[set_delegation_fee_instruction], Some(&payer.pubkey()));
|
|
584
706
|
transaction.sign(&[&payer], recent_blockhash);
|
|
585
707
|
banks_client.process_transaction(transaction).await.unwrap();
|
|
586
708
|
|
|
587
709
|
// Verify delegation fee was updated
|
|
588
710
|
let mailer_account = banks_client.get_account(mailer_pda).await.unwrap().unwrap();
|
|
589
|
-
let mailer_state: MailerState =
|
|
711
|
+
let mailer_state: MailerState =
|
|
712
|
+
BorshDeserialize::deserialize(&mut &mailer_account.data[8..]).unwrap();
|
|
590
713
|
assert_eq!(mailer_state.delegation_fee, 20_000_000);
|
|
591
714
|
}
|
|
592
715
|
|
|
@@ -601,7 +724,7 @@ async fn test_delegation_functionality() {
|
|
|
601
724
|
|
|
602
725
|
let usdc_mint = create_usdc_mint(&mut banks_client, &payer, recent_blockhash).await;
|
|
603
726
|
let (mailer_pda, _) = get_mailer_pda();
|
|
604
|
-
|
|
727
|
+
|
|
605
728
|
// Initialize
|
|
606
729
|
let init_instruction = Instruction::new_with_borsh(
|
|
607
730
|
program_id(),
|
|
@@ -618,10 +741,32 @@ async fn test_delegation_functionality() {
|
|
|
618
741
|
banks_client.process_transaction(transaction).await.unwrap();
|
|
619
742
|
|
|
620
743
|
// Setup token accounts
|
|
621
|
-
let delegator_usdc = create_token_account(
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
744
|
+
let delegator_usdc = create_token_account(
|
|
745
|
+
&mut banks_client,
|
|
746
|
+
&payer,
|
|
747
|
+
recent_blockhash,
|
|
748
|
+
&usdc_mint,
|
|
749
|
+
&payer.pubkey(),
|
|
750
|
+
)
|
|
751
|
+
.await;
|
|
752
|
+
let mailer_usdc = create_token_account(
|
|
753
|
+
&mut banks_client,
|
|
754
|
+
&payer,
|
|
755
|
+
recent_blockhash,
|
|
756
|
+
&usdc_mint,
|
|
757
|
+
&mailer_pda,
|
|
758
|
+
)
|
|
759
|
+
.await;
|
|
760
|
+
|
|
761
|
+
mint_to(
|
|
762
|
+
&mut banks_client,
|
|
763
|
+
&payer,
|
|
764
|
+
recent_blockhash,
|
|
765
|
+
&usdc_mint,
|
|
766
|
+
&delegator_usdc,
|
|
767
|
+
50_000_000,
|
|
768
|
+
)
|
|
769
|
+
.await; // 50 USDC
|
|
625
770
|
|
|
626
771
|
let delegate = Keypair::new();
|
|
627
772
|
let (delegation_pda, _) = get_delegation_pda(&payer.pubkey());
|
|
@@ -643,13 +788,19 @@ async fn test_delegation_functionality() {
|
|
|
643
788
|
],
|
|
644
789
|
);
|
|
645
790
|
|
|
646
|
-
let mut transaction =
|
|
791
|
+
let mut transaction =
|
|
792
|
+
Transaction::new_with_payer(&[delegate_instruction], Some(&payer.pubkey()));
|
|
647
793
|
transaction.sign(&[&payer], recent_blockhash);
|
|
648
794
|
banks_client.process_transaction(transaction).await.unwrap();
|
|
649
795
|
|
|
650
796
|
// Verify delegation was created
|
|
651
|
-
let delegation_account = banks_client
|
|
652
|
-
|
|
797
|
+
let delegation_account = banks_client
|
|
798
|
+
.get_account(delegation_pda)
|
|
799
|
+
.await
|
|
800
|
+
.unwrap()
|
|
801
|
+
.unwrap();
|
|
802
|
+
let delegation: Delegation =
|
|
803
|
+
BorshDeserialize::deserialize(&mut &delegation_account.data[8..]).unwrap();
|
|
653
804
|
assert_eq!(delegation.delegator, payer.pubkey());
|
|
654
805
|
assert_eq!(delegation.delegate, Some(delegate.pubkey()));
|
|
655
806
|
|
|
@@ -662,6 +813,7 @@ async fn test_delegation_functionality() {
|
|
|
662
813
|
vec![
|
|
663
814
|
AccountMeta::new(delegate.pubkey(), true),
|
|
664
815
|
AccountMeta::new(delegation_pda, false),
|
|
816
|
+
AccountMeta::new_readonly(mailer_pda, false),
|
|
665
817
|
],
|
|
666
818
|
);
|
|
667
819
|
|
|
@@ -687,11 +839,25 @@ async fn test_error_conditions() {
|
|
|
687
839
|
|
|
688
840
|
let usdc_mint = create_usdc_mint(&mut banks_client, &payer, recent_blockhash).await;
|
|
689
841
|
let (mailer_pda, _) = get_mailer_pda();
|
|
690
|
-
|
|
842
|
+
|
|
691
843
|
// Test claiming with no claimable amount (should fail)
|
|
692
844
|
let (recipient_claim_pda, _) = get_claim_pda(&payer.pubkey());
|
|
693
|
-
let recipient_usdc = create_token_account(
|
|
694
|
-
|
|
845
|
+
let recipient_usdc = create_token_account(
|
|
846
|
+
&mut banks_client,
|
|
847
|
+
&payer,
|
|
848
|
+
recent_blockhash,
|
|
849
|
+
&usdc_mint,
|
|
850
|
+
&payer.pubkey(),
|
|
851
|
+
)
|
|
852
|
+
.await;
|
|
853
|
+
let mailer_usdc = create_token_account(
|
|
854
|
+
&mut banks_client,
|
|
855
|
+
&payer,
|
|
856
|
+
recent_blockhash,
|
|
857
|
+
&usdc_mint,
|
|
858
|
+
&mailer_pda,
|
|
859
|
+
)
|
|
860
|
+
.await;
|
|
695
861
|
|
|
696
862
|
let claim_instruction = Instruction::new_with_borsh(
|
|
697
863
|
program_id(),
|
|
@@ -708,8 +874,160 @@ async fn test_error_conditions() {
|
|
|
708
874
|
|
|
709
875
|
let mut transaction = Transaction::new_with_payer(&[claim_instruction], Some(&payer.pubkey()));
|
|
710
876
|
transaction.sign(&[&payer], recent_blockhash);
|
|
711
|
-
|
|
877
|
+
|
|
712
878
|
// This should fail because no claim exists
|
|
713
879
|
let result = banks_client.process_transaction(transaction).await;
|
|
714
880
|
assert!(result.is_err());
|
|
715
|
-
}
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
#[tokio::test]
|
|
884
|
+
async fn test_claim_expired_shares_moves_funds_to_owner() {
|
|
885
|
+
let program_test = ProgramTest::new(
|
|
886
|
+
"mailer",
|
|
887
|
+
program_id(),
|
|
888
|
+
processor!(mailer::process_instruction),
|
|
889
|
+
);
|
|
890
|
+
let mut context = program_test.start_with_context().await;
|
|
891
|
+
|
|
892
|
+
let mut recent_blockhash = context.last_blockhash;
|
|
893
|
+
|
|
894
|
+
// Create USDC mint and initialize the program
|
|
895
|
+
let usdc_mint =
|
|
896
|
+
create_usdc_mint(&mut context.banks_client, &context.payer, recent_blockhash).await;
|
|
897
|
+
recent_blockhash = context.banks_client.get_latest_blockhash().await.unwrap();
|
|
898
|
+
|
|
899
|
+
let (mailer_pda, _) = get_mailer_pda();
|
|
900
|
+
let init_instruction = Instruction::new_with_borsh(
|
|
901
|
+
program_id(),
|
|
902
|
+
&MailerInstruction::Initialize { usdc_mint },
|
|
903
|
+
vec![
|
|
904
|
+
AccountMeta::new(context.payer.pubkey(), true),
|
|
905
|
+
AccountMeta::new(mailer_pda, false),
|
|
906
|
+
AccountMeta::new_readonly(system_program::id(), false),
|
|
907
|
+
],
|
|
908
|
+
);
|
|
909
|
+
|
|
910
|
+
let mut transaction =
|
|
911
|
+
Transaction::new_with_payer(&[init_instruction], Some(&context.payer.pubkey()));
|
|
912
|
+
transaction.sign(&[&context.payer], recent_blockhash);
|
|
913
|
+
context
|
|
914
|
+
.banks_client
|
|
915
|
+
.process_transaction(transaction)
|
|
916
|
+
.await
|
|
917
|
+
.unwrap();
|
|
918
|
+
recent_blockhash = context.banks_client.get_latest_blockhash().await.unwrap();
|
|
919
|
+
|
|
920
|
+
// Prepare token accounts and fund the sender
|
|
921
|
+
let sender_usdc = create_token_account(
|
|
922
|
+
&mut context.banks_client,
|
|
923
|
+
&context.payer,
|
|
924
|
+
recent_blockhash,
|
|
925
|
+
&usdc_mint,
|
|
926
|
+
&context.payer.pubkey(),
|
|
927
|
+
)
|
|
928
|
+
.await;
|
|
929
|
+
recent_blockhash = context.banks_client.get_latest_blockhash().await.unwrap();
|
|
930
|
+
|
|
931
|
+
let mailer_usdc = create_token_account(
|
|
932
|
+
&mut context.banks_client,
|
|
933
|
+
&context.payer,
|
|
934
|
+
recent_blockhash,
|
|
935
|
+
&usdc_mint,
|
|
936
|
+
&mailer_pda,
|
|
937
|
+
)
|
|
938
|
+
.await;
|
|
939
|
+
recent_blockhash = context.banks_client.get_latest_blockhash().await.unwrap();
|
|
940
|
+
|
|
941
|
+
mint_to(
|
|
942
|
+
&mut context.banks_client,
|
|
943
|
+
&context.payer,
|
|
944
|
+
recent_blockhash,
|
|
945
|
+
&usdc_mint,
|
|
946
|
+
&sender_usdc,
|
|
947
|
+
1_000_000,
|
|
948
|
+
)
|
|
949
|
+
.await; // 1 USDC to cover priority message
|
|
950
|
+
recent_blockhash = context.banks_client.get_latest_blockhash().await.unwrap();
|
|
951
|
+
|
|
952
|
+
let (recipient_claim_pda, _) = get_claim_pda(&context.payer.pubkey());
|
|
953
|
+
|
|
954
|
+
// Send a priority message to create the claim record
|
|
955
|
+
let send_instruction = Instruction::new_with_borsh(
|
|
956
|
+
program_id(),
|
|
957
|
+
&MailerInstruction::Send {
|
|
958
|
+
to: context.payer.pubkey(),
|
|
959
|
+
subject: "Expired claim".to_string(),
|
|
960
|
+
_body: "Body".to_string(),
|
|
961
|
+
revenue_share_to_receiver: true,
|
|
962
|
+
resolve_sender_to_name: false,
|
|
963
|
+
},
|
|
964
|
+
vec![
|
|
965
|
+
AccountMeta::new(context.payer.pubkey(), true),
|
|
966
|
+
AccountMeta::new(recipient_claim_pda, false),
|
|
967
|
+
AccountMeta::new(mailer_pda, false),
|
|
968
|
+
AccountMeta::new(sender_usdc, false),
|
|
969
|
+
AccountMeta::new(mailer_usdc, false),
|
|
970
|
+
AccountMeta::new_readonly(spl_token::id(), false),
|
|
971
|
+
AccountMeta::new_readonly(system_program::id(), false),
|
|
972
|
+
],
|
|
973
|
+
);
|
|
974
|
+
|
|
975
|
+
let mut transaction =
|
|
976
|
+
Transaction::new_with_payer(&[send_instruction], Some(&context.payer.pubkey()));
|
|
977
|
+
transaction.sign(&[&context.payer], recent_blockhash);
|
|
978
|
+
context
|
|
979
|
+
.banks_client
|
|
980
|
+
.process_transaction(transaction)
|
|
981
|
+
.await
|
|
982
|
+
.unwrap();
|
|
983
|
+
recent_blockhash = context.banks_client.get_latest_blockhash().await.unwrap();
|
|
984
|
+
|
|
985
|
+
// Warp forward so the claim expires (claim period is 60 days)
|
|
986
|
+
context.warp_to_slot(20_000_000).unwrap();
|
|
987
|
+
recent_blockhash = context.banks_client.get_latest_blockhash().await.unwrap();
|
|
988
|
+
|
|
989
|
+
// Owner reclaims expired shares
|
|
990
|
+
let claim_expired_instruction = Instruction::new_with_borsh(
|
|
991
|
+
program_id(),
|
|
992
|
+
&MailerInstruction::ClaimExpiredShares {
|
|
993
|
+
recipient: context.payer.pubkey(),
|
|
994
|
+
},
|
|
995
|
+
vec![
|
|
996
|
+
AccountMeta::new(context.payer.pubkey(), true),
|
|
997
|
+
AccountMeta::new(mailer_pda, false),
|
|
998
|
+
AccountMeta::new(recipient_claim_pda, false),
|
|
999
|
+
],
|
|
1000
|
+
);
|
|
1001
|
+
|
|
1002
|
+
let mut transaction =
|
|
1003
|
+
Transaction::new_with_payer(&[claim_expired_instruction], Some(&context.payer.pubkey()));
|
|
1004
|
+
transaction.sign(&[&context.payer], recent_blockhash);
|
|
1005
|
+
context
|
|
1006
|
+
.banks_client
|
|
1007
|
+
.process_transaction(transaction)
|
|
1008
|
+
.await
|
|
1009
|
+
.unwrap();
|
|
1010
|
+
|
|
1011
|
+
// Recipient claim should be cleared
|
|
1012
|
+
let claim_account = context
|
|
1013
|
+
.banks_client
|
|
1014
|
+
.get_account(recipient_claim_pda)
|
|
1015
|
+
.await
|
|
1016
|
+
.unwrap()
|
|
1017
|
+
.unwrap();
|
|
1018
|
+
let claim_state: RecipientClaim =
|
|
1019
|
+
BorshDeserialize::deserialize(&mut &claim_account.data[8..]).unwrap();
|
|
1020
|
+
assert_eq!(claim_state.amount, 0);
|
|
1021
|
+
assert_eq!(claim_state.timestamp, 0);
|
|
1022
|
+
|
|
1023
|
+
// Owner claimable should now include both original owner share and reclaimed amount (total 100,000)
|
|
1024
|
+
let mailer_account = context
|
|
1025
|
+
.banks_client
|
|
1026
|
+
.get_account(mailer_pda)
|
|
1027
|
+
.await
|
|
1028
|
+
.unwrap()
|
|
1029
|
+
.unwrap();
|
|
1030
|
+
let mailer_state: MailerState =
|
|
1031
|
+
BorshDeserialize::deserialize(&mut &mailer_account.data[8..]).unwrap();
|
|
1032
|
+
assert_eq!(mailer_state.owner_claimable, 100_000);
|
|
1033
|
+
}
|