Skip to content

Commit f097f46

Browse files
jayantkJayant Krishnamurthy
andauthored
update docs (#37)
Co-authored-by: Jayant Krishnamurthy <[email protected]>
1 parent 14eb9ce commit f097f46

File tree

3 files changed

+77
-80
lines changed

3 files changed

+77
-80
lines changed

examples/terra-contract/README.md

Lines changed: 50 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,66 @@
1-
# Pyth SDK Example contract for Terra
1+
# Pyth SDK Example Contract for Terra
22

3-
This is an example contract that demonstrates reading the Pyth price from the Pyth on-chain contract. It is created using
4-
[cw-template](https://github.com/InterWasm/cw-template) which is a standard template for developing Terra contracts.
3+
This repository contains an example contract that demonstrates how to read the Pyth price from the Pyth on-chain contract.
4+
The example [contract](src/contract.rs) has two functions:
55

6-
## Development
6+
* `instantiate` sets the Pyth contract address and price feed id that the contract uses.
7+
This function is intended to be called once when the contract is deployed.
8+
See the [Terra SDK README](../../pyth-sdk-terra/README.md) for the list of possible price feed ids.
9+
* `query` queries the Pyth contract to get the current price for the configured price feed id.
710

8-
Visit [Developing](./Developing.md) to learn more on how to compile and develop the contract.
11+
## Testnet Demo
912

10-
## Deploy and Query
11-
The javascript package in `tools` directory contains scripts for querying and deploying the example contract.
12-
13-
If this is the first time running the code, run the below command to install required packages in the `tools` directory:
14-
15-
```
16-
npm install
17-
```
18-
19-
### Testnet Demo
20-
In order to query the contract you can call:
13+
This example contract is running on Terra testnet at `terra1fm4ssxq39m355pdv2wzxggf5uxs2ase4vga9qs`.
14+
This contract has been instantiated to return the price of `Crypto.LUNA/USD`.
15+
You can query the contract from this repo by running:
2116

2217
```sh
18+
cd tools/
19+
# Install dependencies (if you haven't done so already)
20+
npm install
21+
# Query the contract
2322
npm run query -- --network testnet --contract terra1fm4ssxq39m355pdv2wzxggf5uxs2ase4vga9qs
2423
```
2524

26-
If successful the output should look like:
25+
If the query is successful, the output should look like:
2726
```
2827
{
2928
current_price: { price: 8704350000, conf: 3150000, expo: -8 },
3029
ema_price: { price: 8665158600, conf: 2965370, expo: -8 }
3130
}
3231
```
3332

34-
If the price is not available you will get:
33+
If the price feed is currently not available you will see:
3534
```
3635
rpc error: code = Unknown desc = Generic error: Current price is not available: contract query failed
3736
```
3837

39-
`terra1fm4ssxq39m355pdv2wzxggf5uxs2ase4vga9qs` is a live deployment of the example contract in testnet network. This contract
40-
is configured to return price of `Crypto.LUNA/USD` if it is available. If you have deployed your contract you can replace the
41-
address with your contract address.
42-
### Deployment
38+
## Developing
4339

44-
Deploying a contract in terra consists of two steps:
45-
1. Uploading the code. This step will give you a code id.
46-
2. Optionally create a new contract or migrate an existing one:
47-
1. Creating a new contract which has an address with a code id as its program.
48-
2. Migrating an existing contract code id to the new code id.
40+
If you would like to deploy a changed version of this contract, the process consists of two steps:
4941

50-
This script can do both steps at the same time. Read below for the details.
42+
1. Build the WASM for the contract.
43+
2. Upload the code and instantiate a new contract.
5144

52-
#### Uploading the code
45+
### Build WASM
5346

54-
First build the contracts as mentioned in [Developing](../Developing.md).
47+
See the [Developing instructions](Developing.md) for how to build the WASM for the contract.
48+
The instructions in that document will build a file called `example_terra_contract.wasm` under the `artifacts/` directory.
5549

56-
This command will builds and saves all the contracts in the `artifact` directory.
50+
### Upload and Instantiate Contract
5751

58-
Then, for example, to deploy `example_terra_contract.wasm`, run in the `tools` directory:
59-
60-
``` sh
61-
npm run deploy -- --network testnet --artifact ../artifacts/example_terra_contract.wasm --mnemonic "..."
62-
```
63-
64-
which will print something along the lines of:
65-
66-
``` sh
67-
Storing WASM: ../artifacts/example_terra_contract.wasm (367689 bytes)
68-
Deploy fee: 88446uluna
69-
Code ID: 2435
70-
```
71-
72-
If you do not pass any additional arguments to the script it will only upload the code and returns the code id. If you want to create a
73-
new contract or upgrade an existing contract you should pass more arguments that are described below.
74-
75-
#### Instantiating a new contract
76-
If you want instantiate a new contract after your deployment pass `--instantiate` argument to the above command.
77-
It will upload the code and with the resulting code id instantiates a new example contract:
52+
The tools directory contains a deployment script that will upload a WASM file and instantiate a new contract with it.
53+
You can run that script on the built WASM file as follows:
7854

7955
``` sh
56+
cd tools/
57+
npm install
8058
npm run deploy -- --network testnet --artifact ../artifacts/example_terra_contract.wasm --mnemonic "..." --instantiate
8159
```
8260

61+
This command will deploy the contract to `testnet` and sets its owner to the wallet with the provided `mnemonic`.
62+
Note that you have to populate the `--mnemonic` flag with the seedphrase for a valid Terra wallet with some LUNA for the specified network.
63+
8364
If successful, the output should look like:
8465
```
8566
Storing WASM: ../artifacts/example_terra_contract.wasm (183749 bytes)
@@ -91,17 +72,26 @@ Instantiated Pyth Example at terra123456789yelw23uh22nadqlyjvtl7s5527er97 (0x000
9172
Deployed pyth example contract at terra123456789yelw23uh22nadqlyjvtl7s5527er97
9273
```
9374

94-
This scripts currently set the example contract price to `Crypto.LUNA/USD` but you can change it within `deploy.js`.
75+
By default, the deployment script sets the price feed to `Crypto.LUNA/USD` but you can change it in [deploy.js](tools/deploy.js).
76+
77+
### Querying the Contract
78+
79+
Once the contract is instantiated, you can query it by running:
80+
81+
```sh
82+
npm run query -- --network testnet --contract <contract address>
83+
```
9584

96-
#### Migrating an existing contract
97-
If you want to upgrade an existing contract pass `--migrate --contract terra123456xyzqwe..` arguments to the above command.
98-
It will upload the code and with the resulting code id migrates the existing contract to the new one:
85+
### Migrating the Contract
86+
You can also migrate an existing contract by passing the `--migrate --contract terra123456xyzqwe..` arguments to the deploy command:
9987

10088
``` sh
10189
npm run deploy -- --network testnet --artifact ../artifacts/example_terra_contract.wasm --mnemonic "..." --migrate --contract "terra123..."
10290
```
10391

92+
This command will replace the code for the given contract with the specified WASM artifact.
10493
If successful, the output should look like:
94+
10595
```
10696
Storing WASM: ../artifacts/example_terra_contract.wasm (183749 bytes)
10797
Deploy fee: 44682uluna
@@ -111,16 +101,9 @@ Migrating contract terra1rhjej5gkyelw23uh22nadqlyjvtl7s5527er97 to 53227
111101
Contract terra1rhjej5gkyelw23uh22nadqlyjvtl7s5527er97 code_id successfully updated to 53227
112102
```
113103

114-
#### Notes
115-
116-
You might encounter gateway timeout or account sequence mismatch in errors. In is good to double check with terra finder as sometimes
117-
transactions succeed despite being timed out.
118-
119-
If that happens in the middle of an instantiation or migration. You can avoid re-uploading the code and use the resulting Code Id
120-
by passing `--code-id <codeId>` instead of `--artifact` and it will only do the instantiation/migration part.
104+
### Troubleshooting
121105

122-
An example is:
123-
124-
``` sh
125-
npm run deploy -- --network testnet --code-id 50123 --mnemonic "..." --migrate --contract "terra123..."
126-
```
106+
When deploying the contract, you may encounter gateway timeout or account sequence mismatch errors.
107+
If this happens, check terra finder to determine if your transaction succeeded -- sometimes transactions succeed despite timing out.
108+
Note that the deployment script submits multiple transactions.
109+
If any of them fails, simply rerun the entire script; there is no problem re-running the successful transactions.

examples/terra-contract/src/contract.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult<Respons
3131
Ok(Response::new().add_attribute("method", "migrate"))
3232
}
3333

34+
/// The instantiate function is invoked when the contract is first deployed.
35+
/// This function sets configuration values that are used by the query function.
3436
#[cfg_attr(not(feature = "library"), entry_point)]
3537
pub fn instantiate(
3638
deps: DepsMut,
@@ -62,6 +64,7 @@ pub fn execute(
6264
Ok(Response::new().add_attribute("method", "execute"))
6365
}
6466

67+
/// Query the Pyth contract the current price of the configured price feed.
6568
#[cfg_attr(not(feature = "library"), entry_point)]
6669
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
6770
match msg {
@@ -72,22 +75,31 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
7275
fn query_fetch_price(deps: Deps) -> StdResult<FetchPriceResponse> {
7376
let state = STATE.load(deps.storage)?;
7477

78+
// query_price_feed is the standard way to read the current price from a Pyth price feed.
79+
// It takes the address of the Pyth contract (which is fixed for each network) and the id of the price feed.
80+
// The result is a PriceFeed object with fields for the current price and other useful information.
81+
// The function will fail if the contract address or price feed id are invalid.
7582
let price_feed = query_price_feed(
7683
&deps.querier,
7784
state.pyth_contract_addr.into_string(),
7885
state.price_feed_id,
7986
)?
8087
.price_feed;
8188

82-
// This examples throws an error if the price is not available. Price could be
83-
// unavailable if the number of publishers are low or it has not been updated
84-
// for a while due to network errors and etc. It is recommended that you handle
85-
// the scenarios which price is not available in a better way.
86-
// Make sure to read [consumer best practices](https://docs.pyth.network/consumers/best-practices)
87-
// when using pyth data.
89+
// Get the current price and confidence interval from the price feed.
90+
// This function returns None if the price is not currently available.
91+
// This condition can happen for various reasons. For example, some products only trade at specific times, or
92+
// network outages may prevent the price feed from updating.
93+
//
94+
// The example code below throws an error if the price is not available. It is recommended that you handle
95+
// this scenario more carefully. Consult the [consumer best practices](https://docs.pyth.network/consumers/best-practices)
96+
// for recommendations.
8897
let current_price = price_feed
8998
.get_current_price()
9099
.ok_or(StdError::not_found("Current price is not available"))?;
100+
101+
// Get an exponentially-weighted moving average price and confidence interval.
102+
// The same notes about availability apply to this price.
91103
let ema_price = price_feed
92104
.get_ema_price()
93105
.ok_or(StdError::not_found("EMA price is not available"))?;

examples/terra-contract/tools/deploy.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,17 @@ const CONFIG = {
6868
name: "testnet",
6969
},
7070
pythContractAddress: "terra1wzs3rgzgjdde3kg7k3aaz6qx7sc5dcwxqe9fuc",
71-
pythLunaPriceFeedId: "6de025a4cf28124f8ea6cb8085f860096dbc36d9c40002e221fc449337e065b2"
71+
// Change this field to change which price feed is read by the deployed contract.
72+
// The current value is the LUNA/USD price feed.
73+
pythPriceFeedId: "6de025a4cf28124f8ea6cb8085f860096dbc36d9c40002e221fc449337e065b2"
7274
}
7375
}
7476

7577
const terraHost = CONFIG[argv.network].terraHost;
7678
const pythContractAddress = CONFIG[argv.network].pythContractAddress;
77-
const pythLunaPriceFeedId = CONFIG[argv.network].pythLunaPriceFeedId;
79+
const pythPriceFeedId = CONFIG[argv.network].pythPriceFeedId;
80+
7881

79-
8082
const lcd = new LCDClient(terraHost);
8183

8284
const feeDenoms = ["uluna"];
@@ -93,7 +95,7 @@ const wallet = lcd.wallet(
9395

9496
/* Deploy artifacts */
9597

96-
var codeId;
98+
var codeId;
9799

98100
if (argv.codeId !== undefined) {
99101
codeId = argv.codeId;
@@ -168,7 +170,7 @@ if (argv.instantiate) {
168170
.then((rs) => {
169171
try {
170172
address = /"contract_address","value":"([^"]+)/gm.exec(rs.raw_log)[1];
171-
} catch (e) {
173+
} catch (e) {
172174
console.error("Encountered an error in parsing instantiation result. Printing raw log")
173175
console.error(rs.raw_log);
174176
throw(e);
@@ -179,7 +181,7 @@ if (argv.instantiate) {
179181
}
180182

181183
const contractAddress = await instantiate(codeId, {
182-
price_feed_id: Array.from(Buffer.from(pythLunaPriceFeedId, "hex")),
184+
price_feed_id: Array.from(Buffer.from(pythPriceFeedId, "hex")),
183185
pyth_contract_addr: pythContractAddress
184186
});
185187

@@ -209,7 +211,7 @@ if (argv.migrate) {
209211
feeDenoms,
210212
gasPrices,
211213
});
212-
214+
213215
const rs = await lcd.tx.broadcast(tx);
214216
var resultCodeId;
215217
try {

0 commit comments

Comments
 (0)