Skip to content

Commit 9a90cc6

Browse files
all tests passing, using latest methods from steel 2.1
1 parent 3663934 commit 9a90cc6

File tree

5 files changed

+180
-73
lines changed

5 files changed

+180
-73
lines changed

basics/transfer-sol/steel/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,5 @@ transfer-sol-api = { path = "./api", version = "0.1.0" }
1717
bytemuck = "1.14"
1818
num_enum = "0.7"
1919
solana-program = "1.18"
20-
# steel = { version = "1.3", features = ["spl"] }
2120
steel = "2.1"
2221
thiserror = "1.0"

basics/transfer-sol/steel/program/src/with_cpi.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use solana_program::msg;
2-
use solana_program::{program::invoke, system_instruction};
32
use steel::*;
43
use transfer_sol_api::prelude::*;
54

@@ -19,16 +18,7 @@ pub fn process_with_cpi(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramRes
1918
receiver_info.is_writable()?;
2019
system_program.is_program(&system_program::ID)?;
2120

22-
invoke(
23-
&system_instruction::transfer(&signer_info.key, &receiver_info.key, amount),
24-
&[
25-
signer_info.clone(),
26-
receiver_info.clone(),
27-
system_program.clone(),
28-
],
29-
)?;
30-
31-
// collect?
21+
receiver_info.collect(amount, signer_info)?;
3222

3323
Ok(())
3424
}

basics/transfer-sol/steel/program/src/with_program.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,7 @@ pub fn proces_with_program(accounts: &[AccountInfo<'_>], data: &[u8]) -> Program
1717
payer_info.is_writable()?;
1818
receiver_info.is_writable()?;
1919

20-
**payer_info.try_borrow_mut_lamports()? -= amount;
21-
**receiver_info.try_borrow_mut_lamports()? += amount;
22-
23-
// signer_info.send(amount, receiver_info);
24-
25-
// **payer.try_borrow_mut_lamports()? -= amount;
26-
// **recipient.try_borrow_mut_lamports()? += amount;
20+
payer_info.send(amount, receiver_info);
2721

2822
Ok(())
2923
}
Lines changed: 60 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
use std::vec;
2-
31
use solana_program::hash::Hash;
42

53
use solana_program_test::{processor, BanksClient, ProgramTest};
64
use solana_sdk::{
7-
config::program, lamports, native_token::LAMPORTS_PER_SOL, signature::Keypair, signer::Signer,
8-
transaction::Transaction,
5+
native_token::LAMPORTS_PER_SOL, signature::Keypair, signer::Signer, transaction::Transaction,
96
};
10-
use steel::*;
117
use transfer_sol_api::prelude::*;
128

139
async fn setup() -> (BanksClient, Keypair, Hash) {
@@ -21,28 +17,65 @@ async fn setup() -> (BanksClient, Keypair, Hash) {
2117
program_test.start().await
2218
}
2319

24-
// let system_program_id = &system_program::ID;
25-
// let key = Rc::new(*system_program_id);
26-
// let lamports = Rc::new(RefCell::new(0));
27-
// let data = Rc::new(RefCell::new(vec![]));
28-
// let owner = system_program_id;
29-
// let is_signer = false;
30-
// let is_writable = false;
31-
32-
// AccountInfo {
33-
// key: &*key,
34-
// is_signer,
35-
// is_writable,
36-
// lamports,
37-
// data,
38-
// owner,
39-
// executable: true,
40-
// rent_epoch: 0,
41-
// }
42-
// }
20+
#[tokio::test]
21+
async fn transfer_with_program_works() {
22+
// Setup test
23+
let (mut banks, payer, blockhash) = setup().await;
24+
25+
// 1 SOL
26+
let amount = 1 * LAMPORTS_PER_SOL;
27+
28+
// Generate a couple of keypairs to create accounts owned by our program
29+
let acc_1 = Keypair::new();
30+
let acc_2 = Keypair::new();
31+
32+
// Create the program accounts
33+
let create_account_instruction = |pubkey| {
34+
solana_program::system_instruction::create_account(
35+
&payer.pubkey(),
36+
pubkey,
37+
amount,
38+
0,
39+
&transfer_sol_api::ID,
40+
)
41+
};
42+
43+
let tx_create_accounts = Transaction::new_signed_with_payer(
44+
&[
45+
create_account_instruction(&acc_1.pubkey()),
46+
create_account_instruction(&acc_2.pubkey()),
47+
],
48+
Some(&payer.pubkey()),
49+
&[&payer, &acc_1, &acc_2],
50+
blockhash,
51+
);
52+
53+
let res = banks.process_transaction(tx_create_accounts).await;
54+
assert!(res.is_ok());
55+
56+
// Let's transfer some lamports from acc_1 to acc_2
57+
let latest_blockhash = banks.get_latest_blockhash().await.unwrap();
58+
59+
let ix = with_program(acc_1.pubkey(), acc_2.pubkey(), amount);
60+
let tx = Transaction::new_signed_with_payer(
61+
&[ix],
62+
Some(&payer.pubkey()),
63+
&[&payer],
64+
latest_blockhash,
65+
);
66+
67+
let res = banks.process_transaction(tx).await;
68+
assert!(res.is_ok());
69+
70+
// Now, let's check the balances
71+
let acc_1_balance = banks.get_balance(acc_1.pubkey()).await.unwrap();
72+
assert_eq!(acc_1_balance, 0);
73+
let acc_2_balance = banks.get_balance(acc_2.pubkey()).await.unwrap();
74+
assert_eq!(acc_2_balance, 2 * amount);
75+
}
4376

4477
#[tokio::test]
45-
async fn run_test() {
78+
async fn transfer_with_cpi_works() {
4679
// Setup test
4780
let (mut banks, payer, blockhash) = setup().await;
4881

@@ -58,33 +91,6 @@ async fn run_test() {
5891
let res = banks.process_transaction(tx).await;
5992
assert!(res.is_ok());
6093

61-
// // Verify counter was initialized.
62-
// let counter_address = counter_pda().0;
63-
// let counter_account = banks.get_account(counter_address).await.unwrap().unwrap();
64-
// let counter = Counter::try_from_bytes(&counter_account.data).unwrap();
65-
// assert_eq!(counter_account.owner, transfer_sol_api::ID);
66-
// assert_eq!(counter.value, 0);
67-
68-
// // Generate a new keypair to create an account owned by our program
69-
// let program_owned_account = Keypair::new();
70-
// let system_program_account = create_system_program_account_info();
71-
72-
// create_account(
73-
// &program_owned_account,
74-
// &system_program_account,
75-
// &payer.pubkey(),
76-
// &program::ID,
77-
// &[&payer, &system_program_account],
78-
// )?;
79-
80-
// // Submit transfer with program transaction.
81-
// let ix = with_program(payer.pubkey(), recipient.pubkey(), amount);
82-
// let tx = Transaction::new_signed_with_payer(&[ix], Some(&payer.pubkey()), &[&payer], blockhash);
83-
// let res = banks.process_transaction(tx).await;
84-
// assert!(res.is_ok());
85-
86-
// // Verify counter was incremented.
87-
// let counter_account = banks.get_account(counter_address).await.unwrap().unwrap();
88-
// let counter = Counter::try_from_bytes(&counter_account.data).unwrap();
89-
// assert_eq!(counter.value, 42);
94+
let balance = banks.get_balance(recipient.pubkey()).await.unwrap();
95+
assert_eq!(balance, amount);
9096
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import { Keypair, LAMPORTS_PER_SOL, PublicKey, SystemProgram, Transaction, TransactionInstruction } from '@solana/web3.js';
2+
import { assert } from 'chai';
3+
import { describe, it } from 'mocha';
4+
import { BanksClient, ProgramTestContext, start } from 'solana-bankrun';
5+
6+
const instructionDiscriminators = {
7+
withCpi: Buffer.from([0]),
8+
withProgram: Buffer.from([1]),
9+
};
10+
11+
describe('transfer sol', async () => {
12+
const PROGRAM_ID = new PublicKey('z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35');
13+
14+
let context: ProgramTestContext;
15+
let client: BanksClient;
16+
let payer: Keypair;
17+
18+
before(async () => {
19+
context = await start([{ name: 'transfer_sol_program', programId: PROGRAM_ID }], []);
20+
client = context.banksClient;
21+
payer = context.payer;
22+
});
23+
24+
it('should transfer between accounts using our program', async () => {
25+
// 1 SOL
26+
const amount = 1 * LAMPORTS_PER_SOL;
27+
28+
// Generate a couple of keypairs to create accounts owned by our program
29+
const acc1 = Keypair.generate();
30+
const acc2 = Keypair.generate();
31+
32+
const createAccountIx = (pubkey: PublicKey) => {
33+
return SystemProgram.createAccount({
34+
fromPubkey: payer.publicKey,
35+
newAccountPubkey: pubkey,
36+
space: 0,
37+
lamports: 2 * LAMPORTS_PER_SOL,
38+
programId: PROGRAM_ID,
39+
});
40+
};
41+
42+
// Create the accounts
43+
const createAccountsTx = new Transaction();
44+
createAccountsTx.recentBlockhash = context.lastBlockhash;
45+
createAccountsTx.add(createAccountIx(acc1.publicKey)).add(createAccountIx(acc2.publicKey)).sign(payer, acc1, acc2);
46+
47+
await client.processTransaction(createAccountsTx);
48+
49+
// Prepare the transfer instruction
50+
const amountBuffer = Buffer.alloc(8);
51+
amountBuffer.writeBigInt64LE(BigInt(amount), 0);
52+
53+
const data = Buffer.concat([instructionDiscriminators.withProgram, amountBuffer]);
54+
55+
const ix = new TransactionInstruction({
56+
programId: PROGRAM_ID,
57+
keys: [
58+
{ pubkey: acc1.publicKey, isSigner: false, isWritable: true },
59+
{ pubkey: acc2.publicKey, isSigner: false, isWritable: true },
60+
],
61+
data,
62+
});
63+
64+
// Prepare the transaction
65+
const [blockHash, _] = await client.getLatestBlockhash();
66+
const tx = new Transaction();
67+
tx.recentBlockhash = blockHash;
68+
tx.add(ix).sign(payer);
69+
70+
// Check initial balance
71+
const initialRecipientBalance = await client.getBalance(acc2.publicKey);
72+
73+
// Execute the transaction
74+
await client.processTransaction(tx);
75+
76+
// Check the balance
77+
const finalRecipientBalance = await client.getBalance(acc2.publicKey);
78+
assert.equal(finalRecipientBalance, initialRecipientBalance + BigInt(amount));
79+
});
80+
81+
it('should transfer between accounts using the system programa', async () => {
82+
// 1 SOL
83+
const amount = 1 * LAMPORTS_PER_SOL;
84+
85+
// Generate a new keypair for the recipient
86+
const recipient = Keypair.generate();
87+
88+
const amountBuffer = Buffer.alloc(8);
89+
amountBuffer.writeBigInt64LE(BigInt(amount), 0);
90+
91+
// Prepare the instruction
92+
const data = Buffer.concat([instructionDiscriminators.withCpi, amountBuffer]);
93+
94+
console.log(data);
95+
96+
const ix = new TransactionInstruction({
97+
programId: PROGRAM_ID,
98+
keys: [
99+
{ pubkey: payer.publicKey, isSigner: true, isWritable: true },
100+
{ pubkey: recipient.publicKey, isSigner: false, isWritable: true },
101+
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
102+
],
103+
data,
104+
});
105+
106+
// Prepare the transaction
107+
const tx = new Transaction();
108+
tx.recentBlockhash = context.lastBlockhash;
109+
tx.add(ix).sign(payer);
110+
111+
// Execute the transaction
112+
await client.processTransaction(tx);
113+
114+
// Check the balance
115+
const recipientBalance = await client.getBalance(recipient.publicKey);
116+
assert.equal(recipientBalance, BigInt(amount));
117+
});
118+
});

0 commit comments

Comments
 (0)