0.1.0
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
// file: kb_rpc/src/standard_http_tokens.rs
|
||||
// version: 1
|
||||
|
||||
//! Configurable standard SPL Token-oriented Solana HTTP JSON-RPC requests.
|
||||
|
||||
fn pubkey_with_optional_commitment_params(
|
||||
method: &str,
|
||||
address: &str,
|
||||
field: &str,
|
||||
config: &std::option::Option<crate::RpcCommitmentConfig>,
|
||||
) -> kb_core::Result<std::vec::Vec<serde_json::Value>> {
|
||||
let validation_result = crate::validate_solana_pubkey_text(address, field);
|
||||
if let std::result::Result::Err(error) = validation_result {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
let mut params = std::vec![serde_json::Value::String(address.to_string())];
|
||||
if let std::option::Option::Some(config) = config {
|
||||
let config_value = match crate::standard_http::serialize_parameter(method, config) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
params.push(config_value);
|
||||
}
|
||||
return std::result::Result::Ok(params);
|
||||
}
|
||||
|
||||
fn token_accounts_query_params(
|
||||
method: &str,
|
||||
authority: &str,
|
||||
field: &str,
|
||||
filter: &crate::RpcTokenAccountsFilter,
|
||||
config: &std::option::Option<crate::RpcAccountInfoConfig>,
|
||||
) -> kb_core::Result<std::vec::Vec<serde_json::Value>> {
|
||||
let authority_result = crate::validate_solana_pubkey_text(authority, field);
|
||||
if let std::result::Result::Err(error) = authority_result {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
let filter_result = filter.validate();
|
||||
if let std::result::Result::Err(error) = filter_result {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
if let std::option::Option::Some(config) = config {
|
||||
let config_result = config.validate();
|
||||
if let std::result::Result::Err(error) = config_result {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
}
|
||||
let filter_value = match crate::standard_http::serialize_parameter(method, filter) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let mut params = std::vec![serde_json::Value::String(authority.to_string()), filter_value,];
|
||||
if let std::option::Option::Some(config) = config {
|
||||
let config_value = match crate::standard_http::serialize_parameter(method, config) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
params.push(config_value);
|
||||
}
|
||||
return std::result::Result::Ok(params);
|
||||
}
|
||||
|
||||
/// Typed `getTokenAccountBalance` request.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct GetTokenAccountBalanceRequest {
|
||||
/// Token account public key.
|
||||
pub address: std::string::String,
|
||||
/// Optional commitment option.
|
||||
pub config: std::option::Option<crate::RpcCommitmentConfig>,
|
||||
}
|
||||
|
||||
impl crate::StandardHttpRequest for crate::GetTokenAccountBalanceRequest {
|
||||
type Response = crate::RpcResponse<crate::RpcTokenAmount>;
|
||||
|
||||
const METHOD: &'static str = "getTokenAccountBalance";
|
||||
|
||||
fn params(&self) -> kb_core::Result<std::vec::Vec<serde_json::Value>> {
|
||||
return crate::standard_http_tokens::pubkey_with_optional_commitment_params(
|
||||
Self::METHOD,
|
||||
&self.address,
|
||||
"getTokenAccountBalance address",
|
||||
&self.config,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Typed `getTokenAccountsByDelegate` request.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct GetTokenAccountsByDelegateRequest {
|
||||
/// Delegate public key.
|
||||
pub delegate: std::string::String,
|
||||
/// Mint or Token Program selector.
|
||||
pub filter: crate::RpcTokenAccountsFilter,
|
||||
/// Optional account representation and context options.
|
||||
pub config: std::option::Option<crate::RpcAccountInfoConfig>,
|
||||
}
|
||||
|
||||
impl crate::StandardHttpRequest for crate::GetTokenAccountsByDelegateRequest {
|
||||
type Response = crate::RpcResponse<std::vec::Vec<crate::RpcKeyedAccount>>;
|
||||
|
||||
const METHOD: &'static str = "getTokenAccountsByDelegate";
|
||||
|
||||
fn params(&self) -> kb_core::Result<std::vec::Vec<serde_json::Value>> {
|
||||
return crate::standard_http_tokens::token_accounts_query_params(
|
||||
Self::METHOD,
|
||||
&self.delegate,
|
||||
"getTokenAccountsByDelegate delegate",
|
||||
&self.filter,
|
||||
&self.config,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Typed `getTokenAccountsByOwner` request.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct GetTokenAccountsByOwnerRequest {
|
||||
/// Owner public key.
|
||||
pub owner: std::string::String,
|
||||
/// Mint or Token Program selector.
|
||||
pub filter: crate::RpcTokenAccountsFilter,
|
||||
/// Optional account representation and context options.
|
||||
pub config: std::option::Option<crate::RpcAccountInfoConfig>,
|
||||
}
|
||||
|
||||
impl crate::StandardHttpRequest for crate::GetTokenAccountsByOwnerRequest {
|
||||
type Response = crate::RpcResponse<std::vec::Vec<crate::RpcKeyedAccount>>;
|
||||
|
||||
const METHOD: &'static str = "getTokenAccountsByOwner";
|
||||
|
||||
fn params(&self) -> kb_core::Result<std::vec::Vec<serde_json::Value>> {
|
||||
return crate::standard_http_tokens::token_accounts_query_params(
|
||||
Self::METHOD,
|
||||
&self.owner,
|
||||
"getTokenAccountsByOwner owner",
|
||||
&self.filter,
|
||||
&self.config,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Typed `getTokenLargestAccounts` request.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct GetTokenLargestAccountsRequest {
|
||||
/// Mint public key.
|
||||
pub mint: std::string::String,
|
||||
/// Optional commitment option.
|
||||
pub config: std::option::Option<crate::RpcCommitmentConfig>,
|
||||
}
|
||||
|
||||
impl crate::StandardHttpRequest for crate::GetTokenLargestAccountsRequest {
|
||||
type Response = crate::RpcResponse<std::vec::Vec<crate::RpcTokenAccountBalance>>;
|
||||
|
||||
const METHOD: &'static str = "getTokenLargestAccounts";
|
||||
|
||||
fn params(&self) -> kb_core::Result<std::vec::Vec<serde_json::Value>> {
|
||||
return crate::standard_http_tokens::pubkey_with_optional_commitment_params(
|
||||
Self::METHOD,
|
||||
&self.mint,
|
||||
"getTokenLargestAccounts mint",
|
||||
&self.config,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Typed `getTokenSupply` request.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct GetTokenSupplyRequest {
|
||||
/// Mint public key.
|
||||
pub mint: std::string::String,
|
||||
/// Optional commitment option.
|
||||
pub config: std::option::Option<crate::RpcCommitmentConfig>,
|
||||
}
|
||||
|
||||
impl crate::StandardHttpRequest for crate::GetTokenSupplyRequest {
|
||||
type Response = crate::RpcResponse<crate::RpcTokenAmount>;
|
||||
|
||||
const METHOD: &'static str = "getTokenSupply";
|
||||
|
||||
fn params(&self) -> kb_core::Result<std::vec::Vec<serde_json::Value>> {
|
||||
return crate::standard_http_tokens::pubkey_with_optional_commitment_params(
|
||||
Self::METHOD,
|
||||
&self.mint,
|
||||
"getTokenSupply mint",
|
||||
&self.config,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
fn pubkey(seed: u8) -> std::string::String {
|
||||
return bs58::encode([seed; 32]).into_string();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn token_owner_query_preserves_filter_and_independent_account_options() {
|
||||
let request = crate::GetTokenAccountsByOwnerRequest {
|
||||
owner: pubkey(1),
|
||||
filter: crate::RpcTokenAccountsFilter::ProgramId(pubkey(2)),
|
||||
config: std::option::Option::Some(crate::RpcAccountInfoConfig {
|
||||
encoding: std::option::Option::Some(crate::RpcAccountEncoding::Base64Zstd),
|
||||
data_slice: std::option::Option::None,
|
||||
commitment: std::option::Option::Some(crate::RpcCommitmentLevel::Processed),
|
||||
min_context_slot: std::option::Option::Some(42),
|
||||
}),
|
||||
};
|
||||
let params = match crate::StandardHttpRequest::params(&request) {
|
||||
std::result::Result::Ok(params) => params,
|
||||
std::result::Result::Err(error) => panic!("params failed: {error}"),
|
||||
};
|
||||
assert_eq!(params[1], serde_json::json!({ "programId": pubkey(2) }));
|
||||
assert_eq!(params[2]["encoding"], serde_json::Value::String("base64+zstd".to_string()));
|
||||
assert_eq!(params[2]["commitment"], serde_json::Value::String("processed".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn token_balance_omits_unselected_options() {
|
||||
let request = crate::GetTokenAccountBalanceRequest {
|
||||
address: pubkey(3),
|
||||
config: std::option::Option::None,
|
||||
};
|
||||
let params = match crate::StandardHttpRequest::params(&request) {
|
||||
std::result::Result::Ok(params) => params,
|
||||
std::result::Result::Err(error) => panic!("params failed: {error}"),
|
||||
};
|
||||
assert_eq!(params, std::vec![serde_json::Value::String(pubkey(3))]);
|
||||
|
||||
let configured = crate::GetTokenSupplyRequest {
|
||||
mint: pubkey(4),
|
||||
config: std::option::Option::Some(crate::RpcCommitmentConfig {
|
||||
commitment: std::option::Option::Some(crate::RpcCommitmentLevel::Finalized),
|
||||
}),
|
||||
};
|
||||
let configured_params = match crate::StandardHttpRequest::params(&configured) {
|
||||
std::result::Result::Ok(params) => params,
|
||||
std::result::Result::Err(error) => panic!("params failed: {error}"),
|
||||
};
|
||||
assert_eq!(configured_params[1], serde_json::json!({ "commitment": "finalized" }));
|
||||
assert!(configured_params[1].get("minContextSlot").is_none());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user