Beta Price Oracle: Requesting current price

6 348
Avatar for JonathanSilverblood
3 years ago

Introduction

We at generalprotocols are running a public beta of a Price Oracle that is used for our AnyHedge product. This article will show you how to use the @generalprotocols/price-oracle NPM library to connect with the price oracle, request the latest price message, verify the message signature and finally parse the price message to get to the price data.

Setting up

Install the library so that it is available in your project:

npm install @generalprotocols/price-oracle

Include the library parts you will be using, and choose which oracle service provider to use (our beta is hosted at oracles.generalprotocols.com) and which oracle you want to get data for (our beta oracle uses the public key below):

// Import the Price Oracle library.
const { OracleData, OracleNetwork, OracleProtocol } = require('@generalprotocols/price-oracle');

// Choose which oracle to use, and what service provider to use to get the oracle data.
const oracleAddress = 'oracles.generalprotocols.com';
const oraclePublicKey = '0273ee49099f0a09be514cbb45756bf49ad256d0a6de993107e98c89c16b6fa84e';

Requesting the current price

To get the most recently issued price message, first form a request structure, then send the request to the oracle service provider:

// Create a request for the most recently issued price message, for the given oracle.
const requestString = { action: 'latest', public_key: oraclePublicKey };

// Send the request to the oracle service provider, indexing the given oracle data.
const response = await OracleNetwork.request(requestString, oracleAddress);

The response is an object that looks like this:

message: <Buffer df 77 00 00 42 e1 09 00 00 00 00 00 00 00 00 00 ...>,
public_key: <Buffer 02 73 ee 49 09 9f 0a 09 be 51 4c bb 45 75 6b f4 ...>,
signature: <Buffer 31 9f ee dd 7a 19 45 57 dc 3b c0 1d 7f 74 c4 92 ...>

Validating message signature

When you have the response, you should validate that it is signed by the oracle that you requested. Simply call the library function and pass in the message and signature you got in the response, but use the same oracle public key as before so you can be sure the data provided is for the oracle you expect:

// Verify that the signature provided matches the oracle message and public key.
const validity = await OracleData.verifyMessageSignature(response.message, response.signature, Buffer.from(oraclePublicKey, 'hex'));

The value returned will be a boolean indicating the validity of the signature.

true

Parsing price message

After you've made sure that the message is properly signed, you can parse it to get the data stored within the message which you can then use in your application:

// Parse an oracle price message into parts.
const messageParts = await OracleData.parsePriceMessage(response.message);

The returned value is an object with the following properties:

 price: 30311,
 blockHeight: 647491,
 blockHash: <Buffer 00 00 00 00 00 00 00 00 00 a9 d6 af a6 bc 32 ...>,
 blockSequence: 1,
 oracleSequence: 60427,
 timestamp: 1596903497

22
$ 2.33
$ 0.55 from @molecular
$ 0.50 from @emergent_reasons
$ 0.50 from @p0oker
+ 6
Avatar for JonathanSilverblood
3 years ago

Comments

wonderful Article brother......Support me

$ 0.00
3 years ago

nice! 😁

what is(are) your Oracle's price source(es)? I remember back when I still used Legacy BTC, https://bitcoinaverage.com had the best aggregation for "weighted" pricing..

in the custodial.js example you provided me, there was a price request const bitpayResponse = await fetch('https://bitpay.com/api/rates/BCH/USD'); would this Oracle eventually replace that? hmm, maybe not?

I'm still stuck in the Ethereum world where contracts can read a price oracle on-chain. Bitcoin Script can't do that, but I imagine this sort of oracle would be most useful when its output is fed into a contract's params. do you have an example of the oracle being used in this way?

$ 0.00
3 years ago

would this Oracle eventually replace that?

Kindof. It makes a lot of sense to use the same source for the price when you set up the contract, as when the contract settles.

$ 0.00
3 years ago

Currently, the Beta price oracle is using bitpay as the price source. This has a good symbolic representation of actual purchasing power of the coins and fit well with the idea of AnyHedge being a contract to store value.

The bitpay price feed is not perfect though, and we might decide to change before the final release of anyhedge. Note that the oracle libraries is agnostic to which oracle you want to use and that the oracle is identified by the public key it uses for signing the data - the same oracle service provider can index multiple oracles.

We have some collaboration going on to try and make the actual oracle data anchored and/or stored on-chain for auditability purposes, but as you said it's not possible for a smart contract to discover and validate the price on-chain itself.

Yes, I do have an example of a contract that uses this oracle in that way, the anyhedge contract: https://gitlab.com/GeneralProtocols/anyhedge/library/-/blob/development/lib/anyhedge.cash#L103

$ 0.10
3 years ago

ahhh, "The AnyHedge Contract", 255 lines of DeFi goodness 🤩 gonna have to take this on when my eyes are rested and my mind is clear .. thanks for the info!

$ 0.00
3 years ago