Skip to content
This repository has been archived by the owner on Aug 26, 2024. It is now read-only.

Commit

Permalink
Describe new RequesterAuthorizerWithErc721 authorizers (#1221)
Browse files Browse the repository at this point in the history
Co-authored-by: Warren Anderson <[email protected]>
  • Loading branch information
dcroote and wkande authored Mar 21, 2023
1 parent 755d96b commit 5e3c09b
Show file tree
Hide file tree
Showing 14 changed files with 265 additions and 77 deletions.
157 changes: 126 additions & 31 deletions docs/airnode/v0.11/concepts/authorizers.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,50 +190,55 @@ making a static call to check if they are authorized. This scheme both allows
the Airnode to set transparent and flexible policies, and this to be done with
no gas overhead.

Currently there are two `authorizers` scheme types,
`requesterEndpointAuthorizers` and `crossChainRequesterAuthorizers`. These are
set in `chains[n].authorizers` of `config.json` as described below.
Currently there are four `authorizers` scheme types,
`requesterEndpointAuthorizers`, `crossChainRequesterAuthorizers`,
`requesterAuthorizersWithErc721`, and
`crossChainRequesterAuthorizersWithErc721`. These are set in
`chains[n].authorizers` of `config.json` as described below.

### Same-chain: requesterEndpointAuthorizers

The `requesterEndpointAuthorizers` authorizer scheme type specifies an array of
on-chain contract addresses to query when attempting to authorize a request. In
contrast to the other authorizer scheme type, `crossChainRequesterAuthorizers`,
the contract addresses are expected to reside on the chain specified by the `id`
field of the parent `chains` object i.e. the authorizer contract addresses are
on the same chain. There are two configurations possible for
`requesterEndpointAuthorizers`: "allow all" and "filter all".

#### Allow All
### Special case: all authorizers values are empty arrays

When `chains[n].authorizers.requesterEndpointAuthorizers` is an empty array, all
requests are authorized. In the example below, all chain _2_ requests are
authorized.
When all `chains[n].authorizers` values are empty arrays, all requests are
authorized. In the example below, all chain _2_ requests are authorized.

```json
"chains": [
{
"id": "2",
"authorizers": { "requesterEndpointAuthorizers": [] }
"authorizers": {
"requesterEndpointAuthorizers": [],
"crossChainRequesterAuthorizers": [],
"requesterAuthorizersWithErc721": [],
"crossChainRequesterAuthorizersWithErc721": []
}
...
},
...
]
```

#### Filter All
### Same-chain: requesterEndpointAuthorizers

The `requesterEndpointAuthorizers` authorizer scheme type specifies an array of
on-chain contract addresses to query when attempting to authorize a request. In
contrast to the analogous `crossChainRequesterAuthorizers` authorizer scheme
type, the contract addresses are expected to reside on the chain specified by
the `id` field of the parent `chains` object i.e. the authorizer contract
addresses are on the same chain.

If the Airnode wants to authorize selectively, it should use one or more
authorizer contracts that implement filtering logic. In the example below, a
request would be authorized on chain _2_ if _either_ of the two
`requesterEndpointAuthorizers` contracts authorize the request.
In the example below, a request would be authorized on chain _2_ if _either_ of
the two `requesterEndpointAuthorizers` contracts authorize the request.

```json
"chains": [
{
"id": "2",
"authorizers": { "requesterEndpointAuthorizers": ["0xcd...cd8d", "0xff...d19c"] }
...
"authorizers": {
"requesterEndpointAuthorizers": ["0xcd...cd8d", "0xff...d19c"],
"crossChainRequesterAuthorizers": [],
"requesterAuthorizersWithErc721": [],
"crossChainRequesterAuthorizersWithErc721": []
}
}
]
```
Expand All @@ -255,18 +260,15 @@ Note that `crossChainRequesterAuthorizers` is an array that can contain multiple
cross-chain authorizer objects, which allows for authorizers across multiple
chains and/or redundancy in providers for each chain.

The below example combines both `requesterEndpointAuthorizers` and
`crossChainRequesterAuthorizers` authorizer scheme types. Requests will be
authorized if the same-chain (`"id": "2"`) `requesterEndpointAuthorizers`
contract `0xcd...cd8d` authorizes the request or if the cross-chain
In the below example, requests will be authorized if the cross-chain
(`"chainId": "1"`) authorizer contract `0xCE5e...1abc` authorizes the request.

```json
"chains": [
{
"id": "2",
"authorizers": {
"requesterEndpointAuthorizers": ["0xcd...cd8d"],
"requesterEndpointAuthorizers": [],
"crossChainRequesterAuthorizers": [
{
"requesterEndpointAuthorizers": ["0xCE5e...1abc"],
Expand All @@ -279,9 +281,102 @@ contract `0xcd...cd8d` authorizes the request or if the cross-chain
"url": "https://mainnet.infura.io/..."
}
}
],
"requesterAuthorizersWithErc721": [],
"crossChainRequesterAuthorizersWithErc721": []
}
}
]
```

### Same-chain: requesterAuthorizersWithErc721

The `requesterAuthorizersWithErc721` authorizer scheme type allows requests on
one chain to be authorized by NFT deposits on the same chain. More specifically,
it defines an array of objects that allow for ERC721 authorization on the same
chain as the chain specified by the `id` field of the parent `chains` object.
The object consists of two fields: `erc721s`, an array of ERC721 contract
addresses, and `RequesterAuthorizerWithErc721`, the address of the
`RequesterAuthorizerWithErc721` contract. In the example below, a request would
be authorized on chain _2_ if the requester has deposited a token with the
contract address `0x00bDB2315678afecb367f032d93F642f64180a00` to the
`RequesterAuthorizerWithErc721` contract at address
`0x999DB2315678afecb367f032d93F642f64180aa9`. If multiple ERC721 contracts are
specified, the requester will be authorized if a token corresponding to _any_ of
the specified ERC721 contracts has been deposited. For deployed
`RequesterAuthorizerWithErc721` contract addresses, see the
[Airnode Contract Addresses](../reference/airnode-addresses.md#requesterauthorizerwitherc721)
page.

```json
"chains": [
{
"id": "2",
"authorizers": {
"requesterEndpointAuthorizers": [],
"crossChainRequesterAuthorizers": [],
"requesterAuthorizersWithErc721": [
{
"erc721s": ["0x00bDB2315678afecb367f032d93F642f64180a00"],
"RequesterAuthorizerWithErc721": "0x999DB2315678afecb367f032d93F642f64180aa9"
}
],
"crossChainRequesterAuthorizersWithErc721": []
}
}
]
```

### Cross-chain: crossChainRequesterAuthorizersWithErc721

The `crossChainRequesterAuthorizersWithErc721` authorizer scheme type allows for
requests on one chain to be authorized by NFT deposits on a different chain.
More specifically, it defines an array of objects that allow for ERC721
cross-chain request authorization. Like `crossChainRequesterAuthorizers`, some
of the fields within each object resemble other `config.json` objects:
`chainType` and `contracts` are configured equivalently to their like named
parent `chains[n]` objects described in the
[config.json reference](../reference/deployment-files/config-json.md#chains),
`chainId` specifies the cross-chain (network) id, and `chainProvider` is an
object containing the chain provider url for the _chain specified by `chainId`_.
The `erc721s` field value is an array of ERC721 contract addresses and within
`contracts`, `RequesterAuthorizerWithErc721` specifies an address of the
`RequesterAuthorizerWithErc721` contract _on the chain specified by `chainId`_.
If multiple ERC721 contracts are specified in `erc721s`, the requester will be
authorized if a token corresponding to _any_ of the specified ERC721 contracts
has been deposited. For deployed `RequesterAuthorizerWithErc721` contract
addresses, see the
[Airnode Contract Addresses](../reference/airnode-addresses.md#requesterauthorizerwitherc721)
page.

In the below example, the request on chain _2_ will be authorized if the the
`RequesterAuthorizerWithErc721` contract at address
`0x6bbbb2315678afecb367f032d93F642f64180aa4` on chain _4_ authorizes the request
based on the requester having deposited a token with the contract address
`0x3FbDB2315678afecb367f032d93F642f64180aa6`.

```json
"chains": [
{
"id": "2",
"authorizers": {
"requesterEndpointAuthorizers": [],
"crossChainRequesterAuthorizers": [],
"requesterAuthorizersWithErc721": [],
"crossChainRequesterAuthorizersWithErc721": [
{
"erc721s": ["0x3FbDB2315678afecb367f032d93F642f64180aa6"],
"chainType": "evm",
"chainId": "4",
"contracts": {
"RequesterAuthorizerWithErc721": "0x6bbbb2315678afecb367f032d93F642f64180aa4"
},
"chainProvider": {
"url": "http://127.0.0.2"
}
}
]
}
...
}
]
```
Expand Down
16 changes: 12 additions & 4 deletions docs/airnode/v0.11/concepts/chain-providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ provider "infuraSepolia" in the `providers` array.
"requesterEndpointAuthorizers": [
"0xf18c105D0375E80980e4EED829a4A68A539E6178"
],
"crossChainRequesterAuthorizers": []
"crossChainRequesterAuthorizers": [],
"requesterAuthorizersWithErc721": [],
"crossChainRequesterAuthorizersWithErc721": []
},
"authorizations": {
"requesterEndpointAuthorizations": {}
Expand Down Expand Up @@ -103,7 +105,9 @@ Multiple providers can be used per chain. Simply add another object to
"requesterEndpointAuthorizers": [
"0xf18c105D0375E80980e4EED829a4A68A539E6178"
],
"crossChainRequesterAuthorizers": []
"crossChainRequesterAuthorizers": [],
"requesterAuthorizersWithErc721": [],
"crossChainRequesterAuthorizersWithErc721": []
},
"authorizations": {
"requesterEndpointAuthorizations": {}
Expand Down Expand Up @@ -169,7 +173,9 @@ each has a unique `id` and `type` and a list of `providers` for each.
"requesterEndpointAuthorizers": [
"0xf18c105D0375E80980e4EED829a4A68A539E6178"
],
"crossChainRequesterAuthorizers": []
"crossChainRequesterAuthorizers": [],
"requesterAuthorizersWithErc721": [],
"crossChainRequesterAuthorizersWithErc721": []
},
"authorizations": {
"requesterEndpointAuthorizations": {}
Expand Down Expand Up @@ -225,7 +231,9 @@ each has a unique `id` and `type` and a list of `providers` for each.
"requesterEndpointAuthorizers": [
"0xf18c105D0375E80980e4EED829a4A68A539E6178"
],
"crossChainRequesterAuthorizers": []
"crossChainRequesterAuthorizers": [],
"requesterAuthorizersWithErc721": [],
"crossChainRequesterAuthorizersWithErc721": []
},
"authorizations": {
"requesterEndpointAuthorizations": {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,18 @@ endpoints. However, rather than serve them publicly, you may want to:
- Only serve sponsors who have made a subscription payment.
- Only serve sponsors who have gone through KYC.

You can use different authorizer contracts for your Airnode deployment per chain
by declaring them in the `config.json` file under `chains[n].authorizers`. Add
one or more authorizer contract addresses to the
`chains[n].authorizers.requesterEndpointAuthorizers` array or add one or more
cross-chain authorizer objects to the
`chains[n].authorizers.crossChainRequesterAuthorizers` array as shown below. If
the `requesterEndpointAuthorizers` array is left empty then all requests will be
accepted by the Airnode but still could be filtered by using
The `chains[n].authorizers` object within `config.json` enables requests to be
authorized in a variety of ways and even across chains. Currently, the
authorizers include `requesterEndpointAuthorizers`,
`crossChainRequesterAuthorizers`, `requesterAuthorizersWithErc721`, and
`crossChainRequesterAuthorizersWithErc721`.

Note that when all `chains[n].authorizers` values are empty arrays, all requests
are authorized, but still can be filtered by using
[Relayed Meta Data Security Schemes](./api-security.md#relayed-meta-data-security-schemes).

Below are examples of how to use the authorizers.

```json
{
...
Expand All @@ -64,37 +66,31 @@ accepted by the Airnode but still could be filtered by using
"id": "1", on-chain authorizer contract addresses
... such as RequesterAuthorizerWithAirnode
"authorizers": { ⬇︎
"requesterEndpointAuthorizers": [ // Requests must satisfy at least
"requesterEndpointAuthorizers": [ // Requests must be authorized by
"0xeabb...C123", // one of the authorizer contracts
"0xCE5e...1abc"
],
"crossChainRequesterAuthorizers": []
"crossChainRequesterAuthorizers": [],
"requesterAuthorizersWithErc721": [],
"crossChainRequesterAuthorizersWithErc721": []
}
},
{
"id": "2",
...
"authorizers": {
"requesterEndpointAuthorizers": [], // All requests will be processed
"crossChainRequesterAuthorizers": []
"authorizers": { // All requests are authorized
"requesterEndpointAuthorizers": [],
"crossChainRequesterAuthorizers": [],
"requesterAuthorizersWithErc721": [],
"crossChainRequesterAuthorizersWithErc721": []
},
},
{
"id": "3",
...
"authorizers": {
"requesterEndpointAuthorizers": [ // Requests must satisfy a
"0xeabb...C123" // single authorizer contract
],
"crossChainRequesterAuthorizers": []
}
},
{
"id": "4",
...
"authorizers": {
"requesterEndpointAuthorizers": [ // Requests must satisfy a
"0xeabb...C123" // single authorizer contract
"requesterEndpointAuthorizers": [ // Requests must be authorized by
"0xeabb...C123" // a single authorizer contract
], // OR an authorizer contract deployed
// on a different chain (Ethereum mainnet)
"crossChainRequesterAuthorizers": [
Expand All @@ -109,6 +105,45 @@ accepted by the Airnode but still could be filtered by using
"url": "https://mainnet.infura.io/..."
}
}
],
"requesterAuthorizersWithErc721": [],
"crossChainRequesterAuthorizersWithErc721": []
}
},
{
"id": "4",
...
"authorizers": {
"requesterEndpointAuthorizers": [],
"crossChainRequesterAuthorizers": [],
"requesterAuthorizersWithErc721": [
{ // Requests are authorized by an NFT deposit on the same chain as the request
"erc721s": ["0x00bDB2315678afecb367f032d93F642f64180a00"],
"RequesterAuthorizerWithErc721": "0x999DB2315678afecb367f032d93F642f64180aa9"
}
],
"crossChainRequesterAuthorizersWithErc721": []
}
},
{
"id": "5",
...
"authorizers": {
"requesterEndpointAuthorizers": [],
"crossChainRequesterAuthorizers": [],
"requesterAuthorizersWithErc721": [],
"crossChainRequesterAuthorizersWithErc721": [
{ // Requests are authorized by an NFT deposit on Ethereum mainnet
"erc721s": ["0x3FbDB2315678afecb367f032d93F642f64180aa6"],
"chainType": "evm",
"chainId": "1",
"contracts": {
"RequesterAuthorizerWithErc721": "0x6bbbb2315678afecb367f032d93F642f64180aa4"
},
"chainProvider": {
"url": "http://127.0.0.2"
}
}
]
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ Below is a simple chain array with a single chain provider.
"requesterEndpointAuthorizers": [
"0xf18c105D0375E80980e4EED829a4A68A539E6178"
],
"crossChainRequesterAuthorizers": []
"crossChainRequesterAuthorizers": [],
"requesterAuthorizersWithErc721": [],
"crossChainRequesterAuthorizersWithErc721": []
},
"authorizations": {
"requesterEndpointAuthorizations": {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,10 @@ requester addresses that can access them.
"id": "1",
...
"authorizers": {
"requesterEndpointAuthorizers": [
"0xeabb...C123",
"0xCE5e...1abc"
],
"crossChainRequesterAuthorizers": []
"requesterEndpointAuthorizers": [],
"crossChainRequesterAuthorizers": [],
"requesterAuthorizersWithErc721": [],
"crossChainRequesterAuthorizersWithErc721": []
The scheme type requesterEndpointAuthorizations
}, grants access to endpointId/address pairs
"authorizations": { ⬇︎
Expand Down
Loading

1 comment on commit 5e3c09b

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.