The library is a Java client for the Kraken REST API. It is organized around four core concepts:
KrakenAPI— The main entry point. A facade that exposes typed methods for implemented endpoints and generic methods for any endpoint.Endpoint<T>— Represents a single API call. Knows its HTTP method, URL path, parameters, and response type. Splits intoPublicEndpoint<T>(GET) andPrivateEndpoint<T>(POST with HMAC signing).KrakenRestRequester— Interface that performs the actual HTTP request and response parsing.DefaultKrakenRestRequesteris the built-in implementation usingHttpsURLConnection.- Params / Response types — Each endpoint has dedicated parameter objects (
QueryParamsfor public,PostParamsfor private) and response records deserialized via Jackson.
sequenceDiagram
participant User
participant KrakenAPI
participant PublicEndpoint
participant QueryParams
participant RestRequester as DefaultKrakenRestRequester
participant Kraken as Kraken API
User->>KrakenAPI: assetInfo(["BTC", "ETH"])
KrakenAPI->>PublicEndpoint: new AssetInfoEndpoint(assets)
activate PublicEndpoint
PublicEndpoint->>QueryParams: new AssetInfoParams(assets, "currency")
deactivate PublicEndpoint
KrakenAPI->>RestRequester: execute(endpoint)
RestRequester->>PublicEndpoint: buildURL()
PublicEndpoint->>QueryParams: toMap()
QueryParams-->>PublicEndpoint: {asset: "BTC,ETH", aclass: "currency"}
PublicEndpoint-->>RestRequester: https://api.kraken.com/0/public/Assets?asset=BTC,ETH&aclass=currency
RestRequester->>Kraken: GET
Kraken-->>RestRequester: {"error": [], "result": {…}}
RestRequester->>RestRequester: deserialize into KrakenResponse<Map<String, AssetInfo>>
RestRequester->>RestRequester: unwrap result or throw KrakenException
RestRequester-->>KrakenAPI: Map<String, AssetInfo>
KrakenAPI-->>User: Map<String, AssetInfo>
sequenceDiagram
participant User
participant KrakenAPI
participant PrivateEndpoint
participant PostParams
participant NonceGen as KrakenNonceGenerator
participant Credentials as KrakenCredentials
participant RestRequester as DefaultKrakenRestRequester
participant Kraken as Kraken API
User->>KrakenAPI: ledgerInfo(params)
KrakenAPI->>PrivateEndpoint: new LedgerInfoEndpoint(params)
KrakenAPI->>RestRequester: execute(endpoint, credentials, nonceGenerator)
RestRequester->>NonceGen: generate()
NonceGen-->>RestRequester: "1712750400000"
RestRequester->>PrivateEndpoint: encodedParamsWith(nonce)
PrivateEndpoint->>PostParams: setNonce(nonce)
PrivateEndpoint->>PostParams: encoded()
PostParams-->>RestRequester: "nonce=1712750400000&asset=BTC,ETH&…"
RestRequester->>PrivateEndpoint: buildURL()
PrivateEndpoint-->>RestRequester: https://api.kraken.com/0/private/Ledgers
RestRequester->>Credentials: sign(url, nonce, encodedParams)
Note over Credentials: SHA-256(nonce + params)<br/>HMAC-SHA512(base64(secret), path + sha256)
Credentials-->>RestRequester: Base64 signature
RestRequester->>Kraken: POST with API-Key + API-Sign headers
Kraken-->>RestRequester: {"error": [], "result": {…}}
RestRequester->>RestRequester: deserialize into KrakenResponse<LedgerInfo>
RestRequester->>RestRequester: unwrap result or throw KrakenException
RestRequester-->>KrakenAPI: LedgerInfo
KrakenAPI-->>User: LedgerInfo
classDiagram
class KrakenAPI {
-KrakenCredentials credentials
-KrakenNonceGenerator nonceGenerator
-KrakenRestRequester restRequester
+serverTime() ServerTime
+assetInfo(assets) Map~String, AssetInfo~
+ticker(pairs) Map~String, Ticker~
+ledgerInfo(params) LedgerInfo
+query(PublicEndpoint~T~) T
+query(PrivateEndpoint~T~) T
+query(endpoint) JsonNode
+queryPublic(path) JsonNode
+queryPrivate(path) JsonNode
}
class Endpoint~T~ {
<<abstract>>
#String path
-String httpMethod
-TypeReference~T~ responseType
+buildURL() URL
+wrappedResponseType() JavaType
}
class PublicEndpoint~T~ {
-QueryParams queryParams
+buildURL() URL
}
class PrivateEndpoint~T~ {
-PostParams postParams
+encodedParamsWith(nonce) String
+buildURL() URL
}
class KrakenRestRequester {
<<interface>>
+execute(PublicEndpoint~T~) T
+execute(PrivateEndpoint~T~, credentials, nonceGenerator) T
}
class DefaultKrakenRestRequester {
-ObjectMapper OBJECT_MAPPER
}
class KrakenResponse~T~ {
<<record>>
+List~String~ error
+Optional~T~ result
}
class KrakenException {
+List~String~ errors
}
class KrakenCredentials {
+sign(url, nonce, params) String
}
class KrakenNonceGenerator {
<<interface>>
+generate() String
}
Endpoint <|-- PublicEndpoint
Endpoint <|-- PrivateEndpoint
KrakenRestRequester <|.. DefaultKrakenRestRequester
KrakenAPI --> KrakenRestRequester
KrakenAPI --> KrakenCredentials
KrakenAPI --> KrakenNonceGenerator
DefaultKrakenRestRequester ..> KrakenResponse : deserializes
KrakenResponse ..> KrakenException : throws on error
KrakenAPI provides four levels of access, from most to least typed:
| Tier | Methods | Return type | When to use |
|---|---|---|---|
| Custom endpoint | query(myEndpoint) |
Whatever the endpoint declares | You wrote your own PublicEndpoint/PrivateEndpoint for an endpoint the library doesn't implement |
| Typed | assetInfo(), ledgerInfo(), etc. |
Domain records | Endpoint has a dedicated implementation |
| Enum-based | query(Public.TICKER, params) |
JsonNode |
Endpoint is in the Public/Private enum but not yet typed |
| Raw path | queryPublic("Trades", params) |
JsonNode |
Endpoint isn't in the enum yet (e.g., newly added by Kraken) |
To add a new typed endpoint:
- Create a response record in the appropriate
response/package - Create a params class implementing
QueryParams(public) or extendingPostParams(private) - Create an endpoint class extending
PublicEndpoint<T>orPrivateEndpoint<T> - Add a convenience method to
KrakenAPI
Steps 1 to 3 work just as well from outside the library, for an endpoint you need before it is implemented here. Step 4 is then replaced by handing the endpoint to KrakenAPI.query(...), which runs it through the configured KrakenRestRequester and signs private requests with the credentials and nonce generator the instance was built with:
KrakenAPI api = new KrakenAPI(key, secret);
MyResponse response = api.query(new MyEndpoint(params));A PrivateEndpoint queried on an instance built without credentials fails with an IllegalStateException naming the endpoint path.