rosetta_core/
lib.rs

1use crate::crypto::address::{Address, AddressFormat};
2use crate::crypto::{Algorithm, PublicKey, SecretKey};
3use crate::types::{
4    Block, BlockIdentifier, CallRequest, Coin, Currency, CurveType, NetworkIdentifier,
5    PartialBlockIdentifier, SignatureType, Transaction, TransactionIdentifier,
6};
7use anyhow::Result;
8use async_trait::async_trait;
9use serde::de::DeserializeOwned;
10use serde::Serialize;
11use serde_json::Value;
12use std::sync::Arc;
13
14pub use rosetta_crypto as crypto;
15pub use rosetta_types as types;
16
17type NodeCommand = Arc<dyn Fn(&str, u16) -> Vec<String> + Send + Sync + 'static>;
18
19#[derive(Clone)]
20pub struct BlockchainConfig {
21    pub blockchain: &'static str,
22    pub network: &'static str,
23    pub algorithm: Algorithm,
24    pub address_format: AddressFormat,
25    pub coin: u32,
26    pub bip44: bool,
27    pub utxo: bool,
28    pub currency_unit: &'static str,
29    pub currency_symbol: &'static str,
30    pub currency_decimals: u32,
31    pub node_port: u16,
32    pub node_image: &'static str,
33    pub node_command: NodeCommand,
34    pub node_additional_ports: &'static [u16],
35    pub connector_port: u16,
36    pub testnet: bool,
37}
38
39impl BlockchainConfig {
40    pub fn network(&self) -> NetworkIdentifier {
41        NetworkIdentifier {
42            blockchain: self.blockchain.into(),
43            network: self.network.into(),
44            sub_network_identifier: None,
45        }
46    }
47
48    pub fn currency(&self) -> Currency {
49        Currency {
50            symbol: self.currency_symbol.into(),
51            decimals: self.currency_decimals,
52            metadata: None,
53        }
54    }
55
56    pub fn node_url(&self) -> String {
57        format!("http://rosetta.analog.one:{}", self.node_port)
58    }
59
60    pub fn connector_url(&self) -> String {
61        format!("http://rosetta.analog.one:{}", self.connector_port)
62    }
63}
64
65#[async_trait]
66pub trait BlockchainClient: Sized + Send + Sync + 'static {
67    type MetadataParams: DeserializeOwned + Send + Sync + 'static;
68    type Metadata: Serialize;
69    fn create_config(network: &str) -> Result<BlockchainConfig>;
70    async fn new(config: BlockchainConfig, addr: &str) -> Result<Self>;
71    fn config(&self) -> &BlockchainConfig;
72    fn genesis_block(&self) -> &BlockIdentifier;
73    async fn node_version(&self) -> Result<String>;
74    async fn current_block(&self) -> Result<BlockIdentifier>;
75    async fn balance(&self, address: &Address, block: &BlockIdentifier) -> Result<u128>;
76    async fn coins(&self, address: &Address, block: &BlockIdentifier) -> Result<Vec<Coin>>;
77    async fn faucet(&self, address: &Address, param: u128) -> Result<Vec<u8>>;
78    async fn metadata(
79        &self,
80        public_key: &PublicKey,
81        params: &Self::MetadataParams,
82    ) -> Result<Self::Metadata>;
83    async fn submit(&self, transaction: &[u8]) -> Result<Vec<u8>>;
84    async fn block(&self, block: &PartialBlockIdentifier) -> Result<Block>;
85    async fn block_transaction(
86        &self,
87        block: &BlockIdentifier,
88        tx: &TransactionIdentifier,
89    ) -> Result<Transaction>;
90    async fn call(&self, req: &CallRequest) -> Result<Value>;
91}
92
93pub trait RosettaAlgorithm {
94    fn to_signature_type(self) -> SignatureType;
95    fn to_curve_type(self) -> CurveType;
96}
97
98impl RosettaAlgorithm for Algorithm {
99    fn to_signature_type(self) -> SignatureType {
100        match self {
101            Algorithm::EcdsaSecp256k1 => SignatureType::Ecdsa,
102            Algorithm::EcdsaRecoverableSecp256k1 => SignatureType::EcdsaRecovery,
103            Algorithm::EcdsaSecp256r1 => SignatureType::Ecdsa,
104            Algorithm::Ed25519 => SignatureType::Ed25519,
105            Algorithm::Sr25519 => SignatureType::Sr25519,
106        }
107    }
108
109    fn to_curve_type(self) -> CurveType {
110        match self {
111            Algorithm::EcdsaSecp256k1 => CurveType::Secp256k1,
112            Algorithm::EcdsaRecoverableSecp256k1 => CurveType::Secp256k1,
113            Algorithm::EcdsaSecp256r1 => CurveType::Secp256r1,
114            Algorithm::Ed25519 => CurveType::Edwards25519,
115            Algorithm::Sr25519 => CurveType::Schnorrkel,
116        }
117    }
118}
119
120pub trait TransactionBuilder: Default + Sized {
121    type MetadataParams: Serialize + Clone;
122    type Metadata: DeserializeOwned + Sized + Send + Sync + 'static;
123
124    fn transfer(&self, address: &Address, amount: u128) -> Result<Self::MetadataParams>;
125
126    fn method_call(
127        &self,
128        contract: &str,
129        method: &str,
130        values: &[String],
131        amount: u128,
132    ) -> Result<Self::MetadataParams>;
133
134    fn deploy_contract(&self, contract_binary: Vec<u8>) -> Result<Self::MetadataParams>;
135
136    fn create_and_sign(
137        &self,
138        config: &BlockchainConfig,
139        metadata_params: &Self::MetadataParams,
140        metdata: &Self::Metadata,
141        secret_key: &SecretKey,
142    ) -> Vec<u8>;
143}