These endpoints can be authenticated using a combination of your API Key and a signature.
First, make sure to register your API key in the Register an API key for the current user. The endpoint expects 3 inputs:
- Name: a name for your API key. Can be anything.
- Public Key: the public key of a RSA key pair generated by you. The public key should be in PKIX DER format, pem encoded. E.g.:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwOx3GEawTd2D9gHg555j
bBqR+hzW3mQkGKIsq1srnTb2i6W3aJSnobpB/7l6LlALPOhdofgBLaIaqHNwLRSW
TtdMympRAj3iq34gwNlSMAqhXv7yVHi3hj1ANm7wQtjE5RsSETmcubrFm58xyNWq
s7gFzH6UUznJp3xTLcO9aG6/Xn8wLM1V+18lLDko6AsZW6ZVLRG4f9a9QRPnqIK2
lqQ/28Ks1i9Z4La0O7GJtts0Slg9SdgIzAMVZvODBOJ/uVIrl5mQxYbbvyp8IJ4Z
U8lTS4RUzCiUTmTBWabhtZC3KtE+FT8RcG5JH8Hro0jN95+ZA1RLJ0dr0bzZ9xfX
UwIDAQAB
-----END PUBLIC KEY-----
- Signature: this signature is obtained by using the private key generated with the public key to sign the payload obtained by applying the SHA256 hashing algorithm to the same name you sent as input. This is meant simply to help you verify if your public key was successfully accepted and it's ready to verify your API calls.
To access the API endpoints using API Key authentication, you must pass the following headers in your http request:
X-API-Key: {Your API Key hHere}
X-API-Timestamp: {Timestamp in UNIX milliseconds format}
X-API-Signature: {An unique base64 encoded signature you must generate for each of your requests}
The signature you have to send is obtained by the following procedure:
- Concatenate as text: {Timestamp}{Request method}{Endpoint path with query parameters}{Body JSON, if present}
- Apply the SHA256 hashing algorithm.
- Sign the payload with your private key using RSASSA-PKCS1-V1_5-SIGN from RSA PKCS #1 v1.5
- Encode the result into a base64 string.
A full example is provided below:
- Creating the key pair
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
log.Fatal(err)
}
publicKey := &privateKey.PublicKey
privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey)
privateKeyBlock := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: privateKeyBytes,
}
privateKeyEncoded := pem.EncodeToMemory(privateKeyBlock)
publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
log.Fatal(err)
}
publicKeyBlock := &pem.Block{
Type: "PUBLIC KEY",
Bytes: publicKeyBytes,
}
publicKeyEncoded := pem.EncodeToMemory(publicKeyBlock)
log.Println(string(privateKeyEncoded))
log.Println(string(publicKeyEncoded))
openssl genrsa -out keypair.pem 2048
openssl rsa -in keypair.pem -pubout -out publickey.pem
In this example, the keys generated were:
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAp2sCMqZe2cePRooomyX+S3/yfGS3g7TG3eur2gtAtD6PVKaL
lv5Sk/d0zyJXrWaBIrVoU2rlKLGqKhsql1vTB6IcPsIwN4qK5guMC2Mi2+j7dCoG
SY1wU4sDTO6L7fsBKp7tvKw1H11h6Xoan05jfyPGvg4TKhOd9LZHwPCfZCU20L33
s0ryQj4T6v/eGtoT4HCfrMlPLIj7zq4TIHgqHUhnYYsRLJO179JblPqErZzu3iFs
hjDoIdparO3WWO+Z7bq+9JqdLpgJywZuvAUpZd8yNgQcZ0mNnV/GXniMz/U8NbQb
FDeF6eLmCnALT2l20Et2wOAjgY2GAwNyzSschQIDAQABAoIBABPYqp0IfewBLSnm
jOO/gELA+yTl559UWdLK8kdZ2CTF2cXmLFwM8AscZZt8bbpfkWVk7eYdoObPEOYG
7Gie+QhJnmGOMZsT8F1O9x4OdX5uQwjFRpOHkc5Fh3GiQbJHdB7yUipwm6eJMWc1
E1zZNRBIVHIJRxpQ0wPEbAMiQzLiyV82fNGYe3bzlsR84b9KIKmJV4WBEaIz6OfS
2ds/6ArRDtnx21a/wHGZPODVXT6Cs+G7EkS0/a2voCGTkh8apUY6XDwu9yktWPVs
MwtqCZRf6bTwTEmcc4n8IgFuX6QxQMERv9DWoaZZ+TfEDI4DRP+6AdVWffbzF7W6
FyCmrK0CgYEA1QVCzraBbiFYs4AsTdK44mpHTgionapbMRZOWGOUa34qQ9wNQbDv
iRHS9CEFQSYEKs54gO8P81Alu9cxMWoitlNg2Y2c2hiCBmTYEXR4aE6p4x6f7otD
M79ZjlWFXVbpb9d20b+qqECTgQI+lWO9+Cdam5RxaJ5os9fZ+Lu8Xd8CgYEAyTJT
yDTLdVGplDboDTpknQ8nq1+A11xdmdQ52IXNdbWFfErp0OmyPTuGQj+XFf6vY/5L
xDh7ynRHMdMkv3guxoLNil9XBCkl7KMi2VJSfwrV0BntrZ2GQ4MF7DHt2EwrbvkY
QLXoOWYZ/pgurqDG6PYlXMKlyC9kQ4cR/LqtihsCgYEAq2mQWMaDYBt1RPveqsDm
BUuAFUriY/yxZM6OPJHk3JqpZ/GquTGnjqTJG6l2kPYGZGvAi//S1feoZX7EFv9Q
72YoiOdrUBRojLyZIXKXcVfbXOdHyqxFZ16SsfYfWvyU22qGMkIJEVrlVup3cb7R
Ht6MCqVonMbbedw3ie+HpAECgYBQbVPclm42qbxWSVSd5RfPSP2cngLNFFk+Yv30
thgZ08RWmUO6hZEAtUjINs9YtYS7Pi5fdAzYM386RaNM/ugD5snvZIlOWnyUieom
YagkrNon5BWE75F6b2fwsUzYyCocpGqzg4QfXddKVN9kY1TgT3VEDXNkAL3d2KKy
GpXAvQKBgQDD3GKdCW7Q2CD6rIXfJgttCPQ022v3i/ug4phYk+5z7Siw3pEL7PNp
VPPD1b1FNAcbIdTG9Nr5X8Rt2OP0MJs8Lnv7kqN0c0Ssieb9OcYQEDc8ynuon83b
K+hYV35dGsNU0OuixwDjfoa3jfxJp4N0tB9Hv4PNpodCc1OOnILUnA==
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp2sCMqZe2cePRooomyX+
S3/yfGS3g7TG3eur2gtAtD6PVKaLlv5Sk/d0zyJXrWaBIrVoU2rlKLGqKhsql1vT
B6IcPsIwN4qK5guMC2Mi2+j7dCoGSY1wU4sDTO6L7fsBKp7tvKw1H11h6Xoan05j
fyPGvg4TKhOd9LZHwPCfZCU20L33s0ryQj4T6v/eGtoT4HCfrMlPLIj7zq4TIHgq
HUhnYYsRLJO179JblPqErZzu3iFshjDoIdparO3WWO+Z7bq+9JqdLpgJywZuvAUp
Zd8yNgQcZ0mNnV/GXniMz/U8NbQbFDeF6eLmCnALT2l20Et2wOAjgY2GAwNyzSsc
hQIDAQAB
-----END PUBLIC KEY-----
- Signing the API Key register request
privateKeyFile, err := os.ReadFile("privatekey.pem")
if err != nil {
log.Fatal(err)
}
privateKeyBlock, _ := pem.Decode(privateKeyFile)
if privateKeyBlock == nil {
log.Fatal("error decoding private key")
}
privateKey, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
if err != nil {
log.Fatal(err)
}
const keyName = "My API Key"
hasher := sha256.New()
hasher.Write([]byte(keyName))
hash := hasher.Sum(nil)
signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hash)
if err != nil {
log.Fatal(err)
}
base64Signature := base64.StdEncoding.EncodeToString(signature)
log.Println("Signature:", base64Signature) // MMZaJGPtXq571wHdUe/Z/mifFbnnjKJUEgChY1nYREAETNY5vbDo5JM/LOLxQtE5CYtPhcm7w214Vlblh2hoKDLjLALfeyFPo0DpeIyV3EWnr/qQ4F1jYJiP44ke9AKxURctVFqJtLm12ABJ25fPDeTXrfKnZTn+SY3JctRZDD5KHx4ZgM96jgJFU2kLJvrsof/6mdCri2IiHTdwpEuxdnHMnwc2j3yjoJ2IwCsr7n7L+H44S0GYK/dOL/n0cZAmxmFw1m0vB03CdrAoGtbaweTaBtg6psrjrvzkqJOXq9AgWJVoMCx4Hoe8o3txf5l7NZYIrLtQu/CieXSJoMwrDQ==
# Library used: pycryptodome
from Crypto.PublicKey import RSA
from Crypto.Signature.pkcs1_15 import PKCS115_SigScheme
from Crypto.Hash import SHA256
import base64
privKeyTxt = open("privateKey.pem", "r").read()
keyPair = RSA.importKey(privKeyTxt)
pubKey = keyPair.publickey() # Just showing how to get the public key as well
msg = b'My API Key'
hash = SHA256.new(msg)
signer = PKCS115_SigScheme(keyPair)
signature = signer.sign(hash)
print("Signature:", base64.b64encode(signature)) # MMZaJGPtXq571wHdUe/Z/mifFbnnjKJUEgChY1nYREAETNY5vbDo5JM/LOLxQtE5CYtPhcm7w214Vlblh2hoKDLjLALfeyFPo0DpeIyV3EWnr/qQ4F1jYJiP44ke9AKxURctVFqJtLm12ABJ25fPDeTXrfKnZTn+SY3JctRZDD5KHx4ZgM96jgJFU2kLJvrsof/6mdCri2IiHTdwpEuxdnHMnwc2j3yjoJ2IwCsr7n7L+H44S0GYK/dOL/n0cZAmxmFw1m0vB03CdrAoGtbaweTaBtg6psrjrvzkqJOXq9AgWJVoMCx4Hoe8o3txf5l7NZYIrLtQu/CieXSJoMwrDQ==
- Sending the request and registering the API Key
POST /superuser/api-keys
Accept: application/json
Authorization: Bearer {JWT Token Here}
{
"name":"My API Key",
"publicKey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp2sCMqZe2cePRooomyX+\nS3/yfGS3g7TG3eur2gtAtD6PVKaLlv5Sk/d0zyJXrWaBIrVoU2rlKLGqKhsql1vT\nB6IcPsIwN4qK5guMC2Mi2+j7dCoGSY1wU4sDTO6L7fsBKp7tvKw1H11h6Xoan05j\nfyPGvg4TKhOd9LZHwPCfZCU20L33s0ryQj4T6v/eGtoT4HCfrMlPLIj7zq4TIHgq\nHUhnYYsRLJO179JblPqErZzu3iFshjDoIdparO3WWO+Z7bq+9JqdLpgJywZuvAUp\nZd8yNgQcZ0mNnV/GXniMz/U8NbQbFDeF6eLmCnALT2l20Et2wOAjgY2GAwNyzSsc\nhQIDAQAB\n-----END PUBLIC KEY-----",
"signature": "MMZaJGPtXq571wHdUe/Z/mifFbnnjKJUEgChY1nYREAETNY5vbDo5JM/LOLxQtE5CYtPhcm7w214Vlblh2hoKDLjLALfeyFPo0DpeIyV3EWnr/qQ4F1jYJiP44ke9AKxURctVFqJtLm12ABJ25fPDeTXrfKnZTn+SY3JctRZDD5KHx4ZgM96jgJFU2kLJvrsof/6mdCri2IiHTdwpEuxdnHMnwc2j3yjoJ2IwCsr7n7L+H44S0GYK/dOL/n0cZAmxmFw1m0vB03CdrAoGtbaweTaBtg6psrjrvzkqJOXq9AgWJVoMCx4Hoe8o3txf5l7NZYIrLtQu/CieXSJoMwrDQ=="
}
-> Response
{
"apiKey": "ab3915e6-4886-4fef-b3a6-5855962ffbb8"
}
- Calling the Create static pix buy order endpoint
timestamp := time.Now().UnixMilli()
requestMethod := http.MethodPost
endpointPath := "/v1/superuser/buy/static-pix?taxId=12345678900"
bodyData, _ := json.Marshal(struct {
WalletAddress string `json:"walletAddress"`
Chain string `json:"chain"`
Amount int64 `json:"amount"`
}{
WalletAddress: "0xC0D9F3171FB05A9F091EAaa6Fe0a8e98a37F70Ce",
Chain: "Polygon",
Amount: 20000,
})
content := fmt.Sprintf("%s%s%s%s", strconv.FormatInt(timestamp, 10), requestMethod, endpointPath, string(bodyData))
hasher := sha256.New()
hasher.Write([]byte(content))
hash := hasher.Sum(nil)
signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hash)
if err != nil {
log.Fatal(err)
}
base64Signature := base64.StdEncoding.EncodeToString(signature)
req, _ := http.NewRequest(requestMethod, apiUrl+endpointPath, bytes.NewReader(bodyData))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-Key", "ab3915e6-4886-4fef-b3a6-5855962ffbb8")
req.Header.Set("X-API-Timestamp", strconv.FormatInt(timestamp, 10))
req.Header.Set("X-API-Signature", base64Signature)
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusCreated {
log.Fatal("error creating buy request")
}