@@ -39,6 +25,7 @@ Because these resources are public facing, you should review security and best p
## IAM Roles
The Quick Start creates the following IAM roles:
+
- **Administration Role:** Grants the provided administrator ID with administrator access
- **Execution Role:** Grants cloudformation.amazonaws.com the administration role to extend the functionality of stacks by enabling create, update, or delete stacks across multiple accounts and regions with a single operation
- **Chainlink Node Role:**
@@ -49,6 +36,7 @@ The Quick Start creates the following IAM roles:
## Billable Services
The Quick Start has the following billable services. Click on each link to learn about the pricing model for each service:
+
- [**Amazon EC2**](https://aws.amazon.com/ec2/pricing/?nc2=type_a)
- [**Amazon Virtual Private Cloud (VPC)**](https://aws.amazon.com/vpc/pricing/)
- [**Amazon Aurora PostgreSQL-Compatible DB**](https://aws.amazon.com/rds/aurora/pricing/)
@@ -56,8 +44,8 @@ The Quick Start has the following billable services. Click on each link to learn
- [**AWS Secrets Manager**](https://aws.amazon.com/secrets-manager/pricing/?nc1=h_ls)
- [**AWS Key Management Service**](https://aws.amazon.com/kms/pricing/?nc2=type_a)
- [**Amazon CloudWatch**](https://aws.amazon.com/cloudwatch/pricing/?nc2=type_a)
-- (*Optional* if you are not using a public certificate with AWS Certificate Manager) [**Application Load Balancer**](https://aws.amazon.com/elasticloadbalancing/pricing/?nc=sn&loc=3)
-- (*Optional*) [**Amazon Devops Guru**](https://aws.amazon.com/devops-guru/pricing/?nc=sn&loc=3&refid=0c5ce5de-7dc6-4ce5-95c9-29c9047095fc~ha_awssm-10495_event_prospect)
+- (_Optional_ if you are not using a public certificate with AWS Certificate Manager) [**Application Load Balancer**](https://aws.amazon.com/elasticloadbalancing/pricing/?nc=sn&loc=3)
+- (_Optional_) [**Amazon Devops Guru**](https://aws.amazon.com/devops-guru/pricing/?nc=sn&loc=3&refid=0c5ce5de-7dc6-4ce5-95c9-29c9047095fc~ha_awssm-10495_event_prospect)
You are responsible for the cost of the AWS services and any third-party licenses that you use while running this Quick Start. There is no additional cost for using the Quick Start.
@@ -65,18 +53,20 @@ AWS maintains service limits for each account to help guarantee the availability
For more information, visit [Manage Service Limits](https://aws.amazon.com/premiumsupport/knowledge-center/manage-service-limits/).
-
## Best Practices
### Do not run as the root user
+
The operations on the Chainlink node do not require the root user so it is recommended to use the default user or run as a non-root user.
### Protect your AWS account
+
As a best security practice, [rotate programmatic system credentials](https://aws.amazon.com/blogs/security/how-to-rotate-access-keys-for-iam-users/) and [cryptographic keys](https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html).
If you enable Amazon Devops Guru, the Quick Start deploys an AWS managed customer key (CMK) that is used for the Amazon SNS topic for DevOps Guru. The default setting is automatically set to rotate this KMS key every year.
### Monitor your Chainlink node's health
+
Run regular health checks of your Chainlink node.
We recommend using a monitoring solution to track the health of your Chainlink node, such as [Prometheus](https://prometheus.io/docs/prometheus/latest/getting_started/) or [Grafana](https://grafana.com/docs/grafana/latest/getting-started/getting-started-prometheus/). Chainlink exposes metrics on the `/metrics` endpoint of the UI. By default, that's http://localhost:6688/metrics.
@@ -98,6 +88,7 @@ Alternatively, you can run a health check on your node using `curl` and make sur
curl -XGET localhost:6688/health | jq '.'
```
+
```json
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
@@ -140,7 +131,6 @@ curl -XGET localhost:6688/health | jq '.'
To check the status of your Chainlink node container, use the `docker ps` command.
-
## Recovering or Upgrading your Chainlink Node Container
Tag versions for Chainlink node releases are available in the [Chainlink docker hub](https://hub.docker.com/r/smartcontract/chainlink/tags)
@@ -199,7 +189,7 @@ cd /home/ec2-user/.chainlink && docker run -d \
-a /chainlink/.api
```
-You can find more details with maintenance and examples in the [Performing System Maintenance](https://docs.chain.link/docs/performing-system-maintenance/) guide.
+You can find more details with maintenance and examples in the [Performing System Maintenance](/chainlink-nodes/performing-system-maintenance/) guide.
Additionally, follow the directions in the [User Guide for Linux Instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/install-updates.html) to keep your Amazon Linux instance software up to date.
@@ -243,10 +233,10 @@ Management of AWS service limits are not required for proper disaster recovery.
In the AWS console, if the **SSL certificate with AWS Certificate Manager** is set to `false`, you can leave **arn:aws:acm:region:account-id:certificate** as is. However, if your node is external facing and must be reached by the internet, enable this feature and set it to `true`.
-
+
### Amazon Devops Guru
In the AWS console, if the **Amazon DevOps Guru** is set to `false`, you can leave **AdministerAccountId** and **EmailAddress** as is.
-
+
diff --git a/docs/chainlink-nodes/best-security-practices.md b/src/pages/chainlink-nodes/best-security-practices.md
similarity index 78%
rename from docs/chainlink-nodes/best-security-practices.md
rename to src/pages/chainlink-nodes/best-security-practices.md
index c5e9dc1affc..b4590d7e400 100644
--- a/docs/chainlink-nodes/best-security-practices.md
+++ b/src/pages/chainlink-nodes/best-security-practices.md
@@ -1,10 +1,11 @@
---
-layout: nodes.liquid
+layout: ../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Security and Operation Best Practices"
permalink: "docs/best-security-practices/"
---
+
The following information provides a set of security and operation best practices that node operators need to use at a minimum to enhance the security and reliability of their infrastructure.
## Restricting Access
@@ -34,8 +35,8 @@ To ensure there is very minimal downtime, failover capabilities are required on
**Ethereum-specific:**
- Ethereum client websocket connectivity is fronted by a load balancer, used by the Chainlink nodes. [Here is an example on how to set up a load balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/tutorial-target-ecs-containers.html).
- - If a VPN and internal routing is configured, SSL is not needed but still recommended, as all traffic is purely internal.
- - If both Ethereum and Chainlink nodes are public facing without a VPN, SSL is required to ensure that no communication between both can be intercepted.
+ - If a VPN and internal routing is configured, SSL is not needed but still recommended, as all traffic is purely internal.
+ - If both Ethereum and Chainlink nodes are public facing without a VPN, SSL is required to ensure that no communication between both can be intercepted.
## Disaster Recovery
@@ -59,29 +60,29 @@ To be proactive in detecting any issues before or when they occur, active monito
- Ethereum client disk, RAM and CPU usage.
Monitoring can be set up from the Docker container's output and fed into most major logging providers. For example, you can use Docker's docs to set up the logging driver for [Amazon CloudWatch](https://docs.docker.com/config/containers/logging/awslogs/) and [Google Cloud Logging](https://docs.docker.com/config/containers/logging/gcplogs/). You will want to set the [
-JSON_CONSOLE](../configuration-variables/#json_console) configuration variable to `true` so that the output of the container is JSON-formatted for logging.
+JSON_CONSOLE](/chainlink-nodes/configuration-variables/#json_console) configuration variable to `true` so that the output of the container is JSON-formatted for logging.
## Frequent Updates
Due to the early nature of the software, it may be required to perform frequent updates to your Chainlink node.
-On performing system maintenance to update the Chainlink node, follow [this](/docs/performing-system-maintenance/#failover-node-example) guide.
+On performing system maintenance to update the Chainlink node, follow [this](/chainlink-nodes/performing-system-maintenance/#failover-node-example) guide.
## Jobs and Config
The following are suggestions for job specifications and configuration settings for the node.
-[Job Specifications](../jobs/):
+[Job Specifications](/chainlink-nodes/oracle-jobs/jobs/):
-- Include the address of your oracle contract address for all RunLog initiated jobs, as shown in the [Fulfilling Requests](../fulfilling-requests/#add-a-job-to-the-node) guide.
+- Include the address of your oracle contract address for all RunLog initiated jobs, as shown in the [Fulfilling Requests](/chainlink-nodes/fulfilling-requests/#add-a-job-to-the-node) guide.
- Override the global `MIN_INCOMING_CONFIRMATIONS` config by setting a `confirmations` field in jobs which perform off-chain payments to allow for greater security by making the node ensure the transaction is still valid after X blocks.
-[Configuring Chainlink Nodes](../configuration-variables/):
+[Configuring Chainlink Nodes](/chainlink-nodes/configuration-variables/):
-- [MINIMUM_CONTRACT_PAYMENT_LINK_JUELS](../configuration-variables/#minimum_contract_payment_link_juels): ensure your required payment amount is high enough to meet the costs of responding on-chain.
-- [MIN_INCOMING_CONFIRMATIONS](../configuration-variables/#min_incoming_confirmations): this can be set to 0 for common data request jobs. See the bullet above on setting individual `confirmations` for specific jobs.
-- [LOG_FILE_MAX_SIZE](../configuration-variables/#log_file_max_size): Set this to `0` if you're using external log drivers which parse the output from Docker containers. This will save you disk space.
-- [JSON_CONSOLE](../configuration-variables/#json_console): Set to `true` if you're using external log drivers to parse the output of Docker containers. This will make it easier to parse individual fields of the log and set up alerts.
+- [MINIMUM_CONTRACT_PAYMENT_LINK_JUELS](/chainlink-nodes/configuration-variables/#minimum_contract_payment_link_juels): ensure your required payment amount is high enough to meet the costs of responding on-chain.
+- [MIN_INCOMING_CONFIRMATIONS](/chainlink-nodes/configuration-variables/#min_incoming_confirmations): this can be set to 0 for common data request jobs. See the bullet above on setting individual `confirmations` for specific jobs.
+- [LOG_FILE_MAX_SIZE](/chainlink-nodes/configuration-variables/#log_file_max_size): Set this to `0` if you're using external log drivers which parse the output from Docker containers. This will save you disk space.
+- [JSON_CONSOLE](/chainlink-nodes/configuration-variables/#json_console): Set to `true` if you're using external log drivers to parse the output of Docker containers. This will make it easier to parse individual fields of the log and set up alerts.
## Addresses
diff --git a/docs/chainlink-nodes/configuration-variables.md b/src/pages/chainlink-nodes/configuration-variables.md
similarity index 92%
rename from docs/chainlink-nodes/configuration-variables.md
rename to src/pages/chainlink-nodes/configuration-variables.md
index 01214528216..0835f302dc2 100644
--- a/docs/chainlink-nodes/configuration-variables.md
+++ b/src/pages/chainlink-nodes/configuration-variables.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Configuring Chainlink Nodes"
@@ -18,7 +18,7 @@ The environment variables listed here are explicitly supported and current as of
As of Chainlink node v1.1.0 and up, the way nodes manage configuration is changing. Previously, environment variables exclusively handled all node configuration. Although this configuration method worked well in the past, it has its limitations. Notably, it doesn't mesh well with chain-specific configuration profiles.
-For this reason, Chainlink nodes are moving towards a model where you set variables using the API, [CLI](/docs/configuration-variables/#cli-client), or GUI, and the configuration is saved in the database. We encourage you to become familiar with this model because it is likely that nodes will continue to move away from environment variable configuration in the future.
+For this reason, Chainlink nodes are moving towards a model where you set variables using the API, [CLI](/chainlink-nodes/configuration-variables/#cli-client), or GUI, and the configuration is saved in the database. We encourage you to become familiar with this model because it is likely that nodes will continue to move away from environment variable configuration in the future.
As of v1.1.0, Chainlink nodes still support environment variables to configure node settings and chain-specific settings. If the environment variable is set, it overrides any chain-specific, job-specific, or database configuration setting. The log displays a warning to indicate when an override happens, so you know when variables lower in the hierarchy are being ignored.
@@ -28,7 +28,7 @@ Your node applies configuration settings using following hierarchy:
1. Chain-specific variables
1. Job-specific variables
-**Topics**
+**Table of contents:**
- [Changes to node configuration starting in v1.1.0 nodes](#changes-to-node-configuration-starting-in-v110-nodes)
- [Essential environment variables](#essential-environment-variables)
@@ -178,8 +178,8 @@ Your node applies configuration settings using following hierarchy:
- [BLOCK_HISTORY_ESTIMATOR_EIP1559_FEE_CAP_BUFFER_BLOCKS](#block_history_estimator_eip1559_fee_cap_buffer_blocks)
- [BLOCK_HISTORY_ESTIMATOR_TRANSACTION_PERCENTILE](#block_history_estimator_transaction_percentile)
- [EVM/Ethereum Transaction Simulation](#evmethereum-transaction-simulation)
- - [FM_SIMULATE_TRANSACTIONS](#fm_simulate_transactions)
- - [OCR_SIMULATE_TRANSACTIONS](#ocr_simulate_transactions)
+ - [FM_SIMULATE_TRANSACTIONS](#fm_simulate_transactions)
+ - [OCR_SIMULATE_TRANSACTIONS](#ocr_simulate_transactions)
- [Job Pipeline and tasks](#job-pipeline-and-tasks)
- [DEFAULT_HTTP_LIMIT](#default_http_limit)
- [DEFAULT_HTTP_TIMEOUT](#default_http_timeout)
@@ -189,6 +189,7 @@ Your node applies configuration settings using following hierarchy:
- [JOB_PIPELINE_REAPER_THRESHOLD](#job_pipeline_reaper_threshold)
- [JOB_PIPELINE_RESULT_WRITE_QUEUE_DEPTH](#job_pipeline_result_write_queue_depth)
- [OCR](#ocr)
+
- [FEATURE_OFFCHAIN_REPORTING](#feature_offchain_reporting)
- [OCR_KEY_BUNDLE_ID](#ocr_key_bundle_id)
- [OCR_MONITORING_ENDPOINT](#ocr_monitoring_endpoint)
@@ -234,7 +235,7 @@ These are the only environment variables that are _required_ for a Chainlink nod
- Default: _none_
-The PostgreSQL URI to connect to your database. Chainlink nodes require Postgres versions >= 11. See the [Running a Chainlink Node](../running-a-chainlink-node/#set-the-remote-database_url-config) for an example.
+The PostgreSQL URI to connect to your database. Chainlink nodes require Postgres versions >= 11. See the [Running a Chainlink Node](/chainlink-nodes/running-a-chainlink-node/#set-the-remote-database_url-config) for an example.
## General Node Configuration
@@ -334,7 +335,9 @@ Toggles sending telemetry to the ingress server using the batch client.
### SOLANA_ENABLED
-> 🚧 Not intended for use on the Solana mainnet.
+:::caution
+Not intended for use on the Solana mainnet.
+:::
- Default: `"false"`
@@ -559,9 +562,10 @@ Previous versions of Chainlink nodes wrote JSON logs with a unix timestamp. As o
When set, this environment variable configures and enables an optional HTTP logger which is used specifically to send audit log events. Audit logs events are emitted when specific actions are performed by any of the users through the node's API. The value of this variable should be a full URL. Log items will be sent via POST HTTP requests.
There are audit log implemented for the following events:
- - Auth & Sessions (new session, login success, login failed, 2FA enrolled, 2FA failed, password reset, password reset failed, etc.)
- - CRUD actions for all resources (add/create/delete resources such as bridges, nodes, keys)
- - Sensitive actions (keys exported/imported, config changed, log level changed, environment dumped)
+
+- Auth & Sessions (new session, login success, login failed, 2FA enrolled, 2FA failed, password reset, password reset failed, etc.)
+- CRUD actions for all resources (add/create/delete resources such as bridges, nodes, keys)
+- Sensitive actions (keys exported/imported, config changed, log level changed, environment dumped)
A full list of audit log enum types can be found in the source within the `audit` package ([`audit_types.go`](https://github.com/smartcontractkit/chainlink/blob/develop/core/logger/audit/audit_types.go)).
@@ -583,11 +587,11 @@ The `AUDIT_LOGS_*` environment variables below configure this optional audit log
- Default: _none_
-An optional list of HTTP headers to be added for every optional audit log event. If the above `AUDIT_LOGGER_FORWARD_TO_URL` is set, audit log events will be POSTed to that URL, and will include headers specified in this environment variable. One example use case is auth for example:
-```AUDIT_LOGGER_HEADERS="Authorization||{token}"```
+An optional list of HTTP headers to be added for every optional audit log event. If the above `AUDIT_LOGGER_FORWARD_TO_URL` is set, audit log events will be POSTed to that URL, and will include headers specified in this environment variable. One example use case is auth for example:
+`AUDIT_LOGGER_HEADERS="Authorization||{token}"`
Header keys and values are delimited on `||`, and multiple headers can be added with a forward slash delimiter (`\`). An example of multiple key value pairs:
-```AUDIT_LOGGER_HEADERS="Authorization||{token}\Some-Other-Header||{token2}"```
+`AUDIT_LOGGER_HEADERS="Authorization||{token}\Some-Other-Header||{token2}"`
##### AUDIT_LOGGER_JSON_WRAPPER_KEY
@@ -733,7 +737,7 @@ Do not change this setting unless you know what you are doing.
- Default: `"6688"`
-Port used for the Chainlink Node API, [CLI](/docs/configuration-variables/#cli-client), and GUI.
+Port used for the Chainlink Node API, [CLI](/chainlink-nodes/configuration-variables/#cli-client), and GUI.
### SECURE_COOKIES
@@ -815,17 +819,17 @@ The location of the TLS private key file. Example: `/home/$USER/.chainlink/tls/s
Previous Chainlink node versions supported only one chain. From v1.1.0 and up, Chainlink nodes support multiple EVM and non-EVM chains, so the way that chains and nodes are configured has changed.
-The preferred way of configuring Chainlink nodes as of v1.1.0 and up is to use the API, [CLI](/docs/configuration-variables/#cli-client), or UI to set chain-specific configuration and create nodes.
+The preferred way of configuring Chainlink nodes as of v1.1.0 and up is to use the API, [CLI](/chainlink-nodes/configuration-variables/#cli-client), or UI to set chain-specific configuration and create nodes.
The old way of specifying chains using environment variables is still supported, but discouraged. It works as follows:
If you set any value for `ETH_URL`, the values of `ETH_CHAIN_ID`, `ETH_URL`, `ETH_HTTP_URL` and `ETH_SECONDARY_URLS` will be used to create and update chains and nodes representing these values in the database. If an existing chain or node is found, it will be overwritten. This mode is used mainly to ease the process of upgrading. On subsequent runs (once your old settings have been written to the database) it is recommended to unset `ETH_URL` and use the API commands exclusively to administer chains and nodes.
-In the future, support for the `ETH_URL` and associated environment variables might be removed, so it is recommended to use the API, [CLI](/docs/configuration-variables/#cli-client), or GUI instead to setup chains and nodes.
+In the future, support for the `ETH_URL` and associated environment variables might be removed, so it is recommended to use the API, [CLI](/chainlink-nodes/configuration-variables/#cli-client), or GUI instead to setup chains and nodes.
### ETH_URL
-Setting this will enable "legacy eth ENV" mode, which is not compatible with multi-chain. It is better to configure settings using the API, [CLI](/docs/configuration-variables/#cli-client), or GUI instead.
+Setting this will enable "legacy eth ENV" mode, which is not compatible with multi-chain. It is better to configure settings using the API, [CLI](/chainlink-nodes/configuration-variables/#cli-client), or GUI instead.
- Default: _none_
@@ -835,7 +839,7 @@ NOTE: It is also required to set `ETH_CHAIN_ID` if you set ETH_URL.
### ETH_HTTP_URL
-Only has effect if `ETH_URL` set. Otherwise, it can be set in the API, [CLI](/docs/configuration-variables/#cli-client), or GUI.
+Only has effect if `ETH_URL` set. Otherwise, it can be set in the API, [CLI](/chainlink-nodes/configuration-variables/#cli-client), or GUI.
- Default: _none_
@@ -843,14 +847,15 @@ This should be set to the HTTP URL that points to the same ETH node as the prima
### EVM_NODES
-> 🚧 WARNING
->
-> Setting this environment variable will **COMPLETELY ERASE** your `evm_nodes` table on every boot and repopulate from the given data to nullify any runtime modifications. This is a temporary solution until this configuration can be defined in a file in the future.
+:::caution
+Setting this environment variable will **COMPLETELY ERASE** your `evm_nodes` table on every boot and repopulate from the given data to nullify any runtime modifications. This is a temporary solution until this configuration can be defined in a file in the future.
+:::
- Default: _none_
A JSON array of node specifications that allows you to configure multiple nodes or chains using an environment variable. This is not compatible with other environment variables that specify the node such as `ETH_URL` or `ETH_SECONDARY_URLS`. Set this variable using a configuration like the following example:
+
```json
EVM_NODES='
[
@@ -904,13 +909,14 @@ EVM_NODES='
Usage of Docker requires the variable to be formatted as one line with no whitespaces and quotes wrapping it, as follows in the example:
+
```bash
EVM_NODES=[{"name":"primary_0_1","evmChainId":"0","wsUrl":"ws://test1.invalid","sendOnly":false},{"name":"primary_0_2","evmChainId":"0","wsUrl":"ws://test2.invalid","httpUrl":"https://test3.invalid","sendOnly":false},{"name":"primary_1337_1","evmChainId":"1337","wsUrl":"ws://test4.invalid","httpUrl":"http://test5.invalid","sendOnly":false}]
```
### ETH_SECONDARY_URLS
-Only has effect if `ETH_URL` set. Otherwise, it can be set in the API, [CLI](/docs/configuration-variables/#cli-client), or GUI.
+Only has effect if `ETH_URL` set. Otherwise, it can be set in the API, [CLI](/chainlink-nodes/configuration-variables/#cli-client), or GUI.
- Default: _none_
@@ -967,10 +973,9 @@ This variable specifies the number of blocks before the current head that the lo
This variable enables skipping of very long log backfills. For example, this happens in a situation when the node is started after being offline for a long time.
This might be useful on fast chains and if only recent chain events are relevant
-
### ETH_TX_REAPER_INTERVAL
-NOTE: This overrides the setting for _all_ chains, you might want to set this on a per-chain basis using the API, [CLI](/docs/configuration-variables/#cli-client), or GUI instead
+NOTE: This overrides the setting for _all_ chains, you might want to set this on a per-chain basis using the API, [CLI](/chainlink-nodes/configuration-variables/#cli-client), or GUI instead
- Default: `"1h"`
@@ -991,7 +996,7 @@ Setting to `0` disables the reaper.
### ETH_TX_RESEND_AFTER_THRESHOLD
-NOTE: This overrides the setting for _all_ chains, you might want to set this on a per-chain basis using the API, [CLI](/docs/configuration-variables/#cli-client), or GUI instead.
+NOTE: This overrides the setting for _all_ chains, you might want to set this on a per-chain basis using the API, [CLI](/chainlink-nodes/configuration-variables/#cli-client), or GUI instead.
- Default: _automatically set based on Chain ID, typically 1m_
@@ -1068,8 +1073,9 @@ You can override this on a per-job basis.
`MIN_INCOMING_CONFIRMATIONS=1` would kick off a job after seeing the transaction in just one block.
-> 🚧 NOTE
-> The lowest value allowed here is 1, since setting to 0 would imply that logs are processed from the mempool before they are even mined into a block, which isn't possible with Chainlink's current architecture.
+:::caution
+The lowest value allowed here is 1, since setting to 0 would imply that logs are processed from the mempool before they are even mined into a block, which isn't possible with Chainlink's current architecture.
+:::
### MIN_OUTGOING_CONFIRMATIONS
@@ -1084,16 +1090,17 @@ This can be overridden on a per-task basis by setting the `MinRequiredOutgoingCo
### MINIMUM_CONTRACT_PAYMENT_LINK_JUELS
-> 🚧 NOTE
-> This has replaced the formerly used MINIMUM_CONTRACT_PAYMENT
+:::note
+This has replaced the formerly used MINIMUM_CONTRACT_PAYMENT.
+:::
- Default: _automatically set based on Chain ID, typically 10000000000000 (0.00001 LINK) on all chains except Ethereum Mainnet and Goerli where it is 100000000000000000 (0.1 LINK)._
For jobs that use the `EthTx` adapter, this is the minimum payment amount in order for the node to accept and process the job. Since there are no decimals on the EVM, the value is represented like wei.
-> 🚧 Note
->
-> Keep in mind, the Chainlink node currently responds with a 500,000 gas limit. Under pricing your node could mean it spends more in ETH (on gas) than it earns in LINK.
+:::note
+Keep in mind, the Chainlink node currently responds with a 500,000 gas limit. Under pricing your node could mean it spends more in ETH (on gas) than it earns in LINK.
+:::
### NODE_NO_NEW_HEADS_THRESHOLD
@@ -1126,13 +1133,13 @@ Set to zero to disable poll checking.
Controls node picking strategy. Supported values:
- `HighestHead` (default) mode picks a node having the highest reported head number among other alive nodes. When several nodes have the same latest head number, the strategy sticks to the last used node. This mode requires `NODE_NO_NEW_HEADS_THRESHOLD` to be configured, otherwise it will always use the first alive node.
-- `RoundRobin` mode simply iterates among available alive nodes. This was the default behavior prior to this release.
+- `RoundRobin` mode simply iterates among available alive nodes. This was the default behavior prior to this release.
## EVM Gas Controls
These settings allow you to tune your node's gas limits and pricing. In most cases, leaving these values at their defaults should give good results.
-As of Chainlink node v1.1.0, it is recommended to use the API, [CLI](/docs/configuration-variables/#cli-client), or GUI to configure gas controls because you might want to use different settings for different chains. Setting the environment variable typically overrides the setting for all chains.
+As of Chainlink node v1.1.0, it is recommended to use the API, [CLI](/chainlink-nodes/configuration-variables/#cli-client), or GUI to configure gas controls because you might want to use different settings for different chains. Setting the environment variable typically overrides the setting for all chains.
### Configuring your ETH node
@@ -1148,6 +1155,7 @@ It is also recommended to configure go-ethereum properly before increasing `ETH_
Relevant settings for geth and forks (such as BSC).
+
```toml
[Eth]
RPCGasCap = 0 # it is recommended to disable both gas and txfee cap
@@ -1186,10 +1194,12 @@ In EIP-1559 mode, the total price for the transaction is the minimum of base fee
Chainlink's implementation of EIP-1559 works as follows:
If you are using FixedPriceEstimator:
-- With gas bumping disabled, it will submit all transactions with `feecap=ETH_MAX_GAS_PRICE_WEI` and `tipcap=EVM_GAS_TIP_CAP_DEFAULT`.
+
+- With gas bumping disabled, it will submit all transactions with `feecap=ETH_MAX_GAS_PRICE_WEI` and `tipcap=EVM_GAS_TIP_CAP_DEFAULT`
- With gas bumping enabled, it will submit all transactions initially with `feecap=EVM_GAS_FEE_CAP_DEFAULT` and `tipcap=EVM_GAS_TIP_CAP_DEFAULT`.
If you are using BlockHistoryEstimator (default for most chains):
+
- With gas bumping disabled, it will submit all transactions with `feecap=ETH_MAX_GAS_PRICE_WEI` and `tipcap=
`
- With gas bumping enabled (default for most chains) it will submit all transactions initially with `feecap=current block base fee * (1.125 ^ N)` where N is configurable by setting BLOCK_HISTORY_ESTIMATOR_EIP1559_FEE_CAP_BUFFER_BLOCKS but defaults to `gas bump threshold+1` and `tipcap=`
@@ -1384,7 +1394,7 @@ Enables or disables sending transactions through forwarder contracts.
These settings allow you to configure how your node calculates gas prices. In most cases, leaving these values at their defaults should give good results.
-As of Chainlink node v1.1.0, it is recommended to use the API, [CLI](/docs/configuration-variables/#cli-client), or GUI to configure gas controls because you might want to use different settings for different chains. Setting the environment variable typically overrides the setting for all chains.
+As of Chainlink node v1.1.0, it is recommended to use the API, [CLI](/chainlink-nodes/configuration-variables/#cli-client), or GUI to configure gas controls because you might want to use different settings for different chains. Setting the environment variable typically overrides the setting for all chains.
Chainlink nodes decide what gas price to use using an `Estimator`. It ships with several simple and battle-hardened built-in estimators that should work well for almost all use-cases. Note that estimators will change their behaviour slightly depending on if you are in EIP-1559 mode or not.
@@ -1586,7 +1596,9 @@ Example: `P2P_PEER_ID=12D3KooWMHMRLQkgPbFSYHwD3NBuwtS1AmxhvKVUrcfyaGDASR4U`
### Networking Stack V1
-> 🚧 Do not set environment variables for Networking Stack v1 if you are using [Networking Stack V2](#networking-stack-v2).
+:::caution
+Do not set environment variables for Networking Stack v1 if you are using [Networking Stack V2](#networking-stack-v2).
+:::
#### P2P_ANNOUNCE_IP
@@ -1621,17 +1633,28 @@ The default IP address to bind to.
The port to listen on. If left blank, the node randomly selects a different port each time it boots. It is highly recommended to set this to a static value to avoid network instability.
+#### P2P_PEER_ID
+
+- Default: _none_
+
+This environment variable is used for both Networking Stack V1 and V2.
+
+The default peer ID to use for OCR jobs. If unspecified, uses the first available peer ID.
+Example: `P2P_PEER_ID=12D3KooWMHMRLQkgPbFSYHwD3NBuwtS1AmxhvKVUrcfyaGDASR4U`
+
### Networking Stack V2
-> 🚧 If using the Networking Stack V2, you must unset the following [Networking Stack V1](#networking-stack-v1) configuration variables:
->
-> - [P2P_ANNOUNCE_IP](#p2p_announce_ip)
-> - [P2P_ANNOUNCE_PORT](#p2p_announce_port)
-> - [P2P_BOOTSTRAP_PEERS](#p2p_bootstrap_peers)
-> - [P2P_LISTEN_IP](#p2p_listen_ip)
-> - [P2P_LISTEN_PORT](#p2p_listen_port)
->
-> `P2P_PEER_ID` is used for both Networking Stack V1 and V2.
+:::caution
+If using the Networking Stack V2, you must unset the following [Networking Stack V1](#networking-stack-v1) configuration variables:
+
+- [P2P_ANNOUNCE_IP](#p2p_announce_ip)
+- [P2P_ANNOUNCE_PORT](#p2p_announce_port)
+- [P2P_BOOTSTRAP_PEERS](#p2p_bootstrap_peers)
+- [P2P_LISTEN_IP](#p2p_listen_ip)
+- [P2P_LISTEN_PORT](#p2p_listen_port)
+
+[`P2P_PEER_ID`](#p2p_peer_id) is used for both Networking Stack V1 and V2.
+:::
#### P2PV2_ANNOUNCE_ADDRESSES
@@ -1661,21 +1684,21 @@ These environment variables are used specificly for Chainlink Keepers. For most
### KEEPER_CHECK_UPKEEP_GAS_PRICE_FEATURE_ENABLED
-> 🚧 **ADVANCED**
->
-> Do not change this setting unless you know what you are doing.
+:::caution
+Do not change this setting unless you know what you are doing.
+:::
- Default: `"false"`
-Use this setting *only* on Polygon networks.
+Use this setting _only_ on Polygon networks.
Includes gas price in calls to `checkUpkeep()` when set to `true`.
### KEEPER_GAS_PRICE_BUFFER_PERCENT
-> 🚧 **ADVANCED**
->
-> Do not change this setting unless you know what you are doing.
+:::caution
+Do not change this setting unless you know what you are doing.
+:::
- Default: `"20"`
@@ -1683,9 +1706,9 @@ Includes gas price in calls to `checkUpkeep()` when set to `true`.
### KEEPER_GAS_TIP_CAP_BUFFER_PERCENT
-> 🚧 **ADVANCED**
->
-> Do not change this setting unless you know what you are doing.
+:::caution
+Do not change this setting unless you know what you are doing.
+:::
- Default: `"20"`
@@ -1693,9 +1716,9 @@ Includes gas price in calls to `checkUpkeep()` when set to `true`.
### KEEPER_BASE_FEE_BUFFER_PERCENT
-> 🚧 **ADVANCED**
->
-> Do not change this setting unless you know what you are doing.
+:::caution
+Do not change this setting unless you know what you are doing.
+:::
- Default: `"20"`
@@ -1703,9 +1726,9 @@ Adds the specified percentage to the base fee used for checking whether to perfo
### KEEPER_MAXIMUM_GRACE_PERIOD
-> 🚧 **ADVANCED**
->
-> Do not change this setting unless you know what you are doing.
+:::caution
+Do not change this setting unless you know what you are doing.
+:::
- Default: `"100"`
@@ -1713,9 +1736,9 @@ The maximum number of blocks that a keeper will wait after performing an upkeep
### KEEPER_REGISTRY_CHECK_GAS_OVERHEAD
-> 🚧 **ADVANCED**
->
-> Do not change this setting unless you know what you are doing.
+:::caution
+Do not change this setting unless you know what you are doing.
+:::
- Default: `"200000"`
@@ -1723,9 +1746,9 @@ The amount of extra gas to provide checkUpkeep() calls to account for the gas co
### KEEPER_REGISTRY_PERFORM_GAS_OVERHEAD
-> 🚧 **ADVANCED**
->
-> Do not change this setting unless you know what you are doing.
+:::caution
+Do not change this setting unless you know what you are doing.
+:::
- Default: `"300000"`
@@ -1733,9 +1756,9 @@ The amount of extra gas to provide performUpkeep() calls to account for the gas
### KEEPER_REGISTRY_SYNC_INTERVAL
-> 🚧 **ADVANCED**
->
-> Do not change this setting unless you know what you are doing.
+:::caution
+Do not change this setting unless you know what you are doing.
+:::
- Default: `"30m"`
@@ -1743,9 +1766,9 @@ The interval in which the RegistrySynchronizer performs a full sync of the keepe
### KEEPER_REGISTRY_SYNC_UPKEEP_QUEUE_SIZE
-> 🚧 **ADVANCED**
->
-> Do not change this setting unless you know what you are doing.
+:::caution
+Do not change this setting unless you know what you are doing.
+:::
- Default: `"10"`
@@ -1753,9 +1776,9 @@ The interval in which the RegistrySynchronizer performs a full sync of the keepe
### KEEPER_TURN_LOOK_BACK
-> 🚧 **ADVANCED**
->
-> Do not change this setting unless you know what you are doing.
+:::caution
+Do not change this setting unless you know what you are doing.
+:::
- Default: `"1000"`
@@ -1763,9 +1786,9 @@ The number of blocks in the past to look back when getting a block for a turn.
### KEEPER_TURN_FLAG_ENABLED
-> 🚧 **ADVANCED**
->
-> Do not change this setting unless you know what you are doing.
+:::caution
+Do not change this setting unless you know what you are doing.
+:::
- Default: `"false"`
@@ -1777,10 +1800,9 @@ The environment variables in this section apply only when running CLI commands t
### ADMIN_CREDENTIALS_FILE
-> 🚧 Deprecated:
->
-> This environment variable is deprecated and will be removed in a future release. Use the `--admin-credentials-file FILE` CLI argument instead.
-
+:::caution[Deprecated]
+This environment variable is deprecated and will be removed in a future release. Use the `--admin-credentials-file FILE` CLI argument instead.
+:::
- Default: `$ROOT/apicredentials`
@@ -1796,9 +1818,9 @@ mysecurepassw0rd
### CLIENT_NODE_URL
-> 🚧 Deprecated:
->
-> This environment variable is deprecated and will be removed in a future release. Use the `--remote-node-url URL` CLI argument instead.
+:::caution[Deprecated]
+This environment variable is deprecated and will be removed in a future release. Use the `--remote-node-url URL` CLI argument instead.
+:::
- Default: `"http://localhost:6688"`
@@ -1806,9 +1828,9 @@ This is the URL that you will use to interact with the node, including the GUI.
### INSECURE_SKIP_VERIFY
-> 🚧 Deprecated:
->
-> This environment variable is deprecated and will be removed in a future release. Use the `--insecure-skip-verify` CLI argument instead.
+:::caution[Deprecated]
+This environment variable is deprecated and will be removed in a future release. Use the `--insecure-skip-verify` CLI argument instead.
+:::
- Default: `"false"`
@@ -1818,15 +1840,17 @@ It is not recommended to change this unless you know what you are doing.
## Notes on setting environment variables
-> 🚧 NOTE
-> Some environment variables require a duration. A duration string is a possibly signed sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Some examples:
+:::note
+Some environment variables require a duration. A duration string is a possibly signed sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Some examples:
+:::
`10ms`
`1h15m`
`42m30s`
-> 🚧 NOTE
-> Some configuration variables require a file size. A file size string is an unsigned integer (123) or a float (12.3) followed by a unit suffix. Valid file size units are "b", "kb", "mb", "gb", and "tb". If the unit is omitted, it is assumed to be "b" (bytes). Capitalization does not matter. Some examples:
+:::note
+Some configuration variables require a file size. A file size string is an unsigned integer (123) or a float (12.3) followed by a unit suffix. Valid file size units are "b", "kb", "mb", "gb", and "tb". If the unit is omitted, it is assumed to be "b" (bytes). Capitalization does not matter. Some examples:
+:::
`123gb`
`1.2TB`
diff --git a/docs/chainlink-nodes/connecting-to-a-remote-database.md b/src/pages/chainlink-nodes/connecting-to-a-remote-database.md
similarity index 90%
rename from docs/chainlink-nodes/connecting-to-a-remote-database.md
rename to src/pages/chainlink-nodes/connecting-to-a-remote-database.md
index cbcbbe1c8b3..a17f89f218f 100644
--- a/docs/chainlink-nodes/connecting-to-a-remote-database.md
+++ b/src/pages/chainlink-nodes/connecting-to-a-remote-database.md
@@ -1,14 +1,16 @@
---
-layout: nodes.liquid
+layout: ../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Connecting to a Remote Database"
permalink: "docs/connecting-to-a-remote-database/"
-whatsnext: {"Configuring Chainlink":"/docs/configuration-variables/"}
+whatsnext: { "Configuring Chainlink": "/chainlink-nodes/configuration-variables/" }
---
+
This page will serve as a basic, vendor-neutral guide for setting up a PostgreSQL database and connecting your Chainlink node to it.
PostgreSQL is a popular and secure database available on a variety of platforms. This guide will not show you how to create and set up a PostgreSQL database, however, some common guides can be found below:
+
- [Amazon AWS](https://aws.amazon.com/getting-started/tutorials/create-connect-postgresql-db/)
- [Azure](https://docs.microsoft.com/en-us/azure/postgresql/quickstart-create-server-database-portal)
- [Docker](https://docs.docker.com/samples/library/postgres/)
@@ -17,6 +19,7 @@ PostgreSQL is a popular and secure database available on a variety of platforms.
## Obtain Information About Your Database
In order to connect to a remote database, you will need to obtain information about the database and server. Take note of the database's:
+
- Server or IP
- Port
- Username
@@ -25,7 +28,7 @@ In order to connect to a remote database, you will need to obtain information ab
The user must be the owner of the desired database. On first run, the migrations will create the tables necessary for the Chainlink node.
-## Set Your DATABASE_URL Environment Variable
+## Set Your DATABASE_URL Environment Variable
Below is an example for setting the `DATABASE_URL` environment variable:
@@ -34,6 +37,7 @@ DATABASE_URL=postgresql://$USERNAME:$PASSWORD@$SERVER:$PORT/$DATABASE
```
You will need to change the following placeholders to their real values:
+
- `$USERNAME`: The database username (must be owner)
- `$PASSWORD`: The user's password
- `$SERVER`: The server name or IP address of the database server
diff --git a/docs/chainlink-nodes/enabling-https-connections.md b/src/pages/chainlink-nodes/enabling-https-connections.md
similarity index 91%
rename from docs/chainlink-nodes/enabling-https-connections.md
rename to src/pages/chainlink-nodes/enabling-https-connections.md
index 43ae09b5df2..b9a50c73ac6 100644
--- a/docs/chainlink-nodes/enabling-https-connections.md
+++ b/src/pages/chainlink-nodes/enabling-https-connections.md
@@ -1,22 +1,24 @@
---
-layout: nodes.liquid
+layout: ../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Enabling HTTPS Connections"
permalink: "docs/enabling-https-connections/"
-whatsnext: {"Miscellaneous":"/docs/miscellaneous/"}
+whatsnext: { "Miscellaneous": "/chainlink-nodes/miscellaneous/" }
---
+
This guide will walk you through how to generate your own self-signed certificates for use by the Chainlink node. You can also substitute self-signed certificates with certificates of your own, like those created by Let's Encrypt .
-> 📘 Important
->
-> You will need [OpenSSL](https://www.openssl.org) in order to generate your own self-signed certificates.
+:::tip[TLS]
+You will need [OpenSSL](https://www.openssl.org) in order to generate your own self-signed certificates.
+:::
Create a directory `tls/` within your local Chainlink directory:
```text Goerli
mkdir ~/.chainlink-goerli/tls
```
+
```text Mainnet
mkdir ~/.chainlink/tls
```
@@ -29,6 +31,7 @@ openssl req -x509 -out ~/.chainlink-goerli/tls/server.crt -keyout ~/.chainlink
-subj '/CN=localhost' -extensions EXT -config <( \
printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
```
+
```shell Mainnet
openssl req -x509 -out ~/.chainlink/tls/server.crt -keyout ~/.chainlink/tls/server.key \
-newkey rsa:2048 -nodes -sha256 -days 365 \
@@ -60,6 +63,7 @@ Finally, update your run command to forward port 6689 to the container instead o
```shell Goerli
cd ~/.chainlink-goerli && docker run -p 6689:6689 -v ~/.chainlink-goerli:/chainlink -it --env-file=.env smartcontract/chainlink local n
```
+
```shell Mainnet
cd ~/.chainlink && docker run -p 6689:6689 -v ~/.chainlink:/chainlink -it --env-file=.env smartcontract/chainlink local n
```
diff --git a/docs/chainlink-nodes/evm-performance-configuration.md b/src/pages/chainlink-nodes/evm-performance-configuration.md
similarity index 72%
rename from docs/chainlink-nodes/evm-performance-configuration.md
rename to src/pages/chainlink-nodes/evm-performance-configuration.md
index ef7346010c8..6f31c76ca22 100644
--- a/docs/chainlink-nodes/evm-performance-configuration.md
+++ b/src/pages/chainlink-nodes/evm-performance-configuration.md
@@ -1,40 +1,30 @@
---
-layout: nodes.liquid
+layout: ../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
-title: 'Optimizing EVM Performance'
-permalink: 'docs/evm-performance-configuration/'
-whatsnext: {
- "Performing System Maintenance":"/docs/performing-system-maintenance/",
- "Security and Operation Best Practices":"/docs/best-security-practices/"
-}
+title: "Optimizing EVM Performance"
+permalink: "docs/evm-performance-configuration/"
+whatsnext:
+ {
+ "Performing System Maintenance": "/chainlink-nodes/performing-system-maintenance/",
+ "Security and Operation Best Practices": "/chainlink-nodes/best-security-practices/",
+ }
metadata:
- title: 'Optimizing EVM Performance'
- description: 'Configure your Chainlink and EVM nodes for high throughput and reliability'
+ title: "Optimizing EVM Performance"
+ description: "Configure your Chainlink and EVM nodes for high throughput and reliability"
---
The most basic Chainlink node deployment uses the default configuration on only a single primary node with a websocket URL. This configuration is appropriate for small or simple workloads with only a few jobs that execute infrequently. If you need to run hundreds of jobs and thousands of transactions per hour, your Chainlink and RPC nodes will require a more advanced configuration. This guide explains how to configure Chainlink and your EVM nodes for high reliability and throughput.
-> 📘 Note:
->
-> Ethereum clients have bugs. Much work is done on the Chainlink node software to mitigate bugs in various different RPC implementations. This guide helps you understand how to mitigate and work around these bugs.
-
-**Topics**
-
-- [Using multiple nodes](#using-multiple-nodes)
-- [Automatic load balancing and failover](#automatic-load-balancing-and-failover)
-- [Configuring websocket and HTTP URLs](#configuring-websocket-and-http-urls)
-- [Increasing transaction throughput](#increasing-transaction-throughput)
- - [Increase ETH_MAX_QUEUED_TRANSACTIONS](#increase-eth_max_queued_transactions)
- - [Increase ETH_MAX_IN_FLIGHT_TRANSACTIONS](#increasing-transaction-throughput)
-- [Optimizing RPC nodes](#optimizing-rpc-nodes)
-- [Remove rejections on expensive transactions](#remove-rejections-on-expensive-transactions)
-- [Adjusting minimum outgoing confirmations for high throughput jobs](#adjusting-minimum-outgoing-confirmations-for-high-throughput-jobs)
-- [Increase ORM_MAX_OPEN_CONNS and ORM_MAX_IDLE_CONNS](#increase-orm_max_open_conns-and-orm_max_idle_conns)
+:::note[Note on Ethereum clients]
+Ethereum clients have bugs. Much work is done on the Chainlink node software to mitigate bugs in various different RPC implementations. This guide helps you understand how to mitigate and work around these bugs.
+:::
## Using multiple nodes
-> 📘 Providing multiple primary nodes can improve performance and reliability.
+:::note[Use multiple nodes]
+Providing multiple primary nodes can improve performance and reliability.
+:::
Chainlink node version 1.3.0 and later support configurations with multiple primary nodes and send-only nodes with automatic liveness detection and failover. It is no longer necessary to run a load balancing failover RPC proxy between Chainlink and its EVM RPC nodes.
@@ -44,9 +34,11 @@ You can have as many primary nodes as you want. Requests are evenly distributed
You can configure as many send-only nodes as you want. Send-only nodes only broadcast transactions and do not process regular RPC calls. Specifying additional send-only nodes uses a minimum number of RPC calls and can help to include transactions faster. Send-only nodes also act as backup if your primary node starts to blackhole transactions.
-> 📘 Transaction broadcasts are always sent to every primary node and send-only node. It is redundant to specify the same URL for a send-only node as an existing primary node, and it has no effect.
+:::note[Transaction broadcasts]
+Transaction broadcasts are always sent to every primary node and send-only node. It is redundant to specify the same URL for a send-only node as an existing primary node, and it has no effect.
+:::
-Here is an example for how to specifiy the [`EVM_NODES` environment variable](/docs/configuration-variables/#evm_nodes):
+Here is an example for how to specifiy the [`EVM_NODES` environment variable](/chainlink-nodes/configuration-variables/#evm_nodes):
```shell
export EVM_NODES='
@@ -104,9 +96,9 @@ NODE_POLL_FAILURE_THRESHOLD=0
NODE_POLL_INTERVAL=0
```
-- [NODE_NO_NEW_HEADS_THRESHOLD](/docs/configuration-variables/#node_no_new_heads_threshold): Controls how long to wait receiving no new heads before marking a node dead
-- [NODE_POLL_FAILURE_THRESHOLD](/docs/configuration-variables/#node_poll_failure_threshold): Controls how many consecutive poll failures will disable a node
-- [NODE_POLL_INTERVAL](/docs/configuration-variables/#node_poll_interval): Controls how often the node will be polled
+- [NODE_NO_NEW_HEADS_THRESHOLD](/chainlink-nodes/configuration-variables/#node_no_new_heads_threshold): Controls how long to wait receiving no new heads before marking a node dead
+- [NODE_POLL_FAILURE_THRESHOLD](/chainlink-nodes/configuration-variables/#node_poll_failure_threshold): Controls how many consecutive poll failures will disable a node
+- [NODE_POLL_INTERVAL](/chainlink-nodes/configuration-variables/#node_poll_interval): Controls how often the node will be polled
By default, these environment variables use the following values:
@@ -118,15 +110,17 @@ NODE_POLL_INTERVAL="10s"
## Configuring websocket and HTTP URLs
-> 📘 Ideally, every primary node specifies an HTTP URL in addition to the websocket URL.
+:::note[Note on URLs]
+Ideally, every primary node specifies an HTTP URL in addition to the websocket URL.
+:::
-It is not recommended to configure primary nodes with *only* a websocket URL. Routing all traffic over only a websocket can cause problems. As a best practices, every primary node must have both websocket and HTTP URLs specified. This allows Chainlink to route almost all RPC calls over HTTP, which tends to be more robust and reliable. The websocket URL is used only for subscriptions. Both URLs must point to the same node because they are bundled together and have the same liveness state.
+It is not recommended to configure primary nodes with _only_ a websocket URL. Routing all traffic over only a websocket can cause problems. As a best practices, every primary node must have both websocket and HTTP URLs specified. This allows Chainlink to route almost all RPC calls over HTTP, which tends to be more robust and reliable. The websocket URL is used only for subscriptions. Both URLs must point to the same node because they are bundled together and have the same liveness state.
If you enabled HTTP URLs on all your primary nodes, you can increase the values for the following environment variables:
-- [ETH_RPC_DEFAULT_BATCH_SIZE](/docs/configuration-variables/#eth_rpc_default_batch_size)
-- [BLOCK_HISTORY_ESTIMATOR_BATCH_SIZE](/docs/configuration-variables/#block_history_estimator_batch_size)
-- [ETH_LOG_BACKFILL_BATCH_SIZE](/docs/configuration-variables/#eth_log_backfill_batch_size)
+- [ETH_RPC_DEFAULT_BATCH_SIZE](/chainlink-nodes/configuration-variables/#eth_rpc_default_batch_size)
+- [BLOCK_HISTORY_ESTIMATOR_BATCH_SIZE](/chainlink-nodes/configuration-variables/#block_history_estimator_batch_size)
+- [ETH_LOG_BACKFILL_BATCH_SIZE](/chainlink-nodes/configuration-variables/#eth_log_backfill_batch_size)
By default, these config variables are set conservatively to avoid overflowing websocket frames. In HTTP mode, there are no such limitations. You might be able to improve performance with increased values similar to the following example:
@@ -136,17 +130,19 @@ BLOCK_HISTORY_ESTIMATOR_BATCH_SIZE=100
ETH_LOG_BACKFILL_BATCH_SIZE=1000
```
-> 🚧 REMINDER:
->
-> Do not modify these values unless *all* primary nodes are configured with HTTP URLs.
+:::caution
+Do not modify these values unless _all_ primary nodes are configured with HTTP URLs.
+:::
## Increasing transaction throughput
By default, Chainlink has conservative limits because it must be compliant with standard out-of-the-box RPC configurations. This limits transaction throughput and the performance of some RPC calls.
-Before you make any changes to your Chainlink configuration, you must ensure that *all* of your primary and send-only nodes are configured to handle the increased throughput.
+Before you make any changes to your Chainlink configuration, you must ensure that _all_ of your primary and send-only nodes are configured to handle the increased throughput.
-> 📘 The best way to improve transaction throughput is to keep the default configuration and use multiple keys to transmit. Chainlink supports an arbitrary number of keys for any given chain. By default, tasks will round-robin through keys, but you can assign them individually to keys as well. Assigning tasks to keys is the preferred way to improve throughput because increasing the max number of in-flight requests can have complicated effects based on the mempool conmfigurations of other RPC nodes. If you are unable to distribute transmission load across multiple keys, try the following options to increase throughput.
+:::note[Transaction throughput]
+The best way to improve transaction throughput is to keep the default configuration and use multiple keys to transmit. Chainlink supports an arbitrary number of keys for any given chain. By default, tasks will round-robin through keys, but you can assign them individually to keys as well. Assigning tasks to keys is the preferred way to improve throughput because increasing the max number of in-flight requests can have complicated effects based on the mempool conmfigurations of other RPC nodes. If you are unable to distribute transmission load across multiple keys, try the following options to increase throughput.
+:::
### Increase `ETH_MAX_QUEUED_TRANSACTIONS`
@@ -166,7 +162,9 @@ Do not set `ETH_MAX_QUEUED_TRANSACTIONS` too high. It acts as a sanity limit and
The default is set conservatively at `16` because this is a pessimistic minimum that go-ethereum will hold without evicting local transactions. If your node is falling behind and not able to get transactions in as fast as they are created, you can increase this setting.
-> 🚧 If you increase `ETH_MAX_IN_FLIGHT_TRANSACTIONS` you must make sure that your ETH node is configured properly otherwise you can get nonce-gapped and your node will get stuck.
+:::caution
+If you increase `ETH_MAX_IN_FLIGHT_TRANSACTIONS` you must make sure that your ETH node is configured properly otherwise you can get nonce-gapped and your node will get stuck.
+:::
## Optimizing RPC nodes
@@ -208,7 +206,6 @@ Arbitrum Nitro runs a fork of go-ethereum internally, but the original flags are
`--node.rpc.gas-cap 0 --node.rpc.tx-fee-cap 0`
-
## Adjusting minimum outgoing confirmations for high throughput jobs
`ethtx` tasks have a `minConfirmations` label that can be adjusted. You can get a minor performance boost if you set this label to `0`. Use this if you do not need to wait for confirmations on your `ethtx` tasks. For example, if you don't need the receipt or don’t care about failing the task if the transaction reverts on-chain, you can set `minConfirmations` to `0`.
@@ -219,7 +216,9 @@ Set the task label similiarly to the following example:
Note that this only affects the presentation of jobs, and whether they are marked as errored or not. It has no effect on inclusion of the transaction, which is handled with separate logic.
-> 🚧 Do not confuse `minConfirmations` set on the task with transaction inclusion. The transaction manager always attempts to get every transaction mined up to `EVMFinalityDepth`. `minConfirmations` on the task is a task-specific view of when the transaction that can be considered final, which might be fewer blocks than `EVMFinalityDepth`.
+:::caution
+Do not confuse `minConfirmations` set on the task with transaction inclusion. The transaction manager always attempts to get every transaction mined up to `EVMFinalityDepth`. `minConfirmations` on the task is a task-specific view of when the transaction that can be considered final, which might be fewer blocks than `EVMFinalityDepth`.
+:::
## Increase `ORM_MAX_OPEN_CONNS` and `ORM_MAX_IDLE_CONNS`
diff --git a/docs/chainlink-nodes/external-adapters/contract-creators.md b/src/pages/chainlink-nodes/external-adapters/contract-creators.md
similarity index 59%
rename from docs/chainlink-nodes/external-adapters/contract-creators.md
rename to src/pages/chainlink-nodes/external-adapters/contract-creators.md
index 33cd3b8b7bd..6e3fa21030c 100644
--- a/docs/chainlink-nodes/external-adapters/contract-creators.md
+++ b/src/pages/chainlink-nodes/external-adapters/contract-creators.md
@@ -1,20 +1,26 @@
---
-layout: nodes.liquid
+layout: ../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "External Adapters in Solidity"
permalink: "docs/contract-creators/"
-whatsnext: {"Building External Adapters":"/docs/developers/", "Bridges: Adding External Adapters to Nodes":"/docs/node-operators/"}
+whatsnext:
+ {
+ "Building External Adapters": "/chainlink-nodes/external-adapters/developers/",
+ "Bridges: Adding External Adapters to Nodes": "/chainlink-nodes/external-adapters/node-operators/",
+ }
---
+
### Using parameters with an External Adapter
As a contract creator, using an external adapter is no different than creating a request for any other job spec. You will simply need to know which parameters are supported by the adapter. Notice the method below uses `req.add` to create a run parameter for each required value.
-```javascript
+
+```solidity
function requestMWAPrice(string _coin, string _market)
public
onlyOwner
- returns (bytes32 requestId)
+ returns (bytes32 requestId)
{
Chainlink.Request memory req = buildChainlinkRequest(SPEC_ID, this, this.fulfill.selector);
req.add("endpoint", "mwa-historic");
@@ -28,39 +34,42 @@ function requestMWAPrice(string _coin, string _market)
### Using the Copy adapter with an External Adapter
-The [Copy](../core-adapters/#copy) adapter allows for the same functionality of the [JsonParse](../core-adapters/#jsonparse) adapter but for getting data from the external adapter's response.
+The [Copy](/chainlink-nodes/oracle-jobs/v1/adapters/#copy) adapter allows for the same functionality of the [JsonParse](/chainlink-nodes/oracle-jobs/v1/adapters/#jsonparse) adapter but for getting data from the external adapter's response.
For example, if an adapter returns JSON data like what is below:
```json
{
- "firstValue": "SomeValue",
- "details": {
- "close": "100",
- "open": "110",
- "current": "111"
- },
- "other": "GetData"
+ "firstValue": "SomeValue",
+ "details": {
+ "close": "100",
+ "open": "110",
+ "current": "111"
+ },
+ "other": "GetData"
}
```
And you wanted the value in the field "open", you would specify the path for the adapter to walk through the JSON object to your desired field.
+
```json
"copyPath": ["details", "open"]
```
In Solidity, this would look like:
-```javascript
+
+```solidity
string[] memory path = new string[](2);
path[0] = "details";
path[1] = "open";
run.addStringArray("copyPath", path);
```
-Or you can use dot-notation JSONPath to simplify it:
+Or you can use dot-notation JSONPath to simplify it:
-```javascript
-run.add("copyPath", "details.open");
-```
\ No newline at end of file
+
+```solidity
+run.add("copyPath", "details.open")
+```
diff --git a/docs/chainlink-nodes/external-adapters/developers.md b/src/pages/chainlink-nodes/external-adapters/developers.md
similarity index 79%
rename from docs/chainlink-nodes/external-adapters/developers.md
rename to src/pages/chainlink-nodes/external-adapters/developers.md
index e9297030efc..4934ed38aab 100644
--- a/docs/chainlink-nodes/external-adapters/developers.md
+++ b/src/pages/chainlink-nodes/external-adapters/developers.md
@@ -1,16 +1,17 @@
---
-layout: nodes.liquid
+layout: ../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Building External Adapters"
permalink: "docs/developers/"
-whatsnext: {"Bridges: Adding External Adapters to Nodes":"/docs/node-operators/"}
+whatsnext: { "Bridges: Adding External Adapters to Nodes": "/chainlink-nodes/external-adapters/node-operators/" }
---
+
Developers of external adapters will need to know how the Chainlink node requests data from it, and how the data should be formatted for a response. External adapters can be written in any language, and even run on separate machines, to include serverless functions.
Here is our external adapters monorepo which contains many examples to help get you started:
-* Official Chainlink External Adapter Monorepo (NodeJS)
+- Official Chainlink External Adapter Monorepo (NodeJS)
### Requesting Data
@@ -24,15 +25,22 @@ When an external adapter receives a request from the Chainlink node, the JSON pa
#### Examples
```json
-{"data":{}}
+{ "data": {} }
```
```json
-{"data":{}, "responseURL": "http://localhost:6688/v2/runs/278c97ffadb54a5bbb93cfec5f7b5503"}
+{
+ "data": {},
+ "responseURL": "http://localhost:6688/v2/runs/278c97ffadb54a5bbb93cfec5f7b5503"
+}
```
```json
-{"data":{"foo": 42}, "meta":{"bar": "baz"}, "id": "2d38ecdb-975c-4f99-801c-b916a429947c"}
+{
+ "data": { "foo": 42 },
+ "meta": { "bar": "baz" },
+ "id": "2d38ecdb-975c-4f99-801c-b916a429947c"
+}
```
Additional data may be specified in the spec to be utilized by the adapter. This can be useful for requesting data from a REST endpoint where the keys and values can be specified by the requester. For example, if the REST endpoint supports the following:
@@ -99,7 +107,7 @@ If the external adapter wants to use the response URL to send data later, it may
```json
{
- "pending": true
+ "pending": true
}
```
@@ -107,7 +115,6 @@ In this case, the job run on Chainlink side will be put into a `pending` state,
When the external adapter is ready, it should callback to the node to resume the JobRun using an HTTP PATCH request to the `responseURL` field. This will resume the job on the Chainlink side.
-
```json
{
"data": {
@@ -134,43 +141,43 @@ Or, for the error case:
Here is a complete example of a simple external adapter written as a serverless function. This external adapter takes two input fields, inserts the API key as a header, and returns the resulting payload to the node.
```javascript External Adapter
-let request = require('request');
+let request = require("request")
exports.myExternalAdapter = (req, res) => {
- const url = "https://some-api.example.com/api";
- const coin = req.body.data.coin || "";
- const market = req.body.data.market || "";
+ const url = "https://some-api.example.com/api"
+ const coin = req.body.data.coin || ""
+ const market = req.body.data.market || ""
let requestObj = {
coin: coin,
- market: market
- };
+ market: market,
+ }
let headerObj = {
- "API_KEY": "abcd-efgh-ijkl-mnop-qrst-uvwy"
- };
+ API_KEY: "abcd-efgh-ijkl-mnop-qrst-uvwy",
+ }
let options = {
- url: url,
- headers: headerObj,
- qs: requestObj,
- json: true
- };
+ url: url,
+ headers: headerObj,
+ qs: requestObj,
+ json: true,
+ }
request(options, (error, response, body) => {
if (error || response.statusCode >= 400) {
- let errorData = {
- jobRunID: req.body.id,
- status: "errored",
- error: body
- };
- res.status(response.statusCode).send(errorData);
+ let errorData = {
+ jobRunID: req.body.id,
+ status: "errored",
+ error: body,
+ }
+ res.status(response.statusCode).send(errorData)
} else {
let returnData = {
jobRunID: req.body.id,
- data: body
- };
- res.status(response.statusCode).send(returnData);
+ data: body,
+ }
+ res.status(response.statusCode).send(returnData)
}
- });
-};
+ })
+}
```
If given "ETH" as the value for `coin` and "USD" as the value for `market`, this external adapter will build the following URL for the request:
diff --git a/src/pages/chainlink-nodes/external-adapters/external-adapters.md b/src/pages/chainlink-nodes/external-adapters/external-adapters.md
new file mode 100644
index 00000000000..3cf402c0445
--- /dev/null
+++ b/src/pages/chainlink-nodes/external-adapters/external-adapters.md
@@ -0,0 +1,21 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: nodeOperator
+date: Last Modified
+title: "External Adapters Introduction"
+permalink: "docs/external-adapters/"
+whatsnext:
+ {
+ "External Adapters in Solidity": "/chainlink-nodes/external-adapters/contract-creators/",
+ "Building External Adapters": "/chainlink-nodes/external-adapters/developers/",
+ "Bridges: Adding External Adapters to Nodes": "/chainlink-nodes/external-adapters/node-operators/",
+ }
+---
+
+External adapters are how Chainlink enables easy integration of custom computations and specialized APIs. External adapters are services which the core of the Chainlink node communicates via its API with a simple JSON specification. If you want a step by step, be sure to check out our [blog post](https://blog.chain.link/build-and-use-external-adapters/).
+
+Information on external adapters is broken up into three main categories: contract creators, developers, and node operators.
+
+- [Contract Creators](/chainlink-nodes/external-adapters/contract-creators/) will need to know how to specify an external adapter in their request for external data.
+- [Developers](/chainlink-nodes/external-adapters/developers/) will need to know how to implement an external adapter for an API.
+- [Node Operators](/chainlink-nodes/external-adapters/node-operators/) will need to know how to add an external adapter to their node so that they can provide specialized services to smart contracts.
diff --git a/docs/chainlink-nodes/external-adapters/node-operators.md b/src/pages/chainlink-nodes/external-adapters/node-operators.md
similarity index 79%
rename from docs/chainlink-nodes/external-adapters/node-operators.md
rename to src/pages/chainlink-nodes/external-adapters/node-operators.md
index 12ebeb023d9..9e64bfc1144 100644
--- a/docs/chainlink-nodes/external-adapters/node-operators.md
+++ b/src/pages/chainlink-nodes/external-adapters/node-operators.md
@@ -1,11 +1,12 @@
---
-layout: nodes.liquid
+layout: ../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Bridges: Adding External Adapters to Nodes"
permalink: "docs/node-operators/"
---
-You can add external adapters to a Chainlink node by creating a bridge in the Node Operators Interface. Each bridge must have a unique name and a URL for the external adapter. If a job has a [Bridge Task](/docs/jobs/task-types/bridge/), the node searches for a bridge by name and uses that bridge as your external adapter. Bridge names are case insensitive.
+
+You can add external adapters to a Chainlink node by creating a bridge in the Node Operators Interface. Each bridge must have a unique name and a URL for the external adapter. If a job has a [Bridge Task](/chainlink-nodes/oracle-jobs/task-types/task_bridge/), the node searches for a bridge by name and uses that bridge as your external adapter. Bridge names are case insensitive.
To create a bridge on the node, go to the **Create Bridge** tab in the Node Operators Interface. Specify a name for the bridge, the URL for your external adapter, and optionally specify the minimum contract payment and number of confirmations for the bridge. Minimum contract payment is a fee paid in LINK for the Chainlink node making a call to the external adapter via the bridge. This fee is in addition to the fee specified at the global node level for processing job requests.
@@ -13,9 +14,10 @@ To create a bridge on the node, go to the **Create Bridge** tab in the Node Oper
The bridge name must be unique to the local node. The bridge URL is the URL of your external adapter, which can be local or on a separate machine.
-To add jobs that use the bridge, add a [Bridge Task](/docs/jobs/task-types/bridge/) to your job. The `bridge` task defined in the example below is defined as `fetch` and the name of the bridge is `soccer-data`.
+To add jobs that use the bridge, add a [Bridge Task](/chainlink-nodes/oracle-jobs/task-types/task_bridge/) to your job. The `bridge` task defined in the example below is defined as `fetch` and the name of the bridge is `soccer-data`.
-```jpv2
+
+```toml
type = "directrequest"
schemaVersion = 1
name = "Soccer-Data-EA"
@@ -45,19 +47,25 @@ Since `soccer-data` is a bridge task, each node that has this job defined needs
## Testing External Adapters and Bridges
-The easiest way to test if your external adapter is working is to use a [Webhook Job](/docs/jobs/types/webhook/).
+The easiest way to test if your external adapter is working is to use a [Webhook Job](/chainlink-nodes/oracle-jobs/job-types/webhook/).
As an example, assume you have an external adapter named `soccer-data` that is registered in the `bridges` section and it takes one parameter named `playerId`. In solidity, you would pass the parameter with the following request:
+
+
```solidity
request.add("playerId","12345678")
```
+
How can you test the adapter on your node?
-The easiest way is to setup a [Webhook Job](/docs/jobs/types/webhook/) that uses the external adapter, and manually set the parameter.
+The easiest way is to setup a [Webhook Job](/chainlink-nodes/oracle-jobs/job-types/webhook/) that uses the external adapter, and manually set the parameter.
-> Note: You might need to set the [configuration variable](/docs/configuration-variables/) `FEATURE_WEBHOOK_V2=true` in your `.env` file.
+:::note
+You might need to set the [configuration variable](/chainlink-nodes/configuration-variables/) `FEATURE_WEBHOOK_V2=true` in your `.env` file.
+:::
-```jpv2
+
+```toml
type = "webhook"
schemaVersion = 1
name = "Soccer-Data-EA-Web"
@@ -70,11 +78,11 @@ fetch [type=bridge name="soccer-data" requestData="{\\"id\\": \\"0\\", \\
Adding the following into the TOML spec manually sets the parameters passed into the bridge task. It is equivalent to using `request.add` as shown above or adding the data with the `--d` flag if you're using [curl](https://curl.se/).
+
```json
requestData="{\\"id\\": \\"0\\", \\"data\\": { \\"playerId\\": \\"12345678\\"}}"
```
-
There will be a big `Run` button on your job definition, which you can use to kick off the job.
-
\ No newline at end of file
+
diff --git a/docs/chainlink-nodes/external-initiators/building-external-initiators.md b/src/pages/chainlink-nodes/external-initiators/building-external-initiators.md
similarity index 80%
rename from docs/chainlink-nodes/external-initiators/building-external-initiators.md
rename to src/pages/chainlink-nodes/external-initiators/building-external-initiators.md
index 82fde74da27..62110369f18 100644
--- a/docs/chainlink-nodes/external-initiators/building-external-initiators.md
+++ b/src/pages/chainlink-nodes/external-initiators/building-external-initiators.md
@@ -1,10 +1,11 @@
---
-layout: nodes.liquid
+layout: ../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Building External Initiators"
permalink: "docs/building-external-initiators/"
-whatsnext: {"Adding External Initiators to Nodes":"/docs/external-initiators-in-nodes/"}
+whatsnext:
+ { "Adding External Initiators to Nodes": "/chainlink-nodes/external-initiators/external-initiators-in-nodes/" }
---
An external initiator can trigger a run for any webhook job that it has been linked to.
@@ -22,10 +23,10 @@ You will need to specify two headers:
## JSON jobs (REMOVED)
-> ❗️ v1 Jobs are removed
-> The initiators for v1 Jobs are removed for Chainlink nodes running version 1.0.0 and later. Use [v2 jobs](/docs/jobs) instead.
->
-> See the [v2 jobs migration page](/docs/jobs/migration-v1-v2) to learn how to migrate to v2 jobs.
+:::caution[v1 Jobs are removed]
+The initiators for v1 Jobs are removed for Chainlink nodes running version 1.0.0 and later. Use [v2 job types](/chainlink-nodes/oracle-jobs/jobs) instead.
+See the [v2 jobs migration page](/chainlink-nodes/oracle-jobs/migration-v1-v2) to learn how to migrate to v2 jobs.
+:::
We will be using the Chainlink external initiator repo for reference. You can see some examples of existing initiators in the blockchain folder.
diff --git a/docs/chainlink-nodes/external-initiators/external-initiators-in-nodes.md b/src/pages/chainlink-nodes/external-initiators/external-initiators-in-nodes.md
similarity index 83%
rename from docs/chainlink-nodes/external-initiators/external-initiators-in-nodes.md
rename to src/pages/chainlink-nodes/external-initiators/external-initiators-in-nodes.md
index 3aaca9d253b..0bfc86f1a29 100644
--- a/docs/chainlink-nodes/external-initiators/external-initiators-in-nodes.md
+++ b/src/pages/chainlink-nodes/external-initiators/external-initiators-in-nodes.md
@@ -1,23 +1,27 @@
---
-layout: nodes.liquid
+layout: ../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Adding External Initiators to Nodes"
permalink: "docs/external-initiators-in-nodes/"
---
-> 🚧 External initiators are disabled on nodes by default. Set the `FEATURE_EXTERNAL_INITIATORS=true` [configuration variable](/docs/configuration-variables/#feature_external_initiators) to enable this feature.
+:::note
+External initiators are disabled on nodes by default. Set the `FEATURE_EXTERNAL_INITIATORS=true` [configuration variable](/chainlink-nodes/configuration-variables/#feature_external_initiators) to enable this feature.
+:::
## Creating an external initiator
To create an external initiator you must use the remote API. You can do this yourself, like so:
+
```text
POST http:///v2/external_initiators -d
```
where payload is a JSON blob that contains:
+
```json
{
"name": ,
@@ -29,20 +33,23 @@ If a URL is provided, Chainlink will notify this URL of added and deleted jobs t
On creation:
+
```text
POST -d {"jobId": , "type": , "params": }
```
On deletion:
+
```text
DELETE /
```
You can use the chainlink client for convenience to access this API.
-Enter the [Chainlink nodes CLI](/docs/miscellaneous/#execute-commands-running-docker) and run the following command
+Enter the [Chainlink nodes CLI](/chainlink-nodes/miscellaneous/#execute-commands-running-docker) and run the following command
+
```shell
chainlink initiators create
```
@@ -83,7 +90,9 @@ To try a real-life example, feel free to follow along with the Additional external initiator reference
-> 🚧 The External Initiator can only initiate [webhook jobs](/docs/jobs/types/webhook) that have been linked to it. Trying to initiate a job that is not linked will give an unauthorised error.
+:::note
+The External Initiator can only initiate [webhook jobs](/chainlink-nodes/oracle-jobs/job-types/webhook) that have been linked to it. Trying to initiate a job that is not linked will give an unauthorised error.
+:::
## Deleting an external initiator
diff --git a/docs/chainlink-nodes/external-initiators/external-initiators-introduction.md b/src/pages/chainlink-nodes/external-initiators/external-initiators-introduction.md
similarity index 59%
rename from docs/chainlink-nodes/external-initiators/external-initiators-introduction.md
rename to src/pages/chainlink-nodes/external-initiators/external-initiators-introduction.md
index 34f3a82b81f..61bee730620 100644
--- a/docs/chainlink-nodes/external-initiators/external-initiators-introduction.md
+++ b/src/pages/chainlink-nodes/external-initiators/external-initiators-introduction.md
@@ -1,21 +1,29 @@
---
-layout: nodes.liquid
+layout: ../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Introduction"
permalink: "docs/external-initiators-introduction/"
-whatsnext: {"Building External Initiators":"/docs/building-external-initiators/", "Adding External Initiators to Nodes":"/docs/external-initiators-in-nodes/"}
+whatsnext:
+ {
+ "Building External Initiators": "/chainlink-nodes/external-initiators/building-external-initiators/",
+ "Adding External Initiators to Nodes": "/chainlink-nodes/external-initiators/external-initiators-in-nodes/",
+ }
---
External initiators allow jobs in a node to be initiated depending on some external condition. The ability to create and add external initiators to Chainlink nodes enables blockchain agnostic cross-chain compatibility.
-> 🚧 At this time of writing, external initiators do not show up in the bridges tab. However, they act exactly the same as if they did.
+:::note
+At this time of writing, external initiators do not show up in the bridges tab. However, they act exactly the same as if they did.
+:::
-> 🚧 External initiators are disabled on nodes by default. Set the `FEATURE_EXTERNAL_INITIATORS=true` [configuration variable](/docs/configuration-variables/#feature_external_initiators) to enable this feature.
+:::note
+External initiators are disabled on nodes by default. Set the `FEATURE_EXTERNAL_INITIATORS=true` [configuration variable](/chainlink-nodes/configuration-variables/#feature_external_initiators) to enable this feature.
+:::
Initiator Bridges handle the authentication to and from the External Initiator and where to send the messages. When creating a Bridge two parameters are required:
-Only the [webhook](/docs/jobs/types/webhook/) job type can be initiated using an External Initiator.
+Only the [webhook](/chainlink-nodes/oracle-jobs/job-types/webhook/) job type can be initiated using an External Initiator.
The external initiator must be created before the webhook job, and must be referenced by name (whitelisted) in order for that external initiator to be allowed to trigger the given webhook job.
@@ -23,4 +31,4 @@ When the External Initiator is created it generates two pairs of credentials: Ou
Then, once you've created the name, bridge, and have the correct access keys for the URL, you can proceed to use the external initiator as if it's a regular initiator in future job specs.
-For how to create an external initiator see [adding external initiators to nodes](/docs/external-initiators-in-nodes).
+For how to create an external initiator see [adding external initiators to nodes](/chainlink-nodes/external-initiators/external-initiators-in-nodes).
diff --git a/docs/chainlink-nodes/fulfilling-requests.md b/src/pages/chainlink-nodes/fulfilling-requests.md
similarity index 67%
rename from docs/chainlink-nodes/fulfilling-requests.md
rename to src/pages/chainlink-nodes/fulfilling-requests.md
index 4dcfa3daf04..d0ac113e78b 100644
--- a/docs/chainlink-nodes/fulfilling-requests.md
+++ b/src/pages/chainlink-nodes/fulfilling-requests.md
@@ -1,34 +1,36 @@
---
-layout: nodes.liquid
+layout: ../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
-title: 'Fulfilling Requests'
-permalink: 'docs/fulfilling-requests/'
+title: "Fulfilling Requests"
+permalink: "docs/fulfilling-requests/"
whatsnext:
{
- 'Performing System Maintenance': '/docs/performing-system-maintenance/',
- 'v2 Jobs': '/docs/jobs/',
- 'Security and Operation Best Practices': '/docs/best-security-practices/',
+ "Performing System Maintenance": "/chainlink-nodes/performing-system-maintenance/",
+ "v2 Jobs": "/chainlink-nodes/oracle-jobs/jobs/",
+ "Security and Operation Best Practices": "/chainlink-nodes/best-security-practices/",
}
metadata:
- title: 'Chainlink Node Operators: Fulfilling Requests'
- description: 'Deploy your own Oracle contract and add jobs to your node so that it can provide data to smart contracts.'
+ title: "Chainlink Node Operators: Fulfilling Requests"
+ description: "Deploy your own Oracle contract and add jobs to your node so that it can provide data to smart contracts."
+setup: |
+ import CodeSample from "@components/CodeSample/CodeSample.astro"
---
With your own Oracle contract, you can use your own node to fulfill requests. This guide will show you how to deploy your own Oracle contract and add jobs to your node so that it can provide data to smart contracts.
-Chainlink nodes can fulfill requests from open or unauthenticated APIs without the need for [External Adapters](../external-adapters/) as long as you've [added the jobs](#add-a-job-to-the-node) to the node. For these requests, requesters supply the URL to the open API that they want each node to retrieve. The Chainlink node will use [tasks](/docs/tasks/) to fulfill the request.
+Chainlink nodes can fulfill requests from open or unauthenticated APIs without the need for [External Adapters](/chainlink-nodes/external-adapters/external-adapters/) as long as you've [added the jobs](#add-a-job-to-the-node) to the node. For these requests, requesters supply the URL to the open API that they want each node to retrieve. The Chainlink node will use [tasks](/chainlink-nodes/oracle-jobs/task-types/tasks/) to fulfill the request.
-Some APIs require authentication by providing request headers for the operator's API key, which the Chainlink node supports. If you would like to provide access to an API that requires authentication, you must create a job that is specific for that API either using an external adapter or by using the parameters of the [HTTP task](/docs/jobs/task-types/http/).
+Some APIs require authentication by providing request headers for the operator's API key, which the Chainlink node supports. If you would like to provide access to an API that requires authentication, you must create a job that is specific for that API either using an external adapter or by using the parameters of the [HTTP task](/chainlink-nodes/oracle-jobs/task-types/task_http).
## Requirements
Before you begin this guide, complete the following tasks to make sure you have all of the tools that you need:
-- [Set up MetaMask](/docs/deploy-your-first-contract/#install-and-fund-your-metamask-wallet) and [obtain testnet LINK](/docs/acquire-link/).
-- Configure an Ethereum client with an active websocket connection. Either [Run an Ethereum Client](../run-an-ethereum-client/) yourself or use an [External Service](../run-an-ethereum-client/#external-services) that your Chainlink Node can access.
-- [Run a Chainlink Node](../running-a-chainlink-node/) and connect it to a [supported database](../connecting-to-a-remote-database/).
-- Fund the Ethereum address that your Chainlink node uses. You can find the address in the node Operator GUI under the **Keys** tab. The address of the node is the `Regular` type. You can obtain test ETH from several [faucets](../link-token-contracts/).
+- [Set up MetaMask](/getting-started/deploy-your-first-contract/#install-and-fund-your-metamask-wallet) and [obtain testnet LINK](/resources/acquire-link/).
+- Configure an Ethereum client with an active websocket connection. Either [Run an Ethereum Client](/chainlink-nodes/run-an-ethereum-client/) yourself or use an [External Service](/chainlink-nodes/run-an-ethereum-client/#external-services) that your Chainlink Node can access.
+- [Run a Chainlink Node](/chainlink-nodes/running-a-chainlink-node/) and connect it to a [supported database](/chainlink-nodes/connecting-to-a-remote-database/).
+- Fund the Ethereum address that your Chainlink node uses. You can find the address in the node Operator GUI under the **Keys** tab. The address of the node is the `Regular` type. You can obtain test ETH from several [faucets](/resources/link-token-contracts/).
## Address Types
@@ -40,7 +42,7 @@ Your node works with several different types of addresses. Each address type has
## Deploy your own Oracle contract
-1. Go to Remix and [open the `Oracle.sol` smart contract](https://remix.ethereum.org/#url=https://docs.chain.link/samples/NodeOperators/Oracle.sol). The contents of this file will be very minimal.
+1. Go to Remix and [open the `Oracle.sol` smart contract](https://remix.ethereum.org/#url=https://docs.chain.link/samples/ChainlinkNodes/Oracle.sol). The contents of this file will be very minimal.
1. On the **Compile** tab, click the **Compile** button for `Oracle.sol`. Remix automatically selects the compiler version and language from the `pragma` line unless you select a specific version manually.
@@ -48,11 +50,12 @@ Your node works with several different types of addresses. Each address type has
- Select "Injected Provider" as your **Environment**. The Javascript VM environment cannot access your oracle node.
- Select the "Oracle" contract from the **Contract** menu.
- - Copy the [LINK token contract address](/docs/link-token-contracts/) for the network you are using and paste it into the `address_link` field next to the **Deploy** button. Use one of the following network addresses:
+ - Copy the [LINK token contract address](/resources/link-token-contracts/) for the network you are using and paste it into the `address_link` field next to the **Deploy** button. Use one of the following network addresses:
```text Goerli
0x326C977E6efc84E512bB9C30f76E30c160eD06FB
```
+
```text Mainnet
0x514910771AF9Ca656af840dff83E8264EcF986CA
```
@@ -61,11 +64,10 @@ Your node works with several different types of addresses. Each address type has
1. Click **Deploy**. MetaMask prompts you to confirm the transaction.
- > 🚧 MetaMask doesn't pop up?
- >
- > If MetaMask does not prompt you and instead displays the error below, disable "Privacy Mode" in MetaMask. You can do this by clicking on your unique account icon at the top-right, then go to the Settings. Privacy Mode will be a switch near the bottom.
- >
- > Error: **Send transaction failed: Invalid address. If you use an injected provider, please check it is properly unlocked.**
+ :::note[MetaMask doesn't pop up?]
+ If MetaMask does not prompt you and instead displays the error below, disable "Privacy Mode" in MetaMask. You can do this by clicking on your unique account icon at the top-right, then go to the Settings. Privacy Mode will be a switch near the bottom.
+ Error: **Send transaction failed: Invalid address. If you use an injected provider, please check it is properly unlocked.**
+ :::
1. After you deploy the contract, a link to Etherscan displays at the bottom. Open that link in a new tab to keep track of the transaction.
@@ -82,7 +84,7 @@ Your node works with several different types of addresses. Each address type has
Find the address for your Chainlink node and add it to the Oracle contract.
1. In the Chainlink Operator GUI for your node, find and copy the address at the bottom of the **Keys** page in the Account addresses section.
- 
+ 
1. In Remix, call the `setFulfillmentPermission` function with the address of your node, a comma, and the value `true`, as the input parameters. This allows your node to fulfill requests to your oracle contract.
@@ -92,25 +94,24 @@ Find the address for your Chainlink node and add it to the Oracle contract.
## Add a job to the node
-You can add jobs to your Chainlink node in the Chainlink Operator GUI. The [ATestnetConsumer.sol](https://github.com/smartcontractkit/documentation/blob/main/_includes/samples/APIRequests/ATestnetConsumer.sol) consumer contract expects the price value in `Uint256`. Use the following [Job](../jobs/) example:
+You can add jobs to your Chainlink node in the Chainlink Operator GUI. The [ATestnetConsumer.sol](https://remix.ethereum.org/#url=https://docs.chain.link/samples/APIRequests/ATestnetConsumer.sol) consumer contract expects the price value in `Uint256`. Use the following [Job](/chainlink-nodes/oracle-jobs/jobs/) example:
-```jpv2 Uint256
-{% include 'samples/NodeOperators/jobs/get-uint256.toml' %}
-```
+
+
1. In the Chainlink Operator GUI on the **Jobs** tab, click **New Job**.
- 
+ 
1. Paste the job specification from above into the text field.
- 
+ 
1. Replace `YOUR_ORACLE_CONTRACT_ADDRESS` with the address of your deployed oracle contract address from the previous steps. Replace `YOUR_ORACLE_CONTRACT_ADDRESS` for both the attribute `contractAddress` and also attribute `to` for the `submit_tx` step in the `observationSource` part of the job specification. This address not the same as the `ACCOUNT_ADDRESS` from your Chainlink node.
1. Click **Create Job**. If the node creates the job successfully, a notice with the job number appears.
- 
+ 
1. Click the job number to view the job details. You can also find the job listed on the **Jobs** tab in the Node Operators UI.
@@ -118,13 +119,15 @@ You can add jobs to your Chainlink node in the Chainlink Operator GUI. The [ATes
## Create a request to your node
-> 📘 If you're going through this guide on Ethereum mainnet, the `ATestnetConsumer.sol` contract will still work. However, understand that you're sending real LINK to yourself. **Be sure to practice on the test networks multiple times before attempting to run a node on mainnet.**
+:::caution[Practice on testnets!]
+If you're going through this guide on Ethereum mainnet, the `ATestnetConsumer.sol` contract will still work. However, understand that you're sending real LINK to yourself. **Be sure to practice on the test networks multiple times before attempting to run a node on mainnet.**
+:::
After you add jobs to your node, you can use the node to fulfill requests. This section shows what a requester does when they send requests to your node. It is also a way to test and make sure that your node is functioning correctly.
1. Open [ATestnetConsumer.sol in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/APIRequests/ATestnetConsumer.sol).
-1. Note that `setChainlinkToken(0x326C977E6efc84E512bB9C30f76E30c160eD06FB)` is configured for _Goerli_. Fetch the Link token address for the network you are deploying into from the [Link token contracts page](/docs/link-token-contracts).
+1. Note that `setChainlinkToken(0x326C977E6efc84E512bB9C30f76E30c160eD06FB)` is configured for _Goerli_. Fetch the Link token address for the network you are deploying into from the [Link token contracts page](/resources/link-token-contracts/).
1. On the **Compiler** tab, click the **Compile** button for `ATestnetConsumer.sol`.
@@ -137,11 +140,11 @@ After you add jobs to your node, you can use the node to fulfill requests. This
1. Ensure that your Chainlink Node is sufficiently funded with ETH to execute the callbacks to your oracle contract.
-1. Fund the contract by sending LINK to the contract's address. See the [Fund your contract](../fund-your-contract/) page for instructions. The address for the `ATestnetConsumer` contract is on the list of your deployed contracts in Remix.
+1. Fund the contract by sending LINK to the contract's address. See the [Fund your contract](/resources/fund-your-contract/) page for instructions. The address for the `ATestnetConsumer` contract is on the list of your deployed contracts in Remix.
1. After you fund the contract, create a request. Input your oracle contract address and the job ID for the `Get > Uint256` job into the `requestEthereumPrice` request method **without dashes**. The job ID is the `externalJobID` parameter, which you can find on your job's definition page in the Node Operators UI.
- 
+ 
1. Click the **transact** button for the `requestEthereumPrice` function and approve the transaction in Metamask. The `requestEthereumPrice` function asks the node to retrieve `uint256` data specifically from [https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD](https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD).
@@ -153,11 +156,10 @@ After you add jobs to your node, you can use the node to fulfill requests. This
## Retrieving other types of data
-Now that you have a working consumer contract, you can use that same `ATestnetConsumer` contract to obtain other types of data. The [ATestnetConsumer.sol](https://github.com/smartcontractkit/documentation/blob/main/_includes/samples/APIRequests/ATestnetConsumer.sol) consumer contract has a `requestEthereumLastMarket` function that requests more detailed data from [https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD](https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD). Returning this type of data requires another job.
+Now that you have a working consumer contract, you can use that same `ATestnetConsumer` contract to obtain other types of data. The [ATestnetConsumer.sol](https://remix.ethereum.org/#url=https://docs.chain.link/samples/APIRequests/ATestnetConsumer.sol) consumer contract has a `requestEthereumLastMarket` function that requests more detailed data from [https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD](https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD). Returning this type of data requires another job.
-```jpv2 Bytes32
-{% include 'samples/NodeOperators/jobs/get-bytes32.toml' %}
-```
+
+
1. Add the `Get > Bytes32` job to your node like you did for the first job.
@@ -165,7 +167,7 @@ Now that you have a working consumer contract, you can use that same `ATestnetCo
1. Input your oracle contract address and the job ID for the `Get > Bytes32` job into the `requestEthereumLastMarket` request method **without dashes**.
- 
+ 
1. Click the **transact** button for the `requestEthereumLastMarket` function and approve the transaction in Metamask.
@@ -173,9 +175,9 @@ Now that you have a working consumer contract, you can use that same `ATestnetCo
1. In Remix, click the `lastMarket` variable. The value is in bytes that you can convert to a string outside of the smart contract later.
- 
+ 
-Jobs can do more than just retrieve data and put it on chain. You can write your own jobs to accomplish various tasks. See the [v2 Jobs](/docs/jobs/) page to learn more.
+Jobs can do more than just retrieve data and put it on chain. You can write your own jobs to accomplish various tasks. See the [v2 Jobs](/chainlink-nodes/oracle-jobs/jobs/) page to learn more.
## Withdrawing LINK
diff --git a/docs/chainlink-nodes/job-specs/direct-request-existing-job.md b/src/pages/chainlink-nodes/job-specs/direct-request-existing-job.md
similarity index 83%
rename from docs/chainlink-nodes/job-specs/direct-request-existing-job.md
rename to src/pages/chainlink-nodes/job-specs/direct-request-existing-job.md
index a7cc0a929f8..3b3f0ece4bd 100644
--- a/docs/chainlink-nodes/job-specs/direct-request-existing-job.md
+++ b/src/pages/chainlink-nodes/job-specs/direct-request-existing-job.md
@@ -1,19 +1,19 @@
---
-layout: nodes.liquid
+layout: ../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
-title: 'Existing Job Example specs'
-permalink: 'docs/direct-request-existing-job/'
+title: "Existing Job Example specs"
+permalink: "docs/direct-request-existing-job/"
---
This is an example v2 (TOML) job spec for returning gas price using [etherscan](https://docs.etherscan.io/api-endpoints/gas-tracker#get-gas-oracle) in one Chainlink API Call. Note that the job :
-- Uses an [external adapter](/docs/external-adapters/) to consume the etherscan API: [EtherScan External Adapter](https://github.com/smartcontractkit/external-adapters-js/tree/develop/packages/sources/etherscan). Note that this is done using the [bridge](/docs/jobs/task-types/bridge/) task: `type="bridge" name="etherscan"`.
+- Uses an [external adapter](/chainlink-nodes/external-adapters/external-adapters/) to consume the etherscan API: [EtherScan External Adapter](https://github.com/smartcontractkit/external-adapters-js/tree/develop/packages/sources/etherscan). Note that this is done using the [bridge](/chainlink-nodes/oracle-jobs/task-types/task_bridge/) task: `type="bridge" name="etherscan"`.
- Calls the `fulfillOracleRequest2` function. If you are a node operator, use an [Operator contract](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.7/Operator.sol) with this job.
-To test this job spec from a smart contract, see this [Example](/docs/any-api/get-request/examples/existing-job-request/).
+To test this job spec from a smart contract, see this [Example](/any-api/get-request/examples/existing-job-request/).
-```jpv2
+```toml
type = "directrequest"
schemaVersion = 1
name = "Etherscan gas price"
diff --git a/docs/chainlink-nodes/job-specs/direct-request-get-bool.md b/src/pages/chainlink-nodes/job-specs/direct-request-get-bool.md
similarity index 94%
rename from docs/chainlink-nodes/job-specs/direct-request-get-bool.md
rename to src/pages/chainlink-nodes/job-specs/direct-request-get-bool.md
index 4ebbc5e8d3d..c7f4f860d14 100644
--- a/docs/chainlink-nodes/job-specs/direct-request-get-bool.md
+++ b/src/pages/chainlink-nodes/job-specs/direct-request-get-bool.md
@@ -1,14 +1,14 @@
---
-layout: nodes.liquid
+layout: ../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
-title: 'GET > Bool Example Job Spec'
-permalink: 'docs/direct-request-get-bool/'
+title: "GET > Bool Example Job Spec"
+permalink: "docs/direct-request-get-bool/"
---
This is an example v2 (TOML) job spec for calling any public API, parsing the result then returning a _bool_ in one Chainlink API Call. Note that the job calls the `fulfillOracleRequest2` function. If you are a node operator, use an [Operator contract](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.7/Operator.sol) with this job.
-```jpv2
+```toml
type = "directrequest"
schemaVersion = 1
name = "Get > Bool - (TOML)"
diff --git a/docs/chainlink-nodes/job-specs/direct-request-get-bytes.md b/src/pages/chainlink-nodes/job-specs/direct-request-get-bytes.md
similarity index 92%
rename from docs/chainlink-nodes/job-specs/direct-request-get-bytes.md
rename to src/pages/chainlink-nodes/job-specs/direct-request-get-bytes.md
index 702a4ca45e3..d421810a705 100644
--- a/docs/chainlink-nodes/job-specs/direct-request-get-bytes.md
+++ b/src/pages/chainlink-nodes/job-specs/direct-request-get-bytes.md
@@ -1,15 +1,15 @@
---
-layout: nodes.liquid
+layout: ../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
-title: 'GET > Bytes Example Job Spec'
-permalink: 'docs/direct-request-get-bytes/'
+title: "GET > Bytes Example Job Spec"
+permalink: "docs/direct-request-get-bytes/"
---
This is an example v2 (TOML) job spec for returning _bytes_ in one Chainlink API Call. Note that the job calls the `fulfillOracleRequest2` function. If you are a node operator, use an [Operator contract](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.7/Operator.sol) with this job.
-To test it from a smart contract, see this [Example](/docs/any-api/get-request/examples/large-responses/).
+To test it from a smart contract, see this [Example](/any-api/get-request/examples/large-responses/).
-```jpv2
+```toml
type = "directrequest"
schemaVersion = 1
name = "Get > Bytes"
diff --git a/docs/chainlink-nodes/job-specs/direct-request-get-int256.md b/src/pages/chainlink-nodes/job-specs/direct-request-get-int256.md
similarity index 94%
rename from docs/chainlink-nodes/job-specs/direct-request-get-int256.md
rename to src/pages/chainlink-nodes/job-specs/direct-request-get-int256.md
index ffac1ef77a1..b642b5f031c 100644
--- a/docs/chainlink-nodes/job-specs/direct-request-get-int256.md
+++ b/src/pages/chainlink-nodes/job-specs/direct-request-get-int256.md
@@ -1,14 +1,14 @@
---
-layout: nodes.liquid
+layout: ../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
-title: 'GET > Int256 Example Job Spec'
-permalink: 'docs/direct-request-get-int256/'
+title: "GET > Int256 Example Job Spec"
+permalink: "docs/direct-request-get-int256/"
---
This is an example v2 (TOML) job spec for calling any public API, retrieving a number , removing its decimals then returning _int256_ in one Chainlink API Call. Note that the job calls the `fulfillOracleRequest2` function. If you are a node operator, use an [Operator contract](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.7/Operator.sol) with this job.
-```jpv2
+```toml
type = "directrequest"
schemaVersion = 1
name = "Get > Int256 - (TOML)"
diff --git a/src/pages/chainlink-nodes/job-specs/direct-request-get-string.md b/src/pages/chainlink-nodes/job-specs/direct-request-get-string.md
new file mode 100644
index 00000000000..d0806ba8262
--- /dev/null
+++ b/src/pages/chainlink-nodes/job-specs/direct-request-get-string.md
@@ -0,0 +1,15 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: nodeOperator
+date: Last Modified
+title: "GET > String Example Job Spec"
+permalink: "docs/direct-request-get-string/"
+setup: |
+ import CodeSample from "@components/CodeSample/CodeSample.astro"
+---
+
+This is an example v2 (TOML) job spec for returning a _string_ in one Chainlink API Call. Note that the job calls the `fulfillOracleRequest2` function. If you are a node operator, use an [Operator contract](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.7/Operator.sol) with this job.
+To test it from a smart contract, see this [Example](/any-api/get-request/examples/array-response/).
+
+
+
diff --git a/docs/chainlink-nodes/job-specs/direct-request-get-uint256.md b/src/pages/chainlink-nodes/job-specs/direct-request-get-uint256.md
similarity index 90%
rename from docs/chainlink-nodes/job-specs/direct-request-get-uint256.md
rename to src/pages/chainlink-nodes/job-specs/direct-request-get-uint256.md
index dce3e230d79..9618d316eaa 100644
--- a/docs/chainlink-nodes/job-specs/direct-request-get-uint256.md
+++ b/src/pages/chainlink-nodes/job-specs/direct-request-get-uint256.md
@@ -1,15 +1,15 @@
---
-layout: nodes.liquid
+layout: ../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
-title: 'GET > Uint256 Example Job Spec'
-permalink: 'docs/direct-request-get-uint256/'
+title: "GET > Uint256 Example Job Spec"
+permalink: "docs/direct-request-get-uint256/"
---
This is an example v2 (TOML) job spec for calling any public API, retrieving a number , removing its decimals then returning _uint256_ in one Chainlink API Call. Note that the job calls the `fulfillOracleRequest2` function. If you are a node operator, use an [Operator contract](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.7/Operator.sol) with this job.
-To test it from a smart contract, see this [Example](/docs/any-api/get-request/examples/single-word-response/).
+To test it from a smart contract, see this [Example](/any-api/get-request/examples/single-word-response/).
-```jpv2
+```toml
type = "directrequest"
schemaVersion = 1
name = "Get > Uint256 - (TOML)"
diff --git a/docs/chainlink-nodes/job-specs/multi-word-job.md b/src/pages/chainlink-nodes/job-specs/multi-word-job.md
similarity index 92%
rename from docs/chainlink-nodes/job-specs/multi-word-job.md
rename to src/pages/chainlink-nodes/job-specs/multi-word-job.md
index cc69f9a1b89..e6f1c3a0c36 100644
--- a/docs/chainlink-nodes/job-specs/multi-word-job.md
+++ b/src/pages/chainlink-nodes/job-specs/multi-word-job.md
@@ -1,15 +1,15 @@
---
-layout: nodes.liquid
+layout: ../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
-title: 'MultiWord Example Job Spec'
-permalink: 'docs/direct-request-multi-word/'
+title: "MultiWord Example Job Spec"
+permalink: "docs/direct-request-multi-word/"
---
This is an example v2(TOML) job spec for returning multiple responses in 1 Chainlink API Call.Note that the job calls the `fulfillOracleRequest2` function. If you are a node operator, use an [Operator contract](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.7/Operator.sol) with this job.
-To test it from a smart contract, see this [Example](/docs/any-api/get-request/examples/multi-variable-responses/).
+To test it from a smart contract, see this [Example](/any-api/get-request/examples/multi-variable-responses/).
-```jpv2
+```toml
type = "directrequest"
schemaVersion = 1
name = "multi-word (TOML)"
diff --git a/docs/chainlink-nodes/miscellaneous.md b/src/pages/chainlink-nodes/miscellaneous.md
similarity index 58%
rename from docs/chainlink-nodes/miscellaneous.md
rename to src/pages/chainlink-nodes/miscellaneous.md
index 81d67607297..2bf535c620d 100644
--- a/docs/chainlink-nodes/miscellaneous.md
+++ b/src/pages/chainlink-nodes/miscellaneous.md
@@ -1,11 +1,12 @@
---
-layout: nodes.liquid
+layout: ../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Miscellaneous"
permalink: "docs/miscellaneous/"
-whatsnext: {"Security and Operation Best Practices":"/docs/best-security-practices/"}
+whatsnext: { "Security and Operation Best Practices": "/chainlink-nodes/best-security-practices/" }
---
+
## Execute Commands Running Docker
In order to interact with the node's CLI commands, you need to be authenticated. This means that you need to access a shell within the Chainlink node's running container first. You can obtain the running container's `NAME` by running:
@@ -56,7 +57,9 @@ If no jobs have been added, you will receive the following output, otherwise, th
## Transfer funds from node wallet.
-> 🚧 If using Docker, you will first need to follow the [Execute Commands Running Docker](#execute-commands-running-docker) guide to enter the running container.
+:::note[Note for Docker]
+If using Docker, you will first need to follow the [Execute Commands Running Docker](#execute-commands-running-docker) guide to enter the running container.
+:::
To transfer funds from the node wallet to another address, use the following CLI command:
@@ -68,7 +71,9 @@ This method is the preferred way to interact with your node wallet. Using other
## Change your API password
-> 🚧 If using Docker, you will first need to follow the [Execute Commands Running Docker](#execute-commands-running-docker) guide to enter the running container.
+:::note[Note for Docker]
+If using Docker, you will first need to follow the [Execute Commands Running Docker](#execute-commands-running-docker) guide to enter the running container.
+:::
In order to change your password, you first need to log into the CLI by running:
@@ -88,7 +93,6 @@ It will ask for your old password first, then ask for the new password and a con
Once complete, you should see a message "Password updated."
-
## Multi-user and Role Based Access Control (RBAC)
Chainlink Nodes allow the root admin CLI user and any additional admin users to create and assign tiers of role-based access to new users. These new API users can able to log in to the Operator UI independently.
@@ -105,61 +109,61 @@ chainlink admin users create --email=operator-ui-read-only@test.com --role=view
Specific actions are enabled to check role-based access before they execute. The following table lists the actions that have role-based access and the role that is required to run that action:
-| Action | Read | Run | Edit | Admin |
-|:--- | :---: | :---: | :---: | :---: |
-| Update password | X | X | X | X |
-| Create self API token | X | X | X | X |
-| Delete self API token | X | X | X | X |
-| List external initiators | X | X | X | X |
-| Create external initiator | | | X | X |
-| Delete external initiator | | | X | X |
-| List bridges | X | X | X | X |
-| View bridge | X | X | X | X |
-| Create bridge | | | X | X |
-| Edit bridge | | | X | X |
-| Delete bridge | | | X | X |
-| View config | X | X | X | X |
-| Update config | | | | X |
-| Dump env/config | | | | X |
-| View transaction attempts | X | X | X | X |
-| View transaction attempts EVM | X | X | X | X |
-| View transactions | X | X | X | X |
-| Replay a specific block number | | X | X | X |
-| List keys (CSA,ETH,OCR(2),P2P,Solana,Terra) | X | X | X | X |
-| Create keys (CSA,ETH,OCR(2),P2P,Solana,Terra) | | | X | X |
-| Delete keys (CSA,ETH,OCR(2),P2P,Solana,Terra) | | | | X |
-| Import keys (CSA,ETH,OCR(2),P2P,Solana,Terra) | | | | X |
-| Export keys (CSA,ETH,OCR(2),P2P,Solana,Terra) | | | | X |
-| List jobs | X | X | X | X |
-| View job | X | X | X | X |
-| Create job | | | X | X |
-| Delete job | | | X | X |
-| List pipeline runs | X | X | X | X |
-| View job runs | X | X | X | X |
-| Delete job spec errors | | | X | X |
-| View features | X | X | X | X |
-| View log | X | X | X | X |
-| Update log | | | | X |
-| List chains | X | X | X | X |
-| View chain | X | X | X | X |
-| Create chain | | | X | X |
-| Update chain | | | X | X |
-| Delete chain | | | X | X |
-| View nodes | X | X | X | X |
-| Create node | | | X | X |
-| Update node | | | X | X |
-| Delete node | | | X | X |
-| View forwarders | X | X | X | X |
-| Create forwarder | | | X | X |
-| Delete forwarder | | | X | X |
-| Create job run | | X | X | X |
-| Create Transfer EVM | | | | X |
-| Create Transfer Terra | | | | X |
-| Create Transfer Solana | | | | X |
-| Create user | | | | X |
-| Delete user | | | | X |
-| Edit user | | | | X |
-| List users | | | | X |
+| Action | Read | Run | Edit | Admin |
+| :-------------------------------------------- | :--: | :-: | :--: | :---: |
+| Update password | X | X | X | X |
+| Create self API token | X | X | X | X |
+| Delete self API token | X | X | X | X |
+| List external initiators | X | X | X | X |
+| Create external initiator | | | X | X |
+| Delete external initiator | | | X | X |
+| List bridges | X | X | X | X |
+| View bridge | X | X | X | X |
+| Create bridge | | | X | X |
+| Edit bridge | | | X | X |
+| Delete bridge | | | X | X |
+| View config | X | X | X | X |
+| Update config | | | | X |
+| Dump env/config | | | | X |
+| View transaction attempts | X | X | X | X |
+| View transaction attempts EVM | X | X | X | X |
+| View transactions | X | X | X | X |
+| Replay a specific block number | | X | X | X |
+| List keys (CSA,ETH,OCR(2),P2P,Solana,Terra) | X | X | X | X |
+| Create keys (CSA,ETH,OCR(2),P2P,Solana,Terra) | | | X | X |
+| Delete keys (CSA,ETH,OCR(2),P2P,Solana,Terra) | | | | X |
+| Import keys (CSA,ETH,OCR(2),P2P,Solana,Terra) | | | | X |
+| Export keys (CSA,ETH,OCR(2),P2P,Solana,Terra) | | | | X |
+| List jobs | X | X | X | X |
+| View job | X | X | X | X |
+| Create job | | | X | X |
+| Delete job | | | X | X |
+| List pipeline runs | X | X | X | X |
+| View job runs | X | X | X | X |
+| Delete job spec errors | | | X | X |
+| View features | X | X | X | X |
+| View log | X | X | X | X |
+| Update log | | | | X |
+| List chains | X | X | X | X |
+| View chain | X | X | X | X |
+| Create chain | | | X | X |
+| Update chain | | | X | X |
+| Delete chain | | | X | X |
+| View nodes | X | X | X | X |
+| Create node | | | X | X |
+| Update node | | | X | X |
+| Delete node | | | X | X |
+| View forwarders | X | X | X | X |
+| Create forwarder | | | X | X |
+| Delete forwarder | | | X | X |
+| Create job run | | X | X | X |
+| Create Transfer EVM | | | | X |
+| Create Transfer Terra | | | | X |
+| Create Transfer Solana | | | | X |
+| Create user | | | | X |
+| Delete user | | | | X |
+| Edit user | | | | X |
+| List users | | | | X |
The run command allows for minimal interaction and only enables the ability to replay a specific block number and kick off a job run.
@@ -184,6 +188,7 @@ This can be easily accomplished by using the following example run command:
```shell Goerli
cd ~/.chainlink-goerli && docker run --name chainlink -p 6688:6688 -v ~/.chainlink-goerli:/chainlink -it --env-file=.env smartcontract/chainlink local n
```
+
```shell Mainnet
cd ~/.chainlink && docker run --name chainlink -p 6688:6688 -v ~/.chainlink:/chainlink -it --env-file=.env smartcontract/chainlink local n
```
@@ -204,15 +209,16 @@ Then make your changes and use the longer `docker run` command again.
## Use Password and API Files On Startup
-The Chainlink node can be supplied with files for the wallet password and API email and password (on separate lines) on startup so that you don't need to enter credentials when starting the node. Following the pattern established in [Running a Chainlink Node](../running-a-chainlink-node/), you can create an API file by running the following:
+The Chainlink node can be supplied with files for the wallet password and API email and password (on separate lines) on startup so that you don't need to enter credentials when starting the node. Following the pattern established in [Running a Chainlink Node](/chainlink-nodes/running-a-chainlink-node/), you can create an API file by running the following:
-> 🚧 Important
->
-> Change the values within the quotes to something unique for your node.
+:::tip[Important]
+Change the values within the quotes to something unique for your node.
+:::
```shell Goerli
echo "user@example.com" > ~/.chainlink-goerli/.api
```
+
```shell Mainnet
echo "user@example.com" > ~/.chainlink/.api
```
@@ -222,6 +228,7 @@ Then add the password line by running:
```shell Goerli
echo "password" >> ~/.chainlink-goerli/.api
```
+
```shell Mainnet
echo "password" >> ~/.chainlink/.api
```
@@ -231,6 +238,7 @@ Create the password file by running the following:
```shell Goerli
echo "my_wallet_password" > ~/.chainlink-goerli/.password
```
+
```shell Mainnet
echo "my_wallet_password" > ~/.chainlink/.password
```
@@ -240,6 +248,7 @@ Finally, in order to use the password and API files upon running the node, add `
```shell Goerli
cd ~/.chainlink-goerli && docker run -p 6688:6688 -v ~/.chainlink-goerli:/chainlink -it --env-file=.env smartcontract/chainlink local n -p /chainlink/.password -a /chainlink/.api
```
+
```shell Mainnet
cd ~/.chainlink && docker run -p 6688:6688 -v ~/.chainlink:/chainlink -it --env-file=.env smartcontract/chainlink local n -p /chainlink/.password -a /chainlink/.api
```
@@ -254,7 +263,6 @@ chainlink local import ./keystore.json
If there is already a key in your database and you want to import another key, you will need to make sure that the same password unlocks all accounts.
-
## Full example in detached mode
```shell
diff --git a/docs/chainlink-nodes/node-versions.md b/src/pages/chainlink-nodes/node-versions.md
similarity index 80%
rename from docs/chainlink-nodes/node-versions.md
rename to src/pages/chainlink-nodes/node-versions.md
index 1147602f05c..033d903d79c 100644
--- a/docs/chainlink-nodes/node-versions.md
+++ b/src/pages/chainlink-nodes/node-versions.md
@@ -1,13 +1,12 @@
---
-layout: nodes.liquid
+layout: ../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
-title: 'Node Versions and Upgrades'
-permalink: 'docs/node-versions/'
-whatsnext: { 'Running a Chainlink Node': '/docs/running-a-chainlink-node/' }
+title: "Node Versions and Upgrades"
+whatsnext: { "Running a Chainlink Node": "/chainlink-nodes/running-a-chainlink-node" }
metadata:
- title: 'Node Versions and Release Notes'
- description: 'Details about various node versions and how to migrate between them.'
+ title: "Node Versions and Release Notes"
+ description: "Details about various node versions and how to migrate between them."
---
You can find a list of release notes for Chainlink nodes in the [smartcontractkit GitHub repository](https://github.com/smartcontractkit/chainlink/releases). Docker images are available in the [Chainlink Docker hub](https://hub.docker.com/r/smartcontract/chainlink/tags).
@@ -19,18 +18,18 @@ You can find a list of release notes for Chainlink nodes in the [smartcontractki
### Added
- Added an optional external logger `AUDIT_LOGS_FORWARDER_URL`: When set, this environment variable configures and enables an optional HTTP logger which is used specifically to send audit log events. Configure this logger with the following environment variables:
- - [AUDIT_LOGS_FORWARDER_URL](/docs/configuration-variables/#audit_logs_forwarder_url)
- - [AUDIT_LOGS_FORWARDER_HEADERS](/docs/configuration-variables/#audit_logs_forwarder_headers)
- - [AUDIT_LOGGER_JSON_WRAPPER_KEY](/docs/configuration-variables/#audit_logger_json_wrapper_key)
+ - [AUDIT_LOGS_FORWARDER_URL](/chainlink-nodes/configuration-variables/#audit_logs_forwarder_url)
+ - [AUDIT_LOGS_FORWARDER_HEADERS](/chainlink-nodes/configuration-variables/#audit_logs_forwarder_headers)
+ - [AUDIT_LOGGER_JSON_WRAPPER_KEY](/chainlink-nodes/configuration-variables/#audit_logger_json_wrapper_key)
- Added [automatic connectivity detection](#automatic-connectivity-detection) to automatically detect if there is a transaction propagation/connectivity issue and prevent bumping in these cases on EVM chains.
### Changed
- The default maximum gas price on most networks is now effectively unlimited.
- Chainlink will bump as high as necessary to get a transaction included. [Automatic connectivity detection](#automatic-connectivity-detection) prevents excessive bumping when there is a connectivity failure.
- - If you want to change this, manually set the [`ETH_MAX_GAS_PRICE_WEI` environment variable](/docs/configuration-variables/#eth_max_gas_price_wei).
+ - If you want to change this, manually set the [`ETH_MAX_GAS_PRICE_WEI` environment variable](/chainlink-nodes/configuration-variables/#eth_max_gas_price_wei).
- If the `EVMChainID` is not set explicitly in the job spec for a new OCR job, the field is now automatically added with a default chain ID.
- - Old OCR jobs missing `EVMChainID` continue to run on any chain that the [`ETH_CHAIN_ID` variable](/docs/configuration-variables/#eth_chain_id) is set to (or the first chain if it is not set). This can be changed after a restart.
+ - Old OCR jobs missing `EVMChainID` continue to run on any chain that the [`ETH_CHAIN_ID` variable](/chainlink-nodes/configuration-variables/#eth_chain_id) is set to (or the first chain if it is not set). This can be changed after a restart.
- Newly created OCR jobs run only on a single fixed chain and are unaffected by changes to `ETH_CHAIN_ID` after the job is added.
- It should no longer be possible to end up with multiple OCR jobs for a single contract running on the same chain. Only one job per contract per chain is allowed.
- If there are any existing duplicate jobs per contract and per chain, all but the jobs with the latest creation date will be pruned during the upgrade.
@@ -57,8 +56,8 @@ To disable connectivity checking completely, set `BLOCK_HISTORY_ESTIMATOR_CHECK_
**[v1.9.0 release notes](https://github.com/smartcontractkit/chainlink/releases/tag/v1.9.0)**
-- Added the [`length` task](/docs/jobs/task-types/length/) and the [`lessthan` task](/docs/jobs/task-types/lessthan/) for jobs.
-- Added the `gasUnlimited` parameter to the [`ethcall` task](/docs/jobs/task-types/eth-call/).
+- Added the [`length` task](/chainlink-nodes/oracle-jobs/task-types/task_length/) and the [`lessthan` task](/chainlink-nodes/oracle-jobs/task-types/task_lessthan/) for jobs.
+- Added the `gasUnlimited` parameter to the [`ethcall` task](/chainlink-nodes/oracle-jobs/task-types/task_eth_call/).
- The **Keys** page in Operator UI includes several admin commands that were previously available only by using the `keys eth chain` commands:
- Ability to abandon all current transactions: This is the same as the `abandon` CLI command. Previously it was necessary to edit the database directly to abandon transactions. This command makes it easier to resolve issues that require transactions to be abandoned.
- Ability to enable/disable a key for a specific chain: This allows you to control keys on a per-chain basis.
@@ -79,10 +78,10 @@ To disable connectivity checking completely, set `BLOCK_HISTORY_ESTIMATOR_CHECK_
### Added
-- Added the `hexencode` and `base64encode` tasks (pipeline). See the [Hex Encode Task](/docs/jobs/task-types/hexencode/) and [Base64 Encode Task](/docs/jobs/task-types/base64encode/) pages for examples.
+- Added the `hexencode` and `base64encode` tasks (pipeline). See the [Hex Encode Task](/chainlink-nodes/oracle-jobs/task-types/task_hexencode/) and [Base64 Encode Task](/chainlink-nodes/oracle-jobs/task-types/task_base64encode/) pages for examples.
- `forwardingAllowed` per job attribute to allow forwarding txs submitted by the job.
- Added `Arbitrum Goerli` configuration support.
-- Added the [`NODE_SELECTION_MODE` (`EVM.NodePool.SelectionMode`) environment variable](/docs/configuration-variables/#node_selection_mode), which controls node picking strategy. Supported values are:
+- Added the [`NODE_SELECTION_MODE` (`EVM.NodePool.SelectionMode`) environment variable](/chainlink-nodes/configuration-variables/#node_selection_mode), which controls node picking strategy. Supported values are:
- `HighestHead` is the default mode, which picks a node that has the highest reported head number among other alive nodes. When several nodes have the same latest head number, the strategy sticks to the last used node. This mode requires `NODE_NO_NEW_HEADS_THRESHOLD` to be configured, otherwise it will always use the first alive node.
- `RoundRobin` mode iterates among available alive nodes. This was the default behavior prior to this release.
- New `evm keys chain` command. This can also be accessed at `/v2/keys/evm/chain`. This command has the following uses:
@@ -116,11 +115,11 @@ To disable connectivity checking completely, set `BLOCK_HISTORY_ESTIMATOR_CHECK_
### Added
-- `p2pv2Bootstrappers` is added as a new optional property of OCR1 job specs. The default can still be specified with the [`P2PV2_BOOTSTRAPPERS` environment variable](/docs/configuration-variables/#p2pv2_bootstrappers).
+- `p2pv2Bootstrappers` is added as a new optional property of OCR1 job specs. The default can still be specified with the [`P2PV2_BOOTSTRAPPERS` environment variable](/chainlink-nodes/configuration-variables/#p2pv2_bootstrappers).
- Added official support for the [Sepolia testnet](https://sepolia.dev/) on Chainlink nodes.
-- Added [`hexdecode` task](/docs/jobs/task-types/hexdecode/) and the [`base64decode` task](/docs/jobs/task-types/base64decode/) (pipeline).
+- Added [`hexdecode` task](/chainlink-nodes/oracle-jobs/task-types/task_hexdecode/) and the [`base64decode` task](/chainlink-nodes/oracle-jobs/task-types/task_base64decode) (pipeline).
- Added support for the Besu execution client. Although Chainlink supports Besu, Besu itself has several issues that can make it unreliable. For additional context, see the following issues:
@@ -128,7 +127,7 @@ To disable connectivity checking completely, set `BLOCK_HISTORY_ESTIMATOR_CHECK_
- [hyperledger/besu/issues/4192](https://github.com/hyperledger/besu/issues/4192)
- [hyperledger/besu/issues/4114](https://github.com/hyperledger/besu/issues/4114)
-- Added [Multi-user and Role Based Access Control](/docs/miscellaneous/#multi-user-and-role-based-access-control-rbac) functionality. This allows the root admin CLI user and additional admin users to create and assign tiers of role-based access to new users. These new API users are able to log in to the Operator UI independently and can each have specific roles tied to their account. There are four roles: `admin`, `edit`, `run`, and `view`.
+- Added [Multi-user and Role Based Access Control](/chainlink-nodes/miscellaneous/#multi-user-and-role-based-access-control-rbac) functionality. This allows the root admin CLI user and additional admin users to create and assign tiers of role-based access to new users. These new API users are able to log in to the Operator UI independently and can each have specific roles tied to their account. There are four roles: `admin`, `edit`, `run`, and `view`.
- User management can be configured through the use of the new admin CLI command `chainlink admin users`. Be sure to run `chainlink admin login`. For example, a readonly user can be created with: `chainlink admin users create --email=operator-ui-read-only@test.com --role=view`.
- Updated documentation repo with a break down of actions to required role level
@@ -139,17 +138,17 @@ To disable connectivity checking completely, set `BLOCK_HISTORY_ESTIMATOR_CHECK_
1. The job-spec attribute `gasLimit` applies only to a specific job spec.
1. The job-type limits affect any jobs of the corresponding type. The following environment variables are available:
- - [ETH_GAS_LIMIT_OCR_JOB_TYPE](/docs/configuration-variables/#eth_gas_limit_ocr_job_type)
- - [ETH_GAS_LIMIT_DR_JOB_TYPE](/docs/configuration-variables/#eth_gas_limit_dr_job_type)
- - [ETH_GAS_LIMIT_VRF_JOB_TYPE](/docs/configuration-variables/#eth_gas_limit_vrf_job_type)
- - [ETH_GAS_LIMIT_FM_JOB_TYPE](/docs/configuration-variables/#eth_gas_limit_fm_job_type)
- - [ETH_GAS_LIMIT_KEEPER_JOB_TYPE](/docs/configuration-variables/#eth_gas_limit_keeper_job_type)
+ - [ETH_GAS_LIMIT_OCR_JOB_TYPE](/chainlink-nodes/configuration-variables/#eth_gas_limit_ocr_job_type)
+ - [ETH_GAS_LIMIT_DR_JOB_TYPE](/chainlink-nodes/configuration-variables/#eth_gas_limit_dr_job_type)
+ - [ETH_GAS_LIMIT_VRF_JOB_TYPE](/chainlink-nodes/configuration-variables/#eth_gas_limit_vrf_job_type)
+ - [ETH_GAS_LIMIT_FM_JOB_TYPE](/chainlink-nodes/configuration-variables/#eth_gas_limit_fm_job_type)
+ - [ETH_GAS_LIMIT_KEEPER_JOB_TYPE](/chainlink-nodes/configuration-variables/#eth_gas_limit_keeper_job_type)
1. The global `ETH_GAS_LIMIT_DEFAULT` (`EVM.GasEstimator.LimitDefault`) value is used only when the preceding rules are not set.
### Fixed
-- Addressed a very rare bug where using multiple nodes with differently configured RPC tx fee caps could cause missed transactions. Ensure that your RPC nodes have no caps. For more information, see the [performance and tuning guide](https://docs.chain.link/docs/evm-performance-configuration/).
+- Addressed a very rare bug where using multiple nodes with differently configured RPC tx fee caps could cause missed transactions. Ensure that your RPC nodes have no caps. For more information, see the [performance and tuning guide](https://docs.chain.link/chainlink-nodes/evm-performance-configuration/).
- Improved handling of unknown transaction error types to make Chainlink more robust in certain cases on unsupported chains or RPC clients.
## Changes in v1.6.0 nodes
@@ -194,7 +193,7 @@ To disable connectivity checking completely, set `BLOCK_HISTORY_ESTIMATOR_CHECK_
### Added
-- Added the [`ETH_USE_FORWARDERS` config](/docs/configuration-variables/#eth_use_forwarders) option to enable transactions forwarding contracts.
+- Added the [`ETH_USE_FORWARDERS` config](/chainlink-nodes/configuration-variables/#eth_use_forwarders) option to enable transactions forwarding contracts.
- In the `directrequest` job pipeline, three new block variables are available:
@@ -229,9 +228,9 @@ To disable connectivity checking completely, set `BLOCK_HISTORY_ESTIMATOR_CHECK_
- The `Optimism` OVM 1.0 `GAS_ESTIMATOR_MODE` has been removed and the `Optimism2` `GAS_ESTIMATOR_MODE` has been renamed to `L2Suggested`.
-- `MIN_OUTGOING_CONFIRMATIONS` has been removed and no longer has any effect. The [`ETH_FINALITY_DEPTH` environment variable](/docs/configuration-variables/#eth_finality_depth) is now used as the default for `ethtx` confirmations instead. You can override this on a per-task basis by setting `minConfirmations` in the task definition. For example, `foo [type=ethtx minConfirmations=42 ...]`.
+- `MIN_OUTGOING_CONFIRMATIONS` has been removed and no longer has any effect. The [`ETH_FINALITY_DEPTH` environment variable](/chainlink-nodes/configuration-variables/#eth_finality_depth) is now used as the default for `ethtx` confirmations instead. You can override this on a per-task basis by setting `minConfirmations` in the task definition. For example, `foo [type=ethtx minConfirmations=42 ...]`.
- This setting might have a minor impact on performance for very high throughput chains. If you don't care about reporting task status in the UI, set `minConfirmations=0` in your job specs. For more details, see the [Optimizing EVM Performance](/docs/evm-performance-configuration/#adjusting-minimum-outgoing-confirmations-for-high-throughput-jobs) page.
+ This setting might have a minor impact on performance for very high throughput chains. If you don't care about reporting task status in the UI, set `minConfirmations=0` in your job specs. For more details, see the [Optimizing EVM Performance](/chainlink-nodes/evm-performance-configuration/#adjusting-minimum-outgoing-confirmations-for-high-throughput-jobs) page.
## Changes in v1.4.1 nodes
@@ -247,28 +246,28 @@ To disable connectivity checking completely, set `BLOCK_HISTORY_ESTIMATOR_CHECK_
- JSON parse tasks in TOML now support a custom `separator` parameter to substitute for the default `,`.
- Slow SQL queries are now logged.
- Updated the block explorer URLs to include FTMScan and SnowTrace.
-- Keeper upkeep order can now be shuffled. See [KEEPER_TURN_FLAG_ENABLED](/docs/configuration-variables/#keeper_turn_flag_enabled) for details.
+- Keeper upkeep order can now be shuffled. See [KEEPER_TURN_FLAG_ENABLED](/chainlink-nodes/configuration-variables/#keeper_turn_flag_enabled) for details.
- Several fixes. See the [release notes](https://github.com/smartcontractkit/chainlink/releases/tag/v1.4.0) for a full list of changes.
## Changes in v1.3.0 nodes
**[v1.3.0 release notes](https://github.com/smartcontractkit/chainlink/releases/tag/v1.3.0)**
-- Added disk rotating logs. See the [Node Logging](/docs/configuration-variables/#logging) and [LOG_FILE_MAX_SIZE](/docs/configuration-variables/#log_file_max_size) documentation for details.
+- Added disk rotating logs. See the [Node Logging](/chainlink-nodes/configuration-variables/#logging) and [LOG_FILE_MAX_SIZE](/chainlink-nodes/configuration-variables/#log_file_max_size) documentation for details.
- Added support for the `force` flag on the `chainlink blocks replay` CLI command. If set to true, already consumed logs that would otherwise be skipped will be rebroadcasted.
- Added a version compatibility check when using the CLI to login to a remote node. The `bypass-version-check` flag skips this check.
-- Changed default locking mode to "dual". See the [DATABASE_LOCKING_MODE](/docs/configuration-variables/#database_locking_mode) documentation for details.
+- Changed default locking mode to "dual". See the [DATABASE_LOCKING_MODE](/chainlink-nodes/configuration-variables/#database_locking_mode) documentation for details.
- Specifying multiple EVM RPC nodes with the same URL is no longer supported. If you see `ERROR 0106_evm_node_uniqueness.sql: failed to run SQL migration`, you have multiple nodes specified with the same URL and you must fix this before proceeding with the upgrade.
-- EIP-1559 is now enabled by default on the Ethereum Mainnet. See the [EVM_EIP1559_DYNAMIC_FEES](/docs/configuration-variables/#evm_eip1559_dynamic_fees) documentation for details.
-- Added new Chainlink Automation feature that includes gas price in calls to `checkUpkeep()`. To enable the feature, set [KEEPER_CHECK_UPKEEP_GAS_PRICE_FEATURE_ENABLED](/docs/configuration-variables#keeper_check_upkeep_gas_price_feature_enabled) to `true`. Use this setting _only_ on Polygon networks.
+- EIP-1559 is now enabled by default on the Ethereum Mainnet. See the [EVM_EIP1559_DYNAMIC_FEES](/chainlink-nodes/configuration-variables/#evm_eip1559_dynamic_fees) documentation for details.
+- Added new Chainlink Automation feature that includes gas price in calls to `checkUpkeep()`. To enable the feature, set [KEEPER_CHECK_UPKEEP_GAS_PRICE_FEATURE_ENABLED](/chainlink-nodes/configuration-variables#keeper_check_upkeep_gas_price_feature_enabled) to `true`. Use this setting _only_ on Polygon networks.
## Changes in v1.2.0 nodes
**[v1.2.0 release notes](https://github.com/smartcontractkit/chainlink/releases/tag/v1.2.0)**
-> 🚧 Not for use on Solana or Terra
->
-> Although this release provides `SOLANA_ENABLED` and `TERRA_ENABLED` environment variables, these are not intended for use on Solana or Terra mainnets.
+:::caution[Not for use on Solana or Terra]
+Although this release provides `SOLANA_ENABLED` and `TERRA_ENABLED` environment variables, these are not intended for use on Solana or Terra mainnets.
+:::
Significant changes:
@@ -286,7 +285,7 @@ See the [v1.2.0 release notes](https://github.com/smartcontractkit/chainlink/rel
The v1.1.0 release includes several substantial changes to the way you configure and operate Chainlink nodes:
-- **Legacy environment variables**: Legacy environment variables are supported, but they might be removed in future node versions. See the [Configuring Chainlink Nodes](/docs/configuration-variables/#evmethereum-legacy-environment-variables) page to learn how to migrate your nodes away from legacy environment variables and use the API, CLI, or GUI exclusively to administer chains and nodes.
+- **Legacy environment variables**: Legacy environment variables are supported, but they might be removed in future node versions. See the [Configuring Chainlink Nodes](/chainlink-nodes/configuration-variables/#evmethereum-legacy-environment-variables) page to learn how to migrate your nodes away from legacy environment variables and use the API, CLI, or GUI exclusively to administer chains and nodes.
- **Full EIP1559 Support**: Chainlink nodes include experimental support for submitting transactions using type 0x2 (EIP-1559) envelope. EIP-1559 mode is off by default, but can be enabled either globally or on a per-chain basis.
- **New log level added**:
- [crit]: Critical level logs are more severe than [error] and require quick action from the node operator.
@@ -319,7 +318,7 @@ This will cause Chainlink to use the database for its node configuration.
NOTE: ETH_CHAIN_ID does not need to be removed, since it now performs the additional duty of specifying the default chain in a multichain environment (if you leave ETH_CHAIN_ID unset, the default chain is simply the "first").
-For more information on configuring your node, check the [configuration variables in the docs](https://docs.chain.link/docs/configuration-variables/).
+For more information on configuring your node, check the [configuration variables in the docs](https://docs.chain.link/chainlink-nodes/configuration-variables/).
Before you upgrade your nodes to v1.1.0, be aware of the following requirements:
diff --git a/docs/chainlink-nodes/oracle-jobs/job-types/cron.md b/src/pages/chainlink-nodes/oracle-jobs/job-types/cron.md
similarity index 57%
rename from docs/chainlink-nodes/oracle-jobs/job-types/cron.md
rename to src/pages/chainlink-nodes/oracle-jobs/job-types/cron.md
index e640c0e8f7d..df73611d3f8 100644
--- a/docs/chainlink-nodes/oracle-jobs/job-types/cron.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/job-types/cron.md
@@ -1,18 +1,20 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Solidity Cron Jobs"
permalink: "docs/jobs/types/cron/"
---
-> 📘 If you need to schedule a contract function call, use the [Chainlink Job Scheduler](https://automation.chain.link/new-time-based). The Job Scheduler uses the [Chainlink Automation](/docs/chainlink-automation/introduction) network to execute deployed contract calls on a cron schedule that you define, such as an Ethereum cron job for your dApp.
+:::note[Chainlink Job Scheduler]
+If you need to schedule a contract function call, use the [Chainlink Job Scheduler](https://automation.chain.link/new-time-based). The Job Scheduler uses the [Chainlink Automation](/chainlink-automation/introduction) network to execute deployed contract calls on a cron schedule that you define, such as an Ethereum cron job for your dApp.
+:::
Executes a job on a schedule. Does not rely on any kind of external trigger.
**Spec format**
-```jpv2
+```toml
type = "cron"
schemaVersion = 1
evmChainID = 1
@@ -28,13 +30,13 @@ observationSource = """
```
**Shared fields**
-See [shared fields](/docs/jobs/#shared-fields).
+See [shared fields](/chainlink-nodes/oracle-jobs/jobs/#shared-fields).
**Unique fields**
- `schedule`: the frequency with which the job is to be run. There are two ways to specify this:
- - Traditional UNIX cron format, but with 6 fields, not 5. The extra field allows for "seconds" granularity. **Note:** you _must_ specify the `CRON_TZ=...` parameter if you use this format.
- - `@` shorthand, e.g. `@every 1h`. This shorthand does not take account of the node's timezone, rather, it simply begins counting down the moment that the job is added to the node (or the node is rebooted). As such, no `CRON_TZ` parameter is needed.
+ - Traditional UNIX cron format, but with 6 fields, not 5. The extra field allows for "seconds" granularity. **Note:** you _must_ specify the `CRON_TZ=...` parameter if you use this format.
+ - `@` shorthand, e.g. `@every 1h`. This shorthand does not take account of the node's timezone, rather, it simply begins counting down the moment that the job is added to the node (or the node is rebooted). As such, no `CRON_TZ` parameter is needed.
For all supported schedules, please refer to the [cron library documentation](https://pkg.go.dev/github.com/robfig/cron?utm_source=godoc).
diff --git a/docs/chainlink-nodes/oracle-jobs/job-types/direct_request.md b/src/pages/chainlink-nodes/oracle-jobs/job-types/direct_request.md
similarity index 70%
rename from docs/chainlink-nodes/oracle-jobs/job-types/direct_request.md
rename to src/pages/chainlink-nodes/oracle-jobs/job-types/direct_request.md
index d26ce951573..03da50bc364 100644
--- a/docs/chainlink-nodes/oracle-jobs/job-types/direct_request.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/job-types/direct_request.md
@@ -1,29 +1,16 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
-title: 'Direct Request Jobs'
-permalink: 'docs/jobs/types/direct-request/'
+title: "Direct Request Jobs"
+permalink: "docs/jobs/types/direct-request/"
---
Executes a job upon receipt of an explicit request made by a user. The request is detected via a log emitted by an Oracle or Operator contract. This is similar to the legacy ethlog/runlog style of jobs.
-**Topics**
-
-- [Spec format](#spec-format)
- - [Shared fields](#shared-fields)
- - [Unique fields](#unique-fields)
- - [Job type specific pipeline variables](#job-type-specific-pipeline-variables)
-- [Examples](#examples)
- - [Get > Uint256 Job](#get--uint256-job)
- - [Get > String Job](#get--string-job)
- - [Get > Bytes Job](#get--bytes-job)
- - [Multi-Word Job](#multi-word-job)
- - [Existing Job](#existing-job)
-
## Spec format
-```jpv2
+```toml
type = "directrequest"
schemaVersion = 1
evmChainID = 1
@@ -50,7 +37,7 @@ observationSource = """
### Shared fields
-See [shared fields](/docs/jobs/#shared-fields).
+See [shared fields](/chainlink-nodes/oracle-jobs/jobs/#shared-fields).
### Unique fields
@@ -81,45 +68,45 @@ See [shared fields](/docs/jobs/#shared-fields).
Let's assume that a user makes a request to an oracle to call a public API, retrieve a number from the response, remove any decimals and return _uint256_.
-- The smart contract example can be found [here](/docs/any-api/get-request/examples/single-word-response/).
-- The job spec example can be found [here](/docs/direct-request-get-uint256/).
+- The smart contract example can be found [here](/any-api/get-request/examples/single-word-response/).
+- The job spec example can be found [here](/chainlink-nodes/job-specs/direct-request-get-uint256/).
### Get > Int256 Job
Let's assume that a user makes a request to an oracle to call a public API, retrieve a number from the response, remove any decimals and return _int256_.
-- The job spec example can be found [here](/docs/direct-request-get-int256/).
+- The job spec example can be found [here](/chainlink-nodes/job-specs/direct-request-get-int256/).
### Get > Bool Job
Let's assume that a user makes a request to an oracle to call a public API, retrieve a boolean from the response and return _bool_.
-- The job spec example can be found [here](/docs/direct-request-get-bool/).
+- The job spec example can be found [here](/chainlink-nodes/job-specs/direct-request-get-bool/).
### Get > String Job
Let's assume that a user makes a request to an oracle and would like to fetch a _string_ from the response.
-- The smart contract example can be found [here](/docs/any-api/get-request/examples/api-array-response/).
-- The job spec example can be found [here](/docs/direct-request-get-string/).
+- The smart contract example can be found [here](/any-api/get-request/examples/array-response/).
+- The job spec example can be found [here](/chainlink-nodes/job-specs/direct-request-get-string/).
### Get > Bytes Job
Let's assume that a user makes a request to an oracle and would like to fetch _bytes_ from the response (meaning a response that contains an arbitrary-length raw byte data).
-- The smart contract example can be found [here](/docs/any-api/get-request/examples/large-responses/).
-- The job spec example can be found [here](/docs/direct-request-get-bytes/).
+- The smart contract example can be found [here](/any-api/get-request/examples/large-responses/).
+- The job spec example can be found [here](/chainlink-nodes/job-specs/direct-request-get-bytes/).
### Multi-Word Job
Let's assume that a user makes a request to an oracle and would like to fetch multiple words in one single request.
-- The smart contract example can be found [here](/docs/any-api/get-request/examples/multi-variable-responses/).
-- The job spec example can be found [here](/docs/direct-request-multi-word/).
+- The smart contract example can be found [here](/any-api/get-request/examples/multi-variable-responses/).
+- The job spec example can be found [here](/chainlink-nodes/job-specs/multi-word-job/).
### Existing Job
Using an _existing_ Oracle Job makes your smart contract code more succinct. Let's assume that a user makes a request to an oracle that leverages [Etherscan External Adapter](https://github.com/smartcontractkit/external-adapters-js/tree/develop/packages/sources/etherscan) to retrieve the gas price.
-- The smart contract example can be found [here](/docs/any-api/get-request/examples/existing-job-request/).
-- The job spec example can be found [here](/docs/direct-request-existing-job/).
+- The smart contract example can be found [here](/any-api/get-request/examples/existing-job-request/).
+- The job spec example can be found [here](/chainlink-nodes/job-specs/direct-request-existing-job/).
diff --git a/docs/chainlink-nodes/oracle-jobs/job-types/flux_monitor.md b/src/pages/chainlink-nodes/oracle-jobs/job-types/flux_monitor.md
similarity index 87%
rename from docs/chainlink-nodes/oracle-jobs/job-types/flux_monitor.md
rename to src/pages/chainlink-nodes/oracle-jobs/job-types/flux_monitor.md
index 5f184fc438a..852ed56cf44 100644
--- a/docs/chainlink-nodes/oracle-jobs/job-types/flux_monitor.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/job-types/flux_monitor.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Flux Monitor Jobs"
@@ -11,12 +11,12 @@ The Flux Monitor job type is for continually-updating data feeds that aggregate
- An occasional poll, which must show that there has been sufficient deviation from an off-chain data source before a new result is submitted
- New rounds initiated by other oracles on the feeds. If another oracle notices sufficient deviation, all other oracles will submit their current observations as well.
- A heartbeat, which ensures that even if no deviation occurs, we submit a new result to prove liveness. This can take one of two forms:
- - The "idle timer", which begins counting down each time a round is started
- - The "drumbeat", which simply ticks at a steady interval, much like a `cron` job
+ - The "idle timer", which begins counting down each time a round is started
+ - The "drumbeat", which simply ticks at a steady interval, much like a `cron` job
**Spec format**
-```jpv2
+```toml
type = "fluxmonitor"
schemaVersion = 1
name = "example flux monitor spec"
@@ -54,7 +54,7 @@ observationSource = """
```
**Shared fields**
-See [shared fields](/docs/jobs/#shared-fields).
+See [shared fields](/chainlink-nodes/oracle-jobs/jobs/#shared-fields).
**Unique Fields**
@@ -68,8 +68,8 @@ See [shared fields](/docs/jobs/#shared-fields).
- `pollTimerPeriod`: the frequency with which the off-chain data source is checked for deviation against the previously submitted on-chain answer.
- `pollTimerDisabled`: whether the occasional deviation check is used to trigger new rounds.
- **Notes:**
- - For duration parameters, the maximum unit of time is `h` (hour). Durations of a day or longer must be expressed in hours.
- - If no time unit is provided, the default unit is nanoseconds, which is almost never what you want.
+ - For duration parameters, the maximum unit of time is `h` (hour). Durations of a day or longer must be expressed in hours.
+ - If no time unit is provided, the default unit is nanoseconds, which is almost never what you want.
**Job type specific pipeline variables**
diff --git a/docs/chainlink-nodes/oracle-jobs/job-types/keeper.md b/src/pages/chainlink-nodes/oracle-jobs/job-types/keeper.md
similarity index 89%
rename from docs/chainlink-nodes/oracle-jobs/job-types/keeper.md
rename to src/pages/chainlink-nodes/oracle-jobs/job-types/keeper.md
index e7ce7b2766a..32f04ee8d90 100644
--- a/docs/chainlink-nodes/oracle-jobs/job-types/keeper.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/job-types/keeper.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Keeper Jobs"
@@ -18,7 +18,7 @@ Examples:
**Spec format**
-```jpv2
+```toml
type = "keeper"
schemaVersion = 1
evmChainID = 1
@@ -29,7 +29,7 @@ fromAddress = "0xa8037A20989AFcBC51798de9762b351D63ff462e"
**Shared fields**
-See [shared fields](/docs/jobs/#shared-fields).
+See [shared fields](/chainlink-nodes/oracle-jobs/jobs/#shared-fields).
**Unique fields**
diff --git a/docs/chainlink-nodes/oracle-jobs/job-types/offchain_reporting.md b/src/pages/chainlink-nodes/oracle-jobs/job-types/offchain_reporting.md
similarity index 96%
rename from docs/chainlink-nodes/oracle-jobs/job-types/offchain_reporting.md
rename to src/pages/chainlink-nodes/oracle-jobs/job-types/offchain_reporting.md
index 3bde28d636c..2e37082186a 100644
--- a/docs/chainlink-nodes/oracle-jobs/job-types/offchain_reporting.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/job-types/offchain_reporting.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Off-chain Reporting Jobs"
@@ -16,7 +16,7 @@ Every OCR cluster requires at least one bootstrap node as a kind of "rallying po
**Spec format**
-```jpv2
+```toml
type = "offchainreporting"
schemaVersion = 1
evmChainID = 1
@@ -29,7 +29,7 @@ externalJobID = "0EEC7E1D-D0D2-476C-A1A8-72DFB6633F05"
```
**Shared fields**
-See [shared fields](/docs/jobs/#shared-fields).
+See [shared fields](/chainlink-nodes/oracle-jobs/jobs/#shared-fields).
**Unique fields**
@@ -51,7 +51,7 @@ Oracle nodes, on the other hand, are responsible for submitting answers.
**Spec format**
-```jpv2
+```toml
type = "offchainreporting"
schemaVersion = 1
evmChainID = 1
@@ -91,7 +91,7 @@ observationSource = """
```
**Shared fields**
-See [shared fields](/docs/jobs/#shared-fields).
+See [shared fields](/chainlink-nodes/oracle-jobs/jobs/#shared-fields).
**Unique fields**
diff --git a/docs/chainlink-nodes/oracle-jobs/job-types/webhook.md b/src/pages/chainlink-nodes/oracle-jobs/job-types/webhook.md
similarity index 91%
rename from docs/chainlink-nodes/oracle-jobs/job-types/webhook.md
rename to src/pages/chainlink-nodes/oracle-jobs/job-types/webhook.md
index 9212eefdff3..39467dbf6f9 100644
--- a/docs/chainlink-nodes/oracle-jobs/job-types/webhook.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/job-types/webhook.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Webhook Jobs"
@@ -8,11 +8,13 @@ permalink: "docs/jobs/types/webhook/"
Webhook jobs can be initiated by HTTP request, either by a user or external initiator.
-> Note: You'll need `FEATURE_WEBHOOK_V2=true` in your `.env` file.
+:::note
+You'll need `FEATURE_WEBHOOK_V2=true` in your `.env` file.
+:::
This is an example webhook job:
-```jpv2
+```toml
type = "webhook"
schemaVersion = 1
externalInitiators = [
@@ -37,7 +39,7 @@ Webhook jobs may additionally specify zero or more external initiators, which ca
- `externalInitiators`: an array of `{name, spec}` objects, where `name` is the name registered with the node, and `spec` is the job spec to be forwarded to the external initiator when it is created.
**Shared fields**
-See [shared fields](/docs/jobs/#shared-fields).
+See [shared fields](/chainlink-nodes/oracle-jobs/jobs/#shared-fields).
**Job type specific pipeline variables**
diff --git a/docs/chainlink-nodes/oracle-jobs/jobs.md b/src/pages/chainlink-nodes/oracle-jobs/jobs.md
similarity index 65%
rename from docs/chainlink-nodes/oracle-jobs/jobs.md
rename to src/pages/chainlink-nodes/oracle-jobs/jobs.md
index 37bcc722400..dcf8bcdd3d0 100644
--- a/docs/chainlink-nodes/oracle-jobs/jobs.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/jobs.md
@@ -1,23 +1,25 @@
---
-layout: nodes.liquid
+layout: ../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "v2 Jobs"
permalink: "docs/jobs/"
---
-> 📘 This page describes v2 Chainlink jobs. In the Operator UI interface, these are called TOML jobs. The v1 jobs are removed in Chainlink nodes versioned 1.0.0 and later. To learn how to migrate your v1 jobs to v2 jobs, see [Migrating to v2 Jobs](../jobs/migration-v1-v2/). If you still need to use v1 jobs on older versions of Chainlink nodes, see the [v1 Jobs](../job-specifications/) documentation.
+:::note[Chainlink v2 jobs ]
+This page describes Chainlink v2 jobs. In the Operator UI interface, these are called TOML jobs. The v1 jobs are removed in Chainlink nodes versioned 1.0.0 and later. To learn how to migrate your v1 jobs to v2 jobs, see [Migrating to v2 Jobs](/chainlink-nodes/oracle-jobs/migration-v1-v2/). If you still need to use v1 jobs on older versions of Chainlink nodes, see the [v1 Jobs](/chainlink-nodes/oracle-jobs/v1/job-specifications/) documentation.
+:::
## What is a Job?
Chainlink nodes require jobs to do anything useful. For example, posting asset price data on-chain requires jobs. Chainlink nodes support the following job types:
-- [`cron`](./types/cron/)
-- [`directrequest`](./types/direct-request/)
-- [`fluxmonitor`](./types/flux-monitor/)
-- [`keeper`](./types/keeper/)
-- [`offchainreporting`](./types/offchain-reporting/)
-- [`webhook`](./types/webhook/)
+- [`cron`](/chainlink-nodes/oracle-jobs/job-types/cron/)
+- [`directrequest`](/chainlink-nodes/oracle-jobs/job-types/direct_request/)
+- [`fluxmonitor`](/chainlink-nodes/oracle-jobs/job-types/flux_monitor/)
+- [`keeper`](/chainlink-nodes/oracle-jobs/job-types/keeper/)
+- [`offchainreporting`](/chainlink-nodes/oracle-jobs/job-types/offchain_reporting/)
+- [`webhook`](/chainlink-nodes/oracle-jobs/job-types/webhook/)
Jobs are represented by TOML specifications.
@@ -25,7 +27,7 @@ Jobs are represented by TOML specifications.
The following is an example `cron` job spec. This is a simple spec that you can add to a node:
-```jpv2
+```toml
type = "cron"
schemaVersion = 1
schedule = "CRON_TZ=UTC 0 0 1 1 *"
@@ -45,14 +47,14 @@ Every job type supported by a node shares the following TOML fields:
- `name`: The name of the job in the Operator UI
- `type`: Specifies the v2 job type, which can be one of the following:
- - `cron`
- - `directrequest`
- - `fluxmonitor`
- - `keeper`
- - `offchainreporting`
- - `webhook`
+ - `cron`
+ - `directrequest`
+ - `fluxmonitor`
+ - `keeper`
+ - `offchainreporting`
+ - `webhook`
- `schemaVersion`: Must be present and set to a value of `1`. This field will handle progressive iterations of the job spec format gracefully with backwards-compatibility.
- `observationSource`: The v2 pipeline task DAG, which is specified in DOT syntax. See below for information on writing pipeline DAGs.
-- `maxTaskDuration`: The default maximum duration that any task is allowed to run. If the duration is exceeded, the task is errored. This value can be overridden on a per-task basis using the `timeout` attribute. See the [Shared attributes](../tasks/#shared-attributes) section for details.
+- `maxTaskDuration`: The default maximum duration that any task is allowed to run. If the duration is exceeded, the task is errored. This value can be overridden on a per-task basis using the `timeout` attribute. See the [Shared attributes](/chainlink-nodes/oracle-jobs/task-types/tasks#shared-attributes) section for details.
- `externalJobID`: An optional way for a user to deterministically provide the ID of a job. The ID must be unique. For example, you can specify an `externalJobID` if you want to run the same `directrequest` job on two different Chainlink nodes with different bridge names. The spec contents differ slightly, but you can use the same `externalJobID` on both jobs, specify that in your on-chain requests, and both nodes will pick it up. If you do not provide an `externalJobID`, the node generates the ID for you.
- `gasLimit`: Optional gas limit for any outgoing transactions spawned by this job. When specified, it overrides `ETH_GAS_LIMIT_DEFAULT` env variable.
diff --git a/docs/chainlink-nodes/oracle-jobs/migration-v1-v2.md b/src/pages/chainlink-nodes/oracle-jobs/migration-v1-v2.md
similarity index 95%
rename from docs/chainlink-nodes/oracle-jobs/migration-v1-v2.md
rename to src/pages/chainlink-nodes/oracle-jobs/migration-v1-v2.md
index 9844e88abfb..e7338360183 100644
--- a/docs/chainlink-nodes/oracle-jobs/migration-v1-v2.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/migration-v1-v2.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Migrating to v2 Jobs"
@@ -24,11 +24,11 @@ The v2 Job Specs support expanding functionality in Chainlink nodes and prefer e
### DAG dependencies and variables
-v2 jobs require the author to specify dependencies using [DOT syntax](https://en.wikipedia.org/wiki/DOT_(graph_description_language)). If a task needs data produced by another task, this must be specified using DOT.
+v2 jobs require the author to specify dependencies using [DOT syntax](). If a task needs data produced by another task, this must be specified using DOT.
To facilitate explicitness, v2 jobs require the author to specify inputs to tasks using `$(variable)` syntax. For example, if an `http` task feeds data into a `jsonparse` task, it must be specified like the following example:
-```jpv2
+```toml
fetch [type="http" method=GET url="http://chain.link/price_feeds/ethusd"]
// This task consumes the output of the 'fetch' task in its 'data' parameter
@@ -40,7 +40,7 @@ fetch -> parse
Task names must be defined before their opening `[` bracket. In this example, the name of the task is `fetch`. The output of each task is stored in the variable corresponding to the name of the task. In some cases, tasks return complex values like maps or arrays. By using dot access syntax, you can access the elements of these values. For example:
-```jpv2
+```toml
// Assume that this task returns the following object:
// { "ethusd": 123.45, "btcusd": 678.90 }
parse [type="jsonparse" path="data" data="$(fetch)"]
@@ -57,14 +57,13 @@ parse -> submit_btcusd
Some tasks, like the `bridge` tasks above, require you to specify a JSON object. Because the keys of JSON objects must be enclosed in double quotes, you must use the alternative `<` angle bracket `>` quotes. Angle brackets also enable multi-line strings, which can be useful when a JSON object parameter is large:
-```jpv2
+```toml
submit_btcusd [type="bridge"
name="btcusd"
requestData="{\\"data\\":{\\"value\\": $(foo), \\"price\\": $(bar), \\"timestamp\\": $(baz)}}"
]
```
-
### Misc. notes
- Each job type provides a particular set of variables to its pipeline. See the documentation for each job type to understand which variables are provided.
@@ -109,12 +108,13 @@ This spec relies on CBOR-encoded on-chain values for the `httpget` URL and `json
```
Notes:
+
- In v1, the job ID is randomly generated at creation time. In v2 jobs, the job ID can be manually specified or the Chainlink node will automatically generate it.
-- In v2, the `ethbytes32` task and all of the other ABI encoding tasks are now encapsulated in the `ethabiencode` task with much more flexibility. See the [ETH ABI Encode task](/docs/jobs/task-types/eth-abi-encode/) page to learn more.
+- In v2, the `ethbytes32` task and all of the other ABI encoding tasks are now encapsulated in the `ethabiencode` task with much more flexibility. See the [ETH ABI Encode task](/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_encode/) page to learn more.
**Equivalent v2 spec:**
-```jpv2
+```toml
type = "directrequest"
schemaVersion = 1
name = "Get > Bytes32"
@@ -165,9 +165,7 @@ observationSource = """
{
"type": "JSONParse",
"params": {
- "path": [
- "last"
- ]
+ "path": ["last"]
}
},
{
@@ -191,7 +189,7 @@ observationSource = """
**Equivalent v2 spec:**
-```jpv2
+```toml
type = "directrequest"
schemaVersion = 1
name = "Get > Bytes32"
@@ -242,10 +240,7 @@ observationSource = """
{
"type": "JsonParse",
"params": {
- "path": [
- "data",
- "price"
- ]
+ "path": ["data", "price"]
}
},
{
@@ -266,7 +261,7 @@ observationSource = """
**Equivalent v2 spec:**
-```jpv2
+```toml
type = "cron"
schemaVersion = 1
schedule = "CRON_TZ=UTC * */20 * * * *"
@@ -312,7 +307,7 @@ observationSource = """
**Equivalent v2 spec:**
-```jpv2
+```toml
type = "webhook"
schemaVersion = 1
# Optional externalJobID: Automatically generated if unspecified
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/pipelines.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/pipelines.md
similarity index 94%
rename from docs/chainlink-nodes/oracle-jobs/task-types/pipelines.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/pipelines.md
index 981e1773eef..d35ca87fb72 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/pipelines.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/pipelines.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Job Pipelines"
@@ -12,13 +12,13 @@ Pipelines are composed of tasks arranged in a DAG (directed acyclic graph). Pipe
Each node in the graph is a task with a user-specified ID and a set of configuration parameters and attributes:
-```jpv2
+```toml
my_fetch_task [type="http" method=GET url="https://chain.link/eth_usd"]
```
The edges between tasks define how data flows from one task to the next. Some tasks can have multiple inputs, such as `median`. Other tasks are limited to 0 (`http`) or 1 (`jsonparse`).
-```jpv2
+```toml
data_source_1 [type="http" method=GET url="https://chain.link/eth_usd"]
data_source_2 [type="http" method=GET url="https://coingecko.com/eth_usd"]
medianize_data [type="median"]
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_any.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_any.md
similarity index 91%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_any.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_any.md
index b392ba045cc..4eb9c89e5f0 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_any.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_any.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "'Any' Task"
@@ -22,7 +22,7 @@ A randomly-selected value from the set of inputs.
**Example**
-```jpv2
+```toml
fetch1 [type="http" ...]
fetch2 [type="http" ...]
fetch3 [type="http" ...]
@@ -34,4 +34,3 @@ fetch3 -> pick_any
```
`pick_any` will return either the result of `fetch1`, `fetch2`, or `fetch3`.
-
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_base64decode.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_base64decode.md
similarity index 89%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_base64decode.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_base64decode.md
index 32221295ca3..1add3a6e34f 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_base64decode.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_base64decode.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Base64 Decode Task"
@@ -18,7 +18,7 @@ Decoded bytes.
**Example**
-```jpv2
+```toml
my_base64decode_task [type="base64decode" input="SGVsbG8sIHBsYXlncm91bmQ="]
```
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_base64encode.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_base64encode.md
similarity index 89%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_base64encode.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_base64encode.md
index 57da8899391..d7ab32a3b4d 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_base64encode.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_base64encode.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Base64 Encode Task"
@@ -18,7 +18,7 @@ String with Base64 encoding of input.
**Example**
-```jpv2
+```toml
my_base64encode_task [type="base64encode" input="Hello, playground"]
```
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_bridge.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_bridge.md
similarity index 83%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_bridge.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_bridge.md
index 192fcd98091..ae77879bbdf 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_bridge.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_bridge.md
@@ -1,19 +1,19 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Bridge Task"
permalink: "docs/jobs/task-types/bridge/"
---
-Bridge tasks make HTTP POST requests to pre-configured URLs. Bridges can be configured via the UI or the CLI, and are referred to by a simple user-specified name. This is the way that most jobs interact with [External Adapters](/docs/external-adapters/).
+Bridge tasks make HTTP POST requests to pre-configured URLs. Bridges can be configured via the UI or the CLI, and are referred to by a simple user-specified name. This is the way that most jobs interact with [External Adapters](/chainlink-nodes/external-adapters/external-adapters/).
**Parameters**
- `name`: an arbitrary name given to the bridge by the node operator.
- `requestData` (optional): a statically-defined payload to be sent to the external adapter.
- `async` (optional): a boolean indicating whether the task should hibernate and wait for the Bridge to make an HTTP request back to the node at a later time with the result.
-- `cacheTTL` (optional): a duration-formatted string indicating the maximum acceptable staleness for cached bridge responses in case of intermittent failures. This is disabled by default.
+- `cacheTTL` (optional): a duration-formatted string indicating the maximum acceptable staleness for cached bridge responses in case of intermittent failures. This is disabled by default.
**Outputs**
@@ -21,7 +21,7 @@ A string containing the response body.
**Example**
-```jpv2
+```toml
my_bridge_task [type="bridge"
name="some_bridge"
requestData="{\\"data\\":{\\"foo\\": $(foo), \\"bar\\": $(bar)}}"
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_cborparse.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_cborparse.md
similarity index 88%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_cborparse.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_cborparse.md
index 05b133ab10d..cc3c68c9757 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_cborparse.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_cborparse.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "CBOR Parse Task"
@@ -19,7 +19,7 @@ A map containing the request parameters. Parameters can be individually accessed
**Example**
-```jpv2
+```toml
// First, we parse the request log and the CBOR payload inside of it
decode_log [type="ethabidecodelog"
data="$(jobRun.logData)"
@@ -36,4 +36,4 @@ parse [type="jsonparse" path="$(decode_cbor.jsonPath)" data="$(fetch)"]
// ... etc ...
```
-See the [Direct Request page](/docs/jobs/types/direct-request/) for a more comprehensive example.
+See the [Direct Request page](/chainlink-nodes/oracle-jobs/job-types/direct_request) for a more comprehensive example.
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_divide.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_divide.md
similarity index 70%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_divide.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_divide.md
index cd65d2246aa..d7fcfbe892f 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_divide.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_divide.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Divide Task"
@@ -11,20 +11,20 @@ Divides the provided `input` by the `divisor` and returns the result with a numb
**Parameters**
- `input`: The value to be divided
- - number
- - stringified number
- - bytes-ified number
- - `$(variable)`
+ - number
+ - stringified number
+ - bytes-ified number
+ - `$(variable)`
- `divisor`: The value by which to divide the `input`
- - number
- - stringified number
- - bytes-ified number
- - `$(variable)`
+ - number
+ - stringified number
+ - bytes-ified number
+ - `$(variable)`
- `precision`: The number of decimal places to retain in the result
- - number
- - stringified number
- - bytes-ified number
- - `$(variable)`
+ - number
+ - stringified number
+ - bytes-ified number
+ - `$(variable)`
**Outputs**
@@ -32,7 +32,7 @@ The result of the division.
**Example**
-```jpv2
+```toml
my_divide_task [type="divide"
input="$(json_parse_result)"
divisor="3"
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_decode.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_decode.md
similarity index 72%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_decode.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_decode.md
index 7f22c72469b..1c1b56a31a3 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_decode.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_decode.md
@@ -1,21 +1,21 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "ETH ABI Decode Task"
permalink: "docs/jobs/task-types/eth-abi-decode/"
---
-Decodes a ETH ABI-encoded payload, typically the result of an [ETH Call task](/docs/jobs/task-types/eth-call/).
+Decodes a ETH ABI-encoded payload, typically the result of an [ETH Call task](/chainlink-nodes/oracle-jobs/task-types/task_eth_call/).
**Parameters**
- `abi`: a canonical ETH ABI argument string. Should be formatted exactly as in Solidity. Each argument must be named. Examples:
- - `uint256 foo, bytes32 bar, address[] baz`
- - `address a, uint80[3][] u, bytes b, bytes32 b32`
+ - `uint256 foo, bytes32 bar, address[] baz`
+ - `address a, uint80[3][] u, bytes b, bytes32 b32`
- `data`: the ABI-encoded payload to decode. Can be:
- - a byte array
- - a hex-encoded string beginning with `0x`
+ - a byte array
+ - a hex-encoded string beginning with `0x`
**Outputs**
@@ -23,7 +23,8 @@ A map containing the decoded values.
**Example**
-```jpv2
+
+```toml
decode [type="ethabidecode"
abi="bytes32 requestID, uint256 price, address[] oracles"
data="$(eth_call_result)"]
@@ -31,6 +32,7 @@ decode [type="ethabidecode"
This task will return a map with the following schema:
+
```json
{
"requestID": ..., // [32]byte value
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_decode_log.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_decode_log.md
similarity index 55%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_decode_log.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_decode_log.md
index 7035dd338c8..0a90a34574a 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_decode_log.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_decode_log.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "ETH ABI Decode Log Task"
@@ -11,16 +11,16 @@ Decodes a log emitted by an ETH contract.
**Parameters**
- `abi`: a canonical ETH log event definition. Should be formatted exactly as in Solidity. Each argument must be named. Examples:
- - `NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt)`
- - `AuthorizedSendersChanged(address[] senders)`
+ - `NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt)`
+ - `AuthorizedSendersChanged(address[] senders)`
- `data`: the ABI-encoded log data. Can be:
- - a byte array
- - a hex-encoded string beginning with `0x`
- - ... but generally should just be set to `$(jobRun.logData)` (see the [Direct Request page](/docs/jobs/types/direct-request/))
+ - a byte array
+ - a hex-encoded string beginning with `0x`
+ - ... but generally should just be set to `$(jobRun.logData)` (see the [Direct Request page](/chainlink-nodes/oracle-jobs/job-types/direct_request))
- `topics`: the ABI-encoded log topics (i.e., the `indexed` parameters)
- - an array of bytes32 values
- - an array of hex-encoded bytes32 values beginning with `0x`
- - ... but generally should just be set to `$(jobRun.logTopics)` (see the [Direct Request page](/docs/jobs/types/direct-request/))
+ - an array of bytes32 values
+ - an array of hex-encoded bytes32 values beginning with `0x`
+ - ... but generally should just be set to `$(jobRun.logTopics)` (see the [Direct Request page](/chainlink-nodes/oracle-jobs/job-types/direct_request))
**Outputs**
@@ -28,7 +28,8 @@ A map containing the decoded values.
**Example**
-```jpv2
+
+```toml
decode [type="ethabidecodelog"
abi="NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt)"
data="$(jobRun.logData)"
@@ -37,6 +38,7 @@ decode [type="ethabidecodelog"
This task will return a map with the following schema:
+
```json
{
"roundId": ..., // a number
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_encode.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_encode.md
similarity index 70%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_encode.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_encode.md
index ee98e94a4e1..80d04cb9d22 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_encode.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_encode.md
@@ -1,18 +1,18 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "ETH ABI Encode Task"
permalink: "docs/jobs/task-types/eth-abi-encode/"
---
-Encodes a bytes payload according to ETH ABI encoding, typically in order to perform an [ETH Call](/docs/jobs/task-types/eth-call/) or an [ETH Tx](/docs/jobs/task-types/eth-tx/).
+Encodes a bytes payload according to ETH ABI encoding, typically in order to perform an [ETH Call](/chainlink-nodes/oracle-jobs/task-types/task_eth_call/) or an [ETH Tx](/chainlink-nodes/oracle-jobs/task-types/task_eth_tx/).
**Parameters**
- `abi`: a canonical ETH ABI argument string. Should be formatted exactly as in Solidity. Each argument must be named. If a method name is provided, the 4-byte method signature is prepended to the result. Examples:
- - `uint256 foo, bytes32 bar, address[] baz`
- - `fulfillRequest(bytes32 requestID, uint256 answer)`
+ - `uint256 foo, bytes32 bar, address[] baz`
+ - `fulfillRequest(bytes32 requestID, uint256 answer)`
- `data`: a map of the values to be encoded. The task will make a best effort at converting values to the appropriate types.
**Outputs**
@@ -21,7 +21,7 @@ A byte array.
**Example**
-```jpv2
+```toml
encode [type="ethabiencode"
abi="fulfillRequest(bytes32 requestID, uint256 answer)"
data="{\\"requestID\\": $(foo), \\"answer\\": $(bar)}"
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_eth_call.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_eth_call.md
similarity index 96%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_eth_call.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_eth_call.md
index d4bb997f9e2..abe7d64a262 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_eth_call.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_eth_call.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "ETH Call Task"
@@ -25,7 +25,7 @@ An ABI-encoded byte array containing the return value of the contract function.
**Example**
-```jpv2
+```toml
encode_call [type="ethabiencode"
abi="checkUpkeep(bytes data)"
data="{ \\"data\\": $(upkeep_data) }"]
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_eth_tx.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_eth_tx.md
similarity index 97%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_eth_tx.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_eth_tx.md
index 5f321463b93..2916bf9a70d 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_eth_tx.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_eth_tx.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "ETH Tx Task"
@@ -24,7 +24,7 @@ The hash of the transaction attempt that eventually succeeds (after potentially
**Example**
-```jpv2
+```toml
encode_tx [type="ethabiencode"
abi="performUpkeep(bytes performData)"
data="{ \\"data\\": $(upkeep_data) }"]
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_hexdecode.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_hexdecode.md
similarity index 89%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_hexdecode.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_hexdecode.md
index b403821fb9f..85440071fd1 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_hexdecode.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_hexdecode.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Hex Decode Task"
@@ -18,7 +18,7 @@ Decoded bytes.
**Example**
-```jpv2
+```toml
my_hexdecode_task [type="hexdecode" input="0x12345678"]
```
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_hexencode.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_hexencode.md
similarity index 90%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_hexencode.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_hexencode.md
index afabe2ed7b8..8d17656cd94 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_hexencode.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_hexencode.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Hex Encode Task"
@@ -18,7 +18,7 @@ Hexadecimal string prefixed with "0x" (or empty string if input was empty).
**Example**
-```jpv2
+```toml
my_hexencode_task [type="hexencode" input="xyz"]
```
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_http.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_http.md
similarity index 95%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_http.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_http.md
index ea3d39e3f64..f99da0aeac0 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_http.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_http.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "HTTP Task"
@@ -22,7 +22,7 @@ A string containing the response body.
**Example**
-```jpv2
+```toml
my_http_task [type="http"
method=PUT
url="http://chain.link"
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_jsonparse.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_jsonparse.md
similarity index 86%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_jsonparse.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_jsonparse.md
index bfdf520be86..34b0c681e00 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_jsonparse.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_jsonparse.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "JSON Parse Task"
@@ -11,8 +11,8 @@ JSON Parse tasks parse a JSON payload and extract a value at a given keypath.
**Parameters**
- `data`: the JSON string. Can be:
- - string
- - byte array
+ - string
+ - byte array
- `path`: the keypath to extract. Must be a comma-delimited list of keys, or specify a custom `separator` alternative.
- `separator`: (optional) custom `path` key separator. Defaults to comma (`,`).
- `lax` (optional): if false (or omitted), and the keypath doesn't exist, the task will error. If true, the task will return `nil` to the next task.
@@ -23,7 +23,7 @@ The value at the provided keypath.
**Example**
-```jpv2
+```toml
my_json_task [type="jsonparse"
data="$(http_fetch_result)"
path="data,0,price"]
@@ -33,9 +33,6 @@ This task returns `123.45` (float64) when given the following example `data` val
```json
{
- "data": [
- {"price": 123.45},
- {"price": 678.90},
- ]
+ "data": [{ "price": 123.45 }, { "price": 678.9 }]
}
```
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_length.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_length.md
similarity index 91%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_length.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_length.md
index a3bb7a08dd6..a1d68fc1bfb 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_length.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_length.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Length Task"
@@ -20,7 +20,7 @@ The length of the byte array or string.
**Example**
-```jpv2
+```toml
my_length_task [type="length" input="xyz"]
```
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_lessthan.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_lessthan.md
similarity index 63%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_lessthan.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_lessthan.md
index 681633428ba..9c1bee4744c 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_lessthan.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_lessthan.md
@@ -1,25 +1,25 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Less Than Task"
permalink: "docs/jobs/task-types/lessthan/"
---
-Returns a boolean, result of computing `left` < `right`.
+Returns a boolean, result of computing `left < right`.
**Parameters**
- `left`: the left hand side of comparison. Possible values:
- - number
- - stringified number
- - bytes-ified number
- - `$(variable)`
+ - number
+ - stringified number
+ - bytes-ified number
+ - `$(variable)`
- `right`: the right hand side of comparison. Possible values:
- - number
- - stringified number
- - bytes-ified number
- - `$(variable)`
+ - number
+ - stringified number
+ - bytes-ified number
+ - `$(variable)`
**Outputs**
@@ -27,7 +27,7 @@ The result of less than comparison.
**Example**
-```jpv2
+```toml
my_lessthan_task [type="lessthan" left="3" right="10"]
```
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_lowercase.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_lowercase.md
similarity index 87%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_lowercase.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_lowercase.md
index 00e383c326b..f5df22c6cab 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_lowercase.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_lowercase.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Lowercase Task"
@@ -18,7 +18,7 @@ Lowercase string.
**Example**
-```jpv2
+```toml
my_lowercase_task [type="lowercase" input="Hello World!"]
```
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_mean.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_mean.md
similarity index 93%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_mean.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_mean.md
index 0b4e6ed77bc..56805197f15 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_mean.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_mean.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Mean Task"
@@ -20,7 +20,7 @@ The average of the values in the `values` array.
**Example**
-```jpv2
+```toml
my_mean_task [type="mean"
values=<[ $(fetch1), $(fetch2), $(fetch3) ]>
precision=2
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_median.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_median.md
similarity index 93%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_median.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_median.md
index 8d55750cf3f..702c29945c7 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_median.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_median.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Median Task"
@@ -19,7 +19,7 @@ The median of the values in the `values` array.
**Example**
-```jpv2
+```toml
my_median_task [type="median"
values=<[ $(fetch1), $(fetch2), $(fetch3) ]>
allowedFaults=1]
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_mode.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_mode.md
similarity index 85%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_mode.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_mode.md
index 6cea4ca76f7..7155d4b6ebd 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_mode.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_mode.md
@@ -1,9 +1,9 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
-title: 'Mode Task'
-permalink: 'docs/jobs/task-types/mode/'
+title: "Mode Task"
+permalink: "docs/jobs/task-types/mode/"
---
Accepts multiple numerical inputs and returns the mode (most common) of them. If more than one value occur the maximum number of times, it returns all of them.
@@ -17,6 +17,7 @@ Accepts multiple numerical inputs and returns the mode (most common) of them. If
A map containing two keys:
+
```json
{
"results": [ ... ], // An array containing all of the values that occurred the maximum number of times
@@ -26,7 +27,8 @@ A map containing two keys:
**Example**
-```jpv2
+
+```toml
my_mode_task [type="mode"
values=<[ $(fetch1), $(fetch2), $(fetch3), $(fetch4), $(fetch5), $(fetch6), $(fetch7), $(fetch8) ]>
allowedFaults=3]
@@ -34,6 +36,7 @@ my_mode_task [type="mode"
Given a `values` array containing `[ 2, 5, 2, "foo", "foo" "bar", "foo", 2 ]`, the task will return:
+
```json
{
"results": [2, "foo"],
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_multiply.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_multiply.md
similarity index 70%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_multiply.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_multiply.md
index 3fa127569d4..57090100b7b 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_multiply.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_multiply.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Multiply Task"
@@ -11,15 +11,15 @@ Multiplies the provided `input` and `times` values.
**Parameters**
- `input`: the value to be multipled. Possible values:
- - number
- - stringified number
- - bytes-ified number
- - `$(variable)`
+ - number
+ - stringified number
+ - bytes-ified number
+ - `$(variable)`
- `times`: the value to multiply the input with.
- - number
- - stringified number
- - bytes-ified number
- - `$(variable)`
+ - number
+ - stringified number
+ - bytes-ified number
+ - `$(variable)`
**Outputs**
@@ -27,9 +27,8 @@ The result of the multiplication.
**Example**
-```jpv2
+```toml
my_multiply_task [type="multiply" input="$(json_parse_result)" times=3]
```
Given the input `10`, the task will return `30`.
-
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_sum.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_sum.md
similarity index 92%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_sum.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_sum.md
index 206c619ccd5..1173f6f5ad8 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_sum.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_sum.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Sum Task"
@@ -19,7 +19,7 @@ The sum of the values in the `values` array.
**Example**
-```jpv2
+```toml
my_sum_task [type="sum"
values=<[ $(fetch1), $(fetch2), $(fetch3) ]>
allowedFaults=1]
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/task_uppercase.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_uppercase.md
similarity index 87%
rename from docs/chainlink-nodes/oracle-jobs/task-types/task_uppercase.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/task_uppercase.md
index f791ac086c5..d8455628c55 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/task_uppercase.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/task_uppercase.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Uppercase Task"
@@ -18,7 +18,7 @@ Uppercase string.
**Example**
-```jpv2
+```toml
my_uppercase_task [type="uppercase" input="Hello World!"]
```
diff --git a/docs/chainlink-nodes/oracle-jobs/task-types/tasks.md b/src/pages/chainlink-nodes/oracle-jobs/task-types/tasks.md
similarity index 64%
rename from docs/chainlink-nodes/oracle-jobs/task-types/tasks.md
rename to src/pages/chainlink-nodes/oracle-jobs/task-types/tasks.md
index 8db8c48b5c2..0bd37610a1a 100644
--- a/docs/chainlink-nodes/oracle-jobs/task-types/tasks.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/task-types/tasks.md
@@ -1,5 +1,5 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Tasks"
@@ -8,11 +8,13 @@ permalink: "docs/tasks/"
## What is a Task?
-> 📘 Tasks replace the [core adapters](/docs/core-adapters/) from v1 jobs.
+:::note[Tasks]
+Tasks replace the [core adapters](/chainlink-nodes/oracle-jobs/v1/adapters/) from v1 jobs.
+:::
-Tasks are a replacement for core adapters that is more flexible. Tasks can be composed in arbitrary order into [pipelines](/docs/jobs/task-types/pipelines/). Pipelines consist of one or more threads of execution where tasks are executed in a well-defined order.
+Tasks are a replacement for core adapters that is more flexible. Tasks can be composed in arbitrary order into [pipelines](/chainlink-nodes/oracle-jobs/task-types/pipelines/). Pipelines consist of one or more threads of execution where tasks are executed in a well-defined order.
-Chainlink has a number of built-in tasks which are listed below. You can also create your own [external adapters](/docs/external-adapters/) for tasks which are accessed through a `bridge`.
+Chainlink has a number of built-in tasks which are listed below. You can also create your own [external adapters](/chainlink-nodes/external-adapters/external-adapters/) for tasks which are accessed through a `bridge`.
## Shared attributes
@@ -20,7 +22,7 @@ All tasks share a few common attributes:
`index`: when a task has more than one input (or the pipeline overall needs to support more than one final output), and the ordering of the values matters, the index parameter can be used to specify that ordering.
-```jpv2
+```toml
data_1 [type="http" method=GET url="https://chain.link/eth_usd" index=0]
data_2 [type="http" method=GET url="https://chain.link/eth_dominance" index=1]
multiword_abi_encode [type="eth_abi_encode" method="fulfill(uint256,uint256)"]
diff --git a/docs/chainlink-nodes/oracle-jobs/v1/adapters.md b/src/pages/chainlink-nodes/oracle-jobs/v1/adapters.md
similarity index 78%
rename from docs/chainlink-nodes/oracle-jobs/v1/adapters.md
rename to src/pages/chainlink-nodes/oracle-jobs/v1/adapters.md
index 60cf5e86c60..368e85e6ccc 100644
--- a/docs/chainlink-nodes/oracle-jobs/v1/adapters.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/v1/adapters.md
@@ -1,18 +1,22 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: legacy
date: Last Modified
-title: 'Core Adapters [v1]'
-permalink: 'docs/core-adapters/'
-whatsnext: { 'Introduction to External Adapters': '/docs/external-adapters/', 'Initiators': '/docs/initiators/' }
+title: "Core Adapters [v1]"
+permalink: "docs/core-adapters/"
+whatsnext:
+ {
+ "Introduction to External Adapters": "/chainlink-nodes/external-adapters/external-adapters/",
+ "Initiators": "/chainlink-nodes/oracle-jobs/v1/initiators/",
+ }
---
# REMOVED
-> ❗️ v1 Jobs are removed
-> The adapters or JSON adapters for v1 Jobs are removed for Chainlink nodes running version 1.0.0 and later. Use [v2 job tasks](/docs/tasks) instead.
->
-> See the [v2 jobs migration page](/docs/jobs/migration-v1-v2) to learn how to migrate to v2 jobs.
+:::caution[v1 Jobs are removed]
+The initiators for v1 Jobs are removed for Chainlink nodes running version 1.0.0 and later. Use [v2 job types](/chainlink-nodes/oracle-jobs/jobs) instead.
+See the [v2 jobs migration page](/chainlink-nodes/oracle-jobs/migration-v1-v2) to learn how to migrate to v2 jobs.
+:::
## Adapters
@@ -46,6 +50,7 @@ This core adapter compares a user-specified value with the value from the previo
#### Solidity Example
+
```solidity
req.addInt("value", 10000);
req.add("operator", "gte");
@@ -53,7 +58,7 @@ req.add("operator", "gte");
## Copy
-The core adapter walks the `copyPath` specified and returns the value found at that result. If returning JSON data from an [external adapter](../external-adapters/), you will need to use this adapter to parse the response.
+The core adapter walks the `copyPath` specified and returns the value found at that result. If returning JSON data from an [external adapter](/chainlink-nodes/external-adapters/external-adapters/), you will need to use this adapter to parse the response.
#### Parameters
@@ -63,14 +68,16 @@ The core adapter walks the `copyPath` specified and returns the value found at t
For the JSON object:
+
```json
{ "RAW": { "ETH": { "USD": { "LASTMARKET": "_someValue" } } } }
```
You would use the following for an array of strings:
+
```solidity
-string[] memory path = new string[](4);
+string[] memory path = new string(4);
path[0] = "RAW";
path[1] = "ETH";
path[2] = "USD";
@@ -80,14 +87,18 @@ req.addStringArray("copyPath", path);
Or the following for a single comma-delimited string:
+
```solidity
req.add("copyPath", "RAW,ETH,USD,LASTMARKET");
```
-> Note: Chainlink nodes prior to `1.0.0` supported dot delimited strings instead of commas.
+:::note
+Chainlink nodes prior to `1.0.0` supported dot delimited strings instead of commas.
+:::
#### Job Specification Example
+
```json
{
"type": "Copy",
@@ -99,12 +110,14 @@ req.add("copyPath", "RAW,ETH,USD,LASTMARKET");
For arrays, you can access the path of an array by using the index. If this is your JSON:
+
```json
{ "endpoint": [{ "path": "value" }] }
```
You could get the `"value"` by:
+
```solidity
req.add("copyPath", "endpoint.0.path");
```
@@ -165,12 +178,13 @@ The core adapter will report the body of a successful `GET` request to the speci
- `extPath`: takes a slash-delimited string or array of strings to be appended to the job's URL.
- `headers`: takes a object containing keys as strings and values as arrays of strings.
-> 🚧 Headers
->
-> Currently not available on-chain. Available for job specs only.
+:::note[Headers]
+Currently not available on-chain. Available for job specs only.
+:::
#### Solidity Example
+
```solidity
req.add("get", "http://example.com");
req.add("queryParams", "firstKey=firstVal&secondKey=secondVal");
@@ -179,6 +193,7 @@ req.add("extPath", "price/BTC/USD");
#### Job Specification Example
+
```json
{
"type": "HttpGet",
@@ -191,7 +206,9 @@ req.add("extPath", "price/BTC/USD");
}
```
-> 🚧 For security, because the URL can come from an untrusted source, 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.
+:::note[Local network and multicast IPs are disallowed by default]
+For security, because the URL can come from an untrusted source, 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.
+:::
If you really must access one of these IPs, you can use the `HTTPGetWithUnrestrictedNetworkAccess` adapter instead.
@@ -207,12 +224,13 @@ The core adapter will report the body of a successful `POST` request to the spec
- `extPath`: takes a slash-delimited string or array of strings to be appended to the job's URL.
- `body`: the JSON body (as a string) that will be used as the data in the request.
-> 🚧 Headers & Body
->
-> Currently not available on-chain. Available for job specs only.
+:::note[Headers & Body]
+Currently not available on-chain. Available for job specs only.
+:::
#### Solidity Example
+
```solidity
req.add("post", "http://post.example.com");
req.add("queryParams", "firstKey=firstVal&secondKey=secondVal");
@@ -235,13 +253,15 @@ req.add("extPath", "price/BTC/USD");
}
```
-> 🚧 For security, because the URL can come from an untrusted source, HTTPPost imposes some restrictions on which IPs can be fetched. Local network and multicast IPs are disallowed by default and attempting to connect will result in an error.
+:::note[Local network and multicast IPs are disallowed by default]
+For security, because the URL can come from an untrusted source, 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.
+:::
If you really must access one of these IPs, you can use the `HTTPPostWithUnrestrictedNetworkAccess` adapter instead.
## JsonParse
-The core adapter walks the `path` specified and returns the value found at that result. If returning JSON data from the [HttpGet](../core-adapters/#httpget) or [HttpPost](../core-adapters/#httppost) adapters, you must use this adapter to parse the response.
+The core adapter walks the `path` specified and returns the value found at that result. If returning JSON data from the [HttpGet](/chainlink-nodes/oracle-jobs/v1/adapters/#httpget) or [HttpPost](/chainlink-nodes/oracle-jobs/v1/adapters/#httppost) adapters, you must use this adapter to parse the response.
#### Parameters
@@ -251,12 +271,14 @@ The core adapter walks the `path` specified and returns the value found at that
For the stringified JSON:
+
```json
{ "RAW": { "ETH": { "USD": { "LASTMARKET": "_someValue" } } } }
```
You would use the following for an array of strings:
+
```solidity
string[] memory path = new string[](4);
path[0] = "RAW";
@@ -268,14 +290,18 @@ req.addStringArray("path", path);
Or the following for a single comma-delimited string:
+
```solidity
req.add("path", "RAW,ETH,USD,LASTMARKET");
```
-> 🚧 Note: Chainlink nodes prior to 1.0.0 support dot-delimited strings instead of comma-delimited strings.
+:::note
+Chainlink nodes prior to 1.0.0 support dot-delimited strings instead of comma-delimited strings.
+:::
#### Job Specification Example
+
```json
{
"type": "JsonParse",
@@ -287,31 +313,33 @@ req.add("path", "RAW,ETH,USD,LASTMARKET");
#### Parsing Arrays
+
```solidity
req.add("path", "3,standardId");
```
The above example parses the 4th object of the following JSON response and returns 677 as a result:
+
```javascript
-[
+;[
{
standardId: 20,
- name: 'ERC-20',
+ name: "ERC-20",
},
{
standardId: 721,
- name: 'ERC-721',
+ name: "ERC-721",
},
{
standardId: 1155,
- name: 'ERC-1155',
+ name: "ERC-1155",
},
{
standardId: 677,
- name: 'ERC-677',
+ name: "ERC-677",
},
-];
+]
```
## Multiply
@@ -324,6 +352,7 @@ The core adapter parses the input into a float and then multiplies it by the `ti
#### Solidity Example
+
```solidity
run.addInt("times", 100);
```
@@ -360,9 +389,9 @@ This can be useful for inverting outputs, e.g. if your API only offers a USD/ETH
The core adapter will pause the current task pipeline for the given duration.
-> 🚧 ENABLE_EXPERIMENTAL_ADAPTERS
->
-> You must set `ENABLE_EXPERIMENTAL_ADAPTERS=true` in order to use the sleep adapter
+:::note[ENABLE_EXPERIMENTAL_ADAPTERS]
+You must set `ENABLE_EXPERIMENTAL_ADAPTERS=true` in order to use the sleep adapter.
+:::
#### Parameters
@@ -370,12 +399,14 @@ The core adapter will pause the current task pipeline for the given duration.
#### Solidity Example
+
```solidity
req.addUint("until", now + 1 hours);
```
#### Job Specification example
+
```
{
"initiators": [
diff --git a/docs/chainlink-nodes/oracle-jobs/v1/initiators.md b/src/pages/chainlink-nodes/oracle-jobs/v1/initiators.md
similarity index 67%
rename from docs/chainlink-nodes/oracle-jobs/v1/initiators.md
rename to src/pages/chainlink-nodes/oracle-jobs/v1/initiators.md
index 03ad9edde78..8442c387f4f 100644
--- a/docs/chainlink-nodes/oracle-jobs/v1/initiators.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/v1/initiators.md
@@ -1,18 +1,19 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: legacy
date: Last Modified
title: "Initiators [v1]"
permalink: "docs/initiators/"
-whatsnext: {"Introduction to External Initiators":"/docs/external-initiators-introduction/"}
+whatsnext:
+ { "Introduction to External Initiators": "/chainlink-nodes/external-initiators/external-initiators-introduction/" }
---
# REMOVED
-> ❗️ v1 Jobs are removed
-> The initiators for v1 Jobs are removed for Chainlink nodes running version 1.0.0 and later. Use [v2 job types](/docs/jobs) instead.
->
-> See the [v2 jobs migration page](/docs/jobs/migration-v1-v2) to learn how to migrate to v2 jobs.
+:::caution[v1 Jobs are removed]
+The initiators for v1 Jobs are removed for Chainlink nodes running version 1.0.0 and later. Use [v2 job types](/chainlink-nodes/oracle-jobs/jobs) instead.
+See the [v2 jobs migration page](/chainlink-nodes/oracle-jobs/migration-v1-v2) to learn how to migrate to v2 jobs.
+:::
## Initiators
@@ -22,10 +23,11 @@ The `Cron` initiator is a simple way to schedule recurring job runs, using [stan
### Cron Parameters
-`Cron` takes one parameter, `schedule` which is a cron like schedule string. The `Cron`‘s `schedule` is follows [standard cron syntax](https://en.wikipedia.org/wiki/Cron#Overview) but prepends an timezone to be specified with `CRON_TZ`, with an optional field for seconds. For example: `CRON_TZ=UTC */10 * * * *` would run every 10 minutes with the timezone set to UTC. `CRON_TZ=UTC */30 * * * * *` would run every 30 seconds.
+`Cron` takes one parameter, `schedule` which is a cron like schedule string. The `Cron`‘s `schedule` is follows [standard cron syntax](https://en.wikipedia.org/wiki/Cron#Overview) but prepends an timezone to be specified with `CRON_TZ`, with an optional field for seconds. For example: `CRON_TZ=UTC */10 * * * *` would run every 10 minutes with the timezone set to UTC. `CRON_TZ=UTC */30 * * * * *` would run every 30 seconds.
### Example
+
```json cron
"initiators": [
{
@@ -47,6 +49,7 @@ The `EthLog` initiator creates an Ethereum log filter, and when any log comes in
### Example
+
```json ethlog
"initiators": [
{
@@ -58,7 +61,7 @@ The `EthLog` initiator creates an Ethereum log filter, and when any log comes in
## External
-The external initiator works like the [web](../initiators/#web) initiator, but is given its own credentials along with a name and URL.
+The external initiator works like the [web](/chainlink-nodes/oracle-jobs/v1/initiators/#web) initiator, but is given its own credentials along with a name and URL.
You can create an external initiator by running the `chainlink initiators create NAME URL` command. This will give you an access key and secret pair, which will be used for incoming requests to invoke a job with this external initiator, and an outgoing token and secret pair which optionally can be used to help the Chainlink node authenticate with external services. Any incoming requests must provide the access key and secret in order to invoke the job run.
@@ -68,6 +71,7 @@ You can create an external initiator by running the `chainlink initiators create
### Example
+
```json external
"initiators": [
{
@@ -87,7 +91,7 @@ The `fluxmonitor` initiator performs 3 functions:
2. Using that aggregated result to determine if an on-chain update needs to be made (as defined by a threshold)
3. Updates on-chain values based on a heartbeat
-The `fluxmonitor` is the current initiator used by the [Chainlink Data Feeds](https://data.chain.link/)
+The `fluxmonitor` is the current initiator used by the [Chainlink Data Feeds](https://data.chain.link/)
### FluxMonitor Parameters
@@ -102,39 +106,40 @@ The `fluxmonitor` is the current initiator used by the [Chainlink Data Feeds](h
### Example
+
```json
{
- "type": "fluxmonitor",
- "params": {
- "address": "0x7777a77dea5ee3c093e21d77660b5579c21f770b",
- "requestData": {
- "data": {
- "from": "DAI",
- "to": "ETH"
- }
- },
- "feeds": [
- {
- "bridge": "cryptocompare_cl_ea"
- },
- {
- "bridge": "amberdata_cl_ea"
- },
- {
- "bridge": "coinapi_cl_ea"
- }
- ],
- "threshold": 1,
- "absoluteThreshold": 0,
- "precision": 18,
- "pollTimer": {
- "period": "1m0s"
- },
- "idleTimer": {
- "duration": "24h0m0s"
- }
+ "type": "fluxmonitor",
+ "params": {
+ "address": "0x7777a77dea5ee3c093e21d77660b5579c21f770b",
+ "requestData": {
+ "data": {
+ "from": "DAI",
+ "to": "ETH"
+ }
+ },
+ "feeds": [
+ {
+ "bridge": "cryptocompare_cl_ea"
+ },
+ {
+ "bridge": "amberdata_cl_ea"
+ },
+ {
+ "bridge": "coinapi_cl_ea"
}
+ ],
+ "threshold": 1,
+ "absoluteThreshold": 0,
+ "precision": 18,
+ "pollTimer": {
+ "period": "1m0s"
+ },
+ "idleTimer": {
+ "duration": "24h0m0s"
}
+ }
+}
```
## RunAt
@@ -147,6 +152,7 @@ The `RunAt` initiator triggers a one off job run at the time specified.
### Example
+
```json runat
"initiators": [
{
@@ -168,10 +174,11 @@ A new run created by a `RunLog` is automatically given the parameters needed for
### RunLog Parameters
-`RunLog` initiators take an optional `address` parameter and `requesters` parameter. The `address` parameter is a single Ethereum address and the `requesters` parameter is an array of Ethereum addresses. By adding the `address` parameter, you make the event filter of the RunLog initiator more restrictive, only listening for events from that address, instead of any address. By adding the `requesters` parameter, you only allow requests to come from an address within the array.
+`RunLog` initiators take an optional `address` parameter and `requesters` parameter. The `address` parameter is a single Ethereum address and the `requesters` parameter is an array of Ethereum addresses. By adding the `address` parameter, you make the event filter of the RunLog initiator more restrictive, only listening for events from that address, instead of any address. By adding the `requesters` parameter, you only allow requests to come from an address within the array.
### Example
+
```json runlog
"initiators": [
{
@@ -191,8 +198,9 @@ A new run created by a `RunLog` is automatically given the parameters needed for
The `Web` initiator enables jobs to be triggered via web requests, specifically `POST`s to `/v2/specs/:jobID/runs`. Requests coming in to create new job runs must be authenticated by cookie.
-> ℹℹ NOTE
-> For convenience, there is a "Run" button in the operator web UI for the job which will trigger a job run.
+:::note
+For convenience, there is a "Run" button in the operator web UI for the job which will trigger a job run.
+:::
### Web Parameters
@@ -200,6 +208,7 @@ The `Web` initiator enables jobs to be triggered via web requests, specifically
### Example
+
```json web
"initiators": [
{
diff --git a/docs/chainlink-nodes/oracle-jobs/v1/job-specifications.md b/src/pages/chainlink-nodes/oracle-jobs/v1/job-specifications.md
similarity index 67%
rename from docs/chainlink-nodes/oracle-jobs/v1/job-specifications.md
rename to src/pages/chainlink-nodes/oracle-jobs/v1/job-specifications.md
index 99530e97d05..a25b5c7717d 100644
--- a/docs/chainlink-nodes/oracle-jobs/v1/job-specifications.md
+++ b/src/pages/chainlink-nodes/oracle-jobs/v1/job-specifications.md
@@ -1,30 +1,34 @@
---
-layout: nodes.liquid
+layout: ../../../../layouts/MainLayout.astro
section: legacy
date: Last Modified
title: "Job Specifications [v1]"
permalink: "docs/job-specifications/"
-whatsnext: {"Core Adapters":"/docs/core-adapters/", "Initiators":"/docs/initiators/"}
+whatsnext:
+ {
+ "Core Adapters": "/chainlink-nodes/oracle-jobs/v1/adapters/",
+ "Initiators": "/chainlink-nodes/oracle-jobs/v1/initiators/",
+ }
---
# REMOVED
-> ❗️ v1 Jobs are removed
-> The v1 job spec or JSON spec removed for Chainlink nodes running version 1.0.0 and later. If you are still running this type of job, migrate them to v2 specs.
->
-> See the [v2 jobs migration page](/docs/jobs/migration-v1-v2) to learn how to migrate to v2 jobs.
+:::caution[v1 Jobs are removed]
+The v1 job spec or JSON spec removed for Chainlink nodes running version 1.0.0 and later. If you are still running this type of job, migrate them to v2 specs.
+See the [v2 jobs migration page](/chainlink-nodes/oracle-jobs/migration-v1-v2) to learn how to migrate to v2 jobs.
+:::
## What is a job?
Job specifications, or specs, contain the sequential tasks that the node must perform to produce a final result. Chainlink jobs are divided into 2 segments.
-- [Initiators](/docs/initiators/)
-- [Adapters](/docs/core-adapters/) (also known as tasks)
+- [Initiators](/chainlink-nodes/oracle-jobs/v1/initiators/)
+- [Adapters](/chainlink-nodes/oracle-jobs/v1/adapters/) (also known as tasks)
A job must contain at least one of each.
-**Initiators** define *when* a job will run.
-**Adapters** define *how* a job will run.
+**Initiators** define _when_ a job will run.
+**Adapters** define _how_ a job will run.
Specs are defined using standard JSON so that they are human-readable and can be easily parsed by the Chainlink node.
@@ -46,7 +50,7 @@ Here is an example of a spec:
},
{
"type": "JSONParse",
- "params": { "path": [ "last" ] }
+ "params": { "path": ["last"] }
},
{
"type": "Multiply",
@@ -61,11 +65,11 @@ Here is an example of a spec:
}
```
-This example shows the two main components of a spec: initiators and tasks. [Initiators](../glossary/#initiator) determine how the spec will start. [Tasks](../glossary/#task-spec) are the individual steps that the Chainlink node follows to process data in order to produce a result.
+This example shows the two main components of a spec: initiators and tasks. [Initiators](/resources/glossary/#initiator) determine how the spec will start. [Tasks](/resources/glossary/#task-spec) are the individual steps that the Chainlink node follows to process data in order to produce a result.
In the example above, we see that the only initiator is a RunLog. This means that the spec can only be started when a specific event log is emitted from a specified address. The specified address will be the address of the oracle contract on Ropsten, which manages requests from contracts and responses from Chainlink nodes.
-The five tasks (referred to as [core adapters](../core-adapters/)) in the example above follow a common pattern for requesting data from the Chainlink network, and returning a single result. Each task takes three fields: `type`, `confirmations`, and `params`. The `type` is the adapter or [bridge](../glossary/#bridge) name and is required. `confirmations` is optional, and will default to 0. `params` is also optional, and will default to an empty object if not specified. See the [core adapters](../core-adapters/) page for a complete list of `params` for each adapter.
+The five tasks (referred to as [core adapters](/chainlink-nodes/oracle-jobs/v1/adapters/)) in the example above follow a common pattern for requesting data from the Chainlink network, and returning a single result. Each task takes three fields: `type`, `confirmations`, and `params`. The `type` is the adapter or [bridge](/resources/glossary/#bridge) name and is required. `confirmations` is optional, and will default to 0. `params` is also optional, and will default to an empty object if not specified. See the [core adapters](/chainlink-nodes/oracle-jobs/v1/adapters/) page for a complete list of `params` for each adapter.
1. The **HTTPGet** adapter uses the value in the `get` field to perform a standard HTTP GET request at the value specified. The body of that result is passed on to the next task, JSONParse.
2. The **JSONParse** adapter takes a dot-delimited string or an array of strings, and will walk the given path to store the value at the end. In this case, there is only one field to save, "last". JSONParse will then pass the value stored in the "last" field to the Multiply adapter.
@@ -76,6 +80,7 @@ The five tasks (referred to as [core adapters](../core-adapters/)) in the exampl
Note: If specifying multiple adapters of the same type, the parameters can be specified in the job spec itself if the key values need to be different. The requester can also use run parameters for these requests, but shared keys will be the same for any adapter that uses them.
Additional parameters may be specified on the job as well. These include:
+
- **startAt**: The beginning date at which the job can be executed, specified in ISO 8601 standard. Jobs can not be ran before this date. Defaults to null if unspecified.
- **endAt**: The ending date at which the job can be executed, specified in ISO 8601 standard. Jobs can not be ran after this date. Defaults to null if unspecified.
- **minPayment**: The payment amount for this job, specified in LINK to the 18th decimal. If supplied, this will override the global `MIN_CONTRACT_PAYMENT` configuration set on the node, regardless if the value is lower or higher.
diff --git a/docs/chainlink-nodes/performing-system-maintenance.md b/src/pages/chainlink-nodes/performing-system-maintenance.md
similarity index 90%
rename from docs/chainlink-nodes/performing-system-maintenance.md
rename to src/pages/chainlink-nodes/performing-system-maintenance.md
index ac0b597d9a3..6361294c9b6 100644
--- a/docs/chainlink-nodes/performing-system-maintenance.md
+++ b/src/pages/chainlink-nodes/performing-system-maintenance.md
@@ -1,19 +1,19 @@
---
-layout: nodes.liquid
+layout: ../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
title: "Performing System Maintenance"
permalink: "docs/performing-system-maintenance/"
-whatsnext: {"Connecting to a Remote Database":"/docs/connecting-to-a-remote-database/"}
+whatsnext: { "Connecting to a Remote Database": "/chainlink-nodes/connecting-to-a-remote-database/" }
---
You might occasionally need to restart the system that the Chainlink node runs on. To restart without any downtime for completing requests, perform the upgrade as a series of steps that passes database access to a new instance while the first instance is down.
## Maintenance and Image Update Example
-> 📘 Note
->
-> This example uses Docker to run the Chainlink node, see the [Running a Chainlink Node](../running-a-chainlink-node/) page for instructions on how to set it up.
+:::note[Docker]
+This example uses Docker to run the Chainlink node, see the [Running a Chainlink Node](/chainlink-nodes/running-a-chainlink-node/) page for instructions on how to set it up.
+:::
First, find the most recent Chainlink image on [Docker Hub](https://hub.docker.com/r/smartcontract/chainlink/) and pull that Docker image. For version 1.1.0:
@@ -41,6 +41,7 @@ Now start the second instance of the node. The local port option has been modifi
```shell Goerli
cd ~/.chainlink-goerli && docker run -p 6687:6688 -v ~/.chainlink-goerli:/chainlink -it --env-file=.env smartcontract/chainlink local n
```
+
```shell Mainnet
cd ~/.chainlink && docker run -p 6687:6688 -v ~/.chainlink:/chainlink -it --env-file=.env smartcontract/chainlink local n
```
@@ -62,6 +63,7 @@ Next, you will simply need to run the container again with the local port 6688 i
```shell Goerli
cd ~/.chainlink-goerli && docker run -p 6688:6688 -v ~/.chainlink-goerli:/chainlink -it --env-file=.env smartcontract/chainlink local n
```
+
```shell Mainnet
cd ~/.chainlink && docker run -p 6688:6688 -v ~/.chainlink:/chainlink -it --env-file=.env smartcontract/chainlink local n
```
@@ -70,19 +72,20 @@ When the log messages on the first node indicate that it is waiting for the data
## Failover Node Example
-> 📘 Note
->
-> This example uses Docker to run the Chainlink node, see the [Running a Chainlink Node](../running-a-chainlink-node/) page for instructions on how to set it up.
+:::note[Docker]
+This example uses Docker to run the Chainlink node, see the [Running a Chainlink Node](/chainlink-nodes/running-a-chainlink-node/) page for instructions on how to set it up.
+:::
You might want to run multiple instances of the Chainlink node on the same machine. If one instance goes down, the second instance can automatically pick up requests. Building off the concepts in the previous example, use Docker to have primary and a secondary containers referencing the same database URL.
-Use the default `DATABASE_LOCKING_MODE=advisorylock` setting unless you want to test the `lease` or `dual` settings. See [the docs](/docs/configuration-variables/#database_locking_mode) for more information about this configuration variable.
+Use the default `DATABASE_LOCKING_MODE=advisorylock` setting unless you want to test the `lease` or `dual` settings. See [the docs](/chainlink-nodes/configuration-variables/#database_locking_mode) for more information about this configuration variable.
Run the Chainlink node with a name option specified:
```shell Goerli
cd ~/.chainlink-goerli && docker run --name chainlink -p 6688:6688 -v ~/.chainlink-goerli:/chainlink -it --env-file=.env smartcontract/chainlink local n
```
+
```shell Mainnet
cd ~/.chainlink && docker run --name chainlink -p 6688:6688 -v ~/.chainlink:/chainlink -it --env-file=.env smartcontract/chainlink local n
```
@@ -105,6 +108,7 @@ This will remain your primary Chainlink container, and should always use port 66
```shell Goerli
cd ~/.chainlink-goerli && docker run --name secondary -p 6687:6688 -v ~/.chainlink-goerli:/chainlink -it --env-file=.env smartcontract/chainlink local n
```
+
```shell Mainnet
cd ~/.chainlink && docker run --name secondary -p 6687:6688 -v ~/.chainlink:/chainlink -it --env-file=.env smartcontract/chainlink local n
```
diff --git a/src/pages/chainlink-nodes/proof-of-reserves-btc.md b/src/pages/chainlink-nodes/proof-of-reserves-btc.md
new file mode 100644
index 00000000000..a603cfa642c
--- /dev/null
+++ b/src/pages/chainlink-nodes/proof-of-reserves-btc.md
@@ -0,0 +1,522 @@
+---
+layout: ../../layouts/MainLayout.astro
+section: nodeOperator
+date: Last Modified
+title: "Proof of Reserves (BTC)"
+permalink: "docs/proof-of-reserves-btc/"
+hidden: true
+---
+
+In order to contribute to the price aggregator contract, you will need to run external adapters for the provider you have been assigned. The Chainlink team will let you know which API to provide, and you can use this page as a guide for adding jobs to your node.
+
+External adapters can be found [here](https://github.com/smartcontractkit/external-adapters-js).
+
+Follow the instructions in the README to run the adapter in your infrastructure. You may need to obtain an API key for the data provider assigned to you. Follow [these instructions](/chainlink-nodes/external-adapters/node-operators/) for adding the external adapter as a bridge to your node.
+
+First, add a test job to your node which uses the Web initiator so that you can validate that the job will run successfully. Rename bridge names if required.
+
+```json Test RenVM & Blockcypher
+{
+ "initiators": [
+ {
+ "type": "web"
+ }
+ ],
+ "tasks": [
+ {
+ "type": "renvm-address-set",
+ "params": {
+ "network": "mainnet",
+ "tokenOrContract": "btc"
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "blockcypher",
+ "params": {
+ "dataPath": "result",
+ "endpoint": "balance",
+ "confirmations": 6
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "reduce",
+ "params": {
+ "reducer": "sum",
+ "dataPath": "result",
+ "valuePath": "balance",
+ "initialValue": 0
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "ethint256"
+ }
+ ]
+}
+```
+
+```json Test wBTC & Blockcypher
+{
+ "initiators": [
+ {
+ "type": "web"
+ }
+ ],
+ "tasks": [
+ {
+ "type": "wbtc-address-set",
+ "params": {
+ "network": "mainnet",
+ "tokenOrContract": "btc"
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "blockcypher",
+ "params": {
+ "dataPath": "result",
+ "endpoint": "balance",
+ "confirmations": 6
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "reduce",
+ "params": {
+ "reducer": "sum",
+ "dataPath": "result",
+ "valuePath": "balance",
+ "initialValue": 0
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "ethint256"
+ }
+ ]
+}
+```
+
+```json Test RenVM & Blockchain.com
+{
+ "initiators": [
+ {
+ "type": "web"
+ }
+ ],
+ "tasks": [
+ {
+ "type": "renvm-address-set",
+ "params": {
+ "network": "mainnet",
+ "tokenOrContract": "btc"
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "blockchain-com",
+ "params": {
+ "dataPath": "result",
+ "endpoint": "balance",
+ "confirmations": 0
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "reduce",
+ "params": {
+ "reducer": "sum",
+ "dataPath": "result",
+ "valuePath": "balance",
+ "initialValue": 0
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "ethint256"
+ }
+ ]
+}
+```
+
+```json Test wBTC & Blockchain.com
+{
+ "initiators": [
+ {
+ "type": "web"
+ }
+ ],
+ "tasks": [
+ {
+ "type": "wbtc-address-set",
+ "params": {
+ "network": "mainnet",
+ "tokenOrContract": "btc"
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "blockchain-com",
+ "params": {
+ "dataPath": "result",
+ "endpoint": "balance",
+ "confirmations": 0
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "reduce",
+ "params": {
+ "reducer": "sum",
+ "dataPath": "result",
+ "valuePath": "balance",
+ "initialValue": 0
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "ethint256"
+ }
+ ]
+}
+```
+
+On the Job Spec Detail page for the job, click the Run button. You should see a green bar at the top that the node Successfully created job run `JobRunID`. Click on that Job Run ID and verify that all tasks have been Completed with green check marks.
+
+```json
+{
+ "images": [
+ {
+ "image": [
+ "/files/8cfc185-Screenshot_from_2019-06-21_08-29-07.png",
+ "Screenshot from 2019-06-21 08-29-07.png",
+ 1894,
+ 806,
+ "#fafafb"
+ ]
+ }
+ ]
+}
+```
+
+If the test job has ran successfully, add the following job to your node. Rename bridge names if required. Replace the following values:
+
+- `YOUR_ORACLE_CONTRACT_ADDRESS` with your oracle contract address
+
+```json RenVM & Blockcypher
+{
+ "initiators": [
+ {
+ "type": "runlog",
+ "params": {
+ "address": "YOUR_ORACLE_CONTRACT_ADDRESS"
+ }
+ }
+ ],
+ "tasks": [
+ {
+ "type": "renvm-address-set",
+ "params": {
+ "network": "mainnet",
+ "tokenOrContract": "btc"
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "blockcypher",
+ "params": {
+ "dataPath": "result",
+ "endpoint": "balance",
+ "confirmations": 6
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "reduce",
+ "params": {
+ "reducer": "sum",
+ "dataPath": "result",
+ "valuePath": "balance",
+ "initialValue": 0
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "ethint256"
+ },
+ {
+ "type": "ethtx"
+ }
+ ]
+}
+```
+
+```json wBTC & Blockcypher
+{
+ "initiators": [
+ {
+ "type": "runlog",
+ "params": {
+ "address": "YOUR_ORACLE_CONTRACT_ADDRESS"
+ }
+ }
+ ],
+ "tasks": [
+ {
+ "type": "wbtc-address-set",
+ "params": {
+ "network": "mainnet",
+ "tokenOrContract": "btc"
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "blockcypher",
+ "params": {
+ "dataPath": "result",
+ "endpoint": "balance",
+ "confirmations": 6
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "reduce",
+ "params": {
+ "reducer": "sum",
+ "dataPath": "result",
+ "valuePath": "balance",
+ "initialValue": 0
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "ethint256"
+ },
+ {
+ "type": "ethtx"
+ }
+ ]
+}
+```
+
+```json RenVM & Blockchain.com
+{
+ "initiators": [
+ {
+ "type": "runlog",
+ "params": {
+ "address": "YOUR_ORACLE_CONTRACT_ADDRESS"
+ }
+ }
+ ],
+ "tasks": [
+ {
+ "type": "renvm-address-set",
+ "params": {
+ "network": "mainnet",
+ "tokenOrContract": "btc"
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "blockchain-com",
+ "params": {
+ "dataPath": "result",
+ "endpoint": "balance",
+ "confirmations": 0
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "reduce",
+ "params": {
+ "reducer": "sum",
+ "dataPath": "result",
+ "valuePath": "balance",
+ "initialValue": 0
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "ethint256"
+ },
+ {
+ "type": "ethtx"
+ }
+ ]
+}
+```
+
+```json wBTC & Blockchain.com
+{
+ "initiators": [
+ {
+ "type": "runlog",
+ "params": {
+ "address": "YOUR_ORACLE_CONTRACT_ADDRESS"
+ }
+ }
+ ],
+ "tasks": [
+ {
+ "type": "wbtc-address-set",
+ "params": {
+ "network": "mainnet",
+ "tokenOrContract": "btc"
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "blockchain-com",
+ "params": {
+ "dataPath": "result",
+ "endpoint": "balance",
+ "confirmations": 0
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "reduce",
+ "params": {
+ "reducer": "sum",
+ "dataPath": "result",
+ "valuePath": "balance",
+ "initialValue": 0
+ }
+ },
+ {
+ "type": "copy",
+ "params": {
+ "copyPath": ["result"]
+ }
+ },
+ {
+ "type": "ethint256"
+ },
+ {
+ "type": "ethtx"
+ }
+ ]
+}
+```
+
+Once added, open a PR with the Job ID associated with the job above. Base this PR off the branch of the PR sent to you by the Chainlink team.
+
+Make sure that your `MINIMUM_CONTRACT_PAYMENT_LINK_JUELS` environment variable is low enough to accept the payment amount from the aggregator contract on mainnet.
diff --git a/docs/chainlink-nodes/run-an-ethereum-client.md b/src/pages/chainlink-nodes/run-an-ethereum-client.md
similarity index 85%
rename from docs/chainlink-nodes/run-an-ethereum-client.md
rename to src/pages/chainlink-nodes/run-an-ethereum-client.md
index 7d004717a34..412dd2c969c 100644
--- a/docs/chainlink-nodes/run-an-ethereum-client.md
+++ b/src/pages/chainlink-nodes/run-an-ethereum-client.md
@@ -1,19 +1,21 @@
---
-layout: nodes.liquid
+layout: ../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
-title: 'Run an Ethereum Client'
-permalink: 'docs/run-an-ethereum-client/'
+title: "Run an Ethereum Client"
+permalink: "docs/run-an-ethereum-client/"
whatsnext:
{
- 'Running a Chainlink Node': '/docs/running-a-chainlink-node/',
- 'Optimizing Performance': '/docs/evm-performance-configuration/',
+ "Running a Chainlink Node": "/chainlink-nodes/running-a-chainlink-node/",
+ "Optimizing Performance": "/chainlink-nodes/evm-performance-configuration/",
}
---
Chainlink nodes must be able to connect to an Ethereum client with an active websocket connection. This is accomplished by running both an execution client and a consensus client. You can run these clients yourself, but running Ethereum clients requires significant storage and network resources. Optionally, you can use [External Services](#external-services) that manage these clients for you.
-> 📘 If you run these clients yourself, you must enable the websockets API. The websockets API is required for the Chainlink node to communicate with the Ethereum blockchain.
+:::note[Enable the Websockets API]
+If you run these clients yourself, you must enable the websockets API. The websockets API is required for the Chainlink node to communicate with the Ethereum blockchain.
+:::
## Geth
@@ -30,6 +32,7 @@ Create a local directory to persist the data:
```shell Goerli
mkdir ~/.geth-goerli
```
+
```shell Mainnet
mkdir ~/.geth
```
@@ -41,6 +44,7 @@ docker run --name eth -p 8546:8546 -v ~/.geth-goerli:/geth -it \
ethereum/client-go --goerli --ws --ipcdisable \
--ws.addr 0.0.0.0 --ws.origins="*" --datadir /geth
```
+
```shell Mainnet
docker run --name eth -p 8546:8546 -v ~/.geth:/geth -it \
ethereum/client-go --ws --ipcdisable \
@@ -57,7 +61,7 @@ docker start -i eth
Follow Geth's instructions for [Connecting to Consensus Clients](https://geth.ethereum.org/docs/interface/consensus-clients). This will require some additional configuration settings for the Docker command that runs Geth.
-Return to [Running a Chainlink Node](../running-a-chainlink-node/).
+Return to [Running a Chainlink Node](/chainlink-nodes/running-a-chainlink-node/).
## Nethermind
@@ -74,6 +78,7 @@ Create a local directory to persist the data:
```shell Goerli
mkdir ~/.nethermind-goerli
```
+
```shell Mainnet
mkdir ~/.nethermind
```
@@ -87,6 +92,7 @@ docker run --name eth -p 8545:8545 \
--Init.WebSocketsEnabled true --JsonRpc.Enabled true --JsonRpc.Host 0.0.0.0 --NoCategory.CorsOrigins * \
--datadir data
```
+
```shell Mainnet
docker run --name eth -p 8545:8545 \
-v ~/.nethermind/:/nethermind/data \
@@ -105,7 +111,7 @@ docker start -i eth
Follow Nethermind's instructions for [Installing and configuring the Consensus Client](https://docs.nethermind.io/nethermind/guides-and-helpers/validator-setup/eth2-validator#setup). This will require some additional configuration settings for the Docker command that runs Nethermind.
-Return to [Running a Chainlink Node](../running-a-chainlink-node/).
+Return to [Running a Chainlink Node](/chainlink-nodes/running-a-chainlink-node/).
## External Services
@@ -118,6 +124,7 @@ Example connection setting:
```text Goerli
ETH_URL=wss://eth-goerli.alchemyapi.io/v2/YOUR_PROJECT_ID
```
+
```text Mainnet
ETH_URL=wss://eth-mainnet.alchemyapi.io/v2/YOUR_PROJECT_ID
```
@@ -145,9 +152,11 @@ Example connection setting:
```text Goerli
ETH_URL=wss://eth.getblock.io/goerli/?api_key=YOUR_API_KEY
```
+
```text Sepolia
ETH_URL=wss://eth.getblock.io/sepolia/?api_key=YOUR_API_KEY
```
+
```text Mainnet
ETH_URL=wss://eth.getblock.io/mainnet/?api_key=YOUR_API_KEY
```
@@ -159,6 +168,7 @@ Example connection setting. Replace YOUR_PROJECT_ID with the ID Infura provides
```text Goerli
ETH_URL=wss://goerli.infura.io/ws/v3/YOUR_PROJECT_ID
```
+
```text Mainnet
ETH_URL=wss://mainnet.infura.io/ws/v3/YOUR_PROJECT_ID
```
@@ -178,18 +188,20 @@ Example connection setting:
```text Goerli
ETH_URL=wss://your-node-name.goerli.quiknode.pro/security-hash/
```
+
```text Mainnet
ETH_URL=wss://your-node-name.quiknode.pro/security-hash/
```
## Configuring your ETH node
-> 🚧 Warning
-> By default, go-ethereum rejects transactions that exceed the built-in RPC gas/txfee caps. The node will fatally error transactions if this happens. If you ever exceed the caps, the node will miss transactions.
+:::caution[RPC gas/txfee caps]
+By default, go-ethereum rejects transactions that exceed the built-in RPC gas/txfee caps. The node will fatally error transactions if this happens. If you ever exceed the caps, the node will miss transactions.
+:::
At a minimum, disable the default RPC gas and txfee caps on your ETH node. This can be done in the TOML file as seen below, or by running go-ethereum with the command line arguments: `--rpc.gascap=0 --rpc.txfeecap=0`.
-To learn more about configuring ETH nodes, see the [configuration page](/docs/configuration-variables/#configuring-your-eth-node).
+To learn more about configuring ETH nodes, see the [configuration page](/chainlink-nodes/configuration-variables/#configuring-your-eth-node).
## Additional Tools
diff --git a/docs/chainlink-nodes/running-a-chainlink-node.md b/src/pages/chainlink-nodes/running-a-chainlink-node.md
similarity index 72%
rename from docs/chainlink-nodes/running-a-chainlink-node.md
rename to src/pages/chainlink-nodes/running-a-chainlink-node.md
index 36cefa483f2..c462edc55b4 100644
--- a/docs/chainlink-nodes/running-a-chainlink-node.md
+++ b/src/pages/chainlink-nodes/running-a-chainlink-node.md
@@ -1,27 +1,27 @@
---
-layout: nodes.liquid
+layout: ../../layouts/MainLayout.astro
section: nodeOperator
date: Last Modified
-title: 'Running a Chainlink Node'
-permalink: 'docs/running-a-chainlink-node/'
+title: "Running a Chainlink Node"
+permalink: "docs/running-a-chainlink-node/"
whatsnext:
{
- 'Fulfilling Requests': '/docs/fulfilling-requests/',
- 'Optimizing EVN Performance': '/docs/evm-performance-configuration/',
- 'Performing System Maintenance': '/docs/performing-system-maintenance/',
- 'Miscellaneous': '/docs/miscellaneous/',
- 'Security and Operation Best Practices': '/docs/best-security-practices/',
+ "Fulfilling Requests": "/chainlink-nodes/fulfilling-requests/",
+ "Optimizing EVN Performance": "/chainlink-nodes/evm-performance-configuration/",
+ "Performing System Maintenance": "/chainlink-nodes/performing-system-maintenance/",
+ "Miscellaneous": "/chainlink-nodes/miscellaneous/",
+ "Security and Operation Best Practices": "/chainlink-nodes/best-security-practices/",
}
metadata:
- title: 'Running a Chainlink Node'
- description: 'Run your own Chainlink node using this guide which explains the requirements and basics for getting started.'
+ title: "Running a Chainlink Node"
+ description: "Run your own Chainlink node using this guide which explains the requirements and basics for getting started."
---
This page explains the requirements and basic instructions for running your own Chainlink node.
-Note that nodes can fulfill requests for open APIs out-of-the-box using [Tasks](/docs/tasks/) without needing any additional configuration.
+Note that nodes can fulfill requests for open APIs out-of-the-box using [Tasks](/chainlink-nodes/oracle-jobs/task-types/tasks/) without needing any additional configuration.
-To provide data from an authenticated API, add an [external adapter](../external-adapters/) to enable connectivity through the Chainlink node.
+To provide data from an authenticated API, add an [external adapter](/chainlink-nodes/external-adapters/external-adapters/) to enable connectivity through the Chainlink node.

@@ -53,7 +53,7 @@ If you run your node on AWS, use an instance type with dedicated core time. [Bur
### Ethereum Client
-Connectivity to an Ethereum client is also required for communication with the blockchain. If you decide to run your own Ethereum client, you will want to run that on a separate machine. Hardware requirements of Ethereum clients can change over time. You can also use a [third-party service](../run-an-ethereum-client/#external-services) as your Ethereum client.
+Connectivity to an Ethereum client is also required for communication with the blockchain. If you decide to run your own Ethereum client, you will want to run that on a separate machine. Hardware requirements of Ethereum clients can change over time. You can also use a [third-party service](/chainlink-nodes/run-an-ethereum-client/#external-services) as your Ethereum client.
## Running From Source
@@ -74,6 +74,7 @@ It's recommended to run the Chainlink node with [Docker](https://www.docker.com/
exit
# log in again
```
+
```shell CentOS
curl -sSL https://get.docker.com/ | sh
sudo systemctl start docker
@@ -81,12 +82,14 @@ It's recommended to run the Chainlink node with [Docker](https://www.docker.com/
exit
# log in again
```
+
```shell Debian
curl -sSL https://get.docker.com/ | sh
sudo usermod -aG docker $USER
exit
# log in again
```
+
```shell Fedora
curl -sSL https://get.docker.com/ | sh
sudo systemctl start docker
@@ -94,6 +97,7 @@ It's recommended to run the Chainlink node with [Docker](https://www.docker.com/
exit
# log in again
```
+
```shell Ubuntu
curl -sSL https://get.docker.com/ | sh
sudo usermod -aG docker $USER
@@ -101,7 +105,7 @@ It's recommended to run the Chainlink node with [Docker](https://www.docker.com/
# log in again
```
-- A fully synced Ethereum execution client with websockets enabled and a connected consensus client. See [Running an Ethereum Client](/docs/run-an-ethereum-client/) for details. Optionally, you can [use an external service](/docs/run-an-ethereum-client/#external-services) as your client.
+- A fully synced Ethereum execution client with websockets enabled and a connected consensus client. See [Running an Ethereum Client](/chainlink-nodes/run-an-ethereum-client/) for details. Optionally, you can [use an external service](/chainlink-nodes/run-an-ethereum-client/#external-services) as your client.
#### Create a directory
@@ -112,15 +116,18 @@ Create a local directory to hold the Chainlink data:
```shell Goerli
mkdir ~/.chainlink-goerli
```
+
```shell Mainnet
mkdir ~/.chainlink
```
-> **_Other Supported Networks:_** Chainlink is blockchain agnostic technology. The [LINK Token Contracts](../link-token-contracts/) page details networks which support the LINK token. You can setup your node to provide data to any of these blockchains.
+:::note[Other Supported Networks]
+Chainlink is blockchain agnostic technology. The [LINK Token Contracts](/resources/link-token-contracts/) page details networks which support the LINK token. You can setup your node to provide data to any of these blockchains.
+:::
#### Create an Environment File
-Run the following as a command to create an environment file and populate with variables specific to the network you're running on. For a full list of available configuration variables, click [here](../configuration-variables/).
+Run the following as a command to create an environment file and populate with variables specific to the network you're running on. For a full list of available configuration variables, click [here](/chainlink-nodes/configuration-variables/).
```shell Goerli
echo "ROOT=/chainlink
@@ -130,6 +137,7 @@ CHAINLINK_TLS_PORT=0
SECURE_COOKIES=false
ALLOW_ORIGINS=*" > ~/.chainlink-goerli/.env
```
+
```shell Mainnet
echo "ROOT=/chainlink
LOG_LEVEL=debug
@@ -141,9 +149,9 @@ ALLOW_ORIGINS=*" > ~/.chainlink/.env
#### Set your Ethereum Client URL
-> 🚧 Using an external Ethereum client?
->
-> If you're using a 3rd party service to connect to the blockchain, skip to the [External Provider](#ethereum-client-as-an-external-provider) section to set the `ETH_URL` environment variable. We provide general guidance, but you will need to obtain the websocket connection string to add to your environment file.
+:::note[Using an external Ethereum client?]
+If you're using a 3rd party service to connect to the blockchain, skip to the [External Provider](#ethereum-client-as-an-external-provider) section to set the `ETH_URL` environment variable. We provide general guidance, but you will need to obtain the websocket connection string to add to your environment file.
+:::
#### Ethereum Client on the Same Machine
@@ -158,6 +166,7 @@ Then run the following command to add the Ethereum client's URL to your environm
```shell Goerli
echo "ETH_URL=ws://$ETH_CONTAINER_IP:8546" >> ~/.chainlink-goerli/.env
```
+
```shell Mainnet
echo "ETH_URL=ws://$ETH_CONTAINER_IP:8546" >> ~/.chainlink/.env
```
@@ -169,17 +178,18 @@ If you are using an external provider for connectivity to the Ethereum blockchai
```shell Goerli
echo "ETH_URL=CHANGEME" >> ~/.chainlink-goerli/.env
```
+
```shell Mainnet
echo "ETH_URL=CHANGEME" >> ~/.chainlink/.env
```
-> 🚧 Running Chainlink Node on Ganache
->
-> Ganache is a mock testnet. Although you can run nodes on Ganache, it is not officially supported. Most node operators should use one of the supported [testnets](/docs/link-token-contracts/) for development and testing.
+:::note[Running Chainlink Node on Ganache]
+Ganache is a mock testnet. Although you can run nodes on Ganache, it is not officially supported. Most node operators should use one of the supported [testnets](/resources/link-token-contracts/) for development and testing.
+:::
#### Set the Remote DATABASE_URL Config
-You will need to connect your Chainlink node with a remote PostgreSQL database. See the [Connecting to a Remote Database](../connecting-to-a-remote-database/) page for more information. Use the example below to configure your `DATABASE_URL` setting in your environment file, replacing `$VARIABLES` with their actual values.
+You will need to connect your Chainlink node with a remote PostgreSQL database. See the [Connecting to a Remote Database](/chainlink-nodes/connecting-to-a-remote-database/) page for more information. Use the example below to configure your `DATABASE_URL` setting in your environment file, replacing `$VARIABLES` with their actual values.
- `$USERNAME`: The database username (must be owner)
- `$PASSWORD`: The user's password
@@ -187,13 +197,14 @@ You will need to connect your Chainlink node with a remote PostgreSQL database.
- `$PORT`: The port that the database is listening on
- `$DATABASE`: The database to use for the Chainlink node (i.e. "postgres")
-> 🚧 Important
->
-> If you're testing you can add `?sslmode=disable` to the end of your `DATABASE_URL`. However you should _never_ do this on a production node.
+:::tip[Important]
+If you're testing you can add `?sslmode=disable` to the end of your `DATABASE_URL`. However you should _never_ do this on a production node.
+:::
```shell Goerli
echo "DATABASE_URL=postgresql://$USERNAME:$PASSWORD@$SERVER:$PORT/$DATABASE" >> ~/.chainlink-goerli/.env
```
+
```shell Mainnet
echo "DATABASE_URL=postgresql://$USERNAME:$PASSWORD@$SERVER:$PORT/$DATABASE" >> ~/.chainlink/.env
```
@@ -205,18 +216,19 @@ Now you can run the Docker image. Replace `` with your desired version.
```shell Goerli
cd ~/.chainlink-goerli && docker run -p 6688:6688 -v ~/.chainlink-goerli:/chainlink -it --env-file=.env smartcontract/chainlink: local n
```
+
```shell Mainnet
cd ~/.chainlink && docker run -p 6688:6688 -v ~/.chainlink:/chainlink -it --env-file=.env smartcontract/chainlink: local n
```
-> 📘 Local Database
->
-> If you're running a local database you may need to add the `--network host` flag to the command above.
+:::note[Local Database]
+If you're running a local database you may need to add the `--network host` flag to the command above.
+:::
-The first time running the image, it will ask you for a password and confirmation. This will be your wallet password that you can use to unlock the keystore file generated for you. Then, you'll be prompted to enter an API Email and Password. This will be used to expose the API for the GUI interface, and will be used every time you log into your node. When running the node again, you can supply the `-p` option with a path to a text file containing the wallet key password, and a `-a` option, pointing to a text file containing the API email and password. Instructions on how to do that are [here](../miscellaneous/#use-password-and-api-files-on-startup).
+The first time running the image, it will ask you for a password and confirmation. This will be your wallet password that you can use to unlock the keystore file generated for you. Then, you'll be prompted to enter an API Email and Password. This will be used to expose the API for the GUI interface, and will be used every time you log into your node. When running the node again, you can supply the `-p` option with a path to a text file containing the wallet key password, and a `-a` option, pointing to a text file containing the API email and password. Instructions on how to do that are [here](/chainlink-nodes/miscellaneous/#use-password-and-api-files-on-startup).
-> 📘 Important
->
-> You will need to send some ETH to your node's address in order for it to fulfill requests. You can view your node's ETH address when the node starts up or on the Configuration page of the GUI.
+:::tip[Important]
+You will need to send some ETH to your node's address in order for it to fulfill requests. You can view your node's ETH address when the node starts up or on the Configuration page of the GUI.
+:::
-You can now connect to your Chainlink node's UI interface by navigating to [http://localhost:6688](http://localhost:6688). If using a VPS, you can create a [SSH tunnel](https://www.howtogeek.com/168145/how-to-use-ssh-tunneling/) to your node for `6688:localhost:6688` to enable connectivity to the GUI. Typically this is done with `ssh -i $KEY $USER@$REMOTE-IP -L 6688:localhost:6688 -N`. A SSH tunnel is recommended over opening up ports specific to the Chainlink node to be public facing. See the [Security and Operation Best Practices](../best-security-practices/) page for more details on how to secure your node.
+You can now connect to your Chainlink node's UI interface by navigating to [http://localhost:6688](http://localhost:6688). If using a VPS, you can create a [SSH tunnel](https://www.howtogeek.com/168145/how-to-use-ssh-tunneling/) to your node for `6688:localhost:6688` to enable connectivity to the GUI. Typically this is done with `ssh -i $KEY $USER@$REMOTE-IP -L 6688:localhost:6688 -N`. A SSH tunnel is recommended over opening up ports specific to the Chainlink node to be public facing. See the [Security and Operation Best Practices](/chainlink-nodes/best-security-practices/) page for more details on how to secure your node.
diff --git a/src/pages/data-feeds/deprecating-feeds.md b/src/pages/data-feeds/deprecating-feeds.md
new file mode 100644
index 00000000000..e25897cd1af
--- /dev/null
+++ b/src/pages/data-feeds/deprecating-feeds.md
@@ -0,0 +1,12 @@
+---
+layout: ../../layouts/MainLayout.astro
+title: "Deprecation of Chainlink Data Feeds"
+section: ethereum
+metadata:
+ description: "Deprecation of Chainlink Data Feeds"
+date: Last Modified
+setup: |
+ import { FeedPage } from "@features/feeds"
+---
+
+
diff --git a/src/pages/data-feeds/ens.mdx b/src/pages/data-feeds/ens.mdx
new file mode 100644
index 00000000000..15d2ba105ec
--- /dev/null
+++ b/src/pages/data-feeds/ens.mdx
@@ -0,0 +1,103 @@
+---
+layout: ../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Using ENS with Data Feeds"
+excerpt: "Ethereum Name Service"
+---
+
+import { EnsLookupForm } from "../../features/ens/components/EnsLookupForm.tsx"
+import { EnsManualLookupForm } from "../../features/ens/components/EnsManualLookupForm.tsx"
+import CodeSample from "@components/CodeSample/CodeSample.astro"
+
+## Lookup
+
+
+
+## Manual Lookup
+
+
+
+## Naming Structure
+
+Chainlink Data Feeds fall under the `data.eth` naming suffix. To obtain a specific feed address, prefix this with the assets in the feed, separated by a dash (-).
+
+| Pair | ENS Domain Name |
+| :-------- | :----------------- |
+| ETH / USD | `eth-usd.data.eth` |
+| BTC / USD | `btc-usd.data.eth` |
+| ... | `...` |
+
+### Subdomains
+
+By default, the base name structure (`eth-usd.data.eth`) returns the proxy address for that feed. However, subdomains enable callers to retrieve other associated contract addresses, as shown in the following table.
+
+| Contract Addresses | Subdomain Prefix | Example |
+| :-------------------- | :--------------- | :---------------------------- |
+| Proxy | `proxy` | `proxy.eth-usd.data.eth` |
+| Underlying aggregator | `aggregator` | `aggregator.eth-usd.data.eth` |
+| Proposed aggregator | `proposed` | `proposed.eth-usd.data.eth` |
+
+## Naming Structure
+
+Chainlink data feeds fall under the `data.eth` naming suffix. To obtain a specific feed address, prefix this with the assets in the feed, separated by a dash (-).
+
+| Pair | ENS Domain Name |
+| :-------- | :----------------- |
+| ETH / USD | `eth-usd.data.eth` |
+| BTC / USD | `btc-usd.data.eth` |
+| ... | `...` |
+
+### Subdomains
+
+By default, the base name structure (`eth-usd.data.eth`) returns the proxy address for that feed. However, subdomains enable callers to retrieve other associated contract addresses, as shown in the following table.
+
+| Contract Addresses | Subdomain Prefix | Example |
+| :-------------------- | :--------------- | :---------------------------- |
+| Proxy | `proxy` | `proxy.eth-usd.data.eth` |
+| Underlying aggregator | `aggregator` | `aggregator.eth-usd.data.eth` |
+| Proposed aggregator | `proposed` | `proposed.eth-usd.data.eth` |
+
+## Architecture
+
+### Resolver
+
+For each network, there is a single Chainlink resolver, which does not change. Its address can be obtained using the `data.eth` domain. This resolver manages the subdomains associated with `data.eth`.
+
+| Network | Resolver Address |
+| :--------------- | :----------------------------------------------------------------------------------------------------------------------- |
+| Ethereum Mainnet | [0x122eb74f9d0F1a5ed587F43D120C1c2BbDb9360B](https://app.ens.domains/address/0x122eb74f9d0F1a5ed587F43D120C1c2BbDb9360B) |
+
+### Listening for Address Changes
+
+When a new aggregator is deployed for a specific feed, it is first proposed, and when accepted becomes the aggregator for that feed. During this process, the `proposed` and `aggregator` subdomains for that feed will change. With each change, the resolver emits an `AddrChanged` event, using the feed subdomain (for example: `eth-usd.data.eth`) as the indexed parameter.
+
+**Example**: If you want to listen for when the aggregator of the ETH / USD feed changes, set up a listener to track the `AddrChanged` event on the resolver, using a filter like this: `ethers.utils.namehash('aggregator.eth-usd.data.eth')`.
+
+## Obtaining Addresses
+
+:::caution[ Reverse Lookup]
+
+Reverse lookup is not supported.
+
+:::
+
+### Javascript
+
+The example below uses Javascript Web3 library to interact with ENS. See the [ENS documentation](https://docs.ens.domains/dapp-developer-guide/resolving-names) for the full list of languages and libraries libraries that support ENS.
+
+This example logs the address of the data feed on the Ethereum mainnet for ETH / USD prices.
+
+
+
+### Solidity
+
+In Solidity, the address of the ENS registry must be known. According to [ENS documentation](https://docs.ens.domains/ens-deployments), this address is the same across Mainnet and Goerli networks:
+
+ENS registry address: [0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e](https://etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e).
+
+Also, instead of using readable string names like `eth-usd.data.eth`, resolvers accept bytes32 hash IDs for names. Hash IDs can be retrieved from [this subgraph](https://thegraph.com/explorer/subgraph/ensdomains/ens) or via this npm package [eth-ens-namehash](https://www.npmjs.com/package/@ensdomains/eth-ens-namehash).
+
+"ETH / USD" hash: `0xf599f4cd075a34b92169cf57271da65a7a936c35e3f31e854447fbb3e7eb736d`
+
+
diff --git a/src/pages/data-feeds/feed-registry/feed-registry-functions.md b/src/pages/data-feeds/feed-registry/feed-registry-functions.md
new file mode 100644
index 00000000000..0e99bfcd5ec
--- /dev/null
+++ b/src/pages/data-feeds/feed-registry/feed-registry-functions.md
@@ -0,0 +1,344 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Feed Registry API Reference"
+metadata:
+ title: "Feed Registry API Reference"
+ description: "Chainlink Feed Registry Functions"
+---
+
+This guide outlines the functions which can be used with Chainlink's Feed Registry. You can learn more about the feed registry [here](/data-feeds/feed-registry/).
+
+## Functions
+
+| Name | Description |
+| ----------------------------------------- | -------------------------------------------------------------------------------------- |
+| [decimals](#decimals) | The number of decimals in the response. |
+| [description](#description) | The description of the aggregator that the proxy points to. |
+| [getRoundData](#getrounddata) | Get data from a specific round. |
+| [latestRoundData](#latestrounddata) | Get data from the latest round. |
+| [version](#version) | The version representing the type of aggregator the proxy points to. |
+| [getFeed](#getfeed) | Returns the primary aggregator address of a base / quote pair. |
+| [getPhaseFeed](#getphasefeed) | Returns the aggregator address of a base / quote pair at a specified phase. |
+| [isFeedEnabled](#isfeedenabled) | Returns true if an aggregator is enabled as primary on the registry. |
+| [getPhase](#getphase) | Returns the raw starting and ending aggregator round ids of a base / quote pair. |
+| [getRoundFeed](#getroundfeed) | Returns the underlying aggregator address of a base / quote pair at a specified round. |
+| [getPhaseRange](#getphaserange) | Returns the starting and ending round ids of a base / quote pair at a specified phase. |
+| [getPreviousRoundId](#getpreviousroundid) | Returns the previous round id of a base / quote pair given a specified round. |
+| [getNextRoundId](#getnextroundid) | Returns the next round id of a base / quote pair given a specified round. |
+| [getCurrentPhaseId](#getcurrentphaseid) | Returns the current phase id of a base / quote pair. |
+
+---
+
+### decimals
+
+Get the number of decimals present in the response value.
+
+
+```solidity
+function decimals(address base, address quote) external view returns (uint8)
+```
+
+#### Parameters
+
+- `base`: The base asset address.
+- `quote`: The quote asset address.
+
+### Return Values
+
+- `RETURN`: The number of decimals.
+
+## description
+
+Get the description of the underlying aggregator that the proxy points to.
+
+
+```solidity
+function description(address base, address quote) external view returns (string memory)
+```
+
+#### Parameters
+
+- `base`: The base asset address.
+- `quote`: The quote asset address.
+
+#### Return Values
+
+- `RETURN`: The description of the underlying aggregator.
+
+### getRoundData
+
+Get data about a specific round, using the `roundId`.
+
+
+```solidity
+function getRoundData(address base, address quote, uint80 _roundId) external view
+ returns (
+ uint80 roundId,
+ int256 answer,
+ uint256 startedAt,
+ uint256 updatedAt,
+ uint80 answeredInRound
+ )
+```
+
+#### Parameters
+
+- `base`: The base asset address.
+- `quote`: The quote asset address.
+- `roundId`: The round ID.
+
+#### Return Values
+
+- `roundId`: The round ID.
+- `answer`: The price.
+- `startedAt`: Timestamp of when the round started.
+- `updatedAt`: Timestamp of when the round was updated.
+- `answeredInRound`: The round ID of the round in which the answer was computed.
+
+### latestRoundData
+
+Get the price from the latest round.
+
+
+```solidity
+function latestRoundData(address base, address quote) external view
+ returns (
+ uint80 roundId,
+ int256 answer,
+ uint256 startedAt,
+ uint256 updatedAt,
+ uint80 answeredInRound
+ )
+```
+
+#### Return Values
+
+- `roundId`: The round ID.
+- `answer`: The price.
+- `startedAt`: Timestamp of when the round started.
+- `updatedAt`: Timestamp of when the round was updated.
+- `answeredInRound`: The round ID of the round in which the answer was computed.
+
+### version
+
+The version representing the type of aggregator the proxy points to.
+
+
+```solidity
+function version(address base, address quote) external view returns (uint256)
+```
+
+#### Parameters
+
+- `base`: The base asset address.
+- `quote`: The quote asset address.
+
+#### Return Values
+
+- `RETURN`: The version number.
+
+### getFeed
+
+Returns the primary aggregator address of a base / quote pair. Note that on-chain contracts cannot read from aggregators directly, only through Feed Registry or Proxy contracts.
+
+
+```solidity
+function getFeed(address base, address quote) external view returns (AggregatorV2V3Interface aggregator);
+
+```
+
+#### Parameters
+
+- `base`: The base asset address.
+- `quote`: The quote asset address.
+
+#### Return Values
+
+- `aggregator`: The primary aggregator address.
+
+### getPhaseFeed
+
+Returns the underlying aggregator address of a base / quote pair at a specified phase. Note that on-chain contracts cannot read from aggregators directly, only through Feed Registry or Proxy contracts.
+Phase ids start at `1`. You can get the current Phase by calling `getCurrentPhaseId()`.
+
+
+```solidity
+function getPhaseFeed(
+ address base,
+ address quote,
+ uint16 phaseId
+) external view returns (AggregatorV2V3Interface aggregator);
+
+```
+
+#### Parameters
+
+- `base`: The base asset address.
+- `quote`: The quote asset address.
+- `phaseId`: The phase id.
+
+#### Return Values
+
+- `aggregator`: The primary aggregator address at the specified phase.
+
+### isFeedEnabled
+
+Returns true if an aggregator is enabled as primary on the feed registry. This is useful to check if you should index events from an aggregator contract, because you want to only index events of primary aggregators.
+
+
+```solidity
+function isFeedEnabled(address aggregator) external view returns (bool);
+
+```
+
+#### Parameters
+
+- `aggregator`: The aggregator address
+
+#### Return Values
+
+- `RETURN`: `true` if the supplied aggregator is a primary aggregator for any base / quote pair.
+
+### getPhase
+
+Returns the starting and ending aggregator round ids of a base / quote pair.
+
+
+```solidity
+function getPhase(address base, address quote, uint16 phaseId) external view returns (Phase memory phase);
+
+```
+
+Phases hold the following information:
+
+
+```solidity
+struct Phase {
+ uint16 phaseId;
+ uint80 startingAggregatorRoundId;
+ uint80 endingAggregatorRoundId;
+}
+
+```
+
+#### Parameters
+
+- `base`: The base asset address.
+- `quote`: The quote asset address.
+- `phaseId`: The phase id.
+
+#### Return Values
+
+- `RETURN`: `Phase` details of a base / quote pair.
+
+### getRoundFeed
+
+Returns the underlying aggregator address of a base / quote pair at a specified round. Note that on-chain contracts cannot read from aggregators directly, only through Feed Registry or Proxy contracts.
+
+
+```solidity
+function getRoundFeed(
+ address base,
+ address quote,
+ uint80 roundId
+) external view returns (AggregatorV2V3Interface aggregator);
+
+```
+
+#### Parameters
+
+- `base`: The base asset address.
+- `quote`: The quote asset address.
+- `roundId`: The round id.
+
+#### Return Values
+
+- `aggregator`: The underlying aggregator address of a base / quote pair at the specified round.
+
+### getPhaseRange
+
+Returns the starting and ending round ids of a base / quote pair at a specified phase.
+
+Please note that this `roundId` is calculated from the phase id and the underlying aggregator's round id. To get the raw aggregator round ids of a phase for indexing purposes, please use `getPhase()`.
+
+
+```solidity
+function getPhaseRange(
+ address base,
+ address quote,
+ uint16 phaseId
+) external view returns (uint80 startingRoundId, uint80 endingRoundId);
+
+```
+
+#### Parameters
+
+- `base`: The base asset address.
+- `quote`: The quote asset address.
+- `phaseId`: The phase id.
+
+#### Return Values
+
+- `startingRoundId`: The starting round id
+- `endingRoundId`: The ending round id
+
+### getPreviousRoundId
+
+Returns the previous round id of a base / quote pair given a specified round. Note that rounds are non-monotonic across phases.
+
+
+```solidity
+function getPreviousRoundId(address base, address quote, uint80 roundId) external view returns (uint80 previousRoundId);
+
+```
+
+#### Parameters
+
+- `base`: The base asset address.
+- `quote`: The quote asset address.
+- `roundId`: The round id.
+
+#### Return Values
+
+- `previousRoundId`: The previous round id of a base / quote pair.
+
+### getNextRoundId
+
+Returns the next round id of a base / quote pair given a specified round. Note that rounds are non-monotonic across phases.
+
+
+```solidity
+function getNextRoundId(address base, address quote, uint80 roundId) external view returns (uint80 nextRoundId);
+
+```
+
+#### Parameters
+
+- `base`: The base asset address.
+- `quote`: The quote asset address.
+- `roundId`: The round id.
+
+#### Return Values
+
+- `nextRoundId`: The next round id of a base / quote pair.
+
+### getCurrentPhaseId
+
+Returns the current phase id of a base / quote pair.
+
+
+```solidity
+function getCurrentPhaseId(address base, address quote) external view returns (uint16 currentPhaseId);
+
+```
+
+#### Parameters
+
+- `base`: The base asset address.
+- `quote`: The quote asset address.
+
+#### Return Values
+
+- `phaseId`: The current phase id of a base / quote pair.
diff --git a/src/pages/data-feeds/feed-registry/index.mdx b/src/pages/data-feeds/feed-registry/index.mdx
new file mode 100644
index 00000000000..c1427150e21
--- /dev/null
+++ b/src/pages/data-feeds/feed-registry/index.mdx
@@ -0,0 +1,102 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Feed Registry"
+metadata:
+ title: "How to Use Chainlink Feed Registry"
+ description: "The Chainlink Feed Registry is an on-chain mapping of assets to feeds. It allows users and DeFi protocols to query Chainlink data feeds from a given pair of asset and denomination addresses."
+whatsnext:
+ {
+ "Read the Feed Registry API Reference": "/data-feeds/feed-registry/feed-registry-functions/",
+ "See the FeedRegistryInterface contract on GitHub": "https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol",
+ }
+---
+
+import { RegistryPrice, registryAdddresses } from "@features/feeds"
+import { Aside } from "@components"
+import CodeSample from "@components/CodeSample/CodeSample.astro"
+
+The Chainlink Feed Registry is an on-chain mapping of assets to feeds. It enables you to query Chainlink data feeds from asset addresses directly, without needing to know the feed contract addresses. They enable smart contracts to get the latest price of an asset in a single call, from a single contract.
+
+
+
+
+ The Feed Registry only lists feeds with a canonical token address on a network. Non-token feeds such as stock indexes
+ are not supported because they do not have a canonical token address.
+
+
+For a complete list of functions and parameters for the `FeedRegistryInterface` contract, see the [Feed Registry API Reference](/data-feeds/feed-registry/feed-registry-functions/).
+
+## Base and Quote
+
+The Feed Registry fully supports the [`AggregatorV3Interface`](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol) API for multiple feeds. It maps feeds from `base` and `quote` address pairs. To get the latest LINK / USD round data from the registry, call:
+
+{/* prettier-ignore */}
+```solidity
+latestRoundData(address base, address quote)
+```
+
+For example, to get the latest LINK / USD price:
+
+- `base`: The LINK token address on that network e.g. `0x514910771AF9Ca656af840dff83E8264EcF986CA` for LINK on Ethereum mainnet
+- `quote`: A `Denominations.USD` address (`0x0000000000000000000000000000000000000348`), which is based on [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217).
+
+{/* prettier-ignore */}
+```solidity Mainnet
+latestRoundData(0x514910771AF9Ca656af840dff83E8264EcF986CA, 0x0000000000000000000000000000000000000348)
+```
+
+To get the latest LINK / ETH price on Ethereum:
+
+- `base`: The LINK token address on that network e.g. `0x514910771AF9Ca656af840dff83E8264EcF986CA` for LINK on Ethereum mainnet
+- `quote`: A `Denominations.ETH` address (`0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`)
+
+{/* prettier-ignore */}
+```solidity Mainnet
+latestRoundData(0x514910771AF9Ca656af840dff83E8264EcF986CA, 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+```
+
+### Denominations library
+
+A [`Denominations`](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/Denominations.sol) Solidity library is available for you to fetch currency identifiers which lack a canonical Ethereum address:
+
+
+
+## Code Examples
+
+### Solidity
+
+To consume price data from the Feed Registry, your smart contract should reference [`FeedRegistryInterface`](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/FeedRegistryInterface.sol), which defines the external functions implemented by the Feed Registry.
+
+
+
+### Solidity Hardhat Example
+
+
+ You can find a working Feed Registry Hardhat project
+ [here](https://github.com/smartcontractkit/feed-registry-example). Clone the repo and follow the setup instructions to
+ run the example locally.
+
+
+### Javascript
+
+
+
+
+
+## Contract Addresses
+
+This section lists the blockchains that Chainlink Feed Registry are currently available on.
+
+| Network | Address |
+| ---------------- | ----------------------------------------------------------------------------------------------------------------------- |
+| Ethereum Mainnet | [`0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf`](https://etherscan.io/address/0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf) |
diff --git a/src/pages/data-feeds/index.mdx b/src/pages/data-feeds/index.mdx
new file mode 100644
index 00000000000..0472f1d90c3
--- /dev/null
+++ b/src/pages/data-feeds/index.mdx
@@ -0,0 +1,141 @@
+---
+layout: ../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Chainlink Data Feeds Documentation"
+whatsnext:
+ {
+ "Get the latest price of a Data Feed": "/data-feeds/price-feeds/",
+ "Learn more about API references for using Data Feeds": "/data-feeds/price-feeds/api-reference/",
+ "Retrieve contract addresses to use Data Feeds": "/data-feeds/price-feeds/addresses/",
+ }
+metadata:
+ title: "Chainlink Data Feeds Documentation"
+ description: "Add data to your smart contracts and applications. Chainlink data feeds include BTC/USD, BTC/ETH, ETH/USD and more!"
+---
+
+import button from "@chainlink/design-system/button.module.css"
+
+
+
+**Chainlink Data Feeds** are the quickest way to connect your smart contracts to the real-world data such as asset prices, reserve balances, and L2 sequencer health.
+
+If you already have a project started and would like to integrate Chainlink, you can [add Chainlink to your existing project](/resources/create-a-chainlinked-project/#install-into-existing-projects) by using the [`@chainlink/contracts` NPM package](https://www.npmjs.com/package/@chainlink/contracts).
+
+## Types of data feeds
+
+Data feeds provide many different types of data for your applications.
+
+- [Price Feeds](#price-feeds)
+- [Proof of Reserve Feeds](#proof-of-reserve-feeds)
+- [L2 sequencer uptime feeds](#l2-sequencer-uptime-feeds)
+
+### Price Feeds
+
+See the [Data Feeds Contract Addresses](/data-feeds/price-feeds/addresses/) page for a list of networks and proxy addresses.
+
+Smart contracts often act in real-time on data such as prices of assets. This is especially true in [DeFi](https://defi.chain.link/).
+
+For example, [Synthetix](https://www.synthetix.io/) uses Data Feeds to determine prices on their derivatives platform. Lending and borrowing platforms like [AAVE](https://aave.com/) use Data Feeds to ensure the total value of the collateral.
+
+Data Feeds aggregate many data sources and publish them on-chain using a combination of the [Decentralized Data Model](/architecture-overview/architecture-decentralized-model/) and [Off-Chain Reporting](/architecture-overview/off-chain-reporting/).
+
+To learn how to use Price Feeds, see the [Price Feeds](/data-feeds/price-feeds/) documentation.
+
+
+ {"Price Feeds"}
+
+
+### Proof of Reserve Feeds
+
+Proof of Reserves feeds provide the status of reserves for stablecoins, wrapped assets, and real world assets. Proof of Reserve Feeds operate similarly to Price Feeds, but provide answers in units of measurement such as ounces (oz) or number of tokens.
+
+To learn more about Proof of Reserve Feeds, see the [Proof of Reserve](/data-feeds/proof-of-reserve/) documentation.
+
+
+ {"Proof of Reserve Feeds"}
+
+
+### NFT Floor Pricing Feeds
+
+NFT Floor Pricing Feeds provide the price of the lowest priced NFT available in a collection. These feeds operate similarly to [Price Feeds](/data-feeds/price-feeds/) so you can use the [AggregatorV3Interface.sol](https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol) contract to retrieve price answers.
+
+To learn more, see the [NFT Floor Pricing Feeds](/data-feeds/nft-floor-price/) documentation.
+
+
+ {"NFT Floor Pricing Feeds"}
+
+
+### L2 sequencer uptime feeds
+
+L2 sequencer feeds track the last known status of the sequencer on an L2 network at a given point in time. This helps you prevent mass liquidations by providing a grace period to allow customers to react to these events.
+
+To learn how to use L2 sequencer uptime feeds feeds, see the [L2 Sequencer Uptime Feeds](/data-feeds/l2-sequencer-feeds/) documentation.
+
+
+ {"L2 Sequencer Uptime Feeds"}
+
+
+## Components of a data feed
+
+Data Feeds are an example of a decentralized oracle network and include the following components:
+
+- **Consumer**: A consumer is an on-chain or off-chain application that uses Data Feeds. Consumer contracts use the [`AggregatorV3Interface`](https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol) to call functions on the proxy contract and retrieve information from the aggregator contract. For a complete list of functions available in the `AggregatorV3Interface`, see the [Data Feeds API Reference](/data-feeds/price-feeds/api-reference/#aggregatorv3interface).
+- **Proxy contract**: Proxy contracts are on-chain proxies that point to the aggregator for a particular data feed. Using proxies enables the underlying aggregator to be upgraded without any service interruption to consuming contracts. Proxy contracts can vary from one data feed to another, but the [`AggregatorProxy.sol` contract](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.7/dev/AggregatorProxy.sol) on Github is a common example.
+- **Aggregator contract**: An aggregator is a contract that receives periodic data updates from the oracle network. Aggregators store aggregated data on-chain so that consumers can retrieve it and act upon it within the same transaction. For a complete list of functions and variables available on most aggregator contracts, see the [Data Feeds API Reference](/data-feeds/price-feeds/api-reference/#accesscontrolledoffchainaggregator).
+
+To learn how to create a consumer contract that uses an existing data feed, read the [Using Data Feeds](/data-feeds/price-feeds/) documentation.
+
+## Reading proxy and aggregator configurations
+
+Because the proxy and aggregator contracts are all on-chain, you can see the current configuration by reading the variables through an [ABI](https://docs.soliditylang.org/en/latest/abi-spec.html) or using a blockchain explorer for your network. For example, you can see the [BTC/USD proxy configuration](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#readContract) on the Ethereum network using Etherscan.
+
+If you read the BTC/USD proxy configuration, you can query all of the functions and variables that are publicly accessible for that contract including the `aggregator` address, `latestRoundData()` function, `latestAnswer` variable, `owner` address, `latestTimestamp` variable, and several others. To see descriptions for the proxy contract variables and functions, see the source code for your specific data feed on [Etherscan](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#code#L568).
+
+The proxy contract points to an aggregator. This allows you to retrieve data through the proxy even if the aggregator is upgraded. If you view the `aggregator` address defined in the proxy configuration, you can see the aggregator and its configuration. For example, see the [BTC/USD aggregator contract](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#code) in Etherscan. This contract includes several variables and functions, including another `latestRoundData()`. To see descriptions for the aggregator variables and functions, see the source code on [GitHub](https://github.com/smartcontractkit/libocr/blob/master/contract/AccessControlledOffchainAggregator.sol) or [Etherscan](https://etherscan.io/address/0xae74faa92cb67a95ebcab07358bc222e33a34da7#code#F1#L1).
+
+You can call the `latestRoundData()` function directly on the aggregator, but it is a best practice to use the proxy instead so that changes to the aggregator do not affect your application. Similar to the proxy contract, the aggregator contract has a `latestAnswer` variable, `owner` address, `latestTimestamp` variable, and several others.
+
+## Components of an aggregator
+
+The aggregator contract has several variables and functions that might be useful for your application. Although aggregator contracts are similar for each data feed, some aggregators have different variables. Use the `typeAndVersion()` function on the aggregator to identify what type of aggregator it is and what version it is running.
+
+Always check the contract source code and configuration to understand how specific data feeds operate. For example, the [aggregator contract for BTC/USD on Arbitrum](https://arbiscan.io/address/0x942d00008d658dbb40745bbec89a93c253f9b882#code) is different from the aggregators on other networks.
+
+For examples of the contracts that are typically used in aggregator deployments, see the [libocr repository](https://github.com/smartcontractkit/libocr/blob/master/contract/) on GitHub.
+
+For a complete list of functions and variables available on most aggregator contracts, see the [Data Feeds API Reference](/data-feeds/price-feeds/api-reference/#accesscontrolledoffchainaggregator).
+
+## Updates to proxy and aggregator contracts
+
+To accommodate the dynamic nature of off-chain environments, Chainlink Data Feeds are updated from time to time to add new features and capabilities as well as respond to externalities such as token migrations, protocol rebrands, extreme market events, and upstream issues with data or node operations.
+
+These updates include changes to the aggregator configuration or a complete replacement of the aggregator that the proxy uses. If you consume data feeds through the proxy, your applications can continue to operate during these changes.
+
+Proxy and aggregator contracts all have an `owner` address that has permission to change variables and functions. For example, if you read the [BTC/USD proxy contract](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c#readContract) in Etherscan, you can see the `owner` address. This address is a [multi-signature safe](https://docs.gnosis-safe.io/introduction/the-programmable-account/gnosis-safe) (multisig) that you can also inspect.
+
+If you [view the multisig contract](https://etherscan.io/address/0x21f73d42eb58ba49ddb685dc29d3bf5c0f0373ca#readProxyContract) in Etherscan using the _Read as Proxy_ feature, you can see the full details of the multisig including the list of addresses that can sign and the number of signers required for the multisig to approve actions on any contracts that it owns.
+
+The multisig-coordinated upgradability of Chainlink Data Feeds involves time-tested processes that balance collusion-resistance with the flexibility required to implement improvements and swiftly react to external conditions. The approach taken to upgradability will continue to evolve over time to meet user requirements.
+
+## Monitoring data feeds
+
+When you build applications and protocols that depend on data feeds, include monitoring and safeguards to protect against the negative impact of extreme market events, possible malicious activity on third-party venues or contracts, potential delays, and outages.
+
+Create your own monitoring alerts based on deviations in the answers that data feeds provide. This will notify you when potential issues occur so you can respond to them.
+
+### Check the latest answer against reasonable limits
+
+The data feed aggregator includes both [`minAnswer` and `maxAnswer` values](https://github.com/smartcontractkit/libocr/blob/9e4afd8896f365b964bdf769ca28f373a3fb0300/contract/AccessControlledOffchainAggregator.sol#L33). These variables prevent the aggregator from updating the `latestAnswer` outside the agreed range of acceptable values, but they do not stop your application from reading the most recent answer.
+
+Configure your application to detect when the reported answer is close to reaching `minAnswer` or `maxAnswer` and issue an alert so you can respond to a potential market event. Separately, configure your application to detect and respond to extreme price volatility or prices that are outside of your acceptable limits.
+
+### Check the timestamp of the latest answer
+
+Chainlink Price Feeds do not provide streaming data. Rather, the aggregator updates its `latestAnswer` when the value deviates beyond a specified threshold or when the heartbeat idle time has passed. You can find the heartbeat and deviation values for each data feed at [data.chain.link](https://data.chain.link/) or in the [Contract Addresses](/data-feeds/price-feeds/addresses/) lists.
+
+Your application should track the `latestTimestamp` variable or use the `updatedAt` value from the `latestRoundData()` function to make sure that the latest answer is recent enough for your application to use it. If your application detects that the reported answer is not updated within the heartbeat or within time limits that you determine are acceptable for your application, pause operation or switch to an alternate operation mode while identifying the cause of the delay.
+
+During periods of low volatility, the heartbeat triggers updates to the latest answer. Some heartbeats are configured to last several hours, so your application should check the timestamp and verify that the latest answer is recent enough for your application.
+
+To learn more about the heartbeat and deviation threshold, read the [Decentralized Data Model](/architecture-overview/architecture-decentralized-model#aggregator) page.
diff --git a/src/pages/data-feeds/l2-sequencer-feeds.md b/src/pages/data-feeds/l2-sequencer-feeds.md
new file mode 100644
index 00000000000..11adeb1d55a
--- /dev/null
+++ b/src/pages/data-feeds/l2-sequencer-feeds.md
@@ -0,0 +1,102 @@
+---
+layout: ../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "L2 Sequencer Uptime Feeds"
+---
+
+Optimistic rollup protocols move all execution off the layer 1 (L1) Ethereum chain, complete execution on a layer 2 (L2) chain, and return the results of the L2 execution back to the L1. These protocols have a [sequencer](https://community.optimism.io/docs/how-optimism-works/#block-production) that executes and rolls up the L2 transactions by batching multiple transactions into a single transaction.
+
+If a sequencer becomes unavailable, it is impossible to access read/write APIs that consumers are using and applications on the L2 network will be down for most users without interacting directly through the L1 optimistic rollup contracts. The L2 has not stopped, but it would be unfair to continue providing service on your applications when only a few users can use them.
+
+To help your applications identify when the sequencer is unavailable, you can use a data feed that tracks the last known status of the sequencer at a given point in time. This helps you prevent mass liquidations by providing a grace period to allow customers to react to such an event.
+
+## Available networks
+
+You can find proxy addresses for the L2 sequencer feeds at the following addresses:
+
+- Arbitrum:
+ - Arbitrum mainnet: [0xFdB631F5EE196F0ed6FAa767959853A9F217697D](https://arbiscan.io/address/0xfdb631f5ee196f0ed6faa767959853a9f217697d)
+ - Arbitrum Goerli testnet: [0x4da69F028a5790fCCAfe81a75C0D24f46ceCDd69](https://goerli-rollup-explorer.arbitrum.io/address/0x4da69F028a5790fCCAfe81a75C0D24f46ceCDd69)
+- Optimism:
+ - Optimism mainnet: [0x371EAD81c9102C9BF4874A9075FFFf170F2Ee389](https://optimistic.etherscan.io/address/0x371EAD81c9102C9BF4874A9075FFFf170F2Ee389)
+ - Optimism Goerli testnet: [0x4C4814aa04433e0FB31310379a4D6946D5e1D353](https://goerli-optimism.etherscan.io/address/0x4C4814aa04433e0FB31310379a4D6946D5e1D353)
+- Metis:
+ - Andromeda mainnet: [0x58218ea7422255EBE94e56b504035a784b7AA204](https://andromeda-explorer.metis.io/address/0x58218ea7422255EBE94e56b504035a784b7AA204)
+
+### Arbitrum
+
+The diagram below shows how these feeds update and how a consumer retrieves the status of the Arbitrum sequencer.
+
+
+
+1. Chainlink nodes trigger an OCR round every 30s and update the sequencer status by calling the `validate` function in the [`ArbitrumValidator` contract](https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/dev/ArbitrumValidator.sol) by calling it through the [`ValidatorProxy` contract](https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/ValidatorProxy.sol).
+1. The `ArbitrumValidator` checks to see if the latest update is different from the previous update. If it detects a difference, it places a message in the [Arbitrum inbox contract](https://developer.offchainlabs.com/docs/inside_arbitrum#the-big-picture).
+1. The inbox contract sends the message to the [`ArbitrumSequencerUptimeFeed` contract](https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/dev/ArbitrumSequencerUptimeFeed.sol). The message calls the `updateStatus` function in the `ArbitrumSequencerUptimeFeed` contract and updates the latest sequencer status to 0 if the sequencer is up and 1 if it is down. It also records the block timestamp to indicate when the message was sent from the L1 network.
+1. A consumer contract on the L2 network can read these values from the [`ArbitrumUptimeFeedProxy` contract](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.6/EACAggregatorProxy.sol), which reads values from the `ArbitrumSequencerUptimeFeed` contract.
+
+### Handling Arbitrum outages
+
+If the Arbitrum network becomes unavailable, the `ArbitrumValidator` contract continues to send messages to the L2 network through the delayed inbox on L1. This message stays there until the sequencer is back up again. When the sequencer comes back online after downtime, it processes all transactions from the delayed inbox before it accepts new transactions. The message that signals when the sequencer is down will be processed before any new messages with transactions that require the sequencer to be operational.
+
+## Optimism and Metis
+
+On Optimism and Metis, the sequencer’s status is relayed from L1 to L2 where the consumer can retrieve it.
+
+
+
+**On the L1 network:**
+
+1. A network of node operators runs the external adapter to post the latest sequencer status to the `AggregatorProxy` contract and relays the status to the `Aggregator` contract. The `Aggregator` contract calls the `validate` function in the `OptimismValidator` contract.
+
+1. The `OptimismValidator` contract calls the `sendMessage` function in the `L1CrossDomainMessenger` contract. This message contains instructions to call the `updateStatus(bool status, uint64 timestamp)` function in the sequencer uptime feed deployed on the L2 network.
+
+1. The `L1CrossDomainMessenger` contract calls the `enqueue` function to enqueue a new message to the `CanonicalTransactionChain`.
+
+1. The `Sequencer` processes the transaction enqueued in the `CanonicalTransactionChain` contract to send it to the L2 contract.
+
+**On the L2 network:**
+
+1. The `Sequencer` posts the message to the `L2CrossDomainMessenger` contract.
+
+1. The `L2CrossDomainMessenger` contract relays the message to the `OptimismSequencerUptimeFeed` contract.
+
+1. The message relayed by the `L2CrossDomainMessenger` contains instructions to call `updateStatus` in the `OptimismSequencerUptimeFeed` contract.
+
+1. Consumers can then read from the `AggregatorProxy` contract, which fetches the latest round data from the `OptimismSequencerUptimeFeed` contract.
+
+### Handling outages on Optimism and Metis
+
+If the sequencer is down, messages cannot be transmitted from L1 to L2 and **no L2 transactions are executed**. Instead, messages are enqueued in the `CanonicalTransactionChain` on L1 and only processed in the order they arrived later when the sequencer comes back up. As long as the message from the validator on L1 is already enqueued in the `CTC`, the flag on the sequencer uptime feed on L2 will be guaranteed to be flipped prior to any subsequent transactions. The transaction that flips the flag on the uptime feed will be executed before transactions that were enqueued after it. This is further explained in the diagrams below.
+
+When the Sequencer is down, all L2 transactions sent from the L1 network wait in the pending queue.
+
+1. **Transaction 3** contains Chainlink’s transaction to set the status of the sequencer as being down on L2.
+1. **Transaction 4** is a transaction made by a consumer that is dependent on the sequencer status.
+
+
+
+After the sequencer comes back up, it moves moves all transactions in the pending queue to the processed queue.
+
+1. Transactions are processed in the order they arrived so **Transaction 3** is processed before **Transaction 4**.
+1. Because **Transaction 3** happens before **Transaction 4**, **Transaction 4** will read the status of the Sequencer as being down and responds accordingly.
+
+
+
+## Example code
+
+Create the consumer contract for sequencer uptime feeds similarly to contracts you use for [Chainlink Data Feeds](/data-feeds/price-feeds/#solidity). Configure the constructor using the following variables:
+
+- Configure the `sequencerUptimeFeed` object with the [sequencer uptime feed proxy address](#available-networks) for your L2 network.
+- Configure the `priceFeed` object with one of the [Data Feed proxy addresses](/data-feeds/price-feeds/addresses/) that are available for your network.
+
+::solidity-remix[samples/PriceFeeds/PriceConsumerWithSequencerCheck.sol]
+
+The `sequencerUptimeFeed` object returns the following values:
+
+- `answer`: A variable with a value of either `1` or `0`
+ - 0: The sequencer is up
+ - 1: The sequencer is down
+- `startedAt`: This timestamp indicates when the sequencer changed status. This timestamp returns `0` if a round is invalid. When the sequencer comes back up after an outage, wait for the `GRACE_PERIOD_TIME` to pass before accepting answers from the price data feed. Subtract `startedAt` from `block.timestamp` and revert the request if the result is less than the `GRACE_PERIOD_TIME`.
+
+If the sequencer is up and the `GRACE_PERIOD_TIME` has passed, the function retrieves the latest price from the data feed using the `priceFeed` object.
diff --git a/src/pages/data-feeds/nft-floor-price/addresses.md b/src/pages/data-feeds/nft-floor-price/addresses.md
new file mode 100644
index 00000000000..5f2e5bd5030
--- /dev/null
+++ b/src/pages/data-feeds/nft-floor-price/addresses.md
@@ -0,0 +1,14 @@
+---
+layout: ../../../layouts/MainLayout.astro
+title: "NFT Floor Pricing Feed Addresses"
+section: ethereum
+datafeedtype: nftFloor
+metadata:
+ title: "NFT Floor Pricing Feed Addresses"
+ description: "NFT Floor Pricing Feed Addresses"
+date: Last Modified
+setup: |
+ import { FeedPage } from "@features/feeds"
+---
+
+
diff --git a/src/pages/data-feeds/nft-floor-price/index.md b/src/pages/data-feeds/nft-floor-price/index.md
new file mode 100644
index 00000000000..8bd946adeee
--- /dev/null
+++ b/src/pages/data-feeds/nft-floor-price/index.md
@@ -0,0 +1,24 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "NFT Floor Pricing Feeds"
+permalink: "docs/data-feeds/nft-floor-price/"
+whatsnext:
+ {
+ "Learn how to read answers from Data Feeds": "/docs/data-feeds/price-feeds/",
+ "Find contract addresses for NFT Floor Pricing Feeds": "/docs/data-feeds/nft-floor-price/addresses/",
+ }
+---
+
+Chainlink NFT Floor Pricing Feeds provide the lowest price of an NFT in a collection. These feeds operate the same way as other Chainlink Data Feeds. NFT Floor Pricing Feeds are supported by [Coinbase Cloud’s](https://www.coinbase.com/cloud/) aggregation algorithm and Chainlink’s oracle infrastructure to help eliminate extreme price outliers and make these feeds resistant to market manipulation. You can use NFT Floor Pricing Feeds for use cases that rely on high-quality NFT data, including lending and borrowing, on-chain derivatives, dynamic NFTs, gaming guilds, CeFi products, prediction markets, and more.
+
+Find the list of testnet feeds on the [Contract Addresses](/data-feeds/nft-floor-price/addresses/) page. To sign up for access to NFT Floor Pricing feeds on Ethereum Mainnet, [use this TypeForm](https://chainlinkcommunity.typeform.com/nft-price-feeds).
+
+## Using NFT Floor Pricing Feeds
+
+Read answers from NFT Floor Pricing Feeds the same way that you use [Price Feeds](/data-feeds/price-feeds/).
+
+Using Solidity, your smart contract should reference [`AggregatorV3Interface`](https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol), which defines the external functions implemented by Data Feeds.
+
+::solidity-remix[samples/PriceFeeds/NFTFloorPriceConsumerV3.sol]
diff --git a/src/pages/data-feeds/price-feeds/addresses.md b/src/pages/data-feeds/price-feeds/addresses.md
new file mode 100644
index 00000000000..26f6ba8c806
--- /dev/null
+++ b/src/pages/data-feeds/price-feeds/addresses.md
@@ -0,0 +1,13 @@
+---
+layout: ../../../layouts/MainLayout.astro
+title: "Price Feed Contract Addresses"
+section: ethereum
+metadata:
+ title: "Price Feed Contract Addresses"
+ description: "A list of Price Feed addresses on supported networks."
+date: Last Modified
+setup: |
+ import { FeedPage } from "@features/feeds"
+---
+
+
diff --git a/src/pages/data-feeds/price-feeds/api-reference.md b/src/pages/data-feeds/price-feeds/api-reference.md
new file mode 100644
index 00000000000..11a133f6bcf
--- /dev/null
+++ b/src/pages/data-feeds/price-feeds/api-reference.md
@@ -0,0 +1,458 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Data Feeds API Reference"
+permalink: "docs/data-feeds/price-feeds/api-reference/"
+metadata:
+ description: "API reference for using Chainlink Data Feeds in smart contracts."
+---
+
+When you use data feeds, retrieve the feeds through the `AggregatorV3Interface` and the proxy address. Optionally, you can call variables and functions in the `AccessControlledOffchainAggregator` contract to get information about the aggregator behind the proxy.
+
+## AggregatorV3Interface
+
+Import this interface to your contract and use it to run functions in the proxy contract. Create the interface object by pointing to the proxy address. For example, on Goerli you could create the interface object in the constructor of your contract using the following example:
+
+
+```solidity
+/**
+ * Network: Goerli
+ * Data Feed: BTC/USD
+ * Address: 0xA39434A63A52E749F02807ae27335515BA4b07F7
+ */
+constructor() {
+ priceFeed = AggregatorV3Interface(0xA39434A63A52E749F02807ae27335515BA4b07F7);
+}
+
+```
+
+To see examples for how to use this interface, read the [Using Data Feeds](/data-feeds/price-feeds/) guide.
+
+You can see the code for the [`AggregatorV3Interface` contract](https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol) on GitHub.
+
+### Functions in AggregatorV3Interface
+
+| Name | Description |
+| ----------------------------------- | -------------------------------------------------------------------- |
+| [decimals](#decimals) | The number of decimals in the response. |
+| [description](#description) | The description of the aggregator that the proxy points to. |
+| [getRoundData](#getrounddata) | Get data from a specific round. |
+| [latestRoundData](#latestrounddata) | Get data from the latest round. |
+| [version](#version) | The version representing the type of aggregator the proxy points to. |
+
+#### decimals
+
+Get the number of decimals present in the response value.
+
+
+```solidity
+function decimals() external view returns (uint8);
+
+```
+
+- `RETURN`: The number of decimals.
+
+#### description
+
+Get the description of the underlying aggregator that the proxy points to.
+
+
+```solidity
+function description() external view returns (string memory);
+
+```
+
+- `RETURN`: The description of the underlying aggregator.
+
+#### getRoundData
+
+Get data about a specific round, using the `roundId`.
+
+
+```solidity
+function getRoundData(
+ uint80 _roundId
+) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
+
+```
+
+**Parameters:**
+
+- `_roundId`: The round ID
+
+**Return values:**
+
+- `roundId`: The round ID
+- `answer`: The answer for this round
+- `startedAt`: Timestamp of when the round started
+- `updatedAt`: Timestamp of when the round was updated
+- `answeredInRound`: The round ID in which the answer was computed
+
+#### latestRoundData
+
+Get the price from the latest round.
+
+
+```solidity
+function latestRoundData() external view
+ returns (
+ uint80 roundId,
+ int256 answer,
+ uint256 startedAt,
+ uint256 updatedAt,
+ uint80 answeredInRound
+ )
+```
+
+**Return values:**
+
+- `roundId`: The round ID.
+- `answer`: The price.
+- `startedAt`: Timestamp of when the round started.
+- `updatedAt`: Timestamp of when the round was updated.
+- `answeredInRound`: The round ID of the round in which the answer was computed.
+
+#### version
+
+The version representing the type of aggregator the proxy points to.
+
+
+```solidity
+function version() external view returns (uint256)
+```
+
+- `RETURN`: The version number.
+
+## AccessControlledOffchainAggregator
+
+This is the contract for the aggregator. You can call functions on the aggregator directly, but it is a best practice to use the [AggregatorV3Interface](#aggregatorv3interface) to run functions on the proxy instead so that changes to the aggregator do not affect your application. Read the aggregator contract only if you need functions that are not available in the proxy.
+
+The aggregator contract has several variables and functions that might be useful for your application. Although aggregator contracts are similar for each data feed, some aggregators have different variables. Use the `typeAndVersion()` function on the aggregator to identify what type of aggregator it is and what version it is running.
+
+Always check the contract source code and configuration to understand how specific data feeds operate. For example, the [aggregator contract for BTC/USD on Arbitrum](https://arbiscan.io/address/0x942d00008d658dbb40745bbec89a93c253f9b882#code) is different from the aggregators on other networks.
+
+For examples of the contracts that are typically used in aggregator deployments, see the [libocr repository](https://github.com/smartcontractkit/libocr/blob/master/contract/) on GitHub.
+
+### Variables and functions in AccessControlledOffchainAggregator
+
+This contract imports `OffchainAggregator` and `SimpleReadAccessController`, which also include their own imports. The variables and functions lists include the publicly accessible items from these imported contracts.
+
+A simple way to read the variables or functions is to get the ABI from a blockchain explorer and point the ABI to the aggregator address. To do this in Remix, follow the [Using the ABI with AtAddress](https://remix-ide.readthedocs.io/en/latest/run.html#using-the-abi-with-ataddress) guide in the Remix documentation. As an example, you can find the ABI for the BTC/USD aggregator by viewing the [contract code in Etherscan](https://etherscan.io/address/0xae74faa92cb67a95ebcab07358bc222e33a34da7#code).
+
+**Variables:**
+
+| Name | Description |
+| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| LINK | The address for the LINK token contract on a specific network. |
+| billingAccessController | The address for the billingAccessController, which limits access to the [billing configuration](https://github.com/smartcontractkit/libocr/blob/master/contract/OffchainAggregatorBilling.sol) for the aggregator. |
+| checkEnabled | A boolean that indicates if access is limited to addresses on the internal access list. |
+| maxAnswer | The highest median answer that the aggregator will accept. This prevents the aggregator from accepting extreme erroneous values. |
+| minAnswer | The lowest median answer that the aggregator will accept. This prevents the aggregator from accepting extreme erroneous values. |
+| owner | The address that owns this aggregator contract. This controls which address can execute specific functions. |
+
+**Functions:**
+
+| Name | Description |
+| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [decimals](#decimals-1) | Return the number of digits of precision for the stored answer. Answers are stored in fixed-point format. |
+| [description](#description-1) | Return a description for this data feed. Usually this is an asset pair for a price feed. |
+| [getAnswer](#getanswer) | (Deprecated) |
+| [getBilling](#getbilling) | Retrieve the current billing configuration. |
+| [getRoundData](#getrounddata-1) | Get the full information for a specific aggregator round including the answer and update timestamps. Use this to get the full historical data for a round. |
+| [getTimestamp](#gettimestamp) | (Deprecated) |
+| [hasAccess](#hasaccess) | Check if an address has internal access. |
+| [latestAnswer](#latestanswer) | (Deprecated) |
+| [latestConfigDetails](#latestconfigdetails) | Return information about the current off-chain reporting protocol configuration. |
+| [latestRound](#latestround) | (Deprecated) |
+| [latestRoundData](#latestrounddata-1) | Get the full information for the most recent round including the answer and update timestamps. |
+| [latestTimestamp](#latesttimestamp) | (Deprecated) |
+| [latestTransmissionDetails](#latesttransmissiondetails) | Get information about the most recent answer. |
+| [linkAvailableForPayment](#linkavailableforpayment) | Get the amount of LINK on this contract that is available to make payments to oracles. This value can be negative if there are outstanding payment obligations. |
+| [oracleObservationCount](#oracleobservationcount) | Returns the number of observations that oracle is due to be reimbursed for. |
+| [owedPayment](#owedpayment) | Returns how much LINK an oracle is owed for its observations. |
+| [requesterAccessController](#requesteraccesscontroller) | Returns the address for the access controller contract. |
+| [transmitters](#transmitters) | The oracle addresses that can report answers to this aggregator. |
+| [typeAndVersion](#typeandversion) | Returns the aggregator type and version. Many aggregators are `AccessControlledOffchainAggregator 3.0.0`, but there are other variants in production. The version is for the type of aggregator, and different from the contract `version`. |
+| [validatorConfig](#validatorconfig) | Returns the address and the gas limit for the validator contract. |
+| [version](#version-1) | Returns the contract version. This is different from the `typeAndVersion` for the aggregator. |
+
+#### decimals
+
+Return the number of digits of precision for the stored answer. Answers are stored in fixed-point format.
+
+
+```solidity
+function decimals() external view returns (uint8 decimalPlaces);
+
+```
+
+#### description
+
+Return a description for this data feed. Usually this is an asset pair for a price feed.
+
+
+```solidity
+function description() public view override checkAccess returns (string memory) {
+ return super.description();
+}
+
+```
+
+#### getAnswer
+
+:::caution[ This function is deprecated.]
+
+:::
+
+#### getBilling
+
+Retrieve the current billing configuration.
+
+
+```solidity
+function getBilling()
+ external
+ view
+ returns (
+ uint32 maximumGasPrice,
+ uint32 reasonableGasPrice,
+ uint32 microLinkPerEth,
+ uint32 linkGweiPerObservation,
+ uint32 linkGweiPerTransmission
+ )
+{
+ Billing memory billing = s_billing;
+ return (
+ billing.maximumGasPrice,
+ billing.reasonableGasPrice,
+ billing.microLinkPerEth,
+ billing.linkGweiPerObservation,
+ billing.linkGweiPerTransmission
+ );
+}
+
+```
+
+#### getRoundData
+
+Get the full information for a specific aggregator round including the answer and update timestamps. Use this to get the full historical data for a round.
+
+
+```solidity
+function getRoundData(
+ uint80 _roundId
+)
+ public
+ view
+ override
+ checkAccess
+ returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
+{
+ return super.getRoundData(_roundId);
+}
+
+```
+
+#### getTimestamp
+
+:::caution[ This function is deprecated.]
+
+:::
+
+#### hasAccess
+
+Check if an address has internal access.
+
+
+```solidity
+function hasAccess(address _user, bytes memory _calldata) public view virtual override returns (bool) {
+ return super.hasAccess(_user, _calldata) || _user == tx.origin;
+}
+
+```
+
+#### latestAnswer
+
+:::caution[ This function is deprecated.]
+
+:::
+
+#### latestConfigDetails
+
+Return information about the current off-chain reporting protocol configuration.
+
+
+```solidity
+function latestConfigDetails() external view returns (uint32 configCount, uint32 blockNumber, bytes16 configDigest) {
+ return (s_configCount, s_latestConfigBlockNumber, s_hotVars.latestConfigDigest);
+}
+
+```
+
+#### latestRound
+
+:::caution[ This function is deprecated.]
+
+:::
+
+#### latestRoundData
+
+Get the full information for the most recent round including the answer and update timestamps.
+
+
+```solidity
+function latestRoundData()
+ public
+ view
+ override
+ checkAccess
+ returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
+{
+ return super.latestRoundData();
+}
+
+```
+
+#### latestTimestamp
+
+:::caution[ This function is deprecated.]
+
+:::
+
+#### latestTransmissionDetails
+
+Get information about the most recent answer.
+
+
+```solidity
+function latestTransmissionDetails()
+ external
+ view
+ returns (bytes16 configDigest, uint32 epoch, uint8 round, int192 latestAnswer, uint64 latestTimestamp)
+{
+ require(msg.sender == tx.origin, "Only callable by EOA");
+ return (
+ s_hotVars.latestConfigDigest,
+ uint32(s_hotVars.latestEpochAndRound >> 8),
+ uint8(s_hotVars.latestEpochAndRound),
+ s_transmissions[s_hotVars.latestAggregatorRoundId].answer,
+ s_transmissions[s_hotVars.latestAggregatorRoundId].timestamp
+ );
+}
+
+```
+
+#### linkAvailableForPayment
+
+Get the amount of LINK on this contract that is available to make payments to oracles. This value can be negative if there are outstanding payment obligations.
+
+
+```solidity
+function linkAvailableForPayment() external view returns (int256 availableBalance) {
+ // there are at most one billion LINK, so this cast is safe
+ int256 balance = int256(LINK.balanceOf(address(this)));
+ // according to the argument in the definition of totalLINKDue,
+ // totalLINKDue is never greater than 2**172, so this cast is safe
+ int256 due = int256(totalLINKDue());
+ // safe from overflow according to above sizes
+ return int256(balance) - int256(due);
+}
+
+```
+
+#### oracleObservationCount
+
+Returns the number of observations that oracle is due to be reimbursed for.
+
+
+```solidity
+function oracleObservationCount(address _signerOrTransmitter) external view returns (uint16) {
+ Oracle memory oracle = s_oracles[_signerOrTransmitter];
+ if (oracle.role == Role.Unset) {
+ return 0;
+ }
+ return s_oracleObservationsCounts[oracle.index] - 1;
+}
+
+```
+
+#### owedPayment
+
+Returns how much LINK an oracle is owed for its observations.
+
+
+```solidity
+function owedPayment(address _transmitter) public view returns (uint256) {
+ Oracle memory oracle = s_oracles[_transmitter];
+ if (oracle.role == Role.Unset) {
+ return 0;
+ }
+ Billing memory billing = s_billing;
+ uint256 linkWeiAmount = uint256(s_oracleObservationsCounts[oracle.index] - 1) *
+ uint256(billing.linkGweiPerObservation) *
+ (1 gwei);
+ linkWeiAmount += s_gasReimbursementsLinkWei[oracle.index] - 1;
+ return linkWeiAmount;
+}
+
+```
+
+#### requesterAccessController
+
+Returns the address for the access controller contract.
+
+
+```solidity
+function requesterAccessController() external view returns (AccessControllerInterface) {
+ return s_requesterAccessController;
+}
+
+```
+
+#### transmitters
+
+The oracle addresses that can report answers to this aggregator.
+
+
+```solidity
+function transmitters() external view returns (address[] memory) {
+ return s_transmitters;
+}
+
+```
+
+#### typeAndVersion
+
+Returns the aggregator type and version. Many aggregators are `AccessControlledOffchainAggregator 2.0.0`, but there are other variants in production. The version is for the type of aggregator, and different from the contract `version`.
+
+
+```solidity
+function typeAndVersion() external pure virtual override returns (string memory) {
+ return "AccessControlledOffchainAggregator 2.0.0";
+}
+
+```
+
+#### validatorConfig
+
+Returns the address and the gas limit for the validator contract.
+
+
+```solidity
+function validatorConfig() external view returns (AggregatorValidatorInterface validator, uint32 gasLimit) {
+ ValidatorConfig memory vc = s_validatorConfig;
+ return (vc.validator, vc.gasLimit);
+}
+
+```
+
+#### version
+
+Returns the contract version. This is different from the `typeAndVersion` for the aggregator.
+
+
+```solidity
+function version() external view returns (uint256);
+
+```
diff --git a/src/pages/data-feeds/price-feeds/historical-data.mdx b/src/pages/data-feeds/price-feeds/historical-data.mdx
new file mode 100644
index 00000000000..48285e69f83
--- /dev/null
+++ b/src/pages/data-feeds/price-feeds/historical-data.mdx
@@ -0,0 +1,142 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Historical Price Data"
+permalink: "docs/data-feeds/price-feeds/historical-data/"
+whatsnext: { "API Reference": "/data-feeds/price-feeds/api-reference/", "Contract Addresses": "/data-feeds/" }
+metadata:
+ title: "Get Historical Data"
+ description: "How to use Chainlink Data Feeds to retrieve historical data in your smart contracts."
+---
+
+import { HistoricalPrice, priceFeedAddresses } from "@features/feeds"
+import { Aside } from "@components"
+import CodeSample from "@components/CodeSample/CodeSample.astro"
+import button from "@chainlink/design-system/button.module.css"
+
+The most common use case for Data Feeds is to [Get the Latest Data](/data-feeds/price-feeds/) from a feed. However, the [AggregatorV3Interface.sol](https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol) also has functions to retrieve data of a previous round IDs.
+
+There are two parameters that can cause Chainlink nodes to update:
+
+| Name | Description |
+| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
+| Deviation Threshold | Chainlink nodes are monitoring data off-chain. The deviation of the real-world data beyond a certain interval triggers all the nodes to update. |
+| Heartbeat Threshold | If the data values stay within the deviation parameters, it will only trigger an update every _X_ minutes / hours. |
+
+You can find these parameters at [data.chain.link](https://data.chain.link/) on an example like [ETH / USD](https://data.chain.link/ethereum/mainnet/crypto-usd/eth-usd).
+
+To learn how data feeds update, see the [Decentralized Data Model](/architecture-overview/architecture-decentralized-model#aggregator) page.
+
+## Historical Rounds
+
+As shown in the [decentralized model](/architecture-overview/architecture-decentralized-model/), the consumer contracts call the proxy contract, which abstracts the underlying aggregator contract. The main advantage is to enable upgrades of the aggregator without impacting the consumer contracts. That also means that historical data can can be stored in different aggregators.
+As show in the following sequence diagram, to get historical data, call the `getRoundData` [function](/data-feeds/price-feeds/api-reference/#getrounddata) function and provide `roundId` as a parameter.
+
+
+
+Note that roundIds have different meanings in proxy contracts and in aggregator contracts.
+
+### `roundId` in Aggregator (aggregatorRoundId)
+
+Oracles provide periodic data updates to the aggregators. Data feeds are updated in **rounds**. Rounds are identified by their `roundId`, which increases with each new round. This increase may not be monotonic. Knowing the `roundId` of a previous round allows contracts to consume historical data.
+
+The examples in this document name the aggregator `roundId` as `aggregatorRoundId` to differentiate it from the proxy `roundId`.
+
+### `roundId` in Proxy
+
+Because a proxy has references to current and all previous underlying aggregators, it needs a way to fetch data from the correct aggregator. The `roundId` is computed in the [proxy contract](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.7/dev/AggregatorProxy.sol) as shown in the following example:
+
+{/* prettier-ignore */}
+```solidity
+roundId = uint80((uint256(phaseId) << 64) | aggregatorRoundId);
+```
+
+where:
+
+- `phaseId` is incremented each time the underlying aggregator implementation is updated. It is used as key to find the aggregator address.
+- `aggregatorRoundId` is the aggregator `roundId`. The id starts at 1.
+- `roundId` is the computed round id. From the above formula, you can think of it as a large number containing the `phaseId` and the `aggregatorRoundId`.
+
+
+ The example formula above ensures that no matter how many times the underlying aggregator changes, the proxy `roundId`
+ will always increase.
+
+
+**Example:**
+
+When you query historical data, it is important to know when you reach the end of the history of the underlying aggregator. As an example, if the `latestRoundData` [function](/data-feeds/price-feeds/api-reference/#latestrounddata) of the [LINK / USD feed on Ethereum Mainnet](/data-feeds/price-feeds/addresses/?network=ethereum) returns `roundId = 92233720368547771158`, you can use this value to compute the `phaseId` and `aggregatorRoundId`:
+
+- `phaseId = 92233720368547771158 >> 64`: Right shifting an integer by 64 bits is equivalent to dividing it by 2^64: `phaseId = 92233720368547771158/ 2^64 = 5`. The current phase id is 5 , which means that this proxy has had 5 underlying aggregators since its initial deployment.
+- `aggregatorRoundId = uint64(92233720368547771158)`: This retrieves the first 64 bits from the right. To calculate this off-chain, you can use the following JavaScript example:
+
+```javascript
+// First parse to BigInt to perform computation with big integers
+const num = BigInt("92233720368547771158")
+const num2 = BigInt("0xFFFFFFFFFFFFFFFF") // Largest 64bits integer
+
+console.log(Number(num >> 64n)) // returns 5 (phaseId)
+console.log(Number(num & num2)) // returns 13078 (aggregatorRoundId) . Use & (AND bitwise operator) which sets each bit to _1_ if both bits are _1_
+```
+
+Using _13078_ as the current aggregator's round, get its historical data by looping over the [`getRoundData` function](/data-feeds/price-feeds/api-reference/#getrounddata):
+
+- Start from the first round: _92233720368547758081_ (result of _92233720368547771158 - 13078 + 1_)
+- Continue until the current round: _92233720368547771158_
+
+To get the historical data for previous aggregators, decrement the `phaseId` and start from round _1_. For phase _4_, get the starting `roundId` off-chain using the following JavaScript example:
+
+```javascript
+const phaseId = BigInt("4")
+const aggregatorRoundId = BigInt("1")
+
+roundId = (phaseId << 64n) | aggregatorRoundId // returns 73786976294838206465n
+```
+
+Loop over the [`getRoundData` function](/data-feeds/price-feeds/api-reference/#getrounddata). Start at _73786976294838206465_ and increment it until you get a revert. This means that you reached the last round for the underlying aggregator. The same process could be repeated for previous `phaseIds` (3,2,1).
+
+
+ The examples showed how to loop off-chain to fetch all historical data from a given proxy. You could also write a
+ similar code on-chain, but be aware that this could cause **very high gas prices** if a state is changed within the
+ same function.
+
+
+### `getRoundData` return values
+
+The [`getRoundData` function](/data-feeds/price-feeds/api-reference/#getrounddata) returns the following values:
+
+- `roundId`: The combination of `aggregatorRoundId` and `phaseId` (see explanation above). The `roundId` can jump significantly when the `phaseId` is updated.
+- `answer` is the price.
+- `answeredInRound`: The combination of `aggregatorAnsweredInRound` and `phaseId`. `aggregatorAnsweredInRound`: The round the answer was updated in. You can check `answeredInRound` against the current `roundId`. If `answeredInRound` is less than `roundId`, the answer is being carried over. If `answeredInRound` is equal to `roundId`, then the answer is fresh.
+- `startedAt`: The timestamp when the round started.
+- `updatedAt`: The timestamp when the answer was computed.
+
+
+ A read can revert if the caller is requesting the details of a round that was invalid or has not yet been answered. If
+ you are deriving a round ID without having observed it before, the round might not be complete. To check the round,
+ validate that the timestamp on that round is not 0. In a best-case scenario, rounds update chronologically. However, a
+ round can time out if it doesn't reach consensus. Technically, that is a timed out round that carries over the answer
+ from the previous round.
+
+
+### Solidity
+
+
+
+### Javascript
+
+
+
+
+
+### Python
+
+
+
+ {"Run this Python example"}
+
diff --git a/src/pages/data-feeds/price-feeds/index.mdx b/src/pages/data-feeds/price-feeds/index.mdx
new file mode 100644
index 00000000000..413ac748bd0
--- /dev/null
+++ b/src/pages/data-feeds/price-feeds/index.mdx
@@ -0,0 +1,116 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Using Price Feeds"
+permalink: "docs/data-feeds/price-feeds/"
+whatsnext:
+ {
+ "Historical Price Data": "/data-feeds/price-feeds/historical-data/",
+ "Price Feeds API Reference": "/data-feeds/price-feeds/api-reference/",
+ "Price Feed Contract Addresses": "/data-feeds/price-feeds/addresses/",
+ }
+metadata:
+ title: "Using Data Feeds"
+ description: "How to use Chainlink Data Feeds in your smart contracts."
+---
+
+import { LatestPrice, priceFeedAddresses } from "@features/feeds"
+import { Aside } from "@components"
+import { Tabs } from "@components/Tabs"
+import button from "@chainlink/design-system/button.module.css"
+import CodeSample from "@components/CodeSample/CodeSample.astro"
+
+Chainlink Data Feeds are the quickest way to connect your smart contracts to the real-world market prices of assets. For example, one use for data feeds is to enable smart contracts to retrieve the latest pricing data of an asset in a single call.
+
+This guide applies specifically to using data feeds on EVM Chains. To get the full list of Chainlink Price Feeds running on the EVM Chains, see the [Contract Addresses](/data-feeds/price-feeds/addresses/) page.
+
+
+ Be aware of the quality of the data that you use. [Learn more about making responsible data quality
+ decisions.](/data-feeds/selecting-data-feeds/)
+
+
+For important updates regarding the use of Chainlink Price Feeds, users should join the official Chainlink Discord and subscribe to the data-feeds-user-notifications channel: [https://discord.gg/Dqy5N9UbsR](https://discord.gg/Dqy5N9UbsR)
+
+These examples show you how to get the price of Ethereum (ETH) on the Ethereum Goerli testnet, but you can modify the examples to work on other chains as well. The list of price feeds for each network are available on the [Data Feed Contracts](/data-feeds/price-feeds/addresses/) page. For development, use testnet data feeds such as the [BTC / USD feed](https://goerli.etherscan.io/address/0xA39434A63A52E749F02807ae27335515BA4b07F7) on the Goerli testnet.
+
+You can write smart contracts that consume Price Feeds using several languages, but this guide shows examples using the following languages:
+
+- [Solidity](#solidity)
+- [Vyper](#vyper)
+- [Javascript](#javascript) with [web3.js](https://web3js.readthedocs.io/)
+- [Python](#python) with [Web3.py](https://web3py.readthedocs.io/en/stable/)
+- [Golang](#golang) with [go-ethereum](https://github.com/ethereum/go-ethereum)
+
+## Solidity
+
+To consume price data, your smart contract should reference [`AggregatorV3Interface`](https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol), which defines the external functions implemented by Data Feeds.
+
+
+
+The `latestRoundData` function returns five values representing information about the latest price data. See the [Data Feeds API Reference](/data-feeds/price-feeds/api-reference/) for more details.
+
+## Vyper
+
+To consume price data, your smart contract should import `AggregatorV3Interface` which defines the external functions implemented by Data Feeds. You can find it [here](https://github.com/smartcontractkit/apeworx-starter-kit/blob/main/contracts/interfaces/AggregatorV3Interface.vy).
+You can find a `PriceConsumer` example [here](https://github.com/smartcontractkit/apeworx-starter-kit/blob/main/contracts/PriceConsumer.vy). Read the _**apeworx-starter-kit**_ [README](https://github.com/smartcontractkit/apeworx-starter-kit) to learn how to run the example.
+
+## Javascript
+
+This example uses [web3.js](https://web3js.readthedocs.io/) to retrieve feed data from the [BTC / USD feed](https://goerli.etherscan.io/address/0xA39434A63A52E749F02807ae27335515BA4b07F7) on the Goerli testnet.
+
+
+ web3.js
+ ethers.js
+
+
+
+
+
+
+
+
+
+
+## Python
+
+This example uses [Web3.py](https://web3py.readthedocs.io/en/stable/) to retrieve feed data from the [BTC / USD feed](https://goerli.etherscan.io/address/0xA39434A63A52E749F02807ae27335515BA4b07F7) on the Goerli testnet.
+
+
+
+ {"Run this Python example"}
+
+
+## Golang
+
+You can find an example with all the source files [here](https://github.com/smartcontractkit/smart-contract-examples/tree/main/pricefeed-golang). This example uses [go-ethereum](https://github.com/ethereum/go-ethereum) to retrieve feed data from the [BTC / USD feed](https://goerli.etherscan.io/address/0xA39434A63A52E749F02807ae27335515BA4b07F7) on the Goerli testnet.
+To learn how to run the example, see the [README](https://github.com/smartcontractkit/smart-contract-examples/blob/main/pricefeed-golang/README.md).
+
+
+ You can use the [Feed Registry](/data-feeds/feed-registry/) to reference data feed assets by name or currency
+ identifier instead of by pair/proxy address.
+
+
+## Getting a different price denomination
+
+Chainlink Data Feeds can be used in combination to derive denominated price pairs in other currencies.
+
+If you require a denomination other than what is provided, you can use two data feeds to derive the pair that you need. For example, if you needed a BTC / EUR price, you could take the BTC / USD feed and the EUR / USD feed and derive BTC / EUR using division.
+
+
+
+
+ If your contracts require Solidity versions that are `>=0.6.0 <0.8.0`, use [OpenZeppelin's SafeMath version 3.4](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.4/contracts/math/SafeMath.sol).
+
+
+
+
+## How Do Data Feeds Get Their Data?
+
+Data Feeds are aggregated from many data sources by a decentralized set of independent Node Operators. The [Decentralized Data Model](/architecture-overview/architecture-decentralized-model/) describes this in detail.
+
+## More Aggregator Functions
+
+Getting the latest price is not the only data that aggregators can retrieve. You can also retrieve historical price data. To learn more, see the [Historical Price Data](/data-feeds/price-feeds/historical-data/) page.
+
+To understand different use cases for Chainlink Price Feeds, refer to [Other Tutorials](/getting-started/other-tutorials/).
diff --git a/src/pages/data-feeds/proof-of-reserve/addresses.md b/src/pages/data-feeds/proof-of-reserve/addresses.md
new file mode 100644
index 00000000000..445bdb3da3e
--- /dev/null
+++ b/src/pages/data-feeds/proof-of-reserve/addresses.md
@@ -0,0 +1,14 @@
+---
+layout: ../../../layouts/MainLayout.astro
+title: "Proof of Reserve Feed Addresses"
+section: ethereum
+datafeedtype: por
+metadata:
+ title: "Proof of Reserve Feed Addresses"
+ description: "Chainlink Proof of Reserve Feed Addresses"
+date: Last Modified
+setup: |
+ import { FeedPage } from "@features/feeds"
+---
+
+
diff --git a/src/pages/data-feeds/proof-of-reserve/index.md b/src/pages/data-feeds/proof-of-reserve/index.md
new file mode 100644
index 00000000000..a99797f1248
--- /dev/null
+++ b/src/pages/data-feeds/proof-of-reserve/index.md
@@ -0,0 +1,55 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Proof of Reserve Feeds"
+permalink: "docs/data-feeds/proof-of-reserve/"
+whatsnext: { "Find contract addresses for Proof of Reserve Feeds": "/docs/data-feeds/proof-of-reserve/addresses/" }
+---
+
+Chainlink Proof of Reserve Feeds provide the status of the reserves for several assets. You can consume these feeds the same way as [Price Feeds](/data-feeds/price-feeds/).
+
+To find a list of available Proof of Reserve Feeds, see the [Contract Addresses](/data-feeds/proof-of-reserve/addresses/) page.
+
+## Types of Proof of Reserve Feeds
+
+Reserves are available for both cross-chain assets and off-chain assets. Token issuers prove the reserves for their assets through several different methods:
+
+- [Cross-chain reserves](#cross-chain-reserves):
+ - Wallet address manager
+ - Self-attested wallet API
+- [Off-chain reserves](#off-chain-reserves):
+ - Third-party API
+ - Custodian API
+ - Self-attested API
+
+### Cross-chain reserves
+
+Cross-Chain reserves are sourced from the network where the reserves are held. This includes but is not limited to networks including Bitcoin, Filecoin, Cardano, and chains where Chainlink has a native integration. Chainlink Node operators can report cross-chain reserves by running an [external adapter](/chainlink-nodes/external-adapters/external-adapters) and querying the source-chain client directly. In some instances, the reserves are composed of a dynamic list of IDs or addresses using a composite adapter.
+
+
+
+Cross-chain reserves provide their data using the following methods:
+
+- Wallet address manager: The project uses the [IPoRAddressList](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/PoRAddressList.sol) wallet address manager contract and self-attests to which addresses they own.
+- Self-attested wallet API: The project attests which addresses they own through a self-hosted API.
+
+### Off-chain reserves
+
+Off-Chain reserves are sourced from APIs through an [external adapter](/chainlink-nodes/external-adapters/external-adapters).
+
+
+
+Off-chain reserves provide their data using the following methods:
+
+- Third-party API: An auditor or a third-party verifies the reserves and provides that data through an API.
+- Custodian API: Reserve status is read directly from a bank or custodian API.
+- Self-attested API: Reserve status is read from an API that the token issuer hosts.
+
+## Using Proof of Reserve Feeds
+
+Read answers from Proof of Reserve Feeds the same way that you use [Price Feeds](/data-feeds/price-feeds/).
+
+Using Solidity, your smart contract should reference [`AggregatorV3Interface`](https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol), which defines the external functions implemented by Data Feeds.
+
+::solidity-remix[samples/PriceFeeds/ReserveConsumerV3.sol]
diff --git a/src/pages/data-feeds/selecting-data-feeds.md b/src/pages/data-feeds/selecting-data-feeds.md
new file mode 100644
index 00000000000..045ec4e9b99
--- /dev/null
+++ b/src/pages/data-feeds/selecting-data-feeds.md
@@ -0,0 +1,194 @@
+---
+layout: ../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Selecting Quality Data Feeds"
+excerpt: "Learn how to assess data feeds that you use in your smart contracts."
+---
+
+When you design your applications, consider the quality of the data that you use in your smart contracts. Ultimately you are responsible for identifying and assessing the accuracy, availability, and quality of data that you choose to consume via the Chainlink Network. Note that all feeds contain some inherent risk. Read the [Risk Mitigation](#risk-mitigation) and [Evaluating Data Sources](#evaluating-data-sources-and-risks) sections when making design decisions. Chainlink lists decentralized data feeds in the documentation to help developers build new applications integrated with data.
+
+## Data Feed Categories
+
+This categorization is put in place to inform users about the intended use cases of feeds and help to highlight some of the inherent market risks surrounding the data quality of these feeds.
+
+All feeds published on [docs.chain.link](http://docs.chain.link) are monitored and maintained to the same levels and standards. Each feed goes through a rigorous assessment process when implemented. The assessment criteria can change depending on the product type of feed being deployed.
+
+Feeds do though evolve over time and we regularly monitor their market fundamentals and will proactively communicate any upcoming changes or issues we identify with a feed, these categories are designed to act as a mechanism in order to assist in accomplishing that task.
+
+Data feeds are grouped into the following categories based on the level of risk from lowest to highest:
+
+- [🟢 Verified Feeds](#-verified-feeds)
+- [🟡 Monitored Feeds](#-monitored-feeds)
+- [🔵 Custom Feeds](#-custom-feeds)
+- [⚫ Specialized Feeds](#-specialized-feeds)
+- [⭕ Deprecating](#-deprecating)
+
+:::note[ For important updates regarding the use of Chainlink Price Feeds, users should join the official Chainlink Discord and subscribe to the [data-feeds-user-notifications channel](https://discord.gg/Dqy5N9UbsR).]
+
+:::
+
+### 🟢 Verified Feeds
+
+These are data feeds that follow a standardized data feeds workflow. Chainlink node operators each query several sources for the market price and aggregate the estimates provided by those sources.
+
+Verified feeds have the following characteristics:
+
+- Highly resilient to disruption
+- Leverage many data sources
+- Use an extensive network of nodes
+- Highly liquid and well represented on a large number of markets
+
+These feeds incorporate three layers of aggregation (at the data source, node operator, and oracle network layers), providing industry-grade security and reliability on the price data they reference. To learn more about the three layers of data aggregation, see the blog post about [Data Aggregation in Chainlink Price Feeds](https://blog.chain.link/levels-of-data-aggregation-in-chainlink-price-feeds/).
+
+Inherent risks might still exist based on your use case, the blockchain on which the feed is deployed and the conditions on that chain.
+
+### 🟡 Monitored Feeds
+
+Feeds under the monitored category are _under review_ by the Chainlink Labs team to support the stability of the broader ecosystem. While generally resilient and distributed, these feeds carry additional risk.
+
+Data feeds might be under review for the following reasons:
+
+- The token project or asset is in early development
+- The project is going through a market event such as a token or liquidity migration
+- The token or project is being deprecated in the market
+- The asset has a high spread between data providers or low liquidity in the market
+
+### 🔵 Custom Feeds
+
+Custom Feeds are built to serve a specific use case and might not be suitable for general use or your use case's risk parameters. Users must evaluate the properties of a feed to make sure it aligns with their intended use case. [Contact the Chainlink Labs team](https://chainlinkcommunity.typeform.com/to/OYQO67EF?page=market-data-feeds) if you want more detail on any specific feeds in this category.
+
+Custom feeds have the following categories and compositions:
+
+- **On-chain single source feeds:** These feeds take their data from an on-chain source, however the feed has only a single data provider currently supporting the feed.
+- **On-chain Proof of Reserve Feeds:** Chainlink Proof of Reserve uses the largest decentralized collection of security-reviewed and Sybil-resistant node operators in the industry to acquire and verify reserve data. In this use case, reserves reside on-chain.
+- **Technical Feeds:** Feeds within this category measure a particular technical metric from a specified blockchain. For example, Fast Gas or Block Difficulty.
+- **Total Value Locked Feeds:** These feeds measure the total value locked in a particular protocol.
+- **Custom Index Feeds:** An index calculates a function of the values for multiple underlying assets. The function is specific to that index and is typically calculated by node operators following an agreed formula.
+
+If you plan on using one of these feeds and would like to get a more detailed understanding, [contact the Chainlink Labs team](https://chainlinkcommunity.typeform.com/to/OYQO67EF?page=market-data-feeds).
+
+### ⚫ Specialized Feeds
+
+These are purpose-built feeds that might rely heavily on contracts maintained by external entities. Typical users of these feeds are large institutional users with deep expertise in the market space they operate in.
+
+These feeds are monitored and well-supported, but they might not meet the same levels of resiliency as the above categories. We strongly advise you to [speak with the Chainlink Labs team](https://chainlinkcommunity.typeform.com/to/OYQO67EF?page=market-data-feeds) to understand their use cases, properties, and associated risks.
+
+**Examples of Specialized feeds:**
+
+- **Off-chain Single Source Feeds:** Some data providers use a single data source, which might be necessary if only one source exists off-chain for a specific type of data.
+- **Off-chain Proof of Reserve Feeds:** Chainlink Proof of Reserve uses the largest decentralized collection of security-reviewed and Sybil-resistant node operators in the industry to acquire and verify reserve data. In this use case, reserves reside off-chain.
+- **LP Token Feeds:** These feeds use a decentralized feed for the underlying asset as well as calculations to value the LP tokens.
+- **Wrapped Calculated Feeds:** These feeds are typically pegged 1:1 to the underlying token or asset. Under normal market conditions, these feeds track their underlying value accurately. However, the price is a derivative formed from a calculated method and might not always track value precisely.
+
+If you plan on using one of these feeds and would like to get a more detailed understanding, [contact the Chainlink Labs team](https://chainlinkcommunity.typeform.com/to/OYQO67EF?page=market-data-feeds).
+
+### ⭕ Deprecating
+
+These feeds are being deprecated. To find the deprecation dates for specific feeds, see the [Feeds Scheduled For Deprecation](/data-feeds/deprecating-feeds/) page.
+
+## Risk Mitigation
+
+As a development best practice, design your systems and smart contracts to be resilient and mitigate risk to your protocol and your users. Ensure that your systems can tolerate known and unknown exceptions that might occur. Some examples include but are not limited to volatile market conditions, the degraded performance of infrastructure, chains, or networks, and any other upstream outage related to data providers or node operators. You bear responsibility for any manner in which you use the Chainlink Network, its software, and documentation.
+
+To help you prepare for unforeseen market events, we recommend taking additional steps for custom or specialized feeds to protect your application or protocol. This might also be worth considering in all categories based on the value that your application secures. This tooling is put in place to mitigate extreme market events, possible malicious activity on third-party venues or contracts, potential delays, performance degradation, and outages.
+
+Below are some examples of tooling that Chainlink users have put in place:
+
+- **Circuit breakers:** In the case of an extreme price event, the contract would pause operations for a limited period of time.
+- **Contract update delays:** Contracts would not update until the protocol had received a recent fresh input from the data feed.
+- **Manual kill switch:** If a vulnerability or bug is discovered in one of the upstream contracts, the user can manually cease operation and temporarily sever the connection to the data feed.
+- **Monitoring:** Some users create their own monitoring alerts based on deviations in the data feeds that they are using.
+- **Soak testing:** Users are strongly advised to thoroughly test price feed integrations and incorporate a [soak period](https://en.wikipedia.org/wiki/Soak_testing) prior to providing access to end users or securing value.
+
+For more detailed information about some of these examples, see the [Monitoring data feeds](/data-feeds/#monitoring-data-feeds) documentation.
+
+For important updates regarding the use of Chainlink Price Feeds, users should join the official Chainlink Discord and subscribe to the data-feeds-user-notifications channel: https://discord.gg/Dqy5N9UbsR
+
+## Chainlink Community Deployments
+
+Chainlink technology is used by many within the blockchain community to support their use cases. Deployments built and run by community members are not tracked in the Chainlink documentation. Chainlink's community is continuously growing, and we believe they play a vital role in developing the ecosystem, so we continue to develop our software and tooling for anyone to use. Users have a wide variety of options for choosing how to deliver data on-chain. They can deploy Chainlink nodes themselves or via the extensive network of node operators that offer services and access one of the community-managed oracle networks that support the supply of various types of data on-chain. Chainlink Labs does not take responsibility for the use of Chainlink node software.
+
+It is always recommended that you conduct a thorough analysis of your requirements and carry out appropriate due diligence on any partners you wish to use with your project.
+
+> **The Chainlink Labs team does not monitor community deployments** and encourages users to use best practices in observability, monitoring, and risk mitigation as appropriate for your application's stage of development and use case.
+
+As your usage of data feeds evolves and requirements for higher availability and greater security increases, such as securing substantive value, the reliability properties of your data feed will become crucial. [Contact Chainlink Labs team](https://chainlinkcommunity.typeform.com/to/OYQO67EF?page=market-data-feeds) for services to ensure deployments meet the highest levels of availability and security.
+
+**High Risk: Forked, modified, or custom software:**
+
+As Chainlink is open source, independent forks and modifications may exist. Chainlink Labs and development teams are not involved in these and do not track or maintain visibility on them. Chainlink Labs is not responsible for updates, enhancements, or bug fixes for these versions, and Chainlink Labs does not monitor them. Their use might pose risks that can do harm to your project. Users are responsible for thoroughly vetting and validating such deployments and determining their suitability.
+
+## Evaluating Data Sources and Risks
+
+If your smart contracts use data feeds, assess those data feeds for the following characteristics:
+
+- [Liquidity and its Distribution](#liquidity-and-its-distribution)
+- [Single Source Data Providers](#single-source-data-providers)
+- [Crypto and Blockchain Actions](#crypto-and-blockchain-actions)
+- [Market Failures Resulting from Extreme Events](#market-failures-resulting-from-extreme-events)
+- [Periods of High Network Congestion](#periods-of-high-network-congestion)
+- [Unknown and Known Users](#unknown-and-known-users)
+- [Fast Gas Reliability](#fast-gas-reliability)
+
+### Liquidity and its Distribution
+
+If your smart contract relies on pricing data for a specific asset, make sure that the asset has sufficient liquidity in the market to avoid price manipulation. Assets with low liquidity can be volatile, which might negatively impact your application and its users. Malicious actors might try to exploit volatility to take advantage of the logic in a smart contract and cause it to execute in a way that you did not intend.
+
+Some data feeds obtain their pricing data from individual exchanges rather than from aggregated price tracking services that gather their data from multiple exchanges. These are marked as such in the docs page for that feed. Assess the liquidity and reliability of that specific exchange.
+
+_Liquidity migrations_ occur when a project moves its tokens from one liquidity provider (such as a DEX, a CEX, or a new DeFi application) to another. When liquidity migrations occur, it can result in low liquidity in the original pool, making the asset susceptible to market manipulation. If your project is considering a liquidity migration, you should coordinate with relevant stakeholders, including liquidity providers, exchanges, oracle node operators, and users, to ensure prices are accurately reported throughout the migration.
+
+Feeds for assets with low market liquidity where data providers exhibit an abnormal price spread may, on occasion, see a price oscillate between two or more price points within regular intervals. To mitigate risk associated with such price oscillation, users must regularly monitor & assess the quality of an asset’s liquidity.
+
+Design and test your contracts to handle price spikes and implement risk management measures to protect your assets. For example, create mock tests that return various oracle responses.
+
+### Single Source Data Providers
+
+Some data providers use a single data source, which might be necessary if only one source exists off-chain for a specific type of data. Evaluate data providers to make sure they provide high-quality data that your smart contracts can rely on. Any error or omission in the provider's data might negatively impact your application and its users.
+
+### Crypto and Blockchain Actions
+
+Price data quality is subject to crypto actions by the crypto and blockchain project teams. Crypto actions are similar to [corporate actions](https://en.wikipedia.org/wiki/Corporate_action) but are specific to cryptocurrency and blockchain projects, such as token renaming, token swaps, redenominations, splits, network upgrades, and other migrations that teams who govern the blockchain or token might undertake
+
+Sustaining data quality is dependent on data sources implementing the necessary adjustments related to such actions. For example, when a project upgrades to a new version of their token, this results in a _token migration_. When token migrations occur, they require building a new price feed to ensure that the token price is accurately reported. Similarly, actions by blockchain project teams, such as forks or upgrades to the network, may require new Price Feeds to ensure continuity and data quality. When considering a token migration, fork, network upgrade, or other crypto action, projects should proactively reach out to relevant stakeholders to ensure the asset price is accurately reported throughout the process.
+
+### Market Failures Resulting from Extreme Events
+
+Users are strongly advised to set up monitoring and alerts in the event of unexpected market failures. Black swan events, hacks, coordinated attacks, or extreme market conditions may trigger unanticipated outcomes such as liquidity pools becoming unbalanced, unexpected re-weighting of indices, abnormal behavior by centralized or decentralized exchanges, or the de-pegging of synthetic assets and currencies from their intended exchange rates.
+
+Users should be aware of inherently increased risk during such periods of high volatility and market failure.
+
+### Periods of High Network Congestion
+
+Data Feed performance relies on the chains they are deployed on. Periods of high network congestion might impact the frequency of Chainlink Price Feeds. It is advised that you configure your applications to detect such chain performance issues and to respond appropriately.
+
+### Unknown and Known Users
+
+Routine maintenance is carried out on Chainlink Data Feeds, including decommissioning, on an ad-hoc basis. These maintenance periods might require users to take action in order to maintain business continuity.
+
+Notifications are sent to inform known users regarding such occurrences, and it is strongly encouraged for all users, including those users utilizing data feeds for off-chain purposes, [to provide their contact information](https://chainlinkcommunity.typeform.com/unknownDfUsers?typeform-source=docs.chain.link) before utilizing data feeds. Without providing contact information, users will be unable to receive notifications regarding important price feed updates.
+
+If you are using Price Feeds but have not provided your contact information, you can do so [here](https://chainlinkcommunity.typeform.com/unknownDfUsers?typeform-source=docs.chain.link). Users that fail to provide notification information do so at their own risk.
+
+### Extreme Events Causing Price Deviations in Wrapped or Bridged Assets
+
+Chainlink Price Feeds are designed to provide the market-wide price of various assets, as determined by a volume-weighted average across a wide range of exchanges. On blockchain networks where assets are wrapped and/or bridged from another environment using a cross-chain token bridge, Chainlink Price Feeds on that blockchain will continue to report the market-wide price of the underlying asset as opposed to the price of the wrapped/bridged asset. This methodology reduces risks around market manipulation because wrapped/bridged tokens are often less liquid than the underlying asset.
+
+However, users should be aware that certain extreme events may result in price deviations between the wrapped/bridged asset and its underlying counterpart. For example, the exploitation or hack of a cross-chain token bridge may cause a collapse in demand for a particular wrapped asset. As such, users should construct their applications with safeguards, such as proactively pausing functionality, to mitigate risk during such scenarios.
+
+One mechanism for securing a protocol utilizing wrapped assets is by incorporating [Chainlink Proof of Reserve](https://chain.link/proof-of-reserve). Chainlink Proof of Reserve enables the real-time reserve monitoring of off-chain and cross-chain assets, including those that have been wrapped/bridged. By comparing the wrapped token’s supply against a Chainlink Proof of Reserve feed, protocols can ensure that these assets are properly collateralized at all times.
+
+### Front Running Risk
+
+Front running (when a third party benefits from prior access to information about a transaction) is a known risk inherent to specific blockchain applications. Chainlink Data Feeds are optimized to prioritize high levels of data quality and reliability over latency.
+
+To mitigate the risk associated with front running, users building highly latency-dependent applications should assess whether the configuration of data feeds meets their needed specifications for speed and frequency.
+
+### Fast Gas Reliability
+
+The [Fast Gas Data Feed](https://data.chain.link/ethereum/mainnet/gas/fast-gas-gwei) provides a simple way to determine the price of gas so you can estimate how much gas you need to make a transaction execute quickly. Fast gas prices can be manipulated, so you should design your applications to detect gas price volatility or malicious activity that might affect the costs of your transactions.
+
+:::note[ The best practices above are provided for informational purposes only. You are responsible for reviewing the quality of the data that you integrate into your smart contracts.]
+
+:::
diff --git a/src/pages/ethereum.mdx b/src/pages/ethereum.mdx
new file mode 100644
index 00000000000..2ef98dba89e
--- /dev/null
+++ b/src/pages/ethereum.mdx
@@ -0,0 +1,189 @@
+---
+layout: ../layouts/MainLayout.astro
+section: ethereum
+title: "Chainlink on EVM (Ethereum) Chains"
+---
+
+import button from "@chainlink/design-system/button.module.css"
+import styles from "@features/landing/styles/EthereumLandingPage.module.css"
+
+Chainlink turns your smart contracts into hybrid smart contracts, giving
+them access to real-world data and services while maintaining the security
+and reliability guarantees inherent to blockchain technology.
+
+
+
+
+ Get Data Feeds in your Smart Contracts
+
+ Retrieve the latest prices and data points of assets in your smart
+ contracts.
+
+
+ {"Learn More"}
+
+
+
+
+
+
+
Generate Verifiable Random Numbers (VRF)
+
Use Chainlink VRF to consume randomness in your smart contracts.
+
+ {"Learn More"}
+
+
+
+
+
+
+
+ Call External APIs from Smart Contracts
+
+ Request & Receive data from any API using the Chainlink contract
+ library.
+
+
+ {"Learn More"}
+
+
+
+
+
+
+
+
+
+
+
New to Chainlink and Smart Contracts?
+
Learn the basics in the Getting Started Guide. Build your first smart contract on Ethereum.
+
+ {"Getting Started Guide"}
+
+
+
+
+
+
+
Automate and Maintain with Chainlink Automation
+
+ Chainlink Automation provides smart contract developers, decentralized applications (dApps), and decentralized
+ autonomous organizations (DAOs) with a highly reliable, decentralized, and cost-efficient method of automating
+ smart contract functions and regular contract maintenance.
+
+
+ {"Learn More"}
+
+
+
+
+
+
Explore Additional Resources
+
Find all the right resources to get the most out of Chainlink.
+
+
+
+
Explore Chainlink Developer Tools
+
+
diff --git a/src/pages/feeds/[stub].astro b/src/pages/feeds/[stub].astro
new file mode 100644
index 00000000000..f168d579d98
--- /dev/null
+++ b/src/pages/feeds/[stub].astro
@@ -0,0 +1,9 @@
+---
+export function getStaticPaths() {
+ return [{ params: { stub: "ethereum-addresses" } }, { params: { stub: "rover" } }, { params: { stub: "spot" } }]
+}
+
+const { stub } = Astro.params
+---
+
+Good stub, {stub}!
diff --git a/src/pages/getting-started/advanced-tutorial.md b/src/pages/getting-started/advanced-tutorial.md
new file mode 100644
index 00000000000..301588bc1c7
--- /dev/null
+++ b/src/pages/getting-started/advanced-tutorial.md
@@ -0,0 +1,149 @@
+---
+layout: ../../layouts/MainLayout.astro
+section: gettingStarted
+date: Last Modified
+title: "API Calls: Using Any API"
+permalink: "docs/advanced-tutorial/"
+excerpt: "Calling APIs from Smart Contracts"
+whatsnext:
+ {
+ "Make a GET Request": "/any-api/get-request/introduction/",
+ "Make an Existing Job Request": "/any-api/get-request/examples/existing-job-request/",
+ }
+metadata:
+ image:
+ 0: "/files/04b8e56-cl.png"
+---
+
+:::note[ Requirements]
+
+This guide requires basic knowledge about smart contracts. If you are new to smart contract development, read the [Consuming Data Feeds](/getting-started/consuming-data-feeds/) and [Random Numbers](/getting-started/intermediates-tutorial/) guides before you begin.
+
+:::
+
+
+
+In this guide, you will learn how to request data from a public API in a smart contract. This includes understanding what Tasks and External adapters are and how Oracle Jobs use them. You will also learn how to find the Oracle Jobs and Tasks for your contract and how to request data from an Oracle Job.
+
+## 1. How does the request and receive cycle work for API calls?
+
+The request and receive cycle describes how a smart contract requests data from an oracle and receives the response in a separate transaction. If you need a refresher, check out the [Basic Request Model](/architecture-overview/architecture-request-model/).
+
+For contracts that use [Chainlink VRF](/vrf/v2/introduction/), you request randomness from a VRF oracle and then await the response. The fulfillment function is already given to us from the `VRFConsumerBase` contract, so oracles already know where to send the response to. However, with API calls, the contract itself _defines_ which function it wants to receive the response to.
+
+Before creating any code, you should understand how Oracle jobs can get data on-chain.
+
+## 2. What are jobs?
+
+Chainlink nodes require [**Jobs**](/chainlink-nodes/oracle-jobs/jobs/) to do anything useful. In the case of a Request and Receive job, the [Direct Request](/chainlink-nodes/oracle-jobs/job-types/direct_request) job monitors the blockchain for a request from a smart contract. Once it catches a request, it runs the tasks (both core and external adapters) that the job is configured to run and eventually returns the response to the requesting contract.
+
+## 3. What are Tasks?
+
+Each oracle job has a configured set of tasks it must complete when it is run. These tasks are split into two subcategories:
+
+- [**Tasks**](/chainlink-nodes/oracle-jobs/task-types/tasks/) - These are tasks that come built-in to each node. (examples: http, ethabidecode, etc).
+- [**External Adapters**](/chainlink-nodes/external-adapters/external-adapters/) - These are custom adapters built by node operators and community members, which perform specific tasks like calling a particular endpoint with a specific set of parameters (like authentication secrets that shouldn't be publicly visible).
+
+### Tasks
+
+If a job needs to make a GET request to an API, find a specific unsigned integer field in a JSON response, then submit that back to the requesting contract, it would need a job containing the following Tasks:
+
+- [HTTP](/chainlink-nodes/oracle-jobs/task-types/task_http) calls the API. the `method` must be set to _GET_.
+- [JSON Parse](/chainlink-nodes/oracle-jobs/task-types/task_jsonparse) parses the JSON and extracts a value at a given keypath.
+- [Multiply](/chainlink-nodes/oracle-jobs/task-types/task_multiply) multiplies the input by a multiplier. Used to remove the decimals.
+- [ETH ABI Encode](/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_encode) converts the data to a bytes payload according to ETH ABI encoding.
+- [ETH Tx](/chainlink-nodes/oracle-jobs/task-types/task_eth_tx) submits the transaction to the chain, completing the cycle.
+
+The job specs example can be found [here](/chainlink-nodes/job-specs/direct-request-get-uint256/).
+Let's walk through a real example, where you will retrieve 24 volumes of the [ETH/USD pair](https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD) from the cryptocompare API.
+
+1. [HTTP](/chainlink-nodes/oracle-jobs/task-types/task_http) calls the API and returns the body of an HTTP GET result for [ETH/USD pair](https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD). Example:
+
+
+```json
+{"RAW":
+ {"ETH":
+ {"USD":
+ {
+ ...,
+ "VOLUMEDAYTO":953806939.7194247,
+ "VOLUME24HOUR":703946.0675653099,
+ "VOLUME24HOURTO":1265826345.488568
+ ...,
+ }
+ }
+ }
+}
+```
+
+2. [JSON Parse](/chainlink-nodes/oracle-jobs/task-types/task_jsonparse) walks a specified `path` (`"RAW,ETH,USD,VOLUME24HOUR"`) and returns the value found at that result. Example: `703946.0675653099`
+
+3. [Multiply](/chainlink-nodes/oracle-jobs/task-types/task_multiply) parses the input into a float and multiplies it by the 10^18. Example: `703946067565309900000000`
+
+4. [ETH ABI Encode](/chainlink-nodes/oracle-jobs/task-types/task_eth_abi_encode) formats the input into an integer and then converts it into Solidity's `uint256` format. Example: `0xc618a1e4`
+
+5. [ETH Tx](/chainlink-nodes/oracle-jobs/task-types/task_eth_tx) takes the given input, places it into the data field of the transaction, signs a transaction, and broadcasts it to the network. Example: [transaction result](https://goerli.etherscan.io/tx/0x5f2023b665e0ae336665ded73fafa90ef752ac33487b9240f34b82f93a77c8ca)
+
+**Note: Some tasks accept parameters to be passed to them to inform them how to run.** Example: [JSON Parse](/chainlink-nodes/oracle-jobs/task-types/task_jsonparse) accepts a `path` parameter which informs the task where to find the data in the JSON object.
+
+Let's see what this looks like in a contract:
+
+### Contract Example
+
+::solidity-remix[samples/APIRequests/APIConsumer.sol]
+
+Here is a breakdown of each component of this contract:
+
+1. Constructor: This sets up the contract with the Oracle address, Job ID, and LINK fee that the oracle charges for the job.
+2. `requestVolumeData` functions: This builds and sends a request - which includes the fulfillment functions selector - to the oracle. Notice how it adds the `get`, `path` and `times` parameters. These are read by the Tasks in the job to perform correctly. `get` is used by [HTTP](/chainlink-nodes/oracle-jobs/task-types/task_http), `path` is used by [JSON Parse](/chainlink-nodes/oracle-jobs/task-types/task_jsonparse) and `times` is used by [Multiply](/chainlink-nodes/oracle-jobs/task-types/task_multiply).
+3. `fulfill` function: This is where the result is sent upon the Oracle Job's completion.
+
+**Note:** The calling contract should own enough LINK to pay the fee, which by default is 0.1 LINK. You can use [this tutorial](/resources/fund-your-contract/) to learn how to fund your contract.
+
+This is an example of a basic HTTP GET request. However, it requires defining the API URL directly in the smart contract. This can, in fact, be extracted and configured on the Job level inside the Oracle node. You can follow the _APIConsumer_ tutorial [here](/any-api/get-request/examples/single-word-response/).
+
+### External Adapters
+
+Here are some examples nodes with external adapters:
+
+- [Google Weather Data](https://docs.chain.link/any-api/data-providers/google-weather/)
+- [Associated Press](https://market.link/nodes/The%20Associated%20Press/integrations)
+
+If all the parameters are defined within the Oracle job, the only things a smart contract needs to define to consume are:
+
+- JobId
+- Oracle address
+- LINK fee
+- Fulfillment function
+
+This will make your smart contract much more succinct. The `requestVolumeData` function from the code example [above](#contract-example) would look more like this:
+
+
+```solidity
+function requestVolumeData() public returns (bytes32 requestId) {
+ Chainlink.Request memory req = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
+
+ // Extra parameters don't need to be defined here because they are already defined in the job
+
+ return sendChainlinkRequest(req, fee);
+}
+```
+
+You can follow a full _Existing Job Tutorial_ [here](/any-api/get-request/examples/existing-job-request/).
+More on External Adapters can be found [here](/chainlink-nodes/external-adapters/external-adapters/).
+
+## 4. How can I use an Oracle Data Service?
+
+Chainlink has facilitated the launch of several new oracle data services that allow dApps to access rich data from external data sources. For instance, you can create a smart contract that checks Google's DNS service to determine if a given domain is owned by a given blockchain address using oracle job without having to specify the URL inside the contract.
+Join the [operator-requests discord channel](https://discord.gg/eGcxsdZzKR) to directly communicate with community node operators.
+A full example on Kovan testnet can be found [here](/any-api/data-providers/dns-ownership/).
+
+## 5. Further Reading
+
+To learn more about connecting smart contracts to external APIs, read our blog posts:
+
+- [Connect a Smart Contract to the Twitter API](https://blog.chain.link/connect-smart-contract-to-twitter-api/)
+- [Connect a Tesla Vehicle API to a Smart Contract](https://blog.chain.link/create-tesla-smart-contract-rental/)
+- [OAuth and API Authentication in Smart Contracts](https://blog.chain.link/oauth-and-api-authentication-in-smart-contracts-2/)
+
+To explore more applications of external API requests, check out our [other tutorials](/getting-started/other-tutorials/#api-requests).
diff --git a/docs/getting-started/conceptual-overview.md b/src/pages/getting-started/conceptual-overview.md
similarity index 72%
rename from docs/getting-started/conceptual-overview.md
rename to src/pages/getting-started/conceptual-overview.md
index 4ebbe414acc..c4a96d0c850 100644
--- a/docs/getting-started/conceptual-overview.md
+++ b/src/pages/getting-started/conceptual-overview.md
@@ -1,11 +1,15 @@
---
-layout: nodes.liquid
+layout: ../../layouts/MainLayout.astro
section: gettingStarted
date: Last Modified
title: "Chainlink Overview"
permalink: "docs/conceptual-overview/"
excerpt: "Smart Contracts and Chainlink"
-whatsnext: {"Deploy Your First Smart Contract":"/docs/deploy-your-first-contract/", "Consuming Data Feeds":"/docs/consuming-data-feeds/"}
+whatsnext:
+ {
+ "Deploy Your First Smart Contract": "/getting-started/deploy-your-first-contract/",
+ "Consuming Data Feeds": "/getting-started/consuming-data-feeds/",
+ }
metadata:
title: "Conceptual Overview"
description: "Learn the basic concepts about what smart contracts are and, how to write them, and how Chainlink oracles work with smart contracts."
@@ -15,44 +19,32 @@ metadata:
Welcome to the Smart Contract Getting Started guide. This overview explains the basic concepts of smart contract development and oracle networks.
-**Skip ahead**
+**Skip ahead:**
To get your hands on the code right away, you can skip this overview:
-- [Deploy Your First Smart Contract](/docs/deploy-your-first-contract/): If you are new to smart contracts, deploy your first smart contract in an interactive web development environment.
-- [Learn how to use Data Feeds](/docs/consuming-data-feeds/): If you are already familiar with smart contracts and want to learn how to create *hybrid* smart contracts, use Chainlink Data Feeds to get asset price data on-chain.
-
- https://www.youtube.com/watch?v=rFXSEEQG9YE
-
+- [Deploy Your First Smart Contract](/getting-started/deploy-your-first-contract/): If you are new to smart contracts, deploy your first smart contract in an interactive web development environment.
+- [Learn how to use Data Feeds](/getting-started/consuming-data-feeds/): If you are already familiar with smart contracts and want to learn how to create _hybrid_ smart contracts, use Chainlink Data Feeds to get asset price data on-chain.
-**Topics**
-
-+ [What is a smart contract? What is a hybrid smart contract?](#what-is-a-smart-contract-what-is-a-hybrid-smart-contract)
-+ [What language is a smart contract written in?](#what-language-is-a-smart-contract-written-in)
-+ [What does a smart contract look like?](#what-does-a-smart-contract-look-like)
-+ [What does "deploying" mean?](#what-does-deploying-mean)
-+ [What is a LINK token?](#what-is-a-link-token)
-+ [What are oracles? Why are they important?](#what-are-oracles)
-+ [How do smart contracts use oracles?](#how-do-smart-contracts-use-oracles)
-+ [What is Remix?](#what-is-remix)
-+ [What is Metamask?](#what-is-metamask)
+
## What is a smart contract? What is a hybrid smart contract?
-When deployed to a blockchain, a *smart contract* is a set of instructions that can be executed without intervention from third parties. The smart contract code defines how it responds to input, just like the code of any other computer program.
+When deployed to a blockchain, a _smart contract_ is a set of instructions that can be executed without intervention from third parties. The smart contract code defines how it responds to input, just like the code of any other computer program.
A valuable feature of smart contracts is that they can store and manage on-chain assets (like [ETH or ERC20 tokens](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/)), just like you can with an Ethereum wallet. Because they have an on-chain address like a wallet, they can do everything any other address can. This enables you to program automated actions when receiving and transferring assets.
-Smart contracts can connect to real-world market prices of assets to produce powerful applications. Securely connecting smart contracts with off-chain data and services is what makes them *hybrid* smart contracts. This is done using oracles.
+Smart contracts can connect to real-world market prices of assets to produce powerful applications. Securely connecting smart contracts with off-chain data and services is what makes them _hybrid_ smart contracts. This is done using oracles.
## What language is a smart contract written in?
The most popular language for writing smart contracts on Ethereum and EVM Chains is [Solidity](https://docs.soliditylang.org/en/v0.8.7/). It was created by the Ethereum Foundation specifically for smart contract development and is constantly being updated. Other languages exist for writing smart contracts on Ethereum and EVM Chains, but Solidity is the language used for Chainlink smart contracts.
-If you've ever written Javascript, Java, or other object-oriented scripting languages, Solidity should be easy to understand. Similar to object-oriented languages, Solidity is considered to be a *contract*-oriented language.
+If you've ever written Javascript, Java, or other object-oriented scripting languages, Solidity should be easy to understand. Similar to object-oriented languages, Solidity is considered to be a _contract_-oriented language.
Some networks are not EVM-compatible and use languages other than Solidity for smart contracts:
- [Solana](/solana/)
+
- [Writing Solana contracts in Rust](https://docs.solana.com/developing/on-chain-programs/developing-rust)
- [Writing Solana contracts in C](https://docs.solana.com/developing/on-chain-programs/developing-c)
@@ -60,14 +52,7 @@ Some networks are not EVM-compatible and use languages other than Solidity for s
The structure of a smart contract is similar to that of a class in Javascript, with a few differences. For example, the following `HelloWorld` contract is a simple smart contract that stores a single variable and includes a function to update the value of that variable.
-```solidity
-{% include 'samples/Tutorials/HelloWorld.sol' %}
-```
-
-
+::solidity-remix[samples/Tutorials/HelloWorld.sol]
### Solidity versions
@@ -75,15 +60,18 @@ The first thing that every Solidity file must have is the Solidity version defin
You can see the latest versions of the Solidity compiler [here](https://github.com/ethereum/solc-bin/blob/gh-pages/bin/list.txt/?target=_blank). You might also notice smart contracts that are compatible with a range of versions.
+
```solidity
pragma solidity >=0.7.0 <0.9.0;
```
+
This means that the code is written for Solidity version 0.7.0, or a newer version of the language up to, but not including version 0.9.0. The `pragma` selects the compiler, which defines how the code is treated.
### Naming a Contract
The `contract` keyword defines the name of the contract, which in this example is `HelloWorld`. This is similar to declaring a `class` in Javascript. The implementation of `HelloWorld` is inside this definition and denoted with curly braces.
+
```solidity
contract HelloWorld {
@@ -94,8 +82,9 @@ contract HelloWorld {
Like Javascript, contracts can have state variables and local variables. **State variables** are variables with values that are permanently stored in contract storage. The values of **local variables**, however, are present only until the function is executing. There are also different types of variables you can use within Solidity, such as `string`, `uint256`, etc. Check out the [Solidity documentation](https://docs.soliditylang.org/en/v0.8.7/) to learn more about the different kinds of variables and types.
-*Visibility modifiers* are used to define the level of access to these variables. Here are some examples of state variables with different visibility modifiers:
+_Visibility modifiers_ are used to define the level of access to these variables. Here are some examples of state variables with different visibility modifiers:
+
```solidity
string public message;
uint256 internal internalVar;
@@ -110,6 +99,7 @@ Another familiar concept to programmers is the **constructor**. When you deploy
In `HelloWorld`, the constructor takes in a `string` as a parameter and sets the `message` state variable to that string.
+
```solidity
constructor(string memory initialMessage) {
message = initialMessage;
@@ -120,6 +110,7 @@ constructor(string memory initialMessage) {
**Functions** can access and modify the state of the contract or call other functions on external contracts. `HelloWorld` has a function named `updateMessage`, which updates the current message stored in the state.
+
```solidity
constructor(string memory initialMessage) {
message = initialMessage;
@@ -130,25 +121,19 @@ function updateMessage(string memory newMessage) public {
}
```
-Functions use visibility modifiers to define the access level. Learn more about functions visibility [here](https://docs.soliditylang.org/en/latest/contracts.html#function-visibility).
+Functions use visibility modifiers to define the access level. Learn more about functions visibility [here](https://docs.soliditylang.org/en/latest/contracts.html#function-visibility).
### Interfaces
An **interface** is another concept that is familiar to programmers of other languages. Interfaces define functions without their implementation, which leaves inheriting contracts to define the actual implementation themselves. This makes it easier to know what functions to call in a contract. Here's an example of an interface:
-```solidity
-{% include 'samples/Tutorials/Test.sol' %}
-```
-
+::solidity-remix[samples/Tutorials/Test.sol]
For this example, `override` is necessary in the `Test` contract function because it overrides the base function contained in the `numberComparison` interface. The contract uses `pure` instead of `view` because the `isSameNum` function in the `Test` contract does not return a storage variable.
## What does "deploying" mean?
-**Deploying** a smart contract is the process of pushing the code to the blockchain, at which point it resides with an on-chain address. Once it's deployed, the code cannot be changed and is said to be *immutable*.
+**Deploying** a smart contract is the process of pushing the code to the blockchain, at which point it resides with an on-chain address. Once it's deployed, the code cannot be changed and is said to be _immutable_.
As long as the address is known, its functions can be called through an interface, on [Etherscan](https://etherscan.io/), or through a library like [web3js](https://web3js.readthedocs.io/), [web3py](https://web3py.readthedocs.io/), [ethers](https://docs.ethers.io), and more. Contracts can also be written to interact with other contracts on the blockchain.
@@ -166,31 +151,29 @@ Oracles play a critical role in facilitating the full potential of smart contrac
## How do smart contracts use oracles?
-Oracles are most popularly used with [*Data Feeds*](/docs/data-feeds/). DeFi platforms like [AAVE](https://aave.com/) and [Synthetix](https://www.synthetix.io/) use Chainlink data feed oracles to obtain accurate real-time asset prices in their smart contracts.
+Oracles are most popularly used with [_Data Feeds_](/data-feeds/). DeFi platforms like [AAVE](https://aave.com/) and [Synthetix](https://www.synthetix.io/) use Chainlink data feed oracles to obtain accurate real-time asset prices in their smart contracts.
-Chainlink data feeds are sources of data [aggregated from many independent Chainlink node operators](../architecture-decentralized-model/). Each data feed has an on-chain address and functions that enable contracts to read from that address. For example, the [ETH / USD feed](https://data.chain.link/eth-usd/).
+Chainlink data feeds are sources of data [aggregated from many independent Chainlink node operators](/architecture-overview/architecture-decentralized-model/). Each data feed has an on-chain address and functions that enable contracts to read from that address. For example, the [ETH / USD feed](https://data.chain.link/eth-usd/).

Smart contracts also use oracles to get other capabilities on-chain:
-- [Generate Verifiable Random Numbers (VRF)](/docs/vrf/v2/introduction/): Use Chainlink VRF to consume randomness in your smart contracts.
-- [Call External APIs (Any API)](/docs/any-api/introduction/): Request & Receive data from any API using the Chainlink contract library.
-- [Automate Smart Contract Functions (Automation)](/docs/chainlink-automation/introduction/): Automating smart contract functions and regular contract maintenance.
+- [Generate Verifiable Random Numbers (VRF)](/vrf/v2/introduction/): Use Chainlink VRF to consume randomness in your smart contracts.
+- [Call External APIs (Any API)](/any-api/introduction/): Request & Receive data from any API using the Chainlink contract library.
+- [Automate Smart Contract Functions (Automation)](/chainlink-automation/introduction/): Automating smart contract functions and regular contract maintenance.
## What is Remix?
-
- https://www.youtube.com/watch?v=JWJWT9cwFbo
-
+
[Remix](https://remix.ethereum.org/) is a web IDE (integrated development environment) for creating, running, and debugging smart contracts in the browser. It is developed and maintained by the Ethereum foundation. Remix allows Solidity developers to write smart contracts without a development machine since everything required is included in the web interface. It allows for a simplified method of interacting with deployed contracts, without the need for a command line interface. Remix also has support for samples. This means that Remix can load code from Github.
To learn how to use Remix, see the [Deploying Your First Smart Contract
-](/docs/deploy-your-first-contract/) guide.
+](/getting-started/deploy-your-first-contract/) guide.
## What is Metamask?
diff --git a/docs/getting-started/consuming-data-feeds.md b/src/pages/getting-started/consuming-data-feeds.md
similarity index 64%
rename from docs/getting-started/consuming-data-feeds.md
rename to src/pages/getting-started/consuming-data-feeds.md
index c6e2fee9faa..b6076173560 100644
--- a/docs/getting-started/consuming-data-feeds.md
+++ b/src/pages/getting-started/consuming-data-feeds.md
@@ -1,11 +1,16 @@
---
-layout: nodes.liquid
+layout: ../../layouts/MainLayout.astro
section: gettingStarted
date: Last Modified
title: "Consuming Data Feeds"
permalink: "docs/consuming-data-feeds/"
excerpt: "Smart Contracts and Chainlink"
-whatsnext: {"Random Numbers: Using Chainlink VRF":"/docs/intermediates-tutorial/", "Connect contracts to Any API":"/docs/advanced-tutorial/", "Chainlink Automation":"/docs/chainlink-automation/introduction/"}
+whatsnext:
+ {
+ "Random Numbers: Using Chainlink VRF": "/getting-started/intermediates-tutorial/",
+ "Connect contracts to Any API": "/getting-started/advanced-tutorial",
+ Chainlink Automation":"/chainlink-automation/introduction/,
+ }
metadata:
title: "Consuming Data Feeds"
description: "Learn how to consume Chainlink Data Feeds in your smart contracts."
@@ -13,72 +18,66 @@ metadata:
0: "/files/1a63254-link.png"
---
-> 📘 New to smart contracts?
->
-> This tutorial assumes that you know how to create and deploy basic smart contracts. If you are new to smart contract development, learn how to [Deploy Your First Smart Contract](/docs/deploy-your-first-contract/) before you start this guide.
+:::note[ New to smart contracts?]
-## Overview
+This tutorial assumes that you know how to create and deploy basic smart contracts. If you are new to smart contract development, learn how to [Deploy Your First Smart Contract](/getting-started/deploy-your-first-contract/) before you start this guide.
-When you connect a smart contract to real-world services or off-chain data, you create a *hybrid smart contract*. For example, you can use Chainlink Data Feeds to connect your smart contracts to asset pricing data like the [ETH / USD feed](https://data.chain.link/eth-usd). These data feeds use the data aggregated from many independent Chainlink node operators. Each price feed has an on-chain address and functions that enable contracts to read pricing data from that address.
+:::
-This guide shows you how to write, deploy, and run a smart contract that consumes data from a price data feed.
-
-**Topics**
+When you connect a smart contract to real-world services or off-chain data, you create a _hybrid smart contract_. For example, you can use Chainlink Data Feeds to connect your smart contracts to asset pricing data like the [ETH / USD feed](https://data.chain.link/eth-usd). These data feeds use the data aggregated from many independent Chainlink node operators. Each price feed has an on-chain address and functions that enable contracts to read pricing data from that address.
-+ [Overview](#overview)
-+ [Examine the sample contract](#examine-the-sample-contract)
-+ [Compile, deploy, and run the contract](#compile-deploy-and-run-the-contract)
+This guide shows you how to write, deploy, and run a smart contract that consumes data from a price data feed.
## Examine the sample contract
The following code describes a contract that obtains the latest ETH / USD price using the Goerli testnet.
-```solidity
-{% include 'samples/PriceFeeds/PriceConsumerV3.sol' %}
-```
+::solidity-remix[samples/PriceFeeds/PriceConsumerV3.sol]
The contract has the following components:
-+ The `import` line imports an interface named `AggregatorV3Interface`. Interfaces define functions without their implementation, which leaves inheriting contracts to define the actual implementation themselves. In this case, `AggregatorV3Interface` defines that all v3 Aggregators have the function `latestRoundData`. You can [see the complete code](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol) for the `AggregatorV3Interface` on GitHub.
+- The `import` line imports an interface named `AggregatorV3Interface`. Interfaces define functions without their implementation, which leaves inheriting contracts to define the actual implementation themselves. In this case, `AggregatorV3Interface` defines that all v3 Aggregators have the function `latestRoundData`. You can [see the complete code](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol) for the `AggregatorV3Interface` on GitHub.
-+ The `constructor() {}` initializes an interface object named `priceFeed` that uses `AggregatorV3Interface` and connects specifically to a proxy aggregator contract that is already deployed at `0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e`. The interface allows your contract to run functions on that deployed aggregator contract.
+- The `constructor() {}` initializes an interface object named `priceFeed` that uses `AggregatorV3Interface` and connects specifically to a proxy aggregator contract that is already deployed at `0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e`. The interface allows your contract to run functions on that deployed aggregator contract.
-+ The `getLatestPrice()` function calls your `priceFeed` object and runs the `latestRoundData()` function. When you deploy the contract, it initializes the `priceFeed` object to point to the aggregator at `0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e`, which is the proxy address for the Goerli ETH / USD data feed. Your contract connects to that address and executes the function. The aggregator connects with several oracle nodes and aggregates the pricing data from those nodes. The response from the aggregator includes several variables, but `getLatestPrice()` returns only the `price` variable.
+- The `getLatestPrice()` function calls your `priceFeed` object and runs the `latestRoundData()` function. When you deploy the contract, it initializes the `priceFeed` object to point to the aggregator at `0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e`, which is the proxy address for the Goerli ETH / USD data feed. Your contract connects to that address and executes the function. The aggregator connects with several oracle nodes and aggregates the pricing data from those nodes. The response from the aggregator includes several variables, but `getLatestPrice()` returns only the `price` variable.
## Compile, deploy, and run the contract
-> 🚧 If you have not already configured your MetaMask wallet and funded it with testnet ETH, follow the instructions in the Deploy Your First Smart Contract to set that up. You can get testnet ETH at one of the available [Goerli faucets](/docs/link-token-contracts/#goerli-testnet).
+:::caution[ If you have not already configured your MetaMask wallet and funded it with testnet ETH, follow the instructions in the Deploy Your First Smart Contract to set that up. You can get testnet ETH at one of the available [Goerli faucets](/resources/link-token-contracts/#goerli-testnet).]
+
+:::
Deploy the `PriceConsumerV3` smart contract on the Goerli testnet.
1. [Open the example contract](https://remix.ethereum.org/#url=https://docs.chain.link/samples/PriceFeeds/PriceConsumerV3.sol) in Remix. Remix opens and shows the contents of the smart contract.
-
+
1. Because the code is already written, you can start the compile step. On the left side of Remix, click the **Solidity Compiler** tab to view the compiler settings.
- 
+ 
1. Use the default compiler settings. Click the **Compile PriceConsumerV3.sol** button to compile the contract. Remix automatically detects the correct compiler version depending on the `pragma` that you specify in the contract. You can ignore warnings about unused local variables in this example.
- 
+ 
1. On the **Deploy** tab, select the **Injected Provider** environment. This contract specifically requires Web3 because it connects with another contract on the blockchain. Running in a JavaScript VM will not work.
- 
+ 
1. Because the example contract has several imports, Remix might select another contract to deploy by default. In the **Contract** section, select the `PriceConsumerV3` contract to make sure that Remix deploys the correct contract.
- 
+ 
1. Click **Deploy** to deploy the contract to the Goerli testnet. MetaMask opens and asks you to confirm payment for deploying the contract. Make sure MetaMask is set to the Goerli network before you accept the transaction. Because these transactions are on the blockchain, they are not reversible.
- 
+ 
1. In the MetaMask prompt, click **Confirm** to approve the transaction and spend your testnet ETH required to deploy the contract.
- 
+ 
1. After a few seconds, the transaction completes and your contract appears under the **Deployed Contracts** list in Remix. Click the contract dropdown to view its variables and functions.
- 
+ 
1. Click **getLatestPrice** to show the latest price from the aggregator contract. The latest price appears just below the button. The returned price is an integer, so it is missing its decimal point.
- 
+ 
-You can run your own oracle networks that provide data to smart contracts similar to the `AggregatorV3Interface`, but first, you should learn how to configure your contracts to pay oracles using LINK tokens. Follow the [Generate Random Numbers](../intermediates-tutorial/) to learn how.
+You can run your own oracle networks that provide data to smart contracts similar to the `AggregatorV3Interface`, but first, you should learn how to configure your contracts to pay oracles using LINK tokens. Follow the [Generate Random Numbers](/getting-started/intermediates-tutorial/) to learn how.
diff --git a/docs/getting-started/deploy-your-first-contract.md b/src/pages/getting-started/deploy-your-first-contract.md
similarity index 69%
rename from docs/getting-started/deploy-your-first-contract.md
rename to src/pages/getting-started/deploy-your-first-contract.md
index 27f8d02caf0..4bc7629805d 100644
--- a/docs/getting-started/deploy-your-first-contract.md
+++ b/src/pages/getting-started/deploy-your-first-contract.md
@@ -1,10 +1,10 @@
---
-layout: nodes.liquid
+layout: ../../layouts/MainLayout.astro
section: gettingStarted
date: Last Modified
title: "Deploy Your First Smart Contract"
permalink: "docs/deploy-your-first-contract/"
-whatsnext: {"Consuming Data Feeds":"/docs/consuming-data-feeds/"}
+whatsnext: { "Consuming Data Feeds": "/getting-started/consuming-data-feeds/" }
metadata:
title: "Deploy Your First Smart Contract"
description: "Deploy and run your first smart contract in an interactive web development environment."
@@ -14,17 +14,11 @@ metadata:
You can write your first smart contract and run it in your browser without any knowledge about Ethereum or blockchains. This guide shows you how easy it is to develop smart contracts using the [Solidity language](https://soliditylang.org/), a [MetaMask wallet](https://metamask.io) and the [Remix Development Environment](https://remix.ethereum.org/). You can use all of these tools in your browser for free with no signup required.
-> 📘 Already know Solidity and have MetaMask configured?
->
-> If you are already familiar with how to deploy Smart Contracts and use MetaMask, you can skip to the [Consuming Data Feeds](/docs/consuming-data-feeds/) guide to learn how to connect your smart contracts to Chainlink data feeds.
+:::note[ Already know Solidity and have MetaMask configured?]
-**Topics**
-+ [Overview](#overview)
-+ [Install and fund MetaMask](#install-and-fund-your-metamask-wallet)
-+ [Write, compile, and deploy your first smart contract](#write-compile-and-deploy-your-first-smart-contract)
-+ [Run functions in your contract](#run-functions-in-your-contract)
+If you are already familiar with how to deploy Smart Contracts and use MetaMask, you can skip to the [Consuming Data Feeds](/getting-started/consuming-data-feeds/) guide to learn how to connect your smart contracts to Chainlink data feeds.
-## Overview
+:::
In general, you create and deploy your smart contracts operate using the following process:
@@ -45,14 +39,14 @@ Deploying smart contracts on-chain requires a wallet and ETH. The ETH pays for t
1. [Install and configure the MetaMask extension](https://metamask.io/download) in your browser.
1. After you install the extension, open your browser extension list and click MetaMask to open MetaMask.
- 
+ 
1. Follow the instructions in MetaMask to create a new MetaMask wallet. The new wallet includes a 12-word mnemonic phrase. This phrase is the key to your wallet. Copy that phrase down in a very secure location that only you can access. You can use this phrase to retrieve your wallet later or add it to another browser.
1. Set MetaMask to use the Goerli test network.
- 
+ 
-1. Select one of the available [Goerli faucets](/docs/link-token-contracts/#goerli-testnet) and follow the steps to send testnet ETH to your MetaMask wallet address. You can copy your wallet address by clicking your account name in MetaMask. After the faucet completes the transaction, you should have testnet ETH in your MetaMask wallet on the Goerli testnet.
+1. Select one of the available [Goerli faucets](/resources/link-token-contracts/#goerli-testnet) and follow the steps to send testnet ETH to your MetaMask wallet address. You can copy your wallet address by clicking your account name in MetaMask. After the faucet completes the transaction, you should have testnet ETH in your MetaMask wallet on the Goerli testnet.
Now that you configured your wallet and funded it with testnet ETH, you can write, compile, and deploy your contract.
@@ -60,42 +54,40 @@ Now that you configured your wallet and funded it with testnet ETH, you can writ
Your first contract is a simple `HelloWorld.sol` example. This example shows you how to set and retrieve variables in a smart contract on-chain.
-```solidity
-{% include 'samples/Tutorials/HelloWorld.sol' %}
-```
+::solidity-remix[samples/Tutorials/HelloWorld.sol]
1. [Open the example contract](https://remix.ethereum.org/#url=https://docs.chain.link/samples/Tutorials/HelloWorld.sol) in the Remix IDE. Remix opens and shows the contents of the smart contract. You can modify the code in this editor when you write your own contract.
-
+
1. Because the code is already written, you can start the compile step. On the left side of Remix, click the **Solidity Compiler** tab to view the compiler settings.
- 
+ 
1. For this contract, use the default compiler settings. Click the **Compile HelloWorld.sol** button to compile the contract. This converts the contract from Solidity into bytecode that the [Ethereum Virtual Machine](https://ethereum.org/en/developers/docs/evm/) can understand. Remix automatically detects the correct compiler version depending on the `pragma` that you specify in the contract.
- 
+ 
1. After Remix compiles the contract, deploy it. On the left side of Remix, click the **Deploy and Run** tab to view the deployment settings.
- 
+ 
1. In the deployment settings, select the **Injected Provider** environment. This tells Remix that you want to deploy your contract to the blockchain that you configured in MetaMask. You could optionally use one of the Javascript VM options, but they run in a virtual environment with no connection to an actual blockchain or Chainlink oracles.
- 
+ 
1. Next to the **Deploy** button, enter a message that you want to send with the smart contract when you deploy it. This contract has a constructor that sets an initial message when you deploy the contract.
- 
+ 
1. Click the **Deploy** button to deploy the contract and its initial message to the blockchain network. MetaMask opens and asks you to confirm payment to deploy the contract. Make sure MetaMask is set to the Goerli network before you accept the transaction. Because these transactions are on the blockchain, they are not reversible.
1. In the MetaMask prompt, click **Confirm** to approve the transaction and spend your testnet ETH required to deploy the contract.
- 
+ 
1. After a few seconds, the transaction completes and your contract appears under the **Deployed Contracts** list in Remix. Click the contract dropdown to view its variables and functions.
- 
+ 
1. Click the `message` variable. Remix retrieves and prints the initial message that you set.
- 
+ 
The contract has an address just like your wallet address. If you save this address, you can return to your deployed contract at any time to retrieve variables or execute functions. To see details about your deployed contract, copy the contract address from the list in Remix and search for it in the [Etherscan Goerli Testnet Explorer](https://goerli.etherscan.io/).
@@ -104,16 +96,16 @@ The contract has an address just like your wallet address. If you save this addr
Because you deployed the contract to an actual blockchain, several nodes on the test network confirmed your payment for the smart contract. The contract, its variables, and its functions remain in the blockchain permanently. To change the `message` variable that is stored with your contract, run the `updateMessage` function.
1. In your deployed contract, enter a new message next to the `updateMessage` function.
- 
+ 
1. Click the `updateMessage` button to set the new message in the contract data. MetaMask opens and asks you to confirm payment to update the state of your contract.
1. In the new MetaMask prompt, click **Confirm** to approve the transaction.
- 
+ 
1. Click the `message` variable again to see the updated value. It might take a few seconds before the transaction updates the variable.
- 
+ 
Now you know how to deploy example contracts to a test network and run the functions in those contracts. You can write your own contracts and test them using this same process.
-Next, read the [Consuming Data Feeds](/docs/consuming-data-feeds/) guide to learn how to connect your smart contracts to Chainlink Data Feeds and retrieve on-chain data that your smart contracts can act on.
+Next, read the [Consuming Data Feeds](/getting-started/consuming-data-feeds/) guide to learn how to connect your smart contracts to Chainlink Data Feeds and retrieve on-chain data that your smart contracts can act on.
diff --git a/docs/getting-started/intermediates-tutorial.md b/src/pages/getting-started/intermediates-tutorial.md
similarity index 59%
rename from docs/getting-started/intermediates-tutorial.md
rename to src/pages/getting-started/intermediates-tutorial.md
index de91d170b28..991e17f3101 100644
--- a/docs/getting-started/intermediates-tutorial.md
+++ b/src/pages/getting-started/intermediates-tutorial.md
@@ -1,69 +1,55 @@
---
-layout: nodes.liquid
+layout: ../../layouts/MainLayout.astro
section: gettingStarted
date: Last Modified
-title: 'Random Numbers: Using Chainlink VRF'
-permalink: 'docs/intermediates-tutorial/'
-excerpt: 'Using Chainlink VRF'
+title: "Random Numbers: Using Chainlink VRF"
+permalink: "docs/intermediates-tutorial/"
+excerpt: "Using Chainlink VRF"
whatsnext:
{
- 'Get a Random Number': '/docs/vrf/v2/subscription/examples/get-a-random-number/',
- 'Programmatic Subscription': '/docs/vrf/v2/subscription/examples/programmatic-subscription/',
- 'Security Considerations': '/docs/vrf/v2/security/',
- 'Best Practices': '/docs/vrf/v2/best-practices/',
- 'Supported Networks': '/docs/vrf/v2/subscription/supported-networks/',
+ "Get a Random Number": "/vrf/v2/subscription/examples/get-a-random-number/",
+ "Programmatic Subscription": "/vrf/v2/subscription/examples/programmatic-subscription/",
+ "Security Considerations": "/vrf/v2/security/",
+ "Best Practices": "/vrf/v2/best-practices/",
+ "Supported Networks": "/vrf/v2/subscription/supported-networks/",
}
metadata:
- title: 'Random Numbers: Using Chainlink VRF'
- description: 'Learn how to use randomness in your smart contracts using Chainlink VRF.'
+ title: "Random Numbers: Using Chainlink VRF"
+ description: "Learn how to use randomness in your smart contracts using Chainlink VRF."
image:
- 0: '/files/2a242f1-link.png'
+ 0: "/files/2a242f1-link.png"
---
-> 📘 Requirements
->
-> This guide assumes that you have basic knowledge about writing and deploying smart contracts. If you are new to smart contract development, read the [Consuming Data Feeds](/docs/consuming-data-feeds/) guide before you begin.
+:::note[ Requirements]
-
- https://www.youtube.com/watch?v=rdJ5d8j1RCg&ab
-
+This guide assumes that you have basic knowledge about writing and deploying smart contracts. If you are new to smart contract development, read the [Consuming Data Feeds](/getting-started/consuming-data-feeds/) guide before you begin.
-VRF v2 - Developer Walkthrough
-
-## Overview
+:::
-In this guide, you will learn about generating randomness on blockchains. This includes learning how to implement a Request and Receive cycle with Chainlink oracles and how to consume random numbers with Chainlink VRF in smart contracts.
+
-**Topics**
+VRF v2 - Developer Walkthrough
-- [Overview](#overview)
-- [1. How is randomness generated on blockchains? What is Chainlink VRF?](#1-how-is-randomness-generated-on-blockchains-what-is-chainlink-vrf)
-- [2. What is the Request and Receive cycle?](#2-what-is-the-request-and-receive-cycle)
-- [3. What is the payment process for generating a random number?](#3-what-is-the-payment-process-for-generating-a-random-number)
-- [4. How can I use Chainlink VRF?](#4-how-can-i-use-chainlink-vrf)
-- [5. How do I deploy to testnet?](#5-how-do-i-deploy-to-testnet)
-- [6. How do I add my contract to my subscription account ?](#6-how-do-i-add-my-contract-to-my-subscription-account)
-- [7. How do I test `rollDice`?](#7-how-do-i-test-rolldice)
-- [8. Further Reading](#8-further-reading)
+In this guide, you will learn about generating randomness on blockchains. This includes learning how to implement a Request and Receive cycle with Chainlink oracles and how to consume random numbers with Chainlink VRF in smart contracts.
-## 1. How is randomness generated on blockchains? What is Chainlink VRF?
+## How is randomness generated on blockchains? What is Chainlink VRF?
-Randomness is very difficult to generate on blockchains. This is because every node on the blockchain must come to the same conclusion and form a consensus. Even though random numbers are versatile and useful in a variety of blockchain applications, they cannot be generated natively in smart contracts. The solution to this issue is [**Chainlink VRF**](/docs/vrf/v2/introduction/), also known as Chainlink Verifiable Random Function.
+Randomness is very difficult to generate on blockchains. This is because every node on the blockchain must come to the same conclusion and form a consensus. Even though random numbers are versatile and useful in a variety of blockchain applications, they cannot be generated natively in smart contracts. The solution to this issue is [**Chainlink VRF**](/vrf/v2/introduction/), also known as Chainlink Verifiable Random Function.
-## 2. What is the Request and Receive cycle?
+## What is the Request and Receive cycle?
-The [previous guide](/docs/consuming-data-feeds/) explained how to consume Chainlink Data Feeds, which consist of reference data posted on-chain by oracles. This data is stored in a contract and can be referenced by consumers until the oracle updates the data again.
+The [previous guide](/getting-started/consuming-data-feeds/) explained how to consume Chainlink Data Feeds, which consist of reference data posted on-chain by oracles. This data is stored in a contract and can be referenced by consumers until the oracle updates the data again.
-Randomness, on the other hand, cannot be reference data. If the result of randomness is stored on-chain, any actor could retrieve the value and predict the outcome. Instead, randomness must be requested from an oracle, which generates a number and a cryptographic proof. Then, the oracle returns that result to the contract that requested it. This sequence is known as the **[Request and Receive cycle](../architecture-request-model/)**.
+Randomness, on the other hand, cannot be reference data. If the result of randomness is stored on-chain, any actor could retrieve the value and predict the outcome. Instead, randomness must be requested from an oracle, which generates a number and a cryptographic proof. Then, the oracle returns that result to the contract that requested it. This sequence is known as the **[Request and Receive cycle](/architecture-overview/architecture-request-model/)**.
-## 3. What is the payment process for generating a random number?
+## What is the payment process for generating a random number?
VRF requests receive funding from subscription accounts. The [Subscription Manager](https://vrf.chain.link) lets you create an account and pre-pay for VRF requests, so that funding of all your application requests are managed in a single location.
-To learn more about VRF request funding, see [Subscriptions](/docs/vrf/v2/subscription/#subscriptions).
+To learn more about VRF requests funding, see [Subscriptions limits](/vrf/v2/subscription#subscription-limits).
-## 4. How can I use Chainlink VRF?
+## How can I use Chainlink VRF?
-To see a basic implementation of Chainlink VRF, see [Get a Random Number](/docs/vrf/v2/subscription/examples/get-a-random-number/). In this section, you will create an application that uses Chainlink VRF to generate randomness. The contract used in this application will have a [_Game of Thrones_](https://en.wikipedia.org/wiki/Game_of_Thrones) theme.
+To see a basic implementation of Chainlink VRF, see [Get a Random Number](/vrf/v2/subscription/examples/get-a-random-number/). In this section, you will create an application that uses Chainlink VRF to generate randomness. The contract used in this application will have a [_Game of Thrones_](https://en.wikipedia.org/wiki/Game_of_Thrones) theme.
The contract will request randomness from Chainlink VRF. The result of the randomness will transform into a number between 1 and 20, mimicking the rolling of a 20 sided die. Each number represents a _Game of Thrones_ house. If the dice land on the value 1, the user is assigned house Targaryan, 2 for Lannister, and so on. A full list of houses can be found [here](https://gameofthrones.fandom.com/wiki/Great_House).
@@ -80,7 +66,7 @@ The contract will have the following functions:
### Create and fund a subscription
Chainlink VRF requests receive funding from subscription accounts. The [Subscription Manager](https://vrf.chain.link) lets you create an account and pre-pay your use of Chainlink VRF requests.
-For this example, create a new subscription on the Goerli testnet as explained [here](/docs/vrf/v2/subscription/examples/get-a-random-number/#create-and-fund-a-subscription).
+For this example, create a new subscription on the Goerli testnet as explained [here](/vrf/v2/subscription/examples/get-a-random-number/#create-and-fund-a-subscription).
### Importing `VRFConsumerBaseV2` and `VRFCoordinatorV2Interface`
@@ -89,21 +75,24 @@ Chainlink maintains a [library of contracts](https://github.com/smartcontractkit
- [`VRFConsumerBaseV2`](https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/VRFConsumerBaseV2.sol) that must be imported and extended from the contract that you create.
- [`VRFCoordinatorV2Interface`](https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol) that must be imported to communicate with the VRF coordinator.
+
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
-import '@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol';
-import '@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol';
+import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
+import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
-contract VRFD20 is VRFConsumerBaseV2 {}
+contract VRFD20 is VRFConsumerBaseV2 {
+}
```
### Contract variables
-This example is adapted for [Goerli testnet](/docs/vrf/v2/subscription/supported-networks/#goerli-testnet) but you can change the configuration and make it run for any [supported network](/docs/vrf/v2/subscription/supported-networks/#configurations).
+This example is adapted for [Goerli testnet](/vrf/v2/subscription/supported-networks/#goerli-testnet) but you can change the configuration and make it run for any [supported network](/vrf/v2/subscription/supported-networks/#configurations).
+
```solidity
uint64 s_subscriptionId;
address vrfCoordinator = 0x2Ca8E0C643bDe4C2E08ab1fA0da3401AdAD7734D;
@@ -122,6 +111,7 @@ uint32 numWords = 1;
To keep track of addresses that roll the dice, the contract uses mappings. [Mappings](https://medium.com/upstate-interactive/mappings-in-solidity-explained-in-under-two-minutes-ecba88aff96e) are unique key-value pair data structures similar to hash tables in Java.
+
```solidity
mapping(uint256 => address) private s_rollers;
mapping(address => uint256) private s_results;
@@ -135,31 +125,31 @@ mapping(address => uint256) private s_results;
The coordinator and subscription id must be initialized in the `constructor` of the contract. To use `VRFConsumerBaseV2` properly, you must also pass the VRF coordinator address into its constructor.
The address that creates the smart contract is the owner of the contract. the modifier `onlyOwner()` checks that only the owner is allowed to do some tasks.
+
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
-import '@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol';
-import '@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol';
+import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
+import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
contract VRFD20 is VRFConsumerBaseV2 {
- // variables
- // ...
-
- // constructor
- constructor(uint64 subscriptionId) VRFConsumerBaseV2(vrfCoordinator) {
- COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
- s_owner = msg.sender;
- s_subscriptionId = subscriptionId;
- }
-
- //...
- modifier onlyOwner() {
- require(msg.sender == s_owner);
- _;
- }
+ // variables
+ // ...
+
+ // constructor
+ constructor(uint64 subscriptionId) VRFConsumerBaseV2(vrfCoordinator) {
+ COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
+ s_owner = msg.sender;
+ s_subscriptionId = subscriptionId;
+ }
+
+ //...
+ modifier onlyOwner() {
+ require(msg.sender == s_owner);
+ _;
+ }
}
-
```
### `rollDice` function
@@ -175,45 +165,44 @@ You must add a `ROLL_IN_PROGRESS` constant to signify that the dice has been rol
Only the owner of the contract can execute the `rollDice` function.
+
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
-import '@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol';
-import '@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol';
+import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
+import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
contract VRFD20 is VRFConsumerBaseV2 {
- // variables
- uint256 private constant ROLL_IN_PROGRESS = 42;
- // ...
-
- // events
- event DiceRolled(uint256 indexed requestId, address indexed roller);
-
- // ...
-
- // ...
- // { constructor }
- // ...
-
- // rollDice function
- function rollDice(address roller) public onlyOwner returns (uint256 requestId) {
- require(s_results[roller] == 0, 'Already rolled');
- // Will revert if subscription is not set and funded.
- requestId = COORDINATOR.requestRandomWords(
- s_keyHash,
- s_subscriptionId,
- requestConfirmations,
- callbackGasLimit,
- numWords
- );
-
- s_rollers[requestId] = roller;
- s_results[roller] = ROLL_IN_PROGRESS;
- emit DiceRolled(requestId, roller);
- }
+ // variables
+ uint256 private constant ROLL_IN_PROGRESS = 42;
+ // ...
+
+ // events
+ event DiceRolled(uint256 indexed requestId, address indexed roller);
+ // ...
+
+ // ...
+ // { constructor }
+ // ...
+
+ // rollDice function
+ function rollDice(address roller) public onlyOwner returns (uint256 requestId) {
+ require(s_results[roller] == 0, "Already rolled");
+ // Will revert if subscription is not set and funded.
+ requestId = COORDINATOR.requestRandomWords(
+ s_keyHash,
+ s_subscriptionId,
+ requestConfirmations,
+ callbackGasLimit,
+ numWords
+ );
+
+ s_rollers[requestId] = roller;
+ s_results[roller] = ROLL_IN_PROGRESS;
+ emit DiceRolled(requestId, roller);
+ }
}
-
```
### `fulfillRandomWords` function
@@ -224,43 +213,44 @@ contract VRFD20 is VRFConsumerBaseV2 {
1. Assign the transformed value to the address in the `s_results` mapping variable.
1. Emit a `DiceLanded` event.
+
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
-import '@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol';
-import '@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol';
+import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
+import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
contract VRFD20 is VRFConsumerBaseV2 {
- // ...
- // { variables }
- // ...
+ // ...
+ // { variables }
+ // ...
- // events
- // ...
- event DiceLanded(uint256 indexed requestId, uint256 indexed result);
+ // events
+ // ...
+ event DiceLanded(uint256 indexed requestId, uint256 indexed result);
- // ...
- // { constructor }
- // ...
+ // ...
+ // { constructor }
+ // ...
- // ...
- // { rollDice function }
- // ...
+ // ...
+ // { rollDice function }
+ // ...
- // fulfillRandomWords function
- function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override {
- // transform the result to a number between 1 and 20 inclusively
- uint256 d20Value = (randomWords[0] % 20) + 1;
+ // fulfillRandomWords function
+ function fulfillRandomWords(uint256 requestId , uint256[] memory randomWords) internal override {
- // assign the transformed value to the address in the s_results mapping variable
- s_results[s_rollers[requestId]] = d20Value;
+ // transform the result to a number between 1 and 20 inclusively
+ uint256 d20Value = (randomWords[0] % 20) + 1;
- // emitting event to signal that dice landed
- emit DiceLanded(requestId, d20Value);
- }
-}
+ // assign the transformed value to the address in the s_results mapping variable
+ s_results[s_rollers[requestId]] = d20Value;
+ // emitting event to signal that dice landed
+ emit DiceLanded(requestId, d20Value);
+ }
+}
```
### `house` function
@@ -269,89 +259,89 @@ Finally, the `house` function returns the house of an address.
To have a list of the house's names, create the `getHouseName` function that is called in the `house` function.
+
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
-import '@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol';
-import '@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol';
+import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
+import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
contract VRFD20 is VRFConsumerBaseV2 {
- // ...
- // { variables }
- // ...
-
- // ...
- // { events }
- // ...
-
- // ...
- // { constructor }
- // ...
-
- // ...
- // { rollDice function }
- // ...
-
- // ...
- // { fulfillRandomWords function }
- // ...
-
- // house function
- function house(address player) public view returns (string memory) {
- // dice has not yet been rolled to this address
- require(s_results[player] != 0, 'Dice not rolled');
-
- // not waiting for the result of a thrown dice
- require(s_results[player] != ROLL_IN_PROGRESS, 'Roll in progress');
-
- // returns the house name from the name list function
- return getHouseName(s_results[player]);
- }
-
- // getHouseName function
- function getHouseName(uint256 id) private pure returns (string memory) {
- // array storing the list of house's names
- string[20] memory houseNames = [
- 'Targaryen',
- 'Lannister',
- 'Stark',
- 'Tyrell',
- 'Baratheon',
- 'Martell',
- 'Tully',
- 'Bolton',
- 'Greyjoy',
- 'Arryn',
- 'Frey',
- 'Mormont',
- 'Tarley',
- 'Dayne',
- 'Umber',
- 'Valeryon',
- 'Manderly',
- 'Clegane',
- 'Glover',
- 'Karstark'
- ];
-
- // returns the house name given an index
- return houseNames[id.sub(1)];
- }
+ // ...
+ // { variables }
+ // ...
+
+ // ...
+ // { events }
+ // ...
+
+ // ...
+ // { constructor }
+ // ...
+
+ // ...
+ // { rollDice function }
+ // ...
+
+ // ...
+ // { fulfillRandomWords function }
+ // ...
+
+ // house function
+ function house(address player) public view returns (string memory) {
+ // dice has not yet been rolled to this address
+ require(s_results[player] != 0, "Dice not rolled");
+
+ // not waiting for the result of a thrown dice
+ require(s_results[player] != ROLL_IN_PROGRESS, "Roll in progress");
+
+ // returns the house name from the name list function
+ return getHouseName(s_results[player]);
+ }
+
+ // getHouseName function
+ function getHouseName(uint256 id) private pure returns (string memory) {
+ // array storing the list of house's names
+ string[20] memory houseNames = [
+ "Targaryen",
+ "Lannister",
+ "Stark",
+ "Tyrell",
+ "Baratheon",
+ "Martell",
+ "Tully",
+ "Bolton",
+ "Greyjoy",
+ "Arryn",
+ "Frey",
+ "Mormont",
+ "Tarley",
+ "Dayne",
+ "Umber",
+ "Valeryon",
+ "Manderly",
+ "Clegane",
+ "Glover",
+ "Karstark"
+ ];
+
+ // returns the house name given an index
+ return houseNames[id.sub(1)];
+ }
}
-
```
You have now completed all necessary functions to generate randomness and assign the user a _Game of Thrones_ house. We've added a few helper functions in there to make using the contract easier and more flexible. You can deploy and interact with the complete contract in Remix.
-## 5. How do I deploy to testnet?
+## How do I deploy to testnet?
-You will now deploy your completed contract. This deployment is slightly different than the example in the [Deploy Your First Contract](/docs/deploy-your-first-contract/) guide. In our case, you will have to pass in parameters to the constructor upon deployment.
+You will now deploy your completed contract. This deployment is slightly different than the example in the [Deploy Your First Contract](/getting-started/deploy-your-first-contract/) guide. In our case, you will have to pass in parameters to the constructor upon deployment.
Once compiled, you'll see a dropdown menu that looks like this in the deploy pane:
@@ -365,27 +355,27 @@ Click the caret arrow on the right hand side of **Deploy** to expand the paramet
Then click the `Deploy` button and use your Metamask account to confirm the transaction.
-**Note**: You should [have some Goerli ETH](/docs/deploy-your-first-contract/#install-and-fund-your-metamask-wallet) in your Metamask account to pay for the GAS.
+**Note**: You should [have some Goerli ETH](/getting-started/deploy-your-first-contract/#install-and-fund-your-metamask-wallet) in your Metamask account to pay for the GAS.
-> 📘 Address, Key Hashes and more
->
-> For a full reference of the addresses, key hashes and fees for each network, see [VRF v2 Subscription method - Supported Networks](/docs/vrf/v2/subscription/supported-networks/#configurations).
+:::note[ Address, Key Hashes and more]
+For a full reference of the addresses, key hashes and fees for each network, see [VRF Supported Networks](/vrf/v2/subscription/supported-networks/#configurations).
+:::
At this point, your contract should be successfully deployed. However, it can't request anything because it is not yet approved to use the LINK balance in your subscription. If you click `rollDice`, the transaction will revert.
-## 6. How do I add my contract to my subscription account?
+## How do I add my contract to my subscription account?
After you deploy your contract, you must add it as an approved consumer contract so it can use the subscription balance when requesting for randomness. Go to the [Subscription Manager](https://vrf.chain.link) and add your deployed contract address to the list of consumers. Find your contract address in Remix under **Deployed Contracts** on the bottom left.

-## 7. How do I test `rollDice`?
+## How do I test `rollDice`?
After you open the deployed contract tab in the bottom left, the function buttons are available. Find `rollDice` and click the caret to expand the parameter fields. Enter an Ethereum address to specify a "dice roller", and click 'rollDice'.
You will have to wait a few minutes for your transaction to confirm and the response to be sent back. You can get your house by clicking the `house` function button with the address passed in `rollDice`. After the response is sent back, you'll be assigned a _Game of Thrones_ house!
-## 8. Further Reading
+## Further Reading
To read more about generating random numbers in Solidity, read our blog posts:
diff --git a/docs/getting-started/other-tutorials.md b/src/pages/getting-started/other-tutorials.md
similarity index 79%
rename from docs/getting-started/other-tutorials.md
rename to src/pages/getting-started/other-tutorials.md
index b3f35b0ab6f..4f5f89a90b1 100644
--- a/docs/getting-started/other-tutorials.md
+++ b/src/pages/getting-started/other-tutorials.md
@@ -1,27 +1,11 @@
---
-layout: nodes.liquid
+layout: ../../layouts/MainLayout.astro
section: gettingStarted
date: Last Modified
title: "Learning Resources"
-permalink: "docs/other-tutorials/"
---
-Welcome to the Resources page. This is a list of links and pages that you might need to help you throughout your learning journey. If you're new to Chainlink, start with the [Getting Started](/docs/conceptual-overview/) guide to better understand the products and services Chainlink offers. This page contains more resources, inspiration, and outreach information to further your learning.
-
-**Topics**
-
-+ [Smart contract learning materials](#smart-contract-learning-materials)
- + [Video tutorials](#video-tutorials)
- + [Applications](#applications)
- + [Game resources](#game-resources)
- + [Coding bootcamps](#coding-bootcamps)
- + [Starter kits](#starter-kits)
- + [External tutorials](#external-tutorials)
- + [More inspiration](#more-inspiration)
-+ [Outreach](#outreach)
- + [Get support](#get-support)
- + [Join the community](#join-the-community)
-
+Welcome to the Resources page. This is a list of links and pages that you might need to help you throughout your learning journey. If you're new to Chainlink, start with the [Getting Started](/getting-started/conceptual-overview/) guide to better understand the products and services Chainlink offers. This page contains more resources, inspiration, and outreach information to further your learning.
## Smart contract learning materials
@@ -42,35 +26,37 @@ We're constantly uploading new videos to our [YouTube](https://www.youtube.com/c
- [Nader Dabit](https://www.youtube.com/watch?v=nS9xP1hxg3w)
### Applications
+
Below is a list of applications of Chainlink's products and services sorted by difficulty and type to help you navigate and search for projects that you might find interesting. See the [Chainlink Blog](https://blog.chain.link/) to stay up to date with new ways to use Chainlink.
#### Data feeds
-| Name | Type | Difficulty |
-|:-------------------------------------------------------------------------------------------------------------------------------------------------- |:-------- |:---------- |
-| [How to Calculate Price Volatility for DeFi Variance Swaps](https://blog.chain.link/how-to-calculate-price-volatility-for-defi-variance-swaps/) | DeFi | Advanced |
-| [Build a dApp on Gnosis Chain (xDai) with Secure Data Feeds](https://blog.chain.link/build-a-dapp-on-xdai-chain-with-secure-data-feeds/) | DeFi | Medium |
-| [Craft Whiskey Crypto Payments With Chainlink Oracles](https://blog.chain.link/craft-whiskey-crypto-payments-with-chainlink-oracles/) | Payments | Advanced |
+
+| Name | Type | Difficulty |
+| :------------------------------------------------------------------------------------------------------------------------------------------------ | :------- | :--------- |
+| [How to Calculate Price Volatility for DeFi Variance Swaps](https://blog.chain.link/how-to-calculate-price-volatility-for-defi-variance-swaps/) | DeFi | Advanced |
+| [Build a dApp on Gnosis Chain (xDai) with Secure Data Feeds](https://blog.chain.link/build-a-dapp-on-xdai-chain-with-secure-data-feeds/) | DeFi | Medium |
+| [Craft Whiskey Crypto Payments With Chainlink Oracles](https://blog.chain.link/craft-whiskey-crypto-payments-with-chainlink-oracles/) | Payments | Advanced |
| [Convert a Vending Machine to Accept Cryptocurrency Payments Using Chainlink Data Feeds](https://blog.chain.link/cryptocurrency-vending-machine/) | Payments | Advanced |
-| [Build a dApp on BNB Chain With Secure Data Feeds](https://blog.chain.link/build-a-dapp-on-binance-smart-chain-with-secure-data-feeds/) | DeFi | Medium |
-| [How to Use Chainlink With Hardhat](https://blog.chain.link/using-chainlink-with-hardhat/) | DeFi | Medium |
-| [Develop a DeFi Project Using Python](https://blog.chain.link/develop-python-defi-project/) | DeFi | Medium |
+| [Build a dApp on BNB Chain With Secure Data Feeds](https://blog.chain.link/build-a-dapp-on-binance-smart-chain-with-secure-data-feeds/) | DeFi | Medium |
+| [How to Use Chainlink With Hardhat](https://blog.chain.link/using-chainlink-with-hardhat/) | DeFi | Medium |
+| [Develop a DeFi Project Using Python](https://blog.chain.link/develop-python-defi-project/) | DeFi | Medium |
| [Build a DeFi Call Option Exchange With Chainlink Data Feeds](https://blog.chain.link/defi-call-option-exchange-in-solidity/) | DeFi | Advanced |
| [Build a DeFi Yield Farming dApp Using Chainlink Data Feeds](https://blog.chain.link/build-defi-yield-farming-application-with-chainlink/) | DeFi | Advanced |
| [Build and Deploy an Avalanche Smart Contract](https://blog.chain.link/how-to-build-and-deploy-an-avalanche-smart-contract/) | DeFi | Beginner |
-
#### Randomness (VRF)
-| Name | Type | Difficulty |
-|:------------------------------------------------------------------------------------------------------- |:-------- |:---------- |
-| [How to Get a Random Number on Polygon](https://blog.chain.link/how-to-get-a-random-number-on-polygon/) | DeFi | Medium |
-| [Build Your Own Dynamic NFT With Hardhat](https://blog.chain.link/dynamic-nft-hardhat/) | NFT | Advanced |
-| [Build, Deploy, and Sell Your Own Dynamic NFT](https://blog.chain.link/build-deploy-and-sell-your-own-dynamic-nft/) | NFT | Advanced |
-| [How to Build a Blockchain Lottery](https://blog.chain.link/how-to-build-a-blockchain-lottery-2/) | Gambling | Advanced |
+
+| Name | Type | Difficulty |
+| :------------------------------------------------------------------------------------------------------------------ | :------- | :--------- |
+| [How to Get a Random Number on Polygon](https://blog.chain.link/how-to-get-a-random-number-on-polygon/) | DeFi | Medium |
+| [Build Your Own Dynamic NFT With Hardhat](https://blog.chain.link/dynamic-nft-hardhat/) | NFT | Advanced |
+| [Build, Deploy, and Sell Your Own Dynamic NFT](https://blog.chain.link/build-deploy-and-sell-your-own-dynamic-nft/) | NFT | Advanced |
+| [How to Build a Blockchain Lottery](https://blog.chain.link/how-to-build-a-blockchain-lottery-2/) | Gambling | Advanced |
#### API requests
| Name | Type | Difficulty |
-| -------------------------------------------------------------------------------------------------------------------------------------------------------------- |:-------------------- |:---------- |
+| -------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------- | :--------- |
| [Build a Real Estate dApp With Chainlink Oracles](https://blog.chain.link/build-a-real-estate-dapp-with-chainlink-oracles/) | Real-Estate | Medium |
| [Off-Chain Computation: Statistical Analysis With Chainlink](https://blog.chain.link/off-chain-computation-statistical-analysis-with-chainlink/) | Statistical Analysis | Advanced |
| [Blockchain Fintech Tutorial: Lending and Borrowing With Python](https://blog.chain.link/blockchain-fintech-defi-tutorial-lending-borrowing-python/) | Lending | Medium |
@@ -82,21 +68,21 @@ Below is a list of applications of Chainlink's products and services sorted by d
| [Connect a Smart Contract to the Twitter API](https://blog.chain.link/connect-smart-contract-to-twitter-api/) | Social Media | Advanced |
| [Build an RFID Blockchain Integration With Chainlink External Adapters](https://blog.chain.link/rfid-blockchain-integration-with-chainlink-external-adapters/) | Identification | Advanced |
| [How to Connect a Tesla Vehicle API to a Smart Contract Via a Chainlink External Adapter](https://blog.chain.link/create-tesla-smart-contract-rental/) | Transportation | Advanced |
-| [OAuth and API Authentication in Smart Contracts](https://blog.chain.link/oauth-and-api-authentication-in-smart-contracts-2/) | Security | Advanced |
+| [OAuth and API Authentication in Smart Contracts](https://blog.chain.link/oauth-and-api-authentication-in-smart-contracts-2/) | Security | Advanced |
#### Automation (Keepers)
-| Name | Type | Difficulty |
-| -------------------------------------------------------------------------------------------------------------------------------------------------------------- |:-------------------- |:---------- |
-| [Smart Contract Automation Master Class Module #1](https://youtu.be/D3rMFshrj7c) | Automation | Beginner |
-| [Smart Contract Automation Master Class Module #2](https://youtu.be/UT2qpUh0tmA/) | Automation | Beginner |
-| [Entropyfi Saves Engineering Hours with Chainlink Keepers](https://medium.com/entropyfi/entropyfi-saves-engineering-hours-with-chainlink-keepers-6ec172a76249) | Gaming | Medium |
-| [Enabling Limit Orders on CivTrade With Chainlink Keepers](https://news.civfund.org/civtrade-with-chainlink-keepers-8b6c3965a92e) | Trading | Medium |
-| [Pickle Finance UniV3 Jars Powered by Chainlink Keepers](https://picklefinance.medium.com/pickle-finance-univ3-jars-powered-by-chainlink-keepers-8ce1756a2497) | Finance | Medium |
-| [JamonSwap Introduces New Limit Order Functionality Using Chainlink Keepers](https://medium.com/@JamonSwap/jamonswap-introduces-new-limit-order-functionality-using-chainlink-keepers-51bd94d75feb) | DeFi | Medium |
-| [How Cratos used Chainlink Keepers to automate the token vesting process](https://cratostoken.medium.com/how-cratos-used-chainlink-keepers-to-automate-the-token-vesting-process-69bcb3611161) | DeFi | Medium |
-| [Enabling automated NFT lotteries with Chainlink Keepers and VRF](https://czodiac.medium.com/enabling-automated-nft-lotteries-with-chainlink-keepers-and-vrf-34dcc191965b) | NFT | Medium |
-| [How ApeSwap Integrated Chainlink Keepers for BANANA Maximizer Vaults](https://ape-swap.medium.com/how-apeswap-integrated-chainlink-keepers-for-banana-maximizer-vaults-2e88abb34eca) | DeFi | Medium |
+| Name | Type | Difficulty |
+| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------- | :--------- |
+| [Smart Contract Automation Master Class Module #1](https://youtu.be/D3rMFshrj7c) | Automation | Beginner |
+| [Smart Contract Automation Master Class Module #2](https://youtu.be/UT2qpUh0tmA/) | Automation | Beginner |
+| [Entropyfi Saves Engineering Hours with Chainlink Keepers](https://medium.com/entropyfi/entropyfi-saves-engineering-hours-with-chainlink-keepers-6ec172a76249) | Gaming | Medium |
+| [Enabling Limit Orders on CivTrade With Chainlink Keepers](https://news.civfund.org/civtrade-with-chainlink-keepers-8b6c3965a92e) | Trading | Medium |
+| [Pickle Finance UniV3 Jars Powered by Chainlink Keepers](https://picklefinance.medium.com/pickle-finance-univ3-jars-powered-by-chainlink-keepers-8ce1756a2497) | Finance | Medium |
+| [JamonSwap Introduces New Limit Order Functionality Using Chainlink Keepers](https://medium.com/@JamonSwap/jamonswap-introduces-new-limit-order-functionality-using-chainlink-keepers-51bd94d75feb) | DeFi | Medium |
+| [How Cratos used Chainlink Keepers to automate the token vesting process](https://cratostoken.medium.com/how-cratos-used-chainlink-keepers-to-automate-the-token-vesting-process-69bcb3611161) | DeFi | Medium |
+| [Enabling automated NFT lotteries with Chainlink Keepers and VRF](https://czodiac.medium.com/enabling-automated-nft-lotteries-with-chainlink-keepers-and-vrf-34dcc191965b) | NFT | Medium |
+| [How ApeSwap Integrated Chainlink Keepers for BANANA Maximizer Vaults](https://ape-swap.medium.com/how-apeswap-integrated-chainlink-keepers-for-banana-maximizer-vaults-2e88abb34eca) | DeFi | Medium |
### Game resources
@@ -128,11 +114,11 @@ Our Starter Kits help jumpstart your full-stack development process. You can get
Looking for more ways to use Chainlink? Here are some resources that discuss Chainlink's use cases as well as the winning projects we've had in our previous hackathons. There is also a link to the Marketplace where you can find the latest data provider nodes and explore the network.
- [77 Use Cases by Chainlink](https://blog.chain.link/44-ways-to-enhance-your-smart-contract-with-chainlink/)
-- [Past Hackathon Winning Projects](/docs/example-projects)
+- [Past Hackathon Winning Projects](/resources/example-projects/)
## Outreach
-The Chainlink community is an inviting group of engineers that is always looking to help users expand their knowledge on Chainlink and solve related issues. Refer back to the [Getting Help](/docs/getting-help) page for the latest information about how to get support.
+The Chainlink community is an inviting group of engineers that is always looking to help users expand their knowledge on Chainlink and solve related issues. Refer back to the [Getting Help](/resources/getting-help/) page for the latest information about how to get support.
### Get support
diff --git a/src/pages/index.astro b/src/pages/index.astro
new file mode 100644
index 00000000000..95c47e8ce8a
--- /dev/null
+++ b/src/pages/index.astro
@@ -0,0 +1,31 @@
+---
+import NodesCTA from "../features/landing/sections/NodesCTA.astro"
+import ProductTabs from "../features/landing/sections/ProductTabs.astro"
+import LinksCTA from "../features/landing/sections/LinksCTA.astro"
+import ResourcesCTA from "../features/landing/sections/ResourcesCTA.astro"
+import LandingLayout from "../layouts/LandingLayout.astro"
+import TutorialsCTA from "../features/landing/sections/TutorialsCTA.astro"
+import HeroCTA from "../features/landing/sections/HeroCTA.astro"
+import NewUserCTA from "~/features/landing/sections/NewUserCTA.astro"
+---
+
+
+
+
+
+
+
diff --git a/src/pages/rc.mdx b/src/pages/rc.mdx
new file mode 100644
index 00000000000..7d73db22304
--- /dev/null
+++ b/src/pages/rc.mdx
@@ -0,0 +1,203 @@
+---
+layout: ../layouts/MainLayout.astro
+section: gettingStarted
+date: Last Modified
+title: "Overview"
+excerpt: "Smart Contracts"
+whatsnext:
+ {
+ "Deploy Your First Smart Contract": "/getting-started/deploy-your-first-contract/",
+ "Consuming Data Feeds": "/getting-started/consuming-data-feeds/",
+ }
+clientSideToc: false
+---
+
+import { Aside, ClickToZoom, CodeSample } from "@components"
+import { Tabs } from "@components/Tabs"
+
+test heading
+
+
+ web3.js
+ ethers.js
+
+
+
+
+
+
+
+
+
+
+
+# MDX
+
+```bash
+npm init astro -- --template docs
+```
+
+
+
+[](https://stackblitz.com/github/withastro/astro/tree/latest/examples/docs)
+
+## Features
+
+- ✅ **Full Markdown support**
+- ✅ **Responsive mobile-friendly design**
+- ✅ **Sidebar navigation**
+- ✅ **Search (powered by Algolia)**
+- ✅ **Multi-language i18n**
+- ✅ **Automatic table of contents**
+- ✅ **Automatic list of contributors**
+- ✅ (and, best of all) **dark mode**
+
+## Commands Cheatsheet
+
+All commands are run from the root of the project, from a terminal:
+
+| Command | Action |
+| :---------------- | :------------------------------------------- |
+| `npm install` | Installs dependencies |
+| `npm run dev` | Starts local dev server at `localhost:3000` |
+| `npm run build` | Build your production site to `./dist/` |
+| `npm run preview` | Preview your build locally, before deploying |
+
+To deploy your site to production, check out our [Deploy an Astro Website](https://docs.astro.build/guides/deploy) guide.
+
+## New to Astro?
+
+Welcome! Check out [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
+
+## Customize This Theme
+
+### Site metadata
+
+`src/config.ts` contains several data objects that describe metadata about your site like title, description, default language, and Open Graph details. You can customize these to match your project.
+
+### CSS styling
+
+The theme's look and feel is controlled by a few key variables that you can customize yourself. You'll find them in the `public/theme.css` CSS file.
+
+If you've never worked with CSS variables before, give [MDN's guide on CSS variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) a quick read.
+
+This theme uses a "cool blue" accent color by default. To customize this for your project, change the `--theme-accent` variable to whatever color you'd like:
+
+```diff
+/* public/theme.css */
+:root {
+ color-scheme: light;
+- --theme-accent: hsla(var(--color-blue), 1);
++ --theme-accent: hsla(var(--color-red), 1); /* or: hsla(#FF0000, 1); */
+```
+
+## Page metadata
+
+Astro uses frontmatter in Markdown pages to choose layouts and pass properties to those layouts. If you are using the default layout, you can customize the page in many different ways to optimize SEO and other things. For example, you can use the `title` and `description` properties to set the document title, meta title, meta description, and Open Graph description.
+
+```markdown
+---
+title: Example title
+description: Really cool docs example that uses Astro
+layout: ../../layouts/MainLayout.astro
+---
+
+# Page content...
+```
+
+For more SEO related properties, look at `src/components/HeadSEO.astro`
+
+### Sidebar navigation
+
+The sidebar navigation is controlled by the `SIDEBAR` variable in your `src/config.ts` file. You can customize the sidebar by modifying this object. A default, starter navigation has already been created for you.
+
+```ts
+export const SIDEBAR = {
+ en: [
+ { text: "Section Header", header: true },
+ { text: "Introduction", link: "en/introduction" },
+ { text: "Page 2", link: "en/page-2" },
+ { text: "Page 3", link: "en/page-3" },
+
+ { text: "Another Section", header: true },
+ { text: "Page 4", link: "en/page-4" },
+ ],
+}
+```
+
+Note the top-level `en` key: This is needed for multi-language support. You can change it to whatever language you'd like, or add new languages as you go. More details on this below.
+
+### Multiple Languages support
+
+The Astro docs template supports multiple langauges out of the box. The default theme only shows `en` documentation, but you can enable multi-language support features by adding a second language to your project.
+
+To add a new language to your project, you'll want to extend the current `src/pages/[lang]/...` layout:
+
+```diff
+ 📂 src/pages
+ ┣ 📂 en
+ ┃ ┣ 📜 page-1.md
+ ┃ ┣ 📜 page-2.md
+ ┃ ┣ 📜 page-3.astro
++ ┣ 📂 es
++ ┃ ┣ 📜 page-1.md
++ ┃ ┣ 📜 page-2.md
++ ┃ ┣ 📜 page-3.astro
+```
+
+You'll also need to add the new language name to the `KNOWN_LANGUAGES` map in your `src/config.ts` file. This will enable your new language switcher in the site header.
+
+```diff
+// src/config.ts
+export const KNOWN_LANGUAGES = {
+ English: 'en',
++ Spanish: 'es',
+};
+```
+
+Last step: you'll need to add a new entry to your sidebar, to create the table of contents for that language. While duplicating every page might not sound ideal to everyone, this extra control allows you to create entirely custom content for every language.
+
+> Make sure the sidebar `link` value points to the correct language!
+
+```diff
+// src/config.ts
+export const SIDEBAR = {
+ en: [
+ { text: 'Section Header', header: true, },
+ { text: 'Introduction', link: 'en/introduction' },
+ // ...
+ ],
++ es: [
++ { text: 'Encabezado de sección', header: true, },
++ { text: 'Introducción', link: 'es/introduction' },
++ // ...
++ ],
+};
+
+// ...
+```
+
+If you plan to use Spanish as the the default language, you just need to modify the redirect path in `src/pages/index.astro`:
+
+```diff
+
+```
+
+You can also remove the above script and write a landing page in Spanish instead.
+
+### What if I don't plan to support multiple languages?
+
+That's totally fine! Not all projects need (or can support) multiple languages. You can continue to use this theme without ever adding a second language.
+
+If that single language is not English, you can just replace `en` in directory layouts and configurations with the preferred language.
+
+### Search (Powered by Algolia)
+
+[Algolia](https://www.algolia.com/) offers a free service to qualified open source projects called [DocSearch](https://docsearch.algolia.com/). If you are accepted to the DocSearch program, provide your API Key & index name in `src/config.ts` and a search box will automatically appear in your site header.
+
+Note that Aglolia and Astro are not affiliated. We have no say over acceptance to the DocSearch program.
+
+If you'd prefer to remove Algolia's search and replace it with your own, check out the `src/components/Header.astro` component to see where the component is added.
diff --git a/src/pages/resources/acquire-link.md b/src/pages/resources/acquire-link.md
new file mode 100644
index 00000000000..d90212210cf
--- /dev/null
+++ b/src/pages/resources/acquire-link.md
@@ -0,0 +1,37 @@
+---
+layout: ../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Acquire testnet LINK"
+permalink: "docs/acquire-link/"
+whatsnext: { "Deploy your first contract": "/getting-started/deploy-your-first-contract/" }
+---
+
+The Getting Started guides show you how to send ETH on the Goerli testnet, but some contracts might require you to use LINK token instead. This page shows you how to obtain testnet LINK and send it to your MetaMask wallet.
+
+## Configure MetaMask to use LINK tokens
+
+To see your LINK token balance in MetaMask, you must manually add the token.
+
+1. Open up MetaMask.
+1. At the bottom of the MetaMask windows, click **Import tokens**.
+1. Find the LINK token contract address for the network that you want to use. On Goerli the LINK token address is: `0x326C977E6efc84E512bB9C30f76E30c160eD06FB`. See the [LINK Token Contracts](/resources/link-token-contracts/) page to find addresses for different testnets.
+1. Paste the token contract address into MetaMask in the Token Address input. The token symbol and decimals of precision will auto-populate.
+ 
+1. Click **Next**. A new window will appears, showing the LINK token details.
+1. Click **Import Tokens** to confirm adding the new token.
+
+MetaMask should now display the new LINK token balance.
+
+## Get testnet LINK from a faucet
+
+1. Go to [https://faucets.chain.link/](https://faucets.chain.link/).
+1. In Metmask, select the network where you want to receive testnet LINK.
+1. Click **Connect wallet** so the faucet app can detect the network and wallet address.
+1. If you want to receive testnet funds at a different address, paste it in the **Wallet address** section. This field defaults to your connected wallet address.
+1. In the **Request type** section, select the testnet funds that you want to receive.
+1. Complete the Captcha and click **Send request**. The funds are transferred from the faucet to the wallet address that you specified.
+
+After the transaction is confirmed on-chain, the faucet app shows "Request complete" and the transaction hash of your request.
+
+
diff --git a/src/pages/resources/contributing-to-chainlink.md b/src/pages/resources/contributing-to-chainlink.md
new file mode 100644
index 00000000000..a641a5b97f7
--- /dev/null
+++ b/src/pages/resources/contributing-to-chainlink.md
@@ -0,0 +1,133 @@
+---
+layout: ../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Contributing to Chainlink"
+permalink: "docs/contributing-to-chainlink/"
+---
+
+Chainlink is an open-source project licensed [under the MIT license](https://github.com/smartcontractkit/chainlink/blob/master/LICENSE), and we encourage contributions from all developers and community members.
+
+
+
+# What It Means to Contribute
+
+When you contribute to the Chainlink project, you as a developer or community member contribute your time and effort to help improve and grow Chainlink. Your contribution can be from various methods:
+
+- [Building and maintaining the Chainlink software and tools](#contributing-to-software-and-tooling)
+- [Improving and maintaining the documentation, including translations into other languages](#contributing-to-the-documentation)
+- [Creating Chainlink focused content (blog posts, tutorials, videos etc)](#creating-community-content)
+- [Becoming a developer expert](#becoming-a-developer-expert)
+- [Becoming a community advocate](#joining-the-chainlink-community-advocate-program)
+- [Running a Chainlink focused developer Bootcamp (in person or online)](#running-a-chainlink-focused-developer-bootcamp)
+- [Running an in-person meetup or watch party](#running-an-in-person-meetup-or-watch-party)
+- [Participate in a hackathon](#participate-in-a-hackathon)
+- [Applying for a grant](#applying-for-a-grant)
+
+# Why Should You Contribute
+
+[Open source software](https://en.wikipedia.org/wiki/Open-source_software) is a model that brings multiple benefits for both the project and the contributors. As a developer or community member, contributing to Chainlink helps you to gain valuable skills and experience, improve the software that you use, and grow your personal brand in the community which can lead to future employment opportunities. On top of these awesome things, contributing to open source is fun. It can give you a sense of community involvement, and gives you a personal sense of satisfaction knowing that you're part of an effort to build something that will enable a fairer, more transparent, and efficient new world.
+
+# Ways to Contribute
+
+## Contributing to Software and Tooling
+
+The most direct way you can contribute to Chainlink is to contribute to the core code or the various tooling found in our [GitHub repository](https://github.com/smartcontractkit/). Contributing to code or code-based tools can generally be split into a few different categories:
+
+- Raising an issue
+- Requesting a new feature
+- Submitting a Pull Request (PR) for a fix, improvement, or new tool
+
+### Raising an Issue
+
+During the course of using Chainlink software or tools, you might encounter errors or unexpected behavior that leads you to believe the software isn't behaving correctly. You can bring this to the attention of the Chainlink Labs team as well as the wider developer community by raising an issue in the project’s GitHub repository. The 'Issues' tab lists all of the open issues for the repository.
+
+After an issue is raised and tagged, the Chainlink Labs team and the wider community can address it. This gives the issue the visibility required for someone to investigate it and resolve the issue.
+
+When you first create an issue, you must also categorize it. This prefixes the issue name to give viewers an indication of what category the issue relates to:
+
+- [NODE]: The issue relates to the core node software
+- [DEVEL]: The issue is a result of working on code found in the current repository
+- [FEAT]: The issue relates to a new feature request
+- [SMRT]: The issue related to using Chainlink smart contracts
+- [EXPL]: The issue related to using the Chainlink Explorer
+- [FAUC]: The issue related to using the Chainlink Faucet
+
+
+
+After you select a category, enter the details for the issue. Include as much detail about the issue as possible. Provide a thorough description, environment, and software version details. Also provide detailed steps that describe how to reproduce the issue. The more thorough you make your description, the better the chances are that someone will be able to pick up the issue and resolve it.
+
+Once a team member acknowledges that the issue has been received, they will tag it with an appropriate label. You should then monitor the state of the open issue for any questions or updates.
+
+### Requesting a new Feature
+
+Have you thought of an improvement or an awesome new feature that you think should be implemented into Chainlink? Request a new feature to bring it to the attention of the team and the wider community. You can request new features by creating a new GitHub issue in the correct repository and tagging that issue with the [FEAT] prefix (Feature request). The process for doing this is covered in the [Raising an Issue](#raising-an-issue) section. Provide as much detail as possible in your feature request, including any benefits, risks, or considerations that you can think of.
+
+#### Voting on new features
+
+Sometimes a new feature is put to a vote to decide if it's something that the team and wider community should implement. When an feature is put to a vote, the issue is tagged with the 'needs votes' label. You can contribute to the voting process by reacting to the first post in the feature request with a thumbs up or thumbs down emoji. This will help drive the decision. You can also contribute your thoughts by replying directly to the feature request with a new post in the thread.
+
+
+
+### Submitting a Pull Request
+
+The best way to contribute to Chainlink is to submit a [pull request (PR)](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests). PRs can be submitted for various reasons, such as fixing an identified issue, adding a feature or improvement to the project, or even adding an entirely new repository to the Chainlink source code for a new tool or feature. If you're looking for something to pick up and create a PR for, you can search through the Chainlink repositories to find open issues, and approved feature requests.
+
+If you're new to contributing to open-source software or Chainlink, we've tagged some [good first issues](https://github.com/smartcontractkit/chainlink/issues?q=is%3Aissue+label%3A%22good+first+issue%22) against the main node software and smart contracts that you can tackle. Each major repository in the Chainlink GitHub should also have some good first issues tagged for developers to be able to take on.
+
+All code changes must follow the [style guide] (https://github.com/smartcontractkit/chainlink/wiki/Code-Style-Guide), All PRs must be in an appropriately named branch with a format like 'feat/feature-description' or 'devel/issue-description'. After you submit a PR, you should get a response by a team member within a day or two acknowledging that the PR has been received. After that, monitor the PR for any additional questions or updates that come up while the team and the community review the changes.
+
+## Contributing to the documentation
+
+The [Chainlink documentation](https://docs.chain.link/) is the go-to place for developers who want to learn how to build applications using Chainlink, and node operators wanting useful information on running a Chainlink node. The documentation is [open source](https://github.com/smartcontractkit/documentation), allowing for other developers and community members to contribute to adding or improving it. You can contribute to the Chainlink documentation in various ways:
+
+- Improving the readability of pages
+- Fixing typos or grammar errors
+- Adding new guides or tutorials that you would find useful
+- Translating the documentation into other languages
+
+The process for contributing to the documentation follows the process defined earlier in the [Submitting a Pull Request](#submitting-a-pull-request) section. Each page also has a 'Suggest Edits' link on the top right, and will directly take you to the page in the [documentation repository](https://github.com/smartcontractkit/documentation), where you can create a new PR with the suggested changes. Before you create a PR for the documentation, read the [contributing guidelines](https://github.com/smartcontractkit/documentation/blob/main/CONTRIBUTING.md).
+
+If you want to translate the documentation into a new language that is not yet supported, feel free to [reach out to the team](mailto:devrel@smartcontract.com) beforehand, so we can make sure you get the support you need.
+
+## Creating Community Content
+
+Chainlink has a strong and vibrant community of developers and community advocates. Community members often create Chainlink-focused content in various forms and publish it for the wider community on various platforms. This increases knowledge and awareness of Chainlink solutions across the wider community and builds the contributor's personal skills and brand in the community.
+
+Some examples of the content generated from the community:
+
+- Document your experience in using Chainlink as part of your project
+- Do a deep dive blog post or video on a Chainlink solution
+- Write up technical tutorials showcasing Chainlink being used in various use cases
+
+## Becoming a Developer Expert
+
+Chainlink Developer Experts are smart contract and blockchain developers with deep experience building applications using Chainlink. They are passionate about sharing their technical knowledge with the world. As a developer expert, you will receive recognition in the community, previews of new Chainlink features, exclusive access to Chainlink events, and opportunities to level up your technical and soft skills. You can apply to become a developer expert on the [Chainlink Developer Experts page](https://chain.link/developers/experts).
+
+## Joining the Chainlink Community Advocate program
+
+The [Chainlink Community Advocate Program](https://blog.chain.link/expanding-the-chainlink-community-advocate-program/) is a program designed to help accelerate the awareness and adoption of Chainlink. Chainlink community advocates are passionate members of the Chainlink community that help to achieve this by running virtual and in-person meetups, connecting with partners and sponsors, creating content, and working directly with the teams that are making Chainlink-powered smart contracts. Many Advocates have gone on to have rewarding careers in the blockchain industry, and some of them work on Chainlink specifically.
+
+To become a community advocate, you can apply via the [community advocates web page](https://chain.link/community/advocates).
+
+## Running a Chainlink Focused Developer Bootcamp
+
+In June 2021, Chainlink [virtually hosted](https://blog.chain.link/smart-contract-developer-bootcamp-on-demand/) the first [Chainlink Developer Bootcamp](http://chain.link/bootcamp). If you're passionate about educating others about smart contracts and Chainlink, you can contribute by running your own developer Bootcamp. You can also contribute by translating an existing Bootcamp and running it in another language. Before you run your own Bootcamp, [reach out to the team](mailto:devrel@smartcontract.com) so we can make sure you have the support that you need.
+
+## Running an In-Person Meetup or Watch Party
+
+If you're passionate about helping to grow the awareness and adoption of Chainlink, you can contribute by running an in-person meetup or watch party for a Chainlink event such as [SmartCon](https://www.smartcontractsummit.io/). Meetups are a great way to meet others also passionate about how hybrid smart contracts can create an economically fair world.
+
+If you're interested in running an in-person meetup or watch party, [reach out to the team](mailto:community@smartcontract.com) so we can make sure you have the support that you need.
+
+## Participate in a Hackathon
+
+Chainlink runs hackathons multiple times per year and often sponsors other hackathons across the blockchain ecosystem. Participating in a hackathon that Chainlink is a part of is a great way to learn how to use Chainlink. It is also a great way to showcase your skills to the Chainlink team and the wider community. Hackathons are a popular place for recruiting talent into the blockchain ecosystem.
+
+To stay up to date on the hackathons that Chainlink is running or sponsoring, keep an eye out on the official Chainlink social media channels, and sign up for our [developer newsletter](/resources/developer-communications/).
+
+## Applying for a Grant
+
+The [Chainlink grant program](https://chain.link/community/grants) encourages the community to create critical developer tooling, add high-quality data, and the launch key services around the Chainlink Network. Grant categories include community, integration, bug bounty, research, and social impact grants. If you have a great idea that fits into one of these categories, you can apply for a grant. If successful, you will receive the funding and support needed to successfully build and implement your idea.
+
+For more information about the grant program, go to the [Chainlink Grants web page](https://chain.link/community/grants).
diff --git a/src/pages/resources/create-a-chainlinked-project.md b/src/pages/resources/create-a-chainlinked-project.md
new file mode 100644
index 00000000000..53327633c4a
--- /dev/null
+++ b/src/pages/resources/create-a-chainlinked-project.md
@@ -0,0 +1,161 @@
+---
+layout: ../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Install Frameworks"
+permalink: "docs/create-a-chainlinked-project/"
+whatsnext:
+ {
+ "Introduction to Data Feeds": "/data-feeds/",
+ "Introduction to Chainlink VRF": "/vrf/v2/introduction/",
+ "Introduction to Using Any API": "/any-api/introduction/",
+ }
+---
+
+
+
+This page explains how to install and use the [Chainlink Library](/any-api/api-reference/) in your projects, either manually or via the user of the Chainlink Starter Kits.
+
+:::note[ Important]
+
+If you're new to smart contract development and want a step-by-step guide, try out our [Getting Started](/getting-started/conceptual-overview/) guide.
+
+:::
+
+# Install into Existing Projects
+
+Chainlink is supported by [Hardhat](http://hardhat.org), [Brownie](https://eth-brownie.readthedocs.io/en/stable), [Truffle](https://www.trufflesuite.com) and other frameworks.
+
+If you already have a project, you can add Chainlink to it by using the following package managers.
+
+## NPM
+
+Install using [NPM](https://www.npmjs.com/):
+
+```shell npm
+npm install @chainlink/contracts --save
+```
+
+## Yarn
+
+Install using [Yarn](https://yarnpkg.com/):
+
+```shell yarn
+yarn add @chainlink/contracts
+```
+
+# Create a New Project
+
+If you're creating a new project from scratch, these commands will help you set up your project to interact with Chainlink tools and features via the use of our Starter Kits.
+
+## Hardhat Starter Kit
+
+To learn more about Hardhat, see the [Hardhat Documentation](https://hardhat.org/getting-started/).
+
+Clone the starter kit. The starter kit includes Hardhat, so you don't need to install it separately.
+
+```shell
+git clone https://github.com/smartcontractkit/hardhat-starter-kit
+cd hardhat-starter-kit
+```
+
+For instructions on how to use the starter kit, refer to the [Hardhat starter kit README](https://github.com/smartcontractkit/hardhat-starter-kit/blob/main/README.md).
+
+For more details on how to use Chainlink with Hardhat, see our blog post about [How to use Hardhat with Chainlink](https://blog.chain.link/using-chainlink-with-hardhat/).
+
+---
+
+## Brownie Starter Kit
+
+Before you begin, [install Brownie](https://eth-brownie.readthedocs.io/en/stable/install.html).
+
+With Brownie installed, run the commands below to open a Brownie project in a new directory.
+
+```shell
+mkdir MyChainlinkProject
+cd MyChainlinkProject/
+brownie bake chainlink-mix
+cd chainlink-mix
+```
+
+For instructions on how to use the starter kit, refer to the [Brownie starter kit README](https://github.com/smartcontractkit/chainlink-mix/blob/master/README.md).
+
+For more details on how to use Chainlink with Brownie, see the [Develop a DeFi Project Using Python](https://blog.chain.link/develop-python-defi-project/) blog post.
+
+---
+
+## Truffle Starter Kit
+
+Before you begin, [install Truffle with NPM](https://www.trufflesuite.com/truffle):
+
+```shell
+npm install truffle -g
+```
+
+Once installed, unbox the Truffle Starter Kit:
+
+```shell Truffle
+mkdir MyChainlinkProject
+cd MyChainlinkProject/
+truffle unbox smartcontractkit/truffle-starter-kit
+```
+
+For instructions on how to use the starter kit, refer to the [Truffle starter kit README](https://github.com/smartcontractkit/truffle-starter-kit/blob/master/README.md).
+
+For more details on how to use Chainlink with Truffle, see our blog post about [Using Truffle to interact with Chainlink Smart Contracts](https://www.trufflesuite.com/blog/using-truffle-to-interact-with-chainlink-smart-contracts).
+
+---
+
+## DappTools Starter Kit
+
+To learn more about DappTools, refer to the [DappTools Documentation](https://dapp.tools/).
+
+1. Install Dapp tools using the [Installation instructions](https://github.com/dapphub/dapptools#installation) in the Dapp tools GitHub repository.
+
+1. After you install the tools, clone the starter kit and install the dependencies:
+
+ ```shell
+ git clone https://github.com/smartcontractkit/dapptools-starter-kit
+ cd dapptools-starter-kit
+ make # This installs the project's dependencies.
+ ```
+
+For instructions on how to use the starter kit, refer to the DappTools starter kit [README](https://github.com/smartcontractkit/dapptools-starter-kit#readme).
+
+For more details on how to use Chainlink with DappTools, see the [How To Use DappTools](https://blog.chain.link/how-to-use-dapptools/) blog post.
+
+---
+
+## Foundry Starter Kit
+
+To learn more about Foundry, refer to the [Foundry Documentation](https://onbjerg.github.io/foundry-book/).
+
+1. Install Foundry using the [Installation instructions](https://onbjerg.github.io/foundry-book/getting-started/installation.html) on GitHub.io.
+
+1. After you install Foundry, clone the starter kit and install the project dependencies:
+
+ ```shell
+ git clone https://github.com/smartcontractkit/foundry-starter-kit
+ cd foundry-starter-kit
+ make # This installs the project's dependencies.
+ ```
+
+For instructions on how to use the starter kit, refer to the [Foundry starter kit README](https://github.com/smartcontractkit/foundry-starter-kit#readme).
+
+---
+
+# Using Chainlink Contracts
+
+Once you have the Chainlink library installed, you can leverage the Chainlink ecosystem.
+
+If you're interested in retrieving up to date crypto prices in your contracts, learn more about our [Data Feeds](/data-feeds/).
+
+If you need to consume randomness in your contracts, learn about [Chainlink VRF](/vrf/v2/introduction/).
+
+And if you want your contracts to retrieve data from off-chain APIs, learn about [Using Any API](/any-api/introduction/).
+
+# Testing Chainlink Contracts
+
+See our blog post on [Testing Chainlink Smart Contracts](https://blog.chain.link/testing-chainlink-smart-contracts/) or watch the [Chainlink Hackathon Workshop](https://www.youtube.com/watch?v=d8SqLaH8pu0).
+
+Tests samples can be found on [Hardhat Starter Kit](https://github.com/smartcontractkit/hardhat-starter-kit/tree/main/test) and [Truffle Starter Kit](https://github.com/smartcontractkit/truffle-starter-kit/tree/master/test) respectively.
diff --git a/src/pages/resources/developer-communications.md b/src/pages/resources/developer-communications.md
new file mode 100644
index 00000000000..4d5fe94713d
--- /dev/null
+++ b/src/pages/resources/developer-communications.md
@@ -0,0 +1,23 @@
+---
+layout: ../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Developer Communications"
+permalink: "docs/developer-communications/"
+metadata:
+ title: "Developer Communications"
+ description: "We are committed to communicating these changes with you in advance. This page will provide information on our current communication channels and detail active notifications / upgrade plans with timelines."
+setup: |
+ import { DeveloperCommunicationsCallout } from "@features/resources"
+---
+
+The Chainlink Developer mailing list is the best place to stay up to date on
+
+- Releases
+- Package Updates
+- New Features
+- Breaking Changes
+- Events
+- Connecting with other developers
+
+
diff --git a/src/pages/resources/example-projects.md b/src/pages/resources/example-projects.md
new file mode 100644
index 00000000000..380bb46aaca
--- /dev/null
+++ b/src/pages/resources/example-projects.md
@@ -0,0 +1,132 @@
+---
+layout: ../../layouts/MainLayout.astro
+date: Last Modified
+title: "Example Projects"
+permalink: "docs/example-projects/"
+section: ethereum
+---
+
+# Hackathons
+
+The following is a list of selected hackathon projects utilizing Chainlinked contracts.
+
+## Hackathon Tutorials
+
+Further exploration into how some of the hackathon winners developed their entries.
+
+| Name | Description | Tutorial |
+| :----------------------- | :----------------------------------------------- | :------------------------------------------------------------------------------------------ |
+| **Link My Ride** | A decentralized Tesla rental platform. | [Go](https://blog.chain.link/create-tesla-smart-contract-rental/) |
+| **Open Library Project** | A library platform for borrowing books on-chain. | [Go](https://blog.chain.link/rfid-blockchain-integration-with-chainlink-external-adapters/) |
+| **Marine Insurance** | Parametric insurance for the marine industry. | [Go](https://blog.chain.link/build-a-marine-insurance-smart-contract-with-chainlink/) |
+| **Fruity Market** | Vending machine cryptocurrency payments. | [Go](https://blog.chain.link/cryptocurrency-vending-machine/) |
+| **Whiskey MarketMaker** | Craft whiskey crypto payments. | [Go](https://blog.chain.link/craft-whiskey-crypto-payments-with-chainlink-oracles/) |
+| **Digital Bridge** | Two factor authentication for smart contracts. | [Go](https://blog.chain.link/2fa-authentication-smart-contracts/) |
+| **Iroiro** | Fetch IPFS Data in Smart Contracts. | [Go](https://blog.chain.link/fetch-ipfs-api-data-token-distribution/) |
+
+## Chainlink Spring 2021 Hackathon
+
+The [Chainlink Spring 2021 Hackathon](https://chain.link/hackathon/spring-2021), read our [blog here!](https://blog.chain.link/congratulations-to-the-spring-2021-chainlink-virtual-hackathon-winners/)
+
+| Name | Description | GitHub |
+| :--------------------------------- | :-------------------------------- | :-------------------------------------------------------------------------------- |
+| **deBridge** 🥇 | Cross-chain defi primative | [Go](https://github.com/debridge-finance) |
+| **Vulcan Exchange** 🥇 | Weather derivatives defi platform | [Go](https://github.com/Vulcan-Exchange?ref=block123) |
+| **DeFi Lending Insurance** 🥇 | DeFi Lending Insurance | [Go](https://github.com/chainlink-hackathon2021-insurance/DeFi-Lending-Insurance) |
+| **Fract** 🥇 | Dynamic NFT no-code UI creator | |
+
+## ETH Global's ETHOnline 2020
+
+The [ETH Online](https://ethglobal.online/), read our [blog here!](https://blog.chain.link/ethonline-2020-chainlink-hackathon-winners/)
+
+| Name | Description | GitHub |
+| :-------------------- | :-------------------------------------------------- | :------------------------------------------------------- |
+| **Iroiro** 🥇 | Decentralized Creators Support Platform. | [Go](https://github.com/TART-tokyo/iroiro) |
+| **Overlay** 🥇 | Long/Short data stream derivatives. | [Go](https://github.com/overlay-market/overlay-protocol) |
+| **Rupia** 🥇 | An Indian Rupee (INR) Stablecoin Derivative. | [Go](https://github.com/vijayengineer/rupia) |
+| **SecretPay** 🥇 | Buy ETH Privately From PayPal and Revolut. | [Go](https://github.com/franono/ethglobal) |
+| **Unipeer** 🥇 | Fiat to Ethereum On-Ramp Using an Open Banking API. | [Go](https://github.com/unipeer/unipeer) |
+
+## Chainlink Hackathon 2020
+
+The [Chainlink Hackathon](https://chain.link/hackathon/2020), read our [blog here!](https://blog.chain.link/congratulations-to-the-winners-of-the-chainlink-virtual-hackathon-2020/)
+
+| Name | Description | GitHub |
+| :------------------------------- | :---------------------------------------------------- | :-------------------------------------------------------- |
+| **Link My Ride** 🥇 | A decentralized Tesla rental platform. | [Go](https://github.com/pappas999/Link-My-Ride) |
+| **Farm Together** 🥇 | A farming game where you can earn real yield in defi. | [Go](https://github.com/johhonn/realyield.farm-contracts) |
+| **Open Library Project** 🥇 | A library platform for borrowing books on-chain. | [Go](https://github.com/amoghaddassi/open-library) |
+
+## ETHGlobal Hack Money
+
+The [Hack Money hackathon](https://ethglobal.online/), read our [blog here!](https://blog.chain.link/showcasing-the-winners-of-the-2020-hackmoney-virtual-hackathon/)
+
+| Name | Description | GitHub |
+| :--------------------- | :------------------------------------------------------------------- | :-------------------------------------------------- |
+| **Genie** 🥇 | A no-loss betting platform for gamers. | [Go](https://github.com/genie-platform) |
+| **DefiDollar** 🥈 | DefiDollar (DUSD) is a stablecoin backed by Curve Finance LP tokens. | [Go](https://github.com/defidollar/defidollar-core) |
+| **CandyShop** 🥉 | Lottery based arbitrage. | [Go](https://github.com/itsthecandyshop/) |
+
+## ETHDenver 2020
+
+Read our [blog post here](https://blog.chain.link/showcasing-the-winning-projects-from-the-ethdenver-2020-hackathon/).
+
+| Name | Description | GitHub |
+| :---------------------------- | :--------------------------------------------------------------------------------------------- | :-------------------------------------------------------------- |
+| **InsuraLink** 🥇 | Data-driven insurance agreements that use Chainlink oracles to bridge IoT and smart contracts. | [Go](https://github.com/mycelium-ethereum/insuralink-contracts) |
+| **1x.ag** 🥈 | Build leveraged trade positions across different lending platforms. | [Go](https://github.com/1x-ag/solidity-contracts) |
+| **We Watch in Public Spaces** | Tracking system for calculating event attendance. | [Go](https://github.com/iainnash/ethdenver-we-watch-in-public) |
+
+## Chainlink Virtual Hackathon 2019
+
+Read our [blog post here](https://blog.chain.link/winners-of-the-chainlink-virtual-hackathon/).
+
+| Name | Description | GitHub |
+| :---------------------------- | :--------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------- |
+| **LinkPal** 🥇 | A smart contract uses Chainlink oracles to confirm that the PayPal invoice has been paid. | [Go](https://github.com/vvoluom/LinkPal) |
+| **Cerebus Wallet** 🥈 | Two-factor authorization for crypto transactions using phone push notifications. | [Go](https://github.com/MikaelLazarev/cerberus) |
+| **Flyt** 🥉 | Flight insurance. | [Go](https://github.com/robin-thomas/flyt) |
+| **Link Total Return Swap** | A Defi platform which enables Chainlink Node Operators to hedge against LINK price volatility. | [Go](https://github.com/mycelium-ethereum/LinkTRS) |
+| **Smart Marketing Campaigns** | Use Google Analytics data to make payments to marketing agencies. | [Go](https://coinlist.co/build/chainlink/projects/6106f616-f9d8-4fec-85d7-c9f98bf8bd9e) |
+| **Steam Trader** | Trustless trading of digital items. | [Go](https://github.com/brent-riva/Steam-Trader) |
+| **Contractor** | Constructor of smart contracts. | [Go](https://github.com/alekcangp/ChainLinkContractor) |
+| **Fiat Gateway** | Crypto Fiat Gateway on Ethereum using Chainlink Oracles | [Go](https://github.com/chatch/fiat-gateway) |
+| **The Anti-Social Challenge** | Incentivize people to reduce their usage of social platforms. | [Go](https://github.com/raphpap/smart-inactivity-agreement) |
+
+## ETHBerlin 2019
+
+Read our [blog post here](https://blog.chain.link/showcasing-the-winners-of-the-etherlin-zwei-hackathon/).
+
+| Name | Description | GitHub |
+| :--------------------------------- | :------------------------------------------------------ | :--------------------------------------------------- |
+| **Chainlink \u2661 Augur** 🥇 | Create derivatives based on the valuations of startups. | [Go](https://github.com/jasperdg/flux-ethberlinzwei) |
+| **VollgasDAO** 🥈 | Gas futures. | [Go](https://devpost.com/software/vollgas-futures) |
+| **Etherflare** 🥉 | Reward white hat hackers. | [Go](https://github.com/EtherFlareGraph/etherflare) |
+
+## ETHNewYork 2019
+
+Read our [blog post here](https://blog.chain.link/showcasing-the-winning-projects-from-the-ethnewyork-hackathon/).
+
+| Name | Description | GitHub |
+| :----------------------------- | :-------------------------------------------------------------- | :------------------------------------------------------------ |
+| **French Toast Kitty** 🥇 | Interact with your Cryptokitty using real-world data. | [Go](https://github.com/frenchtoastkitty/contracts) |
+| **Blocksolid** | Donations that pay for Internet services in developing regions. | [Go](https://github.com/unicef-isp-manager/eth-new-york-2019) |
+
+## ETHParis 2019
+
+Read our [blog post here](https://blog.chain.link/the-winning-projects-from-ethparis-hackathon/).
+
+| Name | Description | GitHub |
+| :------------------- | :------------------------------------------------------------------------ | :--------------------------------------------------- |
+| **Nanti** 🥇 | Issue and use corporate bonds as collateral for instant payment channels. | [Go](https://github.com/cryptotuxorg/nanti-dapp) |
+| **SmartKek** 🥈 | Burn tokens to leave comments. | [Go](https://github.com/smartkek/ETHParis-graveyard) |
+
+## ETHDenver 2019
+
+Read our [blog post here](https://blog.chain.link/detailing-the-winning-chainlink-projects-from-ethdenver-hackathon/).
+
+| Name | Description | GitHub |
+| :---------------------- | :---------------------------------------------------------------------------- | :------------------------------------------------- |
+| **EventLINK** 🥇 | Crowdfund events using Twitter APIs, smart contracts, and staking mechanisms. | [Go](https://github.com/ConnorMaloney/EventLink) |
+| **Grand Fondo** 🥈 | Decentralized athletic competitions using Strava. | [Go](https://github.com/tokensoft/gran-fondo) |
+| **Smart Piggies** | Peer-to-peer global derivatives market. | [Go](https://github.com/smartpiggies/smartpiggies) |
diff --git a/src/pages/resources/fund-your-contract.md b/src/pages/resources/fund-your-contract.md
new file mode 100644
index 00000000000..d3c2dcba7f1
--- /dev/null
+++ b/src/pages/resources/fund-your-contract.md
@@ -0,0 +1,35 @@
+---
+layout: ../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Fund Your Contracts"
+permalink: "docs/fund-your-contract/"
+---
+
+Some smart contracts require funding at their addresses so they can operate without you having to call functions manually and pay for the transactions through MetaMask. This guide explains how to fund Solidity contracts with LINK or ETH.
+
+## Retrieve the contract address
+
+1. In Remix, deploy your contract and wait until you see a new contract in the **Deployed Contracts** section.
+1. On the left side panel, use the **Copy** button located near the contract title to copy the contract address to your clipboard.
+
+
+
+## Send funds to your contract
+
+1. Open MetaMask.
+1. Select the network that you want to send funds on. For example, select the Goerli testnet.
+1. Click the **Send** button to initiate a transaction.
+1. Paste your contract address in the address field.
+1. In the **Asset** drop down menu, select the type of asset that you need to send to your contract. For example, you can send LINK. If LINK is not listed, follow the guide to [Acquire testnet LINK](/resources/acquire-link/).
+1. In the **Amount** field, enter the amount of LINK that you want to send.
+1. Click **Next** to review the transaction details and the Gas cost.
+1. If the transaction details are correct, click **Confirm** and wait for the transaction to process.
+
+
+
+:::caution[ Transaction fee didn't update?]
+
+You may need to click **Fastest**, **Fast**, **Slow**, or **Advanced Options** after entering the **Amount** to update the gas limit for the token transfer to be successful.
+
+:::
diff --git a/src/pages/resources/getting-help.md b/src/pages/resources/getting-help.md
new file mode 100644
index 00000000000..9df22e7900a
--- /dev/null
+++ b/src/pages/resources/getting-help.md
@@ -0,0 +1,102 @@
+---
+layout: ../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Getting Help"
+permalink: "docs/getting-help/"
+---
+
+## Where do I go to get help and support?
+
+If you run into issues and the available documentation, videos, and code repositories are not able to assist you, the best way to get help is to follow the support escalation process in this document. Sometimes you might have a question that is too theoretical or hasn't been solved, so you might not always get what you're looking for!
+
+## 1. Double check the documentation
+
+Check to see if you missed any code, documentation, blog, or video on the topic or issue you're looking for. There are typically a few different resources on a topic if one doesn't answer exactly what you're looking for. You can also use the documentation search bar to look up things as well.
+
+## 2. Do a web search for the specific error or situation you're in
+
+Often someone else has asked the same question that you're asking. If you copy and paste the error into the Google or web search bar, there is a good chance that you will find some helpful material from someone else who has already found the solution to your question.
+
+## 3. Open an issue on GitHub or the code repository
+
+This is only applicable if you're working with a certain set of code. For example, if you're having an issue working with the [Chainlink Hardhat Starter kit](https://github.com/smartcontractkit/hardhat-starter-kit), open an issue on the repo explaining exactly what's going on and someone might have the answer that you need.
+
+When writing issues, remember to:
+
+- Keep titles short
+- Be clear and concise about the issue that you are encountering
+- Format your issue description. Use [three backticks (```)](https://www.freecodecamp.org/news/how-to-format-code-in-markdown/#code-blocks) to format your code or log output.
+- Always add any and all associated code
+- Don't use screenshots. Screenshots are not searchable and generally make it harder to understand your issue.
+
+## 4. Ask a question on [Stack Overflow](https://stackoverflow.com/questions/ask?tags=chainlink) or [Stack Exchange Ethereum](https://ethereum.stackexchange.com/)
+
+This is where most people will end up and is one of the most helpful resources out there. Stack Overflow is living documentation, so do your best to make a [thoughtful and easy to triage question](https://stackoverflow.com/help/how-to-ask). This will make it much easier for people to help debug your issue and ensure it doesn't get removed from the site. Remember, we want to make this question **searchable** so others who run into the same issue can also get their question solved. You could use any forum-based site you like if you prefer another site over Stack Overflow.
+
+Here is an example of a poorly formatted question:
+
+:::note
+
+Title: Please help
+
+I'm following this guide, and my code is breaking, what's going on?
+
+https://docs.chain.link/
+
+Here is my code
+
+```
+pragma solidity 0.6.7; contract HelloWorld { string public message; constructor(string memory initialMessage) {message = initialMessage; }`
+```
+
+:::
+
+Here is that same question with better formatting:
+
+:::note
+Title: Remix Solidity Compile Error - Source File Requires Different Compiler Version
+
+I'm [following this guide](/getting-started/deploy-your-first-contract/), and I'm unable to compile my solidity code in [Remix](https://remix.ethereum.org/).
+
+Here is the code:
+
+```solidity
+pragma solidity 0.6.7;
+
+contract HelloWorld {
+ string public message;
+
+ constructor(string memory initialMessage) {
+ message = initialMessage;
+ }
+
+ function updateMessage(string memory newMessage) public {
+ message = newMessage;
+ }
+}
+
+```
+
+And the error I'm getting is as follows:
+
+```
+ParserError: Source file requires different compiler version (current compiler is 0.8.7+commit.e28d00a7.Emscripten.clang) - note that nightly builds are considered to be strictly less than the released version
+--> contracts/test.sol:1:1:
+|
+1 | pragma solidity 0.6.7;
+| ^^^^^^^^^^^^^^^^^^^^^^
+
+```
+
+:::
+
+It's best to create a [minimum reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) to help others understand your issue. This way, they can help you get an answer quickly. Remember, its a community-run platform!
+
+Don't get discouraged if your question gets downvoted or removed. This just means you need to format your question a little differently next time!
+
+## 5. Ask the community
+
+And lastly, you can always ask the question in the [Discord](https://discord.gg/2YHSAey) and see if there is a community member who might be able to help you out. One of the best ways to ask the community is to drop a link to your Stack Overflow question, issue, or the forum where you're asking a Chainlink question. Remember, these are community members, and they are helping because they are wonderful and kind individuals!
+
+For important updates regarding the use of Chainlink Price Feeds, users should join the official Chainlink Discord and subscribe to the data-feeds-user-notifications channel: https://discord.gg/Dqy5N9UbsR
diff --git a/src/pages/resources/glossary.md b/src/pages/resources/glossary.md
new file mode 100644
index 00000000000..40d387b6fa0
--- /dev/null
+++ b/src/pages/resources/glossary.md
@@ -0,0 +1,130 @@
+---
+layout: ../../layouts/MainLayout.astro
+date: Last Modified
+title: "Glossary"
+permalink: "docs/glossary/"
+section: ethereum
+---
+
+### Adapter
+
+:::danger[ The adapters or JSON adapters for v1 Jobs are removed for Chainlink nodes running version 1.0.0 and later. Use [v2 job tasks](/chainlink-nodes/oracle-jobs/task-types/tasks/) instead.]
+
+:::
+
+An adapter or [task](#task) is a piece of software responsible for executing a specific piece of functionality. A Chainlink node comes with a number of Adapters built-in, commonly known as Core Adapters, but can also be extended via [Bridges](/chainlink-nodes/external-adapters/node-operators/) to connect with user-defined [External Adapters](#external-adapter).
+
+### Answer
+
+The result produced from an oracle service, after all safety checks and aggregations have been performed.
+
+### Bridge
+
+Bridge is the connection between a Chainlink node and an [External Adapter](#external-adapter). The External Adapter runs as a separate [service](https://en.wikipedia.org/wiki/Service-oriented_architecture), and a Bridge facilitates communication between the node and one of these adapters.
+
+If you would like to add a new External Adapter to your node, you create a new Bridge either in the GUI or the CLI. Within the Chainlink node, a bridge must have a unique name, but can share the same URL with other bridges. You can also set a different number of default confirmations for each bridge, and an additional payment amount. Once the bridge is added to the node, its name can then be used as a task type in [Jobs](/chainlink-nodes/oracle-jobs/jobs/).
+
+### Consumer (Contract)
+
+Recipient of an [Answer](#answer) provided by an [Oracle](#oracle). The Consumer is commonly a contract, and is also commonly the same [entity that requested the Answer](#requester), but does not have to be. We have a helper function, ` addExternalRequest`, that gives consuming contracts the ability to safely check answers it receives without requesting them itself.
+
+### Encumbrance Parameters
+
+Encumbrance parameters are the part of a [service agreement](#service-agreement) that can be enforced on-chain. Information on encumbrance parameters can be found on our Wiki .
+
+### External Adapter
+
+[External adapters](https://github.com/smartcontractkit/chainlink/wiki/External-Adapters) are what make Chainlink easily extensible, providing simple integration of custom computations and specialized APIs.
+
+A Chainlink node communicates with external adapters by sending a POST request with a JSON data payload. More information can be found on the external adapter [page](/chainlink-nodes/external-adapters/external-adapters).
+
+### Function Selector
+
+A [function selector](https://docs.soliditylang.org/en/develop/abi-spec.html#function-selector) specifies the function to be called in Ethereum. It is the first four bytes of the call data for a function call in an Ethereum transaction. Solidity contracts have a built-in helper method to access the function selector by using `this.myFunction.selector`, where `myFunction` is a non-overloaded function in the contract.
+
+### Initiator
+
+:::danger[ The initiators for v1 Jobs are removed for Chainlink nodes running version 1.0.0 and later. Use the [v2 job types](/chainlink-nodes/oracle-jobs/jobs/) instead.]
+
+:::
+
+Triggers the execution of a [Job Spec](#job-spec).
+
+### Job
+
+Short-hand for a [Job Spec](#job-spec).
+
+### Job Run
+
+The Job Run is the artifact documenting the outcome of executing a [Job](#job). The Job Run is made up of a [Task](#task) and a [Run Result](#run-result) representing the ultimate outcome of the Job Run.
+
+### JobID
+
+The ID associated to a given [Job Spec](#job-spec). This will be unique per-node, even with the same contents within the spec itself.
+
+### Job Spec
+
+The [Job Specification](/chainlink-nodes/oracle-jobs/jobs/) is the specification of a piece of work to be completed by an Oracle Node. The Job Spec is made up of two main parts:
+
+- The [Task Type](/chainlink-nodes/oracle-jobs/jobs#shared-fields) or the [External Initiator](/chainlink-nodes/external-initiators/external-initiators-introduction/): Defines the ways a Job can be triggered to execute.
+- The [Task list](#task-spec): The `tasks` that specify all of the computation steps to perform when executing a Job Spec. The Task list is sometimes referred to as the [Job Pipeline](/chainlink-nodes/oracle-jobs/task-types/pipelines) because all of the Tasks' operations are performed in order, with the result being fed into the next task.
+
+### Oracle
+
+Entity which connects computations on blockchains with off-chain resources. Typically made up of two components: the [Oracle Node](#oracle-node) (off-chain) and the [Oracle Contract](#oracle-contract) (on-chain).
+
+### Oracle Contract
+
+The on-chain component of an [Oracle](#oracle). The Oracle Contract is the interface through which [Consuming Contracts](#consumer-contract) pass and receive data with off-chain resources.
+
+### Oracle Node
+
+The off-chain component of an [Oracle](#oracle).
+
+### Phase
+
+For data feeds, a phase indicates the underlying aggregator implementation has been updated. Phases are relevant only for the EACAggregatorProxys. You can think of a roundId on the proxies as a large number containing data for two numbers (phaseId + roundId). The roundId is pulled from the aggregator's implementation and combined by bit shifting with the latest phaseId of the proxy.
+
+### Requester
+
+A Smart Contract or Externally Owned Account which requests data from an [Oracle](#oracle). The Requester does not have to be the same entity as the [Consumer](#consumer-contract) but commonly is the same.
+
+### Run Result
+
+A Run Result is the result of executing a [Job Spec](#job-spec).
+
+### Run Status
+
+Each [Job Run](#job) has a status field indicating its current progress. The Run Status can be in one of the [following states](https://godoc.org/github.com/smartcontractkit/chainlink/core/store/models/#pkg-constants):
+
+- Unstarted
+- In Progress
+- Pending Confrimations
+- Pending Bridge
+- Pending Sleep
+- Errored
+- Completed
+
+### SAID
+
+The ID associated with a given [Service Agreement](#service-agreement).
+
+### Service Agreement
+
+The Service agreement consists of a [Job Spec](#job-spec) and a set of [encumbrance parameters](#encumbrance-parameters) that is shared among a creator and multiple Chainlink nodes. Information on service agreements can be found [on our Wiki](https://github.com/smartcontractkit/chainlink/wiki/Service-Agreements-and-the-Coordinator-Contract).
+
+### Spec
+
+Another short-hand for a [Job Spec](#job-spec).
+
+### Task
+
+A v2 job [task](/chainlink-nodes/oracle-jobs/task-types/tasks/).
+
+### Task Spec
+
+The Task Spec is the definition for an individual task to be performed within the [job specification](/chainlink-nodes/oracle-jobs/jobs/) by a specific adapter. The Task Spec always includes a `type` field which specifies which [adapter](#adapter) will execute it. Optionally, a Task Spec can specify additional `params` which will be passed on to its adapter, and `confirmations` which specify how many confirmations a [Task Run](#task-run) needs before executing.
+
+### Task Run
+
+The result of the individual [Task Spec](#task-spec)'s execution. A Task Run includes the Task Spec that it used for input and the [Run Result](#run-result) which was the output of the execution.
diff --git a/src/pages/resources/hackathon-resources.md b/src/pages/resources/hackathon-resources.md
new file mode 100644
index 00000000000..5f4af48c224
--- /dev/null
+++ b/src/pages/resources/hackathon-resources.md
@@ -0,0 +1,73 @@
+---
+layout: ../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Hackathon Resources"
+permalink: "docs/hackathon-resources/"
+---
+
+:::note[ Note on Resources]
+
+For a comprehensive list of resources, refer to the [Learning Resources](/getting-started/other-tutorials/) page.
+
+:::
+
+### Hackathon & Project Resources
+
+If you're looking to just start jumping into stuff, here is a directory that can help you out.
+
+# Want to check out winners code of past hackathons to get some inspiration?
+
+Check out the example winners projects here.
+
+## Boilerplate code, and starter kits
+
+Be sure to check the docs above for remix examples!
+
+- [Chainlink Brownie Starter Kit (Python)](https://github.com/smartcontractkit/chainlink-mix)
+- [Chainlink Truffle Starter Kit (Javascript)](https://github.com/smartcontractkit/truffle-starter-kit)
+- [Chainlink Hardhat Starter Kit (Javascript)](https://github.com/smartcontractkit/hardhat-starter-kit)
+
+## Support Communications
+
+Always refer back to the [getting help](/resources/getting-help) page for the latest information about how to get support.
+
+- [Getting Help](/resources/getting-help)
+- [Stack Overflow](https://stackoverflow.com/questions/tagged/chainlink)
+- [Stack Exchange Ethereum](https://ethereum.stackexchange.com/questions/tagged/chainlink)
+- [Hackathon Discord](https://discord.gg/h3AvTHj)
+- [Developer Discord](https://discord.gg/2YHSAey)
+
+## Tutorials
+
+Be sure to check the documentation in the links above for in depth-descriptions of everything.
+
+New? See the [Getting Started Guide](/getting-started/conceptual-overview/).
+
+- [Video Tutorials](https://www.youtube.com/playlist?list=PLVP9aGDn-X0QwJVbQvuKr-zrh2_DV5M6J)
+- [What is Ethereum?](https://www.youtube.com/playlist?list=PLVP9aGDn-X0QwJVbQvuKr-zrh2_DV5M6J)
+- [Developer Blog (many tutorials)](https://blog.chain.link/tag/developers/)
+- [Testing Chainlink Smart Contracts](https://blog.chain.link/testing-chainlink-smart-contracts/)
+- [NFTs and Chainlink](https://blog.chain.link/build-deploy-and-sell-your-own-dynamic-nft/)
+- [Build an external adapter](/chainlink-nodes/external-adapters/developers/)
+
+## Inspiration
+
+- [77 Use Cases by Chainlink](https://blog.chain.link/44-ways-to-enhance-your-smart-contract-with-chainlink/)
+- [Past winners & code](/resources/example-projects/)
+- [Chainlink docs](/)
+
+### The chainlink community is some of the most inviting groups of engineers always looking to help you grow to the next stage.
+
+# Join the community
+
+- [Twitter](https://mobile.twitter.com/chainlink)
+- [Reddit](https://www.reddit.com/r/Chainlink/)
+- [Telegram](https://t.me/chainlinkofficial)
+- [Blog](https://blog.chain.link)
+
+## Blockchain Specific
+
+- [Matic Data Feeds](/data-feeds/price-feeds/addresses/?network=polygon)
+- [BNB Chain Data Feeds](/data-feeds/price-feeds/addresses/?network=bnb-chain)
+- [Conflux](https://github.com/Conflux-Network-Global/demo-cfx-chainlink)
diff --git a/src/pages/resources/hackathon-rules-waiver-and-release.md b/src/pages/resources/hackathon-rules-waiver-and-release.md
new file mode 100644
index 00000000000..c44678ff35a
--- /dev/null
+++ b/src/pages/resources/hackathon-rules-waiver-and-release.md
@@ -0,0 +1,61 @@
+---
+layout: ../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Hackathon Rules, Waiver & Release, and Code of Conduct"
+permalink: "docs/hackathon-rules-waiver-release-and-code-of-conduct/"
+---
+
+**Code of Conduct**
+
+This event is a community hackathon intended for collaboration and learning in the Chainlink and broader blockchain communities. We value the participation of each member of the community and want all participants to have an enjoyable experience. Accordingly, all participants are expected to show respect and courtesy to other participants throughout the hackathon. To make clear what is expected, all participants of this hackathon are required to conform to the following Code of Conduct. Organizers will enforce this code throughout the event.
+
+##### **The Code**
+
+The spirit of The Code is to prohibit activities including but not limited to:
+
+- Comments that others find offensive
+- Cheating or taking unfair advantage of other participants’ work or efforts
+- Any activity related to harassing, demeaning, mocking, or intimidating others, especially this behavior as it relates to characteristics such as:
+ - Gender
+ - Sexual orientation
+ - Physical or mental ability
+ - Age
+ - Socioeconomic status
+ - Ethnicity
+ - Physical appearance
+ - Race
+ - Religion
+ - Country of origin
+- Examples of other prohibited behaviors include, but are not limited to:
+ - Stalking
+ - Unwanted sexual attention
+ - Use of sexualized content
+
+Participants asked to stop any behavior deemed as harassment are expected to comply immediately. If a participant fails to comply they will be asked to leave the event. Sponsors, judges, mentors, volunteers, organizers, Chainlink team, and anyone else at the event are also subject to the Code.
+
+If a participant engages in behavior that violates the Code, the hackathon organizers will take any action they deem appropriate, including warning the offender or expelling them from the event.
+
+If you feel uncomfortable or think there may be a potential violation of the code of conduct, please report it immediately to one of the event organizers or by emailing us at legal@chain.link. All reporters have the right to remain anonymous.
+
+##### **Event Rules & Conditions**
+
+1. The following rules & conditions (the “Rules”) apply to this Chainlink hackathon (the “Event"). By clicking the “I Accept” button, you acknowledge that you have read these Rules, understand them, and agree to be bound as follows:
+1. You assume full responsibility for any damage or injury caused by you in your participation in the Event (whether to persons or property, and whether to yourself or others) and release SmartContract Chainlink Limited SEZC (and its affiliates) (“Chainlink”), the Event, the organizers of the Event (the “Organizers”), all sponsors of the Event (“Sponsors”), the Event volunteers and the Event staff, (collectively, the “Releasees”) from any liability therefore. **YOU ARE AWARE THAT YOUR PARTICIPATION IN THE EVENT IS SOLELY AT YOUR OWN RISK, AND THAT THE RELEASE HEREIN IS INTENDED TO REFLECT THAT UNDERSTANDING**
+1. You will own any developments that you create during the Event, and all right, title and interest in those developments, including the intellectual property rights therein, shall belong to you. However, you acknowledge that during the course of the Event, you may obtain access to products, developments, information and other materials belonging to Chainlink, other participants of the Event, the Sponsors and/or other third parties (“Third Party Materials”), and that nothing in this Agreement is deemed to transfer any ownership, right, title or interest in such Third Party Materials to you. Your only rights to the Third Party Materials shall be those expressly granted to you by the owner(s) of the Third Party Materials. Specifically, any APIs or other software provided to you by the Sponsors are subject to the subscription terms and software licenses associated with such APIs or other software.
+1. By entering this Event, you represent and warrant that your participation complies with these Rules and that you have sufficient rights to (1) authorize the publication and dissemination of any submission materials and presentations (“Submitted Materials”); (2) allow the Organizers and Sponsors to use and to authorize others to use, publish and disseminate your Submitted Materials. Further, you are entirely responsible for your Submitted Materials, in whole or in part, if: (a) determined to be defamatory, offensive or otherwise inappropriate; (b) determined to violate any laws, rules or regulations; (c) determined to be infringing, or constitute a misappropriation of any intellectual property rights or confidential or proprietary information of any third party; or (d) determined to violate these Rules. Your Submitted Materials must be true and accurate and in compliance with these Rules in all regards. At any time, the Organizers at their sole discretion, reserve the right to remove your Submitted Materials from the Event, in whole or in part, for any violation of these Official Rules.
+1. You acknowledge that the Event is intended to be a place where ideas are shared freely, and therefore acknowledge that any information that you share with other participants of the Event, the Sponsors and/or other third parties during the Event is solely at your discretion and risk. If you wish to protect your information, it is solely your responsibility to implement confidentiality and security measures with respect to the persons to whom you are disclosing your information. None of the Releasees shall have any responsibility under this Agreement or by virtue of their participation in the Event with respect to your information.
+1. You acknowledge that the Organizers and Chainlink have the right to reject participants in the Event at their sole discretion.
+1. The Organizers have the unrestricted right to use your likeness, image, voice, opinions, and appearance, and also any images of your projects, developments, materials and belongings made at or brought to the Event, captured through video, photographs or other media during the Event for the express purpose of creating promotional material (the “Images”), for the purposes of use in websites, promotional materials, publications and other media of any of the Organizers, whether in print or electronically (the “Materials”). The foregoing right includes permission to copyright, use, re-use, publish, and republish Images in which you may be included, intact or in part, composite or distorted in character or form, without restriction as to changes or transformations, in conjunction with your own or a fictitious name, reproduction in color or otherwise, made through any and all media now or hereafter known;
+ 1. The Organizers shall solely own the Materials in which you or your Images, in whole or in part, may appear, including copyright interests, and you have no ownership rights therein;
+ 1. You give all clearances, copyright and otherwise, for use of your Images, and waive any moral rights that you may have in the Materials in which you or your Images may appear. The rights granted to the Organizers herein are perpetual and worldwide. For greater certainty, you agree that your images may continue to be used after the completion of the Event;
+ 1. You relinquish any right that you may have to examine or approve the Materials in which you or your Images may appear or the use to which they may be applied; and
+ 1. You hereby release, discharge and agree to save harmless each and all of the Organizers from any liability by virtue of any blurring, distortion, alteration, optical illusion, or use in composite form of the Images whether intentional or otherwise, that may occur or be produced in the recording of the Images or in any subsequent processing thereof, as well as any publication thereof, including without limitation any claims for libel or invasion of privacy.
+1. You agree that the Organizers may share your registration details, LinkedIn/Github profiles, details of your Hackathon submission, and other information obtained from you in the course of, or relating to, the Event with the Sponsors, and acknowledge that such Sponsors may contact you during and after the Event. By agreeing to this document and/or participating in the Event, you are providing your express consent to communications by the Organizers and Sponsors (including email communications, both marketing and informational) respecting the products and services of the Organizers and Sponsors, and future events.
+1. For valuable consideration, including permission to take part in the Event, you hereby covenant not to sue, and release, waive, and discharge the Releasees, their owners, officers, agents, affiliates, employees, volunteers, and/or any other person or entity in any way associated with the Event, from liability for any injury to your person or property or death arising out of or related to your participation in the Event, whether caused by an act of negligence of the Releasees or otherwise; and hereby assume full responsibility for any risk of bodily injury, death or property damage arising out of or related to your participation in the Event, whether occurring to you or to any other person or entity for whom you are responsible or with whom you are associated, and whether caused by an act of negligence of the Releasees or otherwise. The foregoing release includes, but is not limited to, any occurrences of personal injury, illness (food-borne or otherwise), and loss of belongings, whether by theft or otherwise. You further agree that this instrument (the terms of which collectively are referred to as the Rules) is intended to be as broad and inclusive as is permitted by the laws of the State of California and that if any portion thereof is held invalid, that portion shall be invalid only to the extent required by law, and the balance shall, notwithstanding, continue in full force and effect.
+1. You agree to indemnify and hold the Organizers and Sponsors (and judges, mentors, volunteers, organizers, Chainlink team administering the Event) and each of their employees, representatives, agents, attorneys, affiliates, directors, employees, officers, managers, and shareholders (the “Indemnified Parties”) harmless from any damage, loss, cost, or expense (including without limitation, attorneys’ fees and costs) incurred in connection with any third-party claim, demand, or action (“Claim”) brought or asserted against any of the Indemnified Parties, alleging facts or circumstances that would constitute a breach of any provision of the these Rules by you; arising from, related to, or connected with your entry, Submitted Materials, presentations and participation in any way in any aspect of Event , including receipt of any prize. If you are obligated to provide indemnification pursuant to this provision, the Indemnified Parties may, in their sole discretion, control the disposition of any claim at your sole cost and expense. Without limitation of the foregoing, you may not settle, compromise, or in any other manner dispose of any claim without the Organizers’s express written consent.
+1. If selected as a winner of a Chainlink award, your acceptance of the Chainlink award means you agree to the following:
+ 1. You will not disparage Chainlink or its products, services, agents, representatives, directors, officers, shareholders, attorneys, employees, vendors, business partners, affiliates, successors or assigns, or any person acting by, through, under or in concert with any of them, with any written or oral statement. Nothing in this paragraph shall prohibit the winner from providing truthful information in response to a valid subpoena or other legal process; however, the winning participant agrees to provide Company sufficient notice of such to allow Company the opportunity to oppose such subpoena or legal process prior to providing any information (unless expressly prohibited by applicable law).
+ 1. You agree that awards are subject to availability and Chainlink and the Sponsors reserve the right to substitute or withdraw any prize without giving notice at their sole discretion.
+ 1. Any media, such as a blog post, that is created about winning the Event, will first be shared with the Chainlink team beforehand so that we can coordinate and help you spread the message.
+ 1. You agree to an interview with a writer affiliated with the Chainlink team, which will result in featuring your project on the Chainlink website and sharing your project with the greater community.
diff --git a/src/pages/resources/link-token-contracts.md b/src/pages/resources/link-token-contracts.md
new file mode 100644
index 00000000000..5af3113e9c3
--- /dev/null
+++ b/src/pages/resources/link-token-contracts.md
@@ -0,0 +1,342 @@
+---
+layout: ../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "LINK Token Contracts"
+permalink: "docs/link-token-contracts/"
+metadata:
+ title: "LINK Token Contracts"
+ description: "Addresses for the LINK token on supported networks."
+ linkToWallet: true
+ image:
+ 0: "/files/72d4bd9-link.png"
+---
+
+LINK tokens are used to pay node operators for retrieving data for smart contracts and also for deposits placed by node operators as required by contract creators. The smallest denomination of LINK is called a Juel, and 1,000,000,000,000,000,000 (1e18) Juels are equal to 1 LINK. This is similar to Wei, which is the [smallest denomination of ETH](https://ethereum.org/en/developers/docs/intro-to-ether/#denominations).
+
+The LINK token is an ERC677 token that inherits functionality from the ERC20 token standard and allows token transfers to contain a data payload. Read more about the [ERC677 transferAndCall token standard](https://github.com/ethereum/EIPs/issues/677).
+
+## Ethereum
+
+### Ethereum Mainnet
+
+| Parameter | Value |
+| :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `1` |
+| Address | `0x514910771AF9Ca656af840dff83E8264EcF986CA` |
+| Name | Chainlink Token |
+| Symbol | LINK |
+| Decimals | 18 |
+| Network status | [ethstats.net](https://ethstats.net/) |
+
+### Goerli testnet
+
+Testnet LINK is available at [faucets.chain.link](https://faucets.chain.link/goerli). Testnet ETH is available at [goerlifaucet.com](https://goerlifaucet.com/) or the faucets listed at [faucetlink.to/goerli](https://faucetlink.to/goerli).
+
+| Parameter | Value |
+| :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `ETH_CHAIN_ID` | `5` |
+| Address | `0x326C977E6efc84E512bB9C30f76E30c160eD06FB` |
+| Name | Chainlink Token |
+| Symbol | LINK |
+| Decimals | 18 |
+
+## BNB Chain
+
+### BNB Chain mainnet
+
+BNB is used to pay for transactions on the BNB Chain mainnet.
+
+:::caution[ ERC-677 LINK on BNB Chain]
+
+The LINK provided by the [BNB Chain Bridge](https://www.bnbchain.world/en/bridge) is not ERC-677 compatible, so you cannot use it with Chainlink services or oracle nodes. Use the [**Chainlink PegSwap service**](https://pegswap.chain.link/) to convert bridged LINK to the official ERC-677 LINK token on BNB Chain.
+
+:::
+
+| Parameter | Value |
+| :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `56` |
+| Address | `0x404460C6A5EdE2D891e8297795264fDe62ADBB75` |
+| Name | Chainlink Token |
+| Symbol | LINK |
+| Decimals | 18 |
+| Network status | [bscscan.freshstatus.io](https://bscscan.freshstatus.io/) |
+
+### BNB Chain testnet
+
+Testnet LINK is available at [faucets.chain.link](https://faucets.chain.link/chapel). Testnet BNB is availalbe at [testnet.binance.org/faucet-smart](https://testnet.binance.org/faucet-smart).
+
+| Parameter | Value |
+| :------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `97` |
+| Address | `0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06` |
+| Name | Chainlink Token |
+| Symbol | LINK |
+| Decimals | 18 |
+
+## Polygon (Matic)
+
+### Polygon mainnet
+
+MATIC is used to pay for transactions on Polygon. You can use the [Polygon Bridge](https://wallet.polygon.technology/bridge) to transfer tokens to Polygon mainnet and then use [Polygon Gas Swap](https://wallet.polygon.technology/gas-swap/) to swap supported tokens to MATIC.
+
+:::caution[ ERC-677 LINK on Polygon]
+
+The LINK provided by the [Polygon (Matic) Bridge](https://wallet.polygon.technology/bridge) is not ERC-677 compatible, so you cannot use it with Chainlink services or oracle nodes. Use the [**Chainlink PegSwap service**](https://pegswap.chain.link/) to convert bridged LINK to the official ERC-677 LINK token on Polygon.
+
+Watch the [Moving Chainlink Cross-Chains](https://www.youtube.com/watch?v=WKvIGkBWRUA) video to learn more.
+
+:::
+
+| Parameter | Value |
+| :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `ETH_CHAIN_ID` | `137` |
+| Address | `0xb0897686c545045aFc77CF20eC7A532E3120E0F1` |
+| Name | Chainlink Token |
+| Symbol | LINK |
+| Decimals | 18 |
+| Network status | [polygon.io/system](https://polygon.io/system) |
+
+### Mumbai testnet
+
+Testnet LINK is available at [faucets.chain.link](https://faucets.chain.link/mumbai). Testnet MATIC is available at the [Polygon faucet](https://faucet.polygon.technology/).
+
+| Parameter | Value |
+| :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `80001` |
+| Address | `0x326C977E6efc84E512bB9C30f76E30c160eD06FB ` |
+| Name | Chainlink Token |
+| Symbol | LINK |
+| Decimals | 18 |
+
+## RSK
+
+### RSK mainnet
+
+RBTC is used to pay for transactions on RSK mainnet. Use [RSK’s built in PowPeg](https://developers.rsk.co/guides/get-crypto-on-rsk/powpeg-btc-rbtc/) to transfer BTC to RSK mainnet as RBTC. You can use the [RSK bridge](https://tokenbridge.rsk.co/) to send LINK from Ethereum Mainnet to RSK.
+
+| Parameter | Value |
+| :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `30` |
+| Address | `0x14ADAE34beF7Ca957ce2DDe5AdD97EA050123827` |
+| Name | rLINK |
+| Symbol | rLINK |
+| Decimals | 18 |
+
+## Gnosis Chain (xDai)
+
+### Gnosis Chain mainnet
+
+xDAI is used to pay for transactions on Gnosis Chain mainnet. Use the [xDai Bridge](https://bridge.gnosischain.com/) to send DAI from Ethereum Mainnet to Gnosis Chain and convert it to xDAI. Use [OmniBridge](https://omni.gnosischain.com/bridge) to send LINK from Ethereum Mainnet to Gnosis Chain.
+
+| Parameter | Value |
+| :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `100` |
+| Address | `0xE2e73A1c69ecF83F464EFCE6A5be353a37cA09b2` |
+| Name | Chainlink Token on Gnosis Chain (xDai) |
+| Symbol | LINK |
+| Decimals | 18 |
+| Network status | [gnosisscan.io/](https://gnosisscan.io/) |
+
+## Avalanche
+
+### Avalanche mainnet
+
+AVAX is the token you use to pay for transactions on Avalanche mainnet. Use the [Avalanche Bridge](https://bridge.avax.network/) to transfer LINK from Ethereum Mainnet to Avalanche.
+
+| Parameter | Value |
+| :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `43114` |
+| Address | `0x5947BB275c521040051D82396192181b413227A3` |
+| Name | Chainlink Token on Avalanche |
+| Symbol | LINK |
+| Decimals | 18 |
+| Network status | [status.avax.network](https://status.avax.network/) |
+
+### Fuji testnet
+
+Testnet LINK is available at [faucets.chain.link](https://faucets.chain.link/fuji). Testnet AVAX is available at [faucet.avax.network](https://faucet.avax.network/).
+
+| Parameter | Value |
+| :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `43113` |
+| Address | `0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846` |
+| Name | Chainlink Token on Avalanche |
+| Symbol | LINK |
+| Decimals | 18 |
+
+## Fantom
+
+### Fantom mainnet
+
+FTM is used to pay for transactions on Fantom Mainnet. Use [bridge.multichain.org](https://bridge.multichain.org/#/router) to transfer FTM and LINK to Fantom mainnet.
+
+:::caution[ ERC-677 LINK on Fantom]
+
+You must use ERC-677 LINK on Fantom. ERC-20 LINK will not work with Chainlink services.
+When you use [bridge.multichain.org](https://bridge.multichain.org/#/router) to send LINK to the Fantom network, be sure to select LINK-ERC677 as the token you will receive on Fantom mainnet.
+
+:::
+
+| Parameter | Value |
+| :------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `250` |
+| Address | `0x6F43FF82CCA38001B6699a8AC47A2d0E66939407` |
+| Name | Chainlink Token on Fantom |
+| Symbol | LINK |
+| Decimals | 18 |
+| Network status | [ftmscan.com](https://ftmscan.com/) |
+
+### Fantom testnet
+
+Testnet LINK is available at [faucets.chain.link](https://faucets.chain.link/fantom-testnet). Testnet FTM is available at [faucet.fantom.network](https://faucet.fantom.network/).
+
+| Parameter | Value |
+| :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `4002` |
+| Address | `0xfaFedb041c0DD4fA2Dc0d87a6B0979Ee6FA7af5F` |
+| Name | Chainlink Token on Fantom |
+| Symbol | LINK |
+| Decimals | 18 |
+
+## Arbitrum
+
+### Arbitrum mainnet
+
+ETH is used to pay for transactions on the Arbitrum mainnet. You can use the [Arbitrum Bridge](https://bridge.arbitrum.io/) to transfer ETH and LINK to from Ethereum Mainnet to Arbitrum.
+
+| Parameter | Value |
+| :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `42161` |
+| Address | `0xf97f4df75117a78c1A5a0DBb814Af92458539FB4` |
+| Name | Chainlink Token on Arbitrum Mainnet |
+| Symbol | LINK |
+| Decimals | 18 |
+| Network status | [arbiscan.freshstatus.io](https://arbiscan.freshstatus.io/) |
+
+### Arbitrum Goerli testnet
+
+Testnet ETH is used to pay for transactions on Arbitrum Goerli. Use the [Arbitrum Bridge](https://bridge.arbitrum.io/) to transfer testnet ETH and LINK from Ethereum Goerli to Arbitrum Goerli.
+
+| Parameter | Value |
+| :------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `421613` |
+| Address | `0xd14838A68E8AFBAdE5efb411d5871ea0011AFd28` |
+| Name | Chainlink Token on Arbitrum Rinkeby |
+| Symbol | LINK |
+| Decimals | 18 |
+
+## HECO Chain
+
+### HECO Chain mainnet
+
+| Parameter | Value |
+| :------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `128` |
+| Address | `0x9e004545c59D359F6B7BFB06a26390b087717b42` |
+| Name | Heco-Peg LINK Token |
+| Symbol | LINK |
+| Decimals | 18 |
+| Network status | [hecoinfo.com](https://hecoinfo.com/) |
+
+## Optimism
+
+### Optimism mainnet
+
+ETH is used to pay for transactions on Optimism. Use the [Optimism Bridge](https://app.optimism.io/bridge) to transfer ETH and LINK from Ethereum Mainnet to Optimism mainnet.
+
+| Parameter | Value |
+| :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `10` |
+| Address | `0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6` |
+| Name | Chainlink Token on Optimism Mainnet |
+| Symbol | LINK |
+| Decimals | 18 |
+| Network status | [status.optimism.io](https://status.optimism.io/) |
+
+### Optimism Goerli testnet
+
+Testnet ETH is used to pay for transactions on Optimism. Use the [Optimism Bridge](https://app.optimism.io/bridge) to transfer testnet ETH and LINK from Ethereum Goerli to Optimistim Goerli. Select Optimism Goerli in your wallet to access the Optimism Goerli bridge.
+
+| Parameter | Value |
+| :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `420` |
+| Address | `0xdc2CC710e42857672E7907CF474a69B63B93089f` |
+| Name | Chainlink Token on Optimism Goerli |
+| Symbol | LINK |
+| Decimals | 18 |
+
+## Harmony
+
+### Harmony mainnet
+
+ONE is used to pay for transactions on Harmony mainnet. You can use the [Harmony Bridge](https://bridge.harmony.one/) to transfer ONE and LINK token from Ethereum Mainnet to Harmony mainnet.
+
+| Parameter | Value |
+| :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `ETH_CHAIN_ID` | `1666600000` |
+| Address | `0x218532a12a389a4a92fC0C5Fb22901D1c19198aA` |
+| Name | Chainlink Token on Harmony Mainnet |
+| Symbol | LINK |
+| Decimals | 18 |
+| Network status | [status.harmony.one](https://status.harmony.one/) |
+
+## Moonriver
+
+### Moonriver mainnet
+
+MOVR is used to pay transaction fees on Moonriver mainnet. You can use [bridge.multichain.org](https://bridge.multichain.org/#/router) to transfer LINK to Moonriver mainnet.
+
+| Parameter | Value |
+| :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `1285` |
+| Address | `0x8b12Ac23BFe11cAb03a634C1F117D64a7f2cFD3e` |
+| Name | Chainlink Token on Moonriver Mainnet |
+| Symbol | LINK |
+| Decimals | 18 |
+| Network status | [moonscan.freshstatus.io](https://moonscan.freshstatus.io/) |
+
+## Moonbeam
+
+### Moonbeam mainnet
+
+GLMR is used to pay transaction fees on Moonbeam mainnet.
+
+| Parameter | Value |
+| :------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `1284` |
+| Address | `0x012414A392F9FA442a3109f1320c439C45518aC3` |
+| Name | Chainlink Token on Moonbeam Mainnet |
+| Symbol | LINK |
+| Decimals | 18 |
+| Network status | [moonscan.freshstatus.io](https://moonscan.freshstatus.io/) |
+
+## Metis
+
+### Andromeda mainnet
+
+METIS is the currency that you use to pay for transactions on Metis mainnet. You can use the [Metis Bridge](https://bridge.metis.io/) to transfer METIS and LINK from Ethereum Mainnet to Metis mainnet.
+
+| Parameter | Value |
+| :------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `1088` |
+| Address | `0x79892E8A3Aea66C8F6893fa49eC6208ef07EC046` |
+| Name | Chainlink Token on Metis Mainnet |
+| Symbol | LINK |
+| Decimals | 18 |
+| Network status | [andromeda-explorer.metis.io](https://andromeda-explorer.metis.io/) |
+
+## Klaytn
+
+### Baobab testnet
+
+KLAY is the currency that you use to pay for transactions on Klaytn testnet. Testnet LINK is available from [faucets.chain.link](https://faucets.chain.link/klaytn-testnet). Use the [KLAY Faucet](https://baobab.wallet.klaytn.foundation/faucet) to obtain testnet KLAY.
+
+| Parameter | Value |
+| :------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `ETH_CHAIN_ID` | `1001` |
+| Address | `0x04c5046A1f4E3fFf094c26dFCAA75eF293932f18` |
+| Name | Chainlink Token on the Klaytn testnet |
+| Symbol | LINK |
+| Decimals | 18 |
+| Network status | [status.klaytnapi.com](https://status.klaytnapi.com/) |
diff --git a/src/pages/search-index.astro b/src/pages/search-index.astro
new file mode 100644
index 00000000000..6101d36ac73
--- /dev/null
+++ b/src/pages/search-index.astro
@@ -0,0 +1,46 @@
+---
+import { MarkdownInstance } from "astro"
+import fs from "node:fs"
+
+// import .astro files
+const pages = await Astro.glob("./**/*.astro")
+
+// import .md files
+const posts = [...(await Astro.glob("./**/*.md")).filter((post) => !post.frontmatter.draft)]
+const postsMdx = [...(await Astro.glob("./**/*.mdx")).filter((post) => !post.frontmatter.draft)]
+const postsMdxWithContent = postsMdx.map((post) => {
+ const url = new URL(post.file, import.meta.url)
+ const content = fs.readFileSync(url, "utf-8")
+ return { ...post, rawContent: () => content }
+})
+
+const markDownFiles = [...posts, ...postsMdxWithContent]
+
+const allContent = [...pages, ...posts, ...postsMdx]
+
+const transformMarkdownInstancesToIndexes = async (instances: MarkdownInstance>[]) => {
+ return Promise.all(
+ instances.map(async (instance) => {
+ const { title, section, metadata } = instance.frontmatter
+ const headings = await instance.getHeadings()
+ const content = !!instance.rawContent ? await instance.rawContent() : undefined
+ return {
+ title,
+ headings,
+ url: instance.url,
+ section,
+ description: metadata?.description ?? undefined,
+ content,
+ }
+ })
+ )
+}
+
+const index = await transformMarkdownInstancesToIndexes(markDownFiles)
+
+const stringifiedJson = JSON.stringify({ index }, null, 2)
+
+fs.writeFileSync(`${process.cwd()}/public/search-index.json`, stringifiedJson)
+---
+
+
diff --git a/src/pages/solana.mdx b/src/pages/solana.mdx
new file mode 100644
index 00000000000..94a31e88642
--- /dev/null
+++ b/src/pages/solana.mdx
@@ -0,0 +1,33 @@
+---
+layout: ../layouts/MainLayout.astro
+section: solana
+title: "Chainlink on Solana"
+---
+
+import button from "@chainlink/design-system/button.module.css"
+
+Chainlink turns your smart contracts into hybrid smart contracts, giving
+them access to real-world data and services.
+
+
+
+ ## Use Data Feeds on Solana
+
+ Solana is a high-throughput blockchain. You can use Chainlink Data Feeds on
+ the Solana network to connect your smart contracts to the real-world market
+ prices of assets.
+
+
+ {"Data feeds on Solana"}
+
+
+
+
+
+
+ ## New to Chainlink and Smart Contracts?
+ Learn the basics in the Getting Started Guide. Build your first smart contract on Ethereum.
+
+ {"Getting Started Guide"}
+
+
diff --git a/src/pages/solana/data-feeds/data-feeds-solana.md b/src/pages/solana/data-feeds/data-feeds-solana.md
new file mode 100644
index 00000000000..ac78b962371
--- /dev/null
+++ b/src/pages/solana/data-feeds/data-feeds-solana.md
@@ -0,0 +1,15 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: solana
+title: "Solana Data Feeds Addresses"
+stub: data-feeds-solana
+permalink: "docs/solana/data-feeds-solana/"
+metadata:
+ ecosystem: solana
+ networkstatusurl: "https://status.solana.com/"
+date: Last Modified
+setup: |
+ import { FeedPage } from "@features/feeds"
+---
+
+
diff --git a/src/pages/solana/data-feeds/using-data-feeds-off-chain.md b/src/pages/solana/data-feeds/using-data-feeds-off-chain.md
new file mode 100644
index 00000000000..eb6b7dbb148
--- /dev/null
+++ b/src/pages/solana/data-feeds/using-data-feeds-off-chain.md
@@ -0,0 +1,236 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: solana
+date: Last Modified
+title: "Using Data Feeds Off-Chain (Solana)"
+permalink: "docs/solana/using-data-feeds-off-chain/"
+whatsnext:
+ {
+ "Use data feeds on-chain": "/solana/data-feeds/using-data-feeds-solana/",
+ "See the available data feeds on Solana": "/solana/data-feeds/data-feeds-solana/",
+ }
+metadata:
+ title: "Using Data Feeds Off-Chain (Solana)"
+ description: "How to use Chainlink Data Feeds in your off-chain applications."
+setup: |
+ import { PackageManagerTabs } from "@components"
+ import { Tabs } from "@components/Tabs"
+---
+
+Chainlink Data Feeds are the quickest way to access market prices for real-world assets. This guide demonstrates how to read Chainlink Data Feeds on the Solana Devnet using off-chain examples in the [Chainlink Solana Starter Kit](https://github.com/smartcontractkit/solana-starter-kit). To learn how to use Data Feeds in your on-chain Solana programs, see the [Using Data Feeds On-Chain](/solana/data-feeds/using-data-feeds-solana/) guide.
+
+To get the full list of Chainlink Data Feeds on Solana, see the [Solana Feeds](/solana/data-feeds/data-feeds-solana/) page.
+
+:::warn[Select quality data feeds]
+
+Be aware of the quality of the data that you use. [Learn more about making responsible data quality decisions.](/data-feeds/selecting-data-feeds/)
+:::
+
+## The Chainlink Data Feeds Store Program
+
+The program that contains the logic required for the storing and retrieval of Chainlink Data Feeds data on both Devnet and Mainnet is [cjg3oHmg9uuPsP8D6g29NWvhySJkdYdAo9D25PRbKXJ](https://solscan.io/account/cjg3oHmg9uuPsP8D6g29NWvhySJkdYdAo9D25PRbKXJ?cluster=devnet). This is the program ID that you use to read price data from off-chain. You can find the source code for this program in the [smartcontractkit/chainlink-solana](https://github.com/smartcontractkit/chainlink-solana/tree/develop/contracts/programs/store/src) on GitHub.
+
+You can [add data feeds to an existing off-chain project](#adding-data-feeds-to-an-existing-off-chain-project) or [use the Solana Starter Kit](#using-the-solana-starter-kit).
+
+## Adding Data Feeds to an existing off-chain project
+
+You can read Chainlink Data Feeds off-chain in your existing project by using the [Chainlink Solana NPM library](https://www.npmjs.com/package/@chainlink/solana-sdk).
+
+:::caution[ Reading feed data]
+
+Although you can directly query the data feed accounts, you should not rely on the memory layout always being the same as it currently is. Based on this, the recommendation is to always use the consumer library.
+
+:::
+
+Install the necessary components and include the example code in your project. Optionally, you can run the example code by itself to learn how it works before you integrate it with your project.
+
+1. Install the latest Mainnet version of [the Solana CLI](https://github.com/solana-labs/solana/releases) and export the path to the CLI:
+
+ ```shell
+ sh -c "$(curl -sSfL https://release.solana.com/v1.9.28/install)" &&
+ export PATH="~/.local/share/solana/install/active_release/bin:$PATH"
+ ```
+
+ Run `solana --version` to make sure the Solana CLI is installed correctly.
+
+ ```shell
+ solana --version
+ ```
+
+1. Install [Node.js 14 or higher](https://nodejs.org/en/download/). Run `node --version` to verify which version you have installed:
+
+ ```shell
+ node --version
+ ```
+
+1. Change to your project directory or create a new directory.
+
+ ```shell
+ mkdir off-chain-project && cd off-chain-project
+ ```
+
+1. Optionally [install Yarn](https://classic.yarnpkg.com/lang/en/docs/install/) to use as a package manager and initialize yarn if your project does not already have a `package.json` file:
+
+ ```shell
+ npm install -g yarn && yarn init
+ ```
+
+1. Add the [Anchor library](https://www.npmjs.com/package/@project-serum/anchor) to your project:
+
+
+
+ ```shell yarn
+ yarn add @project-serum/anchor
+ ```
+
+
+
+ ```shell npm
+ npm i @project-serum/anchor
+ ```
+
+
+
+1. Add the [Chainlink Solana NPM library](https://www.npmjs.com/package/@chainlink/solana-sdk) to your project:
+
+
+
+ ```shell yarn
+ yarn add @chainlink/solana-sdk
+ ```
+
+
+
+ ```shell npm
+ npm i -g @chainlink/solana-sdk
+ ```
+
+
+
+1. Create a temporary Solana wallet to use for this example. Alternatively, if you have an existing wallet that you want to use, locate the path to your [keypair](https://docs.solana.com/terminology#keypair) file and use it as the keypair for the rest of this guide.
+
+ ```shell
+ solana-keygen new --outfile ./id.json
+ ```
+
+1. Set the [Anchor environment variables](https://www.twilio.com/blog/2017/01/how-to-set-environment-variables.html). Anchor uses these to determine which wallet to use and how to get a connection to a Solana cluster. Because this example does not generate or sign any transactions, no lamports are required. The wallet is required only by the Anchor library. For a list of available networks and endpoints, see the [Solana Cluster RPC Endpoints](https://docs.solana.com/cluster/rpc-endpoints) documentation.
+
+ ```shell
+ export ANCHOR_PROVIDER_URL=https://api.devnet.solana.com &&
+ export ANCHOR_WALLET=./id.json
+ ```
+
+1. Copy the sample code into your project. This example queries price data off-chain. By default, the script reads the SOL/USD feed, but you can change the `CHAINLINK_FEED_ADDRESS` variable to point to the [feed account addresses](/solana/data-feeds/data-feeds-solana/) that you want to query. You can take the components of these code samples and integrate them with your existing project. Because these examples read data feeds without making any on-chain changes, no lamports are required to run them.
+
+::solidity-remix[samples/Solana/PriceFeeds/off-chain-read.js]
+
+::solidity-remix[samples/Solana/PriceFeeds/off-chain-read.ts]
+
+You can run these examples using the following commands:
+
+
+ Javascript
+ Typescript
+
+ ```shell JavaScript
+ node javascript-example.js
+ ```
+
+
+ ```shell TypeScript
+ yarn add ts-node typescript && yarn ts-node typescript-example.ts
+ ```
+
+
+
+To learn more about Solana and Anchor, see the [Solana Documentation](https://docs.solana.com/) and the [Anchor Documentation](https://book.anchor-lang.com/).
+
+## Using the Solana Starter Kit
+
+This example reads price data from an off-chain client using the [Solana Starter Kit](https://github.com/smartcontractkit/solana-starter-kit).
+
+### Install the required tools
+
+Before you begin, set up your environment for development on Solana:
+
+1. Install [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) if it is not already configured on your system.
+
+1. Install the latest Mainnet version of [the Solana CLI](https://github.com/solana-labs/solana/releases) and export the path to the CLI:
+
+ ```shell
+ sh -c "$(curl -sSfL https://release.solana.com/v1.9.28/install)" &&
+ export PATH="~/.local/share/solana/install/active_release/bin:$PATH"
+ ```
+
+ Run `solana --version` to make sure the Solana CLI is installed correctly.
+
+ ```shell
+ solana --version
+ ```
+
+1. Install [Node.js 14 or higher](https://nodejs.org/en/download/). Run `node --version` to verify which version you have installed:
+
+ ```shell
+ node --version
+ ```
+
+1. [Install Anchor](https://book.anchor-lang.com/getting_started/installation.html). On some operating systems, you might need to build and install Anchor locally. See the [Anchor documentation](https://book.anchor-lang.com/getting_started/installation.html#build-from-source-for-other-operating-systems-without-avm) for instructions.
+
+1. Install [Yarn](https://classic.yarnpkg.com/lang/en/docs/install/) to simplify package management and run code samples in the Starter Kit.
+
+ ```shell
+ npm install -g yarn
+ ```
+
+### Run the example program
+
+After you install the required tools, clone the example code from the [solana-starter-kit](https://github.com/smartcontractkit/solana-starter-kit) repository.
+
+1. In a terminal, clone the [solana-starter-kit](https://github.com/smartcontractkit/solana-starter-kit) repository and change to the `solana-starter-kit` directory:
+
+ ```shell
+ git clone https://github.com/smartcontractkit/solana-starter-kit &&
+ cd ./solana-starter-kit
+ ```
+
+ You can see the complete code for the example on [GitHub](https://github.com/smartcontractkit/solana-starter-kit/).
+
+1. In the `./solana-starter-kit` directory, install Node.js dependencies defined in the `package.json` file:
+
+ ```shell
+ yarn install
+ ```
+
+1. Create a temporary Solana wallet file to use for this example. Because your application runs off-chain and does not run any functions or alter data on-chain, the wallet does not require any SOL tokens to function.
+
+ ```shell
+ solana-keygen new --outfile ./id.json
+ ```
+
+1. Set the [Anchor environment variables](https://www.twilio.com/blog/2017/01/how-to-set-environment-variables.html). Anchor uses these to determine which wallet to use and Solana cluster to use. Take note that because we are not generating or signing any transactions, the wallet isn't used, it's just required by the Anchor library. For a list of available networks and endpoints, see the [Solana Cluster RPC Endpoints](https://docs.solana.com/cluster/rpc-endpoints) documentation.
+
+ ```shell Solana Devnet
+ export ANCHOR_PROVIDER_URL=https://api.devnet.solana.com &&
+ export ANCHOR_WALLET=./id.json
+ ```
+
+1. Run the example:
+
+ ```shell JavaScript
+ node read-data.js
+ ```
+
+ ```shell TypeScript
+ yarn run read-data
+ ```
+
+ The example code retrieves and prints the current price feed data until you close the application:
+
+ ```
+ 4027000000
+ 4026439929
+ 4026476542
+ 4023000000
+ ```
+
+To learn more about Solana and Anchor, see the [Solana Documentation](https://docs.solana.com/) and the [Anchor Documentation](https://book.anchor-lang.com/).
diff --git a/src/pages/solana/data-feeds/using-data-feeds-solana.md b/src/pages/solana/data-feeds/using-data-feeds-solana.md
new file mode 100644
index 00000000000..5b59d4cee1c
--- /dev/null
+++ b/src/pages/solana/data-feeds/using-data-feeds-solana.md
@@ -0,0 +1,341 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: solana
+date: Last Modified
+title: "Using Data Feeds On-Chain (Solana)"
+permalink: "docs/solana/using-data-feeds-solana/"
+whatsnext:
+ {
+ "Use data feeds off-chain": "/solana/data-feeds/using-data-feeds-off-chain/",
+ "See the available data feeds on Solana": "/solana/data-feeds/data-feeds-solana/",
+ }
+metadata:
+ title: "Using Data Feeds On-Chain (Solana)"
+ description: "How to use Chainlink Data Feeds in your on-chain Solana programs."
+setup: |
+ import { Tabs } from "@components/Tabs"
+---
+
+Chainlink Data Feeds are the quickest way to connect your smart contracts to the real-world market prices of assets. This guide demonstrates how to deploy a program to the Solana Devnet cluster and access Data Feeds on-chain using the [Chainlink Solana Starter Kit](https://github.com/smartcontractkit/solana-starter-kit). To learn how to read price feed data using off-chain applications, see the [Using Data Feeds Off-Chain](/solana/using-data-feeds-off-chain/) guide.
+
+To get the full list of available Chainlink Data Feeds on Solana, see the [Solana Feeds](/solana/data-feeds/data-feeds-solana/) page. View the program that owns the Chainlink Data Feeds in the [Solana Devnet Explorer](https://solscan.io/account/HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny?cluster=devnet), or the [Solana Mainnet Explorer](https://solscan.io/account/HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny).
+
+> 🚧 Select quality data feeds
+>
+> Be aware of the quality of the data that you use. [Learn more about making responsible data quality decisions.](/data-feeds/selecting-data-feeds/)
+
+## The Chainlink Data Feeds OCR2 Program
+
+The program that owns the data feeds on both Devnet and Mainnet is [HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny](https://solscan.io/account/HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny?cluster=devnet). This is the program ID that you use to retrieve Chainlink Price Data on-chain in your program. The source code for this program is available in the [smartcontractkit/chainlink-solana](https://github.com/smartcontractkit/chainlink-solana/tree/develop/contracts/programs/ocr2) repository on GitHub.
+
+You can [add data feeds to an existing project](#adding-data-feeds-on-chain-in-an-existing-project) or [use the Solana Starter Kit](#using-the-solana-starter-kit).
+
+## Adding Data Feeds On-Chain In An Existing Project
+
+You can read Chainlink Data Feed data on-chain in your existing project using the [Chainlink Solana Crate](https://crates.io/crates/chainlink_solana).
+
+:::caution[ Reading feed data]
+
+Although you can directly query the data feed accounts, you should not rely on the memory layout always being the same as it currently is. Based on this, the recommendation is to always use the consumer library queries below.
+
+:::
+
+Import the Chainlink Solana Crate into your project and use the code sample to make function calls.
+
+1. Add the Chainlink Solana Crate as an entry in your `Cargo.toml` file dependencies section, as shown in the [starter kit Cargo.toml example](https://github.com/smartcontractkit/solana-starter-kit/blob/main/programs/chainlink_solana_demo/Cargo.toml).
+
+ ```toml
+ [dependencies]
+ chainlink_solana = "1.0.0"
+ ```
+
+1. Use the following code sample to query price data. Each function call to the Chainlink Solana library takes two parameters:
+
+ - The [feed account](/solana/data-feeds/data-feeds-solana/) that you want to query.
+ - The [Chainlink Data Feeds OCR2 Program](#the-chainlink-data-feeds-ocr2-program) for the network. This is a static value that never changes.
+
+The code sample has the following components:
+
+- `latest_round_data`: Returns the latest round information for the specified price pair including the latest price
+- `description`: Returns a price pair description such as SOL/USD
+- `decimals`: Returns the precision of the price, as in how many numbers the price is padded out to
+- `Display`: A helper function that formats the padded out price data into a human-readable price
+
+::solidity-remix[samples/Solana/PriceFeeds/on-chain-read.rs]
+
+::solidity-remix[samples/Solana/PriceFeeds/on-chain-read-anchor.rs]
+
+Program Transaction logs:
+
+
+ Rust
+ Rust with Anchor
+
+ ```shell Rust
+ > Program logged: "Chainlink Price Feed Consumer entrypoint"
+ > Program logged: "SOL / USD price is 83.99000000"
+ > Program consumed: 95953 of 1400000 compute units
+ > Program return: HNYSbr77Jc9LhHeb9tx53SrWbWfNBnQzQrM4b3BB3PCR CA==
+ ```
+
+
+ ```shell Rust with Anchor
+ Fetching transaction logs...
+ [
+ 'Program HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny consumed 1826 of 1306895 compute units',
+ 'Program return: HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny CA==',
+ 'Program HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny success',
+ 'Program log: SOL / USD price is 93.76988029',
+ ]
+ ```
+
+
+
+To learn more about Solana and Anchor, see the [Solana Documentation](https://docs.solana.com/) and the [Anchor Documentation](https://project-serum.github.io/anchor/).
+
+## Using the Solana Starter Kit
+
+This guide demonstrates the following tasks:
+
+- Write and deploy programs to the [Solana Devnet](https://solscan.io/?cluster=devnet) cluster using Anchor.
+- Retrieve price data data using the [Solana Web3 JavaScript API](https://www.npmjs.com/package/@solana/web3.js) with Node.js.
+
+This example shows a full end to end example of using Chainlink Price Feeds on Solana. It includes an on-chain program written in rust, as well as an off-chain client written in JavaScript. The client passes in an account to the program, the program then looks up the latest price of the specified price feed account, and then stores the result in the passed in account. The off-chain client then reads the value stored in the account.
+
+### Install the required tools
+
+Before you begin, set up your environment for development on Solana:
+
+1. Install [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) if it is not already configured on your system.
+
+1. Install [Node.js 14 or higher](https://nodejs.org/en/download/). Run `node --version` to verify which version you have installed:
+
+ ```shell
+ node --version
+ ```
+
+1. Install [Yarn](https://classic.yarnpkg.com/lang/en/docs/install/) to simplify package management and run code samples.
+
+1. Install a C compiler such as the one included in [GCC](https://gcc.gnu.org/install/). Some of the dependencies require a C compiler.
+
+1. Install [Rust](https://www.rust-lang.org/tools/install):
+
+ ```shell
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh &&
+ source $HOME/.cargo/env
+ ```
+
+1. Install the latest Mainnet version of [the Solana CLI](https://github.com/solana-labs/solana/releases) and export the path to the CLI:
+
+ ```shell
+ sh -c "$(curl -sSfL https://release.solana.com/v1.9.28/install)" &&
+ export PATH="~/.local/share/solana/install/active_release/bin:$PATH"
+ ```
+
+ Run `solana --version` to make sure the Solana CLI is installed correctly.
+
+ ```shell
+ solana --version
+ ```
+
+1. [Install Anchor](https://book.anchor-lang.com/getting_started/installation.html). On some operating systems, you might need to build and install Anchor locally. See the [Anchor documentation](https://book.anchor-lang.com/getting_started/installation.html#build-from-source-for-other-operating-systems-without-avm) for instructions.
+
+After you install the required tools, build and deploy the example program from the [solana-starter-kit](https://github.com/smartcontractkit/solana-starter-kit) repository.
+
+### Deploy the example program
+
+This example includes a contract written in Rust. Deploy the contract to the Solana Devnet cluster.
+
+1. In a terminal, clone the [solana-starter-kit](https://github.com/smartcontractkit/solana-starter-kit) repository and change to the `solana-starter-kit` directory:
+
+ ```shell
+ git clone https://github.com/smartcontractkit/solana-starter-kit &&
+ cd ./solana-starter-kit
+ ```
+
+ You can see the complete code for the example on [GitHub](https://github.com/smartcontractkit/solana-starter-kit/).
+
+1. In the `./solana-starter-kit` directory, install Node.js dependencies defined in the `package.json` file:
+
+ ```shell
+ yarn install
+ ```
+
+1. Create a temporary Solana wallet to use for this example. Use a temporary wallet to isolate development from your other wallets and prevent you from unintentionally using lamports on the Solana Mainnet. Alternatively, if you have an existing wallet that you want to use, locate the path to your [keypair](https://docs.solana.com/terminology#keypair) file and use it as the keypair for the rest of this guide.
+
+ ```shell
+ solana-keygen new --outfile ./id.json
+ ```
+
+ When you build your production applications and deploy Solana programs to the Mainnet cluster, always follow the security best practices in the [Solana Wallet Guide](https://docs.solana.com/wallet-guide) for managing your wallets and keypairs.
+
+1. Fund your Solana wallet. On Devnet, use `solana airdrop` to add tokens to your account. The contract requires at least 4 SOL to deploy and the faucet limits each request to 2 SOL, so you must make two requests to get a total of 4 SOL on your wallet:
+
+ ```shell
+ solana airdrop 2 --keypair ./id.json --url devnet &&
+ solana airdrop 2 --keypair ./id.json --url devnet
+ ```
+
+ - If the command line faucet does not work, run `solana address` on the temporary wallet to print the public key value for the wallet and request tokens from [SolFaucet](https://solfaucet.com/):
+
+ ```shell
+ solana address -k ./id.json
+ ```
+
+1. Run `anchor build` to build the example program. If you receive the `no such subcommand: 'build-bpf'` error, restart your terminal session and run `anchor build` again:
+
+ ```shell
+ anchor build
+ ```
+
+1. The build process generates the keypair for your program's account. Before you deploy your program, you must add this public key to the `lib.rs` file:
+
+ 1. Get the keypair from the `./target/deploy/chainlink_solana_demo-keypair.json` file that Anchor generated:
+
+ ```shell
+ solana address -k ./target/deploy/chainlink_solana_demo-keypair.json
+ ```
+
+ 1. Edit the `./programs/chainlink_solana_demo/src/lib.rs` file and replace the keypair in the `declare_id!()` definition:
+
+ ```shell
+ vi ./programs/chainlink_solana_demo/src/lib.rs
+ ```
+
+ ```shell
+ declare_id!("JC16qi56dgcLoaTVe4BvnCoDL6FhH5NtahA7jmWZFdqm");
+ ```
+
+1. With the new program ID added, run `anchor build` again. This recreates the necessary program files with the correct program ID:
+
+ ```shell
+ anchor build
+ ```
+
+1. Run `anchor deploy` to deploy the program to the Solana Devnet. Remember to specify the keypair file for your wallet and override the default. This wallet is the [account owner](https://docs.solana.com/terminology#account-owner) (authority) for the program:
+
+ ```shell
+ anchor deploy --provider.wallet ./id.json --provider.cluster devnet
+ ```
+
+1. To confirm that the program deployed correctly, run `solana program show --programs` to get a list of deployed programs that your wallet owns. For this example, check the list of deployed programs for the `id.json` wallet on the Solana Devnet:
+
+ ```shell
+ solana program show --programs --keypair ./id.json --url devnet
+ ```
+
+ The command prints the program ID, slot number, the wallet address that owns the program, and the program balance:
+
+ ```shell
+ Program Id | Slot | Authority | Balance
+ GRt21UnJFHZvcaWLbcUrXaTCFMREewDrm1DweDYBak3Z | 110801571 | FsQPnANKDhqpoayxCL3oDHFCBmrhP34NrfbDR34qbQUt | 3.07874904 SOL
+ ```
+
+ To see additional details of your deployed program, copy the program ID and look it up in the [Solana Devnet Explorer](https://solscan.io/?cluster=devnet).
+
+Now that the program is on-chain, you can call it using the [Anchor Web3 module](https://project-serum.github.io/anchor/ts/modules/web3.html).
+
+### Call the deployed program
+
+Use your deployed program to retrieve price data from a Chainlink data feed on Solana Devnet. For this example, call your deployed program using the [Anchor Web3 module](https://project-serum.github.io/anchor/ts/modules/web3.html) and the [`client.js` example](https://github.com/smartcontractkit/solana-starter-kit/blob/main/client.js) code.
+
+1. Set the [Anchor environment variables](https://www.twilio.com/blog/2017/01/how-to-set-environment-variables.html). Anchor uses these to determine which wallet to use and Solana cluster to use.
+
+ ```shell
+ export ANCHOR_PROVIDER_URL=https://api.devnet.solana.com &&
+ export ANCHOR_WALLET=./id.json
+ ```
+
+1. Run the `client.js` example and pass the program address in using the `--program` flag:
+
+ ```shell
+ node client.js --program $(solana address -k ./target/deploy/chainlink_solana_demo-keypair.json)
+ ```
+
+ If the script executes correctly, you will see output with the current price of SOL / USD.
+
+ ```shell
+ ⋮
+ Price Is: 96.79778375
+ Success
+ ⋮
+ ```
+
+1. Each request costs an amount of SOL that is subtracted from the `id.json` wallet. Run `solana balance` to check the remaining balance for your temporary wallet on Devnet.
+
+ ```shell
+ solana balance --keypair ./id.json --url devnet
+ ```
+
+1. To get prices for a different asset pair, run `client.js` again and add the `--feed` flag with one of the available [Chainlink data feeds](/solana/data-feeds/data-feeds-solana/). For example, to get the price of BTC / USD on Devnet, use the following command:
+
+ ```shell
+ node client.js \
+ --program $(solana address -k ./target/deploy/chainlink_solana_demo-keypair.json) \
+ --feed CzZQBrJCLqjXRfMjRN3fhbxur2QYHUzkpaRwkWsiPqbz
+ ```
+
+ ```shell
+ Price Is: 12.4215826
+ Success
+ ```
+
+The program that owns the data feeds is [HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny](https://solscan.io/account/HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny?cluster=devnet), which you can see defined for `const CHAINLINK_PROGRAM_ID` in the `client.js` file.
+
+### Clean up
+
+After you are done with your deployed contract and no longer need it, it is nice to close the program and withdraw the Devnet SOL tokens for future use. In a production environment, you will want to withdraw unused SOL tokens from any Solana program that you no longer plan to use, so it is good to practice the process when you are done with programs on Devnet.
+
+1. Run `solana program show` to see the list of deployed programs that your wallet owns and the balances for each of those programs:
+
+ ```shell
+ solana program show --programs --keypair ./id.json --url devnet
+ ```
+
+ ```shell
+ Program Id | Slot | Authority | Balance
+ GRt21UnJFHZvcaWLbcUrXaTCFMREewDrm1DweDYBak3Z | 110801571 | FsQPnANKDhqpoayxCL3oDHFCBmrhP34NrfbDR34qbQUt | 3.07874904 SOL
+ ```
+
+1. Run `solana program close` and specify the program that you want to close:
+
+ ```shell
+ solana program close [YOUR_PROGRAM_ID] --keypair ./id.json --url devnet
+ ```
+
+ The program closes and the remaining SOL is transferred to your temporary wallet.
+
+1. If you have deployments that failed, they might still be in the buffer holding SOL tokens. Run `solana program show` again with the `--buffers` flag:
+
+ ```shell
+ solana program show --buffers --keypair ./id.json --url devnet
+ ```
+
+ If you have open buffers, they will appear in the list.
+
+ ```shell
+ Buffer Address | Authority | Balance
+ CSc9hnBqYJoYtBgsryJAmrjAE6vZ918qaFhL6N6BdEmB | FsQPnANKDhqpoayxCL3oDHFCBmrhP34NrfbDR34qbQUt | 1.28936088 SOL
+ ```
+
+1. If you have any buffers that you do not plan to finish deploying, run the same `solana program close` command to close them and retrieve the unused SOL tokens:
+
+ ```shell
+ solana program close [YOUR_PROGRAM_ID] --keypair ./id.json --url devnet
+ ```
+
+1. Check the balance on your temporary wallet.
+
+ ```shell
+ solana balance --keypair ./id.json --url devnet
+ ```
+
+1. If you are done using this wallet for examples and testing, you can use [`solana transfer`](https://docs.solana.com/cli/transfer-tokens) to send the remaining SOL tokens to your default wallet or another Solana wallet that you use. For example, if your default wallet keypair is at `~/.config/solana/id.json`, you can send `ALL` of the temporary wallet's balance with the following command:
+
+ ```shell
+ solana transfer ~/.config/solana/id.json ALL --keypair ./id.json --url devnet
+ ```
+
+ Alternatively, you can send the remaining balance to a web wallet. Specify the public key for your wallet instead of the path the default wallet keypair. Now you can use those Devnet funds for other examples and development.
+
+To learn more about Solana and Anchor, see the [Solana Documentation](https://docs.solana.com/) and the [Anchor Documentation](https://project-serum.github.io/anchor/).
diff --git a/src/pages/solana/overview.md b/src/pages/solana/overview.md
new file mode 100644
index 00000000000..0fb4924403c
--- /dev/null
+++ b/src/pages/solana/overview.md
@@ -0,0 +1,83 @@
+---
+layout: ../../layouts/MainLayout.astro
+section: solana
+date: Last Modified
+title: "Overview"
+permalink: "docs/solana/"
+whatsnext:
+ {
+ "Use data feeds off-chain": "/solana/using-data-feeds-off-chain/",
+ "Use data feeds on-chain": "/solana/using-data-feeds-solana/",
+ "See the available data feeds on Solana": "/solana/data-feeds/data-feeds-solana/",
+ }
+---
+
+Chainlink provides data feeds on the [Solana](https://solana.com/) network. Chainlink data feeds on Solana employ [Off-Chain Reporting (OCR)](/architecture-overview/off-chain-reporting/) to aggregate data from data providers who pull from both centralized and decentralized exchanges. Chainlink’s Solana deployment has no dependencies on external blockchain networks such as Ethereum. In Solana, storage and smart contract logic are separate. Programs store all the logic similar to an EVM (Ethereum) smart contract. The accounts store all the data. Compared to Solidity, the combination of an account and a program is equivalent to a smart contract on an EVM chain. State and logic are separate in Solana.
+
+Solana programs are stateless, so you don't always need to deploy your program to the network to test it. You can deploy and test your programs on a [Solana Test Validator](https://docs.solana.com/developing/test-validator). However, to use Chainlink products on Solana, you must deploy your contract on-chain to one of the [supported Solana clusters](#chainlink-products-and-solana-clusters).
+
+:::note
+Please note that Price Feeds performance relies on the chains they are deployed on. Periods of high network congestion may impact the frequency of Chainlink Price Feeds. Subscribe to [Solana status](https://status.solana.com/) notifications to stay updated on system performance.
+:::
+
+To learn how to mitigate risk to your applications, read the [Selecting Quality Data Feeds](/data-feeds/selecting-data-feeds/) page.
+
+## Chainlink products and Solana clusters
+
+[Data Feeds](/solana/data-feeds/data-feeds-solana/) are available on the following Solana clusters:
+
+- [Solana Mainnet](https://solscan.io/)
+- [Solana Devnet](https://solscan.io/?cluster=devnet)
+
+Solana provides a [Testnet cluster](https://docs.solana.com/clusters#testnet) that runs newer [Solana releases](https://github.com/solana-labs/solana/releases), but Chainlink Data Feeds are not available on this cluster.
+
+See the [Solana Data Feeds](/solana/data-feeds/data-feeds-solana/) page for a full list of Chainlink data feeds that are available on Solana.
+
+To learn when more Chainlink services become available, follow us on [Twitter](https://twitter.com/chainlink) or sign up for our [mailing list](/resources/developer-communications/).
+
+## Languages, tools, and frameworks
+
+The examples in the Chainlink documentation use the following languages, tools, and frameworks:
+
+- [Node.js 14 or higher](https://nodejs.org/en/download/): Used to run client code
+- [Rust](https://docs.solana.com/developing/on-chain-programs/developing-rust): A general-purpose programming language designed for performance and memory safety
+- [Anchor](https://project-serum.github.io/anchor/getting-started/introduction.html): A framework for the [Solana Sealevel runtime](https://github.com/solana-labs/sealevel) that provides several developer tools
+- [Chainlink Solana Starter Kit](https://github.com/smartcontractkit/solana-starter-kit): An Anchor based program and client that shows developers how to use and interact with Chainlink Data Feeds on Solana
+- [Solana CLI](https://docs.solana.com/cli): The Solana command line interface
+- [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git): Used to clone the example code repository
+
+When developing applications to use Chainlink products on Solana, always use a [Mainnet release](https://github.com/solana-labs/solana/releases) version of the Solana CLI that is equal to or greater than the version currently running on your target cluster. Use `solana --version` and `solana cluster-version` to check CLI and cluster versions:
+
+```shell
+solana --version
+solana-cli 1.9.28 (src:b576e9cc; feat:320703611)
+
+solana cluster-version --url devnet
+1.9.25
+
+solana cluster-version --url mainnet-beta
+1.9.28
+```
+
+The examples in this documentation use Solana programs in [Rust](https://docs.solana.com/developing/on-chain-programs/developing-rust), but you can also write Solana programs in [C](https://docs.solana.com/developing/on-chain-programs/developing-c). To learn more about the Solana programming model, see the [Solana Documentation](https://docs.solana.com/developing/programming-model/overview).
+
+## Solana Wallets
+
+When you use Chainlink on Solana, you need a [Solana wallet](https://docs.solana.com/wallet-guide/). The Chainlink documentation uses [file system wallets](https://docs.solana.com/wallet-guide/file-system-wallet) and free Devnet SOL tokens to demonstrate examples. When you deploy your programs to the Solana Mainnet, you must use wallets with mainnet lamports.
+
+If you have existing wallets that you want to use for the guides in the Chainlink documentation, find your wallet keypair and make it available in your development environment as a file. You can point [Anchor](https://project-serum.github.io/anchor/getting-started/introduction.html) and the [Solana CLI](https://docs.solana.com/cli) to a specific keypair when you deploy or manage your Solana programs.
+
+```shell
+anchor build
+⋮
+
+anchor deploy --provider.wallet ~/.config/solana/id.json --provider.cluster devnet
+⋮
+
+solana program show --programs --keypair ~/.config/solana/id.json --url devnet
+
+Program Id | Slot | Authority | Balance
+6U4suTp55kiJRKqV7HGAQvFgcLaStLnUA4myg5DRqsKw | 109609728 | E6gKKToCJPgf4zEL1GRLL6T99g2WcfAzJAMvtma1KijT | 2.57751768 SOL
+```
+
+When you build your production applications and deploy Solana programs to the Mainnet cluster, always follow the security best practices in the [Solana Wallet Guide](https://docs.solana.com/wallet-guide) for managing your wallets and keypairs.
diff --git a/src/pages/vrf/v1/api-reference.md b/src/pages/vrf/v1/api-reference.md
new file mode 100644
index 00000000000..770b7edf61a
--- /dev/null
+++ b/src/pages/vrf/v1/api-reference.md
@@ -0,0 +1,84 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: legacy
+date: Last Modified
+title: "Chainlink VRF API Reference [v1]"
+permalink: "docs/vrf/v1/api-reference/"
+metadata:
+ title: "Chainlink VRF API Reference"
+ description: "API reference for VRFConsumerBase."
+setup: |
+ import VrfCommon from "@features/vrf/v1/common/VrfCommon.astro"
+---
+
+
+
+API reference for [`VRFConsumerBase`](https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/VRFConsumerBase.sol).
+
+## Index
+
+### Constructors
+
+| Name | Description |
+| --------------------------- | ----------------------------------- |
+| [constructor](#constructor) | Initialize your consuming contract. |
+
+### Functions
+
+| Name | Description |
+| --------------------------------------- | ------------------------------------------------------------ |
+| [requestRandomness](#requestrandomness) | Make a request to the VRFCoordinator. |
+| [fulfillRandomness](#fulfillrandomness) | Called by VRFCoordinator when it receives a valid VRF proof. |
+
+---
+
+## Constructor
+
+Initialize your consuming contract.
+
+
+```solidity
+constructor(address _vrfCoordinator, address _link)
+```
+
+- `_vrfCoordinator`: Address of the Chainlink VRF Coordinator. See [Chainlink VRF Addresses](/vrf/v1/supported-networks/) for details.
+- `_link`: Address of the LINK token. See [LINK Token Addresses](/resources/link-token-contracts/) for details.
+
+---
+
+> Note: `_seed` has recently been deprecated.
+
+## Functions
+
+### requestRandomness
+
+Make a request to the VRF coordinator.
+
+
+```solidity
+function requestRandomness(bytes32 _keyHash, uint256 _fee)
+ public returns (bytes32 requestId)
+```
+
+- `_keyHash`: The public key against which randomness is generated. See [Chainlink VRF supported networks](/vrf/v1/supported-networks) for details.
+- `_fee`: The fee, in LINK, for the request. Specified by the oracle.
+- `RETURN`: The ID unique to a single request.
+
+### fulfillRandomness
+
+Called by VRFCoordinator when it receives a valid VRF proof. Override this function to act upon the random number generated by Chainlink VRF.
+
+
+```solidity
+function fulfillRandomness(bytes32 requestId, uint256 randomness)
+ internal virtual;
+```
+
+- `requestId`: The ID initially returned by `requestRandomness`.
+- `randomness`: The random number generated by Chainlink VRF.
+
+## Reference
+
+### Maximizing security
+
+Chainlink VRF provides powerful security guarantees and is easy to integrate. However, smart contract security is a nuanced topic. You can read about the [top security considerations for VRF](/vrf/v1/security).
diff --git a/src/pages/vrf/v1/best-practices.md b/src/pages/vrf/v1/best-practices.md
new file mode 100644
index 00000000000..c5e2442bcb7
--- /dev/null
+++ b/src/pages/vrf/v1/best-practices.md
@@ -0,0 +1,101 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: legacy
+date: Last Modified
+title: "VRF Best Practices [v1]"
+permalink: "docs/vrf/v1/best-practices/"
+metadata:
+ title: "Chainlink VRF API Reference"
+ description: "Best pracices for using Chainlink VRF."
+setup: |
+ import VrfCommon from "@features/vrf/v1/common/VrfCommon.astro"
+---
+
+
+
+Best are the practices for using Chainlink VRF.
+
+## Getting a random number within a range
+
+If you need to generate a random number within a given range, you use [modulo](https://docs.soliditylang.org/en/v0.8.17/types.html#modulo) to define the limits of your range. Below you can see how to get a random number between 1 and 50.
+
+
+```solidity
+uint256 public randomResult;
+
+function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
+ randomResult = (randomness % 50) + 1;
+}
+```
+
+## Getting multiple random numbers
+
+If you want to get multiple random numbers from a single VRF response, you should create an array where the `randomValue` is your original returned VRF number and `n` is the desired number of random numbers.
+
+
+```solidity
+function expand(uint256 randomValue, uint256 n) public pure returns (uint256[] memory expandedValues) {
+ expandedValues = new uint256[](n);
+ for (uint256 i = 0; i < n; i++) {
+ expandedValues[i] = uint256(keccak256(abi.encode(randomValue, i)));
+ }
+ return expandedValues;
+}
+
+```
+
+## Having multiple VRF requests in flight
+
+If you want to have multiple VRF requests in flight, you might want to create a mapping between the `requestId` and the address of the requester.
+
+
+```solidity
+mapping(bytes32 => address) public requestIdToAddress;
+
+function getRandomNumber() public returns (bytes32 requestId) {
+ require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet");
+ bytes32 requestId = requestRandomness(keyHash, fee);
+ requestIdToAddress[requestId] = msg.sender;
+}
+
+function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
+ address requestAddress = requestIdToAddress[requestId];
+}
+```
+
+If you want to keep order when a request was made, you might want to use a mapping of `requestId` to the index/order of this request.
+
+
+```solidity
+mapping(bytes32 => uint256) public requestIdToRequestNumberIndex;
+uint256 public requestCounter;
+
+function getRandomNumber() public returns (bytes32 requestId) {
+ require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet");
+ bytes32 requestId = requestRandomness(keyHash, fee);
+ requestIdToRequestNumberIndex[requestId] = requestCounter;
+ requestCounter += 1;
+}
+
+function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
+ uint256 requestNumber = requestIdToRequestNumberIndex[requestId];
+}
+```
+
+If you want to keep generated random numbers of several VRF requests, you might want to use a mapping of `requestId` to the returned random number.
+
+
+```solidity
+mapping(bytes32 => uint256) public requestIdToRandomNumber;
+
+function getRandomNumber() public returns (bytes32 requestId) {
+ require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet");
+ return requestRandomness(keyHash, fee);
+}
+
+function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
+ requestIdToRandomNumber[requestId] = randomness;
+}
+```
+
+Feel free to use whatever data structure you prefer.
diff --git a/src/pages/vrf/v1/examples/get-a-random-number.md b/src/pages/vrf/v1/examples/get-a-random-number.md
new file mode 100644
index 00000000000..f6b70af13e3
--- /dev/null
+++ b/src/pages/vrf/v1/examples/get-a-random-number.md
@@ -0,0 +1,54 @@
+---
+layout: ../../../../layouts/MainLayout.astro
+section: legacy
+date: Last Modified
+title: "Get a Random Number [v1]"
+permalink: "docs/vrf/v1/examples/get-a-random-number/"
+whatsnext: { "API Reference": "/vrf/v1/api-reference/", "Supported Networks": "/vrf/v1/supported-networks/" }
+metadata:
+ description: "How to generate a random number inside a smart contract using Chainlink VRF."
+setup: |
+ import VrfCommon from "@features/vrf/v1/common/VrfCommon.astro"
+---
+
+
+
+This page explains how to get a random number inside a smart contract using Chainlink VRF.
+
+## Random Number Consumer
+
+Chainlink VRF follows the [Request & Receive Data](/any-api/introduction/) cycle. To consume randomness, your contract should inherit from [VRFConsumerBase](https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/VRFConsumerBase.sol) and define two required functions:
+
+- `requestRandomness`, which makes the initial request for randomness.
+- `fulfillRandomness`, which is the function that receives and does something with verified randomness.
+
+The contract should own enough LINK to pay the specified fee. The beginner walkthrough explains how to [fund your contract](/resources/fund-your-contract/).
+
+Note, the below values have to be configured correctly for VRF requests to work. You can find the respective values for your network in the [VRF Contracts page](/vrf/v1/supported-networks).
+
+- `LINK Token` - LINK token address on the corresponding network (Ethereum, Polygon, BSC, etc)
+- `VRF Coordinator` - address of the Chainlink VRF Coordinator
+- `Key Hash` - public key against which randomness is generated
+- `Fee` - fee required to fulfill a VRF request
+
+:::tip[Security Considerations]
+Be sure to look your contract over with [these security considerations](/vrf/v1/security) in mind!
+:::
+
+:::note[Remember to fund your contract with LINK!]
+Requesting randomness will fail unless your deployed contract has enough LINK to pay for it. **Learn how to [Acquire testnet LINK](/resources/acquire-link/) and [Fund your contract](/resources/fund-your-contract/)**.
+:::
+
+::solidity-remix[/samples/VRF/RandomNumberConsumer.sol]
+
+:::note[Maximum Gas for Callback]
+If your `fulfillRandomness` function uses more than 200k gas, the transaction will fail.
+:::
+
+## Getting More Randomness
+
+If you are looking for how to turn a single result into multiple random numbers, check out our guide on [Randomness Expansion](/vrf/v1/best-practices/#getting-multiple-random-numbers).
+
+## Network Congestion and Responsiveness
+
+Network congestion can occur on all blockchains from time to time, which may result in transactions taking longer to get included in a block. During times of network congestion, the VRF service will continue responding to randomness requests, but fulfillment response times will corresponding increase based on the level of congestion. It is important you account for this in your use case and set expectations accordingly.
diff --git a/src/pages/vrf/v1/introduction.md b/src/pages/vrf/v1/introduction.md
new file mode 100644
index 00000000000..45c63306f87
--- /dev/null
+++ b/src/pages/vrf/v1/introduction.md
@@ -0,0 +1,38 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: legacy
+date: Last Modified
+title: "Introduction to Chainlink VRF [v1]"
+permalink: "docs/vrf/v1/introduction/"
+whatsnext:
+ {
+ "Get a Random Number": "/vrf/v1/examples/get-a-random-number/",
+ "API Reference": "/vrf/v1/api-reference/",
+ "Supported Networks": "/vrf/v1/supported-networks/",
+ }
+metadata:
+ title: "Generate Random Numbers for Smart Contracts using Chainlink VRF"
+ description: "Learn how to securely generate random numbers for your smart contract with Chainlink VRF (an RNG). This guide uses Solidity code examples."
+setup: |
+ import VrfCommon from "@features/vrf/v1/common/VrfCommon.astro"
+---
+
+
+
+
+
+## Generate Random Numbers in your Smart Contracts
+
+Chainlink VRF (Verifiable Random Function) is a provably-fair and verifiable source of randomness designed for smart contracts. Smart contract developers can use Chainlink VRF as a tamper-proof random number generator (RNG) to build reliable smart contracts for any applications which rely on unpredictable outcomes:
+
+- Blockchain games and NFTs
+- Random assignment of duties and resources (e.g. randomly assigning judges to cases)
+- Choosing a representative sample for consensus mechanisms
+
+Learn how to write smart contracts that consume random numbers: [Get a Random Number](/vrf/v1/examples/get-a-random-number/).
+
+## On-chain Verification of Randomness
+
+Chainlink VRF enables smart contracts to access randomness without compromising on security or usability. With every new request for randomness, Chainlink VRF generates a random number and cryptographic proof of how that number was determined. The proof is published and verified on-chain before it can be used by any consuming applications. This process ensures that the results cannot be tampered with nor manipulated by anyone, including oracle operators, miners, users and even smart contract developers.
+
+Read more about Chainlink VRF in [our announcement post](https://blog.chain.link/verifiable-random-functions-vrf-random-number-generation-rng-feature/).
diff --git a/src/pages/vrf/v1/security.md b/src/pages/vrf/v1/security.md
new file mode 100644
index 00000000000..b76b485966e
--- /dev/null
+++ b/src/pages/vrf/v1/security.md
@@ -0,0 +1,78 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: legacy
+date: Last Modified
+title: "VRF Security Considerations [v1]"
+permalink: "docs/vrf/v1/security/"
+setup: |
+ import VrfCommon from "@features/vrf/v1/common/VrfCommon.astro"
+---
+
+
+
+Gaining access to high quality randomness on-chain requires a solution like Chainlink's VRF, but it also requires you to understand some of the ways that randonmess generation can be manipulated by miners/validators. Here are some of the top security considerations you should review in your project.
+
+- [Use `requestId` to match randomness requests with their fulfillment in order](#use-requestid-to-match-randomness-requests-with-their-fulfillment-in-order)
+- [Choose a safe block confirmation time, which will vary between blockchains](#choose-a-safe-block-confirmation-time-which-will-vary-between-blockchains)
+- [Do not re-request randomness, even if you don't get an answer right away](#do-not-re-request-randomness-even-if-you-dont-get-an-answer-right-away)
+- [Don't accept bids/bets/inputs after you have made a randomness request](#dont-accept-bidsbetsinputs-after-you-have-made-a-randomness-request)
+- [`fulfillRandomness` must not revert](#fulfillrandomness-must-not-revert)
+- [Use `VRFConsumerBase` in your contract, to interact with the VRF service](#use-vrfconsumerbase-in-your-contract-to-interact-with-the-vrf-service)
+
+## Use `requestId` to match randomness requests with their fulfillment in order
+
+If your contract could have multiple VRF requests in flight simultaneously, you must ensure that the order in which the VRF fulfillments arrive cannot be used to manipulate your contract's user-significant behavior.
+
+Blockchain miners/validators can control the order in which your requests appear on-chain, and hence the order in which your contract responds to them.
+
+For example, if you made randomness requests `A`, `B`, `C` in short succession, there is no guarantee that the associated randomness fulfillments will also be in order `A`, `B`, `C`. The randomness fulfillments might just as well arrive at your contract in order `C`, `A`, `B` or any other order.
+
+We recommend using the `requestID` to match randomness requests with their corresponding fulfillments.
+
+## Choose a safe block confirmation time, which will vary between blockchains
+
+:::note[Customizing block confirmation time]
+[Reach out to customize your VRF block confirmation time](https://chainlinkcommunity.typeform.com/to/OYQO67EF) as this configuration must be done on the VRF service, and cannot be configured as part of a VRF request.
+:::
+
+In principle, miners and validators of your underlying blockchain could rewrite the chain's history to put a randomness request from your contract into a different block, which would result in a different VRF output. Note that this does not enable a miner to determine the random value in advance. It only enables them to get a fresh random value that may or not be to their advantage. By way of analogy, they can only re-roll the dice, not predetermine or predict which side it will land on.
+
+You must choose an appropriate confirmation time for the randomness requests you make (i.e. how many blocks the the VRF service waits before writing a fulfillment to the chain) to make such rewrite attacks unprofitable in the context of your application and its value-at-risk.
+
+On proof-of-stake blockchains (e.g. BSC, Polygon), what block confirmation time is considered secure depends on the specifics of their consensus mechanism and whether you're willing to trust any underlying assumptions of (partial) honesty of validators.
+
+For further details, take a look at the consensus documentation for the chain you want to use:
+
+- [Ethereum Consensus Mechanisms](https://ethereum.org/en/developers/docs/consensus-mechanisms/)
+- [BNB Chain Consensus Docs](https://docs.binance.org/smart-chain/guides/concepts/consensus.html)
+- [Polygon Consensus Docs](https://docs.matic.network/docs/contribute/bor/consensus/)
+
+Understanding the blockchains you build your application on is very important. You should take time to understand [chain reorganization](https://blog.ethereum.org/2015/08/08/chain-reorganisation-depth-expectations/) which will also result in a different VRF output, which could be exploited.
+
+## Do not re-request randomness, even if you don't get an answer right away
+
+Doing so would give the VRF service provider the option to withhold a VRF fulfillment, if it doesn't like the outcome, and wait for the re-request in the hopes that it gets a better outcome, similar to the considerations with block confirmation time.
+
+## Don't accept bids/bets/inputs after you have made a randomness request
+
+Consider the example of a contract that mints a random NFT in response to a users' actions.
+
+The contract should:
+
+1. record whatever actions of the user may affect the generated NFT
+1. **stop accepting further user actions that may affect the generated NFT** and issue a randomness request
+1. on randomness fulfillment, mint the NFT
+
+Generally speaking, whenever an outcome in your contract depends on some user-supplied inputs and randomness, the contract should not accept any additional user-supplied inputs once the randomness request has been issued.
+
+Otherwise, the cryptoeconomic security properties may be violated by an attacker that can rewrite the chain.
+
+## `fulfillRandomness` must not revert
+
+If your fulfillRandomness implementation reverts, the VRF service will not attempt to call it a second time. Make sure your contract logic does not revert. Consider simply storing the randomness and taking more complex follow-on actions in separate contract calls made by you or your users.
+
+## Use `VRFConsumerBase` in your contract, to interact with the VRF service
+
+`VRFConsumerBase` tracks important state which needs to be synchronized with the `VRFCoordinator` state. Some users fold `VRFConsumerBase` into their own contracts, but this means taking on significant extra complexity, so we advise against doing so.
+
+Along the same lines, don't override `rawFulfillRandomness`.
diff --git a/src/pages/vrf/v1/supported-networks.md b/src/pages/vrf/v1/supported-networks.md
new file mode 100644
index 00000000000..28ed906a3a0
--- /dev/null
+++ b/src/pages/vrf/v1/supported-networks.md
@@ -0,0 +1,104 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: legacy
+date: Last Modified
+title: "Chainlink VRF Supported Networks [v1]"
+permalink: "docs/vrf/v1/supported-networks/"
+metadata:
+ title: "Chainlink VRF v1 Supported Networks"
+setup: |
+ import VrfCommon from "@features/vrf/v1/common/VrfCommon.astro"
+---
+
+
+
+Chainlink VRF allows you to integrate provably-fair and verifiably random data in your smart contract.
+
+For implementation details, read [Introduction to Chainlink VRF](/vrf/v1/introduction).
+
+## Polygon (Matic) Mainnet
+
+:::tip[Important]
+The LINK provided by the [Polygon (Matic) Bridge](https://wallet.polygon.technology/bridge) is not ERC-677 compatible, so cannot be used with Chainlink oracles. However, it can be [**converted to the official LINK token on Polygon (Matic) using Chainlink's PegSwap service**](https://pegswap.chain.link/)
+:::
+
+| Item | Value |
+| --------------- | -------------------------------------------------------------------- |
+| LINK Token | `0xb0897686c545045aFc77CF20eC7A532E3120E0F1` |
+| VRF Coordinator | `0x3d2341ADb2D31f1c5530cDC622016af293177AE0` |
+| Key Hash | `0xf86195cf7690c55907b2b611ebb7343a6f649bff128701cc542f0569e2c549da` |
+| Fee | 0.0001 LINK |
+
+:::note[VRF Response Times on Polygon]
+VRF responses are generated after 10 block confirmations on Polygon by default. Please [get in touch with us](https://chainlinkcommunity.typeform.com/to/OYQO67EF?page=docs-VRF) if you require VRF responses to be generated after a higher number of block confirmations, based on what you feel is best for achieving secure finality times on Polygon.
+:::
+
+## Polygon (Matic) Mumbai Testnet
+
+:::note[Mumbai Faucet]
+Testnet LINK and MATIC are available from [the official Matic faucet](https://faucet.polygon.technology/) and https://faucets.chain.link/mumbai.
+:::
+
+| Item | Value |
+| --------------- | -------------------------------------------------------------------- |
+| LINK Token | `0x326C977E6efc84E512bB9C30f76E30c160eD06FB` |
+| VRF Coordinator | `0x8C7382F9D8f56b33781fE506E897a4F1e2d17255` |
+| Key Hash | `0x6e75b569a01ef56d18cab6a8e71e6600d6ce853834d4a5748b720d06f878b3a4` |
+| Fee | 0.0001 LINK |
+
+## BNB Chain Mainnet
+
+:::tip[Important]
+The LINK provided by the [BNB Chain Bridge](https://www.bnbchain.world/en/bridge) is not ERC-677 compatible, so cannot be used with Chainlink oracles. However, it can be [**converted to the official LINK token on BNB Chain using Chainlink's PegSwap service**](https://pegswap.chain.link/).
+:::
+
+| Item | Value |
+| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| LINK Token | `0x404460C6A5EdE2D891e8297795264fDe62ADBB75` |
+| VRF Coordinator | `0x747973a5A2a4Ae1D3a8fDF5479f1514F65Db9C31` |
+| Key Hash | `0xc251acd21ec4fb7f31bb8868288bfdbaeb4fbfec2df3735ddbd4f7dc8d60103c` |
+| Fee | 0.2 LINK - initial fees on BNB Chain are meant to cover the highest gas cost prices. To use VRF more efficiently, please [contact us](https://chainlinkcommunity.typeform.com/to/OYQO67EF?page=docs-VRF) |
+
+:::note[Early Access]
+For the most efficient consumption of Chainlink VRF on BNB Chain, please contact us using [this form](https://chainlinkcommunity.typeform.com/to/OYQO67EF?page=docs-VRF) to create a payment channel, through which we can provide VRF to you at the cost of BNB Chain network gas fees. You will only be paying in LINK for the gas costs incurred by the Chainlink VRF service from calling your smart contract.
+:::
+
+## BNB Chain Testnet
+
+:::note[BNB Chain Faucet]
+Testnet LINK is available from https://faucets.chain.link/chapel
+:::
+
+| Item | Value |
+| --------------- | --------------------------------------------------------------------- |
+| LINK | `0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06` |
+| VRF Coordinator | `0xa555fC018435bef5A13C6c6870a9d4C11DEC329C ` |
+| Key Hash | `0xcaf3c3727e033261d383b315559476f48034c13b18f8cafed4d871abe5049186 ` |
+| Fee | 0.1 LINK |
+
+## Ethereum Mainnet
+
+| Item | Value |
+| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| LINK Token | `0x514910771AF9Ca656af840dff83E8264EcF986CA` |
+| VRF Coordinator | `0xf0d54349aDdcf704F77AE15b96510dEA15cb7952` |
+| Key Hash | `0xAA77729D3466CA35AE8D28B3BBAC7CC36A5031EFDC430821C02BC31A238AF445` |
+| Fee | 2 LINK - initial fees on Ethereum are meant to cover the highest gas cost prices. To use VRF more efficiently, please [contact us](https://chainlinkcommunity.typeform.com/to/OYQO67EF?page=docs-VRF) |
+
+:::note[Early Access]
+For the most efficient consumption of Chainlink VRF on Ethereum, please contact us using [this form](https://chainlinkcommunity.typeform.com/to/OYQO67EF?page=docs-VRF) to create a payment channel, through which we can provide VRF to you at the cost of Ethereum network gas fees. You will only be paying in LINK for the gas costs incurred by the Chainlink VRF service from calling your smart contract.
+:::
+
+## Goerli
+
+:::note[Goerli Faucets]
+Testnet LINK is available from https://faucets.chain.link/goerli
+Testnet ETH is available from https://goerlifaucet.com/ or faucets listed at https://faucetlink.to/goerli
+:::
+
+| Item | Value |
+| --------------- | -------------------------------------------------------------------- |
+| LINK | `0x326C977E6efc84E512bB9C30f76E30c160eD06FB` |
+| VRF Coordinator | `0x2bce784e69d2Ff36c71edcB9F88358dB0DfB55b4` |
+| Key Hash | `0x0476f9a745b61ea5c0ab224d3a6e4c99f0b02fce4da01143a4f70aa80ae76e8a` |
+| Fee | 0.1 LINK |
diff --git a/src/pages/vrf/v2/best-practices.md b/src/pages/vrf/v2/best-practices.md
new file mode 100644
index 00000000000..505ac325815
--- /dev/null
+++ b/src/pages/vrf/v2/best-practices.md
@@ -0,0 +1,111 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "VRF Best Practices"
+permalink: "docs/vrf/v2/best-practices/"
+metadata:
+ title: "Chainlink VRF API Reference"
+ description: "Best pracices for using Chainlink VRF."
+setup: |
+ import VrfCommon from "@features/vrf/v2/common/VrfCommon.astro"
+---
+
+
+
+These are example best practices for using Chainlink VRF. To explore more applications of VRF, refer to our [blog](https://blog.chain.link/).
+
+## Getting a random number within a range
+
+If you need to generate a random number within a given range, use [modulo](https://docs.soliditylang.org/en/v0.8.7/types.html#modulo) to define the limits of your range. Below you can see how to get a random number in a range from 1 to 50.
+
+
+```solidity
+function fulfillRandomWords(
+ uint256, /* requestId */
+ uint256[] memory randomWords
+) internal override {
+ // Assuming only one random word was requested.
+ s_randomRange = (randomWords[0] % 50) + 1;
+}
+
+```
+
+## Getting multiple random values
+
+If you want to get multiple random values from a single VRF request, you can request this directly with the `numWords` argument:
+
+- If you are using the VRF v2 subscription method, see the [Get a Random Number](/vrf/v2/subscription/examples/get-a-random-number/) guide for an example where one request returns multiple random values.
+- If you are using the VRF v2 direct funding method, see the [Get a Random Number](/vrf/v2/direct-funding/examples/get-a-random-number/) guide for an example where one request returns multiple random values.
+
+## Processing simultaneous VRF requests
+
+If you want to have multiple VRF requests processing simultaneously, create a mapping between `requestId` and the response. You might also create a mapping between the `requestId` and the address of the requester to track which address made each request.
+
+
+```solidity
+mapping(uint256 => uint256[]) public s_requestIdToRandomWords;
+mapping(uint256 => address) public s_requestIdToAddress;
+uint256 public s_requestId;
+
+function requestRandomWords() external onlyOwner returns (uint256) {
+ uint256 requestId = COORDINATOR.requestRandomWords(
+ keyHash,
+ s_subscriptionId,
+ requestConfirmations,
+ callbackGasLimit,
+ numWords
+ );
+ s_requestIdToAddress[requestId] = msg.sender;
+
+ // Store the latest requestId for this example.
+ s_requestId = requestId;
+
+ // Return the requestId to the requester.
+ return requestId;
+}
+
+function fulfillRandomWords(
+ uint256 requestId,
+ uint256[] memory randomWords
+ ) internal override {
+ // You can return the value to the requester,
+ // but this example simply stores it.
+ s_requestIdToRandomWords[requestId] = randomWords;
+}
+```
+
+You could also map the `requestId` to an index to keep track of the order in which a request was made.
+
+
+```solidity
+mapping(uint256 => uint256) s_requestIdToRequestIndex;
+mapping(uint256 => uint256[]) public s_requestIndexToRandomWords;
+uint256 public requestCounter;
+
+function requestRandomWords() external onlyOwner {
+ uint256 requestId = COORDINATOR.requestRandomWords(
+ keyHash,
+ s_subscriptionId,
+ requestConfirmations,
+ callbackGasLimit,
+ numWords
+ );
+ s_requestIdToRequestIndex[requestId] = requestCounter;
+ requestCounter += 1;
+}
+
+function fulfillRandomWords(
+ uint256 requestId,
+ uint256[] memory randomWords
+ ) internal override {
+ uint256 requestNumber = s_requestIdToRequestIndex[requestId];
+ s_requestIndexToRandomWords[requestNumber] = randomWords;
+}
+```
+
+## Processing VRF responses through different execution paths
+
+If you want to process VRF responses depending on predetermined conditions, you can create an `enum`. When requesting for randomness, map each `requestId` to an enum. This way, you can handle different execution paths in `fulfillRandomWords`. See the following example:
+
+::solidity-remix[samples/VRF/VRFv2MultiplePaths.sol]
diff --git a/src/pages/vrf/v2/direct-funding/examples/get-a-random-number.md b/src/pages/vrf/v2/direct-funding/examples/get-a-random-number.md
new file mode 100644
index 00000000000..d44dc0d9da5
--- /dev/null
+++ b/src/pages/vrf/v2/direct-funding/examples/get-a-random-number.md
@@ -0,0 +1,115 @@
+---
+layout: ../../../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Get a Random Number"
+permalink: "docs/vrf/v2/direct-funding/examples/get-a-random-number/"
+whatsnext:
+ {
+ "Security Considerations": "/vrf/v2/security/",
+ "Best Practices": "/vrf/v2/best-practices/",
+ "Migrating from VRF v1": "/vrf/v2/direct-funding/migration-from-v1/",
+ "Supported Networks": "/vrf/v2/direct-funding/supported-networks/",
+ }
+metadata:
+ description: "How to generate a random number inside a smart contract using Chainlink VRF v2 - Direct funding method."
+setup: |
+ import VrfCommon from "@features/vrf/v2/common/VrfCommon.astro"
+ import CodeSample from "@components/CodeSample/CodeSample.astro"
+---
+
+
+
+This guide explains how to get random values using a simple contract to request and receive random values from Chainlink VRF v2 without managing a subscription. To explore more applications of VRF, refer to our [blog](https://blog.chain.link/).
+
+## Requirements
+
+This guide assumes that you know how to create and deploy smart contracts on Ethereum testnets using the following tools:
+
+- [The Remix IDE](https://remix.ethereum.org/)
+- [MetaMask](https://metamask.io/)
+- [Goerli testnet ETH](/resources/link-token-contracts/#goerli-testnet)
+
+If you are new to developing smart contracts on Ethereum, see the [Getting Started](/getting-started/conceptual-overview/) guide to learn the basics.
+
+## Create and deploy a VRF v2 compatible contract
+
+For this example, use the [VRFv2DirectFundingConsumer.sol](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFv2DirectFundingConsumer.sol) sample contract. This contract imports the following dependencies:
+
+- `VRFV2WrapperConsumerBase.sol`[(link)](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFV2WrapperConsumerBase.sol)
+- `ConfirmedOwner.sol`[(link)](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/ConfirmedOwner.sol)
+
+The contract also includes pre-configured values for the necessary request parameters such as `callbackGasLimit`, `requestConfirmations`, the number of random words `numWords`, the VRF v2 Wrapper address `wrapperAddress`, and the LINK token address `linkAddress`. You can change these parameters if you want to experiment on different testnets.
+
+Build and deploy the contract on Goerli.
+
+1. Open the [`VRFv2DirectFundingConsumer.sol` contract](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFv2DirectFundingConsumer.sol) in Remix.
+
+
+
+
+1. On the **Compile** tab in Remix, compile the `VRFv2DirectFundingConsumer` contract.
+
+1. Configure your deployment. On the **Deploy** tab in Remix, select the **Injected Web3 Environment** and select the `VRFv2DirectFundingConsumer` contract from the contract list.
+
+1. Click the **Deploy** button to deploy your contract on-chain. MetaMask opens and asks you to confirm the transaction.
+
+1. After you deploy your contract, copy the address from the **Deployed Contracts** list in Remix. Before you can request randomness from VRF v2, you must fund your consuming contract with enough LINK tokens in order to request for randomness. Next, [fund your contract](#fund-your-contract).
+
+## Fund Your Contract
+
+Requests for randomness will fail unless your consuming contract has enough LINK. Learn how to [Acquire testnet LINK](/resources/acquire-link/) and [Fund your contract](/resources/fund-your-contract/). For this example, funding with 2 LINK should be sufficient.
+
+## Request random values
+
+The deployed contract requests random values from Chainlink VRF, receives those values, builds a struct `RequestStatus` containing them, and stores the struct in a mapping `s_requests`. Run the `requestRandomWords()` function on your contract to start the request.
+
+1. Return to Remix and view your deployed contract functions in the **Deployed Contracts** list.
+
+1. Click the `requestRandomWords()` function to send the request for random values to Chainlink VRF. MetaMask opens and asks you to confirm the transaction. **Note** Remix IDE doesn't set the right gas limit. For this example to work, set a gas limit of _400,000_ as explained [here](https://metamask.zendesk.com/hc/en-us/articles/360022895972). After you approve the transaction, Chainlink VRF processes your request. Chainlink VRF fulfills the request and returns the random values to your contract in a callback to the `fulfillRandomWords()` function. At this point, a new key `requestId` is added to the mapping `s_requests`.
+
+ Depending on current testnet conditions, it might take a few minutes for the callback to return the requested random values to your contract.
+
+1. To fetch the request ID of your request, call `lastRequestId()`.
+
+1. After the oracle returns the random values to your contract, the mapping `s_requests` is updated. The received random values are stored in `s_requests[_requestId].randomWords`.
+
+1. Call `getRequestStatus()` and specify the `requestId` to display the random words.
+
+:::note[Note on Requesting Randomness]
+Do not re-request randomness even if you do **not** receive an answer right away. Doing so would give the VRF service provider the option to withhold a VRF fulfillment, if it doesn't like the outcome, and wait for the re-request in the hopes that it gets a better outcome. This is similar to the considerations with block confirmation time. For more information, see the [VRF Security Considerations](/vrf/v2/security/) page.
+:::
+
+## Analyzing the contract
+
+In this example, the consuming contract uses static configuration parameters.
+
+::solidity-remix[samples/VRF/VRFv2DirectFundingConsumer.sol]
+
+The parameters define how your requests will be processed. You can find the values for your network in the [Supported networks](/vrf/v2/direct-funding/supported-networks/) page.
+
+- `uint32 callbackGasLimit`: The limit for how much gas to use for the callback request to your contract's `fulfillRandomWords()` function. It must be less than the `maxGasLimit` limit on the coordinator contract minus the `wrapperGasOverhead`. See the [VRF v2 Direct funding limits](/vrf/v2/direct-funding/#limits) for more details. Adjust this value for larger requests depending on how your `fulfillRandomWords()` function processes and stores the received random values. If your `callbackGasLimit` is not sufficient, the callback will fail and your consuming contract is still charged for the work done to generate your requested random values.
+
+- `uint16 requestConfirmations`: How many confirmations the Chainlink node should wait before responding. The longer the node waits, the more secure the random value is. It must be greater than the `minimumRequestBlockConfirmations` limit on the coordinator contract.
+
+- `uint32 numWords`: How many random values to request. If you can use several random values in a single callback, you can reduce the amount of gas that you spend per random value. The total cost of the callback request depends on how your `fulfillRandomWords()` function processes and stores the received random values, so adjust your `callbackGasLimit` accordingly.
+
+The contract includes the following functions:
+
+- `requestRandomWords()`: Takes your specified parameters and submits the request to the VRF v2 Wrapper contract.
+
+- `fulfillRandomWords()`: Receives random values and stores them with your contract.
+
+- `getRequestStatus()`: Retrive request details for a given `_requestId`.
+
+- `withdrawLink()`: At any time, the owner of the contract can withdraw outstanding LINK balance from it.
+
+:::note[Security Considerations]
+Be sure to review your contracts to make sure they follow the best practices on the [security considerations](/vrf/v2/security/) page.
+:::
+
+## Clean up
+
+After you are done with this contract, you can retrieve the remaining testnet LINK to use with other examples.
+
+1. Call `withdrawLink()` function. MetaMask opens and asks you to confirm the transaction. After you approve the transaction, the remaining LINK will be transfered from your consuming contract to your wallet address.
diff --git a/src/pages/vrf/v2/direct-funding/index.md b/src/pages/vrf/v2/direct-funding/index.md
new file mode 100644
index 00000000000..1e2fe5d176f
--- /dev/null
+++ b/src/pages/vrf/v2/direct-funding/index.md
@@ -0,0 +1,112 @@
+---
+layout: ../../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Direct Funding Method"
+permalink: "docs/vrf/v2/direct-funding/"
+whatsnext:
+ {
+ "Get a Random Number": "/vrf/v2/direct-funding/examples/get-a-random-number/",
+ "Supported Networks": "/vrf/v2/direct-funding/supported-networks/",
+ }
+metadata:
+ title: "Generate Random Numbers for Smart Contracts using Chainlink VRF v2 - Direct funding method"
+ description: "Learn how to securely generate random numbers for your smart contract with Chainlink VRF v2. This guide uses the Direct funding method."
+setup: |
+ import VrfCommon from "@features/vrf/v2/common/VrfCommon.astro"
+---
+
+
+
+This guide explains how to generate random numbers using the Direct funding method. This method doesn't require a subscription and is optimal for one-off requests for randomness. This method also works best for applications where your end-users must pay the fees for VRF because the cost of the request is determined at request time.
+
+## VRF Direct funding
+
+Unlike the [subscription method](/vrf/v2/subscription/), the Direct funding method does not require you to create subscriptions and pre-fund them. Instead, you must directly fund consuming contracts with LINK tokens before they request randomness.
+
+For Chainlink VRF v2 to fulfill your requests, you must have a sufficient amount of LINK in your consuming contract. Gas cost calculation includes the following variables:
+
+- **Gas price:** The current gas price, which fluctuates depending on network conditions.
+
+- **Callback gas:** The amount of gas used for the callback request that returns your requested random values.
+
+- **Verification gas:** The amount of gas used to verify randomness on-chain.
+
+- **Wrapper overhead gas:** The amount of gas used by the VRF Wrapper contract. See the [Request and Receive Data](#request-and-receive-data) section for details about the VRF v2 Wrapper contract design.
+
+The gas price depends on current network conditions. The callback gas depends on your callback function and the number of random values in your request. You define the limits that you are willing to spend for the request with the following variable:
+
+- **Callback gas limit:** Specifies the maximum amount of gas you are willing to spend on the callback request. Define this limit by specifying the `callbackGasLimit` value in your request.
+
+:::note[Note on transaction costs]
+
+Because the consuming contract directly pays the LINK for the request, the cost is calculated during the request and not during the callback when the randomness is fulfilled. Test your callback function to learn how to correctly estimate the callback gas limit.
+
+- If the gas limit is underestimated, the callback fails and the consuming contract is still charged for the work done to generate the requested random values.
+- If the gas limit is overestimated, the callback function will be executed but your contract is not refunded for the excess gas amount that you paid.
+
+Make sure that your consuming contracts are funded with enough LINK tokens to cover the transaction costs. If the consuming contract doesn't have enough LINK tokens, your request will revert.
+:::
+
+## Request and Receive Data
+
+### End To End Diagram
+
+
+
+Two types of accounts exist in the Ethereum ecosystem:
+
+- EOA (Externally Owned Account): An externally owned account that has a private key and can control a smart contract. Transactions can be initiated only by EOAs.
+- Smart contract: A smart contract that does not have a private key and executes what it has been designed for as a decentralized application.
+
+The Chainlink VRF v2 solution uses both off-chain and on-chain components:
+
+- [VRF v2 Wrapper (on-chain component)](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFV2Wrapper.sol): A wrapper for the VRF Coordinator that provides an interface for consuming contracts.
+- [VRF v2 Coordinator (on-chain component)](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFCoordinatorV2.sol): A contract designed to interact with the VRF service. It emits an event when a request for randomness is made, and then verifies the random number and proof of how it was generated by the VRF service.
+- VRF service (off-chain component): Listens for requests by subscribing to the VRF Coordinator event logs and calculates a random number based on the block hash and nonce. The VRF service then sends a transaction to the `VRFCoordinator` including the random number and a proof of how it was generated.
+
+### Explanation
+
+Requests to Chainlink VRF v2 follow the [Request & Receive Data](#request-and-receive-data) cycle. The VRF wrapper calls the coordinator to process the request using the following steps:
+
+1. The consuming contract must inherit [VRFV2WrapperConsumerBase](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFV2WrapperConsumerBase.sol) and implement the `fulfillRandomWords` function, which is the _callback VRF function_. Submit your VRF request by calling the `requestRandomness` function in the [VRFV2WrapperConsumerBase](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFV2WrapperConsumerBase.sol) contract. Include the following parameters in your request:
+
+ - `requestConfirmations`: The number of block confirmations the VRF service will wait to respond. The minimum and maximum confirmations for your network can be found [here](/vrf/v2/direct-funding/supported-networks/#configurations).
+ - `callbackGasLimit`: The maximum amount of gas to pay for completing the callback VRF function.
+ - `numWords`: The number of random numbers to request. You can find the maximum number of random values per request for your network in the [Supported networks](/vrf/v2/direct-funding/supported-networks/#configurations) page.
+
+1. The consuming contract calls the [VRFV2Wrapper](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFV2Wrapper.sol) `calculateRequestPrice` function to estimate the total transaction cost to fulfill randomness. Then the consuming contract calls the [LinkToken](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.4/LinkToken.sol) `transferAndCall` function to pay the wrapper with the calculated request price. This method sends LINK tokens and executes the [VRFV2Wrapper](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFV2Wrapper.sol) `onTokenTransfer` logic. This triggers the VRF [VRF Coordinator](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFCoordinatorV2.sol) `requestRandomWords` function to request randomness.
+ The final gas cost to fulfill randomness is estimated based on how much gas is expected for the verification and callback. The total gas cost in wei uses the following formula:
+
+ ```
+ (Gas price * (Verification gas + Callback gas limit + Wrapper gas Overhead)) = total gas cost
+ ```
+
+ The total gas cost is converted to LINK using the ETH/LINK data feed. In the unlikely event that the data feed is unavailable, the VRF Wrapper uses the `fallbackWeiPerUnitLink` value for the conversion instead. The `fallbackWeiPerUnitLink` value is defined in the [VRF v2 Wrapper contract](/vrf/v2/direct-funding/supported-networks/#configurations) for your selected network.
+
+ A LINK premium is then added to the total gas cost. The premium is divided in two parts:
+
+ - Wrapper premium: The premium percentage. You can find the percentage for your network in the [Supported networks](/vrf/v2/direct-funding/supported-networks/#configurations) page.
+ - Coordinator premium: A flat fee. This premium is defined in the `fulfillmentFlatFeeLinkPPMTier1` parameter in millionths of LINK. You can find the flat fee of the coordinator for your network in the [Supported networks](/vrf/v2/direct-funding/supported-networks/#configurations) page.
+
+ ```
+ ((total gas cost * Wrapper premium) + Coordinator premium) = total request cost
+ ```
+
+1. The VRF coordinator emits an event.
+
+1. The event is picked up by the VRF service and waits for the specified number of block confirmations to respond back to the VRF coordinator with the random values and a proof (`requestConfirmations`).
+
+1. The VRF coordinator verifies the proof on-chain. Then, it calls back the wrapper contract `fulfillRandomWords` function.
+
+1. Finally, the VRF Wrapper calls back your consuming contract.
+
+## Limits
+
+You can see the configuration for each network on the [Supported networks](/vrf/v2/direct-funding/supported-networks/) page. You can also view the full configuration for each VRF v2 Wrapper contract directly in Etherscan. As an example, view the [Ethereum Mainnet VRF v2 Wrapper contract](https://etherscan.io/address/0x5A861794B927983406fCE1D062e00b9368d97Df6#readContract) configuration by calling `getConfig` function.
+
+- Each wrapper has a `maxNumWords` parameter that limits the maximum number of random values you can receive in each request.
+
+:::note[Note on maximum gas limit]
+The maximum allowed `callbackGasLimit` value for your requests is defined in the [Coordinator contract supported networks](/vrf/v2/subscription/supported-networks/) page. Because the VRF v2 Wrapper adds an overhead, your `callbackGasLimit` must not exceed `maxGasLimit - wrapperGasOverhead`.
+:::
diff --git a/src/pages/vrf/v2/direct-funding/migration-from-v1.md b/src/pages/vrf/v2/direct-funding/migration-from-v1.md
new file mode 100644
index 00000000000..4fe86ced752
--- /dev/null
+++ b/src/pages/vrf/v2/direct-funding/migration-from-v1.md
@@ -0,0 +1,33 @@
+---
+layout: ../../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Migrating from VRF v1"
+permalink: "docs/vrf/v2/direct-funding/migration-from-v1/"
+setup: |
+ import VrfCommon from "@features/vrf/v2/common/VrfCommon.astro"
+---
+
+
+
+## Comparison between VRF v1 and VRF v2 (Direct funding method)
+
+The main similarity between VRF v1 and VRF v2 Direct funding method is that consuming contracts must be funded with LINK to pay for requests. However, Chainlink VRF v2 includes several improvements.
+
+- **Variable Callback Gas Limit:** Chainlink VRF v2 lets you adjust the callback gas limit when your smart contract application receives verifiable randomness. Consuming contracts can execute more complex logic in the callback request function that receives the random values. Tasks involving the delivered randomness are handled during the response process. The new gas limits are higher than the VRF V1 limit, and vary depending on the underlying blockchain that you use. See the gas limits on the [Supported networks](/vrf/v2/direct-funding/supported-networks/) page.
+
+- **More configuration capability:** You can define how many block confirmations must pass before verifiable randomness is generated and delivered on-chain when your application makes a request transaction. The range is from 3 to 200 blocks. VRF V1 always waited 10 blocks on Ethereum before delivering on-chain randomness. Select a value that protects your application from block re-organizations while still providing sufficiently low latency from request to response. See the [Security Considerations](/vrf/v2/security/) page to learn more.
+
+- **Multiple Random Outputs in a Single Request:** The [VRF Wrapper contracts](/vrf/v2/direct-funding/supported-networks/) in VRF v2 allow you to request multiple random numbers (multi-word) in a single on-chain transaction, which reduces gas costs. The fulfillment is also a single transaction, which reduces the latency of responses.
+
+## Updating your applications to use VRF v2
+
+To modify your existing smart contract code to work with VRF v2, complete the following changes. See the [Get a Random Number](/vrf/v2/direct-funding/examples/get-a-random-number/) guide for an example.
+
+1. Import and inherit the new [`VRFV2WrapperConsumerBase.sol` contract](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFV2WrapperConsumerBase.sol) and remove the v1 `VRFConsumerBase.sol` import. This contract includes the `fulfillRandomWords` function.
+
+1. Add a `VRFV2WrapperConsumerBase` constructor as shown in the [Get a Random Number](/vrf/v2/direct-funding/examples/get-a-random-number/) example and use the correct VRF v2 Direct funding configuration.
+
+1. You can still call the `requestRandomness` function. However, the v2 `requestRandomness` function requires several different parameters (`callbackGasLimit` , `requestConfirmations` , `numWords`). See the [Supported networks](/vrf/v2/direct-funding/supported-networks/) page to adjust them for your own needs.
+
+1. Change `fulfillRandomness` function calls to `fulfillRandomWords`. Update the call to handle the returned `uint256[]` array instead of the single `uint256` variable.
diff --git a/src/pages/vrf/v2/direct-funding/supported-networks.md b/src/pages/vrf/v2/direct-funding/supported-networks.md
new file mode 100644
index 00000000000..20f2e4cbea0
--- /dev/null
+++ b/src/pages/vrf/v2/direct-funding/supported-networks.md
@@ -0,0 +1,232 @@
+---
+layout: ../../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Supported Networks"
+permalink: "docs/vrf/v2/direct-funding/supported-networks/"
+metadata:
+ title: "Chainlink VRF Contract Addresses"
+ linkToWallet: true
+ image:
+ 0: "/files/OpenGraph_V3.png"
+setup: |
+ import VrfCommon from "@features/vrf/v2/common/VrfCommon.astro"
+---
+
+
+
+Chainlink VRF allows you to integrate provably fair and verifiably random data in your smart contract.
+
+For implementation details, read [Introduction to Chainlink VRF v2 Direct funding method](/vrf/v2/direct-funding/).
+
+## Wrapper Parameters
+
+These parameters are configured in the VRF v2 Wrapper contract. You can view these values by running `getConfig` on the VRF v2 Wrapper or by viewing the VRF v2 Wrapper contract in a blockchain explorer.
+
+- `uint32 stalenessSeconds`: How long the VRF v2 Wrapper waits until we consider the ETH/LINK price used for converting gas costs to LINK is stale and use `fallbackWeiPerUnitLink`.
+- `uint32 wrapperGasOverhead`: The gas overhead of the VRF v2 Wrapper's `fulfillRandomWords` function.
+- `uint32 coordinatorGasOverhead`: The gas overhead of the coordinator's `fulfillRandomWords` function.
+- `uint8 maxNumWords`: Maximum number of words that can be requested in a single wrapped VRF request.
+
+## Coordinator Parameters
+
+Some parameters are important to know and are configured in the coordinator contract. You can view these values by running `getConfig` on the coordinator or by viewing the coordinator contract in a blockchain explorer.
+
+- `uint16 minimumRequestConfirmations`: The minimum number of confirmation blocks on VRF requests before oracles respond
+- `uint32 maxGasLimit`: The maximum gas limit supported for a `fulfillRandomWords` callback. Note that you still need to substract the `wrapperGasOverhead` for the accurate limit, as explained in [Direct funding limits](/vrf/v2/direct-funding/#limits).
+
+## Fee Parameters
+
+Fee parameters are configured in the VRF v2 Wrapper and the VRF v2 Coordinator contracts and specify the premium you pay per request in addition to the gas cost for the transaction. You can view them by running `getConfig` on the VRF v2 Wrapper:
+
+- The `uint32 fulfillmentFlatFeeLinkPPM` parameter is a flat fee and defines the fees per request specified in millionths of LINK.
+- The `uint8 wrapperPremiumPercentage` parameter defines the premium ratio in percentage. For example, a value of _0_ indicates no premium. A value of _15_ indicates a _15%_ premium.
+
+The details for calculating the total transaction cost can be found [here](/vrf/v2/direct-funding/#request-and-receive-data).
+
+## Configurations
+
+- [Ethereum Mainnet](#ethereum-mainnet)
+- [Goerli testnet](#goerli-testnet)
+- [BNB Chain](#bnb-chain)
+- [BNB Chain testnet](#bnb-chain-testnet)
+- [Polygon Mainnet](#polygon-matic-mainnet)
+- [Polygon Mumbai Testnet](#polygon-matic-mumbai-testnet)
+- [Avalanche Mainnet](#avalanche-mainnet)
+- [Avalanche Fuji Testnet](#avalanche-fuji-testnet)
+- [Fantom Mainnet](#fantom-mainnet)
+- [Fantom Testnet](#fantom-testnet)
+
+### Ethereum Mainnet
+
+| Item | Value |
+| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| LINK Token | `0x514910771AF9Ca656af840dff83E8264EcF986CA` |
+| VRF Wrapper | [`0x5A861794B927983406fCE1D062e00b9368d97Df6`](https://etherscan.io/address/0x5A861794B927983406fCE1D062e00b9368d97Df6) |
+| VRF Coordinator | [`0x271682DEB8C4E0901D1a1550aD2e64D568E69909`](https://etherscan.io/address/0x271682DEB8C4E0901D1a1550aD2e64D568E69909) |
+| Wrapper Premium Percentage | 0 |
+| Coordinator Flat Fee | 0.25 LINK |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 10 |
+| Wrapper Gas overhead | 40000 |
+| Coordinator Gas Overhead | 90000 |
+
+### Goerli testnet
+
+:::note[Goerli Faucets]
+Testnet LINK is available from https://faucets.chain.link/goerli
+Testnet ETH is available from https://goerlifaucet.com/ or faucets listed at https://faucetlink.to/goerli
+:::
+
+| Item | Value |
+| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| LINK Token | `0x326C977E6efc84E512bB9C30f76E30c160eD06FB` |
+| VRF Wrapper | [`0x708701a1DfF4f478de54383E49a627eD4852C816`](https://goerli.etherscan.io/address/0x708701a1DfF4f478de54383E49a627eD4852C816) |
+| VRF Coordinator | [`0x2ca8e0c643bde4c2e08ab1fa0da3401adad7734d`](https://goerli.etherscan.io/address/0x2ca8e0c643bde4c2e08ab1fa0da3401adad7734d) |
+| Wrapper Premium Percentage | 0 |
+| Coordinator Flat Fee | 0.25 LINK |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 10 |
+| Wrapper Gas overhead | 40000 |
+| Coordinator Gas Overhead | 90000 |
+
+### BNB Chain
+
+:::tip[Important]
+The LINK provided by the [BNB Chain Bridge](https://www.bnbchain.world/en/bridge) is not ERC-677 compatible, so cannot be used with Chainlink oracles. However, it can be [**converted to the official LINK token on BNB Chain using Chainlink's PegSwap service**](https://pegswap.chain.link/).
+:::
+
+| Item | Value |
+| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| LINK Token | `0x404460C6A5EdE2D891e8297795264fDe62ADBB75` |
+| VRF Wrapper | [`0x721DFbc5Cfe53d32ab00A9bdFa605d3b8E1f3f42`](https://bscscan.com/address/0x721DFbc5Cfe53d32ab00A9bdFa605d3b8E1f3f42) |
+| VRF Coordinator | [`0xc587d9053cd1118f25F645F9E08BB98c9712A4EE`](https://bscscan.com/address/0xc587d9053cd1118f25F645F9E08BB98c9712A4EE) |
+| Wrapper Premium Percentage | 0 |
+| Coordinator Flat Fee | 0.005 LINK |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 10 |
+| Wrapper Gas overhead | 40000 |
+| Coordinator Gas Overhead | 90000 |
+
+### BNB Chain testnet
+
+:::note[BNB Chain Faucet]
+Testnet LINK is available from https://faucets.chain.link/chapel
+:::
+
+| Item | Value |
+| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| LINK Token | `0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06` |
+| VRF Wrapper | [`0x699d428ee890d55D56d5FC6e26290f3247A762bd`](https://testnet.bscscan.com/address/0x699d428ee890d55D56d5FC6e26290f3247A762bd) |
+| VRF Coordinator | [`0x6A2AAd07396B36Fe02a22b33cf443582f682c82f`](https://testnet.bscscan.com/address/0x6A2AAd07396B36Fe02a22b33cf443582f682c82f) |
+| Wrapper Premium Percentage | 0 |
+| Coordinator Flat Fee | 0.005 LINK |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 10 |
+| Wrapper Gas overhead | 40000 |
+| Coordinator Gas Overhead | 90000 |
+
+### Polygon (Matic) Mainnet
+
+:::tip[Important]
+The LINK provided by the [Polygon (Matic) Bridge](https://wallet.polygon.technology/bridge) is not ERC-677 compatible, so cannot be used with Chainlink oracles. However, it can be [**converted to the official LINK token on Polygon (Matic) using Chainlink's PegSwap service**](https://pegswap.chain.link/)
+:::
+
+| Item | Value |
+| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| LINK Token | `0xb0897686c545045aFc77CF20eC7A532E3120E0F1` |
+| VRF Wrapper | [`0x4e42f0adEB69203ef7AaA4B7c414e5b1331c14dc`](https://polygonscan.com/address/0x4e42f0adEB69203ef7AaA4B7c414e5b1331c14dc) |
+| VRF Coordinator | [`0xAE975071Be8F8eE67addBC1A82488F1C24858067`](https://polygonscan.com/address/0xAE975071Be8F8eE67addBC1A82488F1C24858067) |
+| Wrapper Premium Percentage | 0 |
+| Coordinator Flat Fee | 0.0005 LINK |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 10 |
+| Wrapper Gas overhead | 40000 |
+| Coordinator Gas Overhead | 90000 |
+
+### Polygon (Matic) Mumbai Testnet
+
+:::note[Mumbai Faucet]
+Testnet LINK and MATIC are available from [the Polygon faucet](https://faucet.polygon.technology/) and https://faucets.chain.link/mumbai.
+:::
+
+| Item | Value |
+| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| LINK Token | `0x326C977E6efc84E512bB9C30f76E30c160eD06FB ` |
+| VRF Wrapper | [`0x99aFAf084eBA697E584501b8Ed2c0B37Dd136693`](https://mumbai.polygonscan.com/address/0x99aFAf084eBA697E584501b8Ed2c0B37Dd136693) |
+| VRF Coordinator | [`0x7a1BaC17Ccc5b313516C5E16fb24f7659aA5ebed`](https://mumbai.polygonscan.com/address/0x7a1BaC17Ccc5b313516C5E16fb24f7659aA5ebed) |
+| Wrapper Premium Percentage | 0 |
+| Coordinator Flat Fee | 0.0005 LINK |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 10 |
+| Wrapper Gas overhead | 40000 |
+| Coordinator Gas Overhead | 90000 |
+
+### Avalanche Mainnet
+
+| Item | Value |
+| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| LINK Token | `0x5947BB275c521040051D82396192181b413227A3` |
+| VRF Wrapper | [`0x721DFbc5Cfe53d32ab00A9bdFa605d3b8E1f3f42`](https://snowtrace.io/address/0x721DFbc5Cfe53d32ab00A9bdFa605d3b8E1f3f42) |
+| VRF Coordinator | [`0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634`](https://snowtrace.io/address/0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634) |
+| Wrapper Premium Percentage | 0 |
+| Coordinator Flat Fee | 0.005 LINK |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 10 |
+| Wrapper Gas overhead | 40000 |
+| Coordinator Gas Overhead | 90000 |
+
+### Avalanche Fuji Testnet
+
+:::note[Avax Fuji Faucet]
+Testnet LINK is available from https://faucets.chain.link/fuji
+:::
+
+| Item | Value |
+| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| LINK Token | `0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846` |
+| VRF Wrapper | [`0x9345AC54dA4D0B5Cda8CB749d8ef37e5F02BBb21`](https://testnet.snowtrace.io/address/0x9345AC54dA4D0B5Cda8CB749d8ef37e5F02BBb21) |
+| VRF Coordinator | [`0x2eD832Ba664535e5886b75D64C46EB9a228C2610`](https://testnet.snowtrace.io/address/0x2eD832Ba664535e5886b75D64C46EB9a228C2610) |
+| Wrapper Premium Percentage | 0 |
+| Coordinator Flat Fee | 0.005 LINK |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 10 |
+| Wrapper Gas overhead | 40000 |
+| Coordinator Gas Overhead | 90000 |
+
+### Fantom Mainnet
+
+:::tip[Important]
+You must use ERC-677 LINK on Fantom. ERC-20 LINK will not work with Chainlink services.
+Use [bridge.multichain.org](https://bridge.multichain.org/#/router) to send LINK to the Fantom network and be sure to select LINK-ERC677 as the token you will receive on the Fantom mainnet.
+:::
+
+| Item | Value |
+| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| LINK Token | `0x6F43FF82CCA38001B6699a8AC47A2d0E66939407` |
+| VRF Wrapper | [`0xeDA5B00fB33B13c730D004Cf5D1aDa1ac191Ddc2`](https://ftmscan.com/address/0xeDA5B00fB33B13c730D004Cf5D1aDa1ac191Ddc2) |
+| VRF Coordinator | [`0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634`](https://ftmscan.com/address/0xd5d517abe5cf79b7e95ec98db0f0277788aff634) |
+| Wrapper Premium Percentage | 0 |
+| Coordinator Flat Fee | 0.0005 LINK |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 10 |
+| Wrapper Gas overhead | 40000 |
+| Coordinator Gas Overhead | 90000 |
+
+### Fantom Testnet
+
+:::note[Fantom Testnet Faucet]
+Testnet LINK is available from https://faucets.chain.link/fantom-testnet
+:::
+
+| Item | Value |
+| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| LINK Token | `0xfaFedb041c0DD4fA2Dc0d87a6B0979Ee6FA7af5F` |
+| VRF Wrapper | [`0x38336BDaE79747a1d2c4e6C67BBF382244287ca6`](https://testnet.ftmscan.com/address/0x38336BDaE79747a1d2c4e6C67BBF382244287ca6) |
+| VRF Coordinator | [`0xbd13f08b8352A3635218ab9418E340c60d6Eb418`](https://testnet.ftmscan.com/address/0xbd13f08b8352a3635218ab9418e340c60d6eb418) |
+| Wrapper Premium Percentage | 0 |
+| Coordinator Flat Fee | 0.0005 LINK |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 10 |
+| Wrapper Gas overhead | 40000 |
+| Coordinator Gas Overhead | 90000 |
diff --git a/src/pages/vrf/v2/introduction.md b/src/pages/vrf/v2/introduction.md
new file mode 100644
index 00000000000..ae3f56df6f6
--- /dev/null
+++ b/src/pages/vrf/v2/introduction.md
@@ -0,0 +1,71 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Introduction to Chainlink VRF"
+permalink: "docs/vrf/v2/introduction/"
+whatsnext: { "Subscription Method": "/vrf/v2/subscription/", "Direct Funding Method": "/vrf/v2/direct-funding/" }
+metadata:
+ title: "Generate Random Numbers for Smart Contracts using Chainlink VRF"
+ description: "Learn how to securely generate random numbers for your smart contract with Chainlink VRF (an RNG). This guide uses Solidity code examples."
+setup: |
+ import VrfCommon from "@features/vrf/v2/common/VrfCommon.astro"
+---
+
+
+
+
+
+**Chainlink VRF (Verifiable Random Function)** is a provably fair and verifiable random number generator (RNG) that enables smart contracts to access random values without compromising security or usability. For each request, Chainlink VRF generates one or more random values and cryptographic proof of how those values were determined. The proof is published and verified on-chain before any consuming applications can use it. This process ensures that results cannot be tampered with or manipulated by any single entity including oracle operators, miners, users, or smart contract developers.
+
+Use Chainlink VRF to build reliable smart contracts for any applications that rely on unpredictable outcomes:
+
+- Building blockchain games and NFTs.
+- Random assignment of duties and resources. For example, randomly assigning judges to cases.
+- Choosing a representative sample for consensus mechanisms.
+
+To learn more about the benefits of Chainlink VRF v2, see our blog post [Chainlink VRF v2 Is Now Live on Mainnet](https://blog.chain.link/vrf-v2-mainnet-launch/). For help with your specific use case, [contact us](https://chainlinkcommunity.typeform.com/to/OYQO67EF?page=docs-footer) to connect with one of our Solutions Architects. You can also ask questions about Chainlink VRF on [Stack Overflow](https://stackoverflow.com/questions/ask?tags=chainlink).
+
+## Two methods to request randomness
+
+Chainlink VRF v2 offers two methods for requesting randomness:
+
+- [Subscription](/vrf/v2/subscription/): Create a subscription account and fund its balance with LINK tokens. Users can then connect multiple consuming contracts to the subscription account. When the consuming contracts request randomness, the transaction costs are calculated after the randomness requests are fulfilled and the subscription balance is deducted accordingly. This method allows you to fund requests for multiple consumer contracts from a single subscription.
+- [Direct funding](/vrf/v2/direct-funding/): Consuming contracts directly pay with LINK when they request random values. You must directly fund your consumer contracts and ensure that there are enough LINK tokens to pay for randomness requests.
+
+## Choosing the correct method
+
+Depending on your use case, one method might be more suitable than another. Consider the following recommendations when you choose a method:
+
+- If your use case requires regular requests for randomness, choose the subscription method to simplify funding and reduce the overall cost. Otherwise, choose the direct funding method. The direct funding method is more suitable for infrequent one-off requests.
+- If you have several VRF consuming contracts, choose the subscription method.
+- To reduce gas overhead and have more control over the maximum gas price for requests, choose the Subscription method. Read the [Subscription Method](/vrf/v2/subscription/) and [Direct Funding Method](/vrf/v2/direct-funding/) pages to understand how the transaction costs are calculated.
+- Because the direct funding method has higher overhead, it cannot return as many random words in a single request as the subscription method. You can compare the maximum number of words per request and per method on the [Subscription supported networks](/vrf/v2/subscription/supported-networks/#configurations) and [Direct Funding supported networks](/vrf/v2/direct-funding/supported-networks/#configurations) pages.
+- If you want to transfer the cost of VRF to the end user, the direct funding method may be more suitable as the cost is known and charged at request time.
+
+## Supported networks
+
+The contract addresses and gas price limits are different depending on which method you use to get randomness. You can find the configuration, addresses, and limits for each method on the following pages:
+
+- [Subscription Supported networks](/vrf/v2/subscription/supported-networks/)
+- [Direct Funding Supported networks](/vrf/v2/direct-funding/supported-networks/)
+
+Chainlink VRF v2 is currently available on the following networks:
+
+- Ethereum:
+ - Mainnet
+ - Goerli testnet
+- BNB Chain:
+ - Mainnet
+ - Testnet
+- Polygon (Matic):
+ - Mainnet
+ - Mumbai Testnet
+- Avalanche:
+ - Avalanche Mainnet
+ - Avalanche Fuji Testnet
+- Fantom:
+ - Fantom Mainnet
+ - Fantom Testnet
+
+To learn when VRF v2 becomes available on more networks, follow us on [Twitter](https://twitter.com/chainlink) or sign up for our [mailing list](/resources/developer-communications/).
diff --git a/src/pages/vrf/v2/security.md b/src/pages/vrf/v2/security.md
new file mode 100644
index 00000000000..b07c14d35c8
--- /dev/null
+++ b/src/pages/vrf/v2/security.md
@@ -0,0 +1,66 @@
+---
+layout: ../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "VRF Security Considerations"
+permalink: "docs/vrf/v2/security/"
+setup: |
+ import VrfCommon from "@features/vrf/v2/common/VrfCommon.astro"
+---
+
+
+
+Gaining access to high quality randomness on-chain requires a solution like Chainlink's VRF, but it also requires you to understand some of the ways that miners or validators can potentially manipulate randomness generation. Here are some of the top security considerations you should review in your project.
+
+- [Use `requestId` to match randomness requests with their fulfillment in order](#use-requestid-to-match-randomness-requests-with-their-fulfillment-in-order)
+- [Choose a safe block confirmation time, which will vary between blockchains](#choose-a-safe-block-confirmation-time-which-will-vary-between-blockchains)
+- [Do not re-request randomness, even if you don't get an answer right away](#do-not-re-request-randomness-even-if-you-dont-get-an-answer-right-away)
+- [Don't accept bids/bets/inputs after you have made a randomness request](#dont-accept-bidsbetsinputs-after-you-have-made-a-randomness-request)
+- [The `fulfillRandomWords` function must not revert](#fulfillrandomwords-must-not-revert)
+- [Use `VRFConsumerBaseV2` in your contract to interact with the VRF service](#use-vrfconsumerbasev2-in-your-contract-to-interact-with-the-vrf-service)
+
+## Use `requestId` to match randomness requests with their fulfillment in order
+
+If your contract could have multiple VRF requests in flight simultaneously, you must ensure that the order in which the VRF fulfillments arrive cannot be used to manipulate your contract's user-significant behavior.
+
+Blockchain miners/validators can control the order in which your requests appear on-chain, and hence the order in which your contract responds to them.
+
+For example, if you made randomness requests `A`, `B`, `C` in short succession, there is no guarantee that the associated randomness fulfillments will also be in order `A`, `B`, `C`. The randomness fulfillments might just as well arrive at your contract in order `C`, `A`, `B` or any other order.
+
+We recommend using the `requestID` to match randomness requests with their corresponding fulfillments.
+
+## Choose a safe block confirmation time, which will vary between blockchains
+
+In principle, miners/validators of your underlying blockchain could rewrite the chain's history to put a randomness request from your contract into a different block, which would result in a different VRF output. Note that this does not enable a miner to determine the random value in advance. It only enables them to get a fresh random value that might or might not be to their advantage. By way of analogy, they can only re-roll the dice, not predetermine or predict which side it will land on.
+
+You must choose an appropriate confirmation time for the randomness requests you make. Confirmation time is how many blocks the VRF service waits before writing a fulfillment to the chain to make potential rewrite attacks unprofitable in the context of your application and its value-at-risk.
+
+## Do not re-request randomness, even if you don't get an answer right away
+
+Doing so would give the VRF service provider the option to withhold a VRF fulfillment, if it doesn't like the outcome, and wait for the re-request in the hopes that it gets a better outcome, similar to the considerations with block confirmation time.
+
+## Don't accept bids/bets/inputs after you have made a randomness request
+
+Consider the example of a contract that mints a random NFT in response to a user's actions.
+
+The contract should:
+
+1. Record whatever actions of the user may affect the generated NFT.
+1. **Stop accepting further user actions that might affect the generated NFT** and issue a randomness request.
+1. On randomness fulfillment, mint the NFT.
+
+Generally speaking, whenever an outcome in your contract depends on some user-supplied inputs and randomness, the contract should not accept any additional user-supplied inputs after it submits the randomness request.
+
+Otherwise, the cryptoeconomic security properties may be violated by an attacker that can rewrite the chain.
+
+## `fulfillRandomWords` must not revert
+
+If your `fulfillRandomWords()` implementation reverts, the VRF service will not attempt to call it a second time. Make sure your contract logic does not revert. Consider simply storing the randomness and taking more complex follow-on actions in separate contract calls made by you, your users, or an [Automation Node](/chainlink-automation/introduction/).
+
+## Use `VRFConsumerBaseV2` in your contract, to interact with the VRF service
+
+If you implement the [subscription method](/vrf/v2/subscription/), use `VRFConsumerBaseV2`. It includes a check to ensure the randomness is fulfilled by `VRFCoordinatorV2`. For this reason, it is a best practice to inherit from `VRFConsumerBaseV2`. Similarly, don't override `rawFulfillRandomness`.
+
+## Use `VRFv2WrapperConsumer.sol` in your contract, to interact with the VRF service
+
+If you implement the [direct funding method](/vrf/v2/direct-funding/), use `VRFv2WrapperConsumer`. It includes a check to ensure the randomness is fulfilled by the `VRFV2Wrapper`. For this reason, it is a best practice to inherit from `VRFv2WrapperConsumer`. Similarly, don't override `rawFulfillRandomWords`.
diff --git a/src/pages/vrf/v2/subscription/examples/get-a-random-number.md b/src/pages/vrf/v2/subscription/examples/get-a-random-number.md
new file mode 100644
index 00000000000..a185fbfa8f9
--- /dev/null
+++ b/src/pages/vrf/v2/subscription/examples/get-a-random-number.md
@@ -0,0 +1,167 @@
+---
+layout: ../../../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Get a Random Number"
+permalink: "docs/vrf/v2/subscription/examples/get-a-random-number/"
+whatsnext:
+ {
+ "Programmatic Subscription": "/vrf/v2/subscription/examples/programmatic-subscription/",
+ "Subscription Manager UI": "/vrf/v2/subscription/ui/",
+ "Security Considerations": "/vrf/v2/security/",
+ "Best Practices": "/vrf/v2/best-practices/",
+ "Migrating from VRF v1 to v2": "/vrf/v2/subscription/migration-from-v1/",
+ "Supported Networks": "/vrf/v2/subscription/supported-networks/",
+ }
+metadata:
+ description: "How to generate a random number inside a smart contract using Chainlink VRF."
+setup: |
+ import VrfCommon from "@features/vrf/v2/common/VrfCommon.astro"
+ import CodeSample from "@components/CodeSample/CodeSample.astro"
+---
+
+
+
+This guide explains how to get random values using a simple contract to request and receive random values from Chainlink VRF v2. For more advanced examples with programmatic subscription configuration, see the [Programmatic Subscription](/vrf/v2/subscription/examples/programmatic-subscription/) page. To explore more applications of VRF, refer to our [blog](https://blog.chain.link/).
+
+
+
+## Requirements
+
+This guide assumes that you know how to create and deploy smart contracts on Ethereum testnets using the following tools:
+
+- [The Remix IDE](https://remix.ethereum.org/)
+- [MetaMask](https://metamask.io/)
+- [Goerli testnet ETH](/resources/link-token-contracts/#goerli-testnet)
+
+If you are new to developing smart contracts on Ethereum, see the [Getting Started](/getting-started/conceptual-overview/) guide to learn the basics.
+
+## Create and fund a subscription
+
+For this example, create a new subscription on the Goerli testnet.
+
+1. Open MetaMask and set it to use the Goerli testnet. The [Subscription Manager](/vrf/v2/subscription/ui/) detects your network based on the active network in MetaMask.
+
+1. Check MetaMask to make sure you have testnet ETH and LINK on Goerli. You can get testnet ETH and LINK at one of the available [Goerli faucets](/resources/link-token-contracts/#goerli-testnet).
+
+1. Open the Subscription Manager at [vrf.chain.link](https://vrf.chain.link).
+
+
+
+1. Click **Create Subscription** and follow the instructions to create a new subscription account. MetaMask opens and asks you to confirm payment to create the account on-chain. After you approve the transaction, the network confirms the creation of your subscription account on-chain.
+
+1. After the subscription is created, click **Add funds** and follow the instructions to fund your subscription. For this example, a balance of 2 LINK is sufficient. MetaMask opens to confirm the LINK transfer to your subscription. After you approve the transaction, the network confirms the transfer of your LINK token to your subscription account.
+
+1. After you add funds, click **Add consumer**. A page opens with your account details and subscription ID.
+
+1. Record your subscription ID, which you need for your consuming contract. You will add the consuming contract to your subscription later.
+
+You can always find your subscription IDs, balances, and consumers at [vrf.chain.link](https://vrf.chain.link/).
+
+Now that you have a funded subscription account and your subscription ID, [create and deploy a VRF v2 compatible contract](#create-and-deploy-a-vrf-v2-compatible-contract).
+
+## Create and deploy a VRF v2 compatible contract
+
+For this example, use the [VRFv2Consumer.sol](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFv2Consumer.sol) sample contract. This contract imports the following dependencies:
+
+- `VRFConsumerBaseV2.sol`[(link)](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFConsumerBaseV2.sol)
+- `VRFCoordinatorV2Interface.sol`[(link)](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol)
+- `ConfirmedOwner.sol`[(link)](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/ConfirmedOwner.sol)
+
+The contract also includes pre-configured values for the necessary request parameters such as `vrfCoordinator` address, gas lane `keyHash`, `callbackGasLimit`, `requestConfirmations` and number of random words `numWords`. You can change these parameters if you want to experiment on different testnets, but for this example you only need to specify `subscriptionId` when you deploy the contract.
+
+Build and deploy the contract on Goerli.
+
+1. Open the [`VRFv2Consumer.sol` contract](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFv2Consumer.sol) in Remix.
+
+
+
+
+1. On the **Compile** tab in Remix, compile the `VRFv2Consumer.sol` contract.
+
+1. Configure your deployment. On the **Deploy** tab in Remix, select the **Injected Provider** environment, select the `VRFv2Consumer` contract from the contract list, and specify your `subscriptionId` so the constructor can set it.
+
+ 
+
+1. Click the **Deploy** button to deploy your contract on-chain. MetaMask opens and asks you to confirm the transaction.
+
+1. After you deploy your contract, copy the address from the **Deployed Contracts** list in Remix. Before you can request randomness from VRF v2, you must add this address as an approved consuming contract on your subscription account.
+
+ 
+
+1. Open the Subscription Manager at [vrf.chain.link](https://vrf.chain.link/) and click the ID of your new subscription under the **My Subscriptions** list. The subscription details page opens.
+
+1. Under the **Consumers** section, click **Add consumer**.
+
+1. Enter the address of your consuming contract that you just deployed and click **Add consumer**. MetaMask opens and asks you to confirm the transaction.
+
+Your example contract is deployed and approved to use your subscription balance to pay for VRF v2 requests. Next, [request random values](#request-random-values) from Chainlink VRF.
+
+## Request random values
+
+The deployed contract requests random values from Chainlink VRF, receives those values, builds a struct `RequestStatus` containing them and stores the struct in a mapping `s_requests`. Run the `requestRandomWords()` function on your contract to start the request.
+
+1. Return to Remix and view your deployed contract functions in the **Deployed Contracts** list.
+
+1. Click the `requestRandomWords()` function to send the request for random values to Chainlink VRF. MetaMask opens and asks you to confirm the transaction. After you approve the transaction, Chainlink VRF processes your request. Chainlink VRF fulfills the request and returns the random values to your contract in a callback to the `fulfillRandomWords()` function. At this point, a new key `requestId` is added to the mapping `s_requests`.
+
+ Depending on current testnet conditions, it might take a few minutes for the callback to return the requested random values to your contract. You can see a list of pending requests for your subscription ID at [vrf.chain.link](https://vrf.chain.link/).
+
+1. To fetch the request ID of your request, call `lastRequestId()`.
+
+1. After the oracle returns the random values to your contract, the mapping `s_requests` is updated: The received random values are stored in `s_requests[_requestId].randomWords`.
+
+1. Call `getRequestStatus()` specifying the `requestId` to display the random words.
+
+You deployed a simple contract that can request and receive random values from Chainlink VRF. To see more advanced examples where the contract can complete the entire process including subscription setup and management, see the [Programmatic Subscription](/vrf/v2/subscription/examples/programmatic-subscription/) page.
+
+:::note[Note on Requesting Randomness]
+Do not re-request randomness even if you do **not** receive an answer right away. Doing so would give the VRF service provider the option to withhold a VRF fulfillment, if it doesn't like the outcome, and wait for the re-request in the hopes that it gets a better outcome. This is similar to the considerations with block confirmation time. For more information, see the [VRF Security Considerations](/vrf/v2/security/) page.
+:::
+
+## Analyzing the contract
+
+In this example, your MetaMask wallet is the subscription owner and you created a consuming contract to use that subscription. The consuming contract uses static configuration parameters.
+
+::solidity-remix[samples/VRF/VRFv2Consumer.sol]
+
+The parameters define how your requests will be processed. You can find the values for your network in the [Configuration](/vrf/v2/subscription/supported-networks/) page.
+
+- `uint64 s_subscriptionId`: The subscription ID that this contract uses for funding requests.
+
+- `bytes32 keyHash`: The gas lane key hash value, which is the maximum gas price you are willing to pay for a request in wei. It functions as an ID of the off-chain VRF job that runs in response to requests.
+
+- `uint32 callbackGasLimit`: The limit for how much gas to use for the callback request to your contract's `fulfillRandomWords()` function. It must be less than the `maxGasLimit` limit on the coordinator contract. Adjust this value for larger requests depending on how your `fulfillRandomWords()` function processes and stores the received random values. If your `callbackGasLimit` is not sufficient, the callback will fail and your subscription is still charged for the work done to generate your requested random values.
+
+- `uint16 requestConfirmations`: How many confirmations the Chainlink node should wait before responding. The longer the node waits, the more secure the random value is. It must be greater than the `minimumRequestBlockConfirmations` limit on the coordinator contract.
+
+- `uint32 numWords`: How many random values to request. If you can use several random values in a single callback, you can reduce the amount of gas that you spend per random value. The total cost of the callback request depends on how your `fulfillRandomWords()` function processes and stores the received random values, so adjust your `callbackGasLimit` accordingly.
+
+The contract includes the following functions:
+
+- `requestRandomWords()`: Takes your specified parameters and submits the request to the VRF coordinator contract.
+
+- `fulfillRandomWords()`: Receives random values and stores them with your contract.
+
+- `getRequestStatus()`: Retrive request details for a given `_requestId`.
+
+:::note[Security Considerations]
+Be sure to review your contracts to make sure they follow the best practices on the [security considerations](/vrf/v2/security/) page.
+:::
+
+## Clean up
+
+After you are done with this contract and the subscription, you can retrieve the remaining testnet LINK to use with other examples.
+
+1. Open the Subscription Manager at [vrf.chain.link](https://vrf.chain.link/) and click the ID of your new subscription under the **My Subscriptions** list. The subscription details page opens.
+
+1. Under your subscription details, click **Cancel subscription**. A field opens asking which wallet address you want to send the remaining funds to.
+
+1. Enter your wallet address and click **Cancel subscription**. MetaMask opens and asks you to confirm the transaction. After you approve the transaction, Chainlink VRF closes your subscription account and sends the remaining LINK to your wallet.
+
+## Vyper example
+
+You must import the `VRFCoordinatorV2` Vyper interface. You can find it [here](https://github.com/smartcontractkit/apeworx-starter-kit/blob/main/contracts/interfaces/VRFCoordinatorV2.vy).
+You can find a `VRFConsumerV2` example [here](https://github.com/smartcontractkit/apeworx-starter-kit/blob/main/contracts/VRFConsumerV2.vy). Read the _**apeworx-starter-kit**_ [README](https://github.com/smartcontractkit/apeworx-starter-kit) to learn how to run the example.
diff --git a/src/pages/vrf/v2/subscription/examples/programmatic-subscription.md b/src/pages/vrf/v2/subscription/examples/programmatic-subscription.md
new file mode 100644
index 00000000000..1404037d92b
--- /dev/null
+++ b/src/pages/vrf/v2/subscription/examples/programmatic-subscription.md
@@ -0,0 +1,92 @@
+---
+layout: ../../../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Programmatic Subscription"
+permalink: "docs/vrf/v2/subscription/examples/programmatic-subscription/"
+whatsnext:
+ {
+ "Subscription Manager UI": "/vrf/v2/subscription/ui/",
+ "Security Considerations": "/vrf/v2/security/",
+ "Best Practices": "/vrf/v2/best-practices/",
+ "Migrating from VRF v1 to v2": "/vrf/v2/subscription/migration-from-v1/",
+ "Supported Networks": "/vrf/v2/subscription/supported-networks/",
+ }
+metadata:
+ description: "Example contracts for generating a random number inside a smart contract using Chainlink VRF v2."
+setup: |
+ import VrfCommon from "@features/vrf/v2/common/VrfCommon.astro"
+ import CodeSample from "@components/CodeSample/CodeSample.astro"
+---
+
+
+
+How you manage the subscription depends on your randomness needs. You can configure your subscriptions using the [Subscription Manager](/vrf/v2/subscription/ui/), but these examples demonstrate how to create your subscription and add your consumer contracts programmatically. For these examples, the contract owns and manages the subscription. Any wallet can provide funding to those subscriptions.
+
+You can view and monitor your subscriptions in the [Subscription Manager](/vrf/v2/subscription/ui/) even if you create them programmatically. Go to [vrf.chain.link](https://vrf.chain.link) to open the Subscription Manager.
+
+## Modifying subscriptions and configurations
+
+Subscription configurations do not have to be static. You can change your subscription configuration dynamically by calling the following functions using the [VRFCoordinatorV2Interface](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol):
+
+- Change the list of approved subscription consumers with:
+ - `addConsumer(uint64 subId, address consumer)`.
+ - `removeConsumer(uint64 subId, address consumer)`.
+- Transfer the subscription ownership with:
+ - `requestSubscriptionOwnerTransfer(uint64 subId, address newOwner)`.
+ - `acceptSubscriptionOwnerTransfer(uint64 subId)`.
+- View the subscription with `getSubscription(uint64 subId)`.
+- Cancel the subscription with `cancelSubscription(uint64 subId)`.
+
+To send LINK to the subscription balance, use the LINK token interface with `LINKTOKEN.transferAndCall(address(COORDINATOR), amount, abi.encode(subId))`. Any wallet can fund a subscription.
+
+See the example in the [Subscription manager contract](#subscription-manager-contract) section to learn how to create a contract that can change your subscription configuration.
+
+## Subscription manager contract
+
+In this example, the contract operates as a subscription owner and can run functions to add consuming contracts to the subscription. The consuming contracts must include the `requestRandomWords()` function with the correct coordinator parameters and the correct subscription ID to request random values and use the subscription balance. The consuming contracts must also include the `fulfillRandomWords()` function to receive the random values.
+
+Subscription owners and consumers do not have to be separate. This contract not only allows adding consumers with `addConsumer(address consumerAddress)` but can also act as a consumer by running its own `requestRandomWords()` function. This example contract includes a `createNewSubscription()` function in the `constructor()` that creates the subscription and adds itself as a consumer automatically when you deploy it.
+
+::solidity-remix[samples/VRF/VRFv2SubscriptionManager.sol]
+
+To use this contract, compile and deploy it in Remix.
+
+1. Open the contract in [Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFv2SubscriptionManager.sol).
+
+1. Compile and deploy the contract using the Injected Provider environment. The contract includes all of the configuration variables that you need, but you can edit them if necessary. For a full list of available configuration variables, see the [Supported Networks](/vrf/v2/subscription/supported-networks/) page.
+
+ This contract automatically creates a new subscription when you deploy it. Read the `s_subscriptionId` variable to find your subscription ID. You can use this value to find the subscription at [vrf.chain.link](https://vrf.chain.link).
+
+1. In this example, the `topUpSubscription()` function sends LINK from your contract to the subscription. Fund your contract with at least three testnet LINK. Alternatively, you can send LINK directly to the subscription at [vrf.chain.link](https://vrf.chain.link). Any address can provide funding to a subscription balance. If you need testnet LINK, you can get it from the [Chainlink faucet](https://faucets.chain.link/goerli).
+
+1. Run the `topUpSubscription()` function to send LINK from your contract to your subscription balance. For this example, specify a value of `3000000000000000000`, which is equivalent to three LINK.
+
+1. Run the `requestRandomWords()` function. The request might take several minutes to process. Track the pending request status at [vrf.chain.link](https://vrf.chain.link).
+
+1. You can also add and test consumer contracts using the same programmatic subscription process:
+
+ 1. Create and deploy a consumer contract that includes the following components:
+
+ - The `requestRandomWords()` function and the required variables and your subscription ID.
+ - The `fulfillRandomWords()` callback function.
+
+ You can use the example from the [Get a Random Number](/vrf/v2/subscription/examples/get-a-random-number/#analyzing-the-contract) guide.
+
+ 1. After you deploy the consumer contract, add it to the subscription as an approved consumer using the `addConsumer()` function on your subscription manager contract. Specify the address of your consumer contract.
+
+ 1. On the consumer contract, run the `requestRandomWords()` function to request and receive random values. The request might take several minutes to process. Track the pending request status at [vrf.chain.link](https://vrf.chain.link).
+
+ The consumer contract can continue to make requests until your subscription balance runs out. The subscription manager contract must maintain sufficient balance in the subscription so that the consumers can continue to operate.
+
+ 1. If you need to remove consumer contracts from the subscription, use the `removeConsumer()` function. Specify the address of the consumer contract to be removed.
+
+1. When you are done with your contracts and the subscription, run the `cancelSubscription()` function to close the subscription and send the remaining LINK to your wallet address. Specify the address of the receiving wallet.
+
+## Funding and requesting simultaneously
+
+You can fund a subscription and request randomness in a single transaction. You must estimate how much the transaction might cost and determine the amount of funding to send to the subscription yourself. See the [Subscription billing](/vrf/v2/subscription/#subscription-limits) page to learn how to estimate request costs.
+
+
+
+Add this function to your contracts if you need to provide funding simultaneously with your requests. The `transferAndCall()` function sends LINK from your contract to the subscription, and the `requestRandomWords()` function requests the random words. Your contract still needs the `fulfillRandomWords()` callback function to receive the random values.
diff --git a/src/pages/vrf/v2/subscription/index.md b/src/pages/vrf/v2/subscription/index.md
new file mode 100644
index 00000000000..8410c206a0e
--- /dev/null
+++ b/src/pages/vrf/v2/subscription/index.md
@@ -0,0 +1,124 @@
+---
+layout: ../../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Subscription Method"
+permalink: "docs/vrf/v2/subscription/"
+whatsnext:
+ {
+ "Get a Random Number": "/vrf/v2/subscription/examples/get-a-random-number/",
+ "Supported Networks": "/vrf/v2/subscription/supported-networks/",
+ }
+metadata:
+ title: "Generate Random Numbers for Smart Contracts using Chainlink VRF v2 - Subscription Method"
+ description: "Learn how to securely generate random numbers for your smart contract with Chainlink VRF v2(an RNG). This guide uses the subscription method."
+setup: |
+ import VrfCommon from "@features/vrf/v2/common/VrfCommon.astro"
+---
+
+
+
+This section explains how to generate random numbers using the subscription method.
+
+
+
+## Subscriptions
+
+VRF v2 requests receive funding from subscription accounts. The [Subscription Manager](/vrf/v2/subscription/ui/) lets you create an account and pre-pay for VRF v2, so you don't provide funding each time your application requests randomness. This reduces the total gas cost to use VRF v2. It also provides a simple way to fund your use of Chainlink products from a single location, so you don't have to manage multiple wallets across several different systems and applications.
+
+
+
+Subscriptions have the following core concepts:
+
+- **Subscription id:** 64-bit unsigned integer representing the unique identifier of the subscription.
+- **Subscription accounts:** An account that holds LINK tokens and makes them available to fund requests to Chainlink VRF v2 coordinators.
+- **Subscription owner:** The wallet address that creates and manages a subscription account. Any account can add LINK to the subscription balance, but only the owner can add approved consuming contracts or withdraw funds.
+- **Consumers:** Consuming contracts that are approved to use funding from your subscription account.
+- **Subscription balance:** The amount of LINK maintained on your subscription account. Requests from consuming contracts will continue to be funded until the balance runs out, so be sure to maintain sufficient funds in your subscription balance to pay for the requests and keep your applications running.
+
+For Chainlink VRF v2 to fulfill your requests, you must maintain a sufficient amount of LINK in your subscription balance. Gas cost calculation includes the following variables:
+
+- **Gas price:** The current gas price, which fluctuates depending on network conditions.
+
+- **Callback gas:** The amount of gas used for the callback request that returns your requested random values.
+
+- **Verification gas:** The amount of gas used to verify randomness on-chain.
+
+The gas price depends on current network conditions. The callback gas depends on your callback function, and the number of random values in your request. The cost of each request is final only after the transaction is complete, but you define the limits you are willing to spend for the request with the following variables:
+
+- **Gas lane:** The maximum gas price you are willing to pay for a request in wei. Define this limit by specifying the appropriate `keyHash` in your request. The limits of each gas lane are important for handling gas price spikes when Chainlink VRF bumps the gas price to fulfill your request quickly.
+
+- **Callback gas limit:** Specifies the maximum amount of gas you are willing to spend on the callback request. Define this limit by specifying the `callbackGasLimit` value in your request.
+
+## Request and Receive Data
+
+### End To End Diagram
+
+
+
+Two types of accounts exist in the Ethereum ecosystem:
+
+- EOA (Externally Owned Account): An externally owned account that has a private key and can control a smart contract. Transactions can only be initiated by EOAs.
+- Smart contract: A contract that does not have a private key and executes what it has been designed for as a decentralized application.
+
+The Chainlink VRF v2 solution uses both off-chain and on-chain components:
+
+- [VRF v2 Coordinator (on-chain component)](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFCoordinatorV2.sol): A contract designed to interact with the VRF service. It emits an event when a request for randomness is made, and then verifies the random number and proof of how it was generated by the VRF service.
+- VRF service (off-chain component): Listens for requests by subscribing to the VRF Coordinator event logs and calculates a random number based on the block hash and nonce. The VRF service then sends a transaction to the `VRFCoordinator` including the random number and a proof of how it was generated.
+
+### Explanation
+
+Requests to Chainlink VRF v2 follow the [Request & Receive Data](#request-and-receive-data) cycle. The VRF coordinator processes the request and determines the final charge to your subscription using the following steps:
+
+1. The consuming contract must inherit [VRFConsumerBaseV2](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFConsumerBaseV2.sol) and implement the `fulfillRandomWords` function, which is the _callback VRF function_. Submit your VRF request by calling `requestRandomWords` of the [VRF Coordinator](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFCoordinatorV2.sol) with:
+
+ - `keyHash`: Identifier that maps to a job and a private key on the VRF service and that represents a specified gas lane. If your request is urgent, specify a gas lane with a higher gas price limit. The configuration for your network can be found [here](/vrf/v2/subscription/supported-networks/#configurations).
+ - `s_subscriptionId`: The subscription ID that the consuming contract is registered to. LINK funds are deducted from this subscription.
+ - `requestConfirmations`: The number of block confirmations the VRF service will wait to respond. The minimum and maximum confirmations for your network can be found [here](/vrf/v2/subscription/supported-networks/#configurations).
+ - `callbackGasLimit`: The maximum amount of gas a user is willing to pay for completing the callback VRF function. Note that you cannot put a value larger than maxGasLimit of the VRF Coordinator contract (read [coordinator contract limits](#limits) for more details).
+ - `numWords`: The number of random numbers to request. The maximum random values that can be requested for your network can be found [here](/vrf/v2/subscription/supported-networks/#configurations).
+
+1. The VRF coordinator emits an event.
+
+1. The event is picked up by the VRF service and will wait for the specified number of block confirmations to respond back to the VRF coordinator with the random values and a proof (`requestConfirmations`).
+
+1. The VRF coordinator verifies the proof on-chain then calls back the consuming contract `fulfillRandomWords` function.
+ After the request is complete, the final gas cost is recorded based on how much gas is required for the verification and callback. The total gas cost in wei for your request uses the following formula:
+
+ ```
+ (Gas price * (Verification gas + Callback gas)) = total gas cost
+ ```
+
+ The total gas cost is converted to LINK using the ETH/LINK data feed. In the unlikely event that the data feed is unavailable, the VRF coordinator uses the `fallbackWeiPerUnitLink` value for the conversion instead. The `fallbackWeiPerUnitLink` value is defined in the [coordinator contract](/vrf/v2/subscription/supported-networks/#configurations) for your selected network.
+
+ The LINK premium is added to the total gas cost. The premium is defined in the [coordinator contract](/vrf/v2/subscription/supported-networks/#configurations) with the `fulfillmentFlatFeeLinkPPMTier1` parameter in millionths of LINK.
+
+ ```
+ (total gas cost + LINK premium) = total request cost
+ ```
+
+ The total request cost is charged to your subscription balance.
+
+## Limits
+
+Chainlink VRF v2 has some [subscription limits](#subscription-limits) and [coordinator contract limits](#coordinator-contract-limits).
+
+### Subscription limits
+
+Each subscription has the following limits:
+
+- Each subscription must maintain a minimum balance to fund requests from consuming contracts. If your balance is below that minimum, your requests remain pending for up to 24 hours before they expire. After you add sufficient LINK to a subscription, pending requests automatically process as long as they have not expired.
+- The minimum subscription balance must be sufficient for each new consuming contract that you add to a subscription. The required size of the minimum balance depends on the gas lane and the size of the request that the consuming contract makes. For example, a consuming contract that requests one random value will require a smaller minimum balance than a consuming contract that requests 50 random values. In general, you can estimate the required minimum LINK balance using the following formula where max verification gas is always 200,000.
+
+ ```
+ (((Gas lane maximum * (Max verification gas + Callback gas limit)) / (1,000,000,000 Gwei/ETH)) / (ETH/LINK price)) + LINK premium = Minimum LINK
+ ```
+
+- Each subscription supports up to 100 consuming contracts. If you need more than 100 consuming contracts, create multiple subscriptions.
+
+### Coordinator contract limits
+
+You can see the configuration for each network on the [Supported networks](/vrf/v2/subscription/supported-networks/) page. You can also view the full configuration for each coordinator contract directly in Etherscan. As an example, view the [Ethereum Mainnet VRF v2 coordinator contract](https://etherscan.io/token/0x271682DEB8C4E0901D1a1550aD2e64D568E69909#readContract) configuration.
+
+- Each coordinator has a `MAX_NUM_WORDS` parameter that limits the maximum number of random values you can receive in each request.
+- Each coordinator has a `maxGasLimit` parameter, which is the maximum allowed `callbackGasLimit` value for your requests. You must specify a sufficient `callbackGasLimit` to fund the callback request to your consuming contract. This depends on the number of random values you request and how you process them in your `fulfillRandomWords()` function. If your `callbackGasLimit` is not sufficient, the callback fails but your subscription is still charged for the work done to generate your requested random values.
diff --git a/src/pages/vrf/v2/subscription/migration-from-v1.md b/src/pages/vrf/v2/subscription/migration-from-v1.md
new file mode 100644
index 00000000000..fa42c310889
--- /dev/null
+++ b/src/pages/vrf/v2/subscription/migration-from-v1.md
@@ -0,0 +1,50 @@
+---
+layout: ../../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Migrating from VRF v1"
+permalink: "docs/vrf/v2/subscription/migration-from-v1/"
+setup: |
+ import VrfCommon from "@features/vrf/v2/common/VrfCommon.astro"
+ import CodeSample from "@components/CodeSample/CodeSample.astro"
+---
+
+
+
+## Comparing VRF v1 to the VRF v2 subscription method
+
+Chainlink VRF v2 includes several improvements and changes to the way you fund and request randomness for your smart contracts.
+
+- **Subscription management:** Chainlink VRF v2 introduces a [Subscription Manager](/vrf/v2/subscription/ui/) application that allows smart contract applications to pre-fund multiple requests for randomness using a single LINK token balance. This reduces the gas fees for VRF requests by eliminating the need to transfer LINK tokens for each individual request. You transfer LINK tokens to the subscription balance only when it requires additional funding. Read the [Subscription Manager](/vrf/v2/subscription/ui/) page to learn more.
+
+- **Variable Callback Gas Limit:** Chainlink VRF v2 lets you adjust the callback gas limit when your smart contract application receives verifiable randomness. Consuming contracts can execute more complex logic in the callback request function that receives the random values. Tasks involving the delivered randomness are handled during the response process. The new gas limits are higher than the VRF V1 limit, and vary depending on the underlying blockchain you use. See the gas limits on the [VRF Supported Networks](/vrf/v2/subscription/supported-networks/) page.
+
+- **More configuration capability:** You can define how many block confirmations must pass before verifiable randomness is generated and delivered on-chain when your application makes a request transaction. The range is from 3 to 200 blocks. VRF V1 always waited 10 blocks on Ethereum before delivering on-chain randomness. Select a value that protects your application from block re-organizations while still providing sufficiently low latency from request to response. See the [Security Considerations](/vrf/v2/security/) page to learn more.
+
+- **Multiple Random Outputs in a Single Request:** The [VRF Coordinator contracts](/vrf/v2/subscription/supported-networks/) in VRF v2 allow you to request multiple random numbers (multi-word) in a single on-chain transaction, which reduces gas costs. The fulfillment is also a single transaction, which reduces the latency of responses.
+
+- **Unified Billing - Delegate Subscription Balance to Multiple Addresses:** Chainlink VRF v2 allows up to 100 smart contract addresses to fund their requests for verifiable randomness from a single LINK subscription balance, which is managed by the subscription owner.
+
+Read the [Chainlink VRF v2 blog post](https://blog.chain.link/vrf-v2-mainnet-launch/) for a detailed explanation about the benefits and use cases for VRF v2.
+
+## Updating your applications to use VRF v2
+
+
+
+To modify your existing smart contract code to work with VRF v2, complete the following changes. See the [Get a Random Number](/vrf/v2/subscription/examples/get-a-random-number/) guide for an example.
+
+1. Set up and fund a subscription in the Subscription Manager at [vrf.chain.link](https://vrf.chain.link).
+
+
+
+1. Import the new [`VRFConsumerBaseV2.sol` contract](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFConsumerBaseV2.sol) and remove the v1 `VRFConsumerBase.sol` import. This contract includes the `fulfillRandomWords` function.
+
+1. Import the [`VRFCoordinatorV2Interface.sol` interface](https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol). This interface includes the new `requestRandomWords` function.
+
+1. Add a `VRFConsumerBaseV2` constructor as shown in the [Get a Random Number](/vrf/v2/subscription/examples/get-a-random-number/) example.
+
+1. Change `requestRandomness` function calls to `requestRandomWords`. The `requestRandomWords` function requires several additional parameters.
+
+1. Change `fulfillRandomness` function calls to `fulfillRandomWords`. Update the call to handle the returned `uint256[]` array instead of the single `uint256` variable.
diff --git a/src/pages/vrf/v2/subscription/supported-networks.md b/src/pages/vrf/v2/subscription/supported-networks.md
new file mode 100644
index 00000000000..eebf501ee87
--- /dev/null
+++ b/src/pages/vrf/v2/subscription/supported-networks.md
@@ -0,0 +1,239 @@
+---
+layout: ../../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Configuration"
+permalink: "docs/vrf/v2/subscription/supported-networks/"
+metadata:
+ title: "Chainlink VRF v2 Supported Networks"
+ linkToWallet: true
+ image:
+ 0: "/files/OpenGraph_V3.png"
+setup: |
+ import VrfCommon from "@features/vrf/v2/common/VrfCommon.astro"
+---
+
+
+
+Chainlink VRF allows you to integrate provably fair and verifiably random data in your smart contract.
+
+For implementation details, read [Introduction to Chainlink VRF](/vrf/v2/introduction/).
+
+## Coordinator Parameters
+
+These parameters are configured in the coordinator contract. You can view these values by running `getConfig` on the coordinator or by viewing the coordinator contracts in a blockchain explorer.
+
+- `uint16 minimumRequestConfirmations`: The minimum number of confirmation blocks on VRF requests before oracles respond
+- `uint32 maxGasLimit`: The maximum gas limit supported for a `fulfillRandomWords` callback.
+- `uint32 stalenessSeconds`: How long the coordinator waits until we consider the ETH/LINK price used for converting gas costs to LINK is stale and use `fallbackWeiPerUnitLink`
+- `uint32 gasAfterPaymentCalculation`: How much gas is used outside of the payment calculation. This covers the additional operations required to decrement the subscription balance and increment the balance for the oracle that handled the request.
+
+## Fee Parameters
+
+Fee parameters are configured in the coordinator contract and specify the premium you pay per request in addition to the gas cost for the transaction. You can view them by running `getFeeConfig` on the coordinator. The `uint32 fulfillmentFlatFeeLinkPPMTier1` parameter defines the fees per request specified in millionths of LINK.
+The details for calculating the total transaction cost can be found [here](/vrf/v2/subscription/#request-and-receive-data).
+
+## Configurations
+
+- [Ethereum Mainnet](#ethereum-mainnet)
+- [Goerli testnet](#goerli-testnet)
+- [BNB Chain](#bnb-chain)
+- [BNB Chain testnet](#bnb-chain-testnet)
+- [Polygon mainnet](#polygon-matic-mainnet)
+- [Polygon Mumbai testnet](#polygon-matic-mumbai-testnet)
+- [Avalanche mainnet](#avalanche-mainnet)
+- [Avalanche Fuji testnet](#avalanche-fuji-testnet)
+- [Fantom mainnet](#fantom-mainnet)
+- [Fantom testnet](#fantom-testnet)
+- [Klaytn Baobab testnet](#klaytn-baobab-testnet)
+
+### Ethereum Mainnet
+
+| Item | Value |
+| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| LINK Token | `0x514910771AF9Ca656af840dff83E8264EcF986CA` |
+| VRF Coordinator | [`0x271682DEB8C4E0901D1a1550aD2e64D568E69909`](https://etherscan.io/address/0x271682DEB8C4E0901D1a1550aD2e64D568E69909) |
+| 200 gwei Key Hash | `0x8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef` |
+| 500 gwei Key Hash | `0xff8dedfbfa60af186cf3c830acbc32c05aae823045ae5ea7da1e45fbfaba4f92` |
+| 1000 gwei Key Hash | `0x9fe0eebf5e446e3c998ec9bb19951541aee00bb90ea201ae456421a2ded86805` |
+| Premium | 0.25 LINK |
+| Max Gas Limit | 2,500,000 |
+| Minimum Confirmations | 3 |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 500 |
+
+### Goerli testnet
+
+:::note[Goerli Faucets]
+Testnet LINK is available from https://faucets.chain.link/goerli
+Testnet ETH is available from https://goerlifaucet.com/ or faucets listed at https://faucetlink.to/goerli
+:::
+
+| Item | Value |
+| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| LINK Token | `0x326C977E6efc84E512bB9C30f76E30c160eD06FB` |
+| VRF Coordinator | [`0x2Ca8E0C643bDe4C2E08ab1fA0da3401AdAD7734D`](https://goerli.etherscan.io/address/0x2Ca8E0C643bDe4C2E08ab1fA0da3401AdAD7734D) |
+| 150 gwei Key Hash | `0x79d3d8832d904592c0bf9818b621522c988bb8b0c05cdc3b15aea1b6e8db0c15` |
+| Premium | 0.25 LINK |
+| Max Gas Limit | 2,500,000 |
+| Minimum Confirmations | 3 |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 500 |
+
+### BNB Chain
+
+:::tip[Important]
+The LINK provided by the [BNB Chain Bridge](https://www.bnbchain.world/en/bridge) is not ERC-677 compatible, so cannot be used with Chainlink oracles. However, it can be [**converted to the official LINK token on BNB Chain using Chainlink's PegSwap service**](https://pegswap.chain.link/).
+:::
+
+| Item | Value |
+| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| LINK Token | `0x404460C6A5EdE2D891e8297795264fDe62ADBB75` |
+| VRF Coordinator | [`0xc587d9053cd1118f25F645F9E08BB98c9712A4EE`](https://bscscan.com/address/0xc587d9053cd1118f25F645F9E08BB98c9712A4EE) |
+| 200 gwei Key Hash | `0x114f3da0a805b6a67d6e9cd2ec746f7028f1b7376365af575cfea3550dd1aa04` |
+| 500 gwei Key Hash | `0xba6e730de88d94a5510ae6613898bfb0c3de5d16e609c5b7da808747125506f7` |
+| 1000 gwei Key Hash | `0x17cd473250a9a479dc7f234c64332ed4bc8af9e8ded7556aa6e66d83da49f470` |
+| Premium | 0.005 LINK |
+| Max Gas Limit | 2,500,000 |
+| Minimum Confirmations | 3 |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 500 |
+
+### BNB Chain testnet
+
+:::note[BNB Chain Faucet]
+Testnet LINK is available from https://faucets.chain.link/chapel
+:::
+
+| Item | Value |
+| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| LINK Token | `0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06` |
+| VRF Coordinator | [`0x6A2AAd07396B36Fe02a22b33cf443582f682c82f`](https://testnet.bscscan.com/address/0x6A2AAd07396B36Fe02a22b33cf443582f682c82f) |
+| 50 gwei Key Hash | `0xd4bb89654db74673a187bd804519e65e3f71a52bc55f11da7601a13dcf505314` |
+| Premium | 0.005 LINK |
+| Max Gas Limit | 2,500,000 |
+| Minimum Confirmations | 3 |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 500 |
+
+### Polygon (Matic) mainnet
+
+:::tip[Important]
+The LINK provided by the [Polygon (Matic) Bridge](https://wallet.polygon.technology/bridge) is not ERC-677 compatible, so cannot be used with Chainlink oracles. However, it can be [**converted to the official LINK token on Polygon (Matic) using Chainlink's PegSwap service**](https://pegswap.chain.link/)
+:::
+
+| Item | Value |
+| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| LINK Token | `0xb0897686c545045aFc77CF20eC7A532E3120E0F1` |
+| VRF Coordinator | [`0xAE975071Be8F8eE67addBC1A82488F1C24858067`](https://polygonscan.com/address/0xAE975071Be8F8eE67addBC1A82488F1C24858067) |
+| 200 gwei Key Hash | `0x6e099d640cde6de9d40ac749b4b594126b0169747122711109c9985d47751f93` |
+| 500 gwei Key Hash | `0xcc294a196eeeb44da2888d17c0625cc88d70d9760a69d58d853ba6581a9ab0cd` |
+| 1000 gwei Key Hash | `0xd729dc84e21ae57ffb6be0053bf2b0668aa2aaf300a2a7b2ddf7dc0bb6e875a8` |
+| Premium | 0.0005 LINK |
+| Max Gas Limit | 2,500,000 |
+| Minimum Confirmations | 3 |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 500 |
+
+### Polygon (Matic) Mumbai testnet
+
+:::note[Mumbai Faucet]
+Testnet LINK and MATIC are available from [the Polygon faucet](https://faucet.polygon.technology/) and https://faucets.chain.link/mumbai.
+:::
+
+| Item | Value |
+| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| LINK Token | `0x326C977E6efc84E512bB9C30f76E30c160eD06FB ` |
+| VRF Coordinator | [`0x7a1BaC17Ccc5b313516C5E16fb24f7659aA5ebed`](https://mumbai.polygonscan.com/address/0x7a1BaC17Ccc5b313516C5E16fb24f7659aA5ebed) |
+| 500 gwei Key Hash | `0x4b09e658ed251bcafeebbc69400383d49f344ace09b9576fe248bb02c003fe9f` |
+| Premium | 0.0005 LINK |
+| Max Gas Limit | 2,500,000 |
+| Minimum Confirmations | 3 |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 500 |
+
+### Avalanche mainnet
+
+| Item | Value |
+| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| LINK Token | `0x5947BB275c521040051D82396192181b413227A3` |
+| VRF Coordinator | [`0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634`](https://snowtrace.io/address/0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634) |
+| 200 gwei Key Hash | `0x83250c5584ffa93feb6ee082981c5ebe484c865196750b39835ad4f13780435d` |
+| 500 gwei Key Hash | `0x89630569c9567e43c4fe7b1633258df9f2531b62f2352fa721cf3162ee4ecb46` |
+| 1000 gwei Key Hash | `0x06eb0e2ea7cca202fc7c8258397a36f33d88568d2522b37aaa3b14ff6ee1b696` |
+| Premium | 0.005 LINK |
+| Max Gas Limit | 2,500,000 |
+| Minimum Confirmations | 1 |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 500 |
+
+### Avalanche Fuji testnet
+
+:::note[Avax Fuji Faucet]
+Testnet LINK is available from https://faucets.chain.link/fuji
+:::
+
+| Item | Value |
+| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| LINK Token | `0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846` |
+| VRF Coordinator | [`0x2eD832Ba664535e5886b75D64C46EB9a228C2610`](https://testnet.snowtrace.io/address/0x2eD832Ba664535e5886b75D64C46EB9a228C2610) |
+| 300 gwei Key Hash | `0x354d2f95da55398f44b7cff77da56283d9c6c829a4bdf1bbcaf2ad6a4d081f61` |
+| Premium | 0.005 LINK |
+| Max Gas Limit | 2,500,000 |
+| Minimum Confirmations | 1 |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 500 |
+
+### Fantom mainnet
+
+:::tip[Important]
+You must use ERC-677 LINK on Fantom. ERC-20 LINK will not work with Chainlink services.
+Use [bridge.multichain.org](https://bridge.multichain.org/#/router) to send LINK to the Fantom network and be sure to select LINK-ERC677 as the token you will receive on the Fantom mainnet.
+:::
+
+| Item | Value |
+| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| LINK Token | `0x6F43FF82CCA38001B6699a8AC47A2d0E66939407` |
+| VRF Coordinator | [`0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634`](https://ftmscan.com/address/0xd5d517abe5cf79b7e95ec98db0f0277788aff634) |
+| 4000 gwei Key Hash | `0xb4797e686f9a1548b9a2e8c68988d74788e0c4af5899020fb0c47784af76ddfa` |
+| 10000 gwei Key Hash | `0x5881eea62f9876043df723cf89f0c2bb6f950da25e9dfe66995c24f919c8f8ab` |
+| 20000 gwei Key Hash | `0x64ae04e5dba58bc08ba2d53eb33fe95bf71f5002789692fe78fb3778f16121c9` |
+| Premium | 0.0005 LINK |
+| Max Gas Limit | 2,500,000 |
+| Minimum Confirmations | 1 |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 500 |
+
+### Fantom testnet
+
+:::note[Fantom Testnet Faucet]
+Testnet LINK is available from https://faucets.chain.link/fantom-testnet
+:::
+
+| Item | Value |
+| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| LINK Token | `0xfaFedb041c0DD4fA2Dc0d87a6B0979Ee6FA7af5F` |
+| VRF Coordinator | [`0xbd13f08b8352A3635218ab9418E340c60d6Eb418`](https://testnet.ftmscan.com/address/0xbd13f08b8352a3635218ab9418e340c60d6eb418) |
+| 3000 gwei Key Hash | `0x121a143066e0f2f08b620784af77cccb35c6242460b4a8ee251b4b416abaebd4` |
+| Premium | 0.0005 LINK |
+| Max Gas Limit | 2,500,000 |
+| Minimum Confirmations | 1 |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 500 |
+
+### Klaytn Baobab testnet
+
+:::note[Klaytn Testnet Faucet]
+Testnet LINK is available from [faucets.chain.link](https://faucets.chain.link/klaytn-testnet). Use the [KLAY Faucet](https://baobab.wallet.klaytn.foundation/faucet) to obtain testnet KLAY.
+:::
+
+| Item | Value |
+| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| LINK Token | `0x04c5046A1f4E3fFf094c26dFCAA75eF293932f18` |
+| VRF Coordinator | [`0x771143FcB645128b07E41D79D82BE707ad8bDa1C`](https://baobab.scope.klaytn.com/address/0x771143FcB645128b07E41D79D82BE707ad8bDa1C) |
+| 750 gwei Key Hash | `0x9be50e2346ee6abe000e6d3a34245e1d232c669703efc44660a413854427027c` |
+| Premium | 0.005 LINK |
+| Max Gas Limit | 2,500,000 |
+| Minimum Confirmations | 1 |
+| Maximum Confirmations | 200 |
+| Maximum Random Values | 500 |
diff --git a/src/pages/vrf/v2/subscription/ui.md b/src/pages/vrf/v2/subscription/ui.md
new file mode 100644
index 00000000000..d2ec158b8d0
--- /dev/null
+++ b/src/pages/vrf/v2/subscription/ui.md
@@ -0,0 +1,120 @@
+---
+layout: ../../../../layouts/MainLayout.astro
+section: ethereum
+date: Last Modified
+title: "Subscription Manager User Interface"
+permalink: "docs/vrf/v2/subscription/ui/"
+whatsnext:
+ {
+ "Security Considerations": "/vrf/v2/security/",
+ "Best Practices": "/vrf/v2/best-practices/",
+ "Migrating from VRF v1 to v2": "/vrf/v2/subscription/migration-from-v1/",
+ "Supported Networks": "/vrf/v2/subscription/supported-networks/",
+ }
+metadata:
+ title: "Subscription Manager User Interface"
+ description: "Walkthrough Subscription Manager User Interface"
+setup: |
+ import VrfCommon from "@features/vrf/v2/common/VrfCommon.astro"
+---
+
+
+
+The VRF v2 Subscription Manager is available at [vrf.chain.link](https://vrf.chain.link/). The Subscription Manager lets you create a subcription and pre-pay for VRF v2 so you don't need to provide funding each time your application requests randomness. This guide walks you through the main sections of the UI.
+
+:::tip[Troubleshooting]
+Read the [pending](#pending) and [failed requests](#failed-requests) sections to learn how to troubleshoot your VRF requests.
+:::
+
+
+
+Subscription components:
+
+- **Status**: Indicates if the subscription is still active or not.
+- **ID**: The unique subscription identifier. Approved consuming contracts use LINK from this subscription to pay for each randomness request.
+- **Admin**: The account address that owns this subscription ID.
+- **Consumers**: The number of consuming contracts that are approved to make VRF requests using this subscription.
+- **Fulfillment**: The number of successful randomness requests that are already completed.
+- **Balance**: The amount of LINK remaining to be used for requests that use this subscription.
+
+You can cancel your subscription in the user interface. When you cancel your subscription, specify the account address to receive the remaining balance. See the clean up instructions in the [Get a Random Number](/vrf/v2/subscription/examples/get-a-random-number/#clean-up) guide to learn more.
+
+## Consumers
+
+
+
+The **Consumers** section lists the contracts that are allowed to use your subscription to pay for requests.
+
+- **Address**: The address of the consuming contract.
+- **Added**: The time when the consumer was added to the subscription.
+- **Last fulfillment**: The last time a VRF request was fulfilled for the consumer.
+- **Total spent**: The total amount of LINK that has been used by the consuming contract.
+
+You can use this section to add or remove consumers.
+
+## Pending
+
+
+
+The **Pending** list appears if there are requests currently being processed.
+
+- **Time**: The time when the pending VRF request was made.
+- **Consumer**: The address of the consuming contract.
+- **Transaction hash**: The transaction hash of the pending VRF request.
+- **Status**: A timer that informs you when the pending VRF request will move to a failed status. **Note**: Pending requests fail after 24h.
+- **Max Cost**: The calculated total gas cost in LINK based on the configuration. See [VRF v2 Subscription Limits](/vrf/v2/subscription/#limits) for details.
+- **Projected Balance**: This indicates when the subscription is underfunded and how many LINK tokens are required to fund the subscription.
+
+## History
+
+### Recent fulfillments
+
+
+
+The **Recent fulfillments** tab shows the details for successful VRF fulfillments.
+
+- **Time**: The time and block number indicating when the VRF request was successfully fulfilled.
+- **Consumer**: The address of the consuming contract that initiated the VRF request.
+- **Transaction Hash**: The transaction hash of the VRF callback.
+- **Status**: The status of the request. Recent fulfillments always show _Success_.
+- **Spent**: The total amount of LINK spent to fulfill the VRF request.
+- **Balance**: The LINK balance of the subscription after the VRF request was fulfilled.
+
+### Events
+
+
+
+The **Events** tab displays events linked to the subscription. There are five main events:
+
+- Subscription created
+- Subscription funded
+- Consumer added
+- Consumer removed
+- Subscription canceled
+
+Components of VRF events:
+
+- **Time**: The time when the event happened.
+- **Event**: The type of the event.
+- **Transaction Hash**: The transaction hash for the event.
+- **Consumer**: The address of the consuming contract. This is used only for _Consumer added_ and _Consumer canceled_ events.
+- **Amount**:
+ - For _Subscription funded_ events, this indicates the amount of LINK added to the subscription balance.
+ - For _Subscription canceled_ events, this indicates the amount of LINK withdrawn from the subscription balance.
+- **Balance**:
+ - For _Subscription funded_ events, this indicates the LINK balance of the subscription after it was funded.
+ - For _Subscription canceled_ events, this field should display _0_.
+
+### Failed requests
+
+
+
+The **Failed requests** tab displays failed VRF requests.
+
+- **Time**: The time when the VRF request was made.
+- **Transaction Hash**: This can be either the transaction hash of the originating VRF request if the request was pending for over 24 hours _or_ the transaction hash of the VRF callback if the callback failed.
+- **Status**: The status of the request. Failed requests always show _Failed_.
+- **Reason**: The reason why the request failed. Requests fail for one of the following reasons:
+ - Pending for over 24 hours
+ - Wrong key hash specified
+ - Callback gas limit set too low
diff --git a/src/scripts/chainlink-automation/networks-config.ts b/src/scripts/chainlink-automation/networks-config.ts
new file mode 100644
index 00000000000..b77181a6af5
--- /dev/null
+++ b/src/scripts/chainlink-automation/networks-config.ts
@@ -0,0 +1,97 @@
+import { automationAddresses, chainlinkAutomationConfig as currentConfig } from "@features/chainlink-automation/data"
+import { ChainlinkAutomationConfigs, GetStateResponse } from "@features/chainlink-automation/types"
+import { SupportedChain } from "@config"
+import { getWeb3Provider } from "@features/utils"
+import { automationRegistryBaseInterfaceABI } from "@abi"
+import { ethers } from "ethers"
+import { normalize } from "path"
+import { isEqual } from "lodash"
+import { writeFile } from "fs/promises"
+import { format } from "prettier"
+
+const configToBePath = normalize("./src/features/chainlink-automation/data/chainlink-automation-configTOBE.json")
+
+const getChainlinkAutomationConfig = async (provider: ethers.providers.Provider, registryAddress: string) => {
+ const registry = new ethers.Contract(registryAddress, automationRegistryBaseInterfaceABI, provider)
+ const state = (await registry.getState()) as GetStateResponse
+ const {
+ paymentPremiumPPB,
+ blockCountPerTurn,
+ checkGasLimit,
+ gasCeilingMultiplier,
+ minUpkeepSpend,
+ maxPerformGas,
+ fallbackGasPrice,
+ fallbackLinkPrice,
+ flatFeeMicroLink,
+ stalenessSeconds,
+ registrar,
+ transcoder,
+ } = state[1]
+ return {
+ paymentPremiumPPB,
+ blockCountPerTurn,
+ checkGasLimit,
+ gasCeilingMultiplier,
+ minUpkeepSpend,
+ maxPerformGas,
+ fallbackGasPrice,
+ fallbackLinkPrice,
+ flatFeeMicroLink,
+ stalenessSeconds,
+ registrar,
+ transcoder,
+ }
+}
+
+const getChainlinkAutomationConfigs = async () => {
+ const configs: ChainlinkAutomationConfigs = {}
+ for (const key in automationAddresses) {
+ const supportedChain = key as SupportedChain
+ const registryAddress = automationAddresses[key].registryAddress
+ const provider = getWeb3Provider(supportedChain)
+ if (!registryAddress) {
+ console.error(`Registry address not found for ${key}`)
+ } else if (!provider) {
+ console.error(`Web3 provider not found for ${key}`)
+ } else {
+ try {
+ const config = await getChainlinkAutomationConfig(provider, registryAddress)
+ configs[key] = config
+ } catch (error) {
+ console.error(error)
+ console.error(`Error while retriving chainlink automation config for ${key}`)
+ }
+ }
+ }
+ return configs
+}
+
+const compareConfigs = async () => {
+ const toBeConfig: ChainlinkAutomationConfigs = await getChainlinkAutomationConfigs()
+ let result: { isEqual: boolean; toBeConfig?: ChainlinkAutomationConfigs }
+ if (isEqual(JSON.stringify(currentConfig), JSON.stringify(toBeConfig))) {
+ result = { isEqual: true }
+ } else {
+ result = { isEqual: false, toBeConfig }
+ }
+ return result
+}
+
+compareConfigs().then(async (res) => {
+ if (!res.isEqual) {
+ await writeFile(
+ configToBePath,
+ format(JSON.stringify(res.toBeConfig), {
+ parser: "json",
+ semi: true,
+ trailingComma: "es5",
+ singleQuote: true,
+ printWidth: 120,
+ }),
+ {
+ flag: "w",
+ }
+ )
+ }
+})
diff --git a/src/scripts/click-to-zoom.ts b/src/scripts/click-to-zoom.ts
new file mode 100644
index 00000000000..f1c20b320cb
--- /dev/null
+++ b/src/scripts/click-to-zoom.ts
@@ -0,0 +1,34 @@
+document.addEventListener("DOMContentLoaded", () => {
+ document.querySelectorAll(".click-to-zoom").forEach((element: HTMLImageElement) => {
+ element.addEventListener("click", () => {
+ if (element.classList.contains("expanded")) return
+
+ element.classList.add("expanded")
+ // create wrapper for preview
+ const wrapper = document.createElement("div")
+ wrapper.id = "expanded-image-wrapper"
+
+ // create image node
+ const img = document.createElement("img")
+ img.src = element.src
+ img.className = "expanded"
+ img.id = "expanded-image-preview"
+ wrapper.appendChild(img)
+
+ // setup events to close the preview
+ wrapper.onclick = () => {
+ wrapper.remove()
+ element.classList.remove("expanded")
+ }
+ document.onkeyup = (e) => {
+ if (e.key === "Escape") {
+ wrapper.remove()
+ element.classList.remove("expanded")
+ }
+ }
+
+ // add the wrapper to the DOM
+ element.insertAdjacentElement("afterend", wrapper)
+ })
+ })
+})
diff --git a/src/scripts/copy-to-clipboard.ts b/src/scripts/copy-to-clipboard.ts
new file mode 100644
index 00000000000..85c5cb8cfb4
--- /dev/null
+++ b/src/scripts/copy-to-clipboard.ts
@@ -0,0 +1,33 @@
+import ClipboardJS from "clipboard"
+import button from "@chainlink/design-system/button.module.css"
+
+const clipboard = new ClipboardJS(".copy-iconbutton")
+
+clipboard.on("success", function (e) {
+ const oldLabel = e.trigger.innerHTML
+ e.trigger.innerHTML = ` `
+ window.setTimeout(function () {
+ e.trigger.innerHTML = oldLabel
+ }, 2000)
+ e.clearSelection()
+})
+
+document.addEventListener("DOMContentLoaded", () => {
+ document.querySelectorAll("pre").forEach(function (codeBlock) {
+ const container = document.createElement("div")
+ container.className = "copy-code-button-wrapper"
+
+ const copyButton = document.createElement("button")
+ copyButton.className = button.secondary
+ copyButton.classList.add(...["copy-iconbutton"])
+ copyButton.type = "button"
+ const s = codeBlock.innerText
+ copyButton.setAttribute("data-clipboard-text", s)
+ copyButton.innerHTML = ` `
+ copyButton.ariaLabel = "copy to clipard"
+
+ container.appendChild(copyButton)
+
+ codeBlock.insertAdjacentElement("beforebegin", container)
+ })
+})
diff --git a/src/scripts/fix-external-links.ts b/src/scripts/fix-external-links.ts
new file mode 100644
index 00000000000..a47afb5a5f6
--- /dev/null
+++ b/src/scripts/fix-external-links.ts
@@ -0,0 +1,11 @@
+document.addEventListener("DOMContentLoaded", () => {
+ const links = document.links
+ for (let i = 0, linksLength = links.length; i < linksLength; i++) {
+ if (!links[i].href.startsWith("javascript:")) {
+ if (links[i].hostname !== window.location.hostname) {
+ links[i].target = "_blank"
+ links[i].relList.add("noopener")
+ }
+ }
+ }
+})
diff --git a/src/scripts/fix-remix-urls.ts b/src/scripts/fix-remix-urls.ts
new file mode 100644
index 00000000000..d04fc52765f
--- /dev/null
+++ b/src/scripts/fix-remix-urls.ts
@@ -0,0 +1,14 @@
+/** Fixes deployment URLs when on a preview URL */
+document.addEventListener("DOMContentLoaded", () => {
+ const host = window.location.hostname
+ if (host !== "docs.chain.link") {
+ // Rewrite Remix URLs with current hostname
+ // eg https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFD20.sol
+
+ for (const item of Array.from(document.links)) {
+ if (item.href.startsWith("https://remix.ethereum.org")) {
+ item.setAttribute("href", item.href.replace("docs.chain.link", host))
+ }
+ }
+ }
+})
diff --git a/src/scripts/index.ts b/src/scripts/index.ts
new file mode 100644
index 00000000000..fda66e4ba50
--- /dev/null
+++ b/src/scripts/index.ts
@@ -0,0 +1,4 @@
+import "./fix-remix-urls"
+import "./fix-external-links"
+import "./click-to-zoom"
+import "./copy-to-clipboard"
diff --git a/src/scripts/link-to-wallet.ts b/src/scripts/link-to-wallet.ts
new file mode 100644
index 00000000000..31f9ad1de59
--- /dev/null
+++ b/src/scripts/link-to-wallet.ts
@@ -0,0 +1,350 @@
+import { MetaMaskInpageProvider } from "@metamask/providers"
+import detectEthereumProvider from "@metamask/detect-provider"
+import { BigNumberish, ethers } from "ethers"
+import { Web3Provider } from "@ethersproject/providers"
+import LinkToken from "@chainlink/contracts/abi/v0.4/LinkToken.json"
+import chains from "./reference/chains.json"
+import linkNameSymbol from "./reference/linkNameSymbol.json"
+import buttonStyles from "@chainlink/design-system/button.module.css"
+
+// disable unnecessary warnings
+ethers.utils.Logger.setLogLevel(ethers.utils.Logger.levels.ERROR)
+
+const chainlinkLogo =
+ "https://assets-global.website-files.com/5f6b7190899f41fb70882d08/5fa973e31adbc3414aa8f77d_Chainlink-webclip.png"
+
+const separator = "_"
+const addressPattern = "0x[0-9a-fA-F]{40}"
+const hexStringPattern = "(0x|0X)[a-fA-F0-9]+"
+// Test to follow this pattern: chainId_address (e.g.: 1_0x514910771af9ca656af840dff83e8264ecf986ca)
+const pattern = new RegExp(`^[0-9]+${separator}${addressPattern}$`)
+const linkToken = {
+ name: "ChainLink Token",
+ symbol: "LINK",
+ decimals: 18,
+}
+const addToWalletText = "Add to wallet"
+const switchToNetworkText = "Switch network and add to wallet"
+const initChainChangeEventName = "InitChainChange"
+
+/**
+ * Converts a nulber to HexString (a string which has a 0x prefix followed by any number of nibbles (i.e. case-insensitive hexadecimal characters, 0-9 and a-f).)
+ */
+const toHex = ethers.utils.hexValue
+
+/**
+ * Check that the format of ethereum address is valid
+ * @param address Ethereum address
+ * @returns boolean true if format is valid. False otherwise
+ */
+const isAddressFormatValid = (address: string): boolean => {
+ const pattern = new RegExp(`^${addressPattern}$`)
+ return pattern.test(address)
+}
+
+/**
+ * Check that the format of a chainId is hexString
+ * (a string which has a 0x prefix followed by any number of nibbles (i.e. case-insensitive hexadecimal characters, 0-9 and a-f).))
+ * @param chainId
+ * @returns boolean: true if chainId is hexString. False otherwise
+ */
+const isChainIdFormatValid = (chainId: string): boolean => {
+ const pattern = new RegExp(`^${hexStringPattern}$`)
+ return pattern.test(chainId)
+}
+
+interface AddToWalletParameters {
+ type: string
+ address: string
+ symbol: string
+ decimals: number
+ image?: string
+}
+
+interface AddEthereumChainParameter {
+ chainId: string
+ blockExplorerUrls?: string[]
+ chainName?: string
+ iconUrls?: string[]
+ nativeCurrency?: {
+ name: string
+ symbol: string
+ decimals: number
+ }
+ rpcUrls?: string[]
+}
+
+interface ProviderRpcError extends Error {
+ message: string
+ code: number
+ data?: unknown
+}
+
+const defaultWalletParameters: AddToWalletParameters = {
+ type: "ERC20",
+ address: "",
+ symbol: linkToken.symbol,
+ decimals: linkToken.decimals,
+ image: chainlinkLogo,
+}
+
+/**
+ * Validate that the in page ethereum provider is loaded
+ * @param ethereum : InPageProvider
+ */
+const validateEthereumApi = (ethereum: MetaMaskInpageProvider) => {
+ if (!ethereum || !ethereum.isMetaMask) {
+ throw new Error(`Something went wrong. Add to wallet is called while an ethereum object not detected.`)
+ }
+}
+
+/**
+ * Add asset (e.g.: Link token) to wallet
+ * @param ethereum inpage provider (e.g.: provider loaded by Metamask)
+ * @param parameters
+ */
+const addAssetToWallet = async (ethereum: MetaMaskInpageProvider, parameters: AddToWalletParameters) => {
+ validateEthereumApi(ethereum)
+ const success = await ethereum.request({
+ method: "wallet_watchAsset",
+ params: {
+ type: parameters.type,
+ options: {
+ address: parameters.address,
+ symbol: parameters.symbol,
+ decimals: parameters.decimals,
+ image: parameters.image,
+ },
+ },
+ })
+
+ if (success) {
+ console.log(`${parameters.symbol} of address ${parameters.address} successfully added to the wallet`)
+ } else {
+ throw new Error(
+ `Something went wrong. ${parameters.symbol} of address ${parameters.address} not added to the wallet`
+ )
+ }
+}
+
+/**
+ * Call this function to make the wallet switch to the desired chain
+ * @param chainId designed chain in HexString
+ * @param ethereum ethereum inpage provider (e.g.: provider loaded by Metamask)
+ */
+const switchToChain = async (chainId: string, ethereum: MetaMaskInpageProvider) => {
+ if (!isChainIdFormatValid(chainId)) {
+ throw new Error(`chainId '${chainId}' must be hexString`)
+ }
+ validateEthereumApi(ethereum)
+ await ethereum.request({
+ method: "wallet_switchEthereumChain",
+ params: [{ chainId }],
+ })
+ console.log(`Succesfully switched to chain ${chainId} in metamask`)
+}
+
+/**
+ * Call this function to add a new chain to the wallet. Should only be called if the chain doesn't exist already in the wallet
+ * @param chainId designed chain in HexString
+ * @param ethereum ethereum in page provider (e.g.: provider loaded by Metamask)
+ */
+const addChainToWallet = async (chainId: string, ethereum: MetaMaskInpageProvider) => {
+ if (!isChainIdFormatValid(chainId)) {
+ throw new Error(`chainId '${chainId}' must be hexString`)
+ }
+ validateEthereumApi(ethereum)
+
+ const chain = chains.find((c: any) => toHex(c.chainId) === chainId)
+ if (!chain || !chain.chainId) {
+ throw new Error(`Chain with chainId '${chainId}' not found in reference data`)
+ }
+
+ const params: AddEthereumChainParameter = {
+ chainId,
+ chainName: chain.name,
+ nativeCurrency: chain?.nativeCurrency,
+ blockExplorerUrls:
+ chain.explorers && chain.explorers.length > 0 && chain.explorers[0].url
+ ? chain.explorers.map((explorer: any) => explorer.url)
+ : [chain.infoURL],
+ rpcUrls: chain.rpc,
+ }
+
+ const [signerAddress] = (await ethereum.request({
+ method: "eth_requestAccounts",
+ })) as string[]
+ await ethereum.request({
+ method: "wallet_addEthereumChain",
+ params: [params, signerAddress],
+ })
+ console.log(`Chains ${chainId} of params ${JSON.stringify(params)} succesfully added to wallet`)
+}
+
+/**
+ * Functions which validates the format of Link address and interfacs with the contract to make sure
+ * its metadata (e.g.: symbol) is valid
+ * @param address
+ * @param provider
+ */
+const validateLinkAddress = async (address: string, provider: Web3Provider) => {
+ if (!isAddressFormatValid(address)) {
+ throw new Error(`Something went wrong. format of address '${address}' not correct`)
+ }
+
+ // The Contract object
+ const linkContract = new ethers.Contract(address, LinkToken, provider)
+ let name: string, symbol: string, decimals: BigNumberish
+ try {
+ name = await linkContract.name()
+ symbol = await linkContract.symbol()
+ decimals = await linkContract.decimals()
+ } catch (error) {
+ throw new Error(`Error occured while trying to fetch linkContract metadata ${error}`)
+ }
+
+ let chainId: keyof typeof linkNameSymbol
+ if (Object.keys(linkNameSymbol).includes(provider.network.chainId.toString())) {
+ chainId = provider.network.chainId.toString() as keyof typeof linkNameSymbol
+ } else {
+ throw new Error(`Error chain ${provider.network.chainId} not found in reference data`)
+ }
+
+ const linkAttributes = linkNameSymbol[chainId]
+ if (!linkAttributes || !linkAttributes.name || !linkAttributes.symbol) {
+ throw new Error(`Error linkContract attributes. data ${linkAttributes} for chain ${chainId} corrupted`)
+ }
+ if (name !== linkAttributes.name) {
+ throw new Error(`Error linkContract name. '${name}' !== '${linkAttributes.name}'`)
+ }
+ if (symbol !== linkAttributes.symbol) {
+ throw new Error(`Error linkContract symbol. '${symbol}' !== '${linkAttributes.symbol}'`)
+ }
+ if (linkToken.decimals !== decimals) {
+ throw new Error(`Error linkContract decimals. '${linkToken.decimals}' !== '${decimals}'`)
+ }
+}
+
+try {
+ const ethereum = (await detectEthereumProvider()) as MetaMaskInpageProvider
+ // Support only Metamask extension for now.
+ if (!ethereum || !ethereum.isMetaMask) throw Error()
+
+ const provider = new ethers.providers.Web3Provider(ethereum as any, "any")
+
+ let detectedChainId: string | number | null = (await ethereum.request({
+ method: "eth_chainId",
+ })) as string | null
+ if (!detectedChainId) {
+ console.error(`Something went wrong. Wallet detected but chain not detected`)
+ throw Error()
+ }
+ detectedChainId = toHex(parseInt(detectedChainId))
+ if (!isChainIdFormatValid(detectedChainId)) {
+ console.error(`Something went wrong. format of detectedChainId '${detectedChainId}' not hexString`)
+ throw Error()
+ }
+
+ // Detect when user initiates the chain switch from the webapp
+ // variable chainFromSwitch used to diffenrentiate when user switch the chain
+ // directly from wallet
+ let chainFromSwitch: string
+ window.addEventListener(initChainChangeEventName, (evt: any) => {
+ chainFromSwitch = toHex(parseInt(evt.detail?.chainId))
+ if (!isChainIdFormatValid(chainFromSwitch)) {
+ console.error(`Something went wrong. format of chainFromSwitch '${chainFromSwitch}' not hexString`)
+ }
+ })
+
+ // Reload the page if the user changes the Chain.
+ // Only reload the page if the user initiates the switch directly from wallet
+ ethereum.on("chainChanged", (chainId) => {
+ if (chainId !== detectedChainId && chainFromSwitch !== chainId) {
+ window.location.reload()
+ }
+ })
+
+ const tokenAddressElements = Array.from(document.getElementsByClassName("erc-token-address"))
+
+ tokenAddressElements.forEach((element) => {
+ const id = element.id
+ // Make sure it has the right format.
+ if (!pattern.test(id)) {
+ if (!id) {
+ console.error(`Element's id cannot be null/empty if its class is erc-token-address `)
+ } else {
+ console.error(`Format of id ${id} not correct. Format should follow the pattern chainId_address`)
+ }
+ return
+ }
+ let [chainId, address] = id.split(separator)
+ chainId = toHex(parseInt(chainId))
+ if (!isChainIdFormatValid(chainId)) {
+ console.error(`Something went wrong. format of chainId '${chainId}' not hexString`)
+ return
+ }
+
+ const button = document.createElement("button")
+ button.className = `${buttonStyles.secondary} linkToWalletBtn`
+ button.style.marginLeft = "10px"
+ button.style.fontSize = "12px"
+ button.style.padding = "4px"
+ const parameters: AddToWalletParameters = {
+ ...defaultWalletParameters,
+ address,
+ }
+
+ if (chainId === detectedChainId) {
+ // Insert add wallet button only for the detected chainId.
+ button.innerText = addToWalletText
+ button.onclick = async () => {
+ try {
+ await validateLinkAddress(address, provider)
+ addAssetToWallet(ethereum, parameters)
+ } catch (error) {
+ console.error(error)
+ }
+ }
+ } else {
+ button.innerText = switchToNetworkText
+ button.title = `Switch to network ${chainId} before adding the Link token`
+ button.onclick = async () => {
+ window.dispatchEvent(
+ new CustomEvent(initChainChangeEventName, {
+ detail: {
+ chainId,
+ },
+ })
+ )
+ try {
+ await switchToChain(chainId, ethereum)
+ } catch (switchError) {
+ if ((switchError as ProviderRpcError).code === 4902) {
+ // This error code indicates that the chain has not been added to MetaMask.
+ try {
+ await addChainToWallet(chainId, ethereum)
+ } catch (error) {
+ console.error(`Error happened when adding chain ${chainId} to metamask`, error)
+ return
+ }
+ } else {
+ console.error(`Error happened when switching to chain ${chainId} to metamask`, switchError)
+ return
+ }
+ }
+
+ try {
+ await validateLinkAddress(address, provider)
+ addAssetToWallet(ethereum, parameters)
+ } catch (error) {
+ console.error(error)
+ }
+ // Make sure the page is reloaded after the asset is loaded to the wallet
+ window.location.reload()
+ }
+ }
+ element.insertAdjacentElement("afterend", button)
+ })
+} catch (e) {
+ console.error(e)
+}
diff --git a/src/scripts/prism-jpv2.ts b/src/scripts/prism-jpv2.ts
new file mode 100644
index 00000000000..605421fbc17
--- /dev/null
+++ b/src/scripts/prism-jpv2.ts
@@ -0,0 +1,28 @@
+// Expand with support for job spec v2 toml
+Prism.languages.jpv2dot = Prism.languages.extend("dot", {})
+
+const variable = {
+ pattern: /\$\(.*\)/,
+ lookbehind: !0,
+ inside: {
+ comment: {
+ pattern: /[$().]/,
+ },
+ keyword: {
+ pattern: /[^$().]/,
+ },
+ },
+}
+
+Prism.languages.jpv2dot["attr-value"].inside.variable = variable
+Prism.languages.jpv2dot["attr-value"].inside.markup.inside.variable = variable
+
+Prism.languages.jpv2 = Prism.languages.extend("toml", {})
+Prism.languages.insertBefore("jpv2", "string", {
+ pipeline: {
+ pattern: /"""(?:\\[\s\S]|[^\\])*?"""/,
+ inside: Prism.languages.jpv2dot,
+ greedy: !0,
+ alias: "language-jpv2dot",
+ },
+})
diff --git a/src/scripts/reference/chains.json b/src/scripts/reference/chains.json
new file mode 100644
index 00000000000..40d41d8bcc9
--- /dev/null
+++ b/src/scripts/reference/chains.json
@@ -0,0 +1,385 @@
+[
+ {
+ "name": "Ethereum Mainnet",
+ "chain": "ETH",
+ "icon": "ethereum",
+ "rpc": [
+ "https://mainnet.infura.io/v3/${INFURA_API_KEY}",
+ "wss://mainnet.infura.io/ws/v3/${INFURA_API_KEY}",
+ "https://api.mycryptoapi.com/eth",
+ "https://cloudflare-eth.com"
+ ],
+ "faucets": [],
+ "nativeCurrency": { "name": "Ether", "symbol": "ETH", "decimals": 18 },
+ "infoURL": "https://ethereum.org",
+ "shortName": "eth",
+ "chainId": 1,
+ "networkId": 1,
+ "slip44": 60,
+ "ens": { "registry": "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" },
+ "explorers": [{ "name": "etherscan", "url": "https://etherscan.io", "standard": "EIP3091" }]
+ },
+ {
+ "name": "Rinkeby",
+ "title": "Ethereum Testnet Rinkeby",
+ "chain": "ETH",
+ "rpc": ["https://rinkeby.infura.io/v3/${INFURA_API_KEY}", "wss://rinkeby.infura.io/ws/v3/${INFURA_API_KEY}"],
+ "faucets": ["http://fauceth.komputing.org?chain=4&address=${ADDRESS}", "https://faucet.rinkeby.io"],
+ "nativeCurrency": { "name": "Rinkeby Ether", "symbol": "ETH", "decimals": 18 },
+ "infoURL": "https://www.rinkeby.io",
+ "shortName": "rin",
+ "chainId": 4,
+ "networkId": 4,
+ "ens": { "registry": "0xe7410170f87102df0055eb195163a03b7f2bff4a" },
+ "explorers": [{ "name": "etherscan-rinkeby", "url": "https://rinkeby.etherscan.io", "standard": "EIP3091" }]
+ },
+ {
+ "name": "Görli",
+ "title": "Ethereum Testnet Görli",
+ "chain": "ETH",
+ "rpc": [
+ "https://goerli.infura.io/v3/${INFURA_API_KEY}",
+ "wss://goerli.infura.io/v3/${INFURA_API_KEY}",
+ "https://rpc.goerli.mudit.blog/"
+ ],
+ "faucets": [
+ "http://fauceth.komputing.org?chain=5&address=${ADDRESS}",
+ "https://goerli-faucet.slock.it?address=${ADDRESS}",
+ "https://faucet.goerli.mudit.blog"
+ ],
+ "nativeCurrency": { "name": "Görli Ether", "symbol": "ETH", "decimals": 18 },
+ "infoURL": "https://goerli.net/#about",
+ "shortName": "gor",
+ "chainId": 5,
+ "networkId": 5,
+ "ens": { "registry": "0x112234455c3a32fd11230c42e7bccd4a84e02010" },
+ "explorers": [{ "name": "etherscan-goerli", "url": "https://goerli.etherscan.io", "standard": "EIP3091" }]
+ },
+ {
+ "name": "Optimism",
+ "chain": "ETH",
+ "rpc": ["https://mainnet.optimism.io/"],
+ "faucets": [],
+ "nativeCurrency": { "name": "Ether", "symbol": "ETH", "decimals": 18 },
+ "infoURL": "https://optimism.io",
+ "shortName": "oeth",
+ "chainId": 10,
+ "networkId": 10,
+ "explorers": [{ "name": "etherscan", "url": "https://optimistic.etherscan.io", "standard": "EIP3091" }]
+ },
+ {
+ "name": "RSK Mainnet",
+ "chain": "RSK",
+ "rpc": ["https://public-node.rsk.co", "https://mycrypto.rsk.co"],
+ "faucets": ["https://faucet.rsk.co/"],
+ "nativeCurrency": { "name": "Smart Bitcoin", "symbol": "RBTC", "decimals": 18 },
+ "infoURL": "https://rsk.co",
+ "shortName": "rsk",
+ "chainId": 30,
+ "networkId": 30,
+ "slip44": 137,
+ "explorers": [{ "name": "RSK Explorer", "url": "https://explorer.rsk.co", "standard": "EIP3091" }]
+ },
+ {
+ "name": "Binance Smart Chain Mainnet",
+ "chain": "BSC",
+ "rpc": [
+ "https://bsc-dataseed1.binance.org",
+ "https://bsc-dataseed2.binance.org",
+ "https://bsc-dataseed3.binance.org",
+ "https://bsc-dataseed4.binance.org",
+ "https://bsc-dataseed1.defibit.io",
+ "https://bsc-dataseed2.defibit.io",
+ "https://bsc-dataseed3.defibit.io",
+ "https://bsc-dataseed4.defibit.io",
+ "https://bsc-dataseed1.ninicoin.io",
+ "https://bsc-dataseed2.ninicoin.io",
+ "https://bsc-dataseed3.ninicoin.io",
+ "https://bsc-dataseed4.ninicoin.io",
+ "wss://bsc-ws-node.nariox.org"
+ ],
+ "faucets": ["https://free-online-app.com/faucet-for-eth-evm-chains/"],
+ "nativeCurrency": { "name": "Binance Chain Native Token", "symbol": "BNB", "decimals": 18 },
+ "infoURL": "https://www.binance.org",
+ "shortName": "bnb",
+ "chainId": 56,
+ "networkId": 56,
+ "slip44": 714,
+ "explorers": [{ "name": "bscscan", "url": "https://bscscan.com", "standard": "EIP3091" }]
+ },
+ {
+ "name": "Binance Smart Chain Testnet",
+ "chain": "BSC",
+ "rpc": [
+ "https://data-seed-prebsc-1-s1.binance.org:8545",
+ "https://data-seed-prebsc-2-s1.binance.org:8545",
+ "https://data-seed-prebsc-1-s2.binance.org:8545",
+ "https://data-seed-prebsc-2-s2.binance.org:8545",
+ "https://data-seed-prebsc-1-s3.binance.org:8545",
+ "https://data-seed-prebsc-2-s3.binance.org:8545"
+ ],
+ "faucets": ["https://testnet.binance.org/faucet-smart"],
+ "nativeCurrency": { "name": "Binance Chain Native Token", "symbol": "tBNB", "decimals": 18 },
+ "infoURL": "https://testnet.binance.org/",
+ "shortName": "bnbt",
+ "chainId": 97,
+ "networkId": 97,
+ "explorers": [{ "name": "bscscan-testnet", "url": "https://testnet.bscscan.com", "standard": "EIP3091" }]
+ },
+ {
+ "name": "Gnosis",
+ "chain": "GNO",
+ "icon": "gnosis",
+ "rpc": [
+ "https://rpc.gnosischain.com",
+ "https://rpc.ankr.com/gnosis",
+ "https://gnosischain-rpc.gateway.pokt.network",
+ "https://gnosis-mainnet.public.blastapi.io",
+ "wss://rpc.gnosischain.com/wss"
+ ],
+ "faucets": [
+ "https://gnosisfaucet.com",
+ "https://faucet.gimlu.com/gnosis",
+ "https://stakely.io/faucet/gnosis-chain-xdai",
+ "https://faucet.prussia.dev/xdai"
+ ],
+ "nativeCurrency": { "name": "xDAI", "symbol": "xDAI", "decimals": 18 },
+ "infoURL": "https://docs.gnosischain.com",
+ "shortName": "gno",
+ "chainId": 100,
+ "networkId": 100,
+ "slip44": 700,
+ "explorers": [
+ { "name": "gnosisscan", "url": "https://gnosisscan.io", "icon": "gnosisscan", "standard": "EIP3091" },
+ {
+ "name": "blockscout",
+ "url": "https://blockscout.com/xdai/mainnet",
+ "icon": "blockscout",
+ "standard": "EIP3091"
+ }
+ ]
+ },
+ {
+ "name": "Huobi ECO Chain Mainnet",
+ "chain": "Heco",
+ "rpc": ["https://http-mainnet.hecochain.com", "wss://ws-mainnet.hecochain.com"],
+ "faucets": ["https://free-online-app.com/faucet-for-eth-evm-chains/"],
+ "nativeCurrency": { "name": "Huobi ECO Chain Native Token", "symbol": "HT", "decimals": 18 },
+ "infoURL": "https://www.hecochain.com",
+ "shortName": "heco",
+ "chainId": 128,
+ "networkId": 128,
+ "slip44": 1010,
+ "explorers": [{ "name": "hecoinfo", "url": "https://hecoinfo.com", "standard": "EIP3091" }]
+ },
+ {
+ "name": "Polygon Mainnet",
+ "chain": "Polygon",
+ "rpc": [
+ "https://polygon-rpc.com/",
+ "https://rpc-mainnet.matic.network",
+ "https://matic-mainnet.chainstacklabs.com",
+ "https://rpc-mainnet.maticvigil.com",
+ "https://rpc-mainnet.matic.quiknode.pro",
+ "https://matic-mainnet-full-rpc.bwarelabs.com"
+ ],
+ "faucets": [],
+ "nativeCurrency": { "name": "MATIC", "symbol": "MATIC", "decimals": 18 },
+ "infoURL": "https://polygon.technology/",
+ "shortName": "matic",
+ "chainId": 137,
+ "networkId": 137,
+ "slip44": 966,
+ "explorers": [{ "name": "polygonscan", "url": "https://polygonscan.com", "standard": "EIP3091" }]
+ },
+ {
+ "name": "Fantom Opera",
+ "chain": "FTM",
+ "rpc": ["https://rpc.ftm.tools"],
+ "faucets": ["https://free-online-app.com/faucet-for-eth-evm-chains/"],
+ "nativeCurrency": { "name": "Fantom", "symbol": "FTM", "decimals": 18 },
+ "infoURL": "https://fantom.foundation",
+ "shortName": "ftm",
+ "chainId": 250,
+ "networkId": 250,
+ "icon": "fantom",
+ "explorers": [{ "name": "ftmscan", "url": "https://ftmscan.com", "icon": "ftmscan", "standard": "EIP3091" }]
+ },
+ {
+ "name": "Optimism Goerli Testnet",
+ "chain": "ETH",
+ "rpc": ["https://goerli.optimism.io/"],
+ "faucets": [],
+ "nativeCurrency": { "name": "Görli Ether", "symbol": "ETH", "decimals": 18 },
+ "infoURL": "https://optimism.io",
+ "shortName": "ogor",
+ "chainId": 420,
+ "networkId": 420
+ },
+ {
+ "name": "Klaytn Testnet Baobab",
+ "chain": "KLAY",
+ "rpc": ["https://api.baobab.klaytn.net:8651"],
+ "faucets": ["https://baobab.wallet.klaytn.com/access?next=faucet"],
+ "nativeCurrency": { "name": "KLAY", "symbol": "KLAY", "decimals": 18 },
+ "infoURL": "https://www.klaytn.com/",
+ "shortName": "Baobab",
+ "chainId": 1001,
+ "networkId": 1001
+ },
+ {
+ "name": "Metis Andromeda Mainnet",
+ "chain": "ETH",
+ "rpc": ["https://andromeda.metis.io/?owner=1088"],
+ "faucets": [],
+ "nativeCurrency": { "name": "Metis", "symbol": "METIS", "decimals": 18 },
+ "infoURL": "https://www.metis.io",
+ "shortName": "metis-andromeda",
+ "chainId": 1088,
+ "networkId": 1088,
+ "explorers": [{ "name": "blockscout", "url": "https://andromeda-explorer.metis.io", "standard": "EIP3091" }],
+ "parent": { "type": "L2", "chain": "eip155-1", "bridges": [{ "url": "https://bridge.metis.io" }] }
+ },
+ {
+ "name": "Moonbeam",
+ "chain": "MOON",
+ "rpc": ["https://rpc.api.moonbeam.network", "wss://wss.api.moonbeam.network"],
+ "faucets": [],
+ "nativeCurrency": { "name": "Glimmer", "symbol": "GLMR", "decimals": 18 },
+ "infoURL": "https://moonbeam.network/networks/moonbeam/",
+ "shortName": "mbeam",
+ "chainId": 1284,
+ "networkId": 1284,
+ "explorers": [{ "name": "moonscan", "url": "https://moonbeam.moonscan.io", "standard": "none" }]
+ },
+ {
+ "name": "Moonriver",
+ "chain": "MOON",
+ "rpc": ["https://rpc.api.moonriver.moonbeam.network", "wss://wss.api.moonriver.moonbeam.network"],
+ "faucets": [],
+ "nativeCurrency": { "name": "Moonriver", "symbol": "MOVR", "decimals": 18 },
+ "infoURL": "https://moonbeam.network/networks/moonriver/",
+ "shortName": "mriver",
+ "chainId": 1285,
+ "networkId": 1285,
+ "explorers": [{ "name": "moonscan", "url": "https://moonriver.moonscan.io", "standard": "none" }]
+ },
+ {
+ "name": "Fantom Testnet",
+ "chain": "FTM",
+ "rpc": ["https://rpc.testnet.fantom.network"],
+ "faucets": ["https://faucet.fantom.network"],
+ "nativeCurrency": { "name": "Fantom", "symbol": "FTM", "decimals": 18 },
+ "infoURL": "https://docs.fantom.foundation/quick-start/short-guide#fantom-testnet",
+ "shortName": "tftm",
+ "chainId": 4002,
+ "networkId": 4002,
+ "icon": "fantom",
+ "explorers": [{ "name": "ftmscan", "url": "https://testnet.ftmscan.com", "icon": "ftmscan", "standard": "EIP3091" }]
+ },
+ {
+ "name": "Arbitrum One",
+ "chainId": 42161,
+ "shortName": "arb1",
+ "chain": "ETH",
+ "networkId": 42161,
+ "nativeCurrency": { "name": "Ether", "symbol": "ETH", "decimals": 18 },
+ "rpc": [
+ "https://arbitrum-mainnet.infura.io/v3/${INFURA_API_KEY}",
+ "https://arb-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
+ "https://arb1.arbitrum.io/rpc"
+ ],
+ "faucets": [],
+ "explorers": [
+ { "name": "Arbiscan", "url": "https://arbiscan.io", "standard": "EIP3091" },
+ { "name": "Arbitrum Explorer", "url": "https://explorer.arbitrum.io", "standard": "EIP3091" }
+ ],
+ "infoURL": "https://arbitrum.io",
+ "parent": { "type": "L2", "chain": "eip155-1", "bridges": [{ "url": "https://bridge.arbitrum.io" }] }
+ },
+ {
+ "name": "Avalanche Fuji Testnet",
+ "chain": "AVAX",
+ "rpc": ["https://api.avax-test.network/ext/bc/C/rpc"],
+ "faucets": ["https://faucet.avax-test.network/"],
+ "nativeCurrency": { "name": "Avalanche", "symbol": "AVAX", "decimals": 18 },
+ "infoURL": "https://cchain.explorer.avax-test.network",
+ "shortName": "Fuji",
+ "chainId": 43113,
+ "networkId": 1,
+ "explorers": [{ "name": "snowtrace", "url": "https://testnet.snowtrace.io", "standard": "EIP3091" }]
+ },
+ {
+ "name": "Avalanche C-Chain",
+ "chain": "AVAX",
+ "rpc": ["https://api.avax.network/ext/bc/C/rpc"],
+ "faucets": ["https://free-online-app.com/faucet-for-eth-evm-chains/"],
+ "nativeCurrency": { "name": "Avalanche", "symbol": "AVAX", "decimals": 18 },
+ "infoURL": "https://www.avax.network/",
+ "shortName": "avax",
+ "chainId": 43114,
+ "networkId": 43114,
+ "slip44": 9005,
+ "explorers": [{ "name": "snowtrace", "url": "https://snowtrace.io", "standard": "EIP3091" }]
+ },
+ {
+ "name": "Mumbai",
+ "title": "Polygon Testnet Mumbai",
+ "chain": "Polygon",
+ "rpc": [
+ "https://matic-mumbai.chainstacklabs.com",
+ "https://rpc-mumbai.maticvigil.com",
+ "https://matic-testnet-archive-rpc.bwarelabs.com"
+ ],
+ "faucets": ["https://faucet.polygon.technology/"],
+ "nativeCurrency": { "name": "MATIC", "symbol": "MATIC", "decimals": 18 },
+ "infoURL": "https://polygon.technology/",
+ "shortName": "maticmum",
+ "chainId": 80001,
+ "networkId": 80001,
+ "explorers": [{ "name": "polygonscan", "url": "https://mumbai.polygonscan.com", "standard": "EIP3091" }]
+ },
+ {
+ "name": "Arbitrum Rinkeby",
+ "title": "Arbitrum Testnet Rinkeby",
+ "chainId": 421611,
+ "shortName": "arb-rinkeby",
+ "chain": "ETH",
+ "networkId": 421611,
+ "nativeCurrency": { "name": "Arbitrum Rinkeby Ether", "symbol": "ETH", "decimals": 18 },
+ "rpc": ["https://rinkeby.arbitrum.io/rpc"],
+ "faucets": ["http://fauceth.komputing.org?chain=421611&address=${ADDRESS}"],
+ "infoURL": "https://arbitrum.io",
+ "explorers": [
+ { "name": "arbiscan-testnet", "url": "https://testnet.arbiscan.io", "standard": "EIP3091" },
+ { "name": "arbitrum-rinkeby", "url": "https://rinkeby-explorer.arbitrum.io", "standard": "EIP3091" }
+ ],
+ "parent": { "type": "L2", "chain": "eip155-4", "bridges": [{ "url": "https://bridge.arbitrum.io" }] }
+ },
+ {
+ "name": "Harmony Mainnet Shard 0",
+ "chain": "Harmony",
+ "rpc": ["https://api.harmony.one", "https://api.s0.t.hmny.io"],
+ "faucets": ["https://free-online-app.com/faucet-for-eth-evm-chains/"],
+ "nativeCurrency": { "name": "ONE", "symbol": "ONE", "decimals": 18 },
+ "infoURL": "https://www.harmony.one/",
+ "shortName": "hmy-s0",
+ "chainId": 1666600000,
+ "networkId": 1666600000,
+ "explorers": [{ "name": "Harmony Block Explorer", "url": "https://explorer.harmony.one", "standard": "EIP3091" }]
+ },
+ {
+ "name": "Harmony Testnet Shard 0",
+ "chain": "Harmony",
+ "rpc": ["https://api.s0.b.hmny.io"],
+ "faucets": ["https://faucet.pops.one"],
+ "nativeCurrency": { "name": "ONE", "symbol": "ONE", "decimals": 18 },
+ "infoURL": "https://www.harmony.one/",
+ "shortName": "hmy-b-s0",
+ "chainId": 1666700000,
+ "networkId": 1666700000,
+ "explorers": [
+ { "name": "Harmony Testnet Block Explorer", "url": "https://explorer.pops.one", "standard": "EIP3091" }
+ ]
+ }
+]
diff --git a/src/scripts/reference/linkNameSymbol.json b/src/scripts/reference/linkNameSymbol.json
new file mode 100644
index 00000000000..5695e89d59a
--- /dev/null
+++ b/src/scripts/reference/linkNameSymbol.json
@@ -0,0 +1,25 @@
+{
+ "1": { "name": "ChainLink Token", "symbol": "LINK" },
+ "5": { "name": "ChainLink Token", "symbol": "LINK" },
+ "56": { "name": "ChainLink Token", "symbol": "LINK" },
+ "97": { "name": "ChainLink Token", "symbol": "LINK" },
+ "137": { "name": "ChainLink Token", "symbol": "LINK" },
+ "80001": { "name": "ChainLink Token", "symbol": "LINK" },
+ "30": { "name": "rLINK", "symbol": "rLINK" },
+ "100": { "name": "ChainLink Token on xDai", "symbol": "LINK" },
+ "1088": { "name": "ChainLink Token", "symbol": "LINK" },
+ "43114": { "name": "Chainlink Token", "symbol": "LINK.e" },
+ "43113": { "name": "ChainLink Token", "symbol": "LINK" },
+ "250": { "name": "ChainLink Token", "symbol": "anyLINK" },
+ "4002": { "name": "ChainLink Token", "symbol": "LINK" },
+ "42161": { "name": "ChainLink Token", "symbol": "LINK" },
+ "421611": { "name": "ChainLink Token", "symbol": "LINK" },
+ "128": { "name": "Heco-Peg LINK Token", "symbol": "LINK" },
+ "10": { "name": "ChainLink Token", "symbol": "LINK" },
+ "420": { "name": "ChainLink Token", "symbol": "LINK" },
+ "1666600000": { "name": "ChainLink Token", "symbol": "LINK" },
+ "1666700000": { "name": "ChainLink Token", "symbol": "LINK" },
+ "1285": { "name": "ChainLink Token", "symbol": "LINK" },
+ "1284": { "name": "ChainLink Token", "symbol": "LINK" },
+ "1001": { "name": "ChainLink Token", "symbol": "LINK" }
+}
diff --git a/src/styles/copy-to-clipboard.css b/src/styles/copy-to-clipboard.css
new file mode 100644
index 00000000000..9d79717f7cb
--- /dev/null
+++ b/src/styles/copy-to-clipboard.css
@@ -0,0 +1,20 @@
+.copy-code-button-wrapper {
+ padding: var(--space-2x) var(--space-2x) var(--space-0x) var(--space-0x);
+ margin-top: 0 !important;
+ display: flex;
+ z-index: 999;
+ justify-content: flex-end;
+ position: absolute;
+ transform: translateY(5px);
+ right: 0;
+}
+
+.copy-code-button-wrapper > button {
+ padding: var(--space-1x);
+ display: flex;
+}
+
+.copy-code-button-wrapper > button > img {
+ width: 16px;
+ height: 16px;
+}
diff --git a/src/styles/index.css b/src/styles/index.css
new file mode 100644
index 00000000000..f977ea063a9
--- /dev/null
+++ b/src/styles/index.css
@@ -0,0 +1,352 @@
+/* Starter file. Has to be replaced with styles from design-system */
+
+* {
+ box-sizing: border-box;
+ margin: 0;
+}
+
+/* Global focus outline reset */
+*:focus:not(:focus-visible) {
+ outline: none;
+}
+
+:root {
+ --user-font-scale: 1rem - 16px;
+ --max-width: calc(100%);
+ --fullwidth-max-width: calc(100% - 1rem);
+}
+
+@media (min-width: 50em) {
+ :root {
+ --max-width: 46em;
+ --fullwidth-max-width: 80rem;
+ }
+}
+
+body {
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+ max-width: 100vw;
+ overflow-x: hidden;
+ margin: 0;
+}
+
+nav ul {
+ list-style: none;
+ padding: 0;
+}
+
+.content > section > * + * {
+ margin-top: 1.25rem;
+}
+
+.content > section > :first-child {
+ margin-top: 0;
+}
+
+.content :is(ul, ol) {
+ line-height: 1.25em;
+ margin-bottom: 0.7em;
+}
+
+.content :is(ul, ol) > li > :is(ul, ol) {
+ margin-top: 0.5rem;
+}
+
+:where(a) {
+ color: var(--color-text-link);
+ text-decoration: none;
+ align-items: center;
+ gap: 0.3rem;
+}
+
+:where(a:hover) {
+ color: var(--color-text-link-hover);
+}
+:where(a:focus) {
+ color: var(--color-text-link-clicked);
+}
+article > section :is(ul, ol) > * + * {
+ margin-top: 0.75rem;
+}
+
+article > section nav :is(ul, ol) > * + * {
+ margin-top: inherit;
+}
+
+article > section li > :is(p, pre, blockquote):not(:first-child) {
+ margin-top: 1rem;
+}
+
+article > section :is(ul) {
+ padding-left: 1em;
+}
+
+article > section :is(ol) {
+ padding-left: 2em;
+}
+
+article > section nav :is(ul, ol) {
+ padding-left: inherit;
+}
+
+article > section nav {
+ margin-top: 1rem;
+ margin-bottom: 2rem;
+}
+
+article > section ::marker {
+ font-weight: bold;
+ color: var(--theme-text-light);
+}
+
+article > section iframe {
+ width: 100%;
+ height: auto;
+ aspect-ratio: 16 / 9;
+}
+
+.main-section {
+ position: relative;
+}
+
+.main-section :is(p) {
+ /* Override styles from design-system */
+ margin-bottom: 0;
+ max-width: 100%;
+}
+
+.main-section :is(h2, h3, h4) {
+ /* Override styles from design-system */
+ margin-top: 0.5em;
+ max-width: 100%;
+}
+
+a > code {
+ position: relative;
+ color: var(--theme-text-accent);
+ background: transparent;
+ text-underline-offset: var(--padding-block);
+}
+
+a > code::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ display: block;
+ background: var(--theme-accent);
+ opacity: var(--theme-accent-opacity);
+ border-radius: var(--border-radius);
+}
+
+a:focus {
+ outline: 2px solid currentColor;
+ outline-offset: 0.25em;
+}
+
+strong {
+ font-weight: 600;
+ color: inherit;
+}
+
+/* Supporting Content */
+
+/* pre > code {
+ background-color: transparent;
+} */
+:not(pre) > code {
+ --border-radius: 3px;
+ --padding-block: 0.1rem;
+ --padding-inline: 0.33rem;
+
+ font-family: var(--font-mono);
+ font-size: 0.85em;
+ color: inherit;
+ background-color: var(--theme-code-inline-bg);
+ padding: var(--padding-block) var(--padding-inline);
+ margin: calc(var(--padding-block) * -1) -0.125em;
+ border-radius: var(--border-radius);
+ word-break: break-word;
+}
+
+pre.astro-code > code {
+ all: unset;
+}
+
+pre > code {
+ font-size: 1em;
+}
+
+table,
+pre {
+ position: relative;
+ --padding-block: 1rem;
+ --padding-inline: 2rem;
+ padding: var(--padding-block) var(--padding-inline);
+ padding-right: calc(var(--padding-inline) * 2);
+ margin-left: calc(var(--padding-inline) * -1);
+ margin-right: calc(var(--padding-inline) * -1);
+ font-family: var(--font-mono);
+
+ line-height: 1.5;
+ font-size: 0.85em;
+ overflow-y: hidden;
+ overflow-x: auto;
+}
+
+table {
+ width: 100%;
+ padding: var(--padding-block) 0;
+ margin: 0;
+ border-collapse: collapse;
+ color: var(--color-text-primary);
+ font-family: var(--font-family-text);
+ background: #fff;
+ border: 1px solid var(--color-border-primary);
+ line-height: 2;
+}
+
+table thead tr {
+ font-family: var(--font-family-text);
+ line-height: 2.2;
+ font-weight: var(--font-weight-medium);
+ color: var(--color-text-heading);
+}
+
+table tbody tr {
+ border-top: 1px solid var(--color-border-primary);
+}
+
+table code {
+ word-break: keep-all;
+}
+
+th {
+ background: var(--color-black);
+ color: var(--theme-color);
+ font-weight: bold;
+}
+td,
+th {
+ padding: 6px;
+ text-align: left;
+}
+
+pre {
+ background-color: var(--theme-code-bg);
+ color: var(--theme-code-text);
+}
+
+blockquote code {
+ background-color: var(--theme-bg);
+}
+
+@media (min-width: 37.75em) {
+ pre {
+ --padding-inline: 1.25rem;
+ border-radius: 8px;
+ margin-left: 0;
+ margin-right: 0;
+ }
+}
+
+blockquote {
+ margin: 2rem 0;
+ padding: 1.25em 1.5rem;
+ border-left: 3px solid var(--theme-text-light);
+ background-color: var(--theme-bg-offset);
+ border-radius: 0 0.25rem 0.25rem 0;
+ line-height: 1.7;
+}
+
+img {
+ max-width: 100%;
+}
+
+.flex {
+ display: flex;
+ align-items: center;
+}
+
+h2.heading {
+ font-size: 1rem;
+ font-weight: 700;
+ padding: 0.1rem 1rem;
+ text-transform: uppercase;
+ margin-bottom: 0.5rem;
+}
+
+.header-link {
+ font-size: 1rem;
+ padding: 0.1rem 0 0.1rem 1rem;
+ border-left: 4px solid var(--theme-divider);
+}
+
+.header-link.active,
+.header-link:hover,
+.header-link:focus {
+ border-left-color: var(--theme-accent);
+ color: var(--theme-accent);
+}
+.header-link:focus-within {
+ color: var(--theme-text-light);
+ border-left-color: hsla(var(--color-gray-40), 1);
+}
+.header-link svg {
+ opacity: 0.6;
+}
+.header-link:hover svg {
+ opacity: 0.8;
+}
+.header-link a {
+ display: inline-flex;
+ gap: 0.5em;
+ width: 100%;
+ padding: 0.15em 0 0.15em 0;
+}
+
+.header-link.depth-3 {
+ padding-left: 2rem;
+}
+.header-link.depth-4 {
+ padding-left: 3rem;
+}
+
+.header-link a {
+ font: inherit;
+ color: inherit;
+ text-decoration: none;
+}
+
+/* Screenreader Only Text */
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ white-space: nowrap;
+ border-width: 0;
+}
+
+.focus\:not-sr-only:focus,
+.focus\:not-sr-only:focus-visible {
+ position: static;
+ width: auto;
+ height: auto;
+ padding: 0;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+ white-space: normal;
+}
+
+:target {
+ scroll-margin: calc(var(--theme-sidebar-offset, 5rem) + 2rem) 0 2rem;
+}
diff --git a/src/styles/migrated.css b/src/styles/migrated.css
new file mode 100644
index 00000000000..7ee31b526c3
--- /dev/null
+++ b/src/styles/migrated.css
@@ -0,0 +1,61 @@
+/* Callout buttons for Remix and other redirects*/
+/* Applies to the first button, then applies different style to n+2 buttons */
+.remix-callout {
+ display: inline-flex;
+ flex-wrap: wrap;
+ margin-bottom: 0.5em;
+}
+
+.remix-callout > a:nth-of-type(1) {
+ padding: 8px;
+ padding-left: 20px;
+ padding-right: 20px;
+ border: 2px solid #375bd2;
+ margin: 0px 6px;
+ border-radius: 6px;
+ box-sizing: border-box;
+ text-decoration: none !important;
+ color: #ffffff;
+ background-color: #375bd2;
+ text-align: center;
+ transition: all 0.2s;
+}
+
+.remix-callout > a:nth-of-type(1):hover {
+ color: #ffffff;
+ background-color: #1a2b6b;
+ border: 2px solid #0c162c;
+}
+
+.remix-callout > a:nth-of-type(1):active {
+ color: #ffffff;
+ background-color: #0c162c;
+ border: 2px solid #0c162c;
+}
+
+.remix-callout > a:nth-of-type(n + 2) {
+ padding: 8px;
+ padding-left: 20px;
+ padding-right: 20px;
+ border: 2px solid #375bd2;
+ margin: 0px 6px;
+ border-radius: 6px;
+ box-sizing: border-box;
+ text-decoration: none !important;
+ color: #375bd2;
+ background-color: #ffffff;
+ text-align: center;
+ transition: all 0.2s;
+}
+
+.remix-callout > a:nth-of-type(n + 2):hover {
+ color: #1a2b6b;
+ background-color: #f5f7fd;
+ border: 2px solid #1a2b6b;
+}
+
+.remix-callout > a:nth-of-type(n + 2):active {
+ color: #0c162c;
+ background-color: #f5f7fd;
+ border: 2px solid #0c162c;
+}
diff --git a/src/styles/prism-darcula.css b/src/styles/prism-darcula.css
new file mode 100644
index 00000000000..51ecaa87e11
--- /dev/null
+++ b/src/styles/prism-darcula.css
@@ -0,0 +1,163 @@
+/**
+ * Darcula theme
+ *
+ * Adapted from a theme based on:
+ * IntelliJ Darcula Theme (https://github.com/bulenkov/Darcula)
+ *
+ * @author Alexandre Paradis
+ * @version 1.0
+ */
+
+code[class*="language-"],
+pre[class*="language-"] {
+ color: #a9b7c6;
+ font-family: Consolas, Monaco, "Andale Mono", monospace;
+ direction: ltr;
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ line-height: 1.5;
+
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+ color: inherit;
+ background: rgba(33, 66, 131, 0.85);
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+ color: inherit;
+ background: rgba(33, 66, 131, 0.85);
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+ padding: 1em;
+ margin: 0.5em 0;
+ overflow: auto;
+}
+
+:not(pre) > code[class*="language-"],
+pre[class*="language-"] {
+ background: #2b2b2b;
+}
+
+/* Inline code */
+:not(pre) > code[class*="language-"] {
+ padding: 0.1em;
+ border-radius: 0.3em;
+}
+
+.token.comment,
+.token.prolog,
+.token.cdata {
+ color: #808080;
+}
+
+.token.delimiter,
+.token.boolean,
+.token.keyword,
+.token.selector,
+.token.important,
+.token.atrule {
+ color: #cc7832;
+}
+
+.token.operator,
+.token.punctuation,
+.token.attr-name {
+ color: #a9b7c6;
+}
+
+.token.tag,
+.token.tag .punctuation,
+.token.doctype,
+.token.builtin {
+ color: #e8bf6a;
+}
+
+.token.entity,
+.token.number,
+.token.symbol {
+ color: #6897bb;
+}
+
+.token.property,
+.token.constant,
+.token.variable {
+ color: #9876aa;
+}
+
+.token.string,
+.token.char {
+ color: #6a8759;
+}
+
+.token.attr-value,
+.token.attr-value .punctuation {
+ color: #a5c261;
+}
+
+.token.attr-value .punctuation:first-child {
+ color: #a9b7c6;
+}
+
+.token.url {
+ color: #287bde;
+ text-decoration: underline;
+}
+
+.token.function {
+ color: #ffc66d;
+}
+
+.token.regex {
+ background: #364135;
+}
+
+.token.bold {
+ font-weight: bold;
+}
+
+.token.italic {
+ font-style: italic;
+}
+
+.token.inserted {
+ background: #294436;
+}
+
+.token.deleted {
+ background: #484a4a;
+}
+
+code.language-css .token.property,
+code.language-css .token.property + .token.punctuation {
+ color: #a9b7c6;
+}
+
+code.language-css .token.id {
+ color: #ffc66d;
+}
+
+code.language-css .token.selector > .token.class,
+code.language-css .token.selector > .token.attribute,
+code.language-css .token.selector > .token.pseudo-class,
+code.language-css .token.selector > .token.pseudo-element {
+ color: #ffc66d;
+}
diff --git a/src/styles/theme.css b/src/styles/theme.css
new file mode 100644
index 00000000000..bcdab87281b
--- /dev/null
+++ b/src/styles/theme.css
@@ -0,0 +1,87 @@
+/* Starter file. Has to be replaced with styles from design-system */
+:root {
+ --font-body: var(--font-family-text);
+ --font-mono: var(--font-family-code);
+
+ /*
+ * Variables with --color-base prefix define
+ * the hue, and saturation values to be used for
+ * hsla colors.
+ *
+ * ex:
+ *
+ * --color-base-{color}: {hue}, {saturation};
+ *
+ */
+
+ --color-base-white: 0, 0%;
+ --color-base-black: 240, 100%;
+ --color-base-gray: 215, 14%;
+ --color-base-blue: 212, 100%;
+ --color-base-blue-dark: 212, 72%;
+ --color-base-green: 158, 79%;
+ --color-base-orange: 22, 100%;
+ --color-base-purple: 269, 79%;
+ --color-base-red: 351, 100%;
+ --color-base-yellow: 41, 100%;
+
+ /*
+ * Color palettes are made using --color-base
+ * variables, along with a lightness value to
+ * define different variants.
+ *
+ */
+
+ --color-gray-5: var(--color-base-gray), 5%;
+ --color-gray-10: var(--color-base-gray), 10%;
+ --color-gray-20: var(--color-base-gray), 20%;
+ --color-gray-30: var(--color-base-gray), 30%;
+ --color-gray-40: var(--color-base-gray), 40%;
+ --color-gray-50: var(--color-base-gray), 50%;
+ --color-gray-60: var(--color-base-gray), 60%;
+ --color-gray-70: var(--color-base-gray), 70%;
+ --color-gray-80: var(--color-base-gray), 80%;
+ --color-gray-90: var(--color-base-gray), 90%;
+ --color-gray-95: var(--color-base-gray), 95%;
+
+ --color-blue: var(--color-base-blue), 61%;
+ --color-blue-dark: var(--color-base-blue-dark), 39%;
+ --color-green: var(--color-base-green), 42%;
+ --color-orange: var(--color-base-orange), 50%;
+ --color-purple: var(--color-base-purple), 54%;
+ --color-red: var(--color-base-red), 54%;
+ --color-yellow: var(--color-base-yellow), 59%;
+}
+
+:root {
+ --theme-accent: hsla(var(--color-blue), 1);
+ --theme-text-accent: hsla(var(--color-blue), 1);
+ --theme-accent-opacity: 0.15;
+ --theme-divider: hsla(var(--color-gray-95), 1);
+ --theme-text: hsla(var(--color-gray-10), 1);
+ --theme-text-light: hsla(var(--color-gray-40), 1);
+ /* @@@: not used anywhere */
+ --theme-text-lighter: hsla(var(--color-gray-80), 1);
+ --theme-bg: hsla(var(--color-base-white), 100%, 1);
+ --theme-bg-hover: hsla(var(--color-gray-95), 1);
+ --theme-bg-offset: hsla(var(--color-gray-90), 1);
+ --theme-bg-accent: hsla(var(--color-blue), var(--theme-accent-opacity));
+ --theme-code-inline-bg: hsla(var(--color-gray-95), 1);
+ --theme-code-inline-text: var(--theme-text);
+ --theme-code-bg: hsla(217, 19%, 27%, 1);
+ --theme-code-text: hsla(var(--color-gray-95), 1);
+ --theme-navbar-bg: hsla(var(--color-base-white), 100%, 1);
+ --theme-navbar-height: 88px;
+ --theme-selection-color: hsla(var(--color-blue), 1);
+ --theme-selection-bg: hsla(var(--color-blue), var(--theme-accent-opacity));
+}
+
+body {
+ background: var(--color-background-primary);
+ color: var(--color-text-primary);
+}
+
+::selection {
+ color: var(--theme-selection-color);
+ background-color: var(--theme-selection-bg);
+}
diff --git a/tsconfig.json b/tsconfig.json
index c320b78ae5f..29b8a241b94 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,73 +1,28 @@
{
+ "extends": "astro/tsconfigs/base",
"compilerOptions": {
- /* Visit https://aka.ms/tsconfig.json to read more about this file */
-
- /* Basic Options */
- // "incremental": true, /* Enable incremental compilation */
- "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
- "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
- // "lib": [], /* Specify library files to be included in the compilation. */
- // "allowJs": true, /* Allow javascript files to be compiled. */
- // "checkJs": true, /* Report errors in .js files. */
- // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
- // "declaration": true, /* Generates corresponding '.d.ts' file. */
- // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
- // "sourceMap": true, /* Generates corresponding '.map' file. */
- // "outFile": "./", /* Concatenate and emit output to single file. */
- // "outDir": "./", /* Redirect output structure to the directory. */
- // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
- // "composite": true, /* Enable project compilation */
- // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
- // "removeComments": true, /* Do not emit comments to output. */
- // "noEmit": true, /* Do not emit outputs. */
- // "importHelpers": true, /* Import emit helpers from 'tslib'. */
- // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
- // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
-
- /* Strict Type-Checking Options */
- "strict": true /* Enable all strict type-checking options. */,
- // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
- // "strictNullChecks": true, /* Enable strict null checks. */
- // "strictFunctionTypes": true, /* Enable strict checking of function types. */
- // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
- // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
- // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
- // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
-
- /* Additional Checks */
- // "noUnusedLocals": true, /* Report errors on unused locals. */
- // "noUnusedParameters": true, /* Report errors on unused parameters. */
- // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
- // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
- // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
- // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
-
- /* Module Resolution Options */
- // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
- // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
- // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
- // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
- // "typeRoots": [], /* List of folders to include type definitions from. */
- // "types": [], /* Type declaration files to be included in compilation. */
- // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
- "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
+ // Enable top-level await, and other modern ESM features.
+ "target": "ESNext",
+ "module": "CommonJS",
+ // Enable node-style module resolution, for things like npm package imports.
+ "moduleResolution": "node",
+ // Enable JSON imports.
"resolveJsonModule": true,
- // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
-
- /* Source Map Options */
- // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
- // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
-
- /* Experimental Options */
- // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
- // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
-
- /* Advanced Options */
- "skipLibCheck": true /* Skip type checking of declaration files. */,
- "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
- },
- "exclude": ["_site", "_includes"]
+ // Enable stricter transpilation for better output.
+ "isolatedModules": true,
+ "esModuleInterop": true,
+ // Add type definitions for our Vite runtime.
+ "types": ["vite/client"],
+ "baseUrl": ".",
+ "paths": {
+ "~/*": ["src/*"],
+ "@config": ["src/config/"],
+ "@config/*": ["src/config/*"],
+ "@features/*": ["src/features/*"],
+ "@variables": ["src/config/markdown-variables.ts"],
+ "@components/*": ["src/components/*"],
+ "@components": ["src/components/index.ts"],
+ "@abi": ["src/features/abi/index.ts"]
+ }
+ }
}
diff --git a/vercel.json b/vercel.json
new file mode 100644
index 00000000000..9da233752bf
--- /dev/null
+++ b/vercel.json
@@ -0,0 +1,412 @@
+{
+ "headers": [
+ {
+ "source": "/samples/(.*)",
+ "headers": [{ "key": "Access-Control-Allow-Origin", "value": "*" }]
+ }
+ ],
+ "cleanUrls": true,
+ "redirects": [
+ {
+ "source": "docs/any-api/api-reference/",
+ "destination": "any-api/api-reference",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/any-api/data-providers/dns-ownership/",
+ "destination": "any-api/data-providers/dns-ownership",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/any-api/data-providers/google-weather/",
+ "destination": "any-api/data-providers/google-weather",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/any-api/data-providers/introduction/",
+ "destination": "any-api/data-providers/introduction",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/any-api/find-oracle/",
+ "destination": "any-api/find-oracle",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/any-api/get-request/examples/api-array-response/",
+ "destination": "any-api/get-request/examples/array-response",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/any-api/get-request/examples/existing-job-request/",
+ "destination": "any-api/get-request/examples/existing-job-request",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/any-api/get-request/examples/large-responses/",
+ "destination": "any-api/get-request/examples/large-responses",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/any-api/get-request/examples/multi-variable-responses/",
+ "destination": "any-api/get-request/examples/multi-variable-responses",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/any-api/get-request/examples/single-word-response/",
+ "destination": "any-api/get-request/examples/single-word-response",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/any-api/get-request/introduction/",
+ "destination": "any-api/get-request/introduction",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/any-api/introduction/",
+ "destination": "any-api/introduction",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/any-api/testnet-oracles/",
+ "destination": "any-api/testnet-oracles",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/architecture-decentralized-model/",
+ "destination": "architecture-overview/architecture-decentralized-model",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/architecture-overview/",
+ "destination": "architecture-overview/architecture-overview",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/architecture-request-model/",
+ "destination": "architecture-overview/architecture-request-model",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/off-chain-reporting/",
+ "destination": "architecture-overview/off-chain-reporting",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/chainlink-automation/automation-economics",
+ "destination": "chainlink-automation/automation-economics",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/chainlink-automation/automation-release-notes",
+ "destination": "chainlink-automation/automation-release-notes",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/chainlink-automation/compatible-contracts",
+ "destination": "chainlink-automation/compatible-contracts",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/chainlink-automation/faqs",
+ "destination": "chainlink-automation/faqs",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/chainlink-automation/flexible-upkeeps",
+ "destination": "chainlink-automation/flexible-upkeeps",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/chainlink-automation/introduction",
+ "destination": "chainlink-automation/introduction",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/chainlink-automation/job-scheduler",
+ "destination": "chainlink-automation/job-scheduler",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/chainlink-automation/manage-upkeeps",
+ "destination": "chainlink-automation/manage-upkeeps",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/chainlink-automation/overview",
+ "destination": "chainlink-automation/overview",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/chainlink-automation/register-upkeep",
+ "destination": "chainlink-automation/register-upkeep",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/chainlink-automation/supported-networks",
+ "destination": "chainlink-automation/supported-networks",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/chainlink-automation/util-overview",
+ "destination": "chainlink-automation/util-overview",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/chainlink-automation/utility-contracts",
+ "destination": "chainlink-automation/utility-contracts",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/data-feeds/deprecating-feeds/",
+ "destination": "data-feeds/deprecating-feeds",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/data-feeds/ens/",
+ "destination": "data-feeds/ens",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/data-feeds/feed-registry/feed-registry-functions/",
+ "destination": "data-feeds/feed-registry/feed-registry-functions",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/data-feeds/feed-registry/",
+ "destination": "data-feeds/feed-registry/index",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/data-feeds/",
+ "destination": "data-feeds/index",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/data-feeds/l2-sequencer-feeds/",
+ "destination": "data-feeds/l2-sequencer-feeds",
+ "statusCode": 301
+ },
+ {
+ "source": "/docs/data-feeds/nft-floor-price/addresses/",
+ "destination": "data-feeds/nft-floor-price/addresses",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/data-feeds/nft-floor-price/",
+ "destination": "data-feeds/nft-floor-price/index",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/data-feeds/price-feeds/addresses/",
+ "destination": "data-feeds/price-feeds/addresses",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/data-feeds/price-feeds/api-reference/",
+ "destination": "data-feeds/price-feeds/api-reference",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/data-feeds/price-feeds/historical-data/",
+ "destination": "data-feeds/price-feeds/historical-data",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/data-feeds/price-feeds/",
+ "destination": "data-feeds/price-feeds/index",
+ "statusCode": 301
+ },
+ {
+ "source": "/docs/data-feeds/proof-of-reserve/addresses/",
+ "destination": "data-feeds/proof-of-reserve/addresses",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/data-feeds/proof-of-reserve/",
+ "destination": "data-feeds/proof-of-reserve/index",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/data-feeds/selecting-data-feeds/",
+ "destination": "data-feeds/selecting-data-feeds",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/acquire-link/",
+ "destination": "resources/acquire-link",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/contributing-to-chainlink/",
+ "destination": "resources/contributing-to-chainlink",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/create-a-chainlinked-project/",
+ "destination": "resources/create-a-chainlinked-project",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/developer-communications/",
+ "destination": "resources/developer-communications",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/ethereum-proof-of-stake-merge/",
+ "destination": "resources/ethereum-proof-of-stake-merge",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/example-projects/",
+ "destination": "resources/example-projects",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/fund-your-contract/",
+ "destination": "resources/fund-your-contract",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/getting-help/",
+ "destination": "resources/getting-help",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/glossary/",
+ "destination": "resources/glossary",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/hackathon-resources/",
+ "destination": "resources/hackathon-resources",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/hackathon-rules-waiver-release-and-code-of-conduct/",
+ "destination": "resources/hackathon-rules-waiver-and-release",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/link-token-contracts/",
+ "destination": "resources/link-token-contracts",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/solana/data-feeds-solana/",
+ "destination": "solana/data-feeds/data-feeds-solana",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/solana/using-data-feeds-off-chain/",
+ "destination": "solana/data-feeds/using-data-feeds-off-chain",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/solana/using-data-feeds-solana/",
+ "destination": "solana/data-feeds/using-data-feeds-solana",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/solana/",
+ "destination": "solana/overview",
+ "statusCode": 301
+ },
+ { "source": "/solana/", "destination": "solana", "statusCode": 301 },
+ {
+ "source": "docs/vrf/v1/api-reference/",
+ "destination": "vrf/v1/api-reference",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v1/best-practices/",
+ "destination": "vrf/v1/best-practices",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v1/examples/get-a-random-number/",
+ "destination": "vrf/v1/examples/get-a-random-number",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v1/introduction/",
+ "destination": "vrf/v1/introduction",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v1/security/",
+ "destination": "vrf/v1/security",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v1/supported-networks/",
+ "destination": "vrf/v1/supported-networks",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v2/best-practices/",
+ "destination": "vrf/v2/best-practices",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v2/direct-funding/",
+ "destination": "vrf/v2/direct-funding/design",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v2/direct-funding/examples/get-a-random-number/",
+ "destination": "vrf/v2/direct-funding/examples/get-a-random-number",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v2/direct-funding/migration-from-v1/",
+ "destination": "vrf/v2/direct-funding/migration-from-v1",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v2/direct-funding/supported-networks/",
+ "destination": "vrf/v2/direct-funding/supported-networks",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v2/introduction/",
+ "destination": "vrf/v2/introduction",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v2/security/",
+ "destination": "vrf/v2/security",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v2/subscription/",
+ "destination": "vrf/v2/subscription/design",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v2/subscription/examples/get-a-random-number/",
+ "destination": "vrf/v2/subscription/examples/get-a-random-number",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v2/subscription/examples/programmatic-subscription/",
+ "destination": "vrf/v2/subscription/examples/programmatic-subscription",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v2/subscription/migration-from-v1/",
+ "destination": "vrf/v2/subscription/migration-from-v1",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v2/subscription/supported-networks/",
+ "destination": "vrf/v2/subscription/supported-networks",
+ "statusCode": 301
+ },
+ {
+ "source": "docs/vrf/v2/subscription/ui/",
+ "destination": "vrf/v2/subscription/ui",
+ "statusCode": 301
+ }
+ ]
+}