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

feat: oracle async wrapper and docs, other misc updates #15

Merged
merged 2 commits into from
Nov 1, 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ $ yarn test
Docs will be available on a vitepress site. You can run the site locally with this command:

```
$ yarn run docs:dev
$ yarn docs:dev
```
4 changes: 3 additions & 1 deletion docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ export default defineConfig({
text: 'Examples',
items: [
{ text: 'Swap', link: '/swap' },
{ text: 'Oracle', link: '/oracle' },
]
}
],

socialLinks: [
{ icon: 'github', link: 'https://github.com/vuejs/vitepress' }
{ icon: 'github', link: 'https://github.com/securesecrets/shadejs' },
{ icon: 'discord', link: 'https://discord.com/channels/905665558610051113/905670616391233566' }
]
}
})
15 changes: 8 additions & 7 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ layout: home

hero:
name: "ShadeJS"
text: "Powerful TypeScript Library for Shade Integration"
text: "Powerful SDK for Shade Integration"
tagline: Simple, Robust, and Efficient Developer Tooling
actions:
- theme: brand
Expand All @@ -15,11 +15,12 @@ hero:
# link: /api-examples

features:
- title: Feature A
details: Lorem ipsum dolor sit amet, consectetur adipiscing elit
- title: Feature B
details: Lorem ipsum dolor sit amet, consectetur adipiscing elit
- title: Feature C
details: Lorem ipsum dolor sit amet, consectetur adipiscing elit
- title: TypeScript Support
details: Seamlessly integrate into your javascript projects.
- title: Shade Smart Contracts
details: Query and execute message interfaces defined for interating with Shade Protocol
- title: Secret.js Wrapper
details: Wraps Secret Network's javascript SDK to simplify the developer experience

---

128 changes: 128 additions & 0 deletions docs/oracle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Oracle Examples

This page demonstrates how to query the Shade Oracle Router, which serves price feeds from various sources inluding: Band Protocol, ShadeSwap pools, derivative redemption rates, and others.
## Single Oracle Price

**input**

```js
async function queryPrice({
contractAddress,
codeHash,
oracleKey,
lcdEndpoint,
chainId,
}:{
contractAddress: string,
codeHash?: string,
oracleKey: string,
lcdEndpoint?: string,
chainId?: string,
}) : Promise<ParsedOraclePriceResponse>
```
::: warning
It is recommended that you provide your own LCD endpoint, although we do provide a default mainnet option. Performance of the default endpoint is not guaranteed.
:::

**output**

```js
type ParsedOraclePriceResponse = {
oracleKey: string,
rate: string,
lastUpdatedBase: number,
lastUpdatedQuote: number,
}


```

**example use**

```js
const output = await queryPrice({
contractAddress: '[ORACLE_CONTRACT_ADDRESS]',
codeHash: '[ORACLE_CODE_HASH]',,
oracleKey: 'BTC',
})
console.log(output)
```
***console***
```md
const priceParsed = {
oracleKey: 'BTC',
rate: '27917207155600000000000',
lastUpdatedBase: 1696644063,
lastUpdatedQuote: 18446744073709552000,
};
```

## Multiple Oracle Prices

**input**

```js
async function queryPrices({
contractAddress,
codeHash,
oracleKeys,
lcdEndpoint,
chainId,
}:{
contractAddress: string,
codeHash?: string,
oracleKeys: string[],
lcdEndpoint?: string,
chainId?: string,
}) : Promise<ParsedOraclePricesResponse>
```
::: warning
It is recommended that you provide your own LCD endpoint, although we do provide a default mainnet option. Performance of the default endpoint is not guaranteed.
:::

**output**

```js
type ParsedOraclePricesResponse = {
[oracleKey: string]: ParsedOraclePriceResponse
}

// type reference below

type ParsedOraclePriceResponse = {
oracleKey: string,
rate: string,
lastUpdatedBase: number,
lastUpdatedQuote: number,
}


```

**example use**

```js
const output = await queryPrices({
contractAddress: '[ORACLE_CONTRACT_ADDRESS]',
codeHash: '[ORACLE_CODE_HASH]',,
oracleKeys: ['BTC', 'ETH'],
})
console.log(output)
```
***console***
```md
{
BTC: {
oracleKey: 'BTC',
rate: '27917207155600000000000',
lastUpdatedBase: 1696644063,
lastUpdatedQuote: 18446744073709552000,
},
ETH: {
oracleKey: 'ETH',
rate: '1644083682900000000000',
lastUpdatedBase: 1696644063,
lastUpdatedQuote: 18446744073709552000,
},
}
```
8 changes: 4 additions & 4 deletions docs/swap.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This page demonstrates how to query the ShadeSwap contracts
**input**

```js
async function queryFactoryConfig = ({
async function queryFactoryConfig({
contractAddress,
codeHash,
lcdEndpoint,
Expand Down Expand Up @@ -99,7 +99,7 @@ query the list of pairs registered in the factory contract
**input**

```js
async function queryFactoryPairs = ({
async function queryFactoryPairs({
contractAddress,
codeHash,
startingIndex,
Expand Down Expand Up @@ -145,7 +145,7 @@ type FactoryPair = {
**example use**

```js
const output = await queryFactoryPairs = ({
const output = await queryFactoryPairs({
contractAddress: 'secret1ja0hcwvy76grqkpgwznxukgd7t8a8anmmx05pp',
codeHash: '2ad4ed2a4a45fd6de3daca9541ba82c26bb66c76d1c3540de39b509abd26538e'
startingIndex: 0,
Expand Down Expand Up @@ -199,7 +199,7 @@ query the configuration of the pair
**input**

```js
async function queryPairConfig = ({
async function queryPairConfig({
contractAddress,
codeHash,
lcdEndpoint,
Expand Down
44 changes: 38 additions & 6 deletions src/contracts/services/oracle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
parsePricesFromContract,
queryPrice$,
queryPrices$,
queryPrice,
queryPrices,
} from '~/contracts/services/oracle';
import priceResponse from '~/test/mocks/oracle/priceResponse.json';
import pricesResponse from '~/test/mocks/oracle/pricesResponse.json';
Expand Down Expand Up @@ -52,16 +54,18 @@ test('it can parse the prices response', () => {
)).toStrictEqual(pricesParsed);
});

test('it can send the query single price service', () => {
sendSecretClientContractQuery$.mockReturnValue(of(priceResponse));

test('it can send the query single price service', async () => {
const input = {
contractAddress: 'CONTRACT_ADDRESS',
codeHash: 'CODE_HASH',
oracleKey: 'ORACLE_KEY',
lcdEndpoint: 'LCD_ENDPOINT',
chainId: 'CHAIN_ID',
};

// observables function
sendSecretClientContractQuery$.mockReturnValueOnce(of(priceResponse));

let output;
queryPrice$(input).subscribe({
next: (response) => {
Expand All @@ -77,18 +81,33 @@ test('it can send the query single price service', () => {
});

expect(output).toStrictEqual(priceParsed);
});

test('it can send the query multiple prices service', () => {
sendSecretClientContractQuery$.mockReturnValue(of(pricesResponse));
// async/await function
sendSecretClientContractQuery$.mockReturnValueOnce(of(priceResponse));
const response = await queryPrice(input);

expect(sendSecretClientContractQuery$).toHaveBeenCalledWith({
queryMsg: 'MSG_QUERY_ORACLE_PRICE',
client: 'CLIENT',
contractAddress: input.contractAddress,
codeHash: input.codeHash,
});

expect(response).toStrictEqual(priceParsed);
});

test('it can send the query multiple prices service', async () => {
const input = {
contractAddress: 'CONTRACT_ADDRESS',
codeHash: 'CODE_HASH',
oracleKeys: ['ORACLE_KEY'],
lcdEndpoint: 'LCD_ENDPOINT',
chainId: 'CHAIN_ID',
};

// observables function
sendSecretClientContractQuery$.mockReturnValueOnce(of(pricesResponse));

let output;
queryPrices$(input).subscribe({
next: (response) => {
Expand All @@ -104,4 +123,17 @@ test('it can send the query multiple prices service', () => {
});

expect(output).toStrictEqual(pricesParsed);

// async/await function
sendSecretClientContractQuery$.mockReturnValueOnce(of(pricesResponse));
const response = await queryPrices(input);

expect(sendSecretClientContractQuery$).toHaveBeenCalledWith({
queryMsg: 'MSG_QUERY_ORACLE_PRICES',
client: 'CLIENT',
contractAddress: input.contractAddress,
codeHash: input.codeHash,
});

expect(response).toStrictEqual(pricesParsed);
});
53 changes: 53 additions & 0 deletions src/contracts/services/oracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
switchMap,
first,
map,
lastValueFrom,
} from 'rxjs';
import { sendSecretClientContractQuery$ } from '~/client/services/clientServices';
import { getActiveQueryClient$ } from '~/client';
Expand Down Expand Up @@ -66,6 +67,31 @@ const queryPrice$ = ({
first(),
);

/**
* query the price of an asset using the oracle key
*/
async function queryPrice({
contractAddress,
codeHash,
oracleKey,
lcdEndpoint,
chainId,
}:{
contractAddress: string,
codeHash?: string,
oracleKey: string,
lcdEndpoint?: string,
chainId?: string,
}) {
return lastValueFrom(queryPrice$({
contractAddress,
codeHash,
oracleKey,
lcdEndpoint,
chainId,
}));
}

/**
* query multiple asset prices using oracle keys
*/
Expand All @@ -92,9 +118,36 @@ const queryPrices$ = ({
first(),
);

/**
* query multiple asset prices using oracle keys
*/
async function queryPrices({
contractAddress,
codeHash,
oracleKeys,
lcdEndpoint,
chainId,
}:{
contractAddress: string,
codeHash?: string,
oracleKeys: string[],
lcdEndpoint?: string,
chainId?: string,
}) {
return lastValueFrom(queryPrices$({
contractAddress,
codeHash,
oracleKeys,
lcdEndpoint,
chainId,
}));
}

export {
parsePriceFromContract,
parsePricesFromContract,
queryPrice$,
queryPrices$,
queryPrice,
queryPrices,
};
Loading
Loading