Endpoint lifecycle
Create and persist an identity, own a React Native endpoint with useMinip2p, and coordinate AppState and shutdown.
A React Native Minip2p object owns one native endpoint. Its identity, driver,
events, pending Promises, and streams all share that lifetime.
Identity first
The secret key is the node’s identity. Generate it once, store the raw 32 bytes in platform-appropriate secure storage, and supply the same bytes on later launches when the app needs a stable peer ID.
import {
generateSecretKey,
peerIdFromSecretKey,
} from "@minip2p/react-native";
const secretKey = generateSecretKey();
const peerId = peerIdFromSecretKey(secretKey);
peerIdFromSecretKey derives the public peer identity without starting an
endpoint. Treat secretKey as credentials: do not log it, transmit it, or put
it in ordinary preferences.
Prefer the lifecycle hook
useMinip2p is the normal component API. It starts in starting, then exposes
the endpoint only after native construction succeeds.
const node = useMinip2p(createConfig);
switch (node.status) {
case "starting":
return <LoadingView />;
case "failed":
return <ErrorView error={node.error} />;
case "closed":
return <ClosedView />;
case "running":
return <PeerView endpoint={node.endpoint} peerId={node.peerId} />;
}
| Status | Available state |
|---|---|
starting |
Native construction is scheduled after commit. |
running |
endpoint, peerId, and the initial listenAddrs. |
closed |
The endpoint closed normally. |
failed |
Construction failed or the native driver stopped unexpectedly. |
Every state also carries an idempotent close() callback. Component cleanup
unbinds AppState and closes the endpoint automatically.
Foreground and background
The hook immediately mirrors the current React Native AppState and keeps it
in sync:
activeselects foreground polling;- every other state selects the native idle behavior.
This changes driver cadence; it does not destroy the endpoint. When the app returns to the foreground, the same endpoint resumes active polling.
If the endpoint is not component-owned, bind and release AppState manually:
import {
Minip2p,
bindAppState,
generateSecretKey,
} from "@minip2p/react-native";
const endpoint = Minip2p.create({
secretKey: generateSecretKey(),
});
const unbindAppState = bindAppState(endpoint);
// Later, in the owner's cleanup path:
unbindAppState();
endpoint.close();
bindAppState applies the current state before it subscribes to later changes.
Close is terminal
endpoint.close() is idempotent. It:
- rejects pending Promise operations;
- closes owned
Streamhandles; - stops and destroys the native endpoint;
- invokes each
onCloseobserver once.
const removeClose = endpoint.onClose((reason) => {
if (reason.reason === "driverFailed") {
console.error(reason.error.kind, reason.error.message);
}
});
endpoint.close();
removeClose();
Use isDriverFailure(node) to narrow a failed hook state to
DriverFailedError when the UI needs the machine-readable failure kind.
Public SDK boundary
Application code should import from @minip2p/react-native. That package
re-exports the platform-neutral high-level types from @minip2p/core.
The generated UniFFI surface at @minip2p/react-native/native and the adapter
contract at @minip2p/core/backend are low-level integration APIs. They expose
native lifecycle details and raw tagged unions; ordinary applications should
not use them.
Next: Connections and streams.