Request Signing
Certain endpoints require secondary validation prior to the request being accepted for processing. We use Ed25519 based signatures to validate requests. These endpoints will specify the x-signature
and x-timestamp
headers as additional parameters.
Signing Keys
You will generate the signing key pair when onboarding. You are required to provide us the generated Ed25519 public key to complete onboarding.
You must use the associated Ed25519 signing key (private key) when creating signatures for requests.
Please note that signing keys (Ed25519 private keys) should be stored securely. The signing key should only be used to derive request signatures and should never be sent in a request. Layer2 will never request you share your private key.
Signatures are optional unless explicitly required, but are encouraged for all requests. If a signature is provided, it will be verified.
Generating the Signing Key
You must securely generate an Ed25519 key pair on your own hardware and retain both the public and private portions. Layer2 requires the 64-character (32 bytes) hex-encoded Ed25519 during onboarding.
Code Sample (Python) -
# https://pypi.org/project/PyNaCl/
import nacl
import nacl.signing
import secrets
seed = secrets.token_bytes(32)
# Generate a new random signing key
signing_key = nacl.signing.SigningKey(seed)
# Obtain the hex-encoded signing key
print('Signing key:')
print(signing_key.encode().hex())
# Obtain the hex-encoded verify key for the given signing key
# Use this when onboarding with Layer2
print('Public key:')
print(signing_key.verify_key.encode().hex())
Generating the Signing Key
To sign a request, generate a request signature using the Ed25519 private (signing) key you generated during onboarding, and provide it alongside the request in the x-signature
header.Signing is a 3 step process (below), details of each field using in signing is explained below.
Step | Action | Description |
---|---|---|
1 | Concatenate | Concatenate the timestamp , method , request path , and body into a string. There are no spaces or other characters between these values. The order of the fields MUST follow the order stipulated here. |
2 | Sign | Take the string from step 1 and generate a signature using your Ed25519 private key |
3 | Encode | Take the signed value and hex-encode the output. |
The fields used to generate the signature are as follows. If the conditions below are not met, your signature will not validate.
| Field | Description |
|---|---|
| Timestamp | The number of seconds since the Unix Epoch in UTC, and must be within one minute of the API service's time when the. The same value MUST be also placed in the x-timestamp
header. |
| Method | Uppercase HTTP verb (GET, PUT, POST, DELETE) |
| Request Path | Lowercase path minus the domain, including ALL query parameters and values (ex. /api/v1/accounts/payments/1001-1234/address?type=abc). |
| Body | Should be omitted where there is no body (e.g. GET). The stringified
HTTP request body. |
Signing Example
You can validate your signing code using the example below;
Field | Value |
---|---|
Timestamp | 1527380000 |
Method | POST |
Request Path | /api/v1/accounts/payments/1001-1234/address?type=abc |
Body | {"amount": "100","paymentreference": "FUND01-00023423","payorid": "0000-0003"} |
Signing Key | 302e020100300506032b6570042204200df0ce421b0830759ea9bfa727c0f4d0aa7086cfaf26c66e7e85bd10787d5728 |
Public Key | 302a300506032b657003210095de28d850d6be3525384323b5add134dcb9b3bb404f43cbf47dac5e11c351de |
Signature Key | 51b19da0a23377bbb72222ba78bc32f0ec24404ac24b1a0c8f6942f2eb9e26bd6ffb078b9630a376f45360b74861f29198a81d93c2ae09971969b19532a9a800 |