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

DNS query and record check adapters #199

Merged
merged 7 commits into from
Jan 5, 2021
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
8 changes: 7 additions & 1 deletion .github/strategy/adapters.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"cryptoid",
"cryptomkt",
"currencylayer",
"dns-query",
"dxfeed",
"eodhistoricaldata",
"etherchain",
Expand Down Expand Up @@ -99,7 +100,12 @@
"cmd": "make zip adapter=composite/__ADAPTER__ name=__ADAPTER__",
"asset_path": "./composite/__ADAPTER__/dist/__ADAPTER__-adapter.zip",
"asset_name": "__ADAPTER__-adapter.zip",
"adapter": ["proof-of-reserves", "market-closure", "defi-pulse"]
"adapter": [
"proof-of-reserves",
"market-closure",
"defi-pulse",
"dns-record-check"
]
},
"synth-index": {
"docker": "make docker-synth-index adapter=__ADAPTER__",
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- `finage` to get Financial data from finage.co.uk
- `coincodex` to get crypto prices from CoinCodex
- `coinranking` to get crypto prices from Coinranking
- `dns-query` to query DNS over HTTPS
- `dns-record-check` to check whether some record provided exists on DNS
- Added support for metadata in requests. This gives adapters access to the FM on-chain round state.
- Moves re-usable test behaviors & testing utils to a new package - `@chainlink/adapter-test-helpers`
- Added support for using query string parameters as input to adapters.
Expand Down
3 changes: 3 additions & 0 deletions composite/dns-record-check/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
...require('../../.eslintrc.ts.js'),
}
22 changes: 22 additions & 0 deletions composite/dns-record-check/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Chainlink External Adapter to Check DNS Records
krebernisak marked this conversation as resolved.
Show resolved Hide resolved

DNS Record Check lets query DNS over HTTPS (DoH) and check whether some record provided exists

## Input Params

- `record` (required): Record to check, eg: "adex-publisher"

This adapter relies on [`dns-query`](../../dns-query/README.md) adapter. Required `dns-query` input params and configuration apply to this adapter as well.

## Output

```json
{
"jobRunID": "1",
"data": {
"result": true
},
"result": true,
"statusCode": 200
}
```
47 changes: 47 additions & 0 deletions composite/dns-record-check/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "@chainlink/dns-record-check-adapter",
"version": "0.0.1",
"description": "Chainlink DNS record check adapter",
"keywords": [
"Chainlink",
"LINK",
"blockchain",
"oracle"
],
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"repository": {
"url": "https://github.com/smartcontractkit/external-adapters-js",
"type": "git"
},
"license": "MIT",
"scripts": {
"prepublishOnly": "yarn build && yarn test:unit",
"setup": "yarn build",
"build": "tsc -b",
"lint": "eslint --ignore-path ../../.eslintignore . --ext .js,.jsx,.ts,.tsx",
"lint:fix": "eslint --ignore-path ../../.eslintignore . --ext .js,.jsx,.ts,.tsx --fix",
"test": "mocha --exit --timeout 6000 -r ts-node/register 'test/**/*.test.ts'",
"test:unit": "mocha --exit --grep @integration --invert -r ts-node/register 'test/**/*.test.ts'",
"test:integration": "mocha --exit --timeout 6000 --grep @integration -r ts-node/register 'test/**/*.test.ts'",
"server": "node -e 'require(\"./index.js\").server()'",
"server:dist": "node -e 'require(\"./dist/index.js\").server()'",
"start": "yarn server:dist"
},
"devDependencies": {
"@types/chai": "^4.2.11",
"@types/express": "^4.17.6",
"@types/mocha": "^7.0.2",
"@types/node": "^14.0.13",
"@typescript-eslint/eslint-plugin": "^3.9.0",
"@typescript-eslint/parser": "^3.9.0",
"ts-node": "^8.10.2",
"typescript": "^3.9.7"
},
"dependencies": {
"@chainlink/dns-query-adapter": "^0.0.1"
}
}
33 changes: 33 additions & 0 deletions composite/dns-record-check/src/adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { ExecuteWithConfig, ExecuteFactory, Config } from '@chainlink/types'
import { Validator } from '@chainlink/external-adapter'
import { Requester } from '@chainlink/external-adapter'
import DNS from '@chainlink/dns-query-adapter'
import { DNSQueryResponse, DNSAnswer } from '@chainlink/dns-query-adapter/dist/types'
import { makeConfig } from './config'

const inputParams = {
record: true,
}

const execute: ExecuteWithConfig = async (input, config) => {
krebernisak marked this conversation as resolved.
Show resolved Hide resolved
const validator = new Validator(input, inputParams)
if (validator.error) throw validator.error

const jobRunID = validator.validated.id
const { record } = validator.validated.data

const dnsExecute = DNS.makeExecute(config)
const dnsResponse = await dnsExecute(input)
const dnsData: DNSQueryResponse = { ...dnsResponse.data }
const foundRecord = dnsData.Answer.find((ans: DNSAnswer) => ans.data.includes(record))

return Requester.success(jobRunID, {
status: 200,
data: {
result: !!foundRecord,
},
})
}

export const makeExecute: ExecuteFactory = (config?: Config) => (input) =>
execute(input, config || makeConfig())
6 changes: 6 additions & 0 deletions composite/dns-record-check/src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Config } from '@chainlink/types'
import DNS from '@chainlink/dns-query-adapter'

export const makeConfig = (): Config => {
krebernisak marked this conversation as resolved.
Show resolved Hide resolved
return DNS.makeConfig()
}
4 changes: 4 additions & 0 deletions composite/dns-record-check/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { expose, util } from '@chainlink/ea-bootstrap'
import { makeExecute } from './adapter'

export = { makeExecute, ...expose(util.wrapExecute(makeExecute())) }
Empty file.
22 changes: 22 additions & 0 deletions composite/dns-record-check/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"typeRoots": [
"../../node_modules/@types",
"../../typings",
"./typings"
],
"resolveJsonModule": true
},
"include": [
"src/**/*",
"src/**/*.json"
],
"exclude": [
"dist",
"**/*.spec.ts",
"**/*.test.ts"
]
}
3 changes: 3 additions & 0 deletions dns-query/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
...require('../.eslintrc.ts.js'),
}
59 changes: 59 additions & 0 deletions dns-query/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Chainlink External Adapter to query DNS

DNS Query lets query DNS over HTTPS (DoH)

## Configuration

The adapter takes the following environment variables:

- `DNS_PROVIDER`: DNS provider to use. Options available:
- `cloudfare`
- `google`
- `CUSTOM_ENDPOINT` (Optional): DNS provider URL. Overrides the option passed on `DNS_PROVIDER`


## Input Params

- `name`: Query Name, eg. "example.com"
- `type`: Query Type (either a numeric value or text), eg. "TXT"
- `do` (optional): DO bit - set if client wants DNSSEC data (either boolean or numeric value), eg. "true"
- `cd` (optional): CD bit - set to disable validation (either boolean or numeric value), eg. "false"

## Output

```json
{
"jobRunID": "1",
"data": {
"Status": 0,
"TC": false,
"RD": true,
"RA": true,
"AD": true,
"CD": false,
"Question": [
{
"name": "strem.io",
"type": 16
}
],
"Answer": [
{
"name": "strem.io",
"type": 16,
"TTL": 300,
"data": "\"adex-publisher=0xd5860D6196A4900bf46617cEf088ee6E6b61C9d6\""
},
{
"name": "strem.io",
"type": 16,
"TTL": 300,
"data": "\"google-site-verification=tYiWtmWtTz38gVx0Gav9fUbchyTbSnd2PKwlyC54ec0\""
}
],
"result": null
},
"result": null,
"statusCode": 200
}
```
45 changes: 45 additions & 0 deletions dns-query/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "@chainlink/dns-query-adapter",
"version": "0.0.1",
"description": "Chainlink DNS query adapter",
"keywords": [
"Chainlink",
"LINK",
"blockchain",
"oracle"
],
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"repository": {
"url": "https://github.com/smartcontractkit/external-adapters-js",
"type": "git"
},
"license": "MIT",
"scripts": {
"prepublishOnly": "yarn build && yarn test:unit",
"setup": "yarn build",
"build": "tsc -b",
"lint": "eslint --ignore-path ../.eslintignore . --ext .js,.jsx,.ts,.tsx",
"lint:fix": "eslint --ignore-path ../.eslintignore . --ext .js,.jsx,.ts,.tsx --fix",
"test": "mocha --exit --timeout 10000 -r ts-node/register 'test/**/*.test.ts'",
"test:unit": "mocha --exit --grep @integration --invert -r ts-node/register 'test/**/*.test.ts'",
"test:integration": "mocha --exit --timeout 3000 --grep @integration -r ts-node/register 'test/**/*.test.ts'",
"server": "node -e 'require(\"./index.js\").server()'",
"server:dist": "node -e 'require(\"./dist/index.js\").server()'",
"start": "yarn server:dist"
},
"devDependencies": {
"@types/chai": "^4.2.11",
"@types/express": "^4.17.6",
"@types/mocha": "^7.0.2",
"@types/node": "^14.0.13",
"@typescript-eslint/eslint-plugin": "^3.9.0",
"@typescript-eslint/parser": "^3.9.0",
"ts-node": "^8.10.2",
"typescript": "^3.9.7"
},
"dependencies": {}
}
45 changes: 45 additions & 0 deletions dns-query/src/adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Config, ExecuteFactory, ExecuteWithConfig } from '@chainlink/types'
import { Requester, Validator } from '@chainlink/external-adapter'
import { makeConfig } from './config'
import { DNSQueryResponse } from './types'

export const inputParams = {
name: true,
type: true,
do: false,
cd: false,
}

const execute: ExecuteWithConfig = async (input, config) => {
const validator = new Validator(input, inputParams)
if (validator.error) throw validator.error

const jobRunID = validator.validated.id
const { name, type, do: doBit, cd: cdBit } = validator.validated.data

const params = {
name,
type,
...(doBit && { do: doBit }),
...(cdBit && { cd: cdBit }),
}
const headers = {
Accept: 'application/dns-json',
}

const result = await Requester.request({
url: config.api.url,
headers,
params,
})

const data: DNSQueryResponse = { ...result.data }

return Requester.success(jobRunID, {
status: 200,
data: data,
})
}
krebernisak marked this conversation as resolved.
Show resolved Hide resolved

export const makeExecute: ExecuteFactory = (config?: Config) => (input) =>
execute(input, config || makeConfig())
25 changes: 25 additions & 0 deletions dns-query/src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { util } from '@chainlink/ea-bootstrap'
import { Config } from '@chainlink/types'

export enum DNSProviders {
Cloudfare = 'cloudfare',
Google = 'google',
}

export const endpoints: Record<string, string> = {
[DNSProviders.Cloudfare]: 'https://cloudflare-dns.com/dns-query',
[DNSProviders.Google]: 'https://dns.google/resolve',
}

export const makeConfig = (): Config => {
const customEndpoint = util.getEnv('CUSTOM_ENDPOINT')
if (customEndpoint) {
return { api: { url: customEndpoint } }
}
const provider = util.getRequiredEnv('DNS_PROVIDER')
if (!Object.values(DNSProviders).includes(provider))
throw new Error(`Unknown DNS Provider: ${provider}`)

const config: Config = { api: { url: endpoints[provider] } }
return config
}
7 changes: 7 additions & 0 deletions dns-query/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { expose, util } from '@chainlink/ea-bootstrap'
import { makeExecute } from './adapter'
import { makeConfig } from './config'

const NAME = 'DNS-Query'

export = { NAME, makeConfig, makeExecute, ...expose(util.wrapExecute(makeExecute())) }
23 changes: 23 additions & 0 deletions dns-query/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export type DNSQuestion = {
name: string
type: number
}

export type DNSAnswer = {
name: string
type: number
TTL: number
data: string
}

export type DNSQueryResponse = {
Status: number
TC: boolean
RD: boolean
RA: boolean
AD: boolean
CD: boolean
Question: DNSQuestion[]
Answer: DNSAnswer[]
Comment?: string
}
Empty file added dns-query/test/adapter.test.ts
Empty file.
Loading