@verified-network/verified-custody 0.3.6 → 0.3.7

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.
Files changed (2) hide show
  1. package/README.md +220 -298
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,16 +1,27 @@
1
- # Verified Custody
1
+ ## 🛡️ Verified Custody
2
2
 
3
- Verified Custody is a react submodule for Custody of digital assets. This react module allows users to create blockchain wallets where private keys are sharded and stored on the blockchain itself in encrypted form. Users do not have to remember mnemonics or back up private keys. Verified Custody requires co-signers to be added by a wallet user and co-signers can be requested to re-generate the sharded and stored keys.
3
+ **Verified Custody** is a React submodule designed for custody of digital assets. This React module enables users to create blockchain wallets where private keys are sharded and stored on-chain in encrypted form. Users **do not need to remember mnemonics or back up private keys**.
4
4
 
5
- ### Installation:
5
+ Verified Custody requires wallet users to add co-signers, who can be requested to re-generate the sharded and stored keys, adding additional security and recovery options.
6
6
 
7
- ```
7
+ ## Objectives
8
+
9
+ - Provide an easy-to-integrate React module for digital asset custody.
10
+ - Support user onboarding (FTU) and returning user workflows.
11
+ - Enable secure co-signer management and transaction signing.
12
+ - Allow flexible communication with co-signers via customizable helper functions.
13
+ - Support wallet recovery and transaction signing workflows.
14
+
15
+ # ⚙️ Installation
16
+
17
+ ```bash
8
18
  npm install @verified-network/verified-custody
9
19
  ```
10
20
 
21
+ # 💻 Usage Example
22
+
11
23
  ```jsx
12
24
  import React from "react";
13
-
14
25
  import { VerifiedCustody } from "@verified-network/verified-custody";
15
26
 
