pub struct Client {
    pub client: RpcClient,
    pub payer: Keypair,
}

Fields§

§client: RpcClient§payer: Keypair

Implementations§

Examples found in repository?
src/client.rs (line 79)
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
    pub fn get_return_data<T: ProgramLogsDeserializable>(
        &self,
        ix: Instruction,
    ) -> ClientResult<T> {
        // let result = self.simulate_transaction(&[ix.clone()], &[self.payer()])?;

        // After we can upgrade our Solana SDK version to 1.14.0 we can just use the below code:
        // let data = result.logs;
        // Ok(T::try_from_slice(logs, &data)
        //     .map_err(|_| ClientError::DeserializationError)?)
        //
        // But for the time being since RpcSimulateTransactionResult.data does not exist yet,
        // We can only parse the logs ourselves to find the return_data
        let logs = self.get_instruction_logs(ix.clone())?;
        T::try_from_program_logs(logs, &ix.program_id)
            .map_err(|_| ClientError::DeserializationError)
    }
Examples found in repository?
src/client.rs (line 85)
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
    pub fn get_instruction_logs(&self, ix: Instruction) -> ClientResult<Vec<String>> {
        let result = self.simulate_transaction(&[ix], &[self.payer()])?;
        let logs = result.logs.ok_or(ClientError::DeserializationError)?;
        Ok(logs)
    }

    pub fn payer(&self) -> &Keypair {
        &self.payer
    }

    pub fn payer_pubkey(&self) -> Pubkey {
        self.payer.pubkey()
    }

    pub fn latest_blockhash(&self) -> ClientResult<Hash> {
        Ok(self.client.get_latest_blockhash()?)
    }

    pub fn airdrop(&self, to_pubkey: &Pubkey, lamports: u64) -> ClientResult<Signature> {
        let blockhash = self.client.get_latest_blockhash()?;
        let signature = self.request_airdrop_with_blockhash(to_pubkey, lamports, &blockhash)?;
        self.confirm_transaction_with_spinner(&signature, &blockhash, self.commitment())?;
        Ok(signature)
    }

    pub fn send<T: Signers>(&self, ixs: &[Instruction], signers: &T) -> ClientResult<Signature> {
        let mut tx = Transaction::new_with_payer(ixs, Some(&self.payer_pubkey()));
        tx.sign(signers, self.latest_blockhash()?);
        Ok(self.send_transaction(&tx)?)
    }

    pub fn send_with_config<T: Signers>(
        &self,
        ixs: &[Instruction],
        signers: &T,
        config: RpcSendTransactionConfig,
    ) -> ClientResult<Signature> {
        let tx = self.transaction(ixs, signers)?;
        Ok(self.client.send_transaction_with_config(&tx, config)?)
    }

    pub fn send_and_confirm<T: Signers>(
        &self,
        ixs: &[Instruction],
        signers: &T,
    ) -> ClientResult<Signature> {
        let tx = self.transaction(ixs, signers)?;
        Ok(self.send_and_confirm_transaction(&tx)?)
    }

    pub fn simulate_transaction<T: Signers>(
        &self,
        ixs: &[Instruction],
        signers: &T,
    ) -> ClientResult<RpcSimulateTransactionResult> {
        let tx = self.transaction(ixs, signers)?;
        let result = self.client.simulate_transaction(&tx)?;
        if result.value.err.is_some() {
            Err(ClientError::DeserializationError)
        } else {
            Ok(result.value)
        }
    }

    fn transaction<T: Signers>(&self,
                               ixs: &[Instruction],
                               signers: &T) -> ClientResult<Transaction> {
        let mut tx = Transaction::new_with_payer(
            ixs,
            Some(&self.payer_pubkey()),
        );
        tx.sign(signers, self.latest_blockhash()?);
        Ok(tx)
    }
}

impl Debug for Client {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "RPC client payer {}", self.payer_pubkey())
    }
}

impl Deref for Client {
    type Target = RpcClient;

    fn deref(&self) -> &Self::Target {
        &self.client
    }
}

impl DerefMut for Client {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.client
    }
}

pub trait SplToken {
    fn create_token_mint(&self, owner: &Pubkey, decimals: u8) -> ClientResult<Keypair>;
    fn create_token_account(&self, owner: &Pubkey, token_mint: &Pubkey) -> ClientResult<Keypair>;
    fn create_token_account_with_lamports(
        &self,
        owner: &Pubkey,
        token_mint: &Pubkey,
        lamports: u64,
    ) -> ClientResult<Keypair>;
    fn mint_to(
        &self,
        owner: &Keypair,
        token_mint: &Pubkey,
        account: &Pubkey,
        amount: u64,
        decimals: u8,
    ) -> ClientResult<()>;
    fn transfer_to(
        &self,
        owner: &Keypair,
        token_mint: &Pubkey,
        source: &Pubkey,
        destination: &Pubkey,
        amount: u64,
        decimals: u8,
    ) -> ClientResult<()>;
    fn get_associated_token_address(wallet_address: &Pubkey, token_mint: &Pubkey) -> Pubkey;
    fn create_associated_token_account(
        &self,
        funder: &Keypair,
        recipient: &Pubkey,
        token_mint: &Pubkey,
    ) -> ClientResult<Pubkey>;
    fn create_associated_token_account_by_payer(
        &self,
        recipient: &Pubkey,
        token_mint: &Pubkey,
    ) -> ClientResult<Pubkey>;
    fn close_token_account(
        &self,
        owner: &Keypair,
        account: &Pubkey,
        destination: &Pubkey,
    ) -> ClientResult<()>;
}

impl SplToken for Client {
    fn create_token_mint(&self, owner: &Pubkey, decimals: u8) -> ClientResult<Keypair> {
        let token_mint = Keypair::new();

        let mut transaction = Transaction::new_with_payer(
            &[
                system_instruction::create_account(
                    &self.payer_pubkey(),
                    &token_mint.pubkey(),
                    self.get_minimum_balance_for_rent_exemption(Mint::LEN)?,
                    Mint::LEN as u64,
                    &spl_token::id(),
                ),
                spl_token::instruction::initialize_mint(
                    &spl_token::id(),
                    &token_mint.pubkey(),
                    owner,
                    None,
                    decimals,
                )?,
            ],
            Some(&self.payer_pubkey()),
        );
        transaction.sign(&[self.payer(), &token_mint], self.latest_blockhash()?);
        self.send_and_confirm_transaction(&transaction)?;

        Ok(token_mint)
    }
    fn create_token_account(&self, owner: &Pubkey, token_mint: &Pubkey) -> ClientResult<Keypair> {
        self.create_token_account_with_lamports(
            owner,
            token_mint,
            self.get_minimum_balance_for_rent_exemption(TokenAccount::LEN)?,
        )
    }
    fn create_token_account_with_lamports(
        &self,
        owner: &Pubkey,
        token_mint: &Pubkey,
        lamports: u64,
    ) -> ClientResult<Keypair> {
        let token_account = Keypair::new();

        let mut transaction = Transaction::new_with_payer(
            &[
                system_instruction::create_account(
                    &self.payer_pubkey(),
                    &token_account.pubkey(),
                    lamports,
                    TokenAccount::LEN as u64,
                    &spl_token::id(),
                ),
                spl_token::instruction::initialize_account(
                    &spl_token::id(),
                    &token_account.pubkey(),
                    token_mint,
                    owner,
                )?,
            ],
            Some(&self.payer_pubkey()),
        );
        transaction.sign(&[self.payer(), &token_account], self.latest_blockhash()?);
        self.send_and_confirm_transaction(&transaction)?;

        Ok(token_account)
    }
    fn mint_to(
        &self,
        owner: &Keypair,
        token_mint: &Pubkey,
        account: &Pubkey,
        amount: u64,
        decimals: u8,
    ) -> ClientResult<()> {
        let mut transaction = Transaction::new_with_payer(
            &[spl_token::instruction::mint_to_checked(
                &spl_token::id(),
                token_mint,
                account,
                &owner.pubkey(),
                &[],
                amount,
                decimals,
            )?],
            Some(&self.payer_pubkey()),
        );
        transaction.sign(&[self.payer(), owner], self.latest_blockhash()?);
        self.send_and_confirm_transaction(&transaction)?;

        Ok(())
    }

    fn transfer_to(
        &self,
        authority: &Keypair,
        token_mint: &Pubkey,
        source: &Pubkey,
        destination: &Pubkey,
        amount: u64,
        decimals: u8,
    ) -> ClientResult<()> {
        let mut transaction = Transaction::new_with_payer(
            &[spl_token::instruction::transfer_checked(
                &spl_token::id(),
                source,
                token_mint,
                destination,
                &authority.pubkey(),
                &[],
                amount,
                decimals,
            )?],
            Some(&self.payer_pubkey()),
        );
        transaction.sign(&[self.payer(), authority], self.latest_blockhash()?);
        self.send_and_confirm_transaction(&transaction)?;

        Ok(())
    }
    fn get_associated_token_address(wallet_address: &Pubkey, token_mint: &Pubkey) -> Pubkey {
        spl_associated_token_account::get_associated_token_address(wallet_address, token_mint)
    }

    fn create_associated_token_account(
        &self,
        funder: &Keypair,
        recipient: &Pubkey,
        token_mint: &Pubkey,
    ) -> ClientResult<Pubkey> {
        let mut transaction = Transaction::new_with_payer(
            &[
                spl_associated_token_account::instruction::create_associated_token_account(
                    &funder.pubkey(),
                    recipient,
                    token_mint,
                    &anchor_spl::token::ID,
                ),
            ],
            Some(&self.payer_pubkey()),
        );
        if funder.pubkey() == self.payer_pubkey() {
            transaction.sign(&[self.payer()], self.latest_blockhash()?);
        } else {
            transaction.sign(&[self.payer(), funder], self.latest_blockhash()?);
        };
        self.send_and_confirm_transaction(&transaction)?;

        Ok(Self::get_associated_token_address(recipient, token_mint))
    }

    fn create_associated_token_account_by_payer(
        &self,
        recipient: &Pubkey,
        token_mint: &Pubkey,
    ) -> ClientResult<Pubkey> {
        self.create_associated_token_account(self.payer(), recipient, token_mint)
    }

    fn close_token_account(
        &self,
        owner: &Keypair,
        account: &Pubkey,
        destination: &Pubkey,
    ) -> ClientResult<()> {
        let mut transaction = Transaction::new_with_payer(
            &[spl_token::instruction::close_account(
                &spl_token::id(),
                account,
                destination,
                &owner.pubkey(),
                &[],
            )?],
            Some(&self.payer_pubkey()),
        );
        transaction.sign(&[self.payer(), owner], self.latest_blockhash()?);
        self.send_and_confirm_transaction(&transaction)?;

        Ok(())
    }
Examples found in repository?
src/client.rs (line 110)
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
    pub fn send<T: Signers>(&self, ixs: &[Instruction], signers: &T) -> ClientResult<Signature> {
        let mut tx = Transaction::new_with_payer(ixs, Some(&self.payer_pubkey()));
        tx.sign(signers, self.latest_blockhash()?);
        Ok(self.send_transaction(&tx)?)
    }

    pub fn send_with_config<T: Signers>(
        &self,
        ixs: &[Instruction],
        signers: &T,
        config: RpcSendTransactionConfig,
    ) -> ClientResult<Signature> {
        let tx = self.transaction(ixs, signers)?;
        Ok(self.client.send_transaction_with_config(&tx, config)?)
    }

    pub fn send_and_confirm<T: Signers>(
        &self,
        ixs: &[Instruction],
        signers: &T,
    ) -> ClientResult<Signature> {
        let tx = self.transaction(ixs, signers)?;
        Ok(self.send_and_confirm_transaction(&tx)?)
    }

    pub fn simulate_transaction<T: Signers>(
        &self,
        ixs: &[Instruction],
        signers: &T,
    ) -> ClientResult<RpcSimulateTransactionResult> {
        let tx = self.transaction(ixs, signers)?;
        let result = self.client.simulate_transaction(&tx)?;
        if result.value.err.is_some() {
            Err(ClientError::DeserializationError)
        } else {
            Ok(result.value)
        }
    }

    fn transaction<T: Signers>(&self,
                               ixs: &[Instruction],
                               signers: &T) -> ClientResult<Transaction> {
        let mut tx = Transaction::new_with_payer(
            ixs,
            Some(&self.payer_pubkey()),
        );
        tx.sign(signers, self.latest_blockhash()?);
        Ok(tx)
    }
}

impl Debug for Client {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "RPC client payer {}", self.payer_pubkey())
    }
}

impl Deref for Client {
    type Target = RpcClient;

    fn deref(&self) -> &Self::Target {
        &self.client
    }
}

impl DerefMut for Client {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.client
    }
}

pub trait SplToken {
    fn create_token_mint(&self, owner: &Pubkey, decimals: u8) -> ClientResult<Keypair>;
    fn create_token_account(&self, owner: &Pubkey, token_mint: &Pubkey) -> ClientResult<Keypair>;
    fn create_token_account_with_lamports(
        &self,
        owner: &Pubkey,
        token_mint: &Pubkey,
        lamports: u64,
    ) -> ClientResult<Keypair>;
    fn mint_to(
        &self,
        owner: &Keypair,
        token_mint: &Pubkey,
        account: &Pubkey,
        amount: u64,
        decimals: u8,
    ) -> ClientResult<()>;
    fn transfer_to(
        &self,
        owner: &Keypair,
        token_mint: &Pubkey,
        source: &Pubkey,
        destination: &Pubkey,
        amount: u64,
        decimals: u8,
    ) -> ClientResult<()>;
    fn get_associated_token_address(wallet_address: &Pubkey, token_mint: &Pubkey) -> Pubkey;
    fn create_associated_token_account(
        &self,
        funder: &Keypair,
        recipient: &Pubkey,
        token_mint: &Pubkey,
    ) -> ClientResult<Pubkey>;
    fn create_associated_token_account_by_payer(
        &self,
        recipient: &Pubkey,
        token_mint: &Pubkey,
    ) -> ClientResult<Pubkey>;
    fn close_token_account(
        &self,
        owner: &Keypair,
        account: &Pubkey,
        destination: &Pubkey,
    ) -> ClientResult<()>;
}

impl SplToken for Client {
    fn create_token_mint(&self, owner: &Pubkey, decimals: u8) -> ClientResult<Keypair> {
        let token_mint = Keypair::new();

        let mut transaction = Transaction::new_with_payer(
            &[
                system_instruction::create_account(
                    &self.payer_pubkey(),
                    &token_mint.pubkey(),
                    self.get_minimum_balance_for_rent_exemption(Mint::LEN)?,
                    Mint::LEN as u64,
                    &spl_token::id(),
                ),
                spl_token::instruction::initialize_mint(
                    &spl_token::id(),
                    &token_mint.pubkey(),
                    owner,
                    None,
                    decimals,
                )?,
            ],
            Some(&self.payer_pubkey()),
        );
        transaction.sign(&[self.payer(), &token_mint], self.latest_blockhash()?);
        self.send_and_confirm_transaction(&transaction)?;

        Ok(token_mint)
    }
    fn create_token_account(&self, owner: &Pubkey, token_mint: &Pubkey) -> ClientResult<Keypair> {
        self.create_token_account_with_lamports(
            owner,
            token_mint,
            self.get_minimum_balance_for_rent_exemption(TokenAccount::LEN)?,
        )
    }
    fn create_token_account_with_lamports(
        &self,
        owner: &Pubkey,
        token_mint: &Pubkey,
        lamports: u64,
    ) -> ClientResult<Keypair> {
        let token_account = Keypair::new();

        let mut transaction = Transaction::new_with_payer(
            &[
                system_instruction::create_account(
                    &self.payer_pubkey(),
                    &token_account.pubkey(),
                    lamports,
                    TokenAccount::LEN as u64,
                    &spl_token::id(),
                ),
                spl_token::instruction::initialize_account(
                    &spl_token::id(),
                    &token_account.pubkey(),
                    token_mint,
                    owner,
                )?,
            ],
            Some(&self.payer_pubkey()),
        );
        transaction.sign(&[self.payer(), &token_account], self.latest_blockhash()?);
        self.send_and_confirm_transaction(&transaction)?;

        Ok(token_account)
    }
    fn mint_to(
        &self,
        owner: &Keypair,
        token_mint: &Pubkey,
        account: &Pubkey,
        amount: u64,
        decimals: u8,
    ) -> ClientResult<()> {
        let mut transaction = Transaction::new_with_payer(
            &[spl_token::instruction::mint_to_checked(
                &spl_token::id(),
                token_mint,
                account,
                &owner.pubkey(),
                &[],
                amount,
                decimals,
            )?],
            Some(&self.payer_pubkey()),
        );
        transaction.sign(&[self.payer(), owner], self.latest_blockhash()?);
        self.send_and_confirm_transaction(&transaction)?;

        Ok(())
    }

    fn transfer_to(
        &self,
        authority: &Keypair,
        token_mint: &Pubkey,
        source: &Pubkey,
        destination: &Pubkey,
        amount: u64,
        decimals: u8,
    ) -> ClientResult<()> {
        let mut transaction = Transaction::new_with_payer(
            &[spl_token::instruction::transfer_checked(
                &spl_token::id(),
                source,
                token_mint,
                destination,
                &authority.pubkey(),
                &[],
                amount,
                decimals,
            )?],
            Some(&self.payer_pubkey()),
        );
        transaction.sign(&[self.payer(), authority], self.latest_blockhash()?);
        self.send_and_confirm_transaction(&transaction)?;

        Ok(())
    }
    fn get_associated_token_address(wallet_address: &Pubkey, token_mint: &Pubkey) -> Pubkey {
        spl_associated_token_account::get_associated_token_address(wallet_address, token_mint)
    }

    fn create_associated_token_account(
        &self,
        funder: &Keypair,
        recipient: &Pubkey,
        token_mint: &Pubkey,
    ) -> ClientResult<Pubkey> {
        let mut transaction = Transaction::new_with_payer(
            &[
                spl_associated_token_account::instruction::create_associated_token_account(
                    &funder.pubkey(),
                    recipient,
                    token_mint,
                    &anchor_spl::token::ID,
                ),
            ],
            Some(&self.payer_pubkey()),
        );
        if funder.pubkey() == self.payer_pubkey() {
            transaction.sign(&[self.payer()], self.latest_blockhash()?);
        } else {
            transaction.sign(&[self.payer(), funder], self.latest_blockhash()?);
        };
        self.send_and_confirm_transaction(&transaction)?;

        Ok(Self::get_associated_token_address(recipient, token_mint))
    }

    fn create_associated_token_account_by_payer(
        &self,
        recipient: &Pubkey,
        token_mint: &Pubkey,
    ) -> ClientResult<Pubkey> {
        self.create_associated_token_account(self.payer(), recipient, token_mint)
    }

    fn close_token_account(
        &self,
        owner: &Keypair,
        account: &Pubkey,
        destination: &Pubkey,
    ) -> ClientResult<()> {
        let mut transaction = Transaction::new_with_payer(
            &[spl_token::instruction::close_account(
                &spl_token::id(),
                account,
                destination,
                &owner.pubkey(),
                &[],
            )?],
            Some(&self.payer_pubkey()),
        );
        transaction.sign(&[self.payer(), owner], self.latest_blockhash()?);
        self.send_and_confirm_transaction(&transaction)?;

        Ok(())
    }
Examples found in repository?
src/client.rs (line 111)
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
    pub fn send<T: Signers>(&self, ixs: &[Instruction], signers: &T) -> ClientResult<Signature> {
        let mut tx = Transaction::new_with_payer(ixs, Some(&self.payer_pubkey()));
        tx.sign(signers, self.latest_blockhash()?);
        Ok(self.send_transaction(&tx)?)
    }

    pub fn send_with_config<T: Signers>(
        &self,
        ixs: &[Instruction],
        signers: &T,
        config: RpcSendTransactionConfig,
    ) -> ClientResult<Signature> {
        let tx = self.transaction(ixs, signers)?;
        Ok(self.client.send_transaction_with_config(&tx, config)?)
    }

    pub fn send_and_confirm<T: Signers>(
        &self,
        ixs: &[Instruction],
        signers: &T,
    ) -> ClientResult<Signature> {
        let tx = self.transaction(ixs, signers)?;
        Ok(self.send_and_confirm_transaction(&tx)?)
    }

    pub fn simulate_transaction<T: Signers>(
        &self,
        ixs: &[Instruction],
        signers: &T,
    ) -> ClientResult<RpcSimulateTransactionResult> {
        let tx = self.transaction(ixs, signers)?;
        let result = self.client.simulate_transaction(&tx)?;
        if result.value.err.is_some() {
            Err(ClientError::DeserializationError)
        } else {
            Ok(result.value)
        }
    }

    fn transaction<T: Signers>(&self,
                               ixs: &[Instruction],
                               signers: &T) -> ClientResult<Transaction> {
        let mut tx = Transaction::new_with_payer(
            ixs,
            Some(&self.payer_pubkey()),
        );
        tx.sign(signers, self.latest_blockhash()?);
        Ok(tx)
    }
}

impl Debug for Client {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "RPC client payer {}", self.payer_pubkey())
    }
}

impl Deref for Client {
    type Target = RpcClient;

    fn deref(&self) -> &Self::Target {
        &self.client
    }
}

impl DerefMut for Client {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.client
    }
}

pub trait SplToken {
    fn create_token_mint(&self, owner: &Pubkey, decimals: u8) -> ClientResult<Keypair>;
    fn create_token_account(&self, owner: &Pubkey, token_mint: &Pubkey) -> ClientResult<Keypair>;
    fn create_token_account_with_lamports(
        &self,
        owner: &Pubkey,
        token_mint: &Pubkey,
        lamports: u64,
    ) -> ClientResult<Keypair>;
    fn mint_to(
        &self,
        owner: &Keypair,
        token_mint: &Pubkey,
        account: &Pubkey,
        amount: u64,
        decimals: u8,
    ) -> ClientResult<()>;
    fn transfer_to(
        &self,
        owner: &Keypair,
        token_mint: &Pubkey,
        source: &Pubkey,
        destination: &Pubkey,
        amount: u64,
        decimals: u8,
    ) -> ClientResult<()>;
    fn get_associated_token_address(wallet_address: &Pubkey, token_mint: &Pubkey) -> Pubkey;
    fn create_associated_token_account(
        &self,
        funder: &Keypair,
        recipient: &Pubkey,
        token_mint: &Pubkey,
    ) -> ClientResult<Pubkey>;
    fn create_associated_token_account_by_payer(
        &self,
        recipient: &Pubkey,
        token_mint: &Pubkey,
    ) -> ClientResult<Pubkey>;
    fn close_token_account(
        &self,
        owner: &Keypair,
        account: &Pubkey,
        destination: &Pubkey,
    ) -> ClientResult<()>;
}

impl SplToken for Client {
    fn create_token_mint(&self, owner: &Pubkey, decimals: u8) -> ClientResult<Keypair> {
        let token_mint = Keypair::new();

        let mut transaction = Transaction::new_with_payer(
            &[
                system_instruction::create_account(
                    &self.payer_pubkey(),
                    &token_mint.pubkey(),
                    self.get_minimum_balance_for_rent_exemption(Mint::LEN)?,
                    Mint::LEN as u64,
                    &spl_token::id(),
                ),
                spl_token::instruction::initialize_mint(
                    &spl_token::id(),
                    &token_mint.pubkey(),
                    owner,
                    None,
                    decimals,
                )?,
            ],
            Some(&self.payer_pubkey()),
        );
        transaction.sign(&[self.payer(), &token_mint], self.latest_blockhash()?);
        self.send_and_confirm_transaction(&transaction)?;

        Ok(token_mint)
    }
    fn create_token_account(&self, owner: &Pubkey, token_mint: &Pubkey) -> ClientResult<Keypair> {
        self.create_token_account_with_lamports(
            owner,
            token_mint,
            self.get_minimum_balance_for_rent_exemption(TokenAccount::LEN)?,
        )
    }
    fn create_token_account_with_lamports(
        &self,
        owner: &Pubkey,
        token_mint: &Pubkey,
        lamports: u64,
    ) -> ClientResult<Keypair> {
        let token_account = Keypair::new();

        let mut transaction = Transaction::new_with_payer(
            &[
                system_instruction::create_account(
                    &self.payer_pubkey(),
                    &token_account.pubkey(),
                    lamports,
                    TokenAccount::LEN as u64,
                    &spl_token::id(),
                ),
                spl_token::instruction::initialize_account(
                    &spl_token::id(),
                    &token_account.pubkey(),
                    token_mint,
                    owner,
                )?,
            ],
            Some(&self.payer_pubkey()),
        );
        transaction.sign(&[self.payer(), &token_account], self.latest_blockhash()?);
        self.send_and_confirm_transaction(&transaction)?;

        Ok(token_account)
    }
    fn mint_to(
        &self,
        owner: &Keypair,
        token_mint: &Pubkey,
        account: &Pubkey,
        amount: u64,
        decimals: u8,
    ) -> ClientResult<()> {
        let mut transaction = Transaction::new_with_payer(
            &[spl_token::instruction::mint_to_checked(
                &spl_token::id(),
                token_mint,
                account,
                &owner.pubkey(),
                &[],
                amount,
                decimals,
            )?],
            Some(&self.payer_pubkey()),
        );
        transaction.sign(&[self.payer(), owner], self.latest_blockhash()?);
        self.send_and_confirm_transaction(&transaction)?;

        Ok(())
    }

    fn transfer_to(
        &self,
        authority: &Keypair,
        token_mint: &Pubkey,
        source: &Pubkey,
        destination: &Pubkey,
        amount: u64,
        decimals: u8,
    ) -> ClientResult<()> {
        let mut transaction = Transaction::new_with_payer(
            &[spl_token::instruction::transfer_checked(
                &spl_token::id(),
                source,
                token_mint,
                destination,
                &authority.pubkey(),
                &[],
                amount,
                decimals,
            )?],
            Some(&self.payer_pubkey()),
        );
        transaction.sign(&[self.payer(), authority], self.latest_blockhash()?);
        self.send_and_confirm_transaction(&transaction)?;

        Ok(())
    }
    fn get_associated_token_address(wallet_address: &Pubkey, token_mint: &Pubkey) -> Pubkey {
        spl_associated_token_account::get_associated_token_address(wallet_address, token_mint)
    }

    fn create_associated_token_account(
        &self,
        funder: &Keypair,
        recipient: &Pubkey,
        token_mint: &Pubkey,
    ) -> ClientResult<Pubkey> {
        let mut transaction = Transaction::new_with_payer(
            &[
                spl_associated_token_account::instruction::create_associated_token_account(
                    &funder.pubkey(),
                    recipient,
                    token_mint,
                    &anchor_spl::token::ID,
                ),
            ],
            Some(&self.payer_pubkey()),
        );
        if funder.pubkey() == self.payer_pubkey() {
            transaction.sign(&[self.payer()], self.latest_blockhash()?);
        } else {
            transaction.sign(&[self.payer(), funder], self.latest_blockhash()?);
        };
        self.send_and_confirm_transaction(&transaction)?;

        Ok(Self::get_associated_token_address(recipient, token_mint))
    }

    fn create_associated_token_account_by_payer(
        &self,
        recipient: &Pubkey,
        token_mint: &Pubkey,
    ) -> ClientResult<Pubkey> {
        self.create_associated_token_account(self.payer(), recipient, token_mint)
    }

    fn close_token_account(
        &self,
        owner: &Keypair,
        account: &Pubkey,
        destination: &Pubkey,
    ) -> ClientResult<()> {
        let mut transaction = Transaction::new_with_payer(
            &[spl_token::instruction::close_account(
                &spl_token::id(),
                account,
                destination,
                &owner.pubkey(),
                &[],
            )?],
            Some(&self.payer_pubkey()),
        );
        transaction.sign(&[self.payer(), owner], self.latest_blockhash()?);
        self.send_and_confirm_transaction(&transaction)?;

        Ok(())
    }
Examples found in repository?
src/client.rs (line 85)
84
85
86
87
88
    pub fn get_instruction_logs(&self, ix: Instruction) -> ClientResult<Vec<String>> {
        let result = self.simulate_transaction(&[ix], &[self.payer()])?;
        let logs = result.logs.ok_or(ClientError::DeserializationError)?;
        Ok(logs)
    }

Methods from Deref<Target = RpcClient>§

Get the configured url of the client’s sender

Get the configured default commitment level.

The commitment config may be specified during construction, and determines how thoroughly committed a transaction must be when waiting for its confirmation or otherwise checking for confirmation. If not specified, the default commitment level is Finalized.

The default commitment level is overridden when calling methods that explicitly provide a CommitmentConfig, like RpcClient::confirm_transaction_with_commitment.

Submit a transaction and wait for confirmation.

Once this function returns successfully, the given transaction is guaranteed to be processed with the configured commitment level.

After sending the transaction, this method polls in a loop for the status of the transaction until it has ben confirmed.

Errors

If the transaction is not signed then an error with kind RpcError is returned, containing an RpcResponseError with code set to JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE.

If the preflight transaction simulation fails then an error with kind RpcError is returned, containing an RpcResponseError with code set to JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE.

If the receiving node is unhealthy, e.g. it is not fully synced to the cluster, then an error with kind RpcError is returned, containing an RpcResponseError with code set to JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY.

RPC Reference

This method is built on the sendTransaction RPC method, and the getLatestBlockhash RPC method.

Examples
let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
let signature = rpc_client.send_and_confirm_transaction(&tx)?;

Submits a signed transaction to the network.

Before a transaction is processed, the receiving node runs a “preflight check” which verifies signatures, checks that the node is healthy, and simulates the transaction. If the preflight check fails then an error is returned immediately. Preflight checks can be disabled by calling send_transaction_with_config and setting the skip_preflight field of RpcSendTransactionConfig to true.

This method does not wait for the transaction to be processed or confirmed before returning successfully. To wait for the transaction to be processed or confirmed, use the send_and_confirm_transaction method.

Errors

If the transaction is not signed then an error with kind RpcError is returned, containing an RpcResponseError with code set to JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE.

If the preflight transaction simulation fails then an error with kind RpcError is returned, containing an RpcResponseError with code set to JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE.

If the receiving node is unhealthy, e.g. it is not fully synced to the cluster, then an error with kind RpcError is returned, containing an RpcResponseError with code set to JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY.

RPC Reference

This method is built on the sendTransaction RPC method.

Examples
// Transfer lamports from Alice to Bob
let latest_blockhash = rpc_client.get_latest_blockhash()?;
let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
let signature = rpc_client.send_transaction(&tx)?;

Submits a signed transaction to the network.

Before a transaction is processed, the receiving node runs a “preflight check” which verifies signatures, checks that the node is healthy, and simulates the transaction. If the preflight check fails then an error is returned immediately. Preflight checks can be disabled by setting the skip_preflight field of RpcSendTransactionConfig to true.

This method does not wait for the transaction to be processed or confirmed before returning successfully. To wait for the transaction to be processed or confirmed, use the send_and_confirm_transaction method.

Errors

If preflight checks are enabled, if the transaction is not signed then an error with kind RpcError is returned, containing an RpcResponseError with code set to JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE.

If preflight checks are enabled, if the preflight transaction simulation fails then an error with kind RpcError is returned, containing an RpcResponseError with code set to JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE.

If the receiving node is unhealthy, e.g. it is not fully synced to the cluster, then an error with kind RpcError is returned, containing an RpcResponseError with code set to JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY.

RPC Reference

This method is built on the sendTransaction RPC method.

Examples
// Transfer lamports from Alice to Bob
let latest_blockhash = rpc_client.get_latest_blockhash()?;
let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
let config = RpcSendTransactionConfig {
    skip_preflight: true,
    .. RpcSendTransactionConfig::default()
};
let signature = rpc_client.send_transaction_with_config(
    &tx,
    config,
)?;

Check the confirmation status of a transaction.

Returns true if the given transaction succeeded and has been committed with the configured commitment level, which can be retrieved with the commitment method.

Note that this method does not wait for a transaction to be confirmed — it only checks whether a transaction has been confirmed. To submit a transaction and wait for it to confirm, use send_and_confirm_transaction.

This method returns false if the transaction failed, even if it has been confirmed.

RPC Reference

This method is built on the getSignatureStatuses RPC method.

Examples
// Transfer lamports from Alice to Bob and wait for confirmation
let latest_blockhash = rpc_client.get_latest_blockhash()?;
let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
let signature = rpc_client.send_transaction(&tx)?;

loop {
    let confirmed = rpc_client.confirm_transaction(&signature)?;
    if confirmed {
        break;
    }
}

Check the confirmation status of a transaction.

Returns an RpcResult with value true if the given transaction succeeded and has been committed with the given commitment level.

Note that this method does not wait for a transaction to be confirmed — it only checks whether a transaction has been confirmed. To submit a transaction and wait for it to confirm, use send_and_confirm_transaction.

This method returns an RpcResult with value false if the transaction failed, even if it has been confirmed.

RPC Reference

This method is built on the getSignatureStatuses RPC method.

Examples
// Transfer lamports from Alice to Bob and wait for confirmation
let latest_blockhash = rpc_client.get_latest_blockhash()?;
let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
let signature = rpc_client.send_transaction(&tx)?;

loop {
    let commitment_config = CommitmentConfig::processed();
    let confirmed = rpc_client.confirm_transaction_with_commitment(&signature, commitment_config)?;
    if confirmed.value {
        break;
    }
}

Simulates sending a transaction.

If the transaction fails, then the err field of the returned RpcSimulateTransactionResult will be Some. Any logs emitted from the transaction are returned in the logs field.

Simulating a transaction is similar to the “preflight check” that is run by default when sending a transaction.

By default, signatures are not verified during simulation. To verify signatures, call the simulate_transaction_with_config method, with the sig_verify field of RpcSimulateTransactionConfig set to true.

RPC Reference

This method is built on the simulateTransaction RPC method.

Examples
// Transfer lamports from Alice to Bob
let latest_blockhash = rpc_client.get_latest_blockhash()?;
let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
let result = rpc_client.simulate_transaction(&tx)?;
assert!(result.value.err.is_none());

Simulates sending a transaction.

If the transaction fails, then the err field of the returned RpcSimulateTransactionResult will be Some. Any logs emitted from the transaction are returned in the logs field.

Simulating a transaction is similar to the “preflight check” that is run by default when sending a transaction.

By default, signatures are not verified during simulation. To verify signatures, call the simulate_transaction_with_config method, with the sig_verify field of RpcSimulateTransactionConfig set to true.

This method can additionally query information about accounts by including them in the accounts field of the RpcSimulateTransactionConfig argument, in which case those results are reported in the accounts field of the returned RpcSimulateTransactionResult.

RPC Reference

This method is built on the simulateTransaction RPC method.

Examples
// Transfer lamports from Alice to Bob
let latest_blockhash = rpc_client.get_latest_blockhash()?;
let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
let config = RpcSimulateTransactionConfig {
    sig_verify: true,
    .. RpcSimulateTransactionConfig::default()
};
let result = rpc_client.simulate_transaction_with_config(
    &tx,
    config,
)?;
assert!(result.value.err.is_none());

Returns the highest slot information that the node has snapshots for.

This will find the highest full snapshot slot, and the highest incremental snapshot slot based on the full snapshot slot, if there is one.

RPC Reference

This method corresponds directly to the getHighestSnapshotSlot RPC method.

Examples
let snapshot_slot_info = rpc_client.get_highest_snapshot_slot()?;
👎Deprecated since 1.8.0: Please use RpcClient::get_highest_snapshot_slot() instead

Check if a transaction has been processed with the default commitment level.

If the transaction has been processed with the default commitment level, then this method returns Ok of Some. If the transaction has not yet been processed with the default commitment level, it returns Ok of None.

If the transaction has been processed with the default commitment level, and the transaction succeeded, this method returns Ok(Some(Ok(()))). If the transaction has peen processed with the default commitment level, and the transaction failed, this method returns Ok(Some(Err(_))), where the interior error is type TransactionError.

This function only searches a node’s recent history, including all recent slots, plus up to [MAX_RECENT_BLOCKHASHES][solana_sdk::clock::MAX_RECENT_BLOCKHASHES] rooted slots. To search the full transaction history use the get_signature_statuse_with_commitment_and_history method.

RPC Reference

This method is built on the getSignatureStatuses RPC method.

Examples
let signature = rpc_client.send_transaction(&tx)?;
let status = rpc_client.get_signature_status(&signature)?;

Gets the statuses of a list of transaction signatures.

The returned vector of [TransactionStatus] has the same length as the input slice.

For any transaction that has not been processed by the network, the value of the corresponding entry in the returned vector is None. As a result, a transaction that has recently been submitted will not have a status immediately.

To submit a transaction and wait for it to confirm, use send_and_confirm_transaction.

This function ignores the configured confirmation level, and returns the transaction status whatever it is. It does not wait for transactions to be processed.

This function only searches a node’s recent history, including all recent slots, plus up to [MAX_RECENT_BLOCKHASHES][solana_sdk::clock::MAX_RECENT_BLOCKHASHES] rooted slots. To search the full transaction history use the get_signature_statuses_with_history method.

Errors

Any individual TransactionStatus may have triggered an error during processing, in which case its [err][TransactionStatus::err] field will be Some.

RPC Reference

This method corresponds directly to the getSignatureStatuses RPC method.

Examples
// Send lamports from Alice to Bob and wait for the transaction to be processed
let latest_blockhash = rpc_client.get_latest_blockhash()?;
let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
let signature = rpc_client.send_transaction(&tx)?;

let status = loop {
   let statuses = rpc_client.get_signature_statuses(&[signature])?.value;
   if let Some(status) = statuses[0].clone() {
       break status;
   }
   std::thread::sleep(Duration::from_millis(100));
};

assert!(status.err.is_none());

Gets the statuses of a list of transaction signatures.

The returned vector of [TransactionStatus] has the same length as the input slice.

For any transaction that has not been processed by the network, the value of the corresponding entry in the returned vector is None. As a result, a transaction that has recently been submitted will not have a status immediately.

To submit a transaction and wait for it to confirm, use send_and_confirm_transaction.

This function ignores the configured confirmation level, and returns the transaction status whatever it is. It does not wait for transactions to be processed.

This function searches a node’s full ledger history and (if implemented) long-term storage. To search for transactions in recent slots only use the get_signature_statuses method.

Errors

Any individual TransactionStatus may have triggered an error during processing, in which case its [err][TransactionStatus::err] field will be Some.

RPC Reference

This method corresponds directly to the getSignatureStatuses RPC method, with the searchTransactionHistory configuration option set to true.

Examples
// Check if an old transaction exists
let signature = get_old_transaction_signature();
let latest_blockhash = rpc_client.get_latest_blockhash()?;
let statuses = rpc_client.get_signature_statuses_with_history(&[signature])?.value;
if statuses[0].is_none() {
    println!("old transaction does not exist");
}

Check if a transaction has been processed with the given commitment level.

If the transaction has been processed with the given commitment level, then this method returns Ok of Some. If the transaction has not yet been processed with the given commitment level, it returns Ok of None.

If the transaction has been processed with the given commitment level, and the transaction succeeded, this method returns Ok(Some(Ok(()))). If the transaction has peen processed with the given commitment level, and the transaction failed, this method returns Ok(Some(Err(_))), where the interior error is type TransactionError.

This function only searches a node’s recent history, including all recent slots, plus up to [MAX_RECENT_BLOCKHASHES][solana_sdk::clock::MAX_RECENT_BLOCKHASHES] rooted slots. To search the full transaction history use the get_signature_statuse_with_commitment_and_history method.

RPC Reference

This method is built on the getSignatureStatuses RPC method.

Examples
let signature = rpc_client.send_and_confirm_transaction(&tx)?;
let commitment_config = CommitmentConfig::processed();
let status = rpc_client.get_signature_status_with_commitment(
    &signature,
    commitment_config,
)?;

Check if a transaction has been processed with the given commitment level.

If the transaction has been processed with the given commitment level, then this method returns Ok of Some. If the transaction has not yet been processed with the given commitment level, it returns Ok of None.

If the transaction has been processed with the given commitment level, and the transaction succeeded, this method returns Ok(Some(Ok(()))). If the transaction has peen processed with the given commitment level, and the transaction failed, this method returns Ok(Some(Err(_))), where the interior error is type TransactionError.

This method optionally searches a node’s full ledger history and (if implemented) long-term storage.

RPC Reference

This method is built on the getSignatureStatuses RPC method.

Examples
let signature = rpc_client.send_transaction(&tx)?;
let commitment_config = CommitmentConfig::processed();
let search_transaction_history = true;
let status = rpc_client.get_signature_status_with_commitment_and_history(
    &signature,
    commitment_config,
    search_transaction_history,
)?;

Returns the slot that has reached the configured commitment level.

RPC Reference

This method corresponds directly to the getSlot RPC method.

Examples
let slot = rpc_client.get_slot()?;

Returns the slot that has reached the given commitment level.

RPC Reference

This method corresponds directly to the getSlot RPC method.

Examples
let commitment_config = CommitmentConfig::processed();
let slot = rpc_client.get_slot_with_commitment(commitment_config)?;

Returns the block height that has reached the configured commitment level.

RPC Reference

This method is corresponds directly to the getBlockHeight RPC method.

Examples
let block_height = rpc_client.get_block_height()?;

Returns the block height that has reached the given commitment level.

RPC Reference

This method is corresponds directly to the getBlockHeight RPC method.

Examples
let commitment_config = CommitmentConfig::processed();
let block_height = rpc_client.get_block_height_with_commitment(
    commitment_config,
)?;

Returns the slot leaders for a given slot range.

RPC Reference

This method corresponds directly to the getSlotLeaders RPC method.

Examples
let start_slot = 1;
let limit = 3;
let leaders = rpc_client.get_slot_leaders(start_slot, limit)?;

Get block production for the current epoch.

RPC Reference

This method corresponds directly to the getBlockProduction RPC method.

Examples
let production = rpc_client.get_block_production()?;

Get block production for the current or previous epoch.

RPC Reference

This method corresponds directly to the getBlockProduction RPC method.

Examples
let leader = rpc_client.get_slot_leaders(start_slot, limit)?;
let leader = leader[0];
let range = RpcBlockProductionConfigRange {
    first_slot: start_slot,
    last_slot: Some(start_slot + limit),
};
let config = RpcBlockProductionConfig {
    identity: Some(leader.to_string()),
    range: Some(range),
    commitment: Some(CommitmentConfig::processed()),
};
let production = rpc_client.get_block_production_with_config(
    config
)?;

Returns epoch activation information for a stake account.

This method uses the configured [commitment level].

RPC Reference

This method corresponds directly to the getStakeActivation RPC method.

Examples
// Find some vote account to delegate to
let vote_accounts = rpc_client.get_vote_accounts()?;
let vote_account = vote_accounts.current.get(0).unwrap_or_else(|| &vote_accounts.delinquent[0]);
let vote_account_pubkey = &vote_account.vote_pubkey;
let vote_account_pubkey = Pubkey::from_str(vote_account_pubkey).expect("pubkey");

// Create a stake account
let stake_account = Keypair::new();
let stake_account_pubkey = stake_account.pubkey();

// Build the instructions to create new stake account,
// funded by alice, and delegate to a validator's vote account.
let instrs = stake::instruction::create_account_and_delegate_stake(
    &alice.pubkey(),
    &stake_account_pubkey,
    &vote_account_pubkey,
    &Authorized::auto(&stake_account_pubkey),
    &Lockup::default(),
    1_000_000,
);

let latest_blockhash = rpc_client.get_latest_blockhash()?;
let tx = Transaction::new_signed_with_payer(
    &instrs,
    Some(&alice.pubkey()),
    &[&alice, &stake_account],
    latest_blockhash,
);

rpc_client.send_and_confirm_transaction(&tx)?;

let epoch_info = rpc_client.get_epoch_info()?;
let activation = rpc_client.get_stake_activation(
    stake_account_pubkey,
    Some(epoch_info.epoch),
)?;

assert_eq!(activation.state, StakeActivationState::Activating);

Returns information about the current supply.

This method uses the configured commitment level.

RPC Reference

This method corresponds directly to the getSupply RPC method.

Examples
let supply = rpc_client.supply()?;

Returns information about the current supply.

RPC Reference

This method corresponds directly to the getSupply RPC method.

Examples
let commitment_config = CommitmentConfig::processed();
let supply = rpc_client.supply_with_commitment(
    commitment_config,
)?;

Returns the 20 largest accounts, by lamport balance.

RPC Reference

This method corresponds directly to the getLargestAccounts RPC method.

Examples
let commitment_config = CommitmentConfig::processed();
let config = RpcLargestAccountsConfig {
    commitment: Some(commitment_config),
    filter: Some(RpcLargestAccountsFilter::Circulating),
};
let accounts = rpc_client.get_largest_accounts_with_config(
    config,
)?;

Returns the account info and associated stake for all the voting accounts that have reached the configured commitment level.

RPC Reference

This method corresponds directly to the getVoteAccounts RPC method.

Examples
let accounts = rpc_client.get_vote_accounts()?;

Returns the account info and associated stake for all the voting accounts that have reached the given commitment level.

RPC Reference

This method corresponds directly to the getVoteAccounts RPC method.

Examples
let commitment_config = CommitmentConfig::processed();
let accounts = rpc_client.get_vote_accounts_with_commitment(
    commitment_config,
)?;

Returns the account info and associated stake for all the voting accounts that have reached the given commitment level.

RPC Reference

This method corresponds directly to the getVoteAccounts RPC method.

Examples
let vote_pubkey = vote_keypair.pubkey();
let commitment = CommitmentConfig::processed();
let config = RpcGetVoteAccountsConfig {
    vote_pubkey: Some(vote_pubkey.to_string()),
    commitment: Some(commitment),
    keep_unstaked_delinquents: Some(true),
    delinquent_slot_distance: Some(10),
};
let accounts = rpc_client.get_vote_accounts_with_config(
    config,
)?;

Returns information about all the nodes participating in the cluster.

RPC Reference

This method corresponds directly to the getClusterNodes RPC method.

Examples
let cluster_nodes = rpc_client.get_cluster_nodes()?;

Returns identity and transaction information about a confirmed block in the ledger.

The encodings are returned in UiTransactionEncoding::Json format. To return transactions in other encodings, use get_block_with_encoding.

RPC Reference

This method corresponds directly to the getBlock RPC method.

Examples
let block = rpc_client.get_block(slot)?;

Returns identity and transaction information about a confirmed block in the ledger.

RPC Reference

This method corresponds directly to the getBlock RPC method.

Examples
let encoding = UiTransactionEncoding::Base58;
let block = rpc_client.get_block_with_encoding(
    slot,
    encoding,
)?;

Returns identity and transaction information about a confirmed block in the ledger.

RPC Reference

This method corresponds directly to the getBlock RPC method.

Examples
let config = RpcBlockConfig {
    encoding: Some(UiTransactionEncoding::Base58),
    transaction_details: Some(TransactionDetails::None),
    rewards: Some(true),
    commitment: None,
    max_supported_transaction_version: Some(0),
};
let block = rpc_client.get_block_with_config(
    slot,
    config,
)?;
👎Deprecated since 1.7.0: Please use RpcClient::get_block() instead
👎Deprecated since 1.7.0: Please use RpcClient::get_block_with_encoding() instead
👎Deprecated since 1.7.0: Please use RpcClient::get_block_with_config() instead

Returns a list of finalized blocks between two slots.

The range is inclusive, with results including the block for both start_slot and end_slot.

If end_slot is not provided, then the end slot is for the latest finalized block.

This method may not return blocks for the full range of slots if some slots do not have corresponding blocks. To simply get a specific number of sequential blocks, use the get_blocks_with_limit method.

This method uses the Finalized commitment level.

Errors

This method returns an error if the range is greater than 500,000 slots.

RPC Reference

This method corresponds directly to the getBlocks RPC method, unless the remote node version is less than 1.7, in which case it maps to the getConfirmedBlocks RPC method.

Examples
// Get up to the first 10 blocks
let start_slot = 0;
let end_slot = 9;
let blocks = rpc_client.get_blocks(start_slot, Some(end_slot))?;

Returns a list of confirmed blocks between two slots.

The range is inclusive, with results including the block for both start_slot and end_slot.

If end_slot is not provided, then the end slot is for the latest block with the given commitment level.

This method may not return blocks for the full range of slots if some slots do not have corresponding blocks. To simply get a specific number of sequential blocks, use the get_blocks_with_limit_and_commitment method.

Errors

This method returns an error if the range is greater than 500,000 slots.

This method returns an error if the given commitment level is below Confirmed.

RPC Reference

This method corresponds directly to the getBlocks RPC method, unless the remote node version is less than 1.7, in which case it maps to the getConfirmedBlocks RPC method.

Examples
// Get up to the first 10 blocks
let start_slot = 0;
let end_slot = 9;
// Method does not support commitment below `confirmed`
let commitment_config = CommitmentConfig::confirmed();
let blocks = rpc_client.get_blocks_with_commitment(
    start_slot,
    Some(end_slot),
    commitment_config,
)?;

Returns a list of finalized blocks starting at the given slot.

This method uses the Finalized commitment level.

Errors

This method returns an error if the limit is greater than 500,000 slots.

RPC Reference

This method corresponds directly to the getBlocksWithLimit RPC method, unless the remote node version is less than 1.7, in which case it maps to the getConfirmedBlocksWithLimit RPC method.

Examples
// Get the first 10 blocks
let start_slot = 0;
let limit = 10;
let blocks = rpc_client.get_blocks_with_limit(start_slot, limit)?;

Returns a list of confirmed blocks starting at the given slot.

Errors

This method returns an error if the limit is greater than 500,000 slots.

This method returns an error if the given commitment level is below Confirmed.

RPC Reference

This method corresponds directly to the getBlocksWithLimit RPC method, unless the remote node version is less than 1.7, in which case it maps to the getConfirmedBlocksWithLimit RPC method.

Examples
// Get the first 10 blocks
let start_slot = 0;
let limit = 10;
let commitment_config = CommitmentConfig::confirmed();
let blocks = rpc_client.get_blocks_with_limit_and_commitment(
    start_slot,
    limit,
    commitment_config,
)?;
👎Deprecated since 1.7.0: Please use RpcClient::get_blocks() instead
👎Deprecated since 1.7.0: Please use RpcClient::get_blocks_with_commitment() instead
👎Deprecated since 1.7.0: Please use RpcClient::get_blocks_with_limit() instead
👎Deprecated since 1.7.0: Please use RpcClient::get_blocks_with_limit_and_commitment() instead

Get confirmed signatures for transactions involving an address.

Returns up to 1000 signatures, ordered from newest to oldest.

This method uses the Finalized commitment level.

RPC Reference

This method corresponds directly to the getSignaturesForAddress RPC method, unless the remote node version is less than 1.7, in which case it maps to the getSignaturesForAddress2 RPC method.

Examples
let signatures = rpc_client.get_signatures_for_address(
    &alice.pubkey(),
)?;

Get confirmed signatures for transactions involving an address.

Errors

This method returns an error if the given commitment level is below Confirmed.

RPC Reference

This method corresponds directly to the getSignaturesForAddress RPC method, unless the remote node version is less than 1.7, in which case it maps to the getSignaturesForAddress2 RPC method.

Examples
let config = GetConfirmedSignaturesForAddress2Config {
    before: None,
    until: None,
    limit: Some(3),
    commitment: Some(CommitmentConfig::confirmed()),
};
let signatures = rpc_client.get_signatures_for_address_with_config(
    &alice.pubkey(),
    config,
)?;
👎Deprecated since 1.7.0: Please use RpcClient::get_signatures_for_address() instead
👎Deprecated since 1.7.0: Please use RpcClient::get_signatures_for_address_with_config() instead

Returns transaction details for a confirmed transaction.

This method uses the Finalized commitment level.

RPC Reference

This method corresponds directly to the getTransaction RPC method, unless the remote node version is less than 1.7, in which case it maps to the getConfirmedTransaction RPC method.

Examples
let signature = rpc_client.send_and_confirm_transaction(&tx)?;
let transaction = rpc_client.get_transaction(
    &signature,
    UiTransactionEncoding::Json,
)?;

Returns transaction details for a confirmed transaction.

Errors

This method returns an error if the given commitment level is below Confirmed.

RPC Reference

This method corresponds directly to the getTransaction RPC method, unless the remote node version is less than 1.7, in which case it maps to the getConfirmedTransaction RPC method.

Examples
let signature = rpc_client.send_and_confirm_transaction(&tx)?;
let config = RpcTransactionConfig {
    encoding: Some(UiTransactionEncoding::Json),
    commitment: Some(CommitmentConfig::confirmed()),
    max_supported_transaction_version: Some(0),
};
let transaction = rpc_client.get_transaction_with_config(
    &signature,
    config,
)?;
👎Deprecated since 1.7.0: Please use RpcClient::get_transaction() instead
👎Deprecated since 1.7.0: Please use RpcClient::get_transaction_with_config() instead

Returns the estimated production time of a block.

RPC Reference

This method corresponds directly to the getBlockTime RPC method.

Examples
// Get the time of the most recent finalized block
let slot = rpc_client.get_slot()?;
let block_time = rpc_client.get_block_time(slot)?;

Returns information about the current epoch.

This method uses the configured default commitment level.

RPC Reference

This method corresponds directly to the getEpochInfo RPC method.

Examples
let epoch_info = rpc_client.get_epoch_info()?;

Returns information about the current epoch.

RPC Reference

This method corresponds directly to the getEpochInfo RPC method.

Examples
let commitment_config = CommitmentConfig::confirmed();
let epoch_info = rpc_client.get_epoch_info_with_commitment(
    commitment_config,
)?;

Returns the leader schedule for an epoch.

This method uses the configured default commitment level.

RPC Reference

This method corresponds directly to the getLeaderSchedule RPC method.

Examples
let leader_schedule = rpc_client.get_leader_schedule(
    Some(slot),
)?;

Returns the leader schedule for an epoch.

RPC Reference

This method corresponds directly to the getLeaderSchedule RPC method.

Examples
let commitment_config = CommitmentConfig::processed();
let leader_schedule = rpc_client.get_leader_schedule_with_commitment(
    Some(slot),
    commitment_config,
)?;

Returns the leader schedule for an epoch.

RPC Reference

This method corresponds directly to the getLeaderSchedule RPC method.

Examples
let config = RpcLeaderScheduleConfig {
    identity: Some(validator_pubkey_str),
    commitment: Some(CommitmentConfig::processed()),
};
let leader_schedule = rpc_client.get_leader_schedule_with_config(
    Some(slot),
    config,
)?;

Returns epoch schedule information from this cluster’s genesis config.

RPC Reference

This method corresponds directly to the getEpochSchedule RPC method.

Examples
let epoch_schedule = rpc_client.get_epoch_schedule()?;

Returns a list of recent performance samples, in reverse slot order.

Performance samples are taken every 60 seconds and include the number of transactions and slots that occur in a given time window.

RPC Reference

This method corresponds directly to the getRecentPerformanceSamples RPC method.

Examples
let limit = 10;
let performance_samples = rpc_client.get_recent_performance_samples(
    Some(limit),
)?;

Returns the identity pubkey for the current node.

RPC Reference

This method corresponds directly to the getIdentity RPC method.

Examples
let identity = rpc_client.get_identity()?;

Returns the current inflation governor.

This method uses the Finalized commitment level.

RPC Reference

This method corresponds directly to the getInflationGovernor RPC method.

Examples
let inflation_governor = rpc_client.get_inflation_governor()?;

Returns the specific inflation values for the current epoch.

RPC Reference

This method corresponds directly to the getInflationRate RPC method.

Examples
let inflation_rate = rpc_client.get_inflation_rate()?;

Returns the inflation reward for a list of addresses for an epoch.

This method uses the configured commitment level.

RPC Reference

This method corresponds directly to the getInflationReward RPC method.

Examples
let addresses = vec![alice.pubkey(), bob.pubkey()];
let inflation_reward = rpc_client.get_inflation_reward(
    &addresses,
    Some(epoch),
)?;

Returns the current solana version running on the node.

RPC Reference

This method corresponds directly to the getVersion RPC method.

Examples
let expected_version = semver::Version::new(1, 7, 0);
let version = rpc_client.get_version()?;
let version = semver::Version::parse(&version.solana_core)?;
assert!(version >= expected_version);

Returns the lowest slot that the node has information about in its ledger.

This value may increase over time if the node is configured to purge older ledger data.

RPC Reference

This method corresponds directly to the minimumLedgerSlot RPC method.

Examples
let slot = rpc_client.minimum_ledger_slot()?;

Returns all information associated with the account of the provided pubkey.

This method uses the configured commitment level.

To get multiple accounts at once, use the get_multiple_accounts method.

Errors

If the account does not exist, this method returns RpcError::ForUser. This is unlike get_account_with_commitment, which returns Ok(None) if the account does not exist.

RPC Reference

This method is built on the getAccountInfo RPC method.

Examples
let alice_pubkey = Pubkey::from_str("BgvYtJEfmZYdVKiptmMjxGzv8iQoo4MWjsP3QsTkhhxa").unwrap();
let account = rpc_client.get_account(&alice_pubkey)?;

Returns all information associated with the account of the provided pubkey.

If the account does not exist, this method returns Ok(None).

To get multiple accounts at once, use the get_multiple_accounts_with_commitment method.

RPC Reference

This method is built on the getAccountInfo RPC method.

Examples
let alice_pubkey = Pubkey::from_str("BgvYtJEfmZYdVKiptmMjxGzv8iQoo4MWjsP3QsTkhhxa").unwrap();
let commitment_config = CommitmentConfig::processed();
let account = rpc_client.get_account_with_commitment(
    &alice_pubkey,
    commitment_config,
)?;
assert!(account.value.is_some());

Returns all information associated with the account of the provided pubkey.

If the account does not exist, this method returns Ok(None).

To get multiple accounts at once, use the get_multiple_accounts_with_config method.

RPC Reference

This method is built on the getAccountInfo RPC method.

Examples
let alice_pubkey = Pubkey::from_str("BgvYtJEfmZYdVKiptmMjxGzv8iQoo4MWjsP3QsTkhhxa").unwrap();
let commitment_config = CommitmentConfig::processed();
let config = RpcAccountInfoConfig {
    encoding: Some(UiAccountEncoding::Base64),
    commitment: Some(commitment_config),
    .. RpcAccountInfoConfig::default()
};
let account = rpc_client.get_account_with_config(
    &alice_pubkey,
    config,
)?;
assert!(account.value.is_some());

Get the max slot seen from retransmit stage.

RPC Reference

This method corresponds directly to the getMaxRetransmitSlot RPC method.

Examples
let slot = rpc_client.get_max_retransmit_slot()?;

Get the max slot seen from after shred insert.

RPC Reference

This method corresponds directly to the getMaxShredInsertSlot RPC method.

Examples
let slot = rpc_client.get_max_shred_insert_slot()?;

Returns the account information for a list of pubkeys.

This method uses the configured commitment level.

RPC Reference

This method is built on the getMultipleAccounts RPC method.

Examples
let pubkeys = vec![alice.pubkey(), bob.pubkey()];
let accounts = rpc_client.get_multiple_accounts(&pubkeys)?;

Returns the account information for a list of pubkeys.

RPC Reference

This method is built on the getMultipleAccounts RPC method.

Examples
let pubkeys = vec![alice.pubkey(), bob.pubkey()];
let commitment_config = CommitmentConfig::processed();
let accounts = rpc_client.get_multiple_accounts_with_commitment(
    &pubkeys,
    commitment_config,
)?;

Returns the account information for a list of pubkeys.

RPC Reference

This method is built on the getMultipleAccounts RPC method.

Examples
let pubkeys = vec![alice.pubkey(), bob.pubkey()];
let commitment_config = CommitmentConfig::processed();
let config = RpcAccountInfoConfig {
    encoding: Some(UiAccountEncoding::Base64),
    commitment: Some(commitment_config),
    .. RpcAccountInfoConfig::default()
};
let accounts = rpc_client.get_multiple_accounts_with_config(
    &pubkeys,
    config,
)?;

Gets the raw data associated with an account.

This is equivalent to calling get_account and then accessing the data field of the returned Account.

RPC Reference

This method is built on the getAccountInfo RPC method.

Examples
let alice_pubkey = Pubkey::from_str("BgvYtJEfmZYdVKiptmMjxGzv8iQoo4MWjsP3QsTkhhxa").unwrap();
let account_data = rpc_client.get_account_data(&alice_pubkey)?;

Returns minimum balance required to make an account with specified data length rent exempt.

RPC Reference

This method corresponds directly to the getMinimumBalanceForRentExemption RPC method.

Examples
let data_len = 300;
let balance = rpc_client.get_minimum_balance_for_rent_exemption(data_len)?;

Request the balance of the provided account pubkey.

This method uses the configured commitment level.

RPC Reference

This method corresponds directly to the getBalance RPC method.

Examples
let balance = rpc_client.get_balance(&alice.pubkey())?;

Request the balance of the provided account pubkey.

RPC Reference

This method corresponds directly to the getBalance RPC method.

Examples
let commitment_config = CommitmentConfig::processed();
let balance = rpc_client.get_balance_with_commitment(
    &alice.pubkey(),
    commitment_config,
)?;

Returns all accounts owned by the provided program pubkey.

This method uses the configured commitment level.

RPC Reference

This method corresponds directly to the getProgramAccounts RPC method.

Examples
let accounts = rpc_client.get_program_accounts(&alice.pubkey())?;

Returns all accounts owned by the provided program pubkey.

RPC Reference

This method is built on the getProgramAccounts RPC method.

Examples
let memcmp = RpcFilterType::Memcmp(Memcmp {
    offset: 0,
    bytes: MemcmpEncodedBytes::Base64(base64_bytes.to_string()),
    encoding: None,
});
let config = RpcProgramAccountsConfig {
    filters: Some(vec![
        RpcFilterType::DataSize(128),
        memcmp,
    ]),
    account_config: RpcAccountInfoConfig {
        encoding: Some(UiAccountEncoding::Base64),
        data_slice: Some(UiDataSliceConfig {
            offset: 0,
            length: 5,
        }),
        commitment: Some(CommitmentConfig::processed()),
        min_context_slot: Some(1234),
    },
    with_context: Some(false),
};
let accounts = rpc_client.get_program_accounts_with_config(
    &alice.pubkey(),
    config,
)?;

Request the transaction count.

👎Deprecated since 1.9.0: Please use get_latest_blockhash and get_fee_for_message instead
👎Deprecated since 1.9.0: Please use get_latest_blockhash_with_commitment and get_fee_for_message instead
👎Deprecated since 1.9.0: Please use get_latest_blockhash instead
👎Deprecated since 1.9.0: Please use get_latest_blockhash_with_commitment instead
👎Deprecated since 1.9.0: Please get_fee_for_message instead
👎Deprecated since 1.9.0: Please get_latest_blockhash_with_commitment and get_fee_for_message instead
👎Deprecated since 1.9.0: Please do not use, will no longer be available in the future
👎Deprecated since 1.9.0: Please do not use, will no longer be available in the future

Poll the server to confirm a transaction.

Poll the server to confirm a transaction.

Poll the server to confirm a transaction.

Trait Implementations§

Formats the value using the given formatter. Read more
The resulting type after dereferencing.
Dereferences the value.
Mutably dereferences the value.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Instruments this type with the current Span, returning an Instrumented wrapper. Read more

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
Should always be Self
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more