-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- PriceAuthorityRegistryAdmin reference - selected BootstrapPermissions += priceAuthority - prune chainlink integration; dup API - prune out-dated / redundant Board docs - refine price authority API link - nav: move price authority under deployed contracts - move price quote data types from zoe to price-authority - add vats to deployed contracts; esp priceAuthority
- Loading branch information
Showing
11 changed files
with
91 additions
and
327 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,5 @@ | ||
# Chainlink Integration | ||
See | ||
|
||
This document explains how to consume [Chainlink | ||
oracles](https://chain.link) when unit testing, integration testing, and | ||
actually on-chain. | ||
|
||
## Overview | ||
|
||
Using Chainlink on Agoric provides two main features: | ||
- Price feeds are exposed on Agoric via the on-chain `home.priceAuthority`. This is an | ||
officially-sponsored [price authority](/guides/zoe/price-authority) built | ||
from aggregating several Chainlink nodes. | ||
- [Chainlink's Any API](https://docs.chain.link/docs/request-and-receive-data) | ||
can initiate a job on a single oracle and return its results | ||
|
||
We have tested these features with [actual Chainlink oracle | ||
software](https://github.com/Agoric/dapp-oracle/blob/HEAD/chainlink-agoric/README.md). | ||
|
||
**Note**: Chainlink has not yet (as of Nov 16, 2020) finished setting up an incentivized testnet for established Chainlink node operators to connect to Agoric. | ||
|
||
## Price Authority | ||
|
||
To test your contract against a locally-simulated price authority, just follow | ||
the instructions in [the Price Authority API](/reference/zoe-api/price-authority). | ||
|
||
To use the curated on-chain price authority, see `home.priceAuthority`. For | ||
example, to get a quote for selling `30 Testnet.$LINK` in `Testnet.$USD`: | ||
|
||
(Note that this is a mock price until there are actual Chainlink nodes on the | ||
testnet). | ||
|
||
```js | ||
const linkIssuer = E(home.wallet).getIssuer('Testnet.$LINK'); | ||
const linkBrand = await E(linkIssuer).getBrand(); | ||
const linkAmount = AmountMath.make(linkBrand, 30 * 10 ** 18); | ||
const usdBrand = await E(E(home.wallet).getIssuer('Testnet.$USD')).getBrand(); | ||
const { quoteAmount: { value: [{ amountOut: usdAmount, timestamp }] } } = await E(home.priceAuthority).quoteGiven(linkAmount, usdBrand); | ||
``` | ||
|
||
## Any API | ||
|
||
To use Chainlink's Any API, you need to get an instance of the | ||
[Low-level Oracle Query Contract](/guides/zoe/contracts/oracle) and submit a | ||
query of the form: | ||
|
||
```js | ||
{ | ||
jobId: <Chainlink JobId>, | ||
params: { ...<job parameters> } | ||
} | ||
``` | ||
|
||
The oracle node returns its result, which is a JSONable value such as a string. | ||
This is sent as your query's reply. | ||
|
||
You can test these queries against a locally-running Chainlink node that you | ||
control. Follow [the Chainlink integration | ||
instructions](https://github.com/Agoric/dapp-oracle/blob/HEAD/chainlink-agoric/README.md) | ||
to set it up. | ||
|
||
There is also a more limited local node that emulates part of the Chainlink API | ||
without having to run Docker containers. This is the [local (mock) builtin | ||
oracle](https://github.com/agoric/dapp-oracle#running-a-local-builtin-oracle). | ||
- [Price Authorty Guide](./zoe/price-authority) | ||
- [PriceAuthority API](../reference/zoe-api/price-authority) | ||
- [Deployed Zoe Contracts](./zoe/actual-contracts/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,95 +1 @@ | ||
# The Agoric Board | ||
|
||
## Introduction | ||
|
||
The Board is a shared, on-chain location that is where users post an object as a value and make | ||
it accessible to others. When a user posts a value, they receive a unique ID | ||
for that value. Others can get the value just by knowing the ID. You can make | ||
an ID known by any communication method; private email, a DM or other private | ||
message, an email blast to a mailing list or many individuals, listing it on a website, etc. | ||
|
||
In particular, the Board is frequently used to give others access to deposit | ||
facets. After you post a deposit facet object to the Board, you distribute its | ||
Board ID string as widely as you'd like. Anyone who has that ID can use it to | ||
get access to its value, the deposit facet object. They can then safely deposit | ||
assets into the facet's associated purse without being able to withdraw assets | ||
from the purse or check its balance. | ||
|
||
The `ids()` method returns all of the Board's currently used IDs. | ||
This means anyone can access any Board-stored value. The Board is public, | ||
not private. | ||
|
||
Note that when calling from the REPL's `home` object, you must use | ||
the [`E` syntax](/guides/js-programming/eventual-send) | ||
as shown below. | ||
|
||
## `E(home.board).getId(value)` | ||
- `value` `{ any }` | ||
- Returns: `{ string }` | ||
|
||
If the `value` is present in the Board, this method returns its Board-associated ID value. | ||
|
||
If the `value` is **not** present in the Board, this method adds it to the Board and assigns it | ||
an associated ID value. It returns the new ID value. | ||
|
||
```js | ||
// Create an ID for an object that you want to make public | ||
command[1] E(home.board).getId(auctionInvitation) | ||
history[1] "1403739213" | ||
// The value auctionInvitation (an Invitation object) now has the ID "1403739213" | ||
command[2] E(home.board).getId(auctionInvitation) | ||
history[2] "1403739213" | ||
``` | ||
|
||
## `E(home.board).getValue(id)` | ||
- `id` `{ string }` | ||
- Returns: `{ any }` | ||
|
||
Looks up the `id` value in the Board and returns the Board-associated value for that ID. | ||
|
||
With respect to the `CRC` used in an error message below, an ID has two parts, the raw id | ||
and a [CRC](https://en.wikipedia.org/wiki/Cyclic_redundancy_check). The CRC error | ||
happens when the passed-in id's CRC value is checked. The alleged ID is split into its | ||
two parts, and if the CRC in the alleged ID doesn't match the CRC produced at this time | ||
from the raw ID value, it throws the error. | ||
|
||
Errors: | ||
- If the `id` value is not a string, errors with the message "id must be string" and a log of the failing `id` that was passed in. | ||
- If the `id` value has too few digits, errors with the message "id must consist of at least 3 digits". | ||
- If the `id` value has a different CRC value than the stored one, errors with the message "id is probably a typo, cannot verify CRC". | ||
- If the `id` value is not in the Board, errors with the message "board does not have id: [id]". | ||
```js | ||
// Continuing from the example above in getValue(), the id returns its associated value | ||
command[3] E(home.board).getValue("1403739213") | ||
// Returns the "abc" value | ||
history[3] [Alleged: presence o-102]{} | ||
``` | ||
|
||
## `E(home.board).has(value)` | ||
- `value` `{ any }` | ||
- Returns `{ boolean }` | ||
|
||
Returns `true` if the specified value has an associated Board ID. | ||
|
||
```js | ||
// Pass an id, not a value, so returns false | ||
command[4] E(home.board).has("1403739213") | ||
history[4] false | ||
// Pass a value that does have an id in the Board, so returns true | ||
command[5] E(home.board).has(auctionInvitation) | ||
history[5] true | ||
``` | ||
|
||
## `E(home.board).ids()` | ||
- Returns: `{ Array of strings }` | ||
|
||
Returns an array of all IDs in the Board. Remember, the Board is public, so | ||
anyone can access anything in it. | ||
|
||
```js | ||
command[6] E(home.board).ids() | ||
history[6] ["604346717","381205908","1667979430","1576549616","1532665031", | ||
"727995140","371571443","1456154132","500716545","815824725", | ||
"262188032","1265655452","1202180815","813441138","605437304", | ||
"1403739213"] | ||
``` | ||
see [Board Name Service](../../guides/integration/name-services#the-board-publishing-under-arbitrary-names) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,117 +1 @@ | ||
# Price Authority | ||
|
||
`PriceAuthority` is an object that mints `PriceQuotes` and handles | ||
triggers and notifiers for changes in the price. | ||
|
||
`PriceAuthority` objects use timer services. You should be familiar with the objects | ||
and methods in the [REPL TimerService document](./timerServices) | ||
|
||
## Price quote objects | ||
|
||
Before discussing `PriceAuthority` and `PriceAuthorityAdmin` methods, we need to | ||
cover the other price-based objects and methods they interact with. | ||
|
||
A `PriceQuote` is an object with two properties: | ||
- `quoteAmount`: An `Amount` whose value is a `PriceQuoteValue`. | ||
- `quotePayment`: The `quoteAmount` wrapped as a `Payment`. It is either an `ERef<Payment>` or `null`. | ||
|
||
The `quoteAmount` describes a price available at a particular time. So that price can be shared by | ||
recipients with others, its associated `quotePayment` is the same value wrapped as a payment from the QuoteIssuer. | ||
This lets other recipients validate the quote is from the intended source. | ||
|
||
Accessing the `quotePayment` value requires a round trip, so `quoteAmount`is included for the original recipient's | ||
convenience. They know who they received it from and don't need to validate provenance. | ||
|
||
A `PriceQuoteValue` is the `Value` part of a `quoteAmount`. Its properties are: | ||
- `amountIn` `{ Amount }`: The amount supplied to a trade | ||
- `amountOut` `{ Amount }`: The quoted result of trading `amountIn` | ||
- `timer` `{ TimerService }`: The service that gave the `timestamp` | ||
- `timestamp` `{ Timestamp }`: A timestamp according to `timer` for the quote | ||
- `conditions` `{ any= }`: Additional conditions for the quote | ||
|
||
## `getQuoteIssuer(brandIn, brandOut)` | ||
- `brandIn` `{ Brand }` | ||
- `brandOut` `{ Brand }` | ||
- Returns: `{ ERef<Issuer> }` | ||
|
||
Returns the ERTP `PriceQuote` issuer for the specified brands pair. | ||
|
||
## `getTimerService(brandIn, brandOut)` | ||
- `brandIn` `{ Brand }` | ||
- `brandOut` `{ Brand }` | ||
- Returns: `{ ERef<TimerService> }` | ||
|
||
Returns the timer used in `PriceQuotes` for the specified brands. | ||
|
||
## `makeQuoteNotifier(amountIn, brandOut)` | ||
- `amountIn` `{ Amount }` | ||
- `brandOut` `{ Brand }` | ||
- Returns: `{ ERef<Notifier<PriceQuotes>> }` | ||
|
||
Be notified of the latest `PriceQuotes` for the given `amountIn`. | ||
Different `PriceAuthories` may issue these at very different rates. | ||
|
||
## `getPriceNotifier(brandIn, brandOut)` | ||
- `brandIn` `{ Brand }` | ||
- `brandOut` `{ Brand }` | ||
- Returns: `{ Notifier }` | ||
|
||
Returns a notifier for the specified brands. Different `PriceAuthories` may | ||
issue these at very different rates. | ||
|
||
## `quoteGiven(amountIn, brandOut)` | ||
- `amountIn` `{ Amount }` | ||
- `brandOut` `{ Brand }` | ||
- Returns: `{ Promise<PriceQuote> }` | ||
|
||
Returns a price quote corresponding to the specified amount in the specified brand. | ||
`quoteGiven() essentially asks "how much `brandOut` would I get for `amountIn`. | ||
|
||
Note that `quoteGiven()` and `quoteWanted()` can give different answers for not-trivial amounts. | ||
|
||
## `quoteWanted(brandIn, amountOut)` | ||
- `brandIn` `{ Brand }` | ||
- `amountOut` `{ Amount }` | ||
- Returns: `{ Promise<PriceQuote> }` | ||
|
||
Returns a price quote for the specified amount in the specified brand. | ||
`quoteWanted() essentially asks "how much `brandIn` would I have to pay to get `amountOut`. | ||
|
||
Note that `quoteGiven()` and `quoteWanted()` can give different answers for not-trivial amounts. | ||
|
||
## `quoteAtTime(deadline, amountIn, brandOut)` | ||
- `deadline` `{ Timestamp }` | ||
- `amountIn` `{ Amount }` | ||
- `brandOut` `{ Brand }` | ||
- Returns: `{ Promise<PriceQuote> }` | ||
|
||
Resolves after `deadline` passes on the Price Authority's `timerService` | ||
with `amountIn`'s price quote at that time. | ||
|
||
## `quoteWhenGT(amountIn, amountOutLimit)` | ||
- `amountIn` `{ Amount }` | ||
- `amountOutLimit `{ Amount }` | ||
- Returns: `{ Promise<PriceQuote> }` | ||
|
||
Resolve when a price quote of `amountIn` exceeds `amountOutLimit` | ||
|
||
## `quoteWhenGTE(amountIn, amountOutLimit)` | ||
- `amountIn` `{ Amount }` | ||
- `amountOutLimit `{ Amount }` | ||
- Returns: `{ Promise<PriceQuote> }` | ||
|
||
Resolve when a price quote of `amountIn` reaches or exceeds `amountOutLimit` | ||
|
||
## `quoteWhenLTE(amountIn, amountOutLimit)` | ||
- `amountIn` `{ Amount }` | ||
- `amountOutLimit `{ Amount }` | ||
- Returns: `{ Promise<PriceQuote> }` | ||
|
||
Resolve when a price quote of `amountIn` reaches or drops below `amountOutLimit` | ||
|
||
## `quoteWhenLT(amountIn, amountOutLimit)` | ||
- `amountIn` `{ Amount }` | ||
- `amountOutLimit `{ Amount }` | ||
- Returns: `{ Promise<PriceQuote> }` | ||
|
||
Resolve when a price quote of `amountIn` drops to below `amountOutLimit`. | ||
see [Price Authority Guide](../../guides/zoe/price-authority), [PriceAuthority API](../zoe-api/price-authority) |
Oops, something went wrong.