Skip to main content

Authentication

Obtaining an API Key

At present, API keys are issued exclusively by Ginco. Please refrain from sharing your API key and API secret with anyone.

Making a Request

For requests that require authentication, include the following information in either the HTTP Header or gRPC Metadata:

  • X-API-KEY
  • X-API-SIGNATURE
    • A Base64-encoded string produced by hashing the X-API-NONCE, Request Path, and Request Body with HMAC-SHA256 using the API secret.
  • X-API-NONCE
    • The current Unix time in milliseconds. This value must be unique for each request that uses the same API key.

Signature Example

Go

package main

import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"time"
)

func main() {
key := "<YOUR API KEY>"
secret := "<YOUR API SECRET>"

nonce := time.Now().UnixMilli()
path := "/gincoinc.web3cloud.ethereum.gateway.v1.GatewayService/GetWallet"

// NOTE: The JSON payload has to be sorted in alphabetical order.
payload := struct {
WalletID string `json:"wallet_id"`
}{
WalletID: "95c1126d-d338-481e-8edb-5d66add6cfbb",
}
jsonPayload, err := json.Marshal(payload)
if err != nil {
log.Fatal(err)
}

msg := fmt.Sprintf("%d%s%s", nonce, path, string(jsonPayload))
h := hmac.New(sha256.New, []byte(secret))
h.Write([]byte(msg))
signature := base64.StdEncoding.EncodeToString(h.Sum(nil))

url := "https://web3-cloud-testnet-prd.gincoapis.com" + path
req, err := http.NewRequest(
http.MethodPost,
url,
bytes.NewBuffer(jsonPayload),
)
if err != nil {
log.Fatal(err)
}

req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-KEY", key)
req.Header.Set("X-API-SIGNATURE", signature)
req.Header.Set("X-API-NONCE", fmt.Sprint(nonce))

resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()

fmt.Println(resp.StatusCode)
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(bodyBytes))
}

Typescript

import * as crypto from 'crypto';
import fetch from 'node-fetch';

const main = async () => {
const key = '<YOUR API KEY>';
const secret = '<YOUR API SECRET>';

const nonce = Date.now();
const path =
'/gincoinc.web3cloud.ethereum.gateway.v1.GatewayService/GetWallet';
// NOTE: The JSON payload has to be sorted in alphabetical order.
const body = JSON.stringify({
wallet_id: '95c1126d-d338-481e-8edb-5d66add6cfbb',
});
const msg = `${nonce}${path}${body}`;
const hmac = crypto.createHmac('sha256', secret);
const signature = hmac.update(msg).digest('base64');

const headers = {
'Content-Type': 'application/json',
'X-API-KEY': key,
'X-API-SIGNATURE': signature,
'X-API-NONCE': `${nonce}`,
};

const url = 'https://web3-cloud-testnet-prd.gincoapis.com' + path;
const response = await fetch(url, {
method: 'POST',
body: body,
headers: headers,
});
const resp = await response.json();
console.log(resp);
};

main().catch((e) => {
console.error(e);
process.exit(1);
});