spark_orderbook_sdk/
lib.rs1use fuels::{
2 prelude::{
3 abigen, AssetId, Bech32ContractId, Contract, ContractId, LoadConfiguration,
4 StorageConfiguration, TxPolicies, WalletUnlocked,
5 },
6 programs::responses::CallResponse,
7 types::{Address, Bytes32},
8};
9use rand::Rng;
10use std::path::PathBuf;
11
12abigen!(Contract(
13 name = "Orderbook",
14 abi = "orderbook-contract/out/release/orderbook-contract-abi.json"
15));
16
17const ORDERBOOK_CONTRACT_BINARY_PATH: &str =
18 "orderbook-contract/out/release/orderbook-contract.bin";
19const ORDERBOOK_CONTRACT_STORAGE_PATH: &str =
20 "orderbook-contract/out/release/orderbook-contract-storage_slots.json";
21
22pub struct OrderbookContract {
23 instance: Orderbook<WalletUnlocked>,
24}
25
26impl OrderbookContract {
27 pub async fn deploy(owner: WalletUnlocked, version: u32) -> anyhow::Result<Self> {
28 let mut rng = rand::thread_rng();
29 let salt = rng.gen::<[u8; 32]>();
30
31 let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
32 let storage_configuration = StorageConfiguration::default()
33 .add_slot_overrides_from_file(root.join(ORDERBOOK_CONTRACT_STORAGE_PATH));
34
35 let configurables = OrderbookConfigurables::default()
36 .with_OWNER(owner.address().into())
37 .unwrap()
38 .with_VERSION(version)
39 .unwrap();
40
41 let contract_configuration = LoadConfiguration::default()
42 .with_storage_configuration(storage_configuration?)
43 .with_configurables(configurables);
44
45 let contract_id = Contract::load_from(
46 root.join(ORDERBOOK_CONTRACT_BINARY_PATH),
47 contract_configuration,
48 )?
49 .with_salt(salt)
50 .deploy(&owner, TxPolicies::default())
51 .await?;
52
53 let orderbook = Orderbook::new(contract_id.clone(), owner.clone());
54
55 Ok(Self {
56 instance: orderbook,
57 })
58 }
59
60 pub async fn new(contract_id: ContractId, wallet: WalletUnlocked) -> Self {
61 let _self = Self {
62 instance: Orderbook::new(contract_id, wallet),
63 };
64 assert!(
65 _self.contract_version().await.unwrap() & 0xFF0000 == Self::sdk_version() & 0xFF0000,
66 "Orderbook contract version mismatch with SDK version"
67 );
68 _self
69 }
70
71 pub async fn with_account(&self, account: &WalletUnlocked) -> anyhow::Result<Self> {
72 Ok(Self {
73 instance: self.instance.clone().with_account(account.clone()),
74 })
75 }
76
77 pub fn id(&self) -> Bytes32 {
78 self.instance.contract_id().hash
79 }
80
81 pub fn contract_id(&self) -> &Bech32ContractId {
82 self.instance.contract_id()
83 }
84
85 pub async fn contract_version(&self) -> anyhow::Result<u32> {
86 let (_, version) = self.config().await?.value;
87 Ok(version)
88 }
89
90 pub async fn contract_str_version(&self) -> anyhow::Result<String> {
91 let version = self.contract_version().await?;
92 Ok(format!(
93 "{}.{}.{}",
94 (version & 0xFF0000) >> 16,
95 (version & 0xFF00) >> 8,
96 version & 0xFF
97 ))
98 }
99
100 pub fn sdk_version() -> u32 {
101 let s_version = Self::sdk_str_version();
102 let version = s_version.split('.').collect::<Vec<&str>>();
104 let len = version.len();
105 version
106 .iter()
107 .enumerate()
108 .map(|(i, &x)| x.parse::<u32>().unwrap() << (8 * (len - i - 1)))
109 .collect::<Vec<u32>>()
110 .iter()
111 .sum()
112 }
113
114 pub fn sdk_str_version() -> String {
115 env!("CARGO_PKG_VERSION").into()
116 }
117
118 pub async fn register_market(&self, market: ContractId) -> anyhow::Result<CallResponse<()>> {
119 Ok(self
120 .instance
121 .methods()
122 .register_market(market)
123 .with_contract_ids(&[market.into()])
124 .call()
125 .await?)
126 }
127
128 pub async fn unregister_market(&self, market: ContractId) -> anyhow::Result<CallResponse<()>> {
129 Ok(self
130 .instance
131 .methods()
132 .unregister_market(market)
133 .with_contract_ids(&[market.into()])
134 .call()
135 .await?)
136 }
137
138 pub async fn config(&self) -> anyhow::Result<CallResponse<(Address, u32)>> {
139 Ok(self.instance.methods().config().simulate().await?)
140 }
141
142 pub async fn markets(
143 &self,
144 assets: Vec<(AssetId, AssetId)>,
145 ) -> anyhow::Result<CallResponse<Vec<(AssetId, AssetId, Option<ContractId>)>>> {
146 Ok(self.instance.methods().markets(assets).simulate().await?)
147 }
148}