Getting Started
Here we provide a full example of how to setup a key and sign a payload using the HFT signer.
In this setup, we use the following JSON file and its corresponding Java class to define which keys will be available for signing.
Fill the JSON file with the relevant values and place it in your resources directory.
{
"vertices": [
{
"url": "vertex-0.example.com",
"api_key": "<HFT_MACHINE_API_KEY_0>",
"key": {
"key_name": "<CLUSTER_KEY_NAME>"
}
},
{
"url": "vertex-1.example.com",
"api_key": "<HFT_MACHINE_API_KEY_1>",
"key": {
"key_name": "<CLUSTER_KEY_NAME>"
}
},
{
"url": "vertex-2.example.com",
"api_key": "<HFT_MACHINE_API_KEY_2>",
"key": {
"key_name": "<CLUSTER_KEY_NAME>"
}
}
]
}
Define the following Java class to map the JSON file to Java objects.
package com.example;
import java.util.List;
public class VertexJson {
public List<Vertex> vertices;
public static class Vertex {
public String name;
public String url;
public String api_key;
public Key key;
}
public static class Key {
public String key_id;
public String key_name;
}
}
You can choose to use either HMAC-SHA256, HMAC-SHA512 or ED25519 keys. The examples below show how to import all three types of keys.
Key Set Up
Set up the keys in the HFT signer.
package com.example;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import dev.sodot.hftsigner.HftSignerSdk;
import dev.sodot.hftsigner.SodotVertexDetails;
import dev.sodot.hftsigner.SodotKeyIdent;
public class Example {
private static final String SERVER_HOST = "127.0.0.1"; // Private IP of the HFT signer instance
private static final int SERVER_PORT = 8000;
public static void main(String[] args) {
try {
HftSignerSdk sdk = new HftSignerSdk(SERVER_HOST, SERVER_PORT);
System.out.println("Creating HFT Signer SDK...");
// Load vertices from JSON
ObjectMapper mapper = new ObjectMapper();
String HmacSha256JsonStr = new String(Files.readAllBytes(Paths.get("hmac_sha256_vertices.json")),
StandardCharsets.UTF_8);
VertexJson HmacSHA256VertexJson = mapper.readValue(HmacSha256JsonStr, VertexJson.class);
SodotVertexDetails[] hmac256VerticesDetails = HmacSHA256VertexJson.vertices.stream().map(v -> {
try {
return new SodotVertexDetails(v.url, v.api_key,
v.key.key_id != null
? SodotKeyIdent.ID.withValue(v.key.key_id)
: SodotKeyIdent.NAME.withValue(v.key.key_name));
} catch (Exception e) {
throw new RuntimeException(e);
}
}).toArray(SodotVertexDetails[]::new);
String HmacSha512JsonStr = new String(Files.readAllBytes(Paths.get("hmac_sha512_vertices.json")),
StandardCharsets.UTF_8);
VertexJson HmacSHA512VertexJson = mapper.readValue(HmacSha512JsonStr, VertexJson.class);
SodotVertexDetails[] hmac512VerticesDetails = HmacSHA512VertexJson.vertices.stream().map(v -> {
try {
return new SodotVertexDetails(v.url, v.api_key,
v.key.key_id != null
? SodotKeyIdent.ID.withValue(v.key.key_id)
: SodotKeyIdent.NAME.withValue(v.key.key_name));
} catch (Exception e) {
throw new RuntimeException(e);
}
}).toArray(SodotVertexDetails[]::new);
String Ed25519JsonStr = new String(Files.readAllBytes(Paths.get("ed25519_vertices.json")),
StandardCharsets.UTF_8);
VertexJson Ed25519VertexJson = mapper.readValue(Ed25519JsonStr, VertexJson.class);
SodotVertexDetails[] ed25519VerticesDetails = Ed25519VertexJson.vertices.stream().map(v -> {
try {
return new SodotVertexDetails(v.url, v.api_key,
v.key.key_id != null
? SodotKeyIdent.ID.withValue(v.key.key_id)
: SodotKeyIdent.NAME.withValue(v.key.key_name));
} catch (Exception e) {
throw new RuntimeException(e);
}
}).toArray(SodotVertexDetails[]::new);
System.out.println("Retrieving vertex details for HMAC-SHA256, HMAC-SHA512 and ED25519");
byte[] hmacHftApiKey256 = sdk.importHmacSha256(hmac256VerticesDetails);
byte[] hmacHftApiKey512 = sdk.importHmacSha512(hmac512VerticesDetails);
byte[] ed25519HftApiKey = sdk.importEd25519(ed25519VerticesDetails);
sdk.close();
System.out.println("HFT Signer SDK closed.");
} catch (Exception e) {
System.err.println("Example failed with error: " + e.getMessage());
e.printStackTrace();
}
}
}
Signing
Sign a payload with the previously set up keys.
package com.example;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import dev.sodot.hftsigner.HftSignerSdk;
public class Example {
private static final String SERVER_HOST = "127.0.0.1"; // Private IP of the HFT signer instance
private static final int SERVER_PORT = 8000;
private static final int ITERATIONS = 1000;
public static void main(String[] args) {
try (HftSignerSdk sdk = new HftSignerSdk(SERVER_HOST, SERVER_PORT);) {
byte[] hmacHftApiKey256 = hexStringToByteArray("a12");
byte[] hmacHftApiKey512 = hexStringToByteArray("b12");
byte[] ed25519HftApiKey = hexStringToByteArray("c12");
// Example data to sign - this would be the order payload in a real scenario
byte[] dataToSign = "Hello, HFT Signer!".getBytes(StandardCharsets.UTF_8);
// Example 1: Sign with HMAC-SHA256
System.out.println("\n--- HMAC-SHA256 Signing ---");
sdk.signHmacSha256(dataToSign, hmacHftApiKey256);
// Example 2: Sign with HMAC-SHA512
System.out.println("\n--- HMAC-SHA512 Signing ---");
sdk.signHmacSha512(dataToSign, hmacHftApiKey512);
// Example 3: Sign with ED25519
System.out.println("\n--- ED25519 Signing ---");
sdk.signEd25519(dataToSign, ed25519HftApiKey);
sdk.close();
System.out.println("HFT Signer SDK closed.");
} catch (Exception e) {
System.err.println("Example failed with error: " + e.getMessage());
e.printStackTrace();
}
}
static byte[] hexStringToByteArray(String hex) {
int len = hex.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i + 1), 16));
}
return data;
}
}
Full Example
This example setup a key and signs 1000 messages.
This example shows how to:
- Create an HftSignerSdk instance
- Set up vertex details for authentication
- Sign data using different algorithms (HMAC256, HMAC512, ED25519)
- Measure the time taken for signing operations
package com.example;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import dev.sodot.hftsigner.HftSignerSdk;
import dev.sodot.hftsigner.SodotVertexDetails;
import dev.sodot.hftsigner.SodotKeyIdent;
public class HftSignerExample {
private static final String SERVER_HOST = "127.0.0.1"; // Private IP of the HFT signer instance
private static final int SERVER_PORT = 8000;
private static final int ITERATIONS = 1000;
public static void main(String[] args) {
try {
HftSignerSdk sdk = new HftSignerSdk(SERVER_HOST, SERVER_PORT);
// Load vertices from JSON
ObjectMapper mapper = new ObjectMapper();
String HmacSha256JsonStr = new String(Files.readAllBytes(Paths.get("hmac_sha256_vertices.json")),
StandardCharsets.UTF_8);
VertexJson HmacSHA256VertexJson = mapper.readValue(HmacSha256JsonStr, VertexJson.class);
SodotVertexDetails[] hmac256VerticesDetails = HmacSHA256VertexJson.vertices.stream().map(v -> {
try {
return new SodotVertexDetails(v.url, v.api_key,
v.key.key_id != null
? SodotKeyIdent.ID.withValue(v.key.key_id)
: SodotKeyIdent.NAME.withValue(v.key.key_name));
} catch (Exception e) {
throw new RuntimeException(e);
}
}).toArray(SodotVertexDetails[]::new);
String HmacSha512JsonStr = new String(Files.readAllBytes(Paths.get("hmac_sha512_vertices.json")),
StandardCharsets.UTF_8);
VertexJson HmacSHA512VertexJson = mapper.readValue(HmacSha512JsonStr, VertexJson.class);
SodotVertexDetails[] hmac512VerticesDetails = HmacSHA512VertexJson.vertices.stream().map(v -> {
try {
return new SodotVertexDetails(v.url, v.api_key,
v.key.key_id != null
? SodotKeyIdent.ID.withValue(v.key.key_id)
: SodotKeyIdent.NAME.withValue(v.key.key_name));
} catch (Exception e) {
throw new RuntimeException(e);
}
}).toArray(SodotVertexDetails[]::new);
String Ed25519JsonStr = new String(Files.readAllBytes(Paths.get("ed25519_vertices.json")),
StandardCharsets.UTF_8);
VertexJson Ed25519VertexJson = mapper.readValue(Ed25519JsonStr, VertexJson.class);
SodotVertexDetails[] ed25519VerticesDetails = Ed25519VertexJson.vertices.stream().map(v -> {
try {
return new SodotVertexDetails(v.url, v.api_key,
v.key.key_id != null
? SodotKeyIdent.ID.withValue(v.key.key_id)
: SodotKeyIdent.NAME.withValue(v.key.key_name));
} catch (Exception e) {
throw new RuntimeException(e);
}
}).toArray(SodotVertexDetails[]::new);
System.out.println("Exporting vertex details for HMAC-SHA256, HMAC-SHA512 and ED25519");
byte[] hmacHftApiKey256 = sdk.importHmacSha256(hmac256VerticesDetails);
byte[] hmacHftApiKey512 = sdk.importHmacSha512(hmac512VerticesDetails);
byte[] ed25519HftApiKey = sdk.importEd25519(ed25519VerticesDetails);
// Example data to sign
byte[] dataToSign = "Hello, HFT Signer!".getBytes(StandardCharsets.UTF_8);
long startTime, endTime, duration;
// Example 1: Sign with HMAC-SHA256
System.out.println("\n--- HMAC-SHA256 Signing ---");
startTime = System.nanoTime();
for (int i = 0; i < ITERATIONS; i++) {
sdk.signHmacSha256(dataToSign, hmacHftApiKey256);
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("Average time taken for HMAC-SHA256 signature: " + (duration / 1000000) + " micro secs");
// Example 2: Sign with HMAC-SHA512
System.out.println("\n--- HMAC-SHA512 Signing ---");
startTime = System.nanoTime();
for (int i = 0; i < ITERATIONS; i++) {
sdk.signHmacSha512(dataToSign, hmacHftApiKey512);
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("Average time taken for HMAC-SHA512 signature: " + (duration / 1000000) + " micro secs");
// Example 3: Sign with ED25519
System.out.println("\n--- ED25519 Signing ---");
startTime = System.nanoTime();
for (int i = 0; i < ITERATIONS; i++) {
sdk.signEd25519(dataToSign, ed25519HftApiKey);
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("Average time taken for ED25519 signature: " + (duration / 1000000) + " micro secs");
sdk.close();
System.out.println("HFT Signer SDK closed.");
} catch (Exception e) {
System.err.println("Example failed with error: " + e.getMessage());
e.printStackTrace();
}
}
}