stablebond_sdk/
lib.rs

1//! To get started quickly with the stablebond SDK, you can use the following methods
2//! to quickly build transactions for the fundamentals of etherfuse stablebonds.
3//!
4//! Including
5//!
6//! * Purchasing a bond
7//! * Requesting a redemption
8//! * Redeeming a bond
9//! * Create a purchase order
10//! * Redeeming a purchase order
11//!
12//! # Examples
13//!
14//! ```rust,ignore
15//! use crate::{
16//!     accounts::{Bond, BondMultisigMeta, PaymentFeed},
17//!     find_bond_multisig_meta_pda, find_bond_pda, find_config_pda, find_issuance_pda, find_kyc_pda,
18//!     find_nft_issuance_vault_pda, find_payment_feed_pda, find_payment_pda, find_payout_pda,
19//!     find_purchase_order_pda, CreatePurchaseOrderV2, CreatePurchaseOrderV2InstructionArgs,
20//!     PurchaseBondV2, PurchaseBondV2InstructionArgs, RedeemBond, RedeemPurchaseOrder,
21//!     RequestRedemptionV2, RequestRedemptionV2InstructionArgs,
22//! };
23//! use anyhow::Result;
24//! use mpl_token_metadata::accounts::{MasterEdition, Metadata};
25//! use solana_client::nonblocking::rpc_client::RpcClient;
26//! use solana_sdk::{message::Message, signature::Keypair};
27//! use solana_sdk::{pubkey::Pubkey, signer::Signer};
28//! use solana_sdk::{system_program, transaction::Transaction};
29//! use spl_associated_token_account::{
30//!     get_associated_token_address, get_associated_token_address_with_program_id,
31//! };
32//!
33//! // Creates a purchase bond transaction that can be sent to solana
34//!
35//! // The user_wallet will have already needed to complete the KYC process for the transaction to be successful.
36//! // See [API Reference](https://docs.etherfuse.com/api-reference/onboarding/generate-onboarding-url) for more information.
37//!
38//!
39//! let client = RpcClient::new(rpc_url);
40//! // Some user wallet keypair
41//! let user_wallet = Keypair::from_str("user_wallet").unwrap();
42//! // Some mint account
43//! let mint = Pubkey::from_str("mint").unwrap();
44//! // Get an un-signed transaction
45//! let tx = make_purchase_bond_instruction(1000000, user_wallet, client, mint).await?;
46//! // Sign the transaction with the users keypair and then...
47//! // Submit the transaction
48//! let sig = client.send_and_confirm_transaction(&tx).await?;
49//!
50//! pub async fn make_purchase_bond_transaction(
51//!     client: &RpcClient,
52//!     amount: u64,
53//!     user_wallet: Pubkey,
54//!     mint: Pubkey,
55//! ) -> Result<Transaction> {
56//!     let ix_args = PurchaseBondV2InstructionArgs { amount };
57//!     let addresses = generate_buy_addresses(client, mint, user_wallet).await?;
58//!     let mint_auth_multisig_account = get_bond_mint_auth_multisig_if_needed(&client, mint).await?;
59//!     let ix = PurchaseBondV2 {
60//!         kyc_account: addresses.kyc_account,
61//!         user_wallet: user_wallet,
62//!         user_token_account: addresses.user_token_account,
63//!         user_payment_token_account: addresses.user_payment_token_account,
64//!         payment_account: addresses.payment_account,
65//!         payment_token_account: addresses.payment_token_account,
66//!         payment_mint_account: addresses.payment_mint_account,
67//!         payment_feed_account: addresses.payment_feed_account,
68//!         payment_base_price_feed_account: addresses.payment_price_feed_account,
69//!         payment_quote_price_feed_account: addresses.payment_quote_price_feed_account,
70//!         mint_auth_multisig_account,
71//!         bond_account: addresses.bond_account,
72//!         issuance_account: addresses.issuance_account,
73//!         mint_account: mint,
74//!         token2022_program: addresses.token_2022_program,
75//!         associated_token_program: addresses.associated_token_program,
76//!         token_program: addresses.token_program,
77//!         system_program: addresses.system_program,
78//!     }
79//!     .instruction(ix_args);
80//!
81//!     let tx = Transaction::new_unsigned(Message::new(&[ix], Some(&user_wallet)));
82//!
83//!     Ok(tx)
84//! }
85//!
86//! // Creates a transaction to begin the bond redemption process
87//!
88//!
89//! let client = RpcClient::new(rpc_url);
90//! // Some user wallet keypair
91//! let user_wallet = Keypair::from_str("user_wallet").unwrap();
92//! // Some mint account
93//! let mint = Pubkey::from_str("mint").unwrap();
94//! // Some NFT mint account
95//! let nft_mint = Pubkey::from_str("nft_mint").unwrap();
96//! // Get an un-signed transaction
97//! let tx = make_request_redemption_instruction(1000000, user_wallet, mint, nft_mint)?;
98//! // Sign the transaction with the users keypair and then...
99//! // Submit the transaction
100//! let sig = client.send_and_confirm_transaction(&tx).await?;
101//!
102//! pub async fn make_request_redemption_transaction(
103//!     client: &RpcClient,
104//!     amount_in_tokens: u64,
105//!     user_wallet: Pubkey,
106//!     mint: Pubkey,
107//! ) -> Result<Transaction> {
108//!     let ix_args = RequestRedemptionV2InstructionArgs {
109//!         amount: amount_in_tokens,
110//!     };
111//!     let addresses = generate_buy_addresses(client, mint, user_wallet).await?;
112//!     let nft_mint_pair = Keypair::new();
113//!     let nft_mint = nft_mint_pair.pubkey();
114//!     let nft_issuance_vault_account = find_nft_issuance_vault_pda(nft_mint).0;
115//!     let nft_issuance_vault_token_account = get_associated_token_address_with_program_id(
116//!         &nft_issuance_vault_account,
117//!         &mint,
118//!         &spl_token_2022::id(),
119//!     );
120//!     let user_nft_token_account = get_associated_token_address(&user_wallet, &nft_mint);
121//!     let nft_metadata_account = Metadata::find_pda(&nft_mint).0;
122//!     let nft_master_edition_account = MasterEdition::find_pda(&nft_mint).0;
123//!     let nft_collection_mint = find_config_pda().0;
124//!
125//!     let nft_collection_metadata_account = Metadata::find_pda(&nft_collection_mint).0;
126//!     let nft_collection_master_edition_account = MasterEdition::find_pda(&nft_collection_mint).0;
127//!
128//!     let ix = RequestRedemptionV2 {
129//!         kyc_account: find_kyc_pda(user_wallet).0,
130//!         user_wallet,
131//!         config_account: find_config_pda().0,
132//!         token2022_program: addresses.token_2022_program,
133//!         associated_token_program: addresses.associated_token_program,
134//!         token_program: addresses.token_program,
135//!         system_program: addresses.system_program,
136//!         metadata_program: mpl_token_metadata::ID,
137//!         sysvar_instructions: solana_sdk::sysvar::instructions::id(),
138//!         bond_account: addresses.bond_account,
139//!         issuance_account: addresses.issuance_account,
140//!         mint_account: mint,
141//!         user_token_account: addresses.user_token_account,
142//!         nft_mint_account: nft_mint,
143//!         nft_issuance_vault_account,
144//!         nft_issuance_vault_token_account,
145//!         user_nft_token_account,
146//!         nft_metadata_account,
147//!         nft_master_edition_account,
148//!         nft_collection_mint,
149//!         nft_collection_metadata_account,
150//!         nft_collection_master_edition_account,
151//!     }
152//!     .instruction(ix_args);
153//!
154//!     Ok(Transaction::new_unsigned(Message::new(
155//!         &[ix],
156//!         Some(&user_wallet),
157//!     )))
158//! }
159//!
160//! // Creates a transaction to redeem a bond once payout is available
161//!
162//!
163//! let client = RpcClient::new(rpc_url);
164//! // Some user wallet keypair
165//! let user_wallet = Keypair::from_str("user_wallet").unwrap();
166//! // The mint for the bond underlying the NFT
167//! let mint = Pubkey::from_str("mint").unwrap();
168//! // The addres of the NFT
169//! let nft_mint = Pubkey::from_str("nft_mint").unwrap();
170//! // Get an un-signed transaction
171//! let tx = make_redeem_bond_transaction(client, user_wallet, mint, nft_mint).await?;
172//! // Sign the transaction with the users keypair and then...
173//! // Submit the transaction
174//! let sig = client.send_and_confirm_transaction(&tx).await?;
175//!
176//! pub async fn make_redeem_bond_transaction(
177//!     client: &RpcClient,
178//!     user_wallet: Pubkey,
179//!     mint: Pubkey,
180//!     nft_mint: Pubkey,
181//! ) -> Result<Transaction> {
182//!     let bond_account = find_bond_pda(mint).0;
183//!     let data = client.get_account_data(&bond_account).await?;
184//!     let bond = Bond::from_bytes(&data).unwrap();
185//!     let payment_feed_account = find_payment_feed_pda(bond.payment_feed_type).0;
186//!     let issuance_account = find_issuance_pda(bond_account, bond.issuance_number).0;
187//!     let payment_mint_account = find_payment_pda(issuance_account).0;
188//!     let nft_issuance_vault_account = find_nft_issuance_vault_pda(nft_mint).0;
189//!     let nft_issuance_vault_token_account = get_associated_token_address_with_program_id(
190//!         &nft_issuance_vault_account,
191//!         &mint,
192//!         &spl_token_2022::id(),
193//!     );
194//!     let user_nft_token_account = get_associated_token_address(&user_wallet, &nft_mint);
195//!     let user_payment_token_account =
196//!         get_associated_token_address(&user_wallet, &payment_mint_account);
197//!     let nft_metadata_account = Metadata::find_pda(&nft_mint).0;
198//!     let nft_master_edition_account = MasterEdition::find_pda(&nft_mint).0;
199//!     let nft_collection_metadata_account = Metadata::find_pda(&nft_mint).0;
200//!     let payout_account = find_payout_pda(issuance_account).0;
201//!     let payout_token_account = get_associated_token_address(&payout_account, &mint);
202//!     let token2022_program = spl_token_2022::id();
203//!     let associated_token_program = spl_associated_token_account::id();
204//!     let token_program = spl_token::id();
205//!     let metadata_program = mpl_token_metadata::ID;
206//!     let system_program = system_program::id();
207//!     let ix = RedeemBond {
208//!         bond_account,
209//!         mint_account: mint,
210//!         issuance_account,
211//!         user_wallet,
212//!         user_nft_token_account,
213//!         user_payment_token_account,
214//!         payment_mint_account,
215//!         payment_feed_account,
216//!         nft_mint_account: nft_mint,
217//!         nft_metadata_account,
218//!         nft_master_edition_account,
219//!         nft_collection_metadata_account,
220//!         nft_issuance_vault_account,
221//!         nft_issuance_vault_token_account,
222//!         payout_account,
223//!         payout_token_account,
224//!         token2022_program,
225//!         associated_token_program,
226//!         token_program,
227//!         metadata_program,
228//!         system_program,
229//!     }
230//!     .instruction();
231//!
232//!     Ok(Transaction::new_unsigned(Message::new(
233//!         &[ix],
234//!         Some(&user_wallet),
235//!     )))
236//! }
237//!
238//! // Creates a transaction to redeem a purchase order
239//!
240//!
241//! let client = RpcClient::new(rpc_url);
242//! // Some user wallet keypair
243//! let user_wallet = Keypair::from_str("user_wallet").unwrap();
244//! // The mint for the bond underlying the NFT
245//! let mint = Pubkey::from_str("mint").unwrap();
246//! // The address of the NFT
247//! let nft_mint = Pubkey::from_str("nft_mint").unwrap();
248//! // Get an un-signed transaction
249//! let tx = make_redeem_purchase_order_transaction(client, user_wallet, mint, nft_mint).await?;
250//! // Sign the transaction with the users keypair and then...
251//! // Submit the transaction
252//! let sig = client.send_and_confirm_transaction(&tx).await?;
253//!
254//! pub async fn make_redeem_purchase_order_transaction(
255//!     client: &RpcClient,
256//!     user_wallet: Pubkey,
257//!     mint: Pubkey,
258//!     nft_mint: Pubkey,
259//! ) -> Result<Transaction> {
260//!     let mint_auth_multisig_account = get_bond_mint_auth_multisig_if_needed(&client, mint).await?;
261//!     let bond_account = find_bond_pda(mint).0;
262//!     let data = client.get_account_data(&bond_account).await?;
263//!     let bond = Bond::from_bytes(&data).unwrap();
264//!     let issuance_account = find_issuance_pda(bond_account, bond.issuance_number).0;
265//!     let purchase_order_vault_account = find_purchase_order_pda(nft_mint).0;
266//!     let user_token_account =
267//!         get_associated_token_address_with_program_id(&user_wallet, &mint, &spl_token_2022::id());
268//!     let user_nft_token_account = get_associated_token_address(&user_wallet, &nft_mint);
269//!     let nft_metadata_account = Metadata::find_pda(&nft_mint).0;
270//!     let nft_master_edition_account = MasterEdition::find_pda(&nft_mint).0;
271//!     let nft_collection_metadata_account = Metadata::find_pda(&nft_mint).0;
272//!     let token2022_program = spl_token_2022::id();
273//!     let associated_token_program = spl_associated_token_account::id();
274//!     let token_program = spl_token::id();
275//!     let metadata_program = mpl_token_metadata::ID;
276//!     let system_program = system_program::id();
277//!
278//!     let ix = RedeemPurchaseOrder {
279//!         user_wallet,
280//!         bond_account,
281//!         mint_account: mint,
282//!         issuance_account,
283//!         purchase_order_vault_account,
284//!         user_token_account,
285//!         user_nft_token_account,
286//!         nft_mint_account: nft_mint,
287//!         nft_metadata_account,
288//!         nft_master_edition_account,
289//!         nft_collection_metadata_account,
290//!         token2022_program,
291//!         token_program,
292//!         associated_token_program,
293//!         metadata_program,
294//!         system_program,
295//!         mint_auth_multisig_account,
296//!     }
297//!     .instruction();
298//!
299//!     Ok(Transaction::new_unsigned(Message::new(
300//!         &[ix],
301//!         Some(&user_wallet),
302//!     )))
303//! }
304//!
305//! // Create a purchase order.
306//!
307//! // The user will need to have already completed the KYC process for the transaction to be successful.
308//! // See [API Reference](https://docs.etherfuse.com/api-reference/onboarding/generate-onboarding-url) for more information.
309//!
310//!
311//! let client = RpcClient::new(rpc_url);
312//! // Some user wallet keypair
313//! let user_wallet = Keypair::from_str("user_wallet").unwrap();
314//! // The mint for the bond underlying the NFT
315//! let mint = Pubkey::from_str("mint").unwrap();
316//! // The amount of tokens to purchase
317//! let token_amount = 1000000;
318//! // Get an un-signed transaction
319//! let tx = make_create_purchase_order_transaction(client, token_amount, user_wallet, mint).await?;
320//! // Sign the transaction with the users keypair and then...
321//! // Submit the transaction
322//! let sig = client.send_and_confirm_transaction(&tx).await?;
323//!
324//! pub async fn make_create_purchase_order_transaction(
325//!     client: &RpcClient,
326//!     token_amount: u64,
327//!     user_wallet: Pubkey,
328//!     mint: Pubkey,
329//! ) -> Result<Transaction> {
330//!     let ix_args = CreatePurchaseOrderV2InstructionArgs {
331//!         amount: token_amount,
332//!     };
333//!     let addresses = generate_buy_addresses(client, mint, user_wallet).await?;
334//!     let nft_mint = Keypair::new();
335//!     let nft_mint_account = nft_mint.pubkey();
336//!     let user_nft_token_account = get_associated_token_address(&user_wallet, &nft_mint_account);
337//!     let nft_master_edition_account = MasterEdition::find_pda(&nft_mint_account).0;
338//!     let purchase_order_vault_account = find_purchase_order_pda(nft_mint_account).0;
339//!     let nft_collection_mint = find_config_pda().0;
340//!     let nft_collection_metadata_account = Metadata::find_pda(&nft_collection_mint).0;
341//!     let nft_collection_master_edition_account = MasterEdition::find_pda(&nft_collection_mint).0;
342//!     let nft_metadata_account = Metadata::find_pda(&nft_mint_account).0;
343//!
344//!     let ix = CreatePurchaseOrderV2 {
345//!         kyc_account: find_kyc_pda(user_wallet).0,
346//!         user_wallet,
347//!         bond_account: addresses.bond_account,
348//!         issuance_account: addresses.issuance_account,
349//!         payment_account: addresses.payment_account,
350//!         payment_token_account: addresses.payment_token_account,
351//!         user_payment_token_account: addresses.user_payment_token_account,
352//!         user_nft_token_account,
353//!         nft_mint_account,
354//!         nft_metadata_account,
355//!         nft_master_edition_account,
356//!         purchase_order_vault_account,
357//!         nft_collection_mint,
358//!         nft_collection_metadata_account,
359//!         nft_collection_master_edition_account,
360//!         payment_mint_account: addresses.payment_mint_account,
361//!         payment_feed_account: addresses.payment_feed_account,
362//!         payment_base_price_feed_account: addresses.payment_price_feed_account,
363//!         config_account: find_config_pda().0,
364//!         associated_token_program: spl_associated_token_account::id(),
365//!         token2022_program: spl_token_2022::id(),
366//!         token_program: spl_token::id(),
367//!         system_program: system_program::id(),
368//!         metadata_program: mpl_token_metadata::ID,
369//!         sysvar_instructions: solana_sdk::sysvar::instructions::id(),
370//!         payment_quote_price_feed_account: addresses.payment_quote_price_feed_account,
371//!     }
372//!     .instruction(ix_args);
373//!
374//!     Ok(Transaction::new_unsigned(Message::new(
375//!         &[ix],
376//!         Some(&user_wallet),
377//!     )))
378//! }
379//!
380//! async fn get_bond_mint_auth_multisig_if_needed(
381//!     rpc_client: &RpcClient,
382//!     mint_account: Pubkey,
383//! ) -> Result<Option<Pubkey>> {
384//!     let bond_account = find_bond_pda(mint_account).0;
385//!     let data = rpc_client.get_account_data(&bond_account).await?;
386//!     let bond = Bond::from_bytes(&data).unwrap();
387//!
388//!     // Get the mint_auth_multisig_account if is_authority_multisig is true
389//!     let mint_auth_multisig_account = if bond.is_authority_multisig {
390//!         let bond_multisig_meta_account = find_bond_multisig_meta_pda(mint_account).0;
391//!         let bond_multisig_meta_data = rpc_client
392//!             .get_account_data(&bond_multisig_meta_account)
393//!             .await?;
394//!         let bond_multisig_meta = BondMultisigMeta::from_bytes(&bond_multisig_meta_data).unwrap();
395//!         Some(bond_multisig_meta.mint_auth_multisig)
396//!     } else {
397//!         None
398//!     };
399//!
400//!     Ok(mint_auth_multisig_account)
401//! }
402//!
403//! struct BuyAddresses {
404//!     issuance_account: Pubkey,
405//!     payment_account: Pubkey,
406//!     payment_mint_account: Pubkey,
407//!     payment_token_account: Pubkey,
408//!     user_payment_token_account: Pubkey,
409//!     bond_account: Pubkey,
410//!     payment_price_feed_account: Pubkey,
411//!     payment_quote_price_feed_account: Option<Pubkey>,
412//!     kyc_account: Pubkey,
413//!     payment_feed_account: Pubkey,
414//!     user_token_account: Pubkey,
415//!     token_2022_program: Pubkey,
416//!     associated_token_program: Pubkey,
417//!     token_program: Pubkey,
418//!     system_program: Pubkey,
419//! }
420//!
421//! async fn generate_buy_addresses(
422//!     client: &RpcClient,
423//!     mint_account: Pubkey,
424//!     user_wallet: Pubkey,
425//! ) -> Result<BuyAddresses> {
426//!     let bond_account = find_bond_pda(mint_account).0;
427//!     let issuance_account = find_issuance_pda(bond_account, 1).0;
428//!     let payment_account = find_payment_pda(issuance_account).0;
429//!     let data = client.get_account_data(&bond_account).await?;
430//!     let bond = Bond::from_bytes(&data).unwrap();
431//!     let payment_feed_account = find_payment_feed_pda(bond.payment_feed_type).0;
432//!     let data = client.get_account_data(&payment_feed_account).await?;
433//!     let payment_feed = PaymentFeed::from_bytes(&data).unwrap();
434//!     let payment_mint_account = payment_feed.payment_mint;
435//!     let mut payment_quote_price_feed_account = None;
436//!     if payment_feed.quote_price_feed != Pubkey::default() {
437//!         payment_quote_price_feed_account = Some(payment_feed.quote_price_feed);
438//!     }
439//!     let user_token_account = get_associated_token_address_with_program_id(
440//!         &user_wallet,
441//!         &mint_account,
442//!         &spl_token_2022::id(),
443//!     );
444//!     let payment_price_feed_account = payment_feed.base_price_feed;
445//!     let kyc_account = find_kyc_pda(user_wallet).0;
446//!     let payment_token_account =
447//!         get_associated_token_address(&payment_account, &payment_mint_account);
448//!     let user_payment_token_account =
449//!         get_associated_token_address(&user_wallet, &payment_mint_account);
450//!
451//!     Ok(BuyAddresses {
452//!         issuance_account,
453//!         payment_account,
454//!         payment_mint_account,
455//!         payment_token_account,
456//!         user_payment_token_account,
457//!         bond_account,
458//!         payment_price_feed_account,
459//!         payment_quote_price_feed_account,
460//!         kyc_account,
461//!         payment_feed_account,
462//!         user_token_account,
463//!         token_2022_program: spl_token_2022::id(),
464//!         associated_token_program: spl_associated_token_account::id(),
465//!         token_program: spl_token::id(),
466//!         system_program: system_program::id(),
467//!     })
468//! }
469
470#[cfg(feature = "sdk")]
471#[doc(hidden)]
472pub mod sdk;
473
474use generated::types::PaymentFeedType;
475use solana_program::pubkey;
476use solana_program::pubkey::Pubkey;
477
478#[allow(unused)]
479#[allow(clippy::identity_op)]
480mod generated;
481
482pub use generated::programs::STABLEBOND_ID;
483pub use generated::programs::STABLEBOND_ID as ID;
484
485// Hide everything, and only re-export the ones we want to expose
486// in public API. This doesn't remove it from the binary, but it will make it
487// harder to use/consume.
488pub use generated::accounts;
489pub use generated::errors;
490#[doc(hidden)]
491pub use generated::instructions;
492#[doc(hidden)]
493pub use generated::programs;
494pub use generated::types;
495
496// ---- Public API ----
497pub use generated::instructions::create_purchase_order_v2::CreatePurchaseOrderV2;
498pub use generated::instructions::create_purchase_order_v2::CreatePurchaseOrderV2Builder;
499pub use generated::instructions::create_purchase_order_v2::CreatePurchaseOrderV2InstructionArgs;
500pub use generated::instructions::purchase_bond_v2::PurchaseBondV2;
501pub use generated::instructions::purchase_bond_v2::PurchaseBondV2Builder;
502pub use generated::instructions::purchase_bond_v2::PurchaseBondV2InstructionArgs;
503pub use generated::instructions::redeem_bond::RedeemBond;
504pub use generated::instructions::redeem_bond::RedeemBondBuilder;
505pub use generated::instructions::redeem_purchase_order::RedeemPurchaseOrder;
506pub use generated::instructions::redeem_purchase_order::RedeemPurchaseOrderBuilder;
507pub use generated::instructions::request_redemption_v2::RequestRedemptionV2;
508pub use generated::instructions::request_redemption_v2::RequestRedemptionV2Builder;
509pub use generated::instructions::request_redemption_v2::RequestRedemptionV2InstructionArgs;
510
511impl AsRef<[u8]> for PaymentFeedType {
512    fn as_ref(&self) -> &[u8] {
513        match self {
514            Self::UsdcUsd => b"usdc_usd",
515            Self::UsdcMxn => b"usdc_mxn",
516            Self::SwitchboardUsdcUsd => b"switchboard_usdc_usd",
517            Self::SwitchboardUsdcMxn => b"switchboard_usdc_mxn",
518            Self::Stub => b"stub",
519            Self::SwitchboardUsdcBrl => b"switchboard_usdc_brl",
520            Self::SwitchboardUsdcEur => b"switchboard_usdc_eur",
521            Self::SwitchboardUsdcGbp => b"switchboard_usdc_gbp",
522            Self::SwitchboardOnDemandUsdcMxn => b"switchboard_on_demand_usdc_mxn",
523            Self::SwitchboardOnDemandUsdcBrl => b"switchboard_on_demand_usdc_brl",
524            Self::SwitchboardOnDemandUsdcEur => b"switchboard_on_demand_usdc_eur",
525            Self::SwitchboardOnDemandUsdcGbp => b"switchboard_on_demand_usdc_gbp",
526            Self::SwitchboardOnDemandUsdcUsd => b"switchboard_on_demand_usdc_usd",
527        }
528    }
529}
530
531pub fn find_config_pda() -> (Pubkey, u8) {
532    Pubkey::find_program_address(&["config".to_string().as_ref()], &crate::ID)
533}
534
535pub fn find_delegate_pda(delegate_wallet: Pubkey) -> (Pubkey, u8) {
536    Pubkey::find_program_address(
537        &["delegate".to_string().as_ref(), delegate_wallet.as_ref()],
538        &crate::ID,
539    )
540}
541
542pub fn find_bond_pda(mint: Pubkey) -> (Pubkey, u8) {
543    Pubkey::find_program_address(&["bond".to_string().as_ref(), mint.as_ref()], &crate::ID)
544}
545
546pub fn find_issuance_pda(bond: Pubkey, issuance_number: u64) -> (Pubkey, u8) {
547    Pubkey::find_program_address(
548        &[
549            "issuance".to_string().as_ref(),
550            bond.as_ref(),
551            &issuance_number.to_le_bytes(),
552        ],
553        &crate::ID,
554    )
555}
556
557pub fn find_payment_pda(issuance: Pubkey) -> (Pubkey, u8) {
558    Pubkey::find_program_address(
559        &["payment".to_string().as_ref(), issuance.as_ref()],
560        &crate::ID,
561    )
562}
563
564pub fn find_payout_pda(issuance: Pubkey) -> (Pubkey, u8) {
565    Pubkey::find_program_address(
566        &["payout".to_string().as_ref(), issuance.as_ref()],
567        &crate::ID,
568    )
569}
570
571pub fn find_payment_feed_pda(payment_feed_type: PaymentFeedType) -> (Pubkey, u8) {
572    Pubkey::find_program_address(
573        &[
574            "payment_feed".to_string().as_ref(),
575            payment_feed_type.as_ref(),
576        ],
577        &crate::ID,
578    )
579}
580
581pub fn find_nft_issuance_vault_pda(nft_mint: Pubkey) -> (Pubkey, u8) {
582    Pubkey::find_program_address(
583        &["nft_issuance_vault".to_string().as_ref(), nft_mint.as_ref()],
584        &crate::ID,
585    )
586}
587
588pub fn find_access_pass_pda(user_wallet: Pubkey) -> (Pubkey, u8) {
589    Pubkey::find_program_address(
590        &["access_pass".to_string().as_ref(), user_wallet.as_ref()],
591        &crate::ID,
592    )
593}
594
595pub fn find_purchase_order_pda(nft_mint: Pubkey) -> (Pubkey, u8) {
596    Pubkey::find_program_address(
597        &["purchase_order".to_string().as_ref(), nft_mint.as_ref()],
598        &crate::ID,
599    )
600}
601
602pub fn find_kyc_pda(user_wallet: Pubkey) -> (Pubkey, u8) {
603    Pubkey::find_program_address(
604        &["kyc".to_string().as_ref(), user_wallet.as_ref()],
605        &crate::ID,
606    )
607}
608
609pub fn find_sell_liquidity_pda(bond: Pubkey) -> (Pubkey, u8) {
610    Pubkey::find_program_address(
611        &["sell_liquidity".to_string().as_ref(), bond.as_ref()],
612        &crate::ID,
613    )
614}
615
616pub fn find_offramp_pda(external_identifier: &[u8; 16]) -> (Pubkey, u8) {
617    Pubkey::find_program_address(
618        &["offramp".to_string().as_ref(), external_identifier.as_ref()],
619        &crate::ID,
620    )
621}
622
623pub fn find_onramp_pda(external_identifier: &[u8; 16]) -> (Pubkey, u8) {
624    Pubkey::find_program_address(
625        &["onramp".to_string().as_ref(), external_identifier.as_ref()],
626        &crate::ID,
627    )
628}
629
630pub fn find_bond_multisig_meta_pda(mint: Pubkey) -> (Pubkey, u8) {
631    Pubkey::find_program_address(
632        &["bond_multisig_meta".to_string().as_ref(), mint.as_ref()],
633        &crate::ID,
634    )
635}
636
637cfg_if::cfg_if! {
638    if #[cfg(feature = "mainnet-beta")] {
639        pub const PYTH_PROGRAM: Pubkey = pubkey!("FsJ3A3u2vn5cTVofAjvy6y5kwABJAqYWpe4975bi2epH");
640    } else {
641        pub const PYTH_PROGRAM: Pubkey = pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s");
642    }
643}
644
645cfg_if::cfg_if! {
646    if #[cfg(feature = "mainnet-beta")] {
647        pub const PYTH_USDC: Pubkey = pubkey!("Gnt27xtC473ZT2Mw5u8wZ68Z3gULkSTb5DuxJy7eJotD");
648    } else {
649        pub const PYTH_USDC: Pubkey = pubkey!("5SSkXsEKQepHHAewytPVwdej4epN1nxgLVM84L4KXgy7");
650    }
651}
652
653cfg_if::cfg_if! {
654    if #[cfg(feature = "mainnet-beta")] {
655        pub const PROGRAM_OWNER: Pubkey = pubkey!("owNEred9E1jEEFsS2E3LRMNtAnUf6XBseqBnyKc33Pz");
656    } else {
657        pub const PROGRAM_OWNER: Pubkey = pubkey!("9Qx7RaqE56rHz4k1bM3Bta2dmqYGd8nLQxonde26MukW");
658    }
659}