Documentation Index
Fetch the complete documentation index at: https://tfh-ertugrulaypek-pop-3807-update-poh-credential-documentat.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
@worldcoin/idkit-core is the lowest-level JavaScript/TypeScript IDKit SDK.
Use it when you want full control over UI and state management or when you’re not using React.
Install
npm i @worldcoin/idkit-core
Entry points
IDKit.request(config) for uniqueness proofs
IDKit.requestWithInviteCode(config) for invite-code mode
orbLegacy, secureDocumentLegacy, documentLegacy, selfieCheckLegacy for presets
Each entry point returns a builder. Finalize it with .preset(...).
Request config
import { IDKit } from "@worldcoin/idkit-core";
const builder = IDKit.request({
app_id: "app_xxxxx",
action: "my-action",
rp_context: {
rp_id: "rp_xxxxx",
nonce: "0x...",
created_at: 1735689600,
expires_at: 1735689900,
signature: "0x...",
},
allow_legacy_proofs: true,
environment: "production", // Only set this to staging for testing with the simulator
return_to: "myapp://verify-done", // Optional: mobile deep-link callback URL
bridge_url: undefined, // Optional: custom bridge URL
});
Generate rp_context in your backend only. Never expose your RP signing key in client code.
Presets
import { IDKit, orbLegacy } from "@worldcoin/idkit-core";
const request = await IDKit.request({
app_id: "app_xxxxx",
action: "my-action",
rp_context,
allow_legacy_proofs: true,
}).preset(orbLegacy({ signal: "user-123" }));
Polling and status
After .preset(...), you get an IDKitRequest object:
connectorURI
requestId
pollOnce()
pollUntilCompletion({ pollInterval, timeout })
import { IDKitErrorCodes } from "@worldcoin/idkit-core";
const completion = await request.pollUntilCompletion({
pollInterval: 2_000,
timeout: 120_000,
});
if (!completion.success) {
if (completion.error === IDKitErrorCodes.Timeout) {
// UI timeout handling
}
if (completion.error === IDKitErrorCodes.Cancelled) {
// User/app cancellation handling
}
}
When running inside World App, native transport is used and connectorURI may be empty.
Outside World App, connectorURI is the URL you render as a QR code.
Invite-code mode
Use IDKit.requestWithInviteCode(config) to open a landing page that displays both an invite code and a QR code. Validation, the returned Status shape, and the poll loop are identical to IDKit.request. See Invite-code mode for when to use it.
import { IDKit, selfieCheckLegacy } from "@worldcoin/idkit-core";
const request = await IDKit.requestWithInviteCode({
app_id: "app_xxxxx",
action: "my-action",
rp_context,
allow_legacy_proofs: true,
}).preset(selfieCheckLegacy({ signal: "user-123" }));
const connectorURI = request.connectorURI; // URL with &c=<code>&a=<app_id>
const expiresAt = request.expiresAt; // Unix seconds
const completion = await request.pollUntilCompletion();
IDKitInviteCodeRequest exposes:
connectorURI
expiresAt
requestId
pollOnce()
pollUntilCompletion({ pollInterval, timeout })
Migrating from QR / connect-URL
// Before — QR / connect-URL flow
const request = await IDKit.request({
app_id: "app_xxxxx",
action: "my-action",
rp_context,
allow_legacy_proofs: true,
}).preset(orbLegacy({ signal: "user-123" }));
const connectorURI = request.connectorURI; // render as QR
const completion = await request.pollUntilCompletion();
// After — invite-code mode
const request = await IDKit.requestWithInviteCode({
app_id: "app_xxxxx",
action: "my-action",
rp_context,
allow_legacy_proofs: true,
}).preset(selfieCheckLegacy({ signal: "user-123" }));
const connectorURI = request.connectorURI; // display to user (URL with code embedded)
const expiresAt = request.expiresAt; // drive a countdown
const completion = await request.pollUntilCompletion();
The config object is unchanged. The connectorURI now includes &c=<code>&a=<app_id> params; use it alongside expiresAt in your UI. Polling, proof verification, and nullifier storage stay the same.
Server-side helpers
Use subpath exports on your backend:
import { signRequest } from "@worldcoin/idkit-core/signing";
import { hashSignal } from "@worldcoin/idkit-core/hashing";
const { sig, nonce, createdAt, expiresAt } = signRequest({
signingKeyHex: process.env.RP_SIGNING_KEY!,
action: "my-action",
ttl: 300, // optional, default 300s
});
const signalHash = hashSignal("user-123");
signRequest should only run in trusted server environments. See RP Signatures for the full algorithm and test vectors.
Related pages