From 7641f7eacf0c0ce233a7d45f36b88188ccb68ab6 Mon Sep 17 00:00:00 2001 From: Reisen Date: Mon, 27 Nov 2023 16:57:27 +0000 Subject: [PATCH] docs(near): improve example --- target_chains/near/README.md | 5 ++- target_chains/near/example/src/lib.rs | 64 ++++++++++++++++++++------- 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/target_chains/near/README.md b/target_chains/near/README.md index 0ee3d6888..195200716 100644 --- a/target_chains/near/README.md +++ b/target_chains/near/README.md @@ -1,8 +1,8 @@ # Pyth NEAR This directory contains the Pyth contract for NEAR, examples, and utilities to deploy. Within the `example/` -directory you will find an example skeleton NEAR contract that updates and uses a price. You can find -updates to test with from the Hermes API. Additionally see the `scripts/update.sh` script for an example +directory you will find an example skeleton NEAR contract that updates and uses several prices. You can find +payloads to test with from the Hermes API. Additionally see the `scripts/update.sh` script for an example of how to manually submit a price update from the CLI. ## Deployment @@ -15,6 +15,7 @@ Deploying the NEAR contract has three steps: - `sha256sum pyth.wasm` after building the contract. - `list(bytes.fromhex(hash))` in Python to get a byte array. - Replace the `codehash` field in deploy.sh for the initial codehash. + - Replace the sources with the keys expected by the network you're deploying on (testnet vs mainnet). ## Further Documentation diff --git a/target_chains/near/example/src/lib.rs b/target_chains/near/example/src/lib.rs index 6aba819e9..91016bc54 100644 --- a/target_chains/near/example/src/lib.rs +++ b/target_chains/near/example/src/lib.rs @@ -7,16 +7,21 @@ use { }, env, is_promise_success, + log, near_bindgen, AccountId, Gas, PanicOnDefault, Promise, - PromiseError, }, - pyth::state::PriceIdentifier, + pyth::state::{ + Price, + PriceIdentifier, + }, }; +/// Our contract simply processes prices, so for now the only state we +/// need is the Pyth contract ID from which we will be fetching prices. #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize, PanicOnDefault)] pub struct PythExample { @@ -31,35 +36,64 @@ impl PythExample { Self { pyth } } - /// Get a Pyth Price Feed Result. + /// Example of submitting an update + request for multiple Price Feeds. #[payable] - pub fn example_price_usage(&mut self, identifier: PriceIdentifier, data: String) -> Promise { + pub fn example_price_usage( + &mut self, + identifiers: Vec, + data: String, + ) -> Promise { pyth::ext::ext_pyth::ext(self.pyth.clone()) .with_static_gas(Gas(30_000_000_000_000)) .with_attached_deposit(env::attached_deposit()) .update_price_feeds(data) .then( - pyth::ext::ext_pyth::ext(self.pyth.clone()) - .get_price(identifier) - .then( - Self::ext(env::current_account_id()) - .with_static_gas(Gas(10_000_000_000)) - .handle_example_price_usage(), - ), + Self::ext(env::current_account_id()) + .with_static_gas(Gas(10_000_000_000)) + .handle_update_callback(identifiers), ) } + /// Handle the case where prices successfully updated, we can start reads at this point. #[payable] #[private] + pub fn handle_update_callback(&mut self, mut identifiers: Vec) -> Promise { + if !is_promise_success() { + panic!("Failed to Update Prices"); + } + + // Fetch a few prices to use. + let price_1 = identifiers.pop().unwrap(); + let price_2 = identifiers.pop().unwrap(); + let price_1 = pyth::ext::ext_pyth::ext(self.pyth.clone()).get_price(price_1); + let price_2 = pyth::ext::ext_pyth::ext(self.pyth.clone()).get_price(price_2); + + // Start parallel reads. + price_1.and(price_2).then( + Self::ext(env::current_account_id()) + .with_static_gas(Gas(10_000_000_000)) + .handle_results_callback(), + ) + } + + /// Handle results of reading multiple prices, the prices can be accessed using + /// NEAR's env::promise_* functions. + #[private] #[handle_result] - pub fn handle_example_price_usage( - &mut self, - #[callback_result] _r: Result, PromiseError>, + pub fn handle_results_callback( + &self, + #[callback_result] price_1: Result, + #[callback_result] price_2: Result, ) { if !is_promise_success() { return; } - // Do things with Price Feed Result. + let price_1 = price_1.unwrap(); + let price_2 = price_2.unwrap(); + + // Do something with the prices. + log!("{:?}", price_1); + log!("{:?}", price_2); } }