Java Guide

Prerequisites

Overview

Currently, Java developers can only use the standard HTTP REST requests when calling the Fireblocks API.

In this guide, we explain in detail the setup using the non-SDK usage (including signing the JWT token).

Using the Fireblocks API

Install Java 8 or newer

While this guide specifies Java 8 or newer. You can check which version of Java you already have installed by running the following command.

java -version

Learn how to install or update Java to a newer version.

Your First Fireblocks Java program!

Now that you're set up, run a quick check for the API. The script will query existing vaults, create a new vault and then query again to see that the vaults were created.

This Maven-based implementation will require some library dependencies:

📘

Use the correct API Base URL

In the following script, make sure you're using the correct value for baseUrl for your environment:

Learn more about workspace differences.

package com.fireblocks.develoepr.example;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import okhttp3.*;
import org.json.JSONObject;

import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.security.interfaces.RSAKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Stream;

public class FireblocksSDKExample {

    public FireblocksSDKExample(){
        StringBuilder secretBuilder = new StringBuilder();
        String API_SECRET_PATH = "<API-SECRET-KEY-PATH>";
        try(Stream<String> stream = Files.lines(Paths.get(API_SECRET_PATH), StandardCharsets.UTF_8)){
            stream.forEach(s -> secretBuilder.append(s).append("\n"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        String API_KEY = "<API-KEY>";
        String BASE_URL = "https://sandbox-api.fireblocks.io"; // Choose the right api url for your workspace type 

        FireblocksHttpClient httpClient = new FireblocksHttpClient(API_KEY, secretBuilder.toString(), BASE_URL);

        JSONObject getVaultsResponse = httpClient.get("/v1/vault/accounts_paged");
        System.out.println(getVaultsResponse.toString(4));

        JSONObject newVaultRequest = new JSONObject().put("name", "QuickStart_Vault3");
        JSONObject newVaultResponse = httpClient.post("/v1/vault/accounts", newVaultRequest);
        System.out.println(newVaultResponse.toString(4));

        getVaultsResponse = httpClient.get("/v1/vault/accounts_paged");
        System.out.println(getVaultsResponse.toString(4));
    }



    private static class FireblocksHttpClient {

        private String baseUrl = "https://api.fireblocks.io";
        private final String apiKey;

        private final PrivateKey privateKey;
        private final OkHttpClient client;

        public FireblocksHttpClient(String apiKey, String apiSecret){
            this(apiKey, apiSecret, "https://api.fireblocks.io");
        }

        public FireblocksHttpClient(String apiKey, String apiSecret, String baseUrl){
            Objects.requireNonNull(apiKey);
            Objects.requireNonNull(apiSecret);
            if(baseUrl != null && !this.baseUrl.equals(baseUrl)){
                this.baseUrl = baseUrl;
            }
            this.apiKey = apiKey;
            this.client = new OkHttpClient();
            try{
                byte[] keyBytes = Base64.decode(apiSecret.replace("-----BEGIN PRIVATE KEY-----", "")
                        .replace("-----END PRIVATE KEY-----", "")
                        .replace("\n",""));
                PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
                KeyFactory factory = KeyFactory.getInstance("RSA");
                this.privateKey = factory.generatePrivate(keySpec);
            } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
                throw new RuntimeException(e);
            }
        }

        public JSONObject get(String path){
            Request req = new Request.Builder()
                    .url(this.baseUrl + path)
                    .addHeader("X-API-Key", this.apiKey)
                    .addHeader("Authorization", "Bearer " + this.signJwt(path))
                    .build();
            try (Response resp = this.client.newCall(req).execute()) {
                ResponseBody body = resp.body();
                if (body == null) {
                    return new JSONObject();
                }
                return new JSONObject(body.string());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        public JSONObject post(String path, JSONObject data){

            Request req = new Request.Builder()
                    .url(this.baseUrl + path)
                    .addHeader("X-API-Key", this.apiKey)
                    .addHeader("Authorization", "Bearer " + this.signJwt(path, data.toString()))
                    .post(RequestBody.create(data.toString().getBytes(),MediaType.parse("application/json; charset=utf-8")))
                    .build();
            try (Response resp = this.client.newCall(req).execute()) {
                ResponseBody body = resp.body();
                if (body == null) {
                    return new JSONObject();
                }
                return new JSONObject(body.string());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        private String signJwt(String path){
            return this.signJwt(path, "");
        }

        private String signJwt(String path, String dataJSONString){
            String bodyHash;
            try {
                MessageDigest digest = MessageDigest.getInstance("SHA-256");
                digest.update(dataJSONString.getBytes());
                BigInteger number = new BigInteger(1, digest.digest());
                StringBuilder hexString = new StringBuilder(number.toString(16));
                while (hexString.length() < 64) {
                    hexString.insert(0, '0');
                }
                bodyHash = hexString.toString();
            } catch (NoSuchAlgorithmException e) {
                throw new RuntimeException(e);
            }
            Algorithm algo = Algorithm.RSA256((RSAKey) this.privateKey);
            Calendar cal = Calendar.getInstance();
            cal.add(Calendar.SECOND, 55);
            return JWT.create()
                    .withSubject(this.apiKey)
                    .withIssuedAt(new Date())
                    .withExpiresAt(cal.getTime())
                    .withClaim("nonce", UUID.randomUUID().toString())
                    .withClaim("uri", path)
                    .withClaim("bodyHash", bodyHash)
                    .sign(algo);
        }
    }

    public static void main(String[] args) {
        new FireblocksSDKExample();
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.fireblocks.developers.example</groupId>
    <artifactId>FireblocksSDKExample</artifactId>
    <version>1.0.0</version>
    <dependencies>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20220320</version>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>4.2.1</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.10.0</version>
        </dependency>
    </dependencies>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

🚧

Warning - Reference only

These examples are not production-ready and are used only for reference.

Please follow our security guidelines for secure API interaction.