Documentation ¶
Overview ¶
Package adapters contain the core adapters used by the Seerlink node.
Bridge ¶
The Bridge adapter is used to send and receive data to and from external adapters. The adapter will POST to the target adapter URL with an "id" field for the TaskRunID and a "data" field. For example:
{"id": "b8004e2989e24e1d8e4449afad2eb480", "data": {}}
Compare ¶
The Compare adapter is used to compare the previous task's result against a specified value. Just like an `if` statement, the compare adapter will save `true` or `false` in the task run's result.
{ "type": "Compare", "params": {"operator": "eq", "value": "Hello" }}
HTTPGet ¶
The HTTPGet adapter is used to grab the JSON data from the given URL.
{ "type": "HTTPGet", "params": {"get": "https://some-api-example.net/api" }}
NOTE: For security, since the URL is untrusted, HTTPGet imposes some restrictions on which IPs may be fetched. Local network and multicast IPs are disallowed by default and attempting to connect will result in an error.
HTTPPost ¶
Sends a POST request to the specified URL and will return the response.
{ "type": "HTTPPost", "params": {"post": "https://weiwatchers.com/api" }}
NOTE: For security, since the URL is untrusted, HTTPPost imposes some restrictions on which IPs may be fetched. Local network and multicast IPs are disallowed by default and attempting to connect will result in an error.
HTTPGetWithUnrestrictedNetworkAccess ¶
Identical to HTTPGet except there are no IP restrictions. Use with caution.
HTTPPostWithUnrestrictedNetworkAccess ¶
Identical to HTTPPost except there are no IP restrictions. Use with caution.
JSONParse ¶
The JSONParse adapter will obtain the value(s) for the given field(s).
{ "type": "JSONParse", "params": {"path": ["someField"] }}
EthBool ¶
The EthBool adapter will take the given values and format them for the Ethereum blockchain in boolean value.
{ "type": "EthBool" }
EthBytes32 ¶
The EthBytes32 adapter will take the given values and format them for the Ethereum blockchain.
{ "type": "EthBytes32" }
EthInt256 ¶
The EthInt256 adapter will take a given signed 256 bit integer and format it to hex for the Ethereum blockchain.
{ "type": "EthInt256" }
EthUint256 ¶
The EthUint256 adapter will take a given 256 bit integer and format it in hex for the Ethereum blockchain.
{ "type": "EthUint256" }
EthTx ¶
The EthTx adapter will write the data to the given address and functionSelector.
{ "type": "EthTx", "params": { "address": "0x0000000000000000000000000000000000000000", "functionSelector": "0xffffffff" } }
Multiplier ¶
The Multiplier adapter multiplies the given input value times another specified value.
{ "type": "Multiply", "params": {"times": 100 }}
Quotient ¶
The Quotient adapter gives the result of x / y where x is a specified value (dividend) and y is the input value (result). This can be useful for inverting outputs, e.g. if you have a USD/ETH conversion rate and you want to flip it to ETH/USD you can use this adapter with a dividend of 1 to get 1 / result.
value.
{ "type": "Quotient", "params": {"dividend": 1 }}
Random ¶
Random adapter generates proofs of randomness verifiable against a public key
WARNING: The Random apdater's output is NOT the randomness you are looking WARNING: for! The node must send the output onchain for verification by the WARNING: method VRFCoordinator.sol#fulfillRandomnessRequest, which will WARNING: pass the actual random output back to the consuming contract. WARNING: Don't use the output of this adapter in any other way, unless you WARNING: thoroughly understand the cryptography in use here, and the exact WARNING: security guarantees it provides. See notes in VRFCoordinator.sol WARNING: for more info. WARNING: This system guarantees that the oracle cannot independently WARNING: concoct a random output to suit itself, but it does not protect WARNING: against collusion between the oracle and the provider of the seed WARNING: the oracle uses to generate the randomness. It also does not WARNING: protect against the oracle simply refusing to respond to a WARNING: randomness request, if it doesn't like the output it would be WARNING: required to provide. Solutions to these limitations are planned.
Here is an example of a Random task specification. For an example of a full jobspec using this, see ../internal/testdata/randomness_job.json.
{ "type": "Random", "params": { "publicKey": "0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800" } }
The publicKey must be the concatenation of its hex representation of its the secp256k1 point's x-ordinate as a uint256, followed by 00 if the y-ordinate is even, or 01 if it's odd. (Note that this is NOT an RFC 5480 section 2.2 public-key representation. DO NOT prefix with 0x02, 0x03 or 0x04.)
The seerlink node must know the corresponding secret key. Such a key pair can be created with the `seerlink local vrf create` command, and exported to a keystore with `vrf export <keystore-path>`.
E.g. `seerlink local vrf create -p <password-file>` will log the public key under the field "public id".
To see the public keys which have already been imported, use the command `seerlink local vrf list`. See `seerlink local vrf help` for more key-manipulation commands.
The adapter output should be passed via EthTx to VRFCoordinator.sol's method fulfillRandomnessRequest.
A "random" task must be initiated by a "randomnesslog" initiator which explicitly specifies which ethereum address the logs will be emitted from, such as
{"initiators": [{"type": "randomnesslog","address": "0xvrfCoordinatorAddr"}]}
This prevents the node from responding to potentially hostile log requests from other contracts, which could be crafted to prematurely reveal the random output if someone learns a prospective input seed prior to its use in the VRF.
Index ¶
- Constants
- Variables
- type BaseAdapter
- type Bridge
- type Compare
- type Copy
- type EthBool
- type EthBytes32
- type EthInt256
- type EthTx
- type EthUint256
- type ExtendedPath
- type HTTPGet
- type HTTPPost
- type JSONParse
- type JSONPath
- type Multiply
- type NoOp
- type NoOpPendOutgoing
- type PipelineAdapter
- type QueryParameters
- type Quotient
- type Random
- type ResultCollect
- type Sleep
Constants ¶
const ( // DataFormatBytes instructs the EthTx Adapter to treat the input value as a // bytes string, rather than a hexadecimal encoded bytes32 DataFormatBytes = "bytes" )
Variables ¶
var ( // TaskTypeCopy is the identifier for the Copy adapter. TaskTypeCopy = models.MustNewTaskType("copy") // TaskTypeEthBool is the identifier for the EthBool adapter. TaskTypeEthBool = models.MustNewTaskType("ethbool") // TaskTypeEthBytes32 is the identifier for the EthBytes32 adapter. TaskTypeEthBytes32 = models.MustNewTaskType("ethbytes32") // TaskTypeEthInt256 is the identifier for the EthInt256 adapter. TaskTypeEthInt256 = models.MustNewTaskType("ethint256") // TaskTypeEthUint256 is the identifier for the EthUint256 adapter. TaskTypeEthUint256 = models.MustNewTaskType("ethuint256") // TaskTypeEthTx is the identifier for the EthTx adapter. TaskTypeEthTx = models.MustNewTaskType("ethtx") // TaskTypeHTTPGetWithUnrestrictedNetworkAccess is the identifier for the HTTPGet adapter, with local/private IP access enabled. TaskTypeHTTPGetWithUnrestrictedNetworkAccess = models.MustNewTaskType("httpgetwithunrestrictednetworkaccess") // TaskTypeHTTPPostWithUnrestrictedNetworkAccess is the identifier for the HTTPPost adapter, with local/private IP access enabled. TaskTypeHTTPPostWithUnrestrictedNetworkAccess = models.MustNewTaskType("httppostwithunrestrictednetworkaccess") // TaskTypeHTTPGet is the identifier for the HTTPGet adapter. TaskTypeHTTPGet = models.MustNewTaskType("httpget") // TaskTypeHTTPPost is the identifier for the HTTPPost adapter. TaskTypeHTTPPost = models.MustNewTaskType("httppost") // TaskTypeJSONParse is the identifier for the JSONParse adapter. TaskTypeJSONParse = models.MustNewTaskType("jsonparse") // TaskTypeMultiply is the identifier for the Multiply adapter. TaskTypeMultiply = models.MustNewTaskType("multiply") // TaskTypeNoOp is the identifier for the NoOp adapter. TaskTypeNoOp = models.MustNewTaskType("noop") // TaskTypeNoOpPendOutgoing is the identifier for the NoOpPendOutgoing adapter. TaskTypeNoOpPendOutgoing = models.MustNewTaskType("nooppendoutgoing") // TaskTypeSleep is the identifier for the Sleep adapter. TaskTypeSleep = models.MustNewTaskType("sleep") // TaskTypeRandom is the identifier for the Random adapter. TaskTypeRandom = models.MustNewTaskType("random") // TaskTypeCompare is the identifier for the Compare adapter. TaskTypeCompare = models.MustNewTaskType("compare") // TaskTypeQuotient is the identifier for the Quotient adapter. TaskTypeQuotient = models.MustNewTaskType("quotient") // TaskTypeResultCollect is the identifier for the ResultCollect adapter. TaskTypeResultCollect = models.MustNewTaskType("resultcollect") )
var ( ErrResultNotNumber = errors.New("the result was not a number") ErrValueNotNumber = errors.New("the value was not a number") ErrOperatorNotSpecified = errors.New("operator not specified") ErrValueNotSpecified = errors.New("value not specified") )
var (
ErrInvalidABIEncoding = errors.New("invalid abi encoding")
)
Functions ¶
This section is empty.
Types ¶
type BaseAdapter ¶
type BaseAdapter interface { TaskType() models.TaskType Perform(models.RunInput, *store.Store) models.RunOutput }
BaseAdapter is the minimum interface required to create an adapter. Only core adapters have this minimum requirement.
func FindNativeAdapterFor ¶
func FindNativeAdapterFor(task models.TaskSpec) BaseAdapter
FindNativeAdapterFor find the native adapter for a given task
type Bridge ¶
type Bridge struct { models.BridgeType Params models.JSON }
Bridge adapter is responsible for connecting the task pipeline to external adapters, allowing for custom computations to be executed and included in runs.
func (*Bridge) Perform ¶
Perform sends a POST request containing the JSON of the input to the external adapter specified in the BridgeType.
It records the RunResult returned to it, and optionally marks the RunResult pending.
If the Perform is resumed with a pending RunResult, the RunResult is marked not pending and the RunResult is returned.
type Compare ¶
Compare adapter type takes an Operator and a Value field to compare to the previous task's Result.
type Copy ¶
type Copy struct {
CopyPath JSONPath `json:"copyPath"`
}
Copy obj keys refers to which value to copy inside `data`, each obj value refers to where to copy the value to inside `data`
type EthBool ¶
type EthBool struct{}
EthBool holds no fields
type EthBytes32 ¶
type EthBytes32 struct{}
EthBytes32 holds no fields.
func (*EthBytes32) Perform ¶
Perform returns the hex value of the first 32 bytes of a string so that it is in the proper format to be written to the blockchain.
For example, after converting the string "16800.01" to hex encoded Ethereum ABI, it would be: "0x31363830302e3031000000000000000000000000000000000000000000000000"
func (*EthBytes32) TaskType ¶
func (e *EthBytes32) TaskType() models.TaskType
TaskType returns the type of Adapter.
type EthInt256 ¶
type EthInt256 struct{}
EthInt256 holds no fields
func (*EthInt256) Perform ¶
Perform returns the hex value of a given string so that it is in the proper format to be written to the blockchain.
For example, after converting the string "-123.99" to hex encoded Ethereum ABI, it would be: "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff85"
type EthTx ¶
type EthTx struct { ToAddress common.Address `json:"address"` // NOTE: FromAddress is deprecated and kept for backwards compatibility, new job specs should use fromAddresses FromAddress common.Address `json:"fromAddress,omitempty"` FromAddresses []common.Address `json:"fromAddresses,omitempty"` FunctionSelector models.FunctionSelector `json:"functionSelector"` // DataPrefix is typically a standard first argument // to seerlink callback calls - usually the requestID DataPrefix hexutil.Bytes `json:"dataPrefix"` DataFormat string `json:"format"` GasLimit uint64 `json:"gasLimit,omitempty"` // Optional list of desired encodings for ResultCollectKey arguments. // i.e. ["uint256", "bytes32"] ABIEncoding []string `json:"abiEncoding"` // MinRequiredOutgoingConfirmations only works with bulletprooftxmanager MinRequiredOutgoingConfirmations uint64 `json:"minRequiredOutgoingConfirmations,omitempty"` }
EthTx holds the Address to send the result to and the FunctionSelector to execute.
type EthUint256 ¶
type EthUint256 struct{}
EthUint256 holds no fields.
func (*EthUint256) Perform ¶
Perform returns the hex value of a given string so that it is in the proper format to be written to the blockchain.
For example, after converting the string "123.99" to hex encoded Ethereum ABI, it would be: "0x000000000000000000000000000000000000000000000000000000000000007b"
func (*EthUint256) TaskType ¶
func (e *EthUint256) TaskType() models.TaskType
TaskType returns the type of Adapter.
type ExtendedPath ¶
type ExtendedPath []string
ExtendedPath is the path to append to a base URL
func (*ExtendedPath) UnmarshalJSON ¶
func (ep *ExtendedPath) UnmarshalJSON(input []byte) error
UnmarshalJSON implements the Unmarshaler interface
type HTTPGet ¶
type HTTPGet struct { URL models.WebURL `json:"url"` GET models.WebURL `json:"get"` Headers http.Header `json:"headers"` QueryParams QueryParameters `json:"queryParams"` ExtendedPath ExtendedPath `json:"extPath"` AllowUnrestrictedNetworkAccess bool `json:"-"` }
HTTPGet requires a URL which is used for a GET request when the adapter is called.
func (*HTTPGet) GetRequest ¶
GetRequest returns the HTTP request including query parameters and headers
type HTTPPost ¶
type HTTPPost struct { URL models.WebURL `json:"url"` POST models.WebURL `json:"post"` Headers http.Header `json:"headers"` QueryParams QueryParameters `json:"queryParams"` Body *string `json:"body,omitempty"` ExtendedPath ExtendedPath `json:"extPath"` AllowUnrestrictedNetworkAccess bool `json:"-"` }
HTTPPost requires a URL which is used for a POST request when the adapter is called.
func (*HTTPPost) GetRequest ¶
GetRequest takes the request body and returns the HTTP request including query parameters and headers.
HTTPPost's Body parameter overrides the given argument if present.
type JSONParse ¶
type JSONParse struct {
Path JSONPath `json:"path"`
}
JSONParse holds a path to the desired field in a JSON object, made up of an array of strings.
type JSONPath ¶
type JSONPath []string
JSONPath is a path to a value in a JSON object
func (*JSONPath) UnmarshalJSON ¶
UnmarshalJSON implements the Unmarshaler interface
type Multiply ¶
Multiply holds the a number to multiply the given value by.
type NoOp ¶
type NoOp struct{}
NoOp adapter type holds no fields
type NoOpPendOutgoing ¶
type NoOpPendOutgoing struct{}
NoOpPendOutgoing adapter type holds no fields
func (*NoOpPendOutgoing) Perform ¶
Perform on this adapter type returns an empty RunResult with an added field for the status to indicate the task is Pending.
func (*NoOpPendOutgoing) TaskType ¶
func (noa *NoOpPendOutgoing) TaskType() models.TaskType
TaskType returns the type of Adapter.
type PipelineAdapter ¶
type PipelineAdapter struct { BaseAdapter // contains filtered or unexported fields }
PipelineAdapter wraps a BaseAdapter with requirements for execution in the pipeline.
func For ¶
func For(task models.TaskSpec, config orm.ConfigReader, orm *orm.ORM) (*PipelineAdapter, error)
For determines the adapter type to use for a given task.
func (PipelineAdapter) MinConfs ¶
func (p PipelineAdapter) MinConfs() uint32
MinConfs returns the private attribute
func (PipelineAdapter) MinPayment ¶
func (p PipelineAdapter) MinPayment() *assets.Link
MinPayment returns the payment for this adapter (defaults to none)
type QueryParameters ¶
QueryParameters are the keys and values to append to the URL
func (*QueryParameters) UnmarshalJSON ¶
func (qp *QueryParameters) UnmarshalJSON(input []byte) error
UnmarshalJSON implements the Unmarshaler interface
type Quotient ¶
Quotient holds the Dividend.
func (Quotient) MarshalJSON ¶
MarshalJSON implements the json.Marshal interface.
func (*Quotient) Perform ¶
Perform returns result of dividend / divisor were divisor is the input's "result" field.
For example, if input value is "2.5", and the adapter's "dividend" value is "1", the result's value will be "0.4".
func (*Quotient) UnmarshalJSON ¶
UnmarshalJSON implements the json.Unqrshal interface.
type Random ¶
type Random struct { // Compressed hex representation public key used in Random's VRF proofs // // This is just a hex string because Random is instantiated by json.Unmarshal. // (See adapters.For function.) PublicKey string `json:"publicKey"` }
Random adapter type implements VRF calculation in its Perform method.
The VRFCoordinator.sol contract and its integration with the seerlink node will handle interaction with the Random adapter, but if you need to interact with it directly, its input to should be a JSON object with "preSeed", "blockHash", "blockNum", and "keyHash" fields containing, respectively,
- The input seed as a hex-represented uint256 (this is the preSeed generated by VRFCoordinator#requestRandomness)
- The hex-represented hash of the block in which request appeared
- The number of the block in which the request appeared, as a JSON number
- The keccak256 hash of the UNCOMPRESSED REPRESENTATION(*) of the public key
E.g., given the input
{ "preSeed": "0x0000000000000000000000000000000000000000000000000000000000000001", "blockHash": "0x31dcb7c2e3f80ce552bf730d5c1a7ed7f9b42c17aff254729b5be081394617e6", "blockNum": 10000000, "keyHash": "0xc0a6c424ac7157ae408398df7e5f4552091a69125d5dfcb7b8c2659029395bdf", }
The adapter will return a proof for the VRF output given these values, as long as the keccak256 hash of its public key matches the hash in the input. Otherwise, it will error.
The seed which is actually passed to the VRF cryptographic module is controlled by vrf.FinalSeed, and is computed from the above inputs.
The adapter returns the hex representation of a solidity bytes array suitable for passing to VRFCoordinator#fulfillRandomnessRequest, a vrf.MarshaledOnChainResponse.
(*) I.e., the 64-byte concatenation of the point's x- and y- ordinates as uint256's
type ResultCollect ¶
type ResultCollect struct{}
func (ResultCollect) TaskType ¶
func (r ResultCollect) TaskType() models.TaskType