@rockerone/xprnkit 0.4.2 → 0.4.4
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
CHANGED
|
@@ -98,10 +98,12 @@ function YourComponent() {
|
|
|
98
98
|
profile,
|
|
99
99
|
identityProof,
|
|
100
100
|
identityProofStatus,
|
|
101
|
+
identityProofError,
|
|
101
102
|
connect,
|
|
102
103
|
disconnect,
|
|
103
104
|
pushTransaction,
|
|
104
105
|
switchToSession,
|
|
106
|
+
requestIdentityProof,
|
|
105
107
|
} = useXPRN();
|
|
106
108
|
|
|
107
109
|
// Use the context values and functions
|
|
@@ -120,6 +122,7 @@ The `useXPRN` hook returns an object with the following properties:
|
|
|
120
122
|
- `profile`: `XPRNKitProfile | null` - Profile data for the active session.
|
|
121
123
|
- `identityProof`: `XPRNKitIdentityProof | null` - Identity proof for the active session (when identity proof is configured).
|
|
122
124
|
- `identityProofStatus`: `XPRNKitIdentityProofStatus` - Current status of the identity proof process (`"idle"` | `"signing"` | `"verifying"` | `"validating"` | `"success"` | `"expired"` | `"error"`).
|
|
125
|
+
- `identityProofError`: `Error | null` - The error from the last failed identity proof attempt, or `null` when there is no error.
|
|
123
126
|
|
|
124
127
|
#### Methods
|
|
125
128
|
|
|
@@ -127,6 +130,7 @@ The `useXPRN` hook returns an object with the following properties:
|
|
|
127
130
|
- `disconnect()`: Disconnects the current active session.
|
|
128
131
|
- `pushTransaction(actions: any[])`: Pushes a transaction with the given actions using the active session.
|
|
129
132
|
- `switchToSession(actor: string, permission: string)`: Switches to a different stored session by restoring it from the Proton Web SDK storage.
|
|
133
|
+
- `requestIdentityProof()`: Triggers the identity proof flow (restore, sign, authenticate) for the current session. Can be used to retry after an error or to request proof on demand when `identityProof.required` is `false`.
|
|
130
134
|
|
|
131
135
|
### Basic Example
|
|
132
136
|
|
|
@@ -229,6 +233,8 @@ type XPRNKitIdentityProofConfig = {
|
|
|
229
233
|
3. If no valid proof exists, the user is prompted to sign a message in their wallet.
|
|
230
234
|
4. The signed message is sent to the `createUrl` backend endpoint for verification.
|
|
231
235
|
5. The backend returns a JWT token which is stored in localStorage and made available via `useXPRN().identityProof`.
|
|
236
|
+
6. If any step fails, `identityProofStatus` is set to `"error"` and the error is available via `useXPRN().identityProofError`.
|
|
237
|
+
7. You can call `requestIdentityProof()` to retry after a failure, or to trigger proof on demand when `required` is `false`.
|
|
232
238
|
|
|
233
239
|
## Backend Endpoints
|
|
234
240
|
|
|
@@ -280,14 +286,21 @@ Validates an existing JWT token:
|
|
|
280
286
|
Use `XPRNIdentityProofGate` to conditionally render content based on identity proof status:
|
|
281
287
|
|
|
282
288
|
```tsx
|
|
283
|
-
import { XPRNIdentityProofGate } from '@rockerone/xprnkit';
|
|
289
|
+
import { XPRNIdentityProofGate, useXPRN } from '@rockerone/xprnkit';
|
|
284
290
|
|
|
285
291
|
function ProtectedContent() {
|
|
292
|
+
const { identityProofError, requestIdentityProof } = useXPRN();
|
|
293
|
+
|
|
286
294
|
return (
|
|
287
295
|
<XPRNIdentityProofGate
|
|
288
296
|
fallback={<p>Please verify your identity to access this content.</p>}
|
|
289
297
|
loading={<p>Verifying identity...</p>}
|
|
290
|
-
error={
|
|
298
|
+
error={
|
|
299
|
+
<div>
|
|
300
|
+
<p>Verification failed: {identityProofError?.message}</p>
|
|
301
|
+
<button onClick={requestIdentityProof}>Retry</button>
|
|
302
|
+
</div>
|
|
303
|
+
}
|
|
291
304
|
notConnected={<p>Please connect your wallet first.</p>}
|
|
292
305
|
>
|
|
293
306
|
<p>This content is only visible after identity verification.</p>
|
|
@@ -13,10 +13,12 @@ type XPRNProviderContext = {
|
|
|
13
13
|
profile: XPRNKitProfile | null;
|
|
14
14
|
identityProof: XPRNKitIdentityProof | null;
|
|
15
15
|
identityProofStatus: XPRNKitIdentityProofStatus;
|
|
16
|
+
identityProofError: Error | null;
|
|
16
17
|
connect: (restore?: boolean) => void;
|
|
17
18
|
disconnect: () => Promise<void>;
|
|
18
19
|
pushTransaction: (actions: any[]) => Promise<void>;
|
|
19
20
|
switchToSession: (actor: string, permission: string) => Promise<void>;
|
|
21
|
+
requestIdentityProof: () => Promise<void>;
|
|
20
22
|
};
|
|
21
23
|
export declare const XPRNProvider: React.FunctionComponent<XPRNProviderProps>;
|
|
22
24
|
export declare function useXPRN(): XPRNProviderContext;
|
|
@@ -14,10 +14,12 @@ const XPRNContext = React.createContext({
|
|
|
14
14
|
profile: null,
|
|
15
15
|
identityProof: null,
|
|
16
16
|
identityProofStatus: "idle",
|
|
17
|
+
identityProofError: null,
|
|
17
18
|
connect: () => { },
|
|
18
19
|
disconnect: async () => { },
|
|
19
20
|
pushTransaction: async () => { },
|
|
20
21
|
switchToSession: async () => { },
|
|
22
|
+
requestIdentityProof: async () => { },
|
|
21
23
|
});
|
|
22
24
|
export const XPRNProvider = ({ children, config, }) => {
|
|
23
25
|
const [session, setSession] = useState(null);
|
|
@@ -25,6 +27,7 @@ export const XPRNProvider = ({ children, config, }) => {
|
|
|
25
27
|
const [profile, setProfile] = useState(null);
|
|
26
28
|
const [identityProof, setIdentityProof] = useState(null);
|
|
27
29
|
const [identityProofStatus, setIdentityProofStatus] = useState("idle");
|
|
30
|
+
const [identityProofError, setIdentityProofError] = useState(null);
|
|
28
31
|
const profileStorage = new XPRNKitProfileStorage();
|
|
29
32
|
const identityProofStorage = new XPRNKitIdentityStorage();
|
|
30
33
|
async function fetchProfile(session) {
|
|
@@ -144,6 +147,35 @@ export const XPRNProvider = ({ children, config, }) => {
|
|
|
144
147
|
}
|
|
145
148
|
});
|
|
146
149
|
}
|
|
150
|
+
async function processIdentityProof(session) {
|
|
151
|
+
if (!config.identityProof)
|
|
152
|
+
return;
|
|
153
|
+
try {
|
|
154
|
+
setIdentityProofError(null);
|
|
155
|
+
setIdentityProofStatus("verifying");
|
|
156
|
+
const existingIdentityProof = await restoreIdentityProof(session).catch(() => null);
|
|
157
|
+
if (existingIdentityProof) {
|
|
158
|
+
setIdentityProof(existingIdentityProof);
|
|
159
|
+
setIdentityProofStatus("success");
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
setIdentityProofStatus("signing");
|
|
163
|
+
const identityProofPayload = await createIdentityProof(session);
|
|
164
|
+
setIdentityProofStatus("verifying");
|
|
165
|
+
const proof = await fetchIdentityProof(identityProofPayload, session);
|
|
166
|
+
setIdentityProof(proof);
|
|
167
|
+
setIdentityProofStatus("success");
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
setIdentityProofStatus("error");
|
|
171
|
+
setIdentityProofError(error instanceof Error ? error : new Error(String(error)));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
const requestIdentityProof_ = useCallback(async () => {
|
|
175
|
+
if (!session)
|
|
176
|
+
return;
|
|
177
|
+
await processIdentityProof(session);
|
|
178
|
+
}, [session, config]);
|
|
147
179
|
const connect = useCallback(async (restore) => {
|
|
148
180
|
const { session, link } = await ConnectWallet({
|
|
149
181
|
linkOptions: {
|
|
@@ -167,24 +199,7 @@ export const XPRNProvider = ({ children, config, }) => {
|
|
|
167
199
|
setLink(link);
|
|
168
200
|
await fetchProfile(session);
|
|
169
201
|
if (config.identityProof && config.identityProof.required) {
|
|
170
|
-
|
|
171
|
-
setIdentityProofStatus("verifying");
|
|
172
|
-
const existingIdentityProof = await restoreIdentityProof(session).catch(() => {
|
|
173
|
-
console.log('Identity proof not found, creating new one through catch');
|
|
174
|
-
});
|
|
175
|
-
console.log('existingIdentityProof', existingIdentityProof);
|
|
176
|
-
if (!existingIdentityProof) {
|
|
177
|
-
console.log('creating identity proof');
|
|
178
|
-
const identityProofPayload = await createIdentityProof(session);
|
|
179
|
-
const identityProof = await fetchIdentityProof(identityProofPayload, session);
|
|
180
|
-
setIdentityProof(identityProof);
|
|
181
|
-
setIdentityProofStatus("success");
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
console.log('restoring identity proof');
|
|
185
|
-
setIdentityProof(existingIdentityProof);
|
|
186
|
-
setIdentityProofStatus("success");
|
|
187
|
-
}
|
|
202
|
+
await processIdentityProof(session);
|
|
188
203
|
}
|
|
189
204
|
}, [config]);
|
|
190
205
|
const disconnect = useCallback(async () => {
|
|
@@ -217,7 +232,7 @@ export const XPRNProvider = ({ children, config, }) => {
|
|
|
217
232
|
if (!session)
|
|
218
233
|
connect(true);
|
|
219
234
|
}, []);
|
|
220
|
-
return (_jsx(XPRNContext.Provider, { value: { config, session, link, profile, identityProof, identityProofStatus, connect, disconnect, pushTransaction, switchToSession }, children: children }));
|
|
235
|
+
return (_jsx(XPRNContext.Provider, { value: { config, session, link, profile, identityProof, identityProofStatus, identityProofError, connect, disconnect, pushTransaction, switchToSession, requestIdentityProof: requestIdentityProof_ }, children: children }));
|
|
221
236
|
};
|
|
222
237
|
export function useXPRN() {
|
|
223
238
|
return useContext(XPRNContext);
|