@donezone/client
v0.1.16
Published
Client-side helpers for interacting with the Done execution stack from browsers or Node. The package mirrors the structure of the backend `Done` API—contract calls are described as HTTP-style requests, wrapped into CosmWasm messages, packed into auth enve
Readme
@donezone/client
Client-side helpers for interacting with the Done execution stack from browsers or Node. The package mirrors the structure of the backend Done API—contract calls are described as HTTP-style requests, wrapped into CosmWasm messages, packed into auth envelopes, and finally submitted to the Done HTTP gateway.
Features
- Envelope utilities (
buildEnvelope,toSignDoc,signDocDigest) that follow the router’s signing rules. - Done HTTP-aware transport via
DoneBackendClientfor/query,/tx, and quota inspection. - Contract helpers for building
WasmMsg::Executepayloads from HTTP-like routes, reusing the ergonomics of theDoneruntime.
Usage
High-level Done facade
import {
Done,
createPasskeyEnvelopeBuilder,
signDocDigest,
} from "@donezone/client";
Done.config({
doneHttp: "https://doneHttp.done.zone",
doneEvents: "https://doneEvents.done.zone",
signer: createPasskeyEnvelopeBuilder({
userId: "user-1",
nonce: async () => Number(new Date()),
expiresAt: () => Math.floor(Date.now() / 1000) + 300,
publicKey: () => storedPasskey.publicKey,
sign: async (signDoc) => {
const digest = signDocDigest(signDoc);
return await signWithPasskeyHardware(digest); // returns Uint8Array or base64
},
}),
});
await Done.run("/done1contract123/buy", {
body: { minAmountOut: "1" },
funds: { uusd: "100" },
memo: "demo purchase",
});
const price = await Done.query("/done1contract123/price");
const stop = Done.subscribe(
"/done1contract123/events",
"PriceChange",
(event) => {
console.log("new price", event.newPrice);
}
);
// later…
stop();
// Contract-specific helper using just the address
const sale = Done.contract("done1contract123");
await sale.run("/buy", { body: { minAmountOut: "1" }, funds: { uusd: "100" } });
const priceAgain = await sale.query("/price");Need a scoped client or different signer? Spawn another instance:
const staging = Done.create({
doneHttp: "https://doneHttp.staging.zone",
doneEvents: "https://doneEvents.staging.zone",
signer: createPasskeyEnvelopeBuilder({...}),
});
await staging.run("/done1contractABC/buy", { body: { minAmountOut: "5" }, funds: { uusd: "250" } });You can still work with contract handles when you need per-contract hooks:
const sale = Done.contract({
baseUrl: "https://doneHttp.done.zone",
address: "done1contract123",
});
const recent = await sale.get("/orders", { query: { limit: 10 } }).json();Lower-level building blocks
import {
DoneBackendClient,
buildEnvelope,
signDocDigest,
toSignDoc,
} from "@donezone/client";
const backend = new DoneBackendClient({ baseUrl: "https://doneHttp.example" });
const contract = backend.contract("done1contract...");
const call = contract.transaction("/buy", {
body: { minAmountOut: "1" },
gasLimit: 500_000,
});
const envelope = buildEnvelope({
user_id: "user-1",
msgs: [call.msg],
nonce: 42,
expires_at: Math.floor(Date.now() / 1000) + 300,
role: "Passkey",
metadata: call.metadata,
});
const signDoc = toSignDoc(envelope);
const digest = signDocDigest(signDoc);
// sign digest with passkey/session key, then attach to envelope.signatures
await backend.executeEnvelope(envelope, {
passkey: { publicKey: "..." },
memo: "demo tx",
});Server-friendly signing helpers
The exported builders (createPasskeyEnvelopeBuilder, createSessionEnvelopeBuilder) accept plain
signing callbacks, so they work in Node, Bun, or browsers alike—the caller decides how to obtain
signatures (WebAuthn, HSM, remote service, etc.). The helpers return the envelope plus any metadata
the Done HTTP transport expects, keeping public/private key plumbing outside of the library.
See packages/done-client/test/envelope.test.ts for more end-to-end examples and expected request payloads.
