Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions js/examples/browser/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# IDKit Browser Example

A simple browser example demonstrating World ID verification using IDKit 4.0.
A simple browser example demonstrating World ID verification using the IDKit core package.

## Usage

Expand All @@ -20,12 +20,12 @@ cd js/examples/browser
pnpm dev
```

Open http://localhost:5173 in your browser (Vite will auto-open it)
Open http://localhost:4000 in your browser (Vite will auto-open it)

#### Production

The example already uses the `@worldcoin/idkit` import. In production, install the package:
The example uses `@worldcoin/idkit-core` for pure TypeScript/browser usage. In production:

```bash
npm install @worldcoin/idkit
npm install @worldcoin/idkit-core
```
39 changes: 19 additions & 20 deletions js/examples/browser/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ <h3>Error</h3>
</section>

<script type="module">
// Import IDKit (alias resolves to local dist or npm package)
import { useWorldBridgeStore } from '@worldcoin/idkit';
// Import IDKit core (pure TypeScript, no dependencies)
import { createSession, initIDKit } from '@worldcoin/idkit-core';

// Demo app configuration (WASM auto-initializes on first use)
// Demo app configuration
const APP_ID = 'app_ce4cb73cb75fc3b73b71ffb4de178410'; // Replace with your actual app ID
const ACTION = 'test-action';

Expand All @@ -62,26 +62,26 @@ <h3>Error</h3>
errorDiv.hidden = true;
};

// Function to verify with World ID using explicit requests
// Initialize WASM on page load
await initIDKit();

// Function to verify with World ID using the new Session API
async function verify(requests) {
try {
hideAll();

const store = useWorldBridgeStore();
store.reset(); // Clear any previous state

statusDiv.hidden = false;
statusText.textContent = 'Creating verification request...';
statusText.textContent = 'Creating verification session...';

// createClient accepts explicit requests array
const client = await store.createClient({
// Create a new session with the requests
const session = await createSession({
app_id: APP_ID,
action: ACTION,
requests: requests,
});

// Use client.connectorURI (not store.connectorURI which is a stale snapshot)
const url = client.connectorURI;
// Get the connector URL from the session
const url = session.connectorURI;
console.log('Connect URL:', url);

qrDiv.hidden = false;
Expand All @@ -91,8 +91,8 @@ <h3>Error</h3>

statusText.textContent = 'Waiting for scan...';

// Use client.pollForUpdates() which handles polling automatically
const proof = await client.pollForUpdates({
// Poll for updates until proof is received
const proof = await session.pollForUpdates({
pollInterval: 2000, // Poll every 2 seconds
timeout: 120000, // 2 minute timeout
});
Expand All @@ -113,18 +113,17 @@ <h3>Error</h3>
// Helper to create a signal with timestamp
const makeSignal = () => 'demo-signal-' + Date.now();

//TODO: Will refactor this
// Button event listeners - using explicit requests pattern
document.getElementById('verifyOrb').addEventListener('click', () =>
// Button event listeners
document.getElementById('verifyOrb').addEventListener('click', () =>
verify([{ credential_type: 'orb', signal: makeSignal() }])
);
document.getElementById('verifyFace').addEventListener('click', () =>
document.getElementById('verifyFace').addEventListener('click', () =>
verify([{ credential_type: 'face', signal: makeSignal() }])
);
document.getElementById('verifyDevice').addEventListener('click', () =>
document.getElementById('verifyDevice').addEventListener('click', () =>
verify([{ credential_type: 'device', signal: makeSignal() }])
);

</script>
</body>
</html>
3 changes: 3 additions & 0 deletions js/examples/browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@worldcoin/idkit-core": "workspace:*"
},
"devDependencies": {
"vite": "^7.0.0"
}
Expand Down
7 changes: 0 additions & 7 deletions js/examples/browser/vite.config.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import { defineConfig } from 'vite';
import { resolve } from 'path';

export default defineConfig({
resolve: {
alias: {
// Resolve to the locally-built core package output in this monorepo.
'@worldcoin/idkit': resolve(__dirname, '../../packages/core/dist/index.js'),
},
},
server: {
port: 4000,
open: true,
Expand Down
22 changes: 2 additions & 20 deletions js/packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@worldcoin/idkit",
"name": "@worldcoin/idkit-core",
"version": "4.0.1",
"description": "Core IDKit SDK for World ID - Browser and Node.js support",
"description": "Core IDKit SDK for World ID - Pure TypeScript, no dependencies",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
Expand All @@ -11,11 +11,6 @@
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./react": {
"types": "./dist/react.d.ts",
"import": "./dist/react.js",
"require": "./dist/react.cjs"
}
},
"files": [
Expand Down Expand Up @@ -46,23 +41,10 @@
"type": "git",
"url": "https://github.com/worldcoin/idkit"
},
"dependencies": {
"zustand": "^4.5"
},
"peerDependencies": {
"react": ">=17.0.0"
},
"peerDependenciesMeta": {
"react": {
"optional": true
}
},
"devDependencies": {
"@types/node": "^20.0.0",
"@types/react": "^18.2.0",
"@vitest/coverage-v8": "^2.0.0",
"happy-dom": "^15.0.0",
"react": "^18.2.0",
"tsup": "^8.0.0",
"typescript": "^5.3.0",
"vitest": "^2.0.0"
Expand Down
61 changes: 13 additions & 48 deletions js/packages/core/src/__tests__/smoke.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@
* These tests verify that the WASM integration and core APIs are functional
*/

import { describe, it, expect, beforeAll } from 'vitest'
import { describe, it, expect } from 'vitest'
import {
initIDKit,
isInitialized,
useWorldBridgeStore,
createSession,
hashToField,
solidityEncode,
buffer_encode,
buffer_decode,
isNode,
isWeb,
AppErrorCodes,
VerificationState,
} from '../index'
Expand Down Expand Up @@ -125,57 +124,23 @@ describe('Platform Detection', () => {
})
})

describe('Bridge Store', () => {
it('should create store instance', () => {
const store = useWorldBridgeStore.getState()
expect(store).toBeDefined()
expect(store.verificationState).toBe(VerificationState.PreparingClient)
describe('Session API', () => {
it('should export createSession function', () => {
expect(typeof createSession).toBe('function')
})

it('should have correct initial state', () => {
const store = useWorldBridgeStore.getState()

expect(store.requestId).toBeNull()
expect(store.connectorURI).toBeNull()
expect(store.result).toBeNull()
expect(store.errorCode).toBeNull()
})

it('should have all required methods', () => {
const store = useWorldBridgeStore.getState()

expect(typeof store.createClient).toBe('function')
expect(typeof store.pollForUpdates).toBe('function')
expect(typeof store.reset).toBe('function')
})

it('should reset state', () => {
const store = useWorldBridgeStore.getState()
store.reset()

expect(store.verificationState).toBe(VerificationState.PreparingClient)
expect(store.requestId).toBeNull()
expect(store.connectorURI).toBeNull()
expect(store.result).toBeNull()
expect(store.errorCode).toBeNull()
})

it('should be callable both ways for v2 compatibility', () => {
// v3 style
const store1 = useWorldBridgeStore.getState()
expect(store1).toBeDefined()

// v2 style also works (returns same state outside React)
const store2 = useWorldBridgeStore() as ReturnType<typeof useWorldBridgeStore.getState>
expect(store2).toBeDefined()

// Should be the same store
expect(store1).toBe(store2)
it('should throw error when requests is empty', async () => {
await expect(
createSession({
app_id: 'app_staging_test',
action: 'test-action',
requests: [],
})
).rejects.toThrow('At least one request is required')
})
})

describe('Enums', () => {

it('should export AppErrorCodes enum', () => {
expect(AppErrorCodes.ConnectionFailed).toBe('connection_failed')
expect(AppErrorCodes.VerificationRejected).toBe('verification_rejected')
Expand Down
Loading
Loading