main.rs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. use anchor_client::solana_sdk::commitment_config::CommitmentConfig;
  2. use anchor_client::solana_sdk::pubkey::Pubkey;
  3. use anchor_client::solana_sdk::signature::read_keypair_file;
  4. use anchor_client::solana_sdk::signature::{Keypair, Signer};
  5. use anchor_client::solana_sdk::system_instruction;
  6. use anchor_client::solana_sdk::sysvar;
  7. use anchor_client::{Client, Cluster, EventContext};
  8. use anyhow::Result;
  9. // The `accounts` and `instructions` modules are generated by the framework.
  10. use basic_2::accounts as basic_2_accounts;
  11. use basic_2::instruction as basic_2_instruction;
  12. use basic_2::Counter;
  13. use events::instruction as events_instruction;
  14. use events::MyEvent;
  15. // The `accounts` and `instructions` modules are generated by the framework.
  16. use basic_4::accounts as basic_4_accounts;
  17. use basic_4::basic_4::Counter as CounterState;
  18. use basic_4::instruction as basic_4_instruction;
  19. // The `accounts` and `instructions` modules are generated by the framework.
  20. use clap::Clap;
  21. use composite::accounts::{Bar, CompositeUpdate, Foo, Initialize};
  22. use composite::instruction as composite_instruction;
  23. use composite::{DummyA, DummyB};
  24. use rand::rngs::OsRng;
  25. use std::time::Duration;
  26. #[derive(Clap)]
  27. pub struct Opts {
  28. #[clap(long)]
  29. composite_pid: Pubkey,
  30. #[clap(long)]
  31. basic_2_pid: Pubkey,
  32. #[clap(long)]
  33. basic_4_pid: Pubkey,
  34. #[clap(long)]
  35. events_pid: Pubkey,
  36. }
  37. // This example assumes a local validator is running with the programs
  38. // deployed at the addresses given by the CLI args.
  39. fn main() -> Result<()> {
  40. println!("Starting test...");
  41. let opts = Opts::parse();
  42. // Wallet and cluster params.
  43. let payer = read_keypair_file(&*shellexpand::tilde("~/.config/solana/id.json"))
  44. .expect("Example requires a keypair file");
  45. let url = Cluster::Custom(
  46. "http://localhost:8899".to_string(),
  47. "ws://127.0.0.1:8900".to_string(),
  48. );
  49. // Client.
  50. let client = Client::new_with_options(url, payer, CommitmentConfig::processed());
  51. // Run tests.
  52. composite(&client, opts.composite_pid)?;
  53. basic_2(&client, opts.basic_2_pid)?;
  54. basic_4(&client, opts.basic_4_pid)?;
  55. events(&client, opts.events_pid)?;
  56. // Success.
  57. Ok(())
  58. }
  59. // Runs a client for examples/tutorial/composite.
  60. //
  61. // Make sure to run a localnet with the program deploy to run this example.
  62. fn composite(client: &Client, pid: Pubkey) -> Result<()> {
  63. // Program client.
  64. let program = client.program(pid);
  65. // `Initialize` parameters.
  66. let dummy_a = Keypair::generate(&mut OsRng);
  67. let dummy_b = Keypair::generate(&mut OsRng);
  68. // Build and send a transaction.
  69. program
  70. .request()
  71. .instruction(system_instruction::create_account(
  72. &program.payer(),
  73. &dummy_a.pubkey(),
  74. program.rpc().get_minimum_balance_for_rent_exemption(500)?,
  75. 500,
  76. &program.id(),
  77. ))
  78. .instruction(system_instruction::create_account(
  79. &program.payer(),
  80. &dummy_b.pubkey(),
  81. program.rpc().get_minimum_balance_for_rent_exemption(500)?,
  82. 500,
  83. &program.id(),
  84. ))
  85. .signer(&dummy_a)
  86. .signer(&dummy_b)
  87. .accounts(Initialize {
  88. dummy_a: dummy_a.pubkey(),
  89. dummy_b: dummy_b.pubkey(),
  90. rent: sysvar::rent::ID,
  91. })
  92. .args(composite_instruction::Initialize)
  93. .send()?;
  94. // Assert the transaction worked.
  95. let dummy_a_account: DummyA = program.account(dummy_a.pubkey())?;
  96. let dummy_b_account: DummyB = program.account(dummy_b.pubkey())?;
  97. assert_eq!(dummy_a_account.data, 0);
  98. assert_eq!(dummy_b_account.data, 0);
  99. // Build and send another transaction, using composite account parameters.
  100. program
  101. .request()
  102. .accounts(CompositeUpdate {
  103. foo: Foo {
  104. dummy_a: dummy_a.pubkey(),
  105. },
  106. bar: Bar {
  107. dummy_b: dummy_b.pubkey(),
  108. },
  109. })
  110. .args(composite_instruction::CompositeUpdate {
  111. dummy_a: 1234,
  112. dummy_b: 4321,
  113. })
  114. .send()?;
  115. // Assert the transaction worked.
  116. let dummy_a_account: DummyA = program.account(dummy_a.pubkey())?;
  117. let dummy_b_account: DummyB = program.account(dummy_b.pubkey())?;
  118. assert_eq!(dummy_a_account.data, 1234);
  119. assert_eq!(dummy_b_account.data, 4321);
  120. println!("Composite success!");
  121. Ok(())
  122. }
  123. // Runs a client for examples/tutorial/basic-2.
  124. //
  125. // Make sure to run a localnet with the program deploy to run this example.
  126. fn basic_2(client: &Client, pid: Pubkey) -> Result<()> {
  127. let program = client.program(pid);
  128. // `Create` parameters.
  129. let counter = Keypair::generate(&mut OsRng);
  130. let authority = program.payer();
  131. // Build and send a transaction.
  132. program
  133. .request()
  134. .instruction(system_instruction::create_account(
  135. &authority,
  136. &counter.pubkey(),
  137. program.rpc().get_minimum_balance_for_rent_exemption(500)?,
  138. 500,
  139. &pid,
  140. ))
  141. .signer(&counter)
  142. .accounts(basic_2_accounts::Create {
  143. counter: counter.pubkey(),
  144. rent: sysvar::rent::ID,
  145. })
  146. .args(basic_2_instruction::Create { authority })
  147. .send()?;
  148. let counter_account: Counter = program.account(counter.pubkey())?;
  149. assert_eq!(counter_account.authority, authority);
  150. assert_eq!(counter_account.count, 0);
  151. println!("Basic 2 success!");
  152. Ok(())
  153. }
  154. fn events(client: &Client, pid: Pubkey) -> Result<()> {
  155. let program = client.program(pid);
  156. let (sender, receiver) = std::sync::mpsc::channel();
  157. let handle = program.on(move |_ctx: &EventContext, event: MyEvent| {
  158. sender.send(event).unwrap();
  159. })?;
  160. std::thread::sleep(Duration::from_millis(1000));
  161. program
  162. .request()
  163. .args(events_instruction::Initialize {})
  164. .send()?;
  165. let event = receiver.recv().unwrap();
  166. assert_eq!(event.data, 5);
  167. assert_eq!(event.label, "hello".to_string());
  168. // TODO: remove once https://github.com/solana-labs/solana/issues/16102
  169. // is addressed. Until then, drop the subscription handle in another
  170. // thread so that we deadlock in the other thread as to not block
  171. // this thread.
  172. std::thread::spawn(move || {
  173. drop(handle);
  174. });
  175. println!("Events success!");
  176. Ok(())
  177. }
  178. pub fn basic_4(client: &Client, pid: Pubkey) -> Result<()> {
  179. let program = client.program(pid);
  180. let authority = program.payer();
  181. // Invoke the state's `new` constructor.
  182. program
  183. .state_request()
  184. .accounts(basic_4_accounts::Auth { authority })
  185. .new(basic_4_instruction::state::New)
  186. .send()?;
  187. let counter_account: CounterState = program.state()?;
  188. assert_eq!(counter_account.authority, authority);
  189. assert_eq!(counter_account.count, 0);
  190. // Call a state method.
  191. program
  192. .state_request()
  193. .accounts(basic_4_accounts::Auth { authority })
  194. .args(basic_4_instruction::state::Increment)
  195. .send()?;
  196. let counter_account: CounterState = program.state()?;
  197. assert_eq!(counter_account.authority, authority);
  198. assert_eq!(counter_account.count, 1);
  199. println!("Basic 4 success!");
  200. Ok(())
  201. }