-
Notifications
You must be signed in to change notification settings - Fork 300
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
Migrating ethwrite adapter to monorepo #290
Merged
ebarakos
merged 17 commits into
develop
from
feature/176643310-ethwrite-monorepo-migration
Feb 22, 2021
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
04d6d27
added ethwrite JS project and its dependencies
ebarakos c5f6b69
converted to TS
ebarakos e8497c6
working with the new structure
ebarakos 55a7b3e
added hardhat and relevant test setup
ebarakos 5ad1608
default config + naming convention fix
ebarakos 2909dbf
changed README, added defaults and test
ebarakos 34045a3
review changes; need to check tests
ebarakos f694dfe
asserting true values written to contract in test
ebarakos 3906e51
small change in config
ebarakos be2b4f3
made dataType optional, altered tests, added helper file
ebarakos 41e9fe1
removed helper files
ebarakos 594f059
installed fresh dependencies
ebarakos 337a93f
README changes and required env vars
ebarakos 41bed79
moved private key to hardhat helpers
ebarakos 3654aa4
yarn install
ebarakos 66f17d3
json for hardhat exported var
ebarakos 5255bd4
cleaned comments
ebarakos File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -81,7 +81,8 @@ | |
"iex-cloud", | ||
"cfbenchmarks", | ||
"harmony", | ||
"tiingo" | ||
"tiingo", | ||
"ethwrite" | ||
] | ||
}, | ||
"2-step": { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ node_modules/ | |
*.zip | ||
dist | ||
.DS_Store | ||
cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports = { | ||
...require('../.eslintrc.ts.js'), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# Chainlink External Adapter for writing to Ethereum-based Blockchains | ||
|
||
This external adapter allows you to configure an endpoint and private key to sign and send transactions to external Ethereum-based blockchains. | ||
|
||
A typical workflow of a Chainlink job for this external adapter could look like: | ||
|
||
- Retrieve a piece of data from _some data source_ | ||
- Parse the desired field from that data source's response | ||
- Utilize this adapter to write the value to ChainB | ||
- Parse the transaction object from ChainB for the transaction hash | ||
- Write the transaction hash from ChainB to ChainA | ||
|
||
### Environment Variables | ||
|
||
| Required? | Name | Description | Options | Defaults to | | ||
| :-------: | :--------------: | :-----------------------------------------------------------------: | :-----: | :---------: | | ||
| ✅ | RPC_URL | RPC endpoint for that client. For example `http://localhost:8545` | | | | ||
| ✅ | PRIVATE_KEY | The private key of a funded account, to sign the transactions from. | | | | ||
| ✅ | CONTRACT_ADDRESS | The contract address that the contract is deployed to. | | | | ||
|
||
--- | ||
|
||
### Input Parameters | ||
|
||
| Required? | Name | Description | Options | Defaults to | | ||
| :-------: | :--------: | :-------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------: | :----------: | | ||
| ✅ | exAddr | The address for sending the transaction to. | | | | ||
| | funcId | The setter function to call: | [`0xc2b12a73`(for bytes32), `0xa53b1c1e`(for int256),`0xd2282dc5`(for uint256)] | `0xd2282dc5` | | ||
| | dataType | Pass this only in case you need to encode the data(normally should be already encoded). | [`bytes32`, `int256`, `uint256`] | | | ||
| | result | The result of the previous adapter | | | | ||
| | dataToSend | If specified, this value will be sent instead of `result`. | | | | ||
|
||
--- | ||
|
||
## Output Format | ||
|
||
```json | ||
{ | ||
"jobRunID": "1", | ||
"data": { | ||
"nonce": 1, | ||
"gasPrice": { "type": "BigNumber", "hex": "0x04a817c800" }, | ||
"gasLimit": { "type": "BigNumber", "hex": "0x53d8" }, | ||
"to": "0xBb5696deFD9005e0CfD8bf40ae4C1f9beB6c109d", | ||
"value": { "type": "BigNumber", "hex": "0x00" }, | ||
"data": "0xa53b1c1e0000000000000000000000000000000000000000000000000000000000000036", | ||
"chainId": 1337, | ||
"v": 2710, | ||
"r": "0x58389e578005462f7e8d0c980cd4fca9e16ab4141882f56f98deec0b572da0b3", | ||
"s": "0x17a977f57a88c3dbbab89beac60beb78ae8ab4dffd676831f84d14151c5b03d5", | ||
"from": "0x78C696E4cA526f17380DAc7b6C5fd54B17F3f637", | ||
"hash": "0x311b1e57342f61379bc597813c41bfa7c3535cfc2a49e61b2456c602dd07708e" | ||
}, | ||
"statusCode": 200 | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
{ | ||
"name": "@chainlink/ethwrite-adapter", | ||
"version": "0.0.2", | ||
"description": "Chainlink ethwrite adapter.", | ||
"keywords": [ | ||
"ethtx", | ||
"ethwrite" | ||
], | ||
"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 --delay --exit --timeout 0 -r ts-node/register 'test/**/*.test.ts'", | ||
"test:unit": "mocha --delay --exit --grep @integration --invert -r ts-node/register 'test/**/*.test.ts'", | ||
"test:integration": "mocha --delay --exit --timeout 0 --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": {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { Requester, Validator, AdapterError } from '@chainlink/external-adapter' | ||
import { ExecuteWithConfig, ExecuteFactory } from '@chainlink/types' | ||
import { makeConfig, DEFAULT_ENDPOINT, Config } from './config' | ||
import { txsend } from './endpoint' | ||
|
||
const inputParams = { | ||
endpoint: false, | ||
} | ||
|
||
export const execute: ExecuteWithConfig<Config> = async (request, config) => { | ||
const validator = new Validator(request, inputParams) | ||
if (validator.error) throw validator.error | ||
|
||
Requester.logConfig(config) | ||
|
||
const jobRunID = validator.validated.id | ||
const endpoint = validator.validated.data.endpoint || DEFAULT_ENDPOINT | ||
|
||
switch (endpoint) { | ||
case txsend.NAME: { | ||
return await txsend.execute(request, config) | ||
} | ||
default: { | ||
throw new AdapterError({ | ||
jobRunID, | ||
message: `Endpoint ${endpoint} not supported.`, | ||
statusCode: 400, | ||
}) | ||
} | ||
} | ||
} | ||
|
||
export const makeExecute: ExecuteFactory<Config> = (config) => { | ||
return async (request) => execute(request, config || makeConfig()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { util } from '@chainlink/ea-bootstrap' | ||
|
||
export type Config = { | ||
rpcUrl: string | ||
network?: string | ||
privateKey: string | ||
api: any | ||
} | ||
|
||
export const DEFAULT_ENDPOINT = 'txsend' | ||
|
||
export const makeConfig = (): Config => { | ||
return { | ||
api: {}, | ||
rpcUrl: util.getRequiredEnv('RPC_URL'), | ||
network: util.getEnv('NETWORK') || 'mainnet', | ||
privateKey: util.getRequiredEnv('PRIVATE_KEY'), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * as txsend from './txsend' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { Requester, Validator, AdapterError } from '@chainlink/external-adapter' | ||
import { ExecuteWithConfig } from '@chainlink/types' | ||
import { ethers } from 'ethers' | ||
import { Config } from '../config' | ||
|
||
export const NAME = 'txsend' | ||
|
||
const encode = (type: any, value: any) => { | ||
let retVal | ||
switch (type) { | ||
case 'bytes32': | ||
retVal = ethers.utils.formatBytes32String(value) | ||
break | ||
default: | ||
retVal = ethers.utils.defaultAbiCoder.encode([type], [value]) | ||
break | ||
} | ||
return retVal.slice(2) | ||
} | ||
|
||
const customParams = { | ||
exAddr: true, | ||
funcId: false, | ||
dataType: false, | ||
result: false, | ||
dataToSend: false, | ||
} | ||
|
||
export const execute: ExecuteWithConfig<Config> = async (request, config) => { | ||
const provider = new ethers.providers.JsonRpcProvider(config.rpcUrl) | ||
const wallet = new ethers.Wallet(config.privateKey, provider) | ||
|
||
const validator = new Validator(request, customParams) | ||
if (validator.error) throw validator.error | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Load the provider and the wallet here, with the values from config |
||
const getUint256 = '0xc2b12a73' | ||
|
||
const jobRunID = validator.validated.id | ||
const externalAddress = validator.validated.data.exAddr | ||
const functionId = validator.validated.data.funcId || getUint256 | ||
// Passing this optionally, in case the data is not encrypted from the previous step | ||
const dataType = validator.validated.data.dataType | ||
// Prioritize data coming from a previous adapter (result), | ||
// but allow dataToSend to be used if specified | ||
const dataToSend = validator.validated.data.result || validator.validated.data.dataToSend || '' | ||
// Ensure we use only 4 bytes for the functionId | ||
let transactionData | ||
if (dataType) { | ||
transactionData = functionId.substring(0, 10) + encode(dataType, dataToSend) | ||
} else { | ||
transactionData = functionId.substring(0, 10) + dataToSend | ||
} | ||
|
||
const transaction = { | ||
to: externalAddress, | ||
data: transactionData, | ||
} | ||
|
||
try { | ||
const tx = await wallet.sendTransaction(transaction) | ||
return Requester.success(jobRunID, { | ||
data: tx, | ||
status: 200, | ||
}) | ||
} catch (e) { | ||
throw new AdapterError({ | ||
jobRunID, | ||
message: e, | ||
statusCode: 400, | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { expose } from '@chainlink/ea-bootstrap' | ||
import { makeExecute } from './adapter' | ||
import { makeConfig } from './config' | ||
|
||
const NAME = 'ETHWRITE' | ||
|
||
export = { NAME, makeExecute, makeConfig, ...expose(makeExecute()) } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can remove
api
right?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I want to use
ExecuteWithConfig<C extends Config>
, I can't, since it is required in main Config type. And I don't feel like changing theadapter.ts
boilerplate, since IMHO should be removed at some point.I was thinking of changing this type to
ExecuteWithConfig<C>
but I am considering of checking this again separately, maybe as part of #293.I can also just use
execute = async (input: AdapterRequest, config: Config): Promise<AdapterResponse>
for the particular adapter as insynth-index
though. Thoughts?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, the tweak is made is some places is defining the makeExecute as
const makeExecute = (config?: Config): Execute => {...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's check changing it to either ExecuteWithConfig or removing the requirement of
api
param, in another PR, what do you think?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's leave it as it is. There's an issue open on
Config
inflexibility, we can leave it for another PRThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tagging #217