Skip to content

Commit f1d8a35

Browse files
committed
feat: Radix docs
1 parent 92b83f7 commit f1d8a35

File tree

5 files changed

+270
-1
lines changed

5 files changed

+270
-1
lines changed

docs/get-started/supported-chains.md renamed to docs/get-started/supported-chains/index.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ sidebar_position: 4
33
sidebar_label: "⛓ Supported Chains"
44
---
55

6+
import DocCardList from '@theme/DocCardList';
7+
68
# ⛓ Supported Chains
79

810
RedStone Oracles are available on all EVM-compatible L1s & L2s + Starknet + Fuel Network. Potentially you can use it on any other chain but it would require some custom development.
@@ -68,6 +70,9 @@ You can check the integration with the showroom app [for EVM Chains](https://sho
6870

6971
### We also support a few non-EVM-compatible chains
7072

73+
<DocCardList />
74+
75+
and others:
7176
- [TRON](https://github.com/redstone-finance/redstone-tron-integration)
7277
- [Stacks](https://stacks.org/redstone)
7378
- [StarkNet](https://github.com/redstone-finance/redstone-oracles-monorepo/tree/main/packages/starknet-connector)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"label": "Radix",
3+
"position": 1,
4+
"link": {
5+
"type": "generated-index",
6+
"description": "XX"
7+
},
8+
"collapsed": false
9+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
sidebar_position: 1
3+
sidebar_label: "How to start"
4+
---
5+
6+
# How to start
7+
8+
1. Read about RedStone models in [Get Started](../../../../category/-get-started) section
9+
2. Follow the [@redstone-finance/radix-connector](https://github.com/redstone-finance/redstone-monorepo-priv/tree/main/packages/radix-connector/README.md) landing page
10+
1. see how to [set up local scrypto environment](https://github.com/redstone-finance/redstone-oracles-monorepo/tree/main/packages/radix-connector/scrypto/README.md)
11+
2. read the [general philosophy of the on-ledger component](https://github.com/redstone-finance/redstone-oracles-monorepo/blob/main/packages/radix-connector/scrypto/price_adapter/README.md)
12+
3. see how to [connect to the contract/component](https://github.com/redstone-finance/redstone-oracles-monorepo/tree/main/packages/radix-connector#-connecting-to-the-contract) in the TypeScript layer
13+
3. See the [docs of the *RedStone Rust SDK*](https://docs.redstone.finance/rust/redstone/crypto_radix,network_radix/redstone/index.html) - the component is built on
14+
15+
16+
### TypeScript level
17+
18+
deploy, instantiate, run
19+
20+
@redstone-finance/radix-connector will be deployed soon
Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
---
2+
sidebar_position: 2
3+
sidebar_label: "How to use in Rust"
4+
---
5+
6+
# Sample component—how it is built
7+
8+
1. Read firstly the docs from [How to start](./how-to-start.md) section, especially the general philosophy of the on-ledger component.
9+
1. The **info described there** is mostly **NOT REPEATED below**.
10+
2. The full source of the component is available [here](https://github.com/redstone-finance/redstone-oracles-monorepo/tree/main/packages/radix-connector/scrypto/price_adapter)
11+
12+
## Dependencies
13+
14+
1. Use the following dependencies to embed *RedStone Rust SDK* into Scrypto.
15+
16+
```toml
17+
[dependencies]
18+
scrypto = { version = "1.3.0" }
19+
redstone = { git = "https://github.com/redstone-finance/rust-sdk", tag = "1.2.0", features = ["crypto_radix", "network_radix"] }
20+
```
21+
22+
## Instantiating & Storage
23+
24+
Some of the values are necessary to be stored inside the component during its instantiating.
25+
Also, for the [Push model](#push-model), the values and timestamp are stored in the component.
26+
27+
```rust
28+
#[blueprint]
29+
mod price_adapter {
30+
struct PriceAdapter {
31+
signer_count_threshold: u8,
32+
signers: Vec<Bytes>,
33+
prices: HashMap<U256Digits, U256Digits>,
34+
timestamp: u64,
35+
}
36+
37+
impl PriceAdapter {
38+
pub fn instantiate(
39+
signer_count_threshold: u8,
40+
allowed_signer_addresses: Signers,
41+
) -> Global<PriceAdapter> {
42+
allowed_signer_addresses.len().assert_or_revert(
43+
|&v| v > 0usize,
44+
|_| Error::contract_error(PriceAdapterError::SignersMustNotBeEmpty),
45+
);
46+
47+
signer_count_threshold.assert_or_revert(
48+
|&v| (v as usize) <= allowed_signer_addresses.len(),
49+
|&v| Error::contract_error(PriceAdapterError::WrongSignerCountThresholdValue(v)),
50+
);
51+
52+
Self {
53+
signer_count_threshold,
54+
signers: allowed_signer_addresses,
55+
prices: hashmap!(),
56+
timestamp: 0
57+
}
58+
.instantiate()
59+
.prepare_to_globalize(OwnerRole::None)
60+
.globalize()
61+
}
62+
}
63+
}
64+
```
65+
66+
## Using the *RedStone Rust SDK*
67+
68+
### Payload processing
69+
70+
1. The payload bytes should be defined as described [here](https://docs.redstone.finance/img/payload.png).
71+
2. The payload can be generated as described [here](https://github.com/redstone-finance/redstone-oracles-monorepo/blob/main/packages/radix-connector/scrypto/README.md#preparing-sample-data).
72+
73+
To process the payload data, the following command should be used inside the `#[blueprint]`.
74+
75+
```rust
76+
use redstone::{
77+
core::{config::Config, processor::process_payload},
78+
network::{
79+
as_str::AsAsciiStr,
80+
assert::{Assert, Unwrap},
81+
error::Error,
82+
specific::Bytes,
83+
},
84+
};
85+
```
86+
87+
The function processes on-chain the payload passed as an argument and returns an array of aggregated values of each feed passed as an identifier inside feed_ids, and a timestamp related to the payload data packages.
88+
89+
```rust
90+
fn process_payload(
91+
&mut self,
92+
feed_ids: Vec<U256>,
93+
payload: Bytes,
94+
) -> (u64, Vec<U256Digits>) {
95+
let current_time = get_current_time();
96+
97+
let config = Config {
98+
signer_count_threshold: self.signer_count_threshold,
99+
signers: self.signers.clone(),
100+
feed_ids,
101+
block_timestamp: current_time * 1000,
102+
};
103+
104+
let result = process_payload(config, payload);
105+
let prices = result.values.iter().map(|v| v.to_digits()).collect();
106+
107+
(result.min_timestamp, prices)
108+
}
109+
```
110+
111+
#### Config
112+
113+
The `Config` structure is described [here](https://docs.redstone.finance/rust/redstone/crypto_radix,network_radix/redstone/core/config/struct.Config.html)
114+
115+
For safety reasons, the allowed `signers` and `signer_count_threshold` should be embedded in the component as defined above.
116+
117+
#### Current timestamp
118+
119+
Also, the current timestamp in milliseconds is necessary to be passed as the `block timestamp` parameter:
120+
121+
```rust
122+
use scrypto::prelude::*;
123+
124+
pub fn get_current_time() -> u64 {
125+
let rtn = ScryptoVmV1Api::object_call(
126+
CONSENSUS_MANAGER.as_node_id(),
127+
CONSENSUS_MANAGER_GET_CURRENT_TIME_IDENT,
128+
scrypto_encode(&ConsensusManagerGetCurrentTimeInputV2 {
129+
precision: TimePrecisionV2::Second,
130+
})
131+
.unwrap(),
132+
);
133+
134+
let instant: Instant = scrypto_decode(&rtn).unwrap();
135+
136+
instant.seconds_since_unix_epoch as u64
137+
}
138+
```
139+
140+
#### Errors
141+
142+
The possible errors thrown during the payload processing can be found [here](https://docs.redstone.finance/rust/redstone/crypto_radix,network_radix/redstone/network/error/enum.Error.html#variant.ContractError)
143+
144+
### Converting the input and output
145+
146+
The following input types are defined regarding the available SBOR representation,
147+
and it's necessary to have it converted to the types supported by RedStone Rust SDK.
148+
149+
```rust
150+
use redstone::network::specific::U256;
151+
152+
pub type U256Digits = [u64; 4];
153+
154+
pub mod types {
155+
use redstone::network::from_bytes_repr::FromBytesRepr;
156+
157+
pub type Payload = Vec<u8>;
158+
pub type FeedIds = Vec<Vec<u8>>;
159+
pub type Signers = Vec<Vec<u8>>;
160+
161+
#[inline]
162+
pub fn convert_feed_ids(input: FeedIds) -> Vec<super::U256> {
163+
input
164+
.iter()
165+
.map(|bytes| super::U256::from_bytes_repr(bytes.clone()))
166+
.collect()
167+
}
168+
}
169+
```
170+
171+
## Pull model
172+
173+
To use the pull model, just invoke the `process_payload` function and return the value.
174+
175+
```rust
176+
pub fn get_prices(
177+
&mut self,
178+
feed_ids: FeedIds,
179+
payload: Payload,
180+
) -> (u64, Vec<U256Digits>) {
181+
self.process_payload(convert_feed_ids(feed_ids), payload)
182+
}
183+
```
184+
185+
186+
187+
## Push model
188+
189+
For the Push model, invoke the `process_payload` function and save the value inside storage.
190+
191+
```rust
192+
pub fn write_prices(
193+
&mut self,
194+
feed_ids: FeedIds,
195+
payload: Payload,
196+
) -> (u64, Vec<U256Digits>) {
197+
let converted_feed_ids = convert_feed_ids(feed_ids);
198+
let (payload_timestamp, values) = self.process_payload(converted_feed_ids.clone(), payload);
199+
200+
payload_timestamp.assert_or_revert(
201+
|&ts| ts > self.timestamp,
202+
|_| Error::contract_error(PriceAdapterError::TimestampMustBeGreaterThanBefore),
203+
);
204+
205+
self.timestamp = payload_timestamp;
206+
self.prices = converted_feed_ids
207+
.iter()
208+
.zip(values.clone())
209+
.map(|(key, value)| (key.to_digits(), value))
210+
.collect();
211+
212+
(payload_timestamp, values)
213+
}
214+
```
215+
216+
Then the values can be read by using
217+
218+
```rust
219+
pub fn read_prices(&mut self, feed_ids: FeedIds) -> Vec<U256Digits> {
220+
convert_feed_ids(feed_ids)
221+
.iter()
222+
.enumerate()
223+
.map(|(index, feed_id)| self.read_price(feed_id.to_digits(), index))
224+
.collect()
225+
}
226+
227+
fn read_price(&mut self, feed_id: U256Digits, index: usize) -> U256Digits {
228+
*self.prices.get(&feed_id).unwrap_or_revert(|_| {
229+
Error::contract_error(PriceAdapterError::MissingDataFeedValue(
230+
index,
231+
U256::from_digits(feed_id).as_ascii_str(),
232+
))
233+
})
234+
}
235+
```

docusaurus.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ const config = {
144144
prism: {
145145
theme: lightCodeTheme,
146146
darkTheme: darkCodeTheme,
147-
additionalLanguages: ["bash", "solidity"],
147+
additionalLanguages: ["bash", "solidity", "rust", "toml"],
148148
},
149149
}),
150150
plugins: [

0 commit comments

Comments
 (0)