From ce39fa08a21c26c87876e3166e1d9767be25709c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kalbarczyk?= Date: Tue, 3 Dec 2024 15:25:56 +0100 Subject: [PATCH] feat: Radix docs --- .../index.mdx} | 5 + .../supported-chains/radix/index.mdx | 15 ++ .../supported-chains/radix/rust-tutorial.md | 239 ++++++++++++++++++ .../radix/typescript-tutorial.md | 64 +++++ docusaurus.config.js | 2 +- 5 files changed, 324 insertions(+), 1 deletion(-) rename docs/get-started/{supported-chains.md => supported-chains/index.mdx} (96%) create mode 100644 docs/get-started/supported-chains/radix/index.mdx create mode 100644 docs/get-started/supported-chains/radix/rust-tutorial.md create mode 100644 docs/get-started/supported-chains/radix/typescript-tutorial.md diff --git a/docs/get-started/supported-chains.md b/docs/get-started/supported-chains/index.mdx similarity index 96% rename from docs/get-started/supported-chains.md rename to docs/get-started/supported-chains/index.mdx index 1e578a3..4433ac7 100644 --- a/docs/get-started/supported-chains.md +++ b/docs/get-started/supported-chains/index.mdx @@ -3,6 +3,8 @@ sidebar_position: 4 sidebar_label: "⛓ Supported Chains" --- +import DocCardList from '@theme/DocCardList'; + # ⛓ Supported Chains 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 ### We also support a few non-EVM-compatible chains + + +and others: - [TRON](https://github.com/redstone-finance/redstone-tron-integration) - [Stacks](https://stacks.org/redstone) - [StarkNet](https://github.com/redstone-finance/redstone-oracles-monorepo/tree/main/packages/starknet-connector) diff --git a/docs/get-started/supported-chains/radix/index.mdx b/docs/get-started/supported-chains/radix/index.mdx new file mode 100644 index 0000000..4fca5bf --- /dev/null +++ b/docs/get-started/supported-chains/radix/index.mdx @@ -0,0 +1,15 @@ +--- +sidebar_position: 1 +sidebar_label: "Radix - how to start" +--- + +import DocCardList from '@theme/DocCardList'; + +# Radix - how to start + +1. Read about RedStone models in [Get Started](../../../category/-get-started) section +2. Follow the [@redstone-finance/radix-connector](https://github.com/redstone-finance/redstone-monorepo-priv/tree/main/packages/radix-connector/README.md) landing page + +Then, see: + + diff --git a/docs/get-started/supported-chains/radix/rust-tutorial.md b/docs/get-started/supported-chains/radix/rust-tutorial.md new file mode 100644 index 0000000..5c64017 --- /dev/null +++ b/docs/get-started/supported-chains/radix/rust-tutorial.md @@ -0,0 +1,239 @@ +--- +sidebar_position: 2 +sidebar_label: "How to use in Rust/Scrypto" +--- + +# Scrypto component—how it is built + +1. Read firstly the docs from [How to start](../) section +2. See how to [set up local scrypto environment](https://github.com/redstone-finance/redstone-oracles-monorepo/tree/main/packages/radix-connector/scrypto/README.md) +3. 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) +4. 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) +5. 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 + +The **info described there** is mostly **NOT REPEATED below**. + +## Dependencies + +1. Use the following dependencies to embed *RedStone Rust SDK* into Scrypto. + +```toml +[dependencies] +scrypto = { version = "1.3.0" } +redstone = { git = "https://github.com/redstone-finance/rust-sdk", tag = "1.2.0", features = ["crypto_radix", "network_radix"] } +``` + +## Instantiating & Storage + +Some of the values are necessary to be stored inside the component during its instantiating. +Also, for the [Push model](#push-model), the values and timestamp are stored in the component. + +```rust +#[blueprint] +mod price_adapter { + struct PriceAdapter { + signer_count_threshold: u8, + signers: Vec, + prices: HashMap, + timestamp: u64, + } + + impl PriceAdapter { + pub fn instantiate( + signer_count_threshold: u8, + allowed_signer_addresses: Signers, + ) -> Global { + allowed_signer_addresses.len().assert_or_revert( + |&v| v > 0usize, + |_| Error::contract_error(PriceAdapterError::SignersMustNotBeEmpty), + ); + + signer_count_threshold.assert_or_revert( + |&v| (v as usize) <= allowed_signer_addresses.len(), + |&v| Error::contract_error(PriceAdapterError::WrongSignerCountThresholdValue(v)), + ); + + Self { + signer_count_threshold, + signers: allowed_signer_addresses, + prices: hashmap!(), + timestamp: 0 + } + .instantiate() + .prepare_to_globalize(OwnerRole::None) + .globalize() + } + } +} +``` + +## Using the *RedStone Rust SDK* + +### Payload processing + +1. The payload bytes should be defined as described [here](https://docs.redstone.finance/img/payload.png). +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). + +To process the payload data, the following command should be used inside the `#[blueprint]`. + +```rust +use redstone::{ + core::{config::Config, processor::process_payload}, + network::{ + as_str::AsAsciiStr, + assert::{Assert, Unwrap}, + error::Error, + specific::Bytes, + }, +}; +``` + +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. + +```rust +fn process_payload( + &mut self, + feed_ids: Vec, + payload: Bytes, +) -> (u64, Vec) { + let current_time = get_current_time(); + + let config = Config { + signer_count_threshold: self.signer_count_threshold, + signers: self.signers.clone(), + feed_ids, + block_timestamp: current_time * 1000, + }; + + let result = process_payload(config, payload); + let prices = result.values.iter().map(|v| v.to_digits()).collect(); + + (result.min_timestamp, prices) +} +``` + +#### Config + +The `Config` structure is described [here](https://docs.redstone.finance/rust/redstone/crypto_radix,network_radix/redstone/core/config/struct.Config.html) + +For safety reasons, the allowed `signers` and `signer_count_threshold` should be embedded in the component as defined above. + +#### Current timestamp + +Also, the current timestamp in milliseconds is necessary to be passed as the `block timestamp` parameter: + +```rust +use scrypto::prelude::*; + +pub fn get_current_time() -> u64 { + let rtn = ScryptoVmV1Api::object_call( + CONSENSUS_MANAGER.as_node_id(), + CONSENSUS_MANAGER_GET_CURRENT_TIME_IDENT, + scrypto_encode(&ConsensusManagerGetCurrentTimeInputV2 { + precision: TimePrecisionV2::Second, + }) + .unwrap(), + ); + + let instant: Instant = scrypto_decode(&rtn).unwrap(); + + instant.seconds_since_unix_epoch as u64 +} +``` + +#### Errors + +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) + +### Converting the input and output + +The following input types are defined regarding the available SBOR representation, +and it's necessary to have it converted to the types supported by RedStone Rust SDK. + +```rust +use redstone::network::specific::U256; + +pub type U256Digits = [u64; 4]; + +pub mod types { + use redstone::network::from_bytes_repr::FromBytesRepr; + + pub type Payload = Vec; + pub type FeedIds = Vec>; + pub type Signers = Vec>; + + #[inline] + pub fn convert_feed_ids(input: FeedIds) -> Vec { + input + .iter() + .map(|bytes| super::U256::from_bytes_repr(bytes.clone())) + .collect() + } +} +``` + +## Pull model + +To use the pull model, just invoke the `process_payload` function and return the value. + +```rust +pub fn get_prices( + &mut self, + feed_ids: FeedIds, + payload: Payload, +) -> (u64, Vec) { + self.process_payload(convert_feed_ids(feed_ids), payload) +} +``` + + + +## Push model + +For the Push model, invoke the `process_payload` function and save the value inside storage. + +```rust +pub fn write_prices( + &mut self, + feed_ids: FeedIds, + payload: Payload, +) -> (u64, Vec) { + let converted_feed_ids = convert_feed_ids(feed_ids); + let (payload_timestamp, values) = self.process_payload(converted_feed_ids.clone(), payload); + + payload_timestamp.assert_or_revert( + |&ts| ts > self.timestamp, + |_| Error::contract_error(PriceAdapterError::TimestampMustBeGreaterThanBefore), + ); + + self.timestamp = payload_timestamp; + self.prices = converted_feed_ids + .iter() + .zip(values.clone()) + .map(|(key, value)| (key.to_digits(), value)) + .collect(); + + (payload_timestamp, values) +} +``` + +Then the values can be read by using + +```rust +pub fn read_prices(&mut self, feed_ids: FeedIds) -> Vec { + convert_feed_ids(feed_ids) + .iter() + .enumerate() + .map(|(index, feed_id)| self.read_price(feed_id.to_digits(), index)) + .collect() +} + +fn read_price(&mut self, feed_id: U256Digits, index: usize) -> U256Digits { + *self.prices.get(&feed_id).unwrap_or_revert(|_| { + Error::contract_error(PriceAdapterError::MissingDataFeedValue( + index, + U256::from_digits(feed_id).as_ascii_str(), + )) + }) +} +``` diff --git a/docs/get-started/supported-chains/radix/typescript-tutorial.md b/docs/get-started/supported-chains/radix/typescript-tutorial.md new file mode 100644 index 0000000..f046bf3 --- /dev/null +++ b/docs/get-started/supported-chains/radix/typescript-tutorial.md @@ -0,0 +1,64 @@ +--- +sidebar_position: 3 +sidebar_label: "How to use in TypeScript" +--- + +# How to use in TypeScript + +1. Read firstly the docs from [How to start](../) section, especially the general philosophy of the on-ledger component +2. 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 +3. The full source of the component is available [here](https://github.com/redstone-finance/redstone-oracles-monorepo/tree/main/packages/radix-connector/src) + +The **info described there** is mostly **NOT REPEATED below**. + +## Dependencies + +1. Use the following dependencies to embed *RedStone Radix Connector* into TypeScript. + +```json +{ + dependencies: { + ... + "@redstone-finance/radix-connector": "0.7.3", + ... + } +} +``` + +`@redstone-finance/radix-connector` will be deployed soon... + + +## Using the PriceAdapter package with `@redstone-finance/radix-connector` + +### Deploying package + +1. The package can be deployed by using the following command, defined [here](https://github.com/redstone-finance/redstone-oracles-monorepo/blob/main/packages/radix-connector/test/scripts/sample_deploy.ts): + +```shell +yarn sample-deploy +``` + +2. The deployed `package.stokenet.addr` address can be found in the `scrypto/price_adapter` directory. +3. The script uses [`RadixPackageDeployer`](https://github.com/redstone-finance/redstone-oracles-monorepo/blob/main/packages/radix-connector/scripts/RadixPackageDeployer.ts) + with the [`@atlantis-l/radix-tool`](https://github.com/atlantis-l/Radix-Desktop-Tool) package under the hood, + as the Radix Desktop Tool uses. + +### Instantiating component + +1. The component can be instantiated by using the following command, defined [here](https://github.com/redstone-finance/redstone-oracles-monorepo/blob/main/packages/radix-connector/test/scripts/sample_instantiate.ts): + +```shell +yarn sample-instantiate +``` + +2. The deployed `component.stokenet.addr` address can be found in the `scrypto/price_adapter` directory. +3. The script uses [`PriceAdapterRadixContractDeployer`](https://github.com/redstone-finance/redstone-oracles-monorepo/blob/main/packages/radix-connector/src/contracts/price_adapter/PriceAdapterRadixContractDeployer.ts) + +### Sample run + +1. The sample scenario can be run by using the following command, defined [here](https://github.com/redstone-finance/redstone-oracles-monorepo/blob/main/packages/radix-connector/test/scripts/sample_run.ts): +2. The script uses [`PriceAdapterRadixContractConnector`](https://github.com/redstone-finance/redstone-oracles-monorepo/blob/main/packages/radix-connector//src/contracts/price_adapter/PriceAdapterRadixContractConnector.ts) + +```shell +yarn sample-run +``` diff --git a/docusaurus.config.js b/docusaurus.config.js index c97289a..c1efc6c 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -144,7 +144,7 @@ const config = { prism: { theme: lightCodeTheme, darkTheme: darkCodeTheme, - additionalLanguages: ["bash", "solidity"], + additionalLanguages: ["bash", "solidity", "rust", "toml"], }, }), plugins: [