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

Add appointOracle RPC #336

Merged
merged 7 commits into from
Jun 3, 2021
Merged
Show file tree
Hide file tree
Changes from 3 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { MasterNodeRegTestContainer } from '@defichain/testcontainers'
import { ContainerAdapterClient } from '../../container_adapter_client'
import { UTXO } from '../../../src/category/oracle'
import { RpcApiError } from '../../../src'

describe('Oracle', () => {
const container = new MasterNodeRegTestContainer()
const client = new ContainerAdapterClient(container)

beforeAll(async () => {
await container.start()
await container.waitForReady()
await container.waitForWalletCoinbaseMaturity()
})

afterAll(async () => {
await container.stop()
})

it('should appointOracle', async () => {
const priceFeeds = [
{ currency: 'USD', token: 'TESLA' },
{ currency: 'EUR', token: 'APPLE' }
]

const data = await client.oracle.appointOracle(await container.getNewAddress(), priceFeeds, { weightage: 1 })

expect(typeof data).toStrictEqual('string')
expect(data.length).toStrictEqual(64)
})

it('should appointOracle with utxos', async () => {
const priceFeeds = [
{ currency: 'USD', token: 'TESLA' },
{ currency: 'EUR', token: 'APPLE' }
Comment on lines +50 to +51
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should test anomalous text length, e.g. 1 char, 15 char

]

const address = await container.getNewAddress()
const utxos = await container.call('listunspent', [1, 9999999, [address], true])
const inputs: UTXO[] = utxos.map((utxo: UTXO) => {
return {
txid: utxo.txid,
vout: utxo.vout
}
})

const data = await client.oracle.appointOracle(address, priceFeeds, { weightage: 1, utxos: inputs })

expect(typeof data).toStrictEqual('string')
expect(data.length).toStrictEqual(64)
})

it('should not appointOracle with arbitrary utxos', async () => {
const priceFeeds = [
{ currency: 'USD', token: 'TESLA' },
{ currency: 'EUR', token: 'APPLE' }
]

const { txid, vout } = await container.fundAddress(await container.getNewAddress(), 10)
const promise = client.oracle.appointOracle(await container.getNewAddress(), priceFeeds, {
weightage: 1,
utxos: [{ txid, vout }]
})

await expect(promise).rejects.toThrow(RpcApiError)
await expect(promise).rejects.toThrow('RpcApiError: \'Test AppointOracleTx execution failed:\ntx not from foundation member\', code: -32600, method: appointoracle')
jingyi2811 marked this conversation as resolved.
Show resolved Hide resolved
})
})
44 changes: 44 additions & 0 deletions packages/jellyfish-api-core/src/category/oracle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { ApiClient } from '../.'

/**
* Oracle RPCs for DeFi Blockchain
*/
export class Oracle {
private readonly client: ApiClient

constructor (client: ApiClient) {
this.client = client
}

/**
* Creates an oracle appointment transaction and saves it to the database.
jingyi2811 marked this conversation as resolved.
Show resolved Hide resolved
*
* @param {string} address
* @param {PriceFeed[]} priceFeeds
* @param {AppointOracleOptions} [options]
* @param {number} options.weightage
* @param {UTXO[]} [options.utxos = []]
* @param {string} [options.utxos.txid]
* @param {number} [options.utxos.vout]
* @return {Promise<string>}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should document that what is return is actually an txid

*/
async appointOracle (address: string, priceFeeds: PriceFeed[], options: AppointOracleOptions = {}): Promise<string> {
const { utxos = [] } = options
return await this.client.call('appointoracle', [address, priceFeeds, options.weightage, utxos], 'number')
}
}

export interface PriceFeed {
currency: string
token: string
}

export interface AppointOracleOptions {
weightage?: number
utxos?: UTXO[]
}

export interface UTXO {
txid: string
vout: number
}
3 changes: 3 additions & 0 deletions packages/jellyfish-api-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Wallet } from './category/wallet'
import { Account } from './category/account'
import { PoolPair } from './category/poolpair'
import { Token } from './category/token'
import { Oracle } from './category/oracle'

export * from '@defichain/jellyfish-json'

Expand All @@ -18,6 +19,7 @@ export * as wallet from './category/wallet'
export * as poolpair from './category/poolpair'
export * as token from './category/token'
export * as account from './category/account'
export * as oracle from './category/oracle'

/**
* A protocol agnostic DeFiChain node client, RPC calls are separated into their category.
Expand All @@ -31,6 +33,7 @@ export abstract class ApiClient {
public readonly account = new Account(this)
public readonly poolpair = new PoolPair(this)
public readonly token = new Token(this)
public readonly oracle = new Oracle(this)

/**
* A promise based procedure call handling
Expand Down
38 changes: 38 additions & 0 deletions website/docs/jellyfish/api/oracle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
id: oracle
title: Oracle API
sidebar_label: Oracle API
slug: /jellyfish/api/oracle
---

```js
import {Client} from '@defichain/jellyfish'
const client = new Client()
// Using client.oracle.
const something = await client.oracle.method()
```

## appointOracle

Creates an oracle appointment transaction and saves it to the database.

```ts title="client.oracle.appointOracle()"
interface oracle {
appointOracle (address: string, priceFeeds: PriceFeed[], options: AppointOracleOptions = {}): Promise<string>
}

interface PriceFeed {
currency: string
token: string
}

interface AppointOracleOptions {
weightage?: number
utxos?: UTXO[]
}

interface UTXO {
txid: string
vout: number
}
```
3 changes: 2 additions & 1 deletion website/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ module.exports = {
'jellyfish/api/wallet',
'jellyfish/api/poolpair',
'jellyfish/api/token',
'jellyfish/api/account'
'jellyfish/api/account',
'jellyfish/api/oracle'
]
}
],
Expand Down