# Reserved Parameters
Reserved parameters are part of an OIS object as part of the endpoints
field
(Airnode endpoints) and warrant a more in-depth explanation. They are part of an
Airnode's defined endpoints in an OIS object but do not map to operation
parameters (API parameters). They are used by Airnode for special purposes.
A requester can pass request parameters either by referencing a template that contains them, or as an argument of the request-making methods of AirnodeRrpV0.sol. In either case, these parameters are encoded using the AirnodeRrpV0 ABI. There are two types of parameters which are part of the OIS object:
- Endpoint parameters - Airnode endpoint parameters are mapped to API operation parameters.
- Reserved parameters - Reserved parameters
perform a specific operation related to the request or on the response before
fulfilling the request. Reserved parameter names start with
_
. Depending on the configuration, they may be overridden by a parameter supplied by a requester.
# _type
Signifies what Solidity type the API response will be encoded to before fulfillment.
Support is provided for most common solidity types (opens new window), but the following are not supported.
- Custom bits integer types - e.g.
uint32
oruint8
- Fixed point decimal numbers - e.g.
fixed128x18
orufixed128x18
- Custom fixed size bytes - e.g.
bytes4
- Tuples - e.g.
(int256, string)
On top of supported solidity types, there is support for a few "artificial" types created for special purposes that would otherwise be hard or impossible to represent.
You can also encode multiple values for one single API call - but this impacts all of the reserved parameters and is explained in the Encoding Multiple Values section below.
# Conversion and encoding behavior
Before the API response value is encoded for on chain use, it is parsed and converted. The conversion behaviors for any given type is explained in depth in the adapter package docs.
The converted value is then encoded internally by ethers ABI Coder (opens new window) using the following
ethers.utils.defaultAbiCoder.encode([solidityType], [value]);
# Supported Primitive Values
int256
uint256
bool
bytes32
address
bytes
string
# string32 (encoded to bytes32
on chain)
The string32
is an artificial type that is not supported by solidity. It is
instead encoded to bytes32
and provides a cheaper alternative to the regular
string
type for values with less than 32 characters.
Limitations
While using string32
is more efficient, decoding the original string from
bytes32
on chain is both difficult and expensive.
Also bear in mind that this type is able to encode only strings shorter than 32 characters. If the value is longer, it will be trimmed and only first 31 characters will be encoded.
# timestamp (encoded to uint256
on chain)
The timestamp
is an artificial type that is not supported by solidity. It is
instead encoded to uint256
and specifies the UNIX timestamp value at the time
when the transaction was encoded. You can use this value on chain to check the
"freshness" of the Airnode response. This might be useful in certain scenarios,
because Airnode cannot guarantee when a particular transaction will be mined on
chain.
When using the timestamp
type, the corresponding _path
and _times
variables must be empty strings or not provided.
# Arrays
Apart from the primitives defined above as well as all "artificial" types we created, you are free to use arrays with any of the above. Multidimensional arrays are supported as well. Solidity allows you to define fixed size arrays, which are more gas efficient to encode and you can use those as well.
For example
int256[]
- regular integer arrayuint256[8]
- unsigned integer array with 8 elementsint256[][]
- 2 dimensional integer arraystring32[]
- is an array ofstring32
values, which will be encoded tobytes32[]
on chainstring[2][][3]
- 3 dimensional string array, where first dimension contains 3 elements, second unboundedly many and last dimension only 2. Notice, that this definition is read backwards (opens new window) compared to C-style languages
# _path
Assuming that the API response will be a JSON object, defines the field to be used to fulfill the request using dot notation. For example, if the API returns
{
"field1": {
"fieldA": [
"valueA1",
"valueA2"
],
"fieldB: "valueB"
},
"field2": {
"fieldZ": "valueZ"
}
}
2
3
4
5
6
7
8
9
10
11
12
and _path
is field1.fieldA.1
, the response will be valueA2
.
If the response is a literal value (i.e., not a JSON object) and _path
is not
provided or is an empty string (needed for
encoding multiple values),
Airnode will use the API response itself to fulfill the request.
Beware the separator
Make sure the keys in the path of the API response do not contain .
, because
it will be incorrectly considered as a separator.
{
"strange.key": "123"
}
2
3
The _path
defined as "strange.key"
will not work. As workaround you can
escape the separator.
# Escaping Separators
In rare cases, when the _path
to the API response would contain ,
or .
(comma or a dot) things get a bit complicated. Those symbols have a very
specific meaning when parsing the reserved parameters and they need to be
escaped if they are to be considered as literals. If the API provider response
looks like the following:
{
"very,strange.key": "123"
}
2
3
Then escape the symbols, in this case _path="very\\,strange\\.key"
.
# _times
If _type
is int256
or uint256
and a valid _times
parameter is provided
Airnode multiplies the value returned by the API with the _times
parameter
before fulfilling the request. For example, if the API returns:
{
"data": "1.238",
"apiVersion": "1.0.4"
}
2
3
4
and the reserved parameters are
_type: int256
_path: data
_times: "100"
2
3
the request will be fulfilled with the value 123
. Note that the number gets
multiplied by 100
, and then gets floored. This is because the result of the
multiplication is cast to
int256
afterwards.
Make sure to pass the _times
parameter as string. Airnode will convert this
string to number internally. You can also pass and empty string ""
to _times
parameter - this has the same effect as if the _times
parameter was not
provided. However, this is important when
encoding multiple values.
The _times
parameter also works in conjunction with arrays and
multidimensional arrays. All elements of the API response array will be
multiplied before they are encoded.
# _gasPrice
The _gasPrice
reserved parameter enables a requester to override
Airnode gas price strategies with
a specified gas price when Airnode
fulfills the request. The
recommended implementation is to have the _gasPrice
reserved parameter without
a default
or fixed
value as shown in the abbreviated snippet below:
{
"reservedParameters": [
{
"name": "_gasPrice"
}
]
}
2
3
4
5
6
7
This allows requesters to specify the gas price via a parameter in their
request. The value, in wei
, should be
encoded as a
string32
type by the requester, for example:
import { encode } from '@api3/airnode-abi';
encode([
{
name: '_gasPrice',
type: 'string32',
// 10 gwei in wei
value: '1000000000000000000',
},
]);
2
3
4
5
6
7
8
9
Note that if a requester specifies a _gasPrice
as a parameter in a request but
the Airnode's configuration does not include the _gasPrice
reserved parameter,
the requester's gas price will be ignored.
# _minConfirmations
The _minConfirmations
reserved parameter enables a requester to override the
default minimum number of block confirmations set by the Airnode for that chain
in
config.json.
The recommended implementation is to have the _minConfirmations
reserved
parameter without a default
or fixed
value as shown in the abbreviated
snippet below:
{
"reservedParameters": [
{
"name": "_minConfirmations"
}
]
}
2
3
4
5
6
7
This allows requesters to specify the minimum number of block confirmations via
a parameter in their request. The value should be
encoded as a
string32
type by the requester, for example:
import { encode } from '@api3/airnode-abi';
encode([{ name: '_minConfirmations', type: 'string32', value: '1' }]);
2
In order to respond to requests in the same nonce order as they are received
when requests specify different _minConfirmations
values, the maximum
_minConfirmations
value of all requests in the queue for a given sponsor is
applied to all requests.
Note that if a requester specifies a _minConfirmations
as a parameter in a
request but the Airnode's configuration does not include the _minConfirmations
reserved parameter, the requester's minimum confirmations value will be ignored.
# Encoding Multiple Values
Solidity has support for decoding and "destructuring" multiple values. For example
function decodeMultipleParameters(bytes calldata data)
public
pure
returns (string memory str, uint256 num, address addr)
{
(str, num, addr) = abi.decode(data, (string, uint256, address));
}
2
3
4
5
6
7
The example above demonstrates the decoding on chain of three values of types
string
, uint256
and address
respectively. You can instruct Airnode to
encode these values using the _type
, _path
, and _times
reserved parameters
by separating the values using ,
(comma). For example using the following
combination of reserved parameters
{
_type: 'string,uint256,address',
_path: 'pathToString,pathToFloat,pathToAddress',
_times: ',10000,'
}
2
3
4
5
Airnode will split the reserved parameters by ,
into "split values" and ensure
they all contain the same number of them. It will extract and convert each of
the "split values". Notice, that an ""
(empty string) is used to specify that
a certain reserved parameter should not be used for a certain "split value".
For example, let's say the API response looks like this
{
"pathToString": "some string",
"pathToFloat": "1234.567",
"pathToAddress": "0xe021...08a74"
}
2
3
4
5
Airnode will extract and convert each of the "split values" separately
- Combination of
_type="string"
,_path="pathToString"
and_times=""
results in"some string"
- Combination of
_type="uint256"
,_path="pathToFloat"
and_times="10000"
results in12345670
- Combination of
_type="address"
,_path="pathToAddress"
and_times=""
results in"0xe021...8a74"
All of these values are then together encoded to single bytes value that can be sent on chain. You can use testing gateway to inspect the raw API response, casting results and the final encoded value.
Multiple Reserved Parameters Tutorial
The weather-multi-value
monorepo example demonstrates encoding of multiple
values of different types,
see here.