16
27
  function App() {
@@ -22,46 +33,58 @@ function App() {
22
33
  }
23
34
  ```
24
35
 
25
- ### Build:
36
+ # 🛠️ Build
37
+
38
+ This module is built with TypeScript and works for both JavaScript and TypeScript React/Vite projects.
39
+ All components are compiled and available under the dist/ directory.
40
+ The module exports React components and helper functions useful for changing UI based on user state or custom business logic.
41
+
42
+ ## 🔄 Main Components & Workflows
43
+
44
+ The complete custody workflow component that handles new and existing users through multiple steps.
45
+
46
+ ```jsx
47
+ <VerifiedCustody />
48
+ ```
49
+
50
+ # 🆕 First Time Users (FTU)
51
+
52
+ `<FTUPage />` Full workflow for first-time users, consisting of:
26
53
 
27
- - This module is built with typescript and work for both javascript and typescript react/vite projects.
28
- - All the components of the module is compiled and available under the dist/ directory.
54
+ <ContactPage /> Starting point where users enter phone number or email to receive an OTP (One-Time Password).
29
55
 
30
- The react module exports react components and helper functions which will be useful when changing UI based on a user's state or any business logic
56
+ <OTPPage /> Where new and existing users verify or resend OTP.
31
57
 
32
- \***\*< VerifiedCustody />\*\*** component is the completed workflow of the custody module, it handles full workflow for new and existing users in steps; it consists of:
58
+ <CreatePinPage /> Users either:
33
59
 
34
- # First Time Users
60
+ Create a 4-digit PIN to secure their account.
35
61
 
36
- \***\*< FTUPage />\*\*** component which handles full workflow for First Time Users. This consists of:
62
+ Input their existing PIN and get redirected accordingly.
37
63
 
38
- \***\*< ContactPage />\*\*** component which is the starting point for all users, where they are required to input their phone number or email. And they receive an OTP(one time password).
64
+ Reset/Update their existing PIN to change to a new PIN.
39
65
 
40
- \***\*< OTPPage />\*\*** component which is where new/existing users verify and resend OTP.
66
+ New user accounts are created here after verifying phone/email.
41
67
 
42
- \***\*< CreatePinPage />\*\*** component which is where all users either;
68
+ <AddCoSignersPage /> New users add co-signers and define signing rules:
69
+ Up to 5 co-signers can be added with a minimum of 2 required signers.
43
70
 
44
- 1. create 4 digit pin to secure their account.
45
- 2. Input their existing pin and get redirected to another page.
46
- In this component new users accounts are created as they had verified their Phone number/Email from previous components.
71
+ # 🔄 Returning Users
47
72
 
48
- \***\*< AddCoSignersPage />\*\*** component which is where all new users gets to add coSigners to their account and decide the rule of signing. Users can add up to 5 Co-signers with 2 as minimum required signers.
73
+ `<EnterPinPage />` Existing users enter their PIN to:
49
74
 
50
- # Returning Users
75
+ Connect wallet/account to an application.
51
76
 
52
- \***\*< EnterPinPage />\*\*** component which is where existing/returning users gets to input their account pin to perform various actions like;
77
+ Accept or reject co-signer invitations.
53
78
 
54
- 1. connect their account/wallet to an application.
55
- 2. Accept/Reject Co-signers invitation.
56
- 3. Recover their lost account/wallet keys
57
- 4. Sign account recovery transaction for users
58
- 5. Sign regular transactions. e.t.c
79
+ Recover lost account/wallet keys.
59
80
 
60
- ## Usage:
81
+ Sign account recovery transactions.
61
82
 
62
- Note: To implement this module in your project there are some important component props required.
83
+ Sign regular transactions, etc.
63
84
 
64
- # Components Props Type:
85
+ ## 📋 Usage Details & Component Props
86
+
87
+ # Component Props Types
65
88
 
66
89
  ```jsx
67
90
  export interface VerifiedCustodyProps {
@@ -83,7 +106,8 @@ export type VerifiedWalletAction =
83
106
  | "getPk"
84
107
  | "invitation"
85
108
  | "signRecovery"
86
- | "completeRecovery";
109
+ | "completeRecovery"
110
+ | "eth_sendTransaction";
87
111
 
88
112
  export type VerifiedWalletVault = {
89
113
  vaultId: string,
@@ -151,287 +175,185 @@ export interface VerifiedCustodyHelpers {
151
175
  }
152
176
  ```
153
177
 
154
- 1. action: which can be either "connect_wallet" or "getPk" or "invitation" or "signRecovery" or "completeRecovery". if action is not passed in the props it will create account for new users or login for an existing users.
155
- 2. helperFunctions:
156
- For Example: sendCoSignerInvitation: this is required to send messages to cosigners using their email or phone number. it must take 4 parameters: ` jsx
157
- channel: "sms" | "email",
158
- cosigerId: string, //email or phone number of the cosigner added. note: phone number must be ``+${countryPhoneCode}${10DigitsPhoneNumber} `` for example: +10987654321 where 1 is the countryCode and 0987654321 is the phone number.
159
- cretorId: string, //email or phone number of the account creator. note: phone number must be ``+${countryPhoneCode}${10DigitsPhoneNumber} `` for example: +10987654321 where 1 is the countryCode and 0987654321 is the phone number.
160
- hashedCretorPin: string `
161
- and return `true or false` true when message sends without error and false incase of any error.
178
+ # Prop Descriptions
179
+
180
+ action:
181
+ Optional. Can be one of:
182
+ "connect_wallet" | "getPk" | "invitation" | "signRecovery" | "completeRecovery" | "eth_sendTransaction"
183
+ If omitted, the component handles account creation or login for new/existing users.
162
184
 
163
- Check the code Below for better explaination of how all helper functions work.
185
+ helperFunctions:
186
+ An object containing functions that handle messaging and notifications (email/SMS) for co-signers and creators.
187
+
188
+ Example:
189
+ sendCoSignerInvitation must take four parameters:
190
+ channel: "sms" | "email"
191
+ cosigerId: string (email or phone number of the co-signer)
192
+ phone number must be in format +{countryCode}{10DigitNumber} e.g. +1098765432
193
+ cretorId: string (email or phone number of the wallet creator)
194
+ hashedCretorPin: string
195
+ It returns a Promise resolving to true on successful message delivery, otherwise false.
164
196
 
165
- ### Full workflow with one component(handle First time users, existing user and all type of actions)
197
+ # 🚀 Full Workflow Example
166
198
 
167
199
  ```jsx
168
- import React from 'react';
169
-
170
- import { VerifiedCustody} from '@verified-network/verified-custody';
171
-
172
- function App(){
173
-
174
- const myCustomSendCoSignerInvitation = async(
175
- channel: "sms" | "email",
176
- cosigerId: string,
177
- cretorId: string,
178
- hashedCretorPin: string
179
- ) => Promise<boolean> {
180
- try {
181
- //sends email/messages depending on the channel
182
- if(channel === "sms") {
183
- //send message to cosigerId phone number using creatorId and hashedCretorPin in message
184
- return true
185
- }else if(channel === "email") {
186
- //send message to cosigerId email using creatorId and hashedCretorPin in message
187
- return true
188
- }else {
189
- return false
190
- }
191
- }catch(err) {
192
- //handles error
193
- return false
194
- }
195
- }
196
-
197
- const myCustomSendCreatorConfirmation = async(
198
- channel: "sms" | "email",
199
- cretorId: string,
200
- cosigersList: [],
201
- requiredSigners: number
202
- ) => Promise<boolean> {
203
- try {
204
- //sends email/messages depending on the channel
205
- if(channel === "sms") {
206
- //send message to cretorId phone number showing creator his coSigners list and rule of signer using requiredSigners and totalNumber of coSignersList
207
- return true
208
- }else if(channel === "email") {
209
- //send message to cretorId email showing creator his coSigners list and rule of signer using requiredSigners and totalNumber of coSignersList
210
- return true
211
- }else {
212
- return false
213
- }
214
- }catch(err) {
215
- //handles error
216
- return false
217
- }
218
- }
219
-
220
- // no action/ create account for new user or login existing user.
221
- return (
222
- <div>
223
- <VerifiedCustody helperFunctions={
224
- sendCoSignerInvitation: myCustomSendCoSignerInvitation,
225
- sendCreatorConfirmation: myCustomSendCreatorConfirmation,
226
- sendCreatorInitiation: myCustomsendCreatorInitiation,
227
- sendCreatorSigned: myCustomSendCreatorSigned,
228
- sendCreatorCompleted: myCustomSendCreatorCompleted,
229
- sendCreatorAcceptance: myCustomSendCreatorAcceptance,
230
- sendCreatorRejection: myCustomSendCreatorRejection
231
- } />
232
- </div>
233
- );
234
-
235
- // connect existing user account
236
- return (
237
- <div>
238
- <VerifiedCustody action="connect_wallet" actionText="CustomActionTextToDisplay like: Connect Your Account" origin="websiteToConnectToUrl" title="websiteToConnectToTitle" helperFunctions={
239
- sendCoSignerInvitation: myCustomSendCoSignerInvitation,
240
- sendCreatorConfirmation: myCustomSendCreatorConfirmation,
241
- sendCreatorInitiation: myCustomsendCreatorInitiation,
242
- sendCreatorSigned: myCustomSendCreatorSigned,
243
- sendCreatorCompleted: myCustomSendCreatorCompleted,
244
- sendCreatorAcceptance: myCustomSendCreatorAcceptance,
245
- sendCreatorRejection: myCustomSendCreatorRejection
246
- } />
247
- </div>
248
- );
249
-
250
- //accept or reject coSigner invitation
251
- return (
252
- <div>
253
- <VerifiedCustody action="invitation" origin="websiteUrl" title="websiteTitle" helperFunctions={
254
- sendCoSignerInvitation: myCustomSendCoSignerInvitation,
255
- sendCreatorConfirmation: myCustomSendCreatorConfirmation,
256
- sendCreatorInitiation: myCustomsendCreatorInitiation,
257
- sendCreatorSigned: myCustomSendCreatorSigned,
258
- sendCreatorCompleted: myCustomSendCreatorCompleted,
259
- sendCreatorAcceptance: myCustomSendCreatorAcceptance,
260
- sendCreatorRejection: myCustomSendCreatorRejection
261
- } />
262
- </div>
263
- );
264
-
265
- //sign account recovery for an existing account as their cosigner
266
- return (
267
- <div>
268
- <VerifiedCustody action="signRecovery" origin="websiteUrl" title="websiteTitle" helperFunctions={
269
- sendCoSignerInvitation: myCustomSendCoSignerInvitation,
270
- sendCreatorConfirmation: myCustomSendCreatorConfirmation,
271
- sendCreatorInitiation: myCustomsendCreatorInitiation,
272
- sendCreatorSigned: myCustomSendCreatorSigned,
273
- sendCreatorCompleted: myCustomSendCreatorCompleted,
274
- sendCreatorAcceptance: myCustomSendCreatorAcceptance,
275
- sendCreatorRejection: myCustomSendCreatorRejection
276
- } />
277
- </div>
278
- );
279
-
280
- //complete account recovery for an existing account
281
- return (
282
- <div>
283
- <VerifiedCustody action="completeRecovery" origin="websiteUrl" title="websiteTitle" helperFunctions={
284
- sendCoSignerInvitation: myCustomSendCoSignerInvitation,
285
- sendCreatorConfirmation: myCustomSendCreatorConfirmation,
286
- sendCreatorInitiation: myCustomsendCreatorInitiation,
287
- sendCreatorSigned: myCustomSendCreatorSigned,
288
- sendCreatorCompleted: myCustomSendCreatorCompleted,
289
- sendCreatorAcceptance: myCustomSendCreatorAcceptance,
290
- sendCreatorRejection: myCustomSendCreatorRejection
291
- } />
292
- </div>
293
- );
200
+ import React from "react";
201
+ import { VerifiedCustody } from "@verified-network/verified-custody";
202
+
203
+ function App() {
204
+ const myCustomSendCoSignerInvitation = async (
205
+ channel: "sms" | "email",
206
+ cosigerId: string,
207
+ cretorId: string,
208
+ hashedCretorPin: string
209
+ ): Promise<boolean> => {
210
+ try {
211
+ if (channel === "sms") {
212
+ // send SMS to cosigerId with cretorId and hashedCretorPin
213
+ return true;
214
+ } else if (channel === "email") {
215
+ // send email to cosigerId with cretorId and hashedCretorPin
216
+ return true;
217
+ }
218
+ return false;
219
+ } catch (err) {
220
+ return false;
221
+ }
222
+ };
223
+
224
+ const myCustomSendCreatorConfirmation = async (
225
+ channel: "sms" | "email",
226
+ cretorId: string,
227
+ cosigersList: [],
228
+ requiredSigners: number
229
+ ): Promise<boolean> => {
230
+ try {
231
+ if (channel === "sms") {
232
+ // send SMS showing coSigners and signing rules to cretorId
233
+ return true;
234
+ } else if (channel === "email") {
235
+ // send email showing coSigners and signing rules to cretorId
236
+ return true;
237
+ }
238
+ return false;
239
+ } catch (err) {
240
+ // If reverted for any reason return false
241
+ return false;
242
+ }
243
+ };
244
+
245
+ // Similarly define other helper functions: myCustomsendCreatorInitiation, myCustomSendCreatorSigned, etc.
246
+
247
+ return (
248
+ <div>
249
+ <VerifiedCustody
250
+ helperFunctions={{
251
+ sendCoSignerInvitation: myCustomSendCoSignerInvitation,
252
+ sendCreatorConfirmation: myCustomSendCreatorConfirmation,
253
+ sendCreatorInitiation: myCustomsendCreatorInitiation,
254
+ sendCreatorSigned: myCustomSendCreatorSigned,
255
+ sendCreatorCompleted: myCustomSendCreatorCompleted,
256
+ sendCreatorAcceptance: myCustomSendCreatorAcceptance,
257
+ sendCreatorRejection: myCustomSendCreatorRejection,
258
+ }}
259
+ />
260
+ </div>
261
+ );
262
+
263
+ // You can also set action prop for different user flows, e.g. action="connect_wallet"
294
264
  }
295
265
  ```
296
266
 
297
- ### First time users
267
+ # 🆕 First Time Users
298
268
 
299
269
  ```jsx
300
- import React from 'react';
301
-
302
- import { FTUPage} from '@verified-network/verified-custody';
303
-
304
- function App(){
305
-
306
- const myCustomSendCoSignerInvitation = async(
307
- channel: "sms" | "email",
308
- cosigerId: string,
309
- cretorId: string,
310
- hashedCretorPin: string
311
- ) => Promise<boolean> {
312
- try {
313
- //sends email/messages depending on the channel
314
- if(channel === "sms") {
315
- //send message to cosigerId phone number using creatorId and hashedCretorPin in message
316
- return true
317
- }else if(channel === "email") {
318
- //send message to cosigerId email using creatorId and hashedCretorPin in message
319
- return true
320
- }else {
321
- return false
322
- }
323
- }catch(err) {
324
- //handles error
325
- return false
326
- }
327
- }
328
-
329
- const myCustomSendCreatorConfirmation = async(
330
- channel: "sms" | "email",
331
- cretorId: string,
332
- cosigersList: [],
333
- requiredSigners: number
334
- ) => Promise<boolean> {
335
- try {
336
- //sends email/messages depending on the channel
337
- if(channel === "sms") {
338
- //send message to cretorId phone number showing creator his coSigners list and rule of signer using requiredSigners and totalNumber of coSignersList
339
- return true
340
- }else if(channel === "email") {
341
- //send message to cretorId email showing creator his coSigners list and rule of signer using requiredSigners and totalNumber of coSignersList
342
- return true
343
- }else {
344
- return false
345
- }
346
- }catch(err) {
347
- //handles error
348
- return false
349
- }
350
- }
351
-
352
- return (
353
- <div>
354
- <FTUPage helperFunctions={
355
- sendCoSignerInvitation: myCustomSendCoSignerInvitation,
356
- sendCreatorConfirmation: myCustomSendCreatorConfirmation,
357
- sendCreatorInitiation: myCustomsendCreatorInitiation,
358
- sendCreatorSigned: myCustomSendCreatorSigned,
359
- sendCreatorCompleted: myCustomSendCreatorCompleted,
360
- sendCreatorAcceptance: myCustomSendCreatorAcceptance,
361
- sendCreatorRejection: myCustomSendCreatorRejection
362
- } />
363
- </div>
364
- );
270
+ import React from "react";
271
+ import { FTUPage } from "@verified-network/verified-custody";
272
+
273
+ function App() {
274
+ const myCustomSendCoSignerInvitation = async (
275
+ channel: "sms" | "email",
276
+ cosigerId: string,
277
+ cretorId: string,
278
+ hashedCretorPin: string
279
+ ): Promise<boolean> => {
280
+ // Implementation as above
281
+ };
282
+
283
+ const myCustomSendCreatorConfirmation = async (
284
+ channel: "sms" | "email",
285
+ cretorId: string,
286
+ cosigersList: [],
287
+ requiredSigners: number
288
+ ): Promise<boolean> => {
289
+ // Implementation as above
290
+ };
291
+
292
+ return (
293
+ <div>
294
+ <FTUPage
295
+ helperFunctions={{
296
+ sendCoSignerInvitation: myCustomSendCoSignerInvitation,
297
+ sendCreatorConfirmation: myCustomSendCreatorConfirmation,
298
+ sendCreatorInitiation: myCustomsendCreatorInitiation,
299
+ sendCreatorSigned: myCustomSendCreatorSigned,
300
+ sendCreatorCompleted: myCustomSendCreatorCompleted,
301
+ sendCreatorAcceptance: myCustomSendCreatorAcceptance,
302
+ sendCreatorRejection: myCustomSendCreatorRejection,
303
+ }}
304
+ />
305
+ </div>
306
+ );
365
307
  }
366
308
  ```
367
309
 
368
- ### Existing/Returning Users
310
+ # 🔄 Existing/Returning Users
369
311
 
370
312
  ```jsx
371
- import React from 'react';
372
-
373
- import { EnterPinPage} from '@verified-network/verified-custody';
374
-
375
- function App(){
376
-
377
- const myCustomSendCoSignerInvitation = async(
378
- channel: "sms" | "email",
379
- cosigerId: string,
380
- cretorId: string,
381
- hashedCretorPin: string
382
- ) => Promise<boolean> {
383
- try {
384
- //sends email/messages depending on the channel
385
- if(channel === "sms") {
386
- //send message to cosigerId phone number using creatorId and hashedCretorPin in message
387
- return true
388
- }else if(channel === "email") {
389
- //send message to cosigerId email using creatorId and hashedCretorPin in message
390
- return true
391
- }else {
392
- return false
393
- }
394
- }catch(err) {
395
- //handles error
396
- return false
397
- }
398
- }
399
-
400
- const myCustomSendCreatorConfirmation = async(
401
- channel: "sms" | "email",
402
- cretorId: string,
403
- cosigersList: [],
404
- requiredSigners: number
405
- ) => Promise<boolean> {
406
- try {
407
- //sends email/messages depending on the channel
408
- if(channel === "sms") {
409
- //send message to cretorId phone number showing creator his coSigners list and rule of signer using requiredSigners and totalNumber of coSignersList
410
- return true
411
- }else if(channel === "email") {
412
- //send message to cretorId email showing creator his coSigners list and rule of signer using requiredSigners and totalNumber of coSignersList
413
- return true
414
- }else {
415
- return false
416
- }
417
- }catch(err) {
418
- //handles error
419
- return false
420
- }
421
- }
422
-
423
- return (
424
- <div>
425
- <EnterPinPage helperFunctions={
426
- sendCoSignerInvitation: myCustomSendCoSignerInvitation,
427
- sendCreatorConfirmation: myCustomSendCreatorConfirmation,
428
- sendCreatorInitiation: myCustomsendCreatorInitiation,
429
- sendCreatorSigned: myCustomSendCreatorSigned,
430
- sendCreatorCompleted: myCustomSendCreatorCompleted,
431
- sendCreatorAcceptance: myCustomSendCreatorAcceptance,
432
- sendCreatorRejection: myCustomSendCreatorRejection
433
- } />
434
- </div>
435
- );
313
+ import React from "react";
314
+ import { EnterPinPage } from "@verified-network/verified-custody";
315
+
316
+ function App() {
317
+ const myCustomSendCoSignerInvitation = async (
318
+ channel: "sms" | "email",
319
+ cosigerId: string,
320
+ cretorId: string,
321
+ hashedCretorPin: string
322
+ ): Promise<boolean> => {
323
+ // Implementation as above
324
+ };
325
+
326
+ const myCustomSendCreatorConfirmation = async (
327
+ channel: "sms" | "email",
328
+ cretorId: string,
329
+ cosigersList: [],
330
+ requiredSigners: number
331
+ ): Promise<boolean> => {
332
+ // Implementation as above
333
+ };
334
+
335
+ return (
336
+ <div>
337
+ <EnterPinPage
338
+ helperFunctions={{
339
+ sendCoSignerInvitation: myCustomSendCoSignerInvitation,
340
+ sendCreatorConfirmation: myCustomSendCreatorConfirmation,
341
+ sendCreatorInitiation: myCustomsendCreatorInitiation,
342
+ sendCreatorSigned: myCustomSendCreatorSigned,
343
+ sendCreatorCompleted: myCustomSendCreatorCompleted,
344
+ sendCreatorAcceptance: myCustomSendCreatorAcceptance,
345
+ sendCreatorRejection: myCustomSendCreatorRejection,
346
+ }}
347
+ />
348
+ </div>
349
+ );
436
350
  }
437
351
  ```
352
+
353
+ ## Summary
354
+
355
+ - Secure blockchain wallet custody with private key sharding and on-chain encrypted storage.
356
+ - Eliminates the need for mnemonic phrases or private key backups.
357
+ - Supports multi-signature wallets via co-signers.
358
+ - Provides complete workflows for **First Time Users** (FTU) and **Returning Users** (RU).
359
+ - Fully customizable via React component props and helper functions.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verified-network/verified-custody",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "description": "React submodule for Custody of digital assets",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",