API Clients
Internal API clients are essential for the Blocklet SDK to facilitate secure and efficient communication within the Blocklet Server ecosystem. These clients handle interactions with both the core Blocklet Server services and other deployed Blocklet components. They are primarily built on Axios and incorporate robust security features, such as request signing, to ensure data integrity and authenticity.
For more details on how these clients are used to manage authentication and component interactions, refer to the Auth Service and Component Interaction sections.
Blocklet Service API Client#
The Blocklet Service API client is responsible for all communications between your Blocklet and the core Blocklet Server services. This client is an Axios instance pre-configured for internal calls, ensuring secure and direct communication within the Blocklet Server environment.
Key Configurations:
proxy: false
: This client explicitly disables proxy settings, as it is designed for internal machine-to-machine calls within the local Blocklet Server instance.baseURL
: The base URL is dynamically constructed using the server host and the Blocklet Service port, typicallyhttp://${getServerHost()}:${process.env.ABT_NODE_SERVICE_PORT}/api/service
.timeout
: A relatively short timeout of 6 seconds is set, reflecting the expectation of fast internal network communication.- Headers: Important headers are injected for environment recognition and security:
User-Agent
: Identifies the Blocklet SDK version.x-blocklet-server-version
: Specifies the Blocklet Server version.x-blocklet-did
: The Decentralized Identifier (DID) of the current Blocklet.x-blocklet-component-id
: The real DID of the Blocklet component.
Request Signing:
Before any request is sent, a request interceptor adds signature information to the headers. This ensures the authenticity and integrity of the request. The signature includes:
x-blocklet-sig
: The cryptographic signature of the request payload.x-blocklet-sig-iat
: The "issued at" timestamp of the signature.x-blocklet-sig-exp
: The expiration timestamp of the signature.x-blocklet-sig-version
: The version of the signature algorithm used.
These signatures are generated using the Blocklet's application secret key and are verified by the Blocklet Server's service interfaces.
import Axios from 'axios';
import { serverVersion } from '@blocklet/env';
import { joinURL } from 'ufo';
import { SERVICE_PREFIX } from './constants';
import { getSignData } from './verify-sign';
import { getServerHost } from './parse-docker-endpoint';
const axios = Axios.create({
proxy: false,
baseURL: `http://${getServerHost()}:${process.env.ABT_NODE_SERVICE_PORT}${SERVICE_PREFIX}`,
timeout: 6 * 1000,
headers: {
'User-Agent': `BlockletSDK/${serverVersion}`,
'x-blocklet-server-version': serverVersion,
'x-blocklet-did': process.env.BLOCKLET_DID,
'x-blocklet-component-id': process.env.BLOCKLET_REAL_DID,
},
});
axios.interceptors.request.use((config) => {
const { sig, exp, iat, version } = getSignData({
data: config.data,
method: config.method,
params: config.params,
url: joinURL(SERVICE_PREFIX, config.url),
});
config.headers['x-blocklet-sig'] = sig;
config.headers['x-blocklet-sig-iat'] = iat;
config.headers['x-blocklet-sig-exp'] = exp;
config.headers['x-blocklet-sig-version'] = version;
return config;
});
export default axios;
Component API Client#
The Component API client facilitates communication between your Blocklet and other Blocklet components deployed on the same Blocklet Server. This client is also an Axios instance, specifically tailored for inter-component interactions.
Key Configurations:
timeout
: Set to 60 seconds, allowing for potentially longer response times when communicating between different components.- Headers: Similar to the service API client, it includes user-agent and Blocklet Server version headers.
paramsSerializer
: Usesqs.stringify
for serializing URL parameters.
Request Signing:
This client also employs a request interceptor to sign outgoing requests, ensuring secure communication between components. The signature headers are similar to the Blocklet Service API client but are prefixed with x-component-
:
x-component-did
: The DID of the component making the request.x-component-sig
: The cryptographic signature of the request payload.x-component-sig-iat
: The "issued at" timestamp of the signature.x-component-sig-exp
: The expiration timestamp of the signature.x-component-sig-version
: The version of the signature algorithm used.
import axios from 'axios';
import { serverVersion } from '@blocklet/env';
import qs from 'qs';
import { getSignData } from './verify-sign';
const componentApi = axios.create({
timeout: 60 * 1000,
headers: {
'User-Agent': `BlockletSDK/${serverVersion}`,
'x-blocklet-server-version': serverVersion,
},
paramsSerializer: (params) => qs.stringify(params),
});
componentApi.interceptors.request.use((config) => {
const { sig, exp, iat, version } = getSignData({
data: config.data,
method: config.method,
params: config.params,
url: config.url,
});
config.headers['x-component-did'] = process.env.BLOCKLET_COMPONENT_DID;
config.headers['x-component-sig'] = sig;
config.headers['x-component-sig-iat'] = iat;
config.headers['x-component-sig-exp'] = exp;
config.headers['x-component-sig-version'] = version;
return config;
});
export default componentApi;
Request Signing Mechanism#
Both internal API clients leverage the verify-sign
utility to cryptographically sign outgoing requests. This mechanism is crucial for establishing trust and ensuring the integrity of communication within the Blocklet ecosystem. The getSignData
function prepares the data to be signed and generates the signature using the Blocklet's designated wallet.
Signed Data Components:
The data included in the signature calculation typically consists of the following components:
iat
(Issued At): A timestamp indicating when the signature was created.exp
(Expiration): A timestamp indicating when the signature expires, usually 5 minutes afteriat
.body
: The request body (parsed as a JSON object).query
: The URL query parameters (parsed as a JSON object).method
: The HTTP method of the request (e.g.,get
,post
), converted to lowercase.url
: The pathname of the request URL.
const getSignData = (
{
data,
params,
method,
url,
}: {
data: object;
params: object;
method: string;
url: string;
},
signOptions?: object
) => {
const iat = Math.floor(Date.now() / 1000);
const exp = iat + 60 * 5; // Expires in 5 minutes
const raw: SignSeed = {
iat,
exp,
};
const tmp = parseURL(url);
raw.body = JSON.parse(JSON.stringify(data ?? {}));
raw.query = qs.parse(qs.stringify(merge(qs.parse(tmp.search.slice(1)), params ?? {})));
raw.method = method.toLowerCase();
raw.url = tmp.pathname;
const sig = sign(raw, signOptions);
const version = SIG_VERSION.DEFAULT;
return {
sig,
iat,
exp,
version,
raw,
};
};
Signing Process Flow:
This diagram illustrates how the Blocklet SDK's internal API clients intercept requests, sign them using the verify-sign
utility, and then send them to the Blocklet Server or other Blocklets for secure processing.
These internal API clients are fundamental to the Blocklet SDK's ability to interact securely and reliably with the broader Blocklet Server infrastructure. Their robust design, including automatic request signing, underpins the security model of decentralized applications built on Blocklet Server.
To understand the shared constants and type definitions that these clients use, proceed to the Constants & Types section.