@fluree/client
v0.1.0
Published
Typed browser/Node client for Fluree Solo — query, transact, and Space app tokens with ledger-enforced policy
Readme
@fluree/client
Typed browser/Node client for a Fluree Solo stack. Query, transact, and mint Space app tokens — with policy enforced at the ledger, below the API. The client carries no policy logic and no privileged credential.
The model in 20 seconds
- A Space is the sandbox: its datasets, agents, grants, and policy classes define everything an app can ever touch.
- A Space app token is a scoped, non-privileged, short-lived credential into that Space. It identifies as the end user, is narrowed to (user ∩ Space), and only carries datasets with explicit policy classes — a dataset without them is excluded at mint and denied at enforcement (fail closed). Even an admin using your app is narrowed.
- API keys are intentionally unsupported. On a Fluree stack an API key is the privileged path that bypasses ledger policy; it must never ship in an app.
Usage
import { createSpaceAppClient } from "@fluree/client";
const app = createSpaceAppClient({
endpoint: "https://your-stack.example.com",
spaceId: "space-abc",
// The user's own credential — used ONLY to mint/refresh the app token.
userAuth: { tokenProvider: () => session.getToken() },
});
// Data calls ride the scoped app token, auto-refreshed before expiry.
const leads = await app.query("leads", {
"@context": { ex: "https://example.org/" },
select: { "?lead": ["*"] },
where: [{ "@id": "?lead", "@type": "ex:Lead" }],
});
await app.insert("leads", {
"@context": { ex: "https://example.org/" },
"@type": "ex:Lead",
"ex:email": "[email protected]",
"ex:campaign": "trailhead",
});
// What can this app actually reach? (renders a capability panel)
console.log(app.capabilities()?.datasets);
console.log(app.capabilities()?.excludedDatasets); // and *why* they're outFor scripts/tools with a token in hand, createFlureeClient({ endpoint,
auth: { bearer } }) gives the same surface without the Space binding.
Error handling
Every non-2xx response throws FlureeError with status and the raw body.
error.isPolicyDenial (403) is the ledger's policy saying no — that's the
governance working, not a bug in your app.
Install
npm i @fluree/clientThe only runtime dependency is zod. The package ships ESM + CJS with bundled
type declarations, and is self-contained — the contract schema types it uses
are inlined at build time.
Development
Inside the monorepo the package is consumed from source (exports →
src/index.ts); the published artifact is built separately. bun run build
emits the self-contained dist/ bundle via tsup; bun run prepare-publish
assembles the publish-ready staging directory under publish/.
