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}