@worldcoin/idkit-core 4.0.1-dev.123c6a8 → 4.0.1-dev.370b7c0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -146
- package/dist/hashing.cjs +28 -0
- package/dist/hashing.d.cts +9 -0
- package/dist/hashing.d.ts +9 -0
- package/dist/hashing.js +26 -0
- package/dist/idkit_wasm_bg.wasm +0 -0
- package/dist/index.cjs +712 -289
- package/dist/index.d.cts +337 -196
- package/dist/index.d.ts +337 -196
- package/dist/index.js +708 -286
- package/dist/signing.cjs +76 -0
- package/dist/signing.d.cts +36 -0
- package/dist/signing.d.ts +36 -0
- package/dist/signing.js +73 -0
- package/package.json +16 -3
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/wasm/idkit_wasm.d.ts +0 -523
- package/wasm/idkit_wasm.js +0 -1879
- package/wasm/idkit_wasm_bg.wasm +0 -0
- package/wasm/idkit_wasm_bg.wasm.d.ts +0 -54
package/README.md
CHANGED
|
@@ -1,186 +1,112 @@
|
|
|
1
1
|
# @worldcoin/idkit-core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
World ID verification SDK for JavaScript/TypeScript. Zero dependencies, WASM-powered.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install @worldcoin/idkit-core
|
|
9
|
-
# or
|
|
10
|
-
pnpm add @worldcoin/idkit-core
|
|
11
9
|
```
|
|
12
10
|
|
|
13
|
-
##
|
|
11
|
+
## Backend: Generate RP Signature
|
|
12
|
+
|
|
13
|
+
The RP signature authenticates your verification requests. Generate it server-side using the `/signing` subpath (pure JS, no WASM init needed):
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
16
|
-
import {
|
|
16
|
+
import { signRequest } from "@worldcoin/idkit-core/signing";
|
|
17
17
|
|
|
18
|
-
//
|
|
19
|
-
const
|
|
18
|
+
// Never expose RP_SIGNING_KEY to clients
|
|
19
|
+
const sig = signRequest("my-action", process.env.RP_SIGNING_KEY);
|
|
20
20
|
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
// Return to client
|
|
22
|
+
res.json({
|
|
23
|
+
sig: sig.sig,
|
|
24
|
+
nonce: sig.nonce,
|
|
25
|
+
created_at: sig.createdAt,
|
|
26
|
+
expires_at: sig.expiresAt,
|
|
26
27
|
});
|
|
27
|
-
|
|
28
|
-
// 3. Display QR code for World App
|
|
29
|
-
console.log("Scan this:", client.connectorURI);
|
|
30
|
-
|
|
31
|
-
// 4. Poll for proof (handles polling automatically)
|
|
32
|
-
try {
|
|
33
|
-
const proof = await client.pollForUpdates();
|
|
34
|
-
console.log("Success:", proof);
|
|
35
|
-
} catch (error) {
|
|
36
|
-
console.error("Verification failed:", error);
|
|
37
|
-
}
|
|
38
28
|
```
|
|
39
29
|
|
|
40
|
-
##
|
|
41
|
-
|
|
42
|
-
You can request verification with multiple credential types. The user can satisfy the request with any of them:
|
|
43
|
-
|
|
44
|
-
```typescript
|
|
45
|
-
const client = await store.createClient({
|
|
46
|
-
app_id: "app_staging_xxxxx",
|
|
47
|
-
action: "my-action",
|
|
48
|
-
requests: [
|
|
49
|
-
{ credential_type: "orb", signal: "user-id-123" },
|
|
50
|
-
{ credential_type: "device", signal: "user-id-123" },
|
|
51
|
-
],
|
|
52
|
-
});
|
|
53
|
-
```
|
|
30
|
+
## Client: Create Verification Request
|
|
54
31
|
|
|
55
|
-
|
|
32
|
+
### Using Presets
|
|
56
33
|
|
|
57
|
-
|
|
58
|
-
- `face` - Verified via Face ID
|
|
59
|
-
- `device` - Verified via device binding
|
|
60
|
-
- `document` - Verified via document scan
|
|
61
|
-
- `secure_document` - Verified via secure document scan
|
|
62
|
-
|
|
63
|
-
## API Reference
|
|
64
|
-
|
|
65
|
-
### Creating a Client
|
|
66
|
-
|
|
67
|
-
```typescript
|
|
68
|
-
const client = await store.createClient(config);
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
**Config:**
|
|
34
|
+
For common verification scenarios with World ID 3.0 backward compatibility:
|
|
72
35
|
|
|
73
36
|
```typescript
|
|
74
|
-
|
|
75
|
-
app_id: `app_${string}`; // Your World ID app ID
|
|
76
|
-
action: string; // Action identifier
|
|
77
|
-
requests: RequestConfig[]; // Required: credential type requests
|
|
78
|
-
bridge_url?: string; // Custom bridge URL (optional)
|
|
79
|
-
partner?: boolean; // Partner mode (optional)
|
|
80
|
-
}
|
|
37
|
+
import { IDKit, orbLegacy } from "@worldcoin/idkit-core";
|
|
81
38
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
signal?: string | AbiEncodedValue; // Optional signal for this request
|
|
85
|
-
}
|
|
39
|
+
// Fetch signature from your backend
|
|
40
|
+
const rpSig = await fetch("/api/rp-signature").then((r) => r.json());
|
|
86
41
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
42
|
+
const request = await IDKit.request({
|
|
43
|
+
app_id: "app_xxxxx",
|
|
44
|
+
action: "my-action",
|
|
45
|
+
rp_context: {
|
|
46
|
+
rp_id: "rp_xxxxx",
|
|
47
|
+
nonce: rpSig.nonce,
|
|
48
|
+
created_at: rpSig.created_at,
|
|
49
|
+
expires_at: rpSig.expires_at,
|
|
50
|
+
signature: rpSig.sig,
|
|
51
|
+
},
|
|
52
|
+
allow_legacy_proofs: false,
|
|
53
|
+
}).preset(orbLegacy({ signal: "user-123" }));
|
|
54
|
+
|
|
55
|
+
// Display QR code for World App
|
|
56
|
+
const qrUrl = request.connectorURI;
|
|
93
57
|
```
|
|
94
58
|
|
|
95
|
-
**
|
|
96
|
-
|
|
97
|
-
- `connectorURI: string` - QR code URL for World App
|
|
98
|
-
- `requestId: string` - Unique request ID
|
|
59
|
+
**Available presets:** `orbLegacy`, `documentLegacy`, `secureDocumentLegacy`
|
|
99
60
|
|
|
100
|
-
|
|
61
|
+
## Handling the Result
|
|
101
62
|
|
|
102
|
-
|
|
103
|
-
- `pollOnce(): Promise<Status>` - Poll once for status (manual polling)
|
|
104
|
-
|
|
105
|
-
**WaitOptions:**
|
|
63
|
+
Poll for the verification proof, then verify it server-side:
|
|
106
64
|
|
|
107
65
|
```typescript
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
```
|
|
66
|
+
// Wait for the user to scan and approve
|
|
67
|
+
const completion = await request.pollUntilCompletion({
|
|
68
|
+
pollInterval: 2000,
|
|
69
|
+
timeout: 120_000,
|
|
70
|
+
});
|
|
114
71
|
|
|
115
|
-
|
|
72
|
+
if (!completion.success) {
|
|
73
|
+
console.error("Verification failed:", completion.error);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
116
76
|
|
|
117
|
-
|
|
118
|
-
const
|
|
77
|
+
// Send proof to your backend for verification
|
|
78
|
+
const verified = await fetch("/api/verify-proof", {
|
|
79
|
+
method: "POST",
|
|
80
|
+
headers: { "Content-Type": "application/json" },
|
|
81
|
+
body: JSON.stringify(completion.result),
|
|
82
|
+
}).then((r) => r.json());
|
|
119
83
|
```
|
|
120
84
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
- `createClient(config: IDKitConfig): Promise<WorldBridgeClient>` - Create new client
|
|
124
|
-
- `reset(): void` - Clear state and start over
|
|
125
|
-
|
|
126
|
-
**State (for reactive frameworks):**
|
|
127
|
-
|
|
128
|
-
- `verificationState: VerificationState` - Current verification state
|
|
129
|
-
- `connectorURI: string | null` - QR code URL for World App
|
|
130
|
-
- `result: ISuccessResult | null` - Proof data when verified
|
|
131
|
-
- `errorCode: AppErrorCodes | null` - Error code if failed
|
|
132
|
-
|
|
133
|
-
### Result Types
|
|
85
|
+
On your backend, forward the result to the Developer Portal:
|
|
134
86
|
|
|
135
87
|
```typescript
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
88
|
+
const response = await fetch(
|
|
89
|
+
`https://developer.worldcoin.org/api/v4/verify/${RP_ID}`,
|
|
90
|
+
{
|
|
91
|
+
method: "POST",
|
|
92
|
+
headers: { "Content-Type": "application/json" },
|
|
93
|
+
body: JSON.stringify(req.body),
|
|
94
|
+
},
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const { success } = await response.json();
|
|
142
98
|
```
|
|
143
99
|
|
|
144
|
-
##
|
|
145
|
-
|
|
146
|
-
```tsx
|
|
147
|
-
import { useWorldBridgeStore, IDKitWidget } from "@worldcoin/idkit-core";
|
|
148
|
-
|
|
149
|
-
function MyComponent() {
|
|
150
|
-
const handleSuccess = (result) => {
|
|
151
|
-
console.log("Verified:", result);
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
return (
|
|
155
|
-
<IDKitWidget
|
|
156
|
-
app_id="app_staging_xxxxx"
|
|
157
|
-
action="my-action"
|
|
158
|
-
requests={[{ credential_type: "orb", signal: "user-123" }]}
|
|
159
|
-
onSuccess={handleSuccess}
|
|
160
|
-
>
|
|
161
|
-
{({ open }) => <button onClick={open}>Verify with World ID</button>}
|
|
162
|
-
</IDKitWidget>
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
## Examples
|
|
168
|
-
|
|
169
|
-
See [examples/browser](../../examples/browser) for a complete working example.
|
|
100
|
+
## Subpath Exports
|
|
170
101
|
|
|
171
|
-
|
|
102
|
+
Pure JS subpath exports are available for server-side use without WASM initialization:
|
|
172
103
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
# Build TypeScript
|
|
178
|
-
npm run build:ts
|
|
104
|
+
| Subpath | Exports |
|
|
105
|
+
| ---------- | ---------------------------------------------------------------- |
|
|
106
|
+
| `/signing` | `signRequest`, `computeRpSignatureMessage`, `RpSignature` (type) |
|
|
107
|
+
| `/hashing` | `hashSignal` |
|
|
179
108
|
|
|
180
|
-
|
|
181
|
-
|
|
109
|
+
```typescript
|
|
110
|
+
import { signRequest } from "@worldcoin/idkit-core/signing";
|
|
111
|
+
import { hashSignal } from "@worldcoin/idkit-core/hashing";
|
|
182
112
|
```
|
|
183
|
-
|
|
184
|
-
## License
|
|
185
|
-
|
|
186
|
-
MIT
|
package/dist/hashing.cjs
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var sha3 = require('@noble/hashes/sha3');
|
|
4
|
+
var utils = require('@noble/hashes/utils');
|
|
5
|
+
|
|
6
|
+
// src/lib/hashing.ts
|
|
7
|
+
function hashToField(input) {
|
|
8
|
+
const hash = BigInt("0x" + utils.bytesToHex(sha3.keccak_256(input))) >> 8n;
|
|
9
|
+
return utils.hexToBytes(hash.toString(16).padStart(64, "0"));
|
|
10
|
+
}
|
|
11
|
+
function hashSignal(signal) {
|
|
12
|
+
let input;
|
|
13
|
+
if (signal instanceof Uint8Array) {
|
|
14
|
+
input = signal;
|
|
15
|
+
} else if (signal.startsWith("0x") && isValidHex(signal.slice(2))) {
|
|
16
|
+
input = utils.hexToBytes(signal.slice(2));
|
|
17
|
+
} else {
|
|
18
|
+
input = new TextEncoder().encode(signal);
|
|
19
|
+
}
|
|
20
|
+
return "0x" + utils.bytesToHex(hashToField(input));
|
|
21
|
+
}
|
|
22
|
+
function isValidHex(s) {
|
|
23
|
+
if (s.length === 0) return false;
|
|
24
|
+
if (s.length % 2 !== 0) return false;
|
|
25
|
+
return /^[0-9a-fA-F]+$/.test(s);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
exports.hashSignal = hashSignal;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hashes a signal to its field element hex representation.
|
|
3
|
+
*
|
|
4
|
+
* @param signal - The signal to hash (string or Uint8Array)
|
|
5
|
+
* @returns 0x-prefixed hex string representing the signal hash
|
|
6
|
+
*/
|
|
7
|
+
declare function hashSignal(signal: string | Uint8Array): string;
|
|
8
|
+
|
|
9
|
+
export { hashSignal };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hashes a signal to its field element hex representation.
|
|
3
|
+
*
|
|
4
|
+
* @param signal - The signal to hash (string or Uint8Array)
|
|
5
|
+
* @returns 0x-prefixed hex string representing the signal hash
|
|
6
|
+
*/
|
|
7
|
+
declare function hashSignal(signal: string | Uint8Array): string;
|
|
8
|
+
|
|
9
|
+
export { hashSignal };
|
package/dist/hashing.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { keccak_256 } from '@noble/hashes/sha3';
|
|
2
|
+
import { hexToBytes, bytesToHex } from '@noble/hashes/utils';
|
|
3
|
+
|
|
4
|
+
// src/lib/hashing.ts
|
|
5
|
+
function hashToField(input) {
|
|
6
|
+
const hash = BigInt("0x" + bytesToHex(keccak_256(input))) >> 8n;
|
|
7
|
+
return hexToBytes(hash.toString(16).padStart(64, "0"));
|
|
8
|
+
}
|
|
9
|
+
function hashSignal(signal) {
|
|
10
|
+
let input;
|
|
11
|
+
if (signal instanceof Uint8Array) {
|
|
12
|
+
input = signal;
|
|
13
|
+
} else if (signal.startsWith("0x") && isValidHex(signal.slice(2))) {
|
|
14
|
+
input = hexToBytes(signal.slice(2));
|
|
15
|
+
} else {
|
|
16
|
+
input = new TextEncoder().encode(signal);
|
|
17
|
+
}
|
|
18
|
+
return "0x" + bytesToHex(hashToField(input));
|
|
19
|
+
}
|
|
20
|
+
function isValidHex(s) {
|
|
21
|
+
if (s.length === 0) return false;
|
|
22
|
+
if (s.length % 2 !== 0) return false;
|
|
23
|
+
return /^[0-9a-fA-F]+$/.test(s);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { hashSignal };
|
package/dist/idkit_wasm_bg.wasm
CHANGED
|
Binary file
|