Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4db4d8cf93 | ||
|
|
1be22264cd | ||
|
|
2b355c5da1 |
63
.github/workflows/nodejs.yml
vendored
Normal file
63
.github/workflows/nodejs.yml
vendored
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
name: Node.js CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ '*' ]
|
||||||
|
tags: [ 'v[0-9]+.[0-9]+.[0-9]+' ]
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: 12
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm test
|
||||||
|
- name: TSLint checks
|
||||||
|
uses: mooyoul/tslint-actions@v1.1.1
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
project: tsconfig.json
|
||||||
|
|
||||||
|
publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [build]
|
||||||
|
if: startsWith(github.ref, 'refs/tags')
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: NPM login
|
||||||
|
# NPM doesn't understand env vars and needs auth file lol
|
||||||
|
run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
|
||||||
|
env:
|
||||||
|
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
|
- name: Set vars
|
||||||
|
id: vars
|
||||||
|
run: |
|
||||||
|
echo "::set-output name=version::$(echo ${GITHUB_REF#refs/tags/v})"
|
||||||
|
echo "::set-output name=repo_name::$(echo ${GITHUB_REPOSITORY#*/})"
|
||||||
|
- name: Check package.json version vs tag
|
||||||
|
run: |
|
||||||
|
[ ${{ steps.vars.outputs.version }} = $(grep '"version":' package.json | grep -o "[0-9.]*") ] || (echo "Git tag doesn't match version in package.json" && false)
|
||||||
|
- name: Publish to npm
|
||||||
|
run: npm publish
|
||||||
|
- name: Create GitHub Release Draft
|
||||||
|
uses: actions/create-release@v1
|
||||||
|
with:
|
||||||
|
tag_name: ${{ github.ref }}
|
||||||
|
release_name: Release ${{ steps.vars.outputs.version }}
|
||||||
|
draft: true
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
- name: Telegram Message Notify
|
||||||
|
uses: appleboy/telegram-action@0.0.7
|
||||||
|
with:
|
||||||
|
to: ${{ secrets.TELEGRAM_CHAT_ID }}
|
||||||
|
token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
|
||||||
|
message: 🚀 Published [${{ steps.vars.outputs.repo_name }}](https://github.com/${{ github.repository }}) version [${{ steps.vars.outputs.version }}](https://www.npmjs.com/package/${{ steps.vars.outputs.repo_name }}/v/${{ steps.vars.outputs.version }}) to npm
|
||||||
|
debug: true
|
||||||
|
format: markdown
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 PepperSec
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
53
README.md
53
README.md
@@ -1,6 +1,16 @@
|
|||||||
# Gas Price Oracle library for Ethereum dApps
|
# Gas Price Oracle library for Ethereum dApps [](https://www.npmjs.com/package/gas-price-oracle)
|
||||||
|
A library that has a collection of onchain and offchain gas price oracle URLs
|
||||||
|
|
||||||
## Instalation
|
Current offchain list:
|
||||||
|
- https://ethgasstation.info/json/ethgasAPI.json
|
||||||
|
- https://gas-oracle.zoltu.io/
|
||||||
|
- https://www.etherchain.org/api/gasPriceOracle
|
||||||
|
- https://gasprice.poa.network/
|
||||||
|
|
||||||
|
Current onchain list:
|
||||||
|
- [chainlink](https://etherscan.io/address/0xA417221ef64b1549575C977764E651c9FAB50141)
|
||||||
|
|
||||||
|
## Installation
|
||||||
`npm i gas-price-oracle`
|
`npm i gas-price-oracle`
|
||||||
|
|
||||||
## Import
|
## Import
|
||||||
@@ -9,11 +19,19 @@ const { GasPriceOracle } = require('gas-price-oracle');
|
|||||||
```
|
```
|
||||||
## Usage
|
## Usage
|
||||||
### Basic
|
### Basic
|
||||||
```js
|
|
||||||
const oracle = new GasPriceOracle();
|
|
||||||
|
|
||||||
oracle.gasPrices().then((gas) => {
|
```js
|
||||||
console.log(gas)
|
|
||||||
|
const options = {
|
||||||
|
defaultRpc: 'https://api.mycryptoapi.com/eth'
|
||||||
|
}
|
||||||
|
const oracle = new GasPriceOracle(options);
|
||||||
|
// optional fallbackGasPrices
|
||||||
|
const fallbackGasPrices = {
|
||||||
|
instant: 70, fast: 31, standard: 20, low: 7
|
||||||
|
}
|
||||||
|
oracle.gasPrices(fallbackGasPrices).then((gasPrices) => {
|
||||||
|
console.log(gasPrices) // { instant: 50, fast: 21, standard: 10, low: 3 }
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -21,28 +39,17 @@ oracle.gasPrices().then((gas) => {
|
|||||||
```js
|
```js
|
||||||
const oracle = new GasPriceOracle();
|
const oracle = new GasPriceOracle();
|
||||||
|
|
||||||
oracle.fetchGasPricesOffChain().then((gas) => {
|
oracle.fetchGasPricesOffChain().then((gasPrices) => {
|
||||||
console.log(gas)
|
console.log(gasPrices) // { instant: 50, fast: 21, standard: 10, low: 3 }
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### Custom RPC URL for onchain oracles
|
### Custom RPC URL for onchain oracles
|
||||||
```js
|
```js
|
||||||
const customRpc = 'https://mainnet.infura.io/v3/<API_KEY>'
|
const defaultRpc = 'https://mainnet.infura.io/v3/<API_KEY>'
|
||||||
const oracle = new GasPriceOracle(customRpc);
|
const oracle = new GasPriceOracle({ defaultRpc });
|
||||||
|
|
||||||
oracle.fetchGasPricesOnChain().then((gas) => {
|
oracle.fetchGasPricesOnChain().then((gasPrices) => {
|
||||||
console.log(gas)
|
console.log(gasPrices) // 21
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Don't throw an error if oracles are down
|
|
||||||
```js
|
|
||||||
oracle.fetchGasPricesOnChain(false).then((gas) => {
|
|
||||||
console.log(gas)
|
|
||||||
});
|
|
||||||
|
|
||||||
oracle.fetchGasPricesOffChain(false).then((gas) => {
|
|
||||||
console.log(gas)
|
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|||||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gas-price-oracle",
|
"name": "gas-price-oracle",
|
||||||
"version": "1.0.0",
|
"version": "0.1.1",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
14
package.json
14
package.json
@@ -1,8 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "gas-price-oracle",
|
"name": "gas-price-oracle",
|
||||||
"version": "0.1.1",
|
"version": "0.1.3",
|
||||||
"description": "Gas Price Oracle library for Ethereum dApps.",
|
"description": "Gas Price Oracle library for Ethereum dApps.",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
|
"homepage": "https://github.com/peppersec/gas-price-oracle",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/peppersec/gas-price-oracle.git"
|
||||||
|
},
|
||||||
"types": "lib/index.d.ts",
|
"types": "lib/index.d.ts",
|
||||||
"prepare": "npm run build",
|
"prepare": "npm run build",
|
||||||
"prepublishOnly": "npm test && npm run lint",
|
"prepublishOnly": "npm test && npm run lint",
|
||||||
@@ -12,7 +17,12 @@
|
|||||||
"lint": "tslint -p tsconfig.json"
|
"lint": "tslint -p tsconfig.json"
|
||||||
},
|
},
|
||||||
"author": "Alexey Pertsev <alexey@peppersec.com> (https://peppersec.com)",
|
"author": "Alexey Pertsev <alexey@peppersec.com> (https://peppersec.com)",
|
||||||
"keywords": ["Gas", "Gas price", "Ethereum", "Oracle"],
|
"keywords": [
|
||||||
|
"Gas",
|
||||||
|
"Gas price",
|
||||||
|
"Ethereum",
|
||||||
|
"Oracle"
|
||||||
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/chai": "^4.2.11",
|
"@types/chai": "^4.2.11",
|
||||||
|
|||||||
68
src/index.ts
68
src/index.ts
@@ -1,26 +1,21 @@
|
|||||||
import fetch from 'node-fetch';
|
import fetch from 'node-fetch';
|
||||||
import config from './config';
|
import config from './config';
|
||||||
import { GasPrice, OffChainOracle, OnChainOracle } from './types';
|
import { GasPrice, OffChainOracle, OnChainOracle, ConstructorArgs } from './types';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
|
|
||||||
export class GasPriceOracle {
|
export class GasPriceOracle {
|
||||||
lastGasPrice: GasPrice = {
|
lastGasPrice: GasPrice;
|
||||||
instant: 40,
|
|
||||||
fast: 21,
|
|
||||||
standard: 10,
|
|
||||||
low: 1
|
|
||||||
};
|
|
||||||
defaultRpc = 'https://api.mycryptoapi.com/eth';
|
defaultRpc = 'https://api.mycryptoapi.com/eth';
|
||||||
offChainOracles = { ...config.offChainOracles };
|
offChainOracles = { ...config.offChainOracles };
|
||||||
onChainOracles = { ...config.onChainOracles };
|
onChainOracles = { ...config.onChainOracles };
|
||||||
|
|
||||||
constructor(defaultRpc?: string) {
|
constructor(options: ConstructorArgs) {
|
||||||
if (defaultRpc) {
|
if (options && options.defaultRpc) {
|
||||||
this.defaultRpc = defaultRpc;
|
this.defaultRpc = options.defaultRpc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchGasPricesOffChain(throwIfFailsToFetch = true): Promise<GasPrice> {
|
async fetchGasPricesOffChain(): Promise<GasPrice> {
|
||||||
for (let oracle of Object.values(this.offChainOracles)) {
|
for (let oracle of Object.values(this.offChainOracles)) {
|
||||||
const { name, url, instantPropertyName, fastPropertyName, standardPropertyName, lowPropertyName, denominator } = oracle;
|
const { name, url, instantPropertyName, fastPropertyName, standardPropertyName, lowPropertyName, denominator } = oracle;
|
||||||
try {
|
try {
|
||||||
@@ -36,8 +31,7 @@ export class GasPriceOracle {
|
|||||||
standard: parseFloat(gas[standardPropertyName]) / denominator,
|
standard: parseFloat(gas[standardPropertyName]) / denominator,
|
||||||
low: parseFloat(gas[lowPropertyName]) / denominator
|
low: parseFloat(gas[lowPropertyName]) / denominator
|
||||||
};
|
};
|
||||||
this.lastGasPrice = gasPrices;
|
return gasPrices;
|
||||||
return this.lastGasPrice;
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Fetch gasPrice from ${name} oracle failed. Trying another one...`);
|
throw new Error(`Fetch gasPrice from ${name} oracle failed. Trying another one...`);
|
||||||
}
|
}
|
||||||
@@ -45,18 +39,16 @@ export class GasPriceOracle {
|
|||||||
console.error(e.message);
|
console.error(e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (throwIfFailsToFetch) {
|
|
||||||
throw new Error('All oracles are down. Probaly network error.');
|
throw new Error('All oracles are down. Probaly network error.');
|
||||||
}
|
}
|
||||||
return this.lastGasPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetchGasPricesOnChain(throwIfFailsToFetch = true): Promise<GasPrice> {
|
async fetchGasPricesOnChain(): Promise<number> {
|
||||||
for (let oracle of Object.values(this.onChainOracles)) {
|
for (let oracle of Object.values(this.onChainOracles)) {
|
||||||
const { name, callData, contract, denominator } = oracle;
|
const { name, callData, contract, denominator } = oracle;
|
||||||
let { rpc } = oracle;
|
let { rpc } = oracle;
|
||||||
rpc = rpc ? rpc : this.defaultRpc;
|
rpc = rpc ? rpc : this.defaultRpc;
|
||||||
const body = { jsonrpc: '2.0',
|
const body = {
|
||||||
|
jsonrpc: '2.0',
|
||||||
id: 1337,
|
id: 1337,
|
||||||
method: 'eth_call',
|
method: 'eth_call',
|
||||||
params: [{ 'data': callData, 'to': contract }, 'latest']
|
params: [{ 'data': callData, 'to': contract }, 'latest']
|
||||||
@@ -76,14 +68,7 @@ export class GasPriceOracle {
|
|||||||
throw new Error(`${name} oracle provides corrupted values`);
|
throw new Error(`${name} oracle provides corrupted values`);
|
||||||
}
|
}
|
||||||
fastGasPrice = fastGasPrice.div(denominator);
|
fastGasPrice = fastGasPrice.div(denominator);
|
||||||
const gasPrices: GasPrice = {
|
return fastGasPrice.toNumber();
|
||||||
instant: fastGasPrice.multipliedBy(1.3).toNumber(),
|
|
||||||
fast: fastGasPrice.toNumber(),
|
|
||||||
standard: fastGasPrice.multipliedBy(0.85).toNumber(),
|
|
||||||
low: fastGasPrice.multipliedBy(0.5).toNumber()
|
|
||||||
};
|
|
||||||
this.lastGasPrice = gasPrices;
|
|
||||||
return this.lastGasPrice;
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Fetch gasPrice from ${name} oracle failed. Trying another one...`);
|
throw new Error(`Fetch gasPrice from ${name} oracle failed. Trying another one...`);
|
||||||
}
|
}
|
||||||
@@ -91,29 +76,38 @@ export class GasPriceOracle {
|
|||||||
console.error(e.message);
|
console.error(e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (throwIfFailsToFetch) {
|
|
||||||
throw new Error('All oracles are down. Probaly network error.');
|
throw new Error('All oracles are down. Probaly network error.');
|
||||||
}
|
}
|
||||||
return this.lastGasPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
async gasPrices(): Promise<GasPrice> {
|
async gasPrices(fallbackGasPrices?: GasPrice): Promise<GasPrice> {
|
||||||
let gas = this.lastGasPrice;
|
const defaultFastGas = 22;
|
||||||
|
const defaultFallbackGasPrices = {
|
||||||
|
instant: defaultFastGas * 1.3,
|
||||||
|
fast: defaultFastGas,
|
||||||
|
standard: defaultFastGas * 0.85,
|
||||||
|
low: defaultFastGas * 0.5
|
||||||
|
};
|
||||||
|
this.lastGasPrice = this.lastGasPrice || fallbackGasPrices || defaultFallbackGasPrices;
|
||||||
try {
|
try {
|
||||||
gas = await this.fetchGasPricesOffChain();
|
this.lastGasPrice = await this.fetchGasPricesOffChain();
|
||||||
return gas;
|
return this.lastGasPrice;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('Failed to fetch gas prices from offchain oracles. Trying onchain ones...');
|
console.log('Failed to fetch gas prices from offchain oracles. Trying onchain ones...');
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
gas = await this.fetchGasPricesOnChain();
|
const fastGas = await this.fetchGasPricesOnChain();
|
||||||
return gas;
|
this.lastGasPrice = {
|
||||||
|
instant: fastGas * 1.3,
|
||||||
|
fast: fastGas,
|
||||||
|
standard: fastGas * 0.85,
|
||||||
|
low: fastGas * 0.5
|
||||||
|
};
|
||||||
|
return this.lastGasPrice;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('Failed to fetch gas prices from onchain oracles. Last known gas will be returned');
|
console.log('Failed to fetch gas prices from onchain oracles. Last known gas will be returned');
|
||||||
}
|
}
|
||||||
|
return this.lastGasPrice;
|
||||||
return gas;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addOffChainOracle(oracle: OffChainOracle) {
|
addOffChainOracle(oracle: OffChainOracle) {
|
||||||
|
|||||||
@@ -22,3 +22,7 @@ export type GasPrice = {
|
|||||||
standard: number;
|
standard: number;
|
||||||
low: number;
|
low: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export interface ConstructorArgs {
|
||||||
|
defaultRpc?: string;
|
||||||
|
}
|
||||||
|
|||||||
@@ -41,46 +41,26 @@ describe('fetchGasPricesOffChain', function () {
|
|||||||
await oracle.fetchGasPricesOffChain().should.be.rejectedWith('All oracles are down. Probaly network error.');
|
await oracle.fetchGasPricesOffChain().should.be.rejectedWith('All oracles are down. Probaly network error.');
|
||||||
mockery.disable();
|
mockery.disable();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not throw if throwIfFailsToFetch is false', async function () {
|
|
||||||
mockery.enable({ useCleanCache: true, warnOnUnregistered: false });
|
|
||||||
const { GasPriceOracle } = require('../src/index');
|
|
||||||
oracle = new GasPriceOracle();
|
|
||||||
await oracle.fetchGasPricesOffChain(false);
|
|
||||||
mockery.disable();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('fetchGasPricesOnChain', function () {
|
describe('fetchGasPricesOnChain', function () {
|
||||||
it('should work', async function () {
|
it('should work', async function () {
|
||||||
const gas: GasPrice = await oracle.fetchGasPricesOnChain();
|
const gas: number = await oracle.fetchGasPricesOnChain();
|
||||||
|
|
||||||
gas.instant.should.be.a('number');
|
gas.should.be.a('number');
|
||||||
gas.fast.should.be.a('number');
|
gas.should.not.be.equal(0);
|
||||||
gas.standard.should.be.a('number');
|
|
||||||
gas.low.should.be.a('number');
|
|
||||||
|
|
||||||
gas.instant.should.be.above(gas.fast);
|
|
||||||
gas.fast.should.be.above(gas.standard);
|
|
||||||
gas.standard.should.be.above(gas.low);
|
|
||||||
gas.low.should.not.be.equal(0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with custom rpc', async function () {
|
it('should work with custom rpc', async function () {
|
||||||
const rpc = 'https://ethereum-rpc.trustwalletapp.com';
|
const rpc = 'https://ethereum-rpc.trustwalletapp.com';
|
||||||
const oracle = new GasPriceOracle(rpc);
|
const oracle = new GasPriceOracle({ defaultRpc: rpc });
|
||||||
oracle.defaultRpc.should.be.equal(rpc);
|
oracle.defaultRpc.should.be.equal(rpc);
|
||||||
const gas: GasPrice = await oracle.fetchGasPricesOnChain();
|
const gas: number = await oracle.fetchGasPricesOnChain();
|
||||||
|
|
||||||
gas.instant.should.be.a('number');
|
gas.should.be.a('number');
|
||||||
gas.fast.should.be.a('number');
|
|
||||||
gas.standard.should.be.a('number');
|
|
||||||
gas.low.should.be.a('number');
|
|
||||||
|
|
||||||
gas.instant.should.be.above(gas.fast);
|
gas.should.be.above(1);
|
||||||
gas.fast.should.be.above(gas.standard);
|
gas.should.not.be.equal(0);
|
||||||
gas.standard.should.be.above(gas.low);
|
|
||||||
gas.low.should.not.be.equal(0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove oracle', async function () {
|
it('should remove oracle', async function () {
|
||||||
@@ -95,17 +75,10 @@ describe('fetchGasPricesOnChain', function () {
|
|||||||
oracle.removeOnChainOracle('chainlink');
|
oracle.removeOnChainOracle('chainlink');
|
||||||
await oracle.fetchGasPricesOnChain().should.be.rejectedWith('All oracles are down. Probaly network error.');
|
await oracle.fetchGasPricesOnChain().should.be.rejectedWith('All oracles are down. Probaly network error.');
|
||||||
oracle.addOnChainOracle(chainlink);
|
oracle.addOnChainOracle(chainlink);
|
||||||
const gas: GasPrice = await oracle.fetchGasPricesOnChain();
|
const gas: number = await oracle.fetchGasPricesOnChain();
|
||||||
|
|
||||||
gas.instant.should.be.a('number');
|
gas.should.be.a('number');
|
||||||
gas.fast.should.be.a('number');
|
gas.should.not.be.equal(0);
|
||||||
gas.standard.should.be.a('number');
|
|
||||||
gas.low.should.be.a('number');
|
|
||||||
|
|
||||||
gas.instant.should.be.above(gas.fast);
|
|
||||||
gas.fast.should.be.above(gas.standard);
|
|
||||||
gas.standard.should.be.above(gas.low);
|
|
||||||
gas.low.should.not.be.equal(0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if all onchain oracles are down', async function () {
|
it('should throw if all onchain oracles are down', async function () {
|
||||||
@@ -116,13 +89,6 @@ describe('fetchGasPricesOnChain', function () {
|
|||||||
mockery.disable();
|
mockery.disable();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not throw if throwIfFailsToFetch is false', async function () {
|
|
||||||
mockery.enable({ useCleanCache: true, warnOnUnregistered: false });
|
|
||||||
const { GasPriceOracle } = require('../src/index');
|
|
||||||
oracle = new GasPriceOracle();
|
|
||||||
await oracle.fetchGasPricesOnChain(false);
|
|
||||||
mockery.disable();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('gasPrice', function () {
|
describe('gasPrice', function () {
|
||||||
@@ -139,6 +105,31 @@ describe('gasPrice', function () {
|
|||||||
gas.standard.should.be.above(gas.low);
|
gas.standard.should.be.above(gas.low);
|
||||||
gas.low.should.not.be.equal(0);
|
gas.low.should.not.be.equal(0);
|
||||||
});
|
});
|
||||||
|
it('should fallback', async function () {
|
||||||
|
mockery.enable({ useCleanCache: true, warnOnUnregistered: false });
|
||||||
|
const { GasPriceOracle } = require('../src/index');
|
||||||
|
oracle = new GasPriceOracle();
|
||||||
|
const gas: GasPrice = await oracle.gasPrices();
|
||||||
|
|
||||||
|
gas.instant.should.be.equal(28.6);
|
||||||
|
gas.fast.should.be.equal(22);
|
||||||
|
gas.standard.should.be.equal(18.7);
|
||||||
|
gas.low.should.be.equal(11);
|
||||||
|
mockery.disable();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fallback to set values', async function () {
|
||||||
|
mockery.enable({ useCleanCache: true, warnOnUnregistered: false });
|
||||||
|
const { GasPriceOracle } = require('../src/index');
|
||||||
|
oracle = new GasPriceOracle();
|
||||||
|
const gas: GasPrice = await oracle.gasPrices({ instant: 50, fast: 21, standard: 10, low: 3 });
|
||||||
|
|
||||||
|
gas.instant.should.be.equal(50);
|
||||||
|
gas.fast.should.be.equal(21);
|
||||||
|
gas.standard.should.be.equal(10);
|
||||||
|
gas.low.should.be.equal(3);
|
||||||
|
mockery.disable();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
after('after', function () {
|
after('after', function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user