use super::{
enums::{AssetSortBy, AssetSortDirection, Context, Interface, OwnershipModel, RoyaltyModel, Scope, UseMethod},
AccountWebhookEncoding, CollectionIdentifier, PriorityLevel, SearchAssetsOptions, SearchConditionType, TokenType,
TransactionStatus, TransactionType, UiTransactionEncoding, WebhookType,
};
use crate::types::{DisplayOptions, Encoding, GetAssetOptions, GpaFilter, TokenAccountsOwnerFilter};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::sync::Arc;
use std::time::Duration;
use solana_client::rpc_config::RpcSendTransactionConfig;
use solana_commitment_config::CommitmentLevel;
use solana_sdk::{instruction::Instruction, message::AddressLookupTableAccount, signature::Signer};
#[derive(Debug, Clone, PartialEq)]
pub enum Cluster {
Devnet,
MainnetBeta,
StakedMainnetBeta,
}
#[derive(Debug, Clone)]
pub struct HeliusEndpoints {
pub api: String,
pub rpc: String,
}
impl HeliusEndpoints {
pub fn for_cluster(cluster: &Cluster) -> Self {
match cluster {
Cluster::Devnet => HeliusEndpoints {
api: "https://api-devnet.helius-rpc.com/".to_string(),
rpc: "https://devnet.helius-rpc.com/".to_string(),
},
Cluster::MainnetBeta => HeliusEndpoints {
api: "https://api-mainnet.helius-rpc.com/".to_string(),
rpc: "https://mainnet.helius-rpc.com/".to_string(),
},
Cluster::StakedMainnetBeta => HeliusEndpoints {
api: "https://api-mainnet.helius-rpc.com/".to_string(),
rpc: "https://staked.helius-rpc.com/".to_string(),
},
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
pub struct RpcRequest<T> {
pub jsonrpc: String,
pub id: String,
pub method: String,
#[serde(rename = "params")]
pub parameters: T,
}
impl<T> RpcRequest<T> {
pub fn new(method: String, parameters: T) -> Self {
Self {
jsonrpc: "2.0".to_string(),
id: "helius-rust-sdk".to_string(),
method,
parameters,
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
pub struct RpcResponse<T> {
pub jsonrpc: String,
pub id: String,
pub result: T,
}
#[derive(Serialize, Deserialize, Default, Debug)]
pub struct GetAssetsByOwner {
#[serde(rename = "ownerAddress")]
pub owner_address: String,
pub page: u32,
pub limit: Option<i32>,
pub before: Option<String>,
pub after: Option<String>,
#[serde(rename = "displayOptions")]
pub display_options: Option<DisplayOptions>,
#[serde(rename = "sortBy")]
pub sort_by: Option<AssetSorting>,
#[serde(default)]
pub cursor: Option<String>,
}
#[derive(Serialize, Deserialize, Default, Debug)]
pub struct GetAssetsByAuthority {
#[serde(rename = "authorityAddress")]
pub authority_address: String,
pub page: u32,
pub limit: Option<u32>,
pub before: Option<String>,
pub after: Option<String>,
#[serde(rename = "displayOptions")]
pub display_options: Option<DisplayOptions>,
#[serde(rename = "sortBy")]
pub sort_by: Option<AssetSorting>,
#[serde(default)]
pub cursor: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct GetAsset {
pub id: String,
#[serde(rename = "displayOptions")]
pub display_options: Option<GetAssetOptions>,
}
#[derive(Debug, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct GetAssetsByCreator {
pub creator_address: String,
pub only_verified: Option<bool>,
pub sort_by: Option<AssetSorting>,
pub limit: Option<u32>,
pub page: Option<u32>,
pub before: Option<String>,
pub after: Option<String>,
#[serde(default, alias = "displayOptions")]
pub options: Option<DisplayOptions>,
#[serde(default)]
pub cursor: Option<String>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetAssetBatch {
pub ids: Vec<String>,
#[serde(rename = "displayOptions")]
pub display_options: Option<GetAssetOptions>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetAssetProof {
pub id: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct GetAssetProofBatch {
pub ids: Vec<String>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct AssetProof {
pub root: String,
pub proof: Vec<String>,
pub node_index: i32,
pub leaf: String,
pub tree_id: String,
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct GetAssetsByGroup {
pub group_key: String,
pub group_value: String,
pub sort_by: Option<AssetSorting>,
pub limit: Option<u32>,
pub page: Option<u32>,
pub before: Option<String>,
pub after: Option<String>,
#[serde(default, alias = "displayOptions")]
pub options: Option<DisplayOptions>,
#[serde(default)]
pub cursor: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct SearchAssets {
pub negate: Option<bool>,
pub condition_type: Option<SearchConditionType>,
pub interface: Option<Interface>,
pub owner_address: Option<String>,
pub owner_type: Option<OwnershipModel>,
pub creator_address: Option<String>,
pub creator_verified: Option<bool>,
pub authority_address: Option<String>,
pub grouping: Option<(String, String)>,
pub delegate: Option<String>,
pub frozen: Option<bool>,
pub supply: Option<u64>,
pub supply_mint: Option<String>,
pub compressed: Option<bool>,
pub compressible: Option<bool>,
pub royalty_target_type: Option<RoyaltyModel>,
pub royalty_target: Option<String>,
pub royalty_amount: Option<u32>,
pub burnt: Option<bool>,
pub sort_by: Option<AssetSorting>,
pub limit: Option<u32>,
pub page: Option<u32>,
pub before: Option<String>,
pub after: Option<String>,
#[serde(default)]
pub json_uri: Option<String>,
#[serde(default)]
pub not: Option<NotFilter>,
#[serde(default, alias = "displayOptions")]
pub options: Option<SearchAssetsOptions>,
#[serde(default)]
pub cursor: Option<String>,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub collections: Option<Vec<String>>,
#[serde(default)]
pub token_type: Option<TokenType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<CreatedAtFilter>,
#[serde(default)]
pub tree: Option<String>,
#[serde(default)]
pub collection_nft: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct GetAssetSignatures {
pub id: Option<String>,
pub limit: Option<u32>,
pub page: Option<u32>,
pub before: Option<String>,
pub after: Option<String>,
pub tree: Option<String>,
pub leaf_index: Option<i64>,
#[serde(default)]
pub cursor: Option<String>,
#[serde(default)]
pub sort_direction: Option<AssetSortDirection>,
}
#[derive(Debug, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct GetTokenAccounts {
pub owner: Option<String>,
pub mint: Option<String>,
pub limit: Option<u32>,
pub page: Option<u32>,
pub before: Option<String>,
pub after: Option<String>,
#[serde(default, alias = "displayOptions")]
pub options: Option<DisplayOptions>,
#[serde(default)]
pub cursor: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct GetNftEditions {
pub mint: Option<String>,
pub limit: Option<u32>,
pub page: Option<u32>,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct AssetSorting {
pub sort_by: AssetSortBy,
pub sort_direction: Option<AssetSortDirection>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct ApiResponse<T> {
pub jsonrpc: String,
pub result: T,
pub id: String,
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct NativeBalance {
pub lamports: u64,
pub price_per_sol: f64,
pub total_price: f64,
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct AssetList {
#[serde(skip_serializing_if = "Option::is_none")]
pub grand_total: Option<u64>,
pub total: u32,
pub limit: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub page: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub before: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub after: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cursor: Option<String>,
pub items: Vec<Asset>,
#[serde(rename = "nativeBalance", skip_serializing_if = "Option::is_none")]
pub native_balance: Option<NativeBalance>,
#[serde(skip_serializing_if = "Option::is_none")]
pub errors: Option<Vec<AssetError>>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(default)]
pub struct TransactionSignatureList {
pub total: u32,
pub limit: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub page: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub before: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub after: Option<String>,
pub items: Vec<(String, String)>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(default)]
pub struct TokenAccountsList {
pub total: u32,
pub limit: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub page: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cursor: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub before: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub after: Option<String>,
pub token_accounts: Vec<TokenAccount>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct EditionsList {
pub total: u32,
pub limit: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub page: Option<u32>,
pub master_edition_address: String,
pub supply: u64,
pub max_supply: Option<u64>,
pub editions: Vec<Edition>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Asset {
pub interface: Interface,
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub content: Option<Content>,
#[serde(skip_serializing_if = "Option::is_none")]
pub authorities: Option<Vec<Authorities>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub compression: Option<Compression>,
#[serde(skip_serializing_if = "Option::is_none")]
pub grouping: Option<Vec<Group>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub royalty: Option<Royalty>,
#[serde(skip_serializing_if = "Option::is_none")]
pub creators: Option<Vec<Creator>>,
pub ownership: Ownership,
#[serde(skip_serializing_if = "Option::is_none")]
pub uses: Option<Uses>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supply: Option<Supply>,
pub mutable: bool,
pub burnt: bool,
pub mint_extensions: Option<Value>,
pub token_info: Option<TokenInfo>,
#[serde(skip_serializing_if = "Option::is_none")]
pub group_definition: Option<GroupDefinition>,
#[serde(skip_serializing_if = "Option::is_none")]
pub system: Option<SystemInfo>,
#[serde(skip_serializing_if = "Option::is_none")]
pub plugins: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub unknown_plugins: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mpl_core_info: Option<MplCoreInfo>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(default)]
pub struct AssetError {
pub id: String,
pub error: String,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct MintExtensions {
pub confidential_transfer_mint: Option<ConfidentialTransferMint>,
pub confidential_transfer_fee_config: Option<ConfidentialTransferFeeConfig>,
pub transfer_fee_config: Option<TransferFeeConfig>,
pub metadata_pointer: MetadataPointer,
pub mint_close_authority: MintCloseAuthority,
pub permanent_delegate: PermanentDelegate,
pub transfer_hook: TransferHook,
pub interest_bearing_config: InterestBearingConfig,
pub default_account_state: DefaultAccountState,
pub confidential_transfer_account: ConfidentialTransferAccount,
pub metadata: MintExtensionMetadata,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ConfidentialTransferMint {
pub authority: String,
pub auto_approve_new_accounts: bool,
pub auditor_elgamal_pubkey: String,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ConfidentialTransferFeeConfig {
pub authority: String,
pub withdraw_withheld_authority_elgamal_pubkey: String,
pub harvest_to_mint_enabled: bool,
pub withheld_amount: String,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct TransferFeeConfig {
pub transfer_fee_config_authority: String,
pub withdraw_withheld_authority: String,
pub withheld_amount: i32,
pub older_transfer_fee: OlderTransferFee,
pub new_transfer_fee: NewTransferFee,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct OlderTransferFee {
pub epoch: String,
pub maximum_fee: String,
pub transfer_fee_basis_points: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct NewTransferFee {
pub epoch: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct MetadataPointer {
pub authority: String,
#[serde(rename = "metadataAddress")]
pub metadata_address: String,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct MintCloseAuthority {
pub close_authority: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct PermanentDelegate {
pub delegate: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct TransferHook {
pub authority: String,
#[serde(rename = "programId")]
pub program_id: String,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct InterestBearingConfig {
pub rate_authority: String,
pub initialization_timestamp: i32,
pub pre_update_average_rate: i32,
pub last_update_timestamp: i32,
pub current_rate: i32,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct DefaultAccountState {
pub state: String,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ConfidentialTransferAccount {
pub approved: bool,
pub elgamal_pubkey: String,
pub pending_balance_lo: String,
pub pending_balance_hi: String,
pub available_balance: String,
pub decryptable_available_balance: String,
pub allow_confidential_credits: bool,
pub allow_non_confidential_credits: bool,
pub pending_balance_credit_counter: i32,
pub maximum_pending_balance_credit_counter: i32,
pub expected_pending_balance_credit_counter: i32,
pub actual_pending_balance_credit_counter: i32,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct MintExtensionMetadata {
#[serde(rename = "updateAuthority")]
pub update_authority: String,
pub mint: String,
pub name: String,
pub symbol: String,
pub uri: String,
#[serde(rename = "additionalMetadata")]
pub additional_metadata: AdditionalMetadata,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct AdditionalMetadata {
pub key: String,
pub value: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct TokenInfo {
pub symbol: Option<String>,
pub balance: Option<u64>,
pub supply: Option<u64>,
pub decimals: Option<i32>,
pub token_program: Option<String>,
pub associated_token_address: Option<String>,
pub price_info: Option<PriceInfo>,
pub mint_authority: Option<String>,
pub freeze_authority: Option<String>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct PriceInfo {
pub price_per_token: f32,
pub currency: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Inscription {
pub order: i32,
pub size: i32,
#[serde(rename = "contentType")]
pub content_type: String,
pub encoding: String,
#[serde(rename = "validationHash")]
pub validation_hash: String,
#[serde(rename = "inscriptionDataAccount")]
pub inscription_data_account: String,
pub authority: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Content {
#[serde(rename = "schema", default)]
#[serde(alias = "$schema")]
pub schema: String,
pub json_uri: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub files: Option<Vec<File>>,
pub metadata: Metadata,
#[serde(skip_serializing_if = "Option::is_none")]
pub links: Option<Links>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct File {
pub uri: Option<String>,
pub mime: Option<String>,
pub cdn_uri: Option<String>,
pub quality: Option<FileQuality>,
pub contexts: Option<Vec<Context>>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct FileQuality {
#[serde(rename = "$$schema")]
pub schema: String,
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(untagged)]
pub enum Attributes {
List(Vec<Attribute>),
Map(serde_json::Map<String, Value>),
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Metadata {
pub attributes: Option<Attributes>,
pub description: Option<String>,
pub name: Option<String>,
pub symbol: Option<String>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Attribute {
pub value: Value,
pub trait_type: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Links {
pub external_url: Option<String>,
pub image: Option<String>,
pub animation_url: Option<String>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Authorities {
pub address: String,
pub scopes: Vec<Scope>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Group {
pub group_key: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub group_value: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub verified: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub collection_metadata: Option<CollectionMetadata>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct CollectionMetadata {
pub name: Option<String>,
pub symbol: Option<String>,
pub image: Option<String>,
pub description: Option<String>,
pub external_url: Option<String>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Compression {
pub eligible: bool,
pub compressed: bool,
pub data_hash: String,
pub creator_hash: String,
pub asset_hash: String,
pub tree: String,
pub seq: i64,
pub leaf_id: i64,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Creator {
pub address: String,
pub share: i32,
pub verified: bool,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Royalty {
pub royalty_model: RoyaltyModel,
pub target: Option<String>,
pub percent: f64,
pub basis_points: u32,
pub primary_sale_happened: bool,
pub locked: bool,
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct Ownership {
pub frozen: bool,
pub delegated: bool,
pub delegate: Option<String>,
pub ownership_model: OwnershipModel,
pub owner: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Uses {
pub use_method: UseMethod,
pub remaining: u64,
pub total: u64,
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct Supply {
pub print_max_supply: Option<u64>,
pub print_current_supply: Option<u64>,
pub edition_nonce: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub edition_number: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub master_edition_mint: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct GroupDefinition {
pub group_key: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub group_value: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub size: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub asset_id: Option<Vec<u8>>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct SystemInfo {
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<i64>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct CreatedAtFilter {
#[serde(skip_serializing_if = "Option::is_none")]
pub after: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub before: Option<i64>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct MplCoreInfo {
#[serde(skip_serializing_if = "Option::is_none")]
pub num_minted: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub current_size: Option<i32>,
pub plugins_json_version: Option<i32>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct NotFilter {
pub collections: Option<Vec<String>>,
pub owners: Option<Vec<Vec<u8>>>,
pub creators: Option<Vec<Vec<u8>>>,
pub authorities: Option<Vec<Vec<u8>>>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct TokenAccount {
pub address: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub mint: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub owner: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub amount: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub delegate: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub delegated_amount: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub token_extensions: Option<Value>,
pub frozen: bool,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Edition {
pub mint: String,
pub edition_address: String,
pub edition: Option<u64>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct MintCompressedNftRequest {
pub name: String,
pub symbol: String,
pub description: String,
pub owner: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub delegate: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub collection: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub uri: Option<String>,
pub attributes: Vec<Attribute>,
#[serde(rename = "imageUrl", skip_serializing_if = "Option::is_none")]
pub image_url: Option<String>,
#[serde(rename = "externalUrl", skip_serializing_if = "Option::is_none")]
pub external_url: Option<String>,
#[serde(rename = "sellerFeeBasisPoints", skip_serializing_if = "Option::is_none")]
pub seller_fee_basis_points: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub creators: Option<Vec<Creator>>,
#[serde(rename = "confirmTransaction", skip_serializing_if = "Option::is_none")]
pub confirm_transaction: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct MintResponse {
pub signature: String,
pub minted: bool,
#[serde(rename = "assetId")]
pub asset_id: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct GetPriorityFeeEstimateOptions {
pub priority_level: Option<PriorityLevel>,
pub include_all_priority_fee_levels: Option<bool>,
pub transaction_encoding: Option<UiTransactionEncoding>,
pub lookback_slots: Option<u8>,
pub recommended: Option<bool>,
pub include_vote: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct GetPriorityFeeEstimateRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub transaction: Option<String>,
#[serde(rename = "accountKeys", skip_serializing_if = "Option::is_none")]
pub account_keys: Option<Vec<String>>,
pub options: Option<GetPriorityFeeEstimateOptions>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct MicroLamportPriorityFeeLevels {
pub min: f64,
pub low: f64,
pub medium: f64,
pub high: f64,
#[serde(rename = "veryHigh")]
pub very_high: f64,
#[serde(rename = "unsafeMax")]
pub unsafe_max: f64,
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct GetPriorityFeeEstimateResponse {
pub priority_fee_estimate: Option<f64>,
pub priority_fee_levels: Option<MicroLamportPriorityFeeLevels>,
}
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct Webhook {
#[serde(rename = "webhookID")]
pub webhook_id: String,
pub wallet: String,
pub project: String,
#[serde(rename = "webhookURL")]
pub webhook_url: String,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub transaction_types: Vec<TransactionType>,
pub account_addresses: Vec<String>,
pub webhook_type: WebhookType,
#[serde(skip_serializing_if = "Option::is_none")]
pub auth_header: Option<String>,
#[serde(default)]
pub txn_status: TransactionStatus,
#[serde(default)]
pub encoding: AccountWebhookEncoding,
#[serde(default = "default_active")]
pub active: bool,
}
fn default_active() -> bool {
true
}
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct CreateWebhookRequest {
#[serde(rename = "webhookURL")]
pub webhook_url: String,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub transaction_types: Vec<TransactionType>,
pub account_addresses: Vec<String>,
pub webhook_type: WebhookType,
#[serde(skip_serializing_if = "Option::is_none")]
pub auth_header: Option<String>,
#[serde(default)]
pub txn_status: TransactionStatus,
#[serde(default)]
pub encoding: AccountWebhookEncoding,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct CreateCollectionWebhookRequest {
pub collection_query: CollectionIdentifier,
#[serde(rename = "webhookURL")]
pub webhook_url: String,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub transaction_types: Vec<TransactionType>,
pub account_addresses: Vec<String>,
pub webhook_type: WebhookType,
#[serde(skip_serializing_if = "Option::is_none")]
pub auth_header: Option<String>,
#[serde(default)]
pub txn_status: TransactionStatus,
#[serde(default)]
pub encoding: AccountWebhookEncoding,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct EditWebhookRequest {
#[serde(skip_serializing)]
pub webhook_id: String,
#[serde(rename = "webhookURL")]
pub webhook_url: String,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub transaction_types: Vec<TransactionType>,
pub account_addresses: Vec<String>,
pub webhook_type: WebhookType,
#[serde(skip_serializing_if = "Option::is_none")]
pub auth_header: Option<String>,
#[serde(default)]
pub txn_status: TransactionStatus,
#[serde(default)]
pub encoding: AccountWebhookEncoding,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct ToggleWebhookRequest {
#[serde(skip_serializing)]
pub webhook_id: String,
pub active: bool,
}
pub struct CreateSmartTransactionConfig {
pub instructions: Vec<Instruction>,
pub signers: Vec<Arc<dyn Signer>>,
pub lookup_tables: Option<Vec<AddressLookupTableAccount>>,
pub fee_payer: Option<Arc<dyn Signer>>,
pub priority_fee_cap: Option<u64>,
pub cu_buffer_multiplier: Option<f32>,
}
impl Default for CreateSmartTransactionConfig {
fn default() -> Self {
Self {
instructions: Vec::new(),
signers: Vec::new(),
lookup_tables: None,
fee_payer: None,
priority_fee_cap: None,
cu_buffer_multiplier: Some(1.25),
}
}
}
impl CreateSmartTransactionConfig {
pub fn new(instructions: Vec<Instruction>, signers: Vec<Arc<dyn Signer>>) -> Self {
Self {
instructions,
signers,
lookup_tables: None,
fee_payer: None,
priority_fee_cap: None,
cu_buffer_multiplier: None,
}
}
}
pub struct Timeout {
pub duration: Duration,
}
impl Default for Timeout {
fn default() -> Self {
Self {
duration: Duration::from_secs(60),
}
}
}
impl From<Timeout> for Duration {
fn from(timeout: Timeout) -> Self {
timeout.duration
}
}
pub struct SmartTransactionConfig {
pub create_config: CreateSmartTransactionConfig,
pub send_options: RpcSendTransactionConfig,
pub timeout: Timeout,
}
impl SmartTransactionConfig {
pub fn new(instructions: Vec<Instruction>, signers: Vec<Arc<dyn Signer>>, timeout: Timeout) -> Self {
Self {
create_config: CreateSmartTransactionConfig::new(instructions, signers),
send_options: RpcSendTransactionConfig::default(),
timeout,
}
}
}
#[derive(Clone)]
pub struct CreateSmartTransactionSeedConfig {
pub instructions: Vec<Instruction>,
pub signer_seeds: Vec<[u8; 32]>,
pub fee_payer_seed: Option<[u8; 32]>,
pub lookup_tables: Option<Vec<AddressLookupTableAccount>>,
pub priority_fee_cap: Option<u64>,
pub cu_buffer_multiplier: Option<f32>,
}
impl Default for CreateSmartTransactionSeedConfig {
fn default() -> Self {
Self {
instructions: Vec::new(),
signer_seeds: Vec::new(),
fee_payer_seed: None,
lookup_tables: None,
priority_fee_cap: None,
cu_buffer_multiplier: Some(1.25),
}
}
}
impl CreateSmartTransactionSeedConfig {
pub fn new(instructions: Vec<Instruction>, signer_seeds: Vec<[u8; 32]>) -> Self {
Self {
instructions,
signer_seeds,
fee_payer_seed: None,
lookup_tables: None,
priority_fee_cap: None,
cu_buffer_multiplier: None,
}
}
pub fn with_fee_payer_seed(mut self, seed: [u8; 32]) -> Self {
self.fee_payer_seed = Some(seed);
self
}
pub fn with_lookup_tables(mut self, lookup_tables: Vec<AddressLookupTableAccount>) -> Self {
self.lookup_tables = Some(lookup_tables);
self
}
}
#[derive(Clone, Debug)]
pub struct SenderSendOptions {
pub region: String,
pub swqos_only: bool,
pub poll_timeout_ms: u64,
pub poll_interval_ms: u64,
}
impl Default for SenderSendOptions {
fn default() -> Self {
Self {
region: "Default".to_string(),
swqos_only: false,
poll_timeout_ms: 60_000,
poll_interval_ms: 2_000,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DataSlice {
pub length: u64,
pub offset: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GpaMemcmp {
pub offset: u64,
pub bytes: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct GetProgramAccountsV2Config {
#[serde(skip_serializing_if = "Option::is_none")]
pub commitment: Option<CommitmentLevel>,
#[serde(rename = "minContextSlot", skip_serializing_if = "Option::is_none")]
pub min_context_slot: Option<u64>,
#[serde(rename = "withContext", skip_serializing_if = "Option::is_none")]
pub with_context: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub encoding: Option<Encoding>,
#[serde(rename = "dataSlice", skip_serializing_if = "Option::is_none")]
pub data_slice: Option<DataSlice>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(rename = "paginationKey", skip_serializing_if = "Option::is_none")]
pub pagination_key: Option<String>,
#[serde(rename = "changedSinceSlot", skip_serializing_if = "Option::is_none")]
pub changed_since_slot: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub filters: Option<Vec<GpaFilter>>,
}
pub type GetProgramAccountsV2Request = (String, GetProgramAccountsV2Config);
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GpaAccount {
pub pubkey: String,
pub account: AccountInfo,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AccountInfo {
pub lamports: u64,
pub owner: String,
pub data: Value,
pub executable: bool,
#[serde(rename = "rentEpoch")]
pub rent_epoch: u64,
#[serde(default)]
pub space: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct GetProgramAccountsV2Response {
pub accounts: Vec<GpaAccount>,
#[serde(rename = "paginationKey")]
pub pagination_key: Option<String>,
#[serde(rename = "totalResults")]
pub total_results: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct GetTokenAccountsByOwnerV2Config {
#[serde(skip_serializing_if = "Option::is_none")]
pub commitment: Option<CommitmentLevel>,
#[serde(rename = "minContextSlot", skip_serializing_if = "Option::is_none")]
pub min_context_slot: Option<u64>,
#[serde(rename = "dataSlice", skip_serializing_if = "Option::is_none")]
pub data_slice: Option<DataSlice>,
#[serde(skip_serializing_if = "Option::is_none")]
pub encoding: Option<Encoding>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(rename = "paginationKey", skip_serializing_if = "Option::is_none")]
pub pagination_key: Option<String>,
#[serde(rename = "changedSinceSlot", skip_serializing_if = "Option::is_none")]
pub changed_since_slot: Option<u64>,
}
pub type GetTokenAccountsByOwnerV2Request = (String, TokenAccountsOwnerFilter, GetTokenAccountsByOwnerV2Config);
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RpcContext {
pub slot: u64,
#[serde(rename = "apiVersion")]
pub api_version: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TokenAccountRecord {
pub pubkey: String,
pub account: AccountInfo,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct GetTokenAccountsByOwnerV2Response {
pub context: Option<RpcContext>,
pub value: GetTokenAccountsByOwnerV2Value,
#[serde(rename = "paginationKey")]
pub pagination_key: Option<String>,
#[serde(rename = "totalResults")]
pub total_results: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct GetTokenAccountsByOwnerV2Value {
pub accounts: Vec<TokenAccountRecord>,
#[serde(rename = "paginationKey")]
pub pagination_key: Option<String>,
pub count: u64,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
#[serde(rename_all = "camelCase")]
pub enum TransactionDetails {
#[default]
Signatures,
Full,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
#[serde(rename_all = "camelCase")]
pub enum SortOrder {
#[default]
Desc,
Asc,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
#[serde(rename_all = "camelCase")]
pub enum TransactionStatusFilter {
#[default]
Any,
Succeeded,
Failed,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct SlotFilter {
#[serde(skip_serializing_if = "Option::is_none")]
pub gte: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub gt: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lte: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lt: Option<u64>,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct BlockTimeFilter {
#[serde(skip_serializing_if = "Option::is_none")]
pub gte: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub gt: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lte: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lt: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub eq: Option<i64>,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct SignatureFilter {
#[serde(skip_serializing_if = "Option::is_none")]
pub gte: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub gt: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lte: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lt: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
#[serde(rename_all = "camelCase")]
pub enum TokenAccountsFilter {
#[default]
None,
BalanceChanged,
All,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
#[serde(rename_all = "camelCase")]
pub struct GetTransactionsFilters {
#[serde(skip_serializing_if = "Option::is_none")]
pub slot: Option<SlotFilter>,
#[serde(skip_serializing_if = "Option::is_none")]
pub block_time: Option<BlockTimeFilter>,
#[serde(skip_serializing_if = "Option::is_none")]
pub signature: Option<SignatureFilter>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<TransactionStatusFilter>,
#[serde(skip_serializing_if = "Option::is_none")]
pub token_accounts: Option<TokenAccountsFilter>,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
#[serde(rename_all = "camelCase")]
pub struct GetTransactionsForAddressOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub transaction_details: Option<TransactionDetails>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sort_order: Option<SortOrder>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pagination_token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub commitment: Option<CommitmentLevel>,
#[serde(skip_serializing_if = "Option::is_none")]
pub filters: Option<GetTransactionsFilters>,
#[serde(skip_serializing_if = "Option::is_none")]
pub encoding: Option<UiTransactionEncoding>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_supported_transaction_version: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_context_slot: Option<u64>,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
#[serde(rename_all = "camelCase")]
pub struct GetTransactionsForAddressResponse {
pub data: Vec<serde_json::Value>,
pub pagination_token: Option<String>,
}
pub type GetTransactionsForAddressRequest = (String, GetTransactionsForAddressOptions);
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct Identity {
pub address: String,
#[serde(rename = "type")]
pub entity_type: String,
pub name: String,
pub category: String,
pub tags: Vec<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct BatchIdentityRequest {
pub addresses: Vec<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct TokenBalance {
pub mint: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub symbol: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub balance: f64,
pub decimals: u8,
#[serde(skip_serializing_if = "Option::is_none")]
pub price_per_token: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub usd_value: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub logo_uri: Option<String>,
pub token_program: String,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Nft {
pub mint: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub image_uri: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub collection_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub collection_address: Option<String>,
pub compressed: bool,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
#[serde(rename_all = "camelCase")]
pub struct BalancesPagination {
pub page: u32,
pub limit: u32,
pub has_more: bool,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
#[serde(rename_all = "camelCase")]
pub struct BalancesResponse {
pub balances: Vec<TokenBalance>,
#[serde(skip_serializing_if = "Option::is_none")]
pub nfts: Option<Vec<Nft>>,
pub total_usd_value: f64,
pub pagination: BalancesPagination,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct BalanceChange {
pub mint: String,
pub amount: f64,
pub decimals: u8,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct HistoryTransaction {
pub signature: String,
pub timestamp: Option<i64>,
pub slot: u64,
pub fee: f64,
pub fee_payer: String,
pub error: Option<String>,
pub balance_changes: Vec<BalanceChange>,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
#[serde(rename_all = "camelCase")]
pub struct Pagination {
pub has_more: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct HistoryResponse {
pub data: Vec<HistoryTransaction>,
pub pagination: Pagination,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum TransferDirection {
In,
Out,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Transfer {
pub signature: String,
pub timestamp: i64,
pub direction: TransferDirection,
pub counterparty: String,
pub mint: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub symbol: Option<String>,
pub amount: f64,
pub amount_raw: String,
pub decimals: u8,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct TransfersResponse {
pub data: Vec<Transfer>,
pub pagination: Pagination,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
#[serde(rename_all = "camelCase")]
pub struct FundingSource {
pub funder: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub funder_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub funder_type: Option<String>,
pub mint: String,
pub symbol: String,
pub amount: f64,
pub amount_raw: String,
pub decimals: u8,
pub signature: String,
pub timestamp: i64,
pub date: String,
pub slot: u64,
pub explorer_url: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
pub enum TokenAccountsOption {
None,
BalanceChanged,
All,
}