diff --git a/js/packages/core/README.md b/js/packages/core/README.md index 494f4d1f..c4ed1b0e 100644 --- a/js/packages/core/README.md +++ b/js/packages/core/README.md @@ -1,6 +1,6 @@ # @worldcoin/idkit-core -World ID verification SDK for JavaScript/TypeScript. Zero dependencies, WASM-powered. +World ID verification SDK for JavaScript/TypeScript. ## Installation @@ -8,6 +8,115 @@ World ID verification SDK for JavaScript/TypeScript. Zero dependencies, WASM-pow npm install @worldcoin/idkit-core ``` +## Quickstart + +### Requirements + +From the [Developer Portal](https://developer.world.org): `app_id`, `rp_id`, and an RP signing key. Keep the signing key on your backend only. + +There are two ways you can request proofs with IDKit, and they depend on how you want to use the SDK. + +If you want to request a World ID session-scoped proof, use `IDKit.createSession()` and store the result `session_id`. You can then use `IDKit.proveSession` with `session_id` as a parameter to log and sync existing users with their session data. + +```js +import { IDKit } from "@worldcoin/idkit-core"; + +const rp_context = await fetch("/api/rp-signature").then((r) => r.json()); + +// First visit — mint a session_id and store it server-side +const IDKitSessionRequest = await IDKit.createSession({ + app_id: "app_xxxxx", + rp_context, // pass through from your backend +}).constraints(IDKit.CredentialRequest("proof_of_human")); // → IDKitRequest + +const result = await IDKitSessionRequest.pollUntilCompletion(); +// → { success: true, result: IDKitResultSession } | { success: false, error } +if (!result.success) { + // user rejected, timeout, etc. — no result to read + console.error(result.error); + return; +} +// IDKitResultSession: { +// protocol_version: "4.0", +// session_id: "session_", +// nonce: string, +// responses: [{ identifier, proof, session_nullifier, ... }], +// environment: string, +// ... +// } +// verify on your backend first, then save result.result.session_id in your DB +``` + +```js +// Return visit — look up that session_id, then prove it +const rp_context = await fetch("/api/rp-signature").then((r) => r.json()); + +const IDKitSessionRequest = await IDKit.proveSession(savedSessionId, { + app_id: "app_xxxxx", + rp_context, // pass through from your backend +}).constraints(IDKit.CredentialRequest("proof_of_human")); // → IDKitRequest + +const result = await IDKitSessionRequest.pollUntilCompletion(); +if (!result.success) { + console.error(result.error); + return; +} +// same shape as createSession — result.result.session_id matches for the same user +// verify on your backend before treating the login as complete +``` + +If you want to request a credential based on an action-key scope, use `IDKit.request()` and store the nullifier. + +```js +const rp_context = await fetch("/api/rp-signature").then((r) => r.json()); + +const request = await IDKit.request({ + app_id: "app_xxxxx", + action: "my-action", + rp_context, // pass through from your backend + allow_legacy_proofs: false, +}).constraints(IDKit.CredentialRequest("proof_of_human")); // → IDKitRequest + +const completion = await request.pollUntilCompletion(); +if (!completion.success) { + console.error(completion.error); + return; +} +// IDKitResult (v4 uniqueness): { +// protocol_version: "4.0", +// action: string, +// nonce: string, +// responses: [{ identifier, proof, nullifier, ... }], +// environment: string, +// ... +// } +// send completion.result to your backend → /api/v4/verify/{rp_id} +// only then store the nullifier; same person + same action = reject on return +``` + +### Handling the result + +Result should always be handled in the backend. A good practice is to have a dedicated `/api/verify` route file where you have some form of the following: + +```typescript +import type { IDKitResult } from "@worldcoin/idkit-core"; + +// proof = completion.result from pollUntilCompletion() +async function verifyProof(proof: IDKitResult, rpId: string) { + const response = await fetch( + `https://developer.world.org/api/v4/verify/${rpId}`, + { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(proof), + }, + ); + + const { success } = await response.json(); + return success; +} +``` + ## Script Tag / CDN The package also publishes a browser global build at @@ -33,17 +142,11 @@ browser global; generate RP signatures on your backend with