Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: deploy contracts #26

Merged
merged 5 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
unit-tests/* linguist-vendored
unit-tests/** linguist-vendored
example/cbtc/** linguist-vendored
* text=lf
139 changes: 54 additions & 85 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@

# Introduction

**Status**: **Developer Preview**
**Status**: **Beta**

This initial release is a Developer Preview of the Stacks x Pyth integration. The integration is live on both the testnet and mainnet networks to help developers test, give feedback, and ensure the reliability and stability of the integration.
The Pyth protocol integration is available as a Beta on both testnet and mainnet networks, to help developers test, give feedback, and ensure the reliability and stability of the integration.

[Stacks](http://stacks.co) is a blockchain linked to Bitcoin by its consensus mechanism that spans the two chains, called Proof of Transfer. This enables Stacks to leverage Bitcoin’s security and enables Stacks apps to use Bitcoin’s state.
Stacks is a Bitcoin layer that enables decentralized apps and smart contracts.
Expand All @@ -39,86 +39,14 @@ $ npm install
$ npm test
```

## Setup and Test a Devnet Bridge
## Consuming price feeds

This guide assumes that a recent installation of Clarinet (available on brew and winget) is available locally.

The bridge can be operated through an off-chain service, `stacks-pyth-relayer`, and a set of contracts implementing the core functionalities specified by the Wormhole protocol.

Start a local Devnet using the command:
```bash
$ clarinet integrate
```

In another console, the service can be compiled and installed using the command:

```bash
$ cd stacks-pyth-bridge/relayer
$ cargo install --path .
```

Once installed, a config can be generated using the command:

```bash
$ stacks-pyth-relayer config new
```

A typical valid config looks like this:

```toml
[pyth]
network = "mainnet"
price_service_url = "https://xc-mainnet.pyth.network"
price_feeds_ids = [
# "0xf9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b", # BTC-USD (testnet)
# "0xc2703fcc925ad32b6256afc3ebad634970d1b1ffb3f4143e36b2d055b1dcd29b", # STX-USD (testnet)
"0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43", # BTC-USD (mainnet)
]
# Price feed IDs available here: https://pyth.network/developers/price-feed-ids

[stacks]
network = "devnet"
stacks_node_rpc_url = "http://localhost:20443"
pyth_oracle_contract_address = "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.pyth-price-feed-oracle-v1"
mnemonic = "prevent gallery kind limb income control noise together echo rival record wedding sense uncover school version force bleak nuclear include danger skirt enact arrow"
derivation_path = "m/44'/5757'/0'/0/0"
start_block = 6

[bridge]
price_updates_per_minute = 5
enable_rbf = true
enable_microblocks = true

[event_observer]
ingestion_port = 20456
```

After reviewing the generated config, the service can be tested using the command:

```bash
$ stacks-pyth-relayer service ping --config-path Bridge.toml
```

After validating that the service can connect to the Price API service and the Stacks chain, the service can be run with the command:

```bash
$ stacks-pyth-relayer service start --config-path Bridge.toml
```

The operator will start fetching prices from the Pyth network Price API and submit these Verified Action Attestations to the Pyth contract. The Pyth contract submits these VAAs to the wormhole contract, ensuring the guardians correctly sign the payloads.

![architecture](docs/architecture.png)


## How to consume the price feeds

### Latest Version
### Latest Deployments

| network | address |
|---------|---------------------------------------------------------------------|
| testnet | ST2J933XB2CP2JQ1A4FGN8JA968BBG3NK3EPXFQFR.pyth-oracle-dev-preview-1 |
| mainnet | SP2J933XB2CP2JQ1A4FGN8JA968BBG3NK3EKZ7Q9F.pyth-oracle-dev-preview-1 |

| testnet | [ST3XVPDNZJ9QN0KJ327SYPKP6YS15PHJRBKWXTZ3M.pyth-helper-v1](https://explorer.hiro.so/txid/0x55bb516f989e18fc55e0f0921201a73c4f95e77abad9e3b129a61a2d43e92a68?chain=testnet) |
| mainnet | [SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP.pyth-helper-v1](https://explorer.hiro.so/txid/0xd43086bd98922ae0f8988c5988bbd37d8cb48acbe6b01c399dde14ca800ac10d?chain=mainnet) |

### Onchain

Expand All @@ -128,14 +56,14 @@ The `pyth-helper-v1` contract is exposing the following method:
(define-public (read-price
(price-feed-id (buff 32))))
```

That can be consumed with the following invocation:

```clarity
(contract-call?
'ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.pyth-helper-v1 ;; Address of the helper contract
'SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP.pyth-helper-v1 ;; Address of the helper contract
read-price
0xf9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b)
0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43) ;; BTC-USD price identifier
```

The authenticity of the price feeds is verified during their ingestion, making the cost of queries as light as possible.
Expand Down Expand Up @@ -171,8 +99,49 @@ For every new price recorded and stored on chain, the `pyth-store-v1` is emittin

These events can be observed using [Chainhook](https://github.com/hirosystems/chainhook), using the `print` predicates.

## Todos:
## Updating price feeds

Pyth Network uses [a pull price update model](https://docs.pyth.network/documentation/pythnet-price-feeds/on-demand) that is slightly different from other oracles you may be more familiar with. Most oracles today use a push model, where the oracle runs an off-chain process that continuously sends transactions to update an on-chain price. In contrast, Pyth Network does not operate an off-chain process that pushes prices on-chain. Instead, it delegates this work to Pyth Network users.

[Hermes](https://docs.pyth.network/documentation/pythnet-price-feeds/hermes) is a web service that listens to the Pythnet and the Wormhole Network for Pyth price updates, and serves them via a convenient web API. It provides Pyth's latest price update data format that are more cost-effective to verify and use on-chain.
Hermes allows users to easily query for recent price updates via a REST API, or subscribe to a websocket for streaming updates. The Pyth Network's Javascript SDKs connect to an instance of Hermes to fetch price updates.

```console
$ curl https://hermes.pyth.network/api/latest_price_feeds?ids[]=ec7a775f46379b5e943c3526b1c8d54cd49749176b0b98e02dde68d1bd335c17&binary=true \
| jq -r '.[0]'.vaa \
| base64 --decode \
| hexdump -ve '1/1 "%.2x"'

504e41550100000003b8...a7b10321ad7c2404a910
```

This sequence of bytes is a Verified Action Approvals (VAA) including the price informations including its cryptographic elements helping the Pyth contract ensuring the authenticity of the data.

This VAA can be encoded as a Clarity buffer, and submitted to the Pyth contract using the following:

```clarity
(contract-call?
'SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP.pyth-helper-v1 ;; Address of the helper contract
verify-and-update-price
0x504e41550100000003b8...a7b10321ad7c2404a910) ;; BTC-USD price update
```

If the VAA is valid, the contract call will return a payload with the following signature:

```clarity
(response
(list 64 {
price-identifier: (buff 32),
price: int,
conf: uint,
expo: int,
ema-price: int,
ema-conf: uint,
publish-time: uint,
prev-publish-time: uint,
})
uint)
```

- [ ] Resolve remaining todo
- [ ] Document usage
- [ ] Document example/cbtc
Including all the prices successfully updating the oracle.
All of the implementation details can be found in [Pyth documentation](https://docs.pyth.network/documentation/how-pyth-works).
32 changes: 16 additions & 16 deletions deployments/v1.mainnet-plan.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,56 +10,56 @@ plan:
transactions:
- contract-publish:
contract-name: wormhole-traits-v1
expected-sender: SP2J933XB2CP2JQ1A4FGN8JA968BBG3NK3EKZ7Q9F
expected-sender: SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP
cost: 1486613
path: contracts/wormhole/wormhole-traits-v1.clar
anchor-block-only: true
clarity-version: 2
- contract-publish:
contract-name: pyth-traits-v1
expected-sender: SP2J933XB2CP2JQ1A4FGN8JA968BBG3NK3EKZ7Q9F
expected-sender: SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP
cost: 1487019
path: contracts/pyth-traits-v1.clar
anchor-block-only: true
clarity-version: 2
- contract-publish:
contract-name: pyth-governance-v1
expected-sender: SP2J933XB2CP2JQ1A4FGN8JA968BBG3NK3EKZ7Q9F
expected-sender: SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP
cost: 1495228
path: contracts/pyth-governance-v1.clar
anchor-block-only: true
clarity-version: 2
- contract-publish:
contract-name: pyth-oracle-v1
expected-sender: SP2J933XB2CP2JQ1A4FGN8JA968BBG3NK3EKZ7Q9F
expected-sender: SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP
cost: 1487263
path: contracts/pyth-oracle-v1.clar
anchor-block-only: true
clarity-version: 2
- contract-publish:
contract-name: pyth-pnau-decoder-v1
expected-sender: SP2J933XB2CP2JQ1A4FGN8JA968BBG3NK3EKZ7Q9F
expected-sender: SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP
cost: 1492627
path: contracts/pyth-pnau-decoder-v1.clar
anchor-block-only: true
clarity-version: 2
- contract-publish:
contract-name: pyth-store-v1
expected-sender: SP2J933XB2CP2JQ1A4FGN8JA968BBG3NK3EKZ7Q9F
expected-sender: SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP
cost: 1487263
path: contracts/pyth-store-v1.clar
anchor-block-only: true
clarity-version: 2
- contract-publish:
contract-name: wormhole-core-v1
expected-sender: SP2J933XB2CP2JQ1A4FGN8JA968BBG3NK3EKZ7Q9F
expected-sender: SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP
cost: 1494091
path: contracts/wormhole/wormhole-core-v1.clar
anchor-block-only: true
clarity-version: 2
- contract-publish:
contract-name: pyth-helper-v1
expected-sender: SP2J933XB2CP2JQ1A4FGN8JA968BBG3NK3EKZ7Q9F
expected-sender: SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP
cost: 1486613
path: contracts/pyth-helper-v1.clar
anchor-block-only: true
Expand All @@ -68,8 +68,8 @@ plan:
- id: 1
transactions:
- contract-call:
contract-id: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.wormhole-core-v1
expected-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
contract-id: SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP.wormhole-core-v1
expected-sender: SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP
method: update-guardians-set
parameters:
# VAA of 1st guardians rotation
Expand Down Expand Up @@ -97,8 +97,8 @@ plan:
0x21f338444e96af31cf44958acf5764844efbddace3b823ed761c340c59ed2685d829818c83eebe8f00f783f1048a53515845536668a9e0c059ade7579a0f4204)'
cost: 5960
- contract-call:
contract-id: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.wormhole-core-v1
expected-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
contract-id: SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP.wormhole-core-v1
expected-sender: SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP
method: update-guardians-set
parameters:
# VAA of 2nd guardians rotation
Expand Down Expand Up @@ -126,8 +126,8 @@ plan:
0x21f338444e96af31cf44958acf5764844efbddace3b823ed761c340c59ed2685d829818c83eebe8f00f783f1048a53515845536668a9e0c059ade7579a0f4204)'
cost: 5960
- contract-call:
contract-id: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.wormhole-core-v1
expected-sender: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM
contract-id: SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP.wormhole-core-v1
expected-sender: SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP
method: update-guardians-set
parameters:
# VAA of 3rd guardians rotation
Expand Down Expand Up @@ -155,8 +155,8 @@ plan:
0x21f338444e96af31cf44958acf5764844efbddace3b823ed761c340c59ed2685d829818c83eebe8f00f783f1048a53515845536668a9e0c059ade7579a0f4204)'
cost: 5960
- contract-call:
contract-id: ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.pyth-helper-v1
expected-sender: ST2CY5V39NHDPWSXMW9QDT3HC3GD6Q6XX4CFRK9AG
contract-id: SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP.pyth-helper-v1
expected-sender: SP19F0S4GN8CJQ4K9PKWRBVE00G2C86QTPTRXZ7GP
method: verify-and-update-price
parameters:
# PNAU payload
Expand Down
Loading