@coinbase/cdp-hooks 0.0.70 → 0.0.71
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 +290 -9
- package/dist/esm/index.js +59 -48
- package/dist/esm/index10.js +1 -1
- package/dist/esm/index100.js +3 -56
- package/dist/esm/index101.js +327 -2
- package/dist/esm/index102.js +13 -7
- package/dist/esm/index103.js +4 -214
- package/dist/esm/index104.js +55 -31
- package/dist/esm/index105.js +2 -22
- package/dist/esm/index106.js +7 -5
- package/dist/esm/index107.js +208 -67
- package/dist/esm/index108.js +32 -6
- package/dist/esm/index109.js +21 -5
- package/dist/esm/index11.js +1 -1
- package/dist/esm/index110.js +5 -35
- package/dist/esm/index111.js +68 -70
- package/dist/esm/index112.js +6 -3
- package/dist/esm/index113.js +5 -23
- package/dist/esm/index114.js +28 -444
- package/dist/esm/index115.js +66 -21
- package/dist/esm/index116.js +3 -27
- package/dist/esm/index117.js +16 -26
- package/dist/esm/index118.js +445 -28
- package/dist/esm/index119.js +21 -184
- package/dist/esm/index12.js +1 -1
- package/dist/esm/index120.js +24 -6
- package/dist/esm/index121.js +34 -2
- package/dist/esm/index122.js +32 -10
- package/dist/esm/index123.js +188 -13
- package/dist/esm/index124.js +6 -25
- package/dist/esm/index125.js +2 -9
- package/dist/esm/index126.js +11 -54
- package/dist/esm/index127.js +15 -42
- package/dist/esm/index128.js +27 -8
- package/dist/esm/index129.js +8 -7
- package/dist/esm/index13.js +1 -1
- package/dist/esm/index130.js +54 -15
- package/dist/esm/index131.js +43 -16
- package/dist/esm/index132.js +8 -24
- package/dist/esm/index133.js +7 -16
- package/dist/esm/index134.js +16 -54
- package/dist/esm/index135.js +18 -11
- package/dist/esm/index136.js +25 -161
- package/dist/esm/index137.js +16 -21
- package/dist/esm/index138.js +53 -126
- package/dist/esm/index139.js +11 -38
- package/dist/esm/index14.js +1 -1
- package/dist/esm/index140.js +160 -6
- package/dist/esm/index141.js +20 -26
- package/dist/esm/index142.js +125 -189
- package/dist/esm/index143.js +39 -4
- package/dist/esm/index144.js +6 -64
- package/dist/esm/index145.js +28 -3
- package/dist/esm/index146.js +185 -14
- package/dist/esm/index147.js +4 -17
- package/dist/esm/index148.js +63 -22
- package/dist/esm/index149.js +3 -12
- package/dist/esm/index15.js +1 -1
- package/dist/esm/index150.js +17 -31
- package/dist/esm/index151.js +17 -3
- package/dist/esm/index152.js +23 -18
- package/dist/esm/index153.js +11 -27
- package/dist/esm/index154.js +33 -34
- package/dist/esm/index155.js +3 -8
- package/dist/esm/index156.js +18 -25
- package/dist/esm/index157.js +26 -27
- package/dist/esm/index158.js +34 -63
- package/dist/esm/index159.js +7 -9
- package/dist/esm/index16.js +1 -1
- package/dist/esm/index160.js +24 -32
- package/dist/esm/index161.js +28 -27
- package/dist/esm/index162.js +63 -23
- package/dist/esm/index163.js +9 -3
- package/dist/esm/index164.js +33 -14
- package/dist/esm/index165.js +26 -102
- package/dist/esm/index166.js +23 -63
- package/dist/esm/index167.js +3 -5
- package/dist/esm/index168.js +14 -6
- package/dist/esm/index169.js +103 -27
- package/dist/esm/index170.js +63 -37
- package/dist/esm/index171.js +5 -13
- package/dist/esm/index172.js +6 -42
- package/dist/esm/index173.js +27 -5
- package/dist/esm/index174.js +38 -11
- package/dist/esm/index175.js +13 -19
- package/dist/esm/index176.js +38 -74
- package/dist/esm/index177.js +6 -2
- package/dist/esm/index178.js +11 -37
- package/dist/esm/index179.js +19 -110
- package/dist/esm/index18.js +7 -8
- package/dist/esm/index180.js +75 -45
- package/dist/esm/index181.js +2 -33
- package/dist/esm/index182.js +37 -8
- package/dist/esm/index183.js +110 -6
- package/dist/esm/index184.js +48 -6
- package/dist/esm/index185.js +32 -11
- package/dist/esm/index186.js +8 -10
- package/dist/esm/index187.js +6 -13
- package/dist/esm/index188.js +6 -32
- package/dist/esm/index189.js +12 -5
- package/dist/esm/index19.js +8 -34
- package/dist/esm/index190.js +10 -8
- package/dist/esm/index191.js +12 -18
- package/dist/esm/index192.js +31 -30
- package/dist/esm/index193.js +5 -21
- package/dist/esm/index194.js +8 -3
- package/dist/esm/index195.js +18 -16
- package/dist/esm/index196.js +31 -10
- package/dist/esm/index197.js +20 -21
- package/dist/esm/index198.js +3 -22
- package/dist/esm/index199.js +17 -5
- package/dist/esm/index2.js +2 -2
- package/dist/esm/index20.js +8 -18
- package/dist/esm/index200.js +10 -5
- package/dist/esm/index201.js +21 -8
- package/dist/esm/index202.js +22 -104
- package/dist/esm/index203.js +6 -3
- package/dist/esm/index204.js +5 -18
- package/dist/esm/index205.js +8 -171
- package/dist/esm/index206.js +104 -17
- package/dist/esm/index207.js +3 -10
- package/dist/esm/index208.js +17 -39
- package/dist/esm/index209.js +172 -2
- package/dist/esm/index21.js +7 -11
- package/dist/esm/index210.js +17 -4
- package/dist/esm/index211.js +10 -11
- package/dist/esm/index212.js +38 -19
- package/dist/esm/index213.js +2 -8
- package/dist/esm/index214.js +69 -11
- package/dist/esm/index215.js +34 -66
- package/dist/esm/index216.js +12 -63
- package/dist/esm/index217.js +39 -184
- package/dist/esm/index218.js +2 -23
- package/dist/esm/index219.js +4 -42
- package/dist/esm/index22.js +8 -11
- package/dist/esm/index220.js +9 -75
- package/dist/esm/index221.js +17 -38
- package/dist/esm/index222.js +7 -16
- package/dist/esm/index223.js +10 -12
- package/dist/esm/index224.js +66 -7
- package/dist/esm/index225.js +65 -6
- package/dist/esm/index226.js +183 -34
- package/dist/esm/index227.js +22 -15
- package/dist/esm/index228.js +42 -8
- package/dist/esm/index229.js +77 -13
- package/dist/esm/index23.js +33 -53
- package/dist/esm/index230.js +40 -9
- package/dist/esm/index231.js +15 -15
- package/dist/esm/index232.js +12 -21
- package/dist/esm/index233.js +7 -30
- package/dist/esm/index234.js +7 -2
- package/dist/esm/index235.js +36 -13
- package/dist/esm/index236.js +15 -12
- package/dist/esm/index237.js +8 -47
- package/dist/esm/index238.js +12 -9
- package/dist/esm/index239.js +9 -13
- package/dist/esm/index24.js +16 -56
- package/dist/esm/index240.js +15 -13
- package/dist/esm/index241.js +22 -8
- package/dist/esm/index242.js +28 -13
- package/dist/esm/index243.js +2 -25
- package/dist/esm/index244.js +13 -11
- package/dist/esm/index245.js +12 -24
- package/dist/esm/index246.js +46 -50
- package/dist/esm/index247.js +9 -17
- package/dist/esm/index248.js +13 -14
- package/dist/esm/index249.js +14 -11
- package/dist/esm/index25.js +12 -56
- package/dist/esm/index250.js +8 -103
- package/dist/esm/index251.js +15 -5
- package/dist/esm/index252.js +23 -222
- package/dist/esm/index253.js +11 -6
- package/dist/esm/index254.js +25 -7
- package/dist/esm/index255.js +49 -24
- package/dist/esm/index256.js +17 -19
- package/dist/esm/index257.js +13 -144
- package/dist/esm/index258.js +12 -13
- package/dist/esm/index259.js +102 -34
- package/dist/esm/index26.js +12 -5
- package/dist/esm/index260.js +5 -41
- package/dist/esm/index261.js +223 -38
- package/dist/esm/index262.js +7 -2
- package/dist/esm/index263.js +7 -70
- package/dist/esm/index264.js +23 -31
- package/dist/esm/index265.js +18 -13
- package/dist/esm/index266.js +146 -2
- package/dist/esm/index267.js +13 -69
- package/dist/esm/index268.js +36 -4
- package/dist/esm/index269.js +41 -136
- package/dist/esm/index27.js +54 -48
- package/dist/esm/index270.js +2 -156
- package/dist/esm/index271.js +68 -9
- package/dist/esm/index272.js +3 -16
- package/dist/esm/index273.js +126 -103
- package/dist/esm/index274.js +123 -102
- package/dist/esm/index275.js +9 -78
- package/dist/esm/index276.js +17 -2
- package/dist/esm/index277.js +105 -689
- package/dist/esm/index278.js +126 -130
- package/dist/esm/index279.js +66 -30
- package/dist/esm/index28.js +56 -31
- package/dist/esm/index280.js +2 -201
- package/dist/esm/index281.js +694 -62
- package/dist/esm/index282.js +138 -4
- package/dist/esm/index283.js +42 -40
- package/dist/esm/index284.js +200 -7
- package/dist/esm/index285.js +3 -62
- package/dist/esm/index286.js +55 -67
- package/dist/esm/index287.js +5 -4
- package/dist/esm/index288.js +40 -194
- package/dist/esm/index289.js +7 -3
- package/dist/esm/index29.js +56 -4
- package/dist/esm/index290.js +57 -58
- package/dist/esm/index291.js +72 -39
- package/dist/esm/index292.js +4 -5
- package/dist/esm/index293.js +195 -5
- package/dist/esm/index294.js +64 -2
- package/dist/esm/index295.js +43 -20
- package/dist/esm/index296.js +7 -0
- package/dist/esm/index297.js +7 -0
- package/dist/esm/index298.js +4 -0
- package/dist/esm/index299.js +24 -0
- package/dist/esm/index3.js +1 -1
- package/dist/esm/index30.js +5 -10
- package/dist/esm/index31.js +42 -63
- package/dist/esm/index32.js +31 -8
- package/dist/esm/index33.js +3 -28
- package/dist/esm/index34.js +9 -70
- package/dist/esm/index35.js +68 -19
- package/dist/esm/index36.js +9 -110
- package/dist/esm/index37.js +27 -59
- package/dist/esm/index38.js +70 -24
- package/dist/esm/index39.js +19 -40
- package/dist/esm/index40.js +110 -37
- package/dist/esm/index41.js +43 -41
- package/dist/esm/index42.js +21 -160
- package/dist/esm/index43.js +38 -37
- package/dist/esm/index44.js +36 -8
- package/dist/esm/index45.js +58 -31
- package/dist/esm/index46.js +161 -34
- package/dist/esm/index47.js +39 -9
- package/dist/esm/index48.js +8 -28
- package/dist/esm/index49.js +29 -44
- package/dist/esm/index5.js +87 -66
- package/dist/esm/index50.js +36 -88
- package/dist/esm/index51.js +9 -40
- package/dist/esm/index52.js +28 -7
- package/dist/esm/index53.js +46 -6
- package/dist/esm/index54.js +88 -16
- package/dist/esm/index55.js +40 -8
- package/dist/esm/index56.js +8 -13
- package/dist/esm/index57.js +5 -6
- package/dist/esm/index58.js +16 -9
- package/dist/esm/index59.js +8 -16
- package/dist/esm/index6.js +3 -3
- package/dist/esm/index60.js +13 -46
- package/dist/esm/index61.js +7 -13
- package/dist/esm/index62.js +9 -16
- package/dist/esm/index63.js +16 -13
- package/dist/esm/index64.js +46 -6
- package/dist/esm/index65.js +11 -33
- package/dist/esm/index66.js +15 -8
- package/dist/esm/index67.js +13 -8
- package/dist/esm/index68.js +6 -25
- package/dist/esm/index69.js +35 -10
- package/dist/esm/index7.js +9 -9
- package/dist/esm/index70.js +8 -13
- package/dist/esm/index71.js +8 -11
- package/dist/esm/index72.js +24 -115
- package/dist/esm/index73.js +10 -33
- package/dist/esm/index74.js +14 -79
- package/dist/esm/index75.js +11 -177
- package/dist/esm/index76.js +114 -42
- package/dist/esm/index77.js +32 -5
- package/dist/esm/index78.js +79 -13
- package/dist/esm/index79.js +177 -13
- package/dist/esm/index8.js +5 -5
- package/dist/esm/index80.js +42 -97
- package/dist/esm/index81.js +6 -72
- package/dist/esm/index82.js +13 -87
- package/dist/esm/index83.js +13 -148
- package/dist/esm/index84.js +93 -130
- package/dist/esm/index85.js +65 -61
- package/dist/esm/index86.js +87 -23
- package/dist/esm/index87.js +145 -102
- package/dist/esm/index88.js +136 -6
- package/dist/esm/index89.js +65 -128
- package/dist/esm/index9.js +1 -1
- package/dist/esm/index90.js +24 -276
- package/dist/esm/index91.js +106 -3
- package/dist/esm/index92.js +7 -4
- package/dist/esm/index93.js +132 -9
- package/dist/esm/index94.js +276 -2
- package/dist/esm/index95.js +3 -2
- package/dist/esm/index96.js +4 -3
- package/dist/esm/index97.js +9 -327
- package/dist/esm/index98.js +2 -14
- package/dist/esm/index99.js +2 -5
- package/dist/types/index.d.ts +36 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -252,6 +252,28 @@ function SignIn() {
|
|
|
252
252
|
console.log("Signed in user:", user);
|
|
253
253
|
|
|
254
254
|
// Access different account types based on configuration
|
|
255
|
+
|
|
256
|
+
// Using new account objects (recommended)
|
|
257
|
+
if (user.evmAccountObjects?.length > 0) {
|
|
258
|
+
user.evmAccountObjects.forEach((account, index) => {
|
|
259
|
+
console.log(`EVM Account ${index + 1}:`, account.address);
|
|
260
|
+
console.log(`Created:`, new Date(account.createdAt).toLocaleDateString());
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
if (user.evmSmartAccountObjects?.length > 0) {
|
|
264
|
+
user.evmSmartAccountObjects.forEach((account, index) => {
|
|
265
|
+
console.log(`Smart Account ${index + 1}:`, account.address);
|
|
266
|
+
console.log(`Owners:`, account.ownerAddresses.join(', '));
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
if (user.solanaAccountObjects?.length > 0) {
|
|
270
|
+
user.solanaAccountObjects.forEach((account, index) => {
|
|
271
|
+
console.log(`Solana Account ${index + 1}:`, account.address);
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Legacy deprecated arrays (for backward compatibility)
|
|
276
|
+
// ⚠️ Use *AccountObjects instead
|
|
255
277
|
if (user.evmAccounts?.length > 0) {
|
|
256
278
|
console.log("User EVM address (EOA):", user.evmAccounts[0]);
|
|
257
279
|
}
|
|
@@ -270,6 +292,81 @@ function SignIn() {
|
|
|
270
292
|
}
|
|
271
293
|
```
|
|
272
294
|
|
|
295
|
+
### Working with Multiple Accounts
|
|
296
|
+
|
|
297
|
+
Users can have up to 10 accounts per blockchain type (EVM, Solana). The SDK provides both single-account and multi-account hooks to support different use cases.
|
|
298
|
+
|
|
299
|
+
#### Single Account Hooks
|
|
300
|
+
|
|
301
|
+
These hooks return the **first account (index 0)**. They're ideal for simple applications where most users have one account:
|
|
302
|
+
|
|
303
|
+
- `useEvmAddress()` - Returns first smart account, then first EOA
|
|
304
|
+
- `useSolanaAddress()` - Returns first Solana account
|
|
305
|
+
|
|
306
|
+
```tsx lines
|
|
307
|
+
function SimpleWallet() {
|
|
308
|
+
const { evmAddress } = useEvmAddress(); // Returns first EVM address
|
|
309
|
+
const { solanaAddress } = useSolanaAddress(); // Returns first Solana address
|
|
310
|
+
|
|
311
|
+
return (
|
|
312
|
+
<div>
|
|
313
|
+
<p>EVM: {evmAddress ?? 'No account'}</p>
|
|
314
|
+
<p>Solana: {solanaAddress ?? 'No account'}</p>
|
|
315
|
+
</div>
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
#### Multi-Account Hooks (All Accounts with Metadata)
|
|
321
|
+
|
|
322
|
+
These hooks return **all accounts** with additional metadata (creation timestamp, owner addresses). Use these when:
|
|
323
|
+
- Users may have multiple accounts
|
|
324
|
+
- You need account metadata (creation date, etc.)
|
|
325
|
+
- You're building an account selector UI
|
|
326
|
+
|
|
327
|
+
Available hooks:
|
|
328
|
+
- `useEvmAccounts()` - All EVM EOA accounts with metadata
|
|
329
|
+
- `useSolanaAccounts()` - All Solana accounts with metadata
|
|
330
|
+
- `useEvmSmartAccounts()` - All EVM smart accounts with metadata
|
|
331
|
+
|
|
332
|
+
```tsx lines
|
|
333
|
+
function MultiAccountWallet() {
|
|
334
|
+
const { evmAccounts } = useEvmAccounts();
|
|
335
|
+
const { solanaAccounts } = useSolanaAccounts();
|
|
336
|
+
|
|
337
|
+
return (
|
|
338
|
+
<div>
|
|
339
|
+
<h3>EVM Accounts</h3>
|
|
340
|
+
{evmAccounts?.map((account, idx) => (
|
|
341
|
+
<div key={account.address}>
|
|
342
|
+
<p>Account {idx + 1}: {account.address}</p>
|
|
343
|
+
<p>Created: {new Date(account.createdAt).toLocaleDateString()}</p>
|
|
344
|
+
</div>
|
|
345
|
+
))}
|
|
346
|
+
|
|
347
|
+
<h3>Solana Accounts</h3>
|
|
348
|
+
{solanaAccounts?.map((account, idx) => (
|
|
349
|
+
<div key={account.address}>
|
|
350
|
+
<p>Account {idx + 1}: {account.address}</p>
|
|
351
|
+
<p>Created: {new Date(account.createdAt).toLocaleDateString()}</p>
|
|
352
|
+
</div>
|
|
353
|
+
))}
|
|
354
|
+
</div>
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
#### When to Use Which?
|
|
360
|
+
|
|
361
|
+
| Use Case | Hook to Use |
|
|
362
|
+
|----------|-------------|
|
|
363
|
+
| Simple wallet display | `useEvmAddress()` / `useSolanaAddress()` |
|
|
364
|
+
| Account selector dropdown | `useEvmAccounts()` / `useSolanaAccounts()` |
|
|
365
|
+
| Display creation dates | `useEvmAccounts()` / `useSolanaAccounts()` |
|
|
366
|
+
| Show owner addresses (smart accounts) | `useEvmSmartAccounts()` |
|
|
367
|
+
| Most users have 1 account | `useEvmAddress()` / `useSolanaAddress()` |
|
|
368
|
+
| Advanced multi-account features | `useEvmAccounts()` / `useSolanaAccounts()` |
|
|
369
|
+
|
|
273
370
|
#### React Native Applications
|
|
274
371
|
|
|
275
372
|
For React Native, you'll use native UI components and handle the sign-in flow similarly:
|
|
@@ -671,7 +768,7 @@ function CustomAuthSignIn() {
|
|
|
671
768
|
console.log("Is new user:", result.isNewUser);
|
|
672
769
|
|
|
673
770
|
// The user is now signed in and wallets are created based on your config
|
|
674
|
-
if (result.user.
|
|
771
|
+
if (result.user.evmAccountObjects?.[0]?.address) {
|
|
675
772
|
console.log("EVM Address:", result.user.evmAccounts[0]);
|
|
676
773
|
}
|
|
677
774
|
} catch (error) {
|
|
@@ -688,6 +785,190 @@ function CustomAuthSignIn() {
|
|
|
688
785
|
}
|
|
689
786
|
```
|
|
690
787
|
|
|
788
|
+
### Multi-Factor Authentication (MFA)
|
|
789
|
+
|
|
790
|
+
The CDP SDK provides hooks for implementing Multi-Factor Authentication using TOTP (Time-based One-Time Password). MFA adds an extra layer of security for user accounts and sensitive operations.
|
|
791
|
+
|
|
792
|
+
#### Enroll User in MFA
|
|
793
|
+
|
|
794
|
+
Use `useInitiateMfaEnrollment` and `useSubmitMfaEnrollment` to enroll a user in MFA:
|
|
795
|
+
|
|
796
|
+
```tsx lines
|
|
797
|
+
import {
|
|
798
|
+
useInitiateMfaEnrollment,
|
|
799
|
+
useSubmitMfaEnrollment,
|
|
800
|
+
useCurrentUser
|
|
801
|
+
} from "@coinbase/cdp-hooks";
|
|
802
|
+
import { useState } from "react";
|
|
803
|
+
import QRCode from "react-qr-code";
|
|
804
|
+
|
|
805
|
+
function MfaEnrollment() {
|
|
806
|
+
const { initiateMfaEnrollment } = useInitiateMfaEnrollment();
|
|
807
|
+
const { submitMfaEnrollment } = useSubmitMfaEnrollment();
|
|
808
|
+
const { currentUser } = useCurrentUser();
|
|
809
|
+
const [enrollmentData, setEnrollmentData] = useState<{
|
|
810
|
+
authUrl: string;
|
|
811
|
+
secret: string;
|
|
812
|
+
} | null>(null);
|
|
813
|
+
const [mfaCode, setMfaCode] = useState("");
|
|
814
|
+
|
|
815
|
+
const handleInitiateEnrollment = async () => {
|
|
816
|
+
try {
|
|
817
|
+
// Step 1: Initiate MFA enrollment
|
|
818
|
+
const result = await initiateMfaEnrollment({ mfaMethod: "totp" });
|
|
819
|
+
|
|
820
|
+
// Store the authUrl and secret for QR code display
|
|
821
|
+
setEnrollmentData(result);
|
|
822
|
+
|
|
823
|
+
console.log("Scan QR code or enter secret:", result.secret);
|
|
824
|
+
} catch (error) {
|
|
825
|
+
console.error("Failed to initiate MFA enrollment:", error);
|
|
826
|
+
}
|
|
827
|
+
};
|
|
828
|
+
|
|
829
|
+
const handleSubmitEnrollment = async () => {
|
|
830
|
+
try {
|
|
831
|
+
// Step 2: Submit the 6-digit code from authenticator app
|
|
832
|
+
const result = await submitMfaEnrollment({
|
|
833
|
+
mfaMethod: "totp",
|
|
834
|
+
mfaCode: mfaCode,
|
|
835
|
+
});
|
|
836
|
+
|
|
837
|
+
console.log("MFA enrolled successfully for user:", result.user.userId);
|
|
838
|
+
setEnrollmentData(null);
|
|
839
|
+
setMfaCode("");
|
|
840
|
+
} catch (error) {
|
|
841
|
+
console.error("Failed to submit MFA enrollment:", error);
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
|
|
845
|
+
if (!currentUser) {
|
|
846
|
+
return <div>Please sign in to enable MFA</div>;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
return (
|
|
850
|
+
<div>
|
|
851
|
+
<h2>Enable MFA</h2>
|
|
852
|
+
|
|
853
|
+
{!enrollmentData ? (
|
|
854
|
+
<button onClick={handleInitiateEnrollment}>
|
|
855
|
+
Start MFA Enrollment
|
|
856
|
+
</button>
|
|
857
|
+
) : (
|
|
858
|
+
<div>
|
|
859
|
+
<p>Scan this QR code with your authenticator app:</p>
|
|
860
|
+
<QRCode value={enrollmentData.authUrl} />
|
|
861
|
+
|
|
862
|
+
<p>Or manually enter this secret: {enrollmentData.secret}</p>
|
|
863
|
+
|
|
864
|
+
<input
|
|
865
|
+
type="text"
|
|
866
|
+
placeholder="Enter 6-digit code"
|
|
867
|
+
value={mfaCode}
|
|
868
|
+
onChange={(e) => setMfaCode(e.target.value)}
|
|
869
|
+
maxLength={6}
|
|
870
|
+
/>
|
|
871
|
+
|
|
872
|
+
<button
|
|
873
|
+
onClick={handleSubmitEnrollment}
|
|
874
|
+
disabled={mfaCode.length !== 6}
|
|
875
|
+
>
|
|
876
|
+
Verify and Enable MFA
|
|
877
|
+
</button>
|
|
878
|
+
</div>
|
|
879
|
+
)}
|
|
880
|
+
</div>
|
|
881
|
+
);
|
|
882
|
+
}
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
#### Verify MFA for Sensitive Operations
|
|
886
|
+
|
|
887
|
+
Use `useInitiateMfaVerification` and `useSubmitMfaVerification` to verify MFA for sensitive operations:
|
|
888
|
+
|
|
889
|
+
```tsx lines
|
|
890
|
+
import {
|
|
891
|
+
useInitiateMfaVerification,
|
|
892
|
+
useSubmitMfaVerification,
|
|
893
|
+
useCurrentUser
|
|
894
|
+
} from "@coinbase/cdp-hooks";
|
|
895
|
+
import { useState } from "react";
|
|
896
|
+
|
|
897
|
+
function MfaVerification() {
|
|
898
|
+
const { initiateMfaVerification } = useInitiateMfaVerification();
|
|
899
|
+
const { submitMfaVerification } = useSubmitMfaVerification();
|
|
900
|
+
const { currentUser } = useCurrentUser();
|
|
901
|
+
const [mfaCode, setMfaCode] = useState("");
|
|
902
|
+
const [verificationInitiated, setVerificationInitiated] = useState(false);
|
|
903
|
+
|
|
904
|
+
const handleSensitiveOperation = async () => {
|
|
905
|
+
try {
|
|
906
|
+
// Step 1: Initiate MFA verification
|
|
907
|
+
await initiateMfaVerification({ mfaMethod: "totp" });
|
|
908
|
+
setVerificationInitiated(true);
|
|
909
|
+
|
|
910
|
+
console.log("MFA verification initiated. Enter your code.");
|
|
911
|
+
} catch (error) {
|
|
912
|
+
console.error("Failed to initiate MFA verification:", error);
|
|
913
|
+
}
|
|
914
|
+
};
|
|
915
|
+
|
|
916
|
+
const handleVerifyMfa = async () => {
|
|
917
|
+
try {
|
|
918
|
+
// Step 2: Submit the 6-digit code from authenticator app
|
|
919
|
+
await submitMfaVerification({
|
|
920
|
+
mfaMethod: "totp",
|
|
921
|
+
mfaCode: mfaCode,
|
|
922
|
+
});
|
|
923
|
+
|
|
924
|
+
console.log("MFA verified successfully");
|
|
925
|
+
setVerificationInitiated(false);
|
|
926
|
+
setMfaCode("");
|
|
927
|
+
|
|
928
|
+
// Now proceed with your sensitive operation
|
|
929
|
+
// e.g., sign a transaction, export private key, etc.
|
|
930
|
+
} catch (error) {
|
|
931
|
+
console.error("MFA verification failed:", error);
|
|
932
|
+
}
|
|
933
|
+
};
|
|
934
|
+
|
|
935
|
+
if (!currentUser) {
|
|
936
|
+
return <div>Please sign in first</div>;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
return (
|
|
940
|
+
<div>
|
|
941
|
+
<h2>Sensitive Operation</h2>
|
|
942
|
+
|
|
943
|
+
{!verificationInitiated ? (
|
|
944
|
+
<button onClick={handleSensitiveOperation}>
|
|
945
|
+
Perform Sensitive Operation
|
|
946
|
+
</button>
|
|
947
|
+
) : (
|
|
948
|
+
<div>
|
|
949
|
+
<p>Enter your MFA code to continue:</p>
|
|
950
|
+
|
|
951
|
+
<input
|
|
952
|
+
type="text"
|
|
953
|
+
placeholder="Enter 6-digit code"
|
|
954
|
+
value={mfaCode}
|
|
955
|
+
onChange={(e) => setMfaCode(e.target.value)}
|
|
956
|
+
maxLength={6}
|
|
957
|
+
/>
|
|
958
|
+
|
|
959
|
+
<button
|
|
960
|
+
onClick={handleVerifyMfa}
|
|
961
|
+
disabled={mfaCode.length !== 6}
|
|
962
|
+
>
|
|
963
|
+
Verify MFA
|
|
964
|
+
</button>
|
|
965
|
+
</div>
|
|
966
|
+
)}
|
|
967
|
+
</div>
|
|
968
|
+
);
|
|
969
|
+
}
|
|
970
|
+
```
|
|
971
|
+
|
|
691
972
|
### View User Information
|
|
692
973
|
|
|
693
974
|
Once the end user has signed in, you can display their information in your application:
|
|
@@ -712,7 +993,7 @@ function UserInformation() {
|
|
|
712
993
|
|
|
713
994
|
<>
|
|
714
995
|
<p>EVM Address (EOA): {evmAddress}</p>
|
|
715
|
-
{user.
|
|
996
|
+
{user.evmSmartAccountObjects?.[0]?.address && (
|
|
716
997
|
<p>Smart Account: {user.evmSmartAccounts[0]}</p>
|
|
717
998
|
)}
|
|
718
999
|
</>
|
|
@@ -856,7 +1137,7 @@ When your application is configured with `solana: { createOnLogin: true }`, you
|
|
|
856
1137
|
|
|
857
1138
|
#### Access Solana Address
|
|
858
1139
|
|
|
859
|
-
Use the `useSolanaAddress` hook to get the user's
|
|
1140
|
+
Use the `useSolanaAddress` hook to get the user's first Solana address:
|
|
860
1141
|
|
|
861
1142
|
```tsx lines
|
|
862
1143
|
import { useSolanaAddress } from "@coinbase/cdp-hooks";
|
|
@@ -1304,7 +1585,7 @@ function CreateSpendPermission() {
|
|
|
1304
1585
|
|
|
1305
1586
|
<button
|
|
1306
1587
|
onClick={handleCreateSpendPermission}
|
|
1307
|
-
disabled={status === "pending" || !currentUser?.
|
|
1588
|
+
disabled={status === "pending" || !currentUser?.evmSmartAccountObjects?.[0]?.address}
|
|
1308
1589
|
>
|
|
1309
1590
|
{status === "pending" ? "Creating..." : "Create Spend Permission"}
|
|
1310
1591
|
</button>
|
|
@@ -1329,7 +1610,7 @@ import { useListSpendPermissions, useCurrentUser } from "@coinbase/cdp-hooks";
|
|
|
1329
1610
|
function SpendPermissionsList() {
|
|
1330
1611
|
const { currentUser } = useCurrentUser();
|
|
1331
1612
|
const { data, error, status, refetch } = useListSpendPermissions({
|
|
1332
|
-
evmSmartAccount: currentUser?.
|
|
1613
|
+
evmSmartAccount: currentUser?.evmSmartAccountObjects?.[0]?.address,
|
|
1333
1614
|
network: "base-sepolia",
|
|
1334
1615
|
pageSize: 10,
|
|
1335
1616
|
enabled: true
|
|
@@ -1423,7 +1704,7 @@ function SendUserOperation() {
|
|
|
1423
1704
|
const { currentUser } = useCurrentUser();
|
|
1424
1705
|
|
|
1425
1706
|
const handleSendUserOperation = async () => {
|
|
1426
|
-
const smartAccount = currentUser?.
|
|
1707
|
+
const smartAccount = currentUser?.evmSmartAccountObjects?.[0]?.address;
|
|
1427
1708
|
if (!smartAccount) return;
|
|
1428
1709
|
|
|
1429
1710
|
try {
|
|
@@ -1692,12 +1973,12 @@ function X402SmartAccountExample() {
|
|
|
1692
1973
|
const { fetchWithPayment } = useX402();
|
|
1693
1974
|
|
|
1694
1975
|
// The hook automatically uses the appropriate account type
|
|
1695
|
-
const accountUsed = currentUser?.
|
|
1976
|
+
const accountUsed = currentUser?.evmSmartAccountObjects?.[0]?.address || currentUser?.evmAccountObjects?.[0]?.address;
|
|
1696
1977
|
|
|
1697
1978
|
return (
|
|
1698
1979
|
<div>
|
|
1699
1980
|
<p>X402 will use account: {accountUsed}</p>
|
|
1700
|
-
<p>Account type: {currentUser?.
|
|
1981
|
+
<p>Account type: {currentUser?.evmSmartAccountObjects?.[0]?.address ? "Smart Account" : "EOA"}</p>
|
|
1701
1982
|
</div>
|
|
1702
1983
|
);
|
|
1703
1984
|
}
|
|
@@ -1712,7 +1993,7 @@ import { useX402, useCurrentUser } from "@coinbase/cdp-hooks";
|
|
|
1712
1993
|
|
|
1713
1994
|
const { currentUser } = useCurrentUser();
|
|
1714
1995
|
const { fetchWithPayment } = useX402({
|
|
1715
|
-
address: currentUser?.
|
|
1996
|
+
address: currentUser?.solanaAccountObjects?.[0]?.address
|
|
1716
1997
|
});
|
|
1717
1998
|
|
|
1718
1999
|
await fetchWithPayment("https://api.example.com/paid-endpoint", {
|
package/dist/esm/index.js
CHANGED
|
@@ -1,66 +1,77 @@
|
|
|
1
1
|
import { APIError as i, OAuth2ProviderType as a } from "@coinbase/cdp-core";
|
|
2
2
|
import { Analytics as e } from "./index2.js";
|
|
3
3
|
import "react";
|
|
4
|
-
import { VERSION as
|
|
4
|
+
import { VERSION as o } from "./index3.js";
|
|
5
5
|
import { CDPContext as p, CDPHooksProvider as S } from "./index4.js";
|
|
6
|
-
import { useAuthenticateWithJWT as
|
|
7
|
-
import { useCreateSpendPermission as
|
|
8
|
-
import { useListSpendPermissions as
|
|
9
|
-
import { useRevokeSpendPermission as
|
|
10
|
-
import { useLinkGoogle as
|
|
11
|
-
import { useLinkApple as
|
|
12
|
-
import { useLinkSms as
|
|
13
|
-
import { useLinkEmail as
|
|
14
|
-
import { useLinkOAuth as
|
|
15
|
-
import { useCreateEvmEoaAccount as
|
|
16
|
-
import { useCreateEvmSmartAccount as
|
|
17
|
-
import { useCreateSolanaAccount as
|
|
18
|
-
import { useX402 as
|
|
19
|
-
|
|
6
|
+
import { useAuthenticateWithJWT as c, useConfig as E, useCurrentUser as x, useEnforceAuthenticated as A, useEnforceUnauthenticated as l, useEvmAccounts as d, useEvmAddress as g, useEvmSmartAccounts as v, useExportEvmAccount as h, useExportSolanaAccount as I, useGetAccessToken as P, useIsInitialized as k, useIsSignedIn as O, useOAuthState as T, useSendEvmTransaction as C, useSendSolanaTransaction as L, useSendUserOperation as M, useSignEvmHash as V, useSignEvmMessage as W, useSignEvmTransaction as y, useSignEvmTypedData as U, useSignInWithEmail as D, useSignInWithOAuth as b, useSignInWithSms as G, useSignOut as H, useSignSolanaMessage as R, useSignSolanaTransaction as z, useSolanaAccounts as F, useSolanaAddress as J, useVerifyEmailOTP as N, useVerifySmsOTP as X, useWaitForUserOperation as j } from "./index5.js";
|
|
7
|
+
import { useCreateSpendPermission as w } from "./index6.js";
|
|
8
|
+
import { useListSpendPermissions as K } from "./index7.js";
|
|
9
|
+
import { useRevokeSpendPermission as Y } from "./index8.js";
|
|
10
|
+
import { useLinkGoogle as _ } from "./index9.js";
|
|
11
|
+
import { useLinkApple as ee } from "./index10.js";
|
|
12
|
+
import { useLinkSms as se } from "./index11.js";
|
|
13
|
+
import { useLinkEmail as te } from "./index12.js";
|
|
14
|
+
import { useLinkOAuth as ue } from "./index13.js";
|
|
15
|
+
import { useCreateEvmEoaAccount as ae } from "./index14.js";
|
|
16
|
+
import { useCreateEvmSmartAccount as pe } from "./index15.js";
|
|
17
|
+
import { useCreateSolanaAccount as fe } from "./index16.js";
|
|
18
|
+
import { useX402 as Ee } from "./index17.js";
|
|
19
|
+
import { useInitiateMfaEnrollment as Ae } from "./index18.js";
|
|
20
|
+
import { useSubmitMfaEnrollment as de } from "./index19.js";
|
|
21
|
+
import { useInitiateMfaVerification as ve } from "./index20.js";
|
|
22
|
+
import { useSubmitMfaVerification as Ie } from "./index21.js";
|
|
23
|
+
e.registerPackageVersion("hooks", o);
|
|
20
24
|
export {
|
|
21
25
|
i as APIError,
|
|
22
26
|
p as CDPContext,
|
|
23
27
|
S as CDPHooksProvider,
|
|
24
28
|
a as OAuth2ProviderType,
|
|
25
|
-
|
|
29
|
+
c as useAuthenticateWithJWT,
|
|
26
30
|
E as useConfig,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
ae as useCreateEvmEoaAccount,
|
|
32
|
+
pe as useCreateEvmSmartAccount,
|
|
33
|
+
fe as useCreateSolanaAccount,
|
|
34
|
+
w as useCreateSpendPermission,
|
|
31
35
|
x as useCurrentUser,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
A as useEnforceAuthenticated,
|
|
37
|
+
l as useEnforceUnauthenticated,
|
|
38
|
+
d as useEvmAccounts,
|
|
39
|
+
g as useEvmAddress,
|
|
40
|
+
v as useEvmSmartAccounts,
|
|
35
41
|
h as useExportEvmAccount,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
T as
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
L as
|
|
42
|
+
I as useExportSolanaAccount,
|
|
43
|
+
P as useGetAccessToken,
|
|
44
|
+
Ae as useInitiateMfaEnrollment,
|
|
45
|
+
ve as useInitiateMfaVerification,
|
|
46
|
+
k as useIsInitialized,
|
|
47
|
+
O as useIsSignedIn,
|
|
48
|
+
ee as useLinkApple,
|
|
49
|
+
te as useLinkEmail,
|
|
50
|
+
_ as useLinkGoogle,
|
|
51
|
+
ue as useLinkOAuth,
|
|
52
|
+
se as useLinkSms,
|
|
53
|
+
K as useListSpendPermissions,
|
|
54
|
+
T as useOAuthState,
|
|
55
|
+
Y as useRevokeSpendPermission,
|
|
56
|
+
C as useSendEvmTransaction,
|
|
57
|
+
L as useSendSolanaTransaction,
|
|
58
|
+
M as useSendUserOperation,
|
|
59
|
+
V as useSignEvmHash,
|
|
52
60
|
W as useSignEvmMessage,
|
|
53
61
|
y as useSignEvmTransaction,
|
|
54
62
|
U as useSignEvmTypedData,
|
|
55
|
-
|
|
56
|
-
|
|
63
|
+
D as useSignInWithEmail,
|
|
64
|
+
b as useSignInWithOAuth,
|
|
57
65
|
G as useSignInWithSms,
|
|
58
66
|
H as useSignOut,
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
R as useSignSolanaMessage,
|
|
68
|
+
z as useSignSolanaTransaction,
|
|
69
|
+
F as useSolanaAccounts,
|
|
70
|
+
J as useSolanaAddress,
|
|
71
|
+
de as useSubmitMfaEnrollment,
|
|
72
|
+
Ie as useSubmitMfaVerification,
|
|
73
|
+
N as useVerifyEmailOTP,
|
|
74
|
+
X as useVerifySmsOTP,
|
|
75
|
+
j as useWaitForUserOperation,
|
|
76
|
+
Ee as useX402
|
|
66
77
|
};
|
package/dist/esm/index10.js
CHANGED
package/dist/esm/index100.js
CHANGED
|
@@ -1,58 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
getDocsUrl: ({ docsBaseUrl: s, docsPath: t = "", docsSlug: e }) => t ? `${s ?? "https://viem.sh"}${t}${e ? `#${e}` : ""}` : void 0,
|
|
4
|
-
version: `viem@${o}`
|
|
5
|
-
};
|
|
6
|
-
class u extends Error {
|
|
7
|
-
constructor(t, e = {}) {
|
|
8
|
-
const i = e.cause instanceof u ? e.cause.details : e.cause?.message ? e.cause.message : e.details, n = e.cause instanceof u && e.cause.docsPath || e.docsPath, a = r.getDocsUrl?.({ ...e, docsPath: n }), l = [
|
|
9
|
-
t || "An error occurred.",
|
|
10
|
-
"",
|
|
11
|
-
...e.metaMessages ? [...e.metaMessages, ""] : [],
|
|
12
|
-
...a ? [`Docs: ${a}`] : [],
|
|
13
|
-
...i ? [`Details: ${i}`] : [],
|
|
14
|
-
...r.version ? [`Version: ${r.version}`] : []
|
|
15
|
-
].join(`
|
|
16
|
-
`);
|
|
17
|
-
super(l, e.cause ? { cause: e.cause } : void 0), Object.defineProperty(this, "details", {
|
|
18
|
-
enumerable: !0,
|
|
19
|
-
configurable: !0,
|
|
20
|
-
writable: !0,
|
|
21
|
-
value: void 0
|
|
22
|
-
}), Object.defineProperty(this, "docsPath", {
|
|
23
|
-
enumerable: !0,
|
|
24
|
-
configurable: !0,
|
|
25
|
-
writable: !0,
|
|
26
|
-
value: void 0
|
|
27
|
-
}), Object.defineProperty(this, "metaMessages", {
|
|
28
|
-
enumerable: !0,
|
|
29
|
-
configurable: !0,
|
|
30
|
-
writable: !0,
|
|
31
|
-
value: void 0
|
|
32
|
-
}), Object.defineProperty(this, "shortMessage", {
|
|
33
|
-
enumerable: !0,
|
|
34
|
-
configurable: !0,
|
|
35
|
-
writable: !0,
|
|
36
|
-
value: void 0
|
|
37
|
-
}), Object.defineProperty(this, "version", {
|
|
38
|
-
enumerable: !0,
|
|
39
|
-
configurable: !0,
|
|
40
|
-
writable: !0,
|
|
41
|
-
value: void 0
|
|
42
|
-
}), Object.defineProperty(this, "name", {
|
|
43
|
-
enumerable: !0,
|
|
44
|
-
configurable: !0,
|
|
45
|
-
writable: !0,
|
|
46
|
-
value: "BaseError"
|
|
47
|
-
}), this.details = i, this.docsPath = n, this.metaMessages = e.metaMessages, this.name = e.name ?? this.name, this.shortMessage = t, this.version = o;
|
|
48
|
-
}
|
|
49
|
-
walk(t) {
|
|
50
|
-
return c(this, t);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
function c(s, t) {
|
|
54
|
-
return t?.(s) ? s : s && typeof s == "object" && "cause" in s && s.cause !== void 0 ? c(s.cause, t) : t ? null : s;
|
|
55
|
-
}
|
|
1
|
+
const e = `Ethereum Signed Message:
|
|
2
|
+
`;
|
|
56
3
|
export {
|
|
57
|
-
|
|
4
|
+
e as presignMessagePrefix
|
|
58
5
|
};
|