Skip to content

Commit 26bae47

Browse files
committed
feat: add IOTA testnet
1 parent 77bf8f9 commit 26bae47

File tree

6 files changed

+200
-0
lines changed

6 files changed

+200
-0
lines changed

pages/price-feeds/contract-addresses.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ The contracts are split by ecosystem into several different documents:
77
- [Solana/SVM](contract-addresses/solana)
88
- [Aptos](contract-addresses/aptos)
99
- [Sui](contract-addresses/sui)
10+
- [IOTA](contract-addresses/iota)
1011
- [Movement](contract-addresses/movement)
1112
- [TON](contract-addresses/ton)
1213
- [Fuel](contract-addresses/fuel)

pages/price-feeds/contract-addresses/_meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"solana": "Solana / SVM",
44
"aptos": "Aptos",
55
"sui": "Sui",
6+
"iota": "IOTA",
67
"movement": "Movement",
78
"ton": "TON",
89
"fuel": "Fuel",
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Price Feed Contract Addresses on IOTA
2+
3+
#### IOTA testnet
4+
5+
| Name | Address |
6+
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
7+
| Pyth State ID | [`0x68dda579251917b3db28e35c4df495c6e664ccc085ede867a9b773c8ebedc2c1`](https://explorer.rebased.iota.org/object/0x68dda579251917b3db28e35c4df495c6e664ccc085ede867a9b773c8ebedc2c1?network=testnet) |
8+
| Pyth Package ID | [`0x23994dd119480ea614f7623520337058dca913cb1bb6e5d8d51c7b067d3ca3bb`](https://explorer.rebased.iota.org/object/0x23994dd119480ea614f7623520337058dca913cb1bb6e5d8d51c7b067d3ca3bb?network=testnet) |
9+
| Wormhole State ID | [`0x8bc490f69520a97ca1b3de864c96aa2265a0cf5d90f5f3f016b2eddf0cf2af2b`](https://explorer.rebased.iota.org/object/0x8bc490f69520a97ca1b3de864c96aa2265a0cf5d90f5f3f016b2eddf0cf2af2b?network=testnet) |
10+
| Wormhole Package ID | [`0xfca58c557f09cddb7930588c4e2a4edbe3cdded1ac1ed2270aa2dfa8d2b9ae0d`](https://explorer.rebased.iota.org/object/0xfca58c557f09cddb7930588c4e2a4edbe3cdded1ac1ed2270aa2dfa8d2b9ae0d?network=testnet) |
11+
12+
#### IOTA mainnet
13+
14+
Coming soon.

pages/price-feeds/use-real-time-data.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Then, consult the relevant ecosystem guide to get started using Pyth real-time p
1515
- [Aptos](use-real-time-data/aptos.md)
1616
- [CosmWasm](use-real-time-data/cosmwasm.md)
1717
- [Sui](use-real-time-data/sui.md)
18+
- [IOTA](use-real-time-data/iota.md)
1819
- [Near](use-real-time-data/sui.md)
1920

2021
Pyth price feeds can also be used in off-chain applications.

pages/price-feeds/use-real-time-data/_meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"fuel": "in Fuel Contracts",
66
"aptos": "in Aptos Contracts",
77
"sui": "in Sui Contracts",
8+
"iota": "in IOTA Contracts",
89
"ton": "in TON Contracts",
910
"cosmwasm": "in CosmWasm Contracts",
1011
"near": "in Near Contracts",
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
import { Callout, Tabs } from "nextra/components";
2+
3+
# How to Use Real-Time Data in IOTA Contracts
4+
5+
This guide explains how to use real-time Pyth data in IOTA applications.
6+
7+
## Install Pyth SDK
8+
9+
Use the following dependency in your `Move.toml` file to use the latest Pyth IOTA package and its dependencies:
10+
11+
<Tabs items={['IOTA Testnet']}>
12+
<Tabs.Tab>
13+
14+
```sh copy
15+
[dependencies.Pyth]
16+
git = "https://github.com/pyth-network/pyth-crosschain.git"
17+
subdir = "target_chains/iota/contracts"
18+
rev = "iota-contract-testnet"
19+
20+
[dependencies.Wormhole]
21+
git = "https://github.com/pyth-network/pyth-crosschain.git"
22+
subdir = "target_chains/iota/contracts/vendor/wormhole_iota_testnet/wormhole"
23+
rev = "iota-contract-testnet"
24+
25+
[dependencies.Iota]
26+
git = "https://github.com/iotaledger/iota.git"
27+
subdir = "crates/iota-framework/packages/iota-framework"
28+
rev = "develop"
29+
```
30+
31+
</Tabs.Tab>
32+
</Tabs>
33+
34+
Pyth also provides a javascript SDK to construct transaction blocks that update price feeds:
35+
36+
<Tabs items={["IOTA"]}>
37+
<Tabs.Tab>
38+
```sh
39+
# NPM
40+
npm install --save @pythnetwork/pyth-iota-js
41+
42+
# Yarn
43+
yarn add @pythnetwork/pyth-iota-js
44+
```
45+
46+
</Tabs.Tab>
47+
</Tabs>
48+
49+
## Write Contract Code
50+
51+
The code snippet below provides a general template for what your contract code should look like:
52+
53+
```rust {18} copy
54+
module pyth_example::main {
55+
use iota::clock::Clock;
56+
use pyth::price_info;
57+
use pyth::price_identifier;
58+
use pyth::price;
59+
use pyth::pyth;
60+
use pyth::price_info::PriceInfoObject;
61+
62+
const E_INVALID_ID: u64 = 1;
63+
64+
public fun use_pyth_price(
65+
// Other arguments
66+
clock: &Clock,
67+
price_info_object: &PriceInfoObject,
68+
){
69+
let max_age = 60;
70+
// Make sure the price is not older than max_age seconds
71+
let price_struct = pyth::get_price_no_older_than(price_info_object,clock, max_age);
72+
73+
// Check the price feed ID
74+
let price_info = price_info::get_price_info_from_price_info_object(price_info_object);
75+
let price_id = price_identifier::get_bytes(&price_info::get_price_identifier(&price_info));
76+
77+
// ETH/USD price feed ID
78+
// The complete list of feed IDs is available at https://pyth.network/developers/price-feed-ids
79+
// Note: IOTA uses the Pyth price feed ID without the `0x` prefix.
80+
assert!(price_id!=x"ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace", E_INVALID_ID);
81+
82+
// Extract the price, decimal, and timestamp from the price struct and use them
83+
let decimal_i64 = price::get_expo(&price_struct);
84+
let price_i64 = price::get_price(&price_struct);
85+
let timestamp_sec = price::get_timestamp(&price_struct);
86+
}
87+
}
88+
```
89+
90+
One can consume the price by calling `pyth::get_price` abovementioned or other utility functions on the `PriceInfoObject` in the Move module
91+
92+
The code snippet below provides an example of how to update the Pyth price feeds:
93+
94+
```ts copy
95+
import { IotaPriceServiceConnection, IotaPythClient } from "@pythnetwork/pyth-iota-js";
96+
import { Transaction } from "@iota/iota-sdk/transactions";
97+
98+
// Get the Stable Hermes service URL from https://docs.pyth.network/price-feeds/api-instances-and-providers/hermes
99+
const connection = new IotaPriceServiceConnection("https://hermes-beta.pyth.network");
100+
101+
const priceIDs = [
102+
// You can find the IDs of prices at https://pyth.network/developers/price-feed-ids
103+
"0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43", // BTC/USD price ID
104+
"0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace", // ETH/USD price ID
105+
];
106+
107+
const priceUpdateData = await connection.getPriceFeedsUpdateData(priceIDs);
108+
109+
// It is either injected from the browser or instantiated in the backend via some private key
110+
const wallet: SignerWithProvider = getWallet();
111+
// Get the state IDs of the Pyth and Wormhole contracts from
112+
// https://docs.pyth.network/price-feeds/contract-addresses/iota
113+
const wormholeStateId = "0x5306f64e312b581766351c07af79c72fcb1cd25147157fdc2f8ad76de9a3fb6a";
114+
const pythStateId = "0x1f9310238ee9298fb703c3419030b35b22bb1cc37113e3bb5007c99aec79e5b8";
115+
116+
const client = new IotaPythClient(wallet.provider, pythStateId, wormholeStateId);
117+
const tx = new Transaction();
118+
const priceInfoObjectIds = await client.updatePriceFeeds(tx, priceFeedUpdateData, priceIDs);
119+
120+
tx.moveCall({
121+
target: `pyth_example::main::use_pyth_price`,
122+
arguments: [
123+
..., // other arguments needed for your contract
124+
tx.object(priceInfoObjectIds[0]),
125+
],
126+
});
127+
128+
const txBlock = {
129+
transactionBlock: tx,
130+
options: {
131+
showEffects: true,
132+
showEvents: true,
133+
},
134+
};
135+
136+
const result = await wallet.signAndExecuteTransactionBlock(txBlock);
137+
```
138+
139+
By calling the `updatePriceFeeds` function, the `IotaPythClient` adds the necessary transactions to the transaction block to update the price feeds.
140+
141+
<Callout type="warning" emoji="⚠️">
142+
143+
Your IOTA Move module **should NOT** have a hard-coded call to `pyth::update_single_price_feed.` In other words, a contract should **never call** the IOTA Pyth `pyth::update_single_price_feed` entry point. Instead, it should be called directly from client code (e.g., Typescript or Rust).
144+
145+
When IOTA contracts are [upgraded](<(https://docs.IOTA.io/build/package-upgrades)>), the address changes, which makes the old address no longer valid. If your module has a hard-coded call to `pyth::update_single_price_feed` living at a fixed call-site, it may eventually get bricked due to how Pyth upgrades are implemented. (Pyth only allow users to interact with the most recent package version for security reasons).
146+
147+
Therefore, you should build a [IOTA programmable transaction](https://docs.IOTA.io/build/prog-trans-ts-sdk) that first updates the price by calling `pyth::update_single_price_feed` at the latest call-site from the client-side and then call a function in your contract that invokes `pyth::get_price` on the `PriceInfoObject` to get the recently updated price.
148+
You can use `IOTAPythClient` to build such transactions and handle all the complexity of updating the price feeds.
149+
150+
Consult [Fetch Price Updates](../fetch-price-updates) for more information on how to fetch the `pyth_price_update`.
151+
152+
</Callout>
153+
154+
## Additional Resources
155+
156+
You may find these additional resources helpful for developing your IOTA application.
157+
158+
### CLI Example
159+
160+
[This example](https://github.com/pyth-network/pyth-crosschain/tree/main/target_chains/iota/cli) shows how to update prices on a IOTA network. It does the following:
161+
162+
1. Fetches update data from Hermes for the given price feeds.
163+
1. Call the Pyth IOTA contract with a price update.
164+
165+
You can run this example with `npm run example-relay`. A full command that updates prices on the IOTA testnet looks like this:
166+
167+
```bash
168+
export IOTA_KEY=YOUR_PRIV_KEY;
169+
npm run example-relay -- --feed-id "5a035d5440f5c163069af66062bac6c79377bf88396fa27e6067bfca8096d280" \
170+
--hermes "https://hermes-beta.pyth.network" \
171+
--full-node "https://fullnode.testnet.IOTA.io:443" \
172+
--pyth-state-id "0xd3e79c2c083b934e78b3bd58a490ec6b092561954da6e7322e1e2b3c8abfddc0" \
173+
--wormhole-state-id "0x31358d198147da50db32eda2562951d53973a0c0ad5ed738e9b17d88b213d790"
174+
```
175+
176+
### Contract Addresses
177+
178+
Consult [IOTA Contract Addresses](../contract-addresses/iota) to find the package IDs.
179+
180+
### Pyth Price Feed IDs
181+
182+
Consult [Pyth Price Feed IDs](https://pyth.network/developers/price-feed-ids) to find Pyth price feed IDs for various assets.

0 commit comments

Comments
 (0)