TypeScript client libraries for interacting with a Nillion cluster.
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Complete examples are available at examples/react or examples/nextjs.
Ensure you are running nillion-devnet
in another terminal window
Add Nillion dependencies to a your React / nextjs project
npm i -P @nillion/client-react-hooks@latest
You have to add certain HTTP headers: adjust your webpack
/ next.config.mjs
configration. Please refer to the React webpack example or the nextjs example
Create a client to interact with the local devnet:
Note: If network: NamedNetwork.enum.Devnet
is provided, then we don't need to specify bootnodes, cluster or chain since these values are copied from the partial configuration provided.
const client = NillionClient.create({
network: NamedNetwork.enum.Devnet,
overrides: async () => {
// this is the account's private key when running `nillion-devnet` with default seed
const signer = await createSignerFromKey("9a975f567428d054f2bf3092812e6c42f901ce07d9711bc77ee2cd81101f42c5");
return {
endpoint: "http://localhost:3000/nilchain",
signer,
userSeed: "nillion-devnet",
};
}
})
NillionClientProvider
:export function App() {
return (
<NillionClientProvider client={client}>
<Home />
</NillionClientProvider>
);
}
export default function Home() {
const [id, setId] = useState("");
const storeValue = useStoreValue();
if (storeValue.data && !id) {
setId(storeValue.data);
}
const handleStoreClick = () => {
storeValue.mutate({
values: {
foo: 42,
},
ttl: 1,
});
};
return (
<div>
<h2>Hello 👋</h2>
<p>Data: {JSON.stringify(data)}</p>
<button onClick={handleStoreClick} disabled={storeValue.isPending}>Store</button>
<ul>
<li>Status: {storeValue.status}</li>
{id && <li>Id: {id}</li>}
</ul>
</div>
);
}
After a few seconds you should see Status: succcess
and Id: <uuid>
rendered. Congratulations, now you can interact with the client. 🎉
Photon
testnet by switching network
to Photon
, then, you are only required to provide a user-seed
Photon
configurations are available as well.
This guide focuses on @nillion/client-vms
and @nillion/client-react-hooks
-- other libraries are not intended for direct consumption by the end user.
@nillion/client-wasm
a wasm bundle and web worker for communicating with the cluster@nillion/client-core
manages wasm initialization and provides a wrapper for wasm functionality@nillion/client-payments
the nilchain gRPC client@nillion/client-vms
combines functionality from client-core
and client-payments
into a single user-facing API@nillion/client-react-hooks
based on ReactQuery: this package provides convenience react hooks for building frontend appsgraph BT
core["@nillion/client-core"] --> wasm["@nillion/client-wasm"]
payments["@nillion/client-payments"] --> core["@nillion/client-core"]
client["@nillion/client-vms"] --> payments["@nillion/client-payments"]
client["@nillion/client-vms"] --> core["@nillion/client-core"]
react["@nillion/client-react-hooks"] --> core["@nillion/client-core"]
react["@nillion/client-react-hooks"] --> client["@nillion/client-vms"]
There are three phases to preparing a client for use:
When a NillionClient
is created connect(): Promise<boolean>
must be called before the client is used. This method will take care of steps 1 and 2 above and ensure the wasm bundle is correctly loaded and initialized.
To create a nillion client:
const config: NillionClientConfig = { ... }
const client = NillionClient(config)
A minimal config for using a nillion-devnet
:
const config = {
// if omitted defaults to Photon testnet,
network: NamedNetwork.enum.Devnet,
overrides: async () => {
const signer = await createSignerFromKey("payment-account-private-key")
return {
signer,
// webpack devserver address proxied to nilchain
endpoint: "http://localhost:8080/nilchain",
userSeed: "unique-user-seed",
}
}
}
Note: Beware of key precedence (highest to lowest):
NillionClientConfig
object passed to NillionClient.create({ ... })
NamedNetwork
configurationQuick Start provides the details to get started. This section builds on it and provides more details on the React hooks exported from @nillion/client-react-hooks
.
NillionClientProvider
provides a NillionClient
instance to child components through the useNillion()
hook. It takes care of asynchronously connecting the client to the network and creating a ReactQuery
client and provider. If an existing ReactQuery
provider is detected it will be reused.
The following hooks are React Query-based:
useFetchValue()
useFetchPermissions()
useFetchProgramOutput()
The following hooks are React Mutation-based:
useStoreValue()
useSetPermissions()
useUpdateValue()
useStoreProgram()
useRunProgram()
Hooks accept an options
object and a React query
or mutation
overrides
an object. For example:
const fetch = useFetchValue(
// options object
{
id,
name: "foo",
type: NadaValueType.enum.SecretString,
},
// react query overrides
{
refetch: false
});
Logging is on by default for all networks except Photon
. To enable it for Photon
:
nillion:*
namespace: const config: NillionClientConfig = { overrides: () => ({ logging : true }) }
or invoke the global helper: window.__NILLION.enableLogging()
; ornillion:*
in your localStorage debug key: localStorage.debug = "foo:*,nillion:*"
.Disable logging with window.__NILLION.disableLogging()
or remove nillion:*
from localStorage.debug
. You may need to reload the window for changes to take effect.
Wasm logging is also an option, but not enabled by default. To enable it:
websocat -s 11100
window__NILLION.enableWasmLogging()
The @nillion/client-react-hooks
and @nillion/client-vms
packages provide convenience functions for storing nada types.
type NadaPrimitiveValue = Uint8Array | string | bigint | number
type StoreValueArgs = {
data: NadaPrimitiveValue,
secret: boolean
}
type values = Record<NamedValue | string, NadaPrimitiveValue | StoreValueArgs>
client.store({
values: {
foo: 42
},
ttl: 1
})
The values
object is converted into a Nada type as follows:
Primitive | Nada Type |
---|---|
number |
SecretInteger |
bigint |
SecretIntegerUnsigned |
string |
SecretBlob |
Uint8Array |
SecretBlob |
To create a public value provide StoreValueArgs
:
const values = {
foo: {
data: 42,
secret: false
}
}
Ask for help in the Nillion Github Discussions, or if you've found a bug with client-ts
, file an issue.