Relay API Reference

The Relay API exposes the following endpoints:

  • txs: send transactions to the Ethereum blockchain and query their status

  • sign: sign arbitrary data with relayer’s private key

  • relayer: retrieve information from the relayer

  • jsonrpc: make json-rpc calls to the Ethereum network

Authentication

A JWT Token is required to make requests to the Relay API. For security reasons authentication uses SRP protocol and it is not possible to retrieve a JWT Token via a single HTTP request, which is why it is advised to use the Amazon Cognito User Pool SDK to retrieve a JWT token.

Note that if you are using the defender-relay-client all authentication is automatically handled for you by supplying the API key and secret.

Python Authentication

The official AWS SDK for python doesn’t support SRP authentication, but it is possible to retrieve a JWT token using the warrant library.

Here is an example:

import boto3
from warrant.aws_srp import AWSSRP

client = boto3.client('cognito-idp', region_name='us-west-2')
aws = AWSSRP(username='API_KEY', password='API_SECRET', pool_id='us-west-2_iLmIggsiy', client_id='1bpd19lcr33qvg5cr3oi79rdap', client=client)
tokens = aws.authenticate_user()
print('Access Token', tokens['AuthenticationResult']['AccessToken'])

Refreshing JWT Token

A JWT token will expire in 60 minutes. If your code requires sessions longer than 60 minutes consider recreating a JWT token or using a refresh token.

Making Authenticated Requests

Once you get a JWT Token you can make requests to the Defender API. A request requires an API key, a JWT Token, optionally a payload, and an API URL. Set $KEY, $TOKEN to the values of API key and JWT Token acquired before. $END_POINT can be either txs or sign.

API_URL='http://api.defender.openzeppelin.com/'

curl \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H "X-Api-Key: $KEY" \
  -H "Authorization: Bearer $TOKEN" \
    "$API_URL/$END_POINT"

Transactions Endpoint

The /txs endpoint is used for both sending transactions and for retrieving transaction information given a transaction identifier.

Send Transaction

To send a transaction to the Ethereum blockchain submit a POST request with the desired payload. The payload format is as follows:

export type Address = string;
export type BigUInt = string | number;
export type Hex = string;
export type Speed = 'safeLow' | 'average' | 'fast' | 'fastest';

export interface SendTransactionRequest {
  to: Address;
  value?: BigUInt; // optional
  data?: Hex; // optional
  speed?: Speed; // optional
  gasPrice?: BigUInt; // optional
  validUntil?: string; // optional
  gasLimit: BigUInt;
}

An example of the request:

DATA='{ "to": "0x179810822f56b0e79469189741a3fa5f2f9a7631", "value": "1", "speed": "fast", "gasLimit": "21000" }'

curl \
  -X POST \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H "X-Api-Key: $KEY" \
  -H "Authorization: Bearer $TOKEN" \
  -d "$DATA" \
    "$API_URL/txs" # http://api.defender.openzeppelin.com/txs

You would receive a response in the following format:

export type Address = string;
export type BigUInt = string | number;
export type Hex = string;
export type Speed = 'safeLow' | 'average' | 'fast' | 'fastest';
export type Status = 'pending' | 'sent' | 'submitted' | 'inmempool' | 'mined' | 'confirmed';

export interface TransactionResponse {
  transactionId: string; // Defender tx id
  hash: string; // Ethereum hash
  to: Address;
  from: Address;
  value: string;
  data: string;
  speed: Speed;
  gasPrice: number;
  gasLimit: number;
  nonce: number;
  status: Status;
  chainId: number;
  validUntil: string;
}

Query Transaction

To retrieve a transaction status and data make a GET request to the txs endpoint with the Defender transactionId, not with the transaction hash.

An example of the request:

curl \
  -X GET \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H "X-Api-Key: $KEY" \
  -H "Authorization: Bearer $TOKEN" \
    "$API_URL/txs/$ID" # http://api.defender.openzeppelin.com/txs/affba150-e563-441e-ae49-04bd6050979a

An example of the response:

{
   "chainId":4,
   "hash":"0xcef95469a9f02757f0968ec8c11449ae5e7486073075381dcd62bacec9e5d627",
   "transactionId":"affba150-e563-441e-ae49-04bd6050979a",
   "value":"0x1",
   "gasPrice":1000000000,
   "gasLimit":21000,
   "to":"0x179810822f56b0e79469189741a3fa5f2f9a7631",
   "from":"0xbce0b5b71668e42d908e387b68dba91789c932b8",
   "data":"0x",
   "nonce":160,
   "status":"mined",
   "speed":"fast"
}

Sign Endpoint

To sign arbitrary data with your Relay private key make a POST request to /sign with a payload containing the hex string to sign. The payload format is:

export interface SignMessagePayload {
  message: Hex;
}

An example of the request:

DATA='{ "message": "0x0123456789abcdef" }'

curl \
  -X POST \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H "X-Api-Key: $KEY" \
  -H "Authorization: Bearer $TOKEN" \
  -d "$DATA" \
    "$API_URL/sign" # http://api.defender.openzeppelin.com/sign

You would receive a response in the following format:

export interface SignedMessagePayload {
  sig: Hex;
  r: Hex;
  s: Hex;
  v: number;
}

An example of the response:

{
   "r":"0x819b2645a0b73494724dac355e6ecfc983d94597b533d34fe3ecd0277046a1eb",
   "s":"0x3b73c695b47dd275d17246d86bbfe35f112a7bdb5bf4a5a1a8e22fe37dfd005a",
   "v":44,
   "sig":"0x819b2645a0b73494724dac355e6ecfc983d94597b533d34fe3ecd0277046a1eb3b73c695b47dd275d17246d86bbfe35f112a7bdb5bf4a5a1a8e22fe37dfd005a2c"
}

Relayer Endpoint

To retrieve a relayer’s data with the Relay API make a GET request to the /relayer endpoint.

An example of the request:

curl \
  -X GET \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H "X-Api-Key: $KEY" \
  -H "Authorization: Bearer $TOKEN" \
    "$API_URL/relayer" # http://api.defender.openzeppelin.com/relayer

You would receive a response in the following format:

export interface RelayerModel {
  relayerId: string;
  name: string;
  address: string;
  network: string;
  paused: boolean;
  createdAt: string;
  pendingTxCost: string;
}

An example of the response:

{
   "relayerId":"d5484fb1-df83-4659-9903-16d57d41f188",
   "name":"Rinkeby",
   "address":"0x71764d6450c2b710fc3e4ee5b7a038d1e7e4fc29",
   "network":"rinkeby",
   "createdAt":"2020-11-02T18:00:00.212Z",
   "paused":false,
   "pendingTxCost":"0"
}

JSON RPC Endpoint

To make a JSON RPC call to the network of your Relay, make a POST request to the /relayer/jsonrpc endpoint with the method name and parameters. Note that event filter methods and websocket subscriptions are not supported.

An example of the request:

DATA='{ "jsonrpc":"2.0","method":"eth_getBalance","params":["0x407d73d8a49eeb85d32cf465507dd71d507100c1","latest"],"id":1 }'

curl \
  -X POST \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H "X-Api-Key: $KEY" \
  -H "Authorization: Bearer $TOKEN" \
  -d "$DATA" \
    "$API_URL/relayer/jsonrpc" # http://api.defender.openzeppelin.com/relayer/jsonrpc

An example of the response:

{
  "id": 1,
  "jsonrpc": "2.0",
  "result": "0x0234c8a3397aab58"
}