antd_client 0.1.0
antd_client: ^0.1.0 copied to clipboard
Dart client for the antd daemon - REST and gRPC access to the Autonomi decentralized storage network (public and private data, chunks, files, external-signer uploads).
antd_client (antd-dart) #
Dart SDK for the antd daemon — the gateway to the Autonomi decentralized network.
Published on pub.dev as antd_client.
Installation #
dart pub add antd_client
Or add to your pubspec.yaml:
dependencies:
antd_client: ^0.1.0
Compatibility #
This package talks to a running antd daemon; it does not join the network itself. Dart 3.0+. Tested against antd 0.13.x. Both the REST client (AntdClient) and the gRPC client (GrpcAntdClient) are included; the gRPC stubs are pre-generated, so protoc is only needed if you regenerate them.
Quick Start #
import 'dart:convert';
import 'dart:typed_data';
import 'package:antd_client/antd_client.dart';
void main() async {
final client = AntdClient();
try {
// Check daemon health
final health = await client.health();
print('OK: ${health.ok}, Network: ${health.network}');
// Store data
final result = await client.dataPutPublic(
Uint8List.fromList(utf8.encode('Hello, Autonomi!')),
);
print('Stored at ${result.address} (chunks: ${result.chunksStored})');
// Retrieve data
final data = await client.dataGetPublic(result.address);
print('Retrieved: ${utf8.decode(data)}');
} on AntdError catch (e) {
print('Error: $e');
} finally {
client.close();
}
}
Payment Mode #
All *put* and *cost* operations accept a PaymentMode parameter that
controls how on-chain payments for stored chunks are bundled:
| Mode | Behavior |
|---|---|
PaymentMode.auto (default) |
Daemon picks merkle for large uploads, single for small. |
PaymentMode.merkle |
One on-chain transaction with a merkle proof covering all chunks. Cheaper for large uploads. Requires ≥2 chunks. |
PaymentMode.single |
N transactions, one per chunk. Works for any chunk count. |
final result = await client.filePut('/tmp/big.bin', paymentMode: PaymentMode.merkle);
gRPC Transport #
The SDK includes a GrpcAntdClient class that provides the same async
methods as the REST AntdClient, but communicates over gRPC.
Setup #
Add the gRPC dependencies (already included in pubspec.yaml):
dependencies:
grpc: ^4.0.1
protobuf: ^4.1.0
Generate the Dart protobuf/gRPC stubs from the proto definitions:
# Install the Dart protoc plugin (pin to 22.x — newer plugins emit code
# targeting protobuf 6+, which conflicts with web3dart's transitive deps).
dart pub global activate protoc_plugin 22.3.0
# Generate stubs into lib/src/generated/
./tool/generate_proto.sh
Usage #
import 'dart:convert';
import 'dart:typed_data';
import 'package:antd_client/src/grpc_client.dart';
void main() async {
final client = GrpcAntdClient.withChannel();
// Or custom host/port:
// final client = GrpcAntdClient(host: 'my-host', port: 50051);
try {
final health = await client.health();
print('OK: ${health.ok}, Network: ${health.network}');
final result = await client.dataPutPublic(
Uint8List.fromList(utf8.encode('Hello via gRPC!')),
);
print('Stored at ${result.address}');
final data = await client.dataGetPublic(result.address);
print('Retrieved: ${utf8.decode(data)}');
} on AntdError catch (e) {
print('Error: $e');
} finally {
await client.close();
}
}
The GrpcAntdClient throws the same AntdError hierarchy as the REST client,
translating gRPC status codes to the appropriate error subclass.
Note: Wallet operations (address, balance, approve) are REST-only. The gRPC
PutDataResponse/PutPublicDataResponsemessages only carry the address/dataMap;chunksStored/paymentModeUsedare populated by REST only.
Prerequisites #
The antd daemon must be running. Start it with:
ant dev start
Configuration #
// Default: http://localhost:8082, 5 minute timeout
final client = AntdClient();
// Custom URL
final client = AntdClient(baseUrl: 'http://custom-host:9090');
// Custom timeout
final client = AntdClient(timeout: Duration(seconds: 30));
// Custom HTTP client (e.g. for testing)
final client = AntdClient(httpClient: myHttpClient);
API Reference #
All methods return Future<T> and can throw AntdError subclasses.
The unqualified verb (dataPut, filePut, dataGet, fileGet) is the
private variant — DataMaps are returned to the caller and not stored
on-network. The *Public variants store the DataMap on-network and return
a shareable address.
Health #
| Method | Description |
|---|---|
health() |
Check daemon status |
Data #
| Method | Description |
|---|---|
dataPutPublic(data, {paymentMode}) |
Store public data — returns DataPutPublicResult (DataMap stored on-network) |
dataGetPublic(address) |
Retrieve public data by address |
dataPut(data, {paymentMode}) |
Store encrypted private data — returns DataPutResult (DataMap returned to caller) |
dataGet(dataMap) |
Retrieve private data using a caller-held DataMap |
dataCost(data, {paymentMode}) |
Estimate storage cost — returns UploadCostEstimate with size, chunks, gas, payment mode |
Chunks #
| Method | Description |
|---|---|
chunkPut(data) |
Store a raw chunk |
chunkGet(address) |
Retrieve a chunk |
prepareChunkUpload(data) |
External-signer prepare step |
finalizeChunkUpload(uploadId, txHashes) |
External-signer finalize step |
Files #
| Method | Description |
|---|---|
filePut(path, {paymentMode}) |
Upload a file privately — returns FilePutResult (DataMap returned to caller) |
fileGet(dataMap, destPath) |
Download a private file using a caller-held DataMap |
filePutPublic(path, {paymentMode}) |
Upload a file publicly — returns FilePutPublicResult (DataMap stored on-network) |
fileGetPublic(address, destPath) |
Download a public file by address |
fileCost(path, {isPublic, paymentMode}) |
Estimate upload cost — returns UploadCostEstimate with size, chunks, gas, payment mode |
Error Handling #
All errors extend AntdError which implements Exception:
try {
final data = await client.dataGetPublic(address);
} on NotFoundError catch (e) {
print('Data not found on network');
} on PaymentError catch (e) {
print('Insufficient funds');
} on AntdError catch (e) {
print('Error ${e.statusCode}: ${e.message}');
}
| Error Type | HTTP Status | When |
|---|---|---|
BadRequestError |
400 | Invalid parameters |
PaymentError |
402 | Insufficient funds |
NotFoundError |
404 | Resource not found |
AlreadyExistsError |
409 | Resource exists |
ForkError |
409 | Version conflict |
TooLargeError |
413 | Payload too large |
InternalError |
500 | Server error |
NetworkError |
502 | Network unreachable |
Examples #
See the example/ directory:
01_connect— Health check02_data— Public data storage and retrieval03_chunks— Raw chunk operations04_files— File upload/download (public)06_private_data— Private encrypted data storage07_external_signer— File + chunk upload via external signer