feat: add Price Oracles support (#2688)

This commit is contained in:
Omar Khan
2024-05-23 12:10:00 -04:00
committed by GitHub
parent 9b3bb9c14b
commit 23adb4924b
23 changed files with 1029 additions and 5 deletions

View File

@@ -104,7 +104,7 @@ describe('fundWallet', function () {
})
assert.equal(dropsToXrp(info.result.account_data.Balance), balance)
assert.equal(balance, 10000)
assert.equal(balance, 1000)
/*
* No test for fund given wallet because the hooks v3 testnet faucet

View File

@@ -0,0 +1,78 @@
import { stringToHex } from '@xrplf/isomorphic/utils'
import { assert } from 'chai'
import { OracleSet } from '../../../src'
import serverUrl from '../serverUrl'
import {
setupClient,
teardownClient,
type XrplIntegrationTestContext,
} from '../setup'
import { testTransaction } from '../utils'
// how long before each test case times out
const TIMEOUT = 20000
describe('get_aggregate_price', function () {
let testContext: XrplIntegrationTestContext
beforeEach(async () => {
testContext = await setupClient(serverUrl)
})
afterEach(async () => teardownClient(testContext))
it(
'base',
async () => {
const tx: OracleSet = {
TransactionType: 'OracleSet',
Account: testContext.wallet.classicAddress,
OracleDocumentID: 1234,
LastUpdateTime: Math.floor(Date.now() / 1000),
PriceDataSeries: [
{
PriceData: {
BaseAsset: 'XRP',
QuoteAsset: 'USD',
AssetPrice: 740,
Scale: 3,
},
},
],
Provider: stringToHex('chainlink'),
URI: '6469645F6578616D706C65',
AssetClass: stringToHex('currency'),
}
await testTransaction(testContext.client, tx, testContext.wallet)
// confirm that the Oracle was actually created
const getAggregatePriceResponse = await testContext.client.request({
command: 'get_aggregate_price',
account: testContext.wallet.classicAddress,
base_asset: 'XRP',
quote_asset: 'USD',
trim: 20,
oracles: [
{
account: testContext.wallet.classicAddress,
oracle_document_id: 1234,
},
],
})
assert.deepEqual(getAggregatePriceResponse.result.entire_set, {
mean: '0.74',
size: 1,
standard_deviation: '0',
})
assert.deepEqual(getAggregatePriceResponse.result.trimmed_set, {
mean: '0.74',
size: 1,
standard_deviation: '0',
})
assert.equal(getAggregatePriceResponse.result.median, '0.74')
assert.equal(getAggregatePriceResponse.result.time, tx.LastUpdateTime)
},
TIMEOUT,
)
})

View File

@@ -0,0 +1,76 @@
import { stringToHex } from '@xrplf/isomorphic/utils'
import { assert } from 'chai'
import { OracleSet, OracleDelete } from '../../../src'
import serverUrl from '../serverUrl'
import {
setupClient,
teardownClient,
type XrplIntegrationTestContext,
} from '../setup'
import { testTransaction } from '../utils'
// how long before each test case times out
const TIMEOUT = 20000
describe('OracleDelete', function () {
let testContext: XrplIntegrationTestContext
beforeEach(async () => {
testContext = await setupClient(serverUrl)
})
afterEach(async () => teardownClient(testContext))
it(
'base',
async () => {
const setTx: OracleSet = {
TransactionType: 'OracleSet',
Account: testContext.wallet.classicAddress,
OracleDocumentID: 1234,
LastUpdateTime: Math.floor(Date.now() / 1000),
PriceDataSeries: [
{
PriceData: {
BaseAsset: 'XRP',
QuoteAsset: 'USD',
AssetPrice: 740,
Scale: 3,
},
},
],
Provider: stringToHex('chainlink'),
URI: '6469645F6578616D706C65',
AssetClass: stringToHex('currency'),
}
await testTransaction(testContext.client, setTx, testContext.wallet)
const aoResult = await testContext.client.request({
command: 'account_objects',
account: testContext.wallet.classicAddress,
type: 'oracle',
})
// confirm that the Oracle was created
assert.equal(aoResult.result.account_objects.length, 1)
const deleteTx: OracleDelete = {
TransactionType: 'OracleDelete',
Account: testContext.wallet.classicAddress,
OracleDocumentID: 1234,
}
await testTransaction(testContext.client, deleteTx, testContext.wallet)
const aoResult2 = await testContext.client.request({
command: 'account_objects',
account: testContext.wallet.classicAddress,
})
// confirm that the Oracle was actually deleted
assert.equal(aoResult2.result.account_objects.length, 0)
},
TIMEOUT,
)
})

View File

@@ -0,0 +1,74 @@
import { stringToHex } from '@xrplf/isomorphic/utils'
import { assert } from 'chai'
import { OracleSet } from '../../../src'
import { Oracle } from '../../../src/models/ledger'
import serverUrl from '../serverUrl'
import {
setupClient,
teardownClient,
type XrplIntegrationTestContext,
} from '../setup'
import { testTransaction } from '../utils'
// how long before each test case times out
const TIMEOUT = 20000
describe('OracleSet', function () {
let testContext: XrplIntegrationTestContext
beforeEach(async () => {
testContext = await setupClient(serverUrl)
})
afterEach(async () => teardownClient(testContext))
it(
'base',
async () => {
const tx: OracleSet = {
TransactionType: 'OracleSet',
Account: testContext.wallet.classicAddress,
OracleDocumentID: 1234,
LastUpdateTime: Math.floor(Date.now() / 1000),
PriceDataSeries: [
{
PriceData: {
BaseAsset: 'XRP',
QuoteAsset: 'USD',
AssetPrice: 740,
Scale: 3,
},
},
],
Provider: stringToHex('chainlink'),
URI: '6469645F6578616D706C65',
AssetClass: stringToHex('currency'),
}
await testTransaction(testContext.client, tx, testContext.wallet)
const result = await testContext.client.request({
command: 'account_objects',
account: testContext.wallet.classicAddress,
type: 'oracle',
})
// confirm that the Oracle was actually created
assert.equal(result.result.account_objects.length, 1)
// confirm details of Oracle ledger entry object
const oracle = result.result.account_objects[0] as Oracle
assert.equal(oracle.LastUpdateTime, tx.LastUpdateTime)
assert.equal(oracle.Owner, testContext.wallet.classicAddress)
assert.equal(oracle.AssetClass, tx.AssetClass)
assert.equal(oracle.Provider, tx.Provider)
assert.equal(oracle.PriceDataSeries.length, 1)
assert.equal(oracle.PriceDataSeries[0].PriceData.BaseAsset, 'XRP')
assert.equal(oracle.PriceDataSeries[0].PriceData.QuoteAsset, 'USD')
assert.equal(oracle.PriceDataSeries[0].PriceData.AssetPrice, '2e4')
assert.equal(oracle.PriceDataSeries[0].PriceData.Scale, 3)
assert.equal(oracle.Flags, 0)
},
TIMEOUT,
)
})