@embarkai/ui-kit 0.1.1 → 0.1.3
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 +98 -100
- package/dist/iframe/index.html +1 -1
- package/dist/iframe/kyc/sumsub.html +1 -1
- package/dist/iframe/main.js +479 -483
- package/dist/iframe/main.js.map +1 -1
- package/dist/iframe/oauth/telegram.html +1 -1
- package/dist/iframe/oauth/x.html +1 -1
- package/dist/index.cjs +1388 -1535
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +78 -102
- package/dist/index.d.ts +78 -102
- package/dist/index.js +1223 -1368
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +4 -5
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ React UI components and hooks for EmbarkAI - a secure, user-friendly authenticat
|
|
|
8
8
|
- 🔑 **MPC Key Management** - Distributed key generation with iframe isolation
|
|
9
9
|
- 💼 **Account Abstraction** - ERC-4337 compliant smart contract wallets
|
|
10
10
|
- 🎨 **Pre-built UI Components** - Ready-to-use React components with customizable themes
|
|
11
|
-
- ⚡ **Easy Integration** - Just wrap your app with `
|
|
11
|
+
- ⚡ **Easy Integration** - Just wrap your app with `Provider`
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
14
14
|
|
|
@@ -129,9 +129,9 @@ import {
|
|
|
129
129
|
combineI18NResources,
|
|
130
130
|
LOCAL_STORAGE_I18N_KEY,
|
|
131
131
|
//
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
132
|
+
Provider,
|
|
133
|
+
RainbowKitProvider,
|
|
134
|
+
SessionProvider
|
|
135
135
|
} from '@embarkai/ui-kit'
|
|
136
136
|
//
|
|
137
137
|
import i18n from 'i18next'
|
|
@@ -154,11 +154,11 @@ function Root() {
|
|
|
154
154
|
|
|
155
155
|
return (
|
|
156
156
|
<QueryClientProvider client={queryClient}>
|
|
157
|
-
<
|
|
158
|
-
projectId="your-project-id" // Get from
|
|
157
|
+
<Provider
|
|
158
|
+
projectId="your-project-id" // Get from EmbarkAI Dashboard
|
|
159
159
|
>
|
|
160
|
-
<
|
|
161
|
-
<
|
|
160
|
+
<RainbowKitProvider>
|
|
161
|
+
<SessionProvider>
|
|
162
162
|
<header>
|
|
163
163
|
<h1>{t('common.appname')}</h1>
|
|
164
164
|
</header>
|
|
@@ -166,9 +166,9 @@ function Root() {
|
|
|
166
166
|
<main>
|
|
167
167
|
<span>{t('page1.title')}</span>
|
|
168
168
|
</main>
|
|
169
|
-
</
|
|
170
|
-
</
|
|
171
|
-
</
|
|
169
|
+
</SessionProvider>
|
|
170
|
+
</RainbowKitProvider>
|
|
171
|
+
</Provider>
|
|
172
172
|
</QueryClientProvider>
|
|
173
173
|
)
|
|
174
174
|
}
|
|
@@ -217,14 +217,14 @@ function YourApp() {
|
|
|
217
217
|
|
|
218
218
|
That's it! The `ConnectWalletButton` provides a complete authentication UI with wallet management.
|
|
219
219
|
|
|
220
|
-
> **Note:** Don't forget to wrap your app with `QueryClientProvider` from `@tanstack/react-query` before using `
|
|
220
|
+
> **Note:** Don't forget to wrap your app with `QueryClientProvider` from `@tanstack/react-query` before using `Provider`, otherwise you'll get an error: "No QueryClient set, use QueryClientProvider to set one"
|
|
221
221
|
|
|
222
222
|
## Configuration Options
|
|
223
223
|
|
|
224
224
|
### Basic Configuration
|
|
225
225
|
|
|
226
226
|
```tsx
|
|
227
|
-
<
|
|
227
|
+
<Provider
|
|
228
228
|
projectId="your-project-id" // Required
|
|
229
229
|
initialConfig={{
|
|
230
230
|
network: {
|
|
@@ -234,6 +234,7 @@ That's it! The `ConnectWalletButton` provides a complete authentication UI with
|
|
|
234
234
|
rpcUrl: 'https://beam-rpc.lumia.org',
|
|
235
235
|
explorerUrl: 'https://beam-explorer.lumia.org',
|
|
236
236
|
testnet: true,
|
|
237
|
+
forceChain: false
|
|
237
238
|
},
|
|
238
239
|
}}
|
|
239
240
|
>
|
|
@@ -245,14 +246,14 @@ The SDK uses the following priority for determining the active chain:
|
|
|
245
246
|
|
|
246
247
|
1. **User's explicit selection** - If user manually switched chains in the UI, their choice is preserved (stored in localStorage)
|
|
247
248
|
2. **dApp config `network.chainId`** - Your configured default chain for first-time users
|
|
248
|
-
3. **SDK default** -
|
|
249
|
+
3. **SDK default** - BSC
|
|
249
250
|
|
|
250
251
|
This ensures returning users keep their preferred chain while new users start on your configured network.
|
|
251
252
|
|
|
252
253
|
### Advanced Configuration
|
|
253
254
|
|
|
254
255
|
```tsx
|
|
255
|
-
<
|
|
256
|
+
<Provider
|
|
256
257
|
projectId="your-project-id"
|
|
257
258
|
initialConfig={{
|
|
258
259
|
// UI customization
|
|
@@ -333,28 +334,28 @@ This ensures returning users keep their preferred chain while new users start on
|
|
|
333
334
|
},
|
|
334
335
|
}}
|
|
335
336
|
callbacks={{
|
|
336
|
-
|
|
337
|
+
onConnecting: ({ method, provider }) => {
|
|
337
338
|
console.log('Connecting with:', method, provider);
|
|
338
339
|
},
|
|
339
|
-
|
|
340
|
+
onConnect: ({ address, session }) => {
|
|
340
341
|
console.log('Connected:', address);
|
|
341
342
|
},
|
|
342
|
-
|
|
343
|
+
onAccount: ({ userId, address, session, hasKeyshare }) => {
|
|
343
344
|
console.log('Account ready:', userId);
|
|
344
345
|
},
|
|
345
|
-
|
|
346
|
+
onAccountUpdate: ({ providers }) => {
|
|
346
347
|
console.log('Profile updated:', providers);
|
|
347
348
|
},
|
|
348
|
-
|
|
349
|
+
onDisconnect: ({ address, userId }) => {
|
|
349
350
|
console.log('Disconnected:', address);
|
|
350
351
|
},
|
|
351
|
-
|
|
352
|
+
onError: ({ error, message }) => {
|
|
352
353
|
console.error('Error:', message);
|
|
353
354
|
},
|
|
354
355
|
onWalletReady: (status) => {
|
|
355
356
|
console.log('Wallet ready:', status.ready);
|
|
356
357
|
},
|
|
357
|
-
|
|
358
|
+
onChainChange: ({ chainId, previousChainId }) => {
|
|
358
359
|
console.log('Chain Changed:', { previousChainId, chainId })
|
|
359
360
|
},
|
|
360
361
|
}}
|
|
@@ -363,15 +364,15 @@ This ensures returning users keep their preferred chain while new users start on
|
|
|
363
364
|
|
|
364
365
|
## Using Hooks
|
|
365
366
|
|
|
366
|
-
> **Note:** The `
|
|
367
|
+
> **Note:** The `useSession` hook is based on pure Zustand store so if you're already using useSession hook please consider 2 options: 1) refactor state extarction so it uses zustand state extraction feature. 2) consider using dedicated EmbarkAI shared store values hooks: `useAccountSession`, `useAddress` etc. Otherwise you might experience excessive re-rendering issues as EmbarkAI shares its internal store and might update some state values which should not affect app render.
|
|
367
368
|
|
|
368
369
|
```tsx
|
|
369
|
-
import {
|
|
370
|
+
import { useAccountSession, useLoadingStatus } from '@embarkai/ui-kit'
|
|
370
371
|
|
|
371
372
|
function MyComponent() {
|
|
372
|
-
// const session =
|
|
373
|
-
const session =
|
|
374
|
-
const { isSessionLoading } =
|
|
373
|
+
// const session = useSession(s => s.session) - with prev hook & Zustand state extraction feature, please prefer this instead:
|
|
374
|
+
const session = useAccountSession()
|
|
375
|
+
const { isSessionLoading } = useLoadingStatus()
|
|
375
376
|
|
|
376
377
|
if (isSessionLoading) return <div>Loading...</div>
|
|
377
378
|
|
|
@@ -390,18 +391,18 @@ function MyComponent() {
|
|
|
390
391
|
}
|
|
391
392
|
```
|
|
392
393
|
|
|
393
|
-
###
|
|
394
|
+
### EmbarkAI hared store values hooks
|
|
394
395
|
|
|
395
|
-
- **
|
|
396
|
-
- **
|
|
397
|
-
- **
|
|
398
|
-
- **
|
|
399
|
-
- **
|
|
400
|
-
- **
|
|
401
|
-
- **
|
|
402
|
-
- **
|
|
403
|
-
- **
|
|
404
|
-
- **
|
|
396
|
+
- **useActiveChainId** - Returns current ChainID
|
|
397
|
+
- **useIsMobileView** - Returns boolean indicating if UI is in mobile view mode
|
|
398
|
+
- **useAccountSession** - Returns current user session object with userId, addresses, and auth info
|
|
399
|
+
- **useLoadingStatus** - Returns `{ isSessionLoading, sessionStatus }` for tracking authentication state
|
|
400
|
+
- **useBalance** - Returns wallet balance data: `{ walletBalance, fiatBalance, cryptoRate, fiatSymbol, cryptoSymbol }`
|
|
401
|
+
- **useIFrameReady** - Returns boolean indicating if the MPC iframe is ready for operations
|
|
402
|
+
- **useAddress** - Returns the current user's wallet address
|
|
403
|
+
- **useError** - Returns any error that occurred during authentication or operations
|
|
404
|
+
- **useRecoveryUserId** - Returns userId for account recovery flow
|
|
405
|
+
- **useHasServerVault** - Returns boolean indicating if user has server-side keyshare backup
|
|
405
406
|
|
|
406
407
|
### useSendTransaction - Send Transactions
|
|
407
408
|
|
|
@@ -439,10 +440,10 @@ function TransactionExample() {
|
|
|
439
440
|
For direct control without using the React hook, you can use `sendUserOperation` function:
|
|
440
441
|
|
|
441
442
|
```tsx
|
|
442
|
-
import { sendUserOperation,
|
|
443
|
+
import { sendUserOperation, useAccountSession } from '@embarkai/ui-kit'
|
|
443
444
|
|
|
444
445
|
function DirectTransactionExample() {
|
|
445
|
-
const session =
|
|
446
|
+
const session = useAccountSession()
|
|
446
447
|
|
|
447
448
|
const handleSend = async () => {
|
|
448
449
|
if (!session) {
|
|
@@ -453,7 +454,7 @@ function DirectTransactionExample() {
|
|
|
453
454
|
try {
|
|
454
455
|
// Send transaction directly with full control
|
|
455
456
|
const userOpHash = await sendUserOperation(
|
|
456
|
-
session, // Required: session from
|
|
457
|
+
session, // Required: session from useAccountSession
|
|
457
458
|
'0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb', // to address
|
|
458
459
|
'1000000000000000000', // value in wei (1 ETH)
|
|
459
460
|
'0x', // data (optional contract call)
|
|
@@ -483,10 +484,10 @@ Deploy the smart account contract immediately after registration. This is **opti
|
|
|
483
484
|
**Smart behavior:** Automatically checks if account is already deployed and skips transaction to save gas.
|
|
484
485
|
|
|
485
486
|
```tsx
|
|
486
|
-
import { deployAccount,
|
|
487
|
+
import { deployAccount, useAccountSession } from '@embarkai/ui-kit'
|
|
487
488
|
|
|
488
489
|
function DeployAccountExample() {
|
|
489
|
-
const session =
|
|
490
|
+
const session = useAccountSession()
|
|
490
491
|
|
|
491
492
|
const handleDeploy = async () => {
|
|
492
493
|
if (!session) return
|
|
@@ -541,10 +542,10 @@ const hash = await deployAccount(session, 'economy', { force: true })
|
|
|
541
542
|
Sign structured data according to [EIP-712](https://eips.ethereum.org/EIPS/eip-712) standard. This is commonly used for off-chain signatures in dApps (e.g., NFT marketplace orders, gasless transactions, permit signatures).
|
|
542
543
|
|
|
543
544
|
```tsx
|
|
544
|
-
import { signTypedData,
|
|
545
|
+
import { signTypedData, useAccountSession } from '@embarkai/ui-kit'
|
|
545
546
|
|
|
546
547
|
function SignatureExample() {
|
|
547
|
-
const session =
|
|
548
|
+
const session = useAccountSession()
|
|
548
549
|
|
|
549
550
|
const handleSign = async () => {
|
|
550
551
|
if (!session) return
|
|
@@ -642,10 +643,10 @@ In Account Abstraction (ERC-4337), there are **two addresses**:
|
|
|
642
643
|
### prepareUserOperation - Prepare for Backend Submission
|
|
643
644
|
|
|
644
645
|
```tsx
|
|
645
|
-
import { prepareUserOperation,
|
|
646
|
+
import { prepareUserOperation, useAccountSession } from '@embarkai/ui-kit'
|
|
646
647
|
|
|
647
648
|
function BackendSubmissionExample() {
|
|
648
|
-
const session =
|
|
649
|
+
const session = useAccountSession()
|
|
649
650
|
|
|
650
651
|
const handlePrepare = async () => {
|
|
651
652
|
if (!session) return
|
|
@@ -709,10 +710,7 @@ const submittedUserOpHash = await sendUserOperationRaw(userOp, { chainId: CHAIN_
|
|
|
709
710
|
const waitForReceipt = async (hash: string, maxAttempts = 60, delayMs = 1000) => {
|
|
710
711
|
for (let i = 0; i < maxAttempts; i++) {
|
|
711
712
|
// REQUIRES bundlerUrl parameter
|
|
712
|
-
const receipt = await getUserOperationReceipt(
|
|
713
|
-
hash as `0x${string}`,
|
|
714
|
-
chainConfig.bundlerUrl
|
|
715
|
-
)
|
|
713
|
+
const receipt = await getUserOperationReceipt(hash as `0x${string}`, chainConfig.bundlerUrl)
|
|
716
714
|
if (receipt) {
|
|
717
715
|
return {
|
|
718
716
|
success: receipt.success,
|
|
@@ -735,25 +733,25 @@ return {
|
|
|
735
733
|
|
|
736
734
|
**Network Configuration:**
|
|
737
735
|
|
|
738
|
-
| Network
|
|
739
|
-
|
|
740
|
-
| Lumia Testnet (Beam)
|
|
741
|
-
| Lumia Mainnet (Prism) | 994873017
|
|
736
|
+
| Network | Chain ID | Bundler URL |
|
|
737
|
+
| --------------------- | ---------- | ------------------------------------------- |
|
|
738
|
+
| Lumia Testnet (Beam) | 2030232745 | https://api.lumiapassport.com/rundler |
|
|
739
|
+
| Lumia Mainnet (Prism) | 994873017 | https://api.lumiapassport.com/rundler-prism |
|
|
742
740
|
|
|
743
|
-
###
|
|
741
|
+
### useOpenPage - Programmatic EmbarkAI Dialog Control
|
|
744
742
|
|
|
745
|
-
Control the
|
|
743
|
+
Control the EmbarkAI dialog programmatically.
|
|
746
744
|
|
|
747
745
|
```tsx
|
|
748
|
-
import { PageKey,
|
|
746
|
+
import { PageKey, useOpenPage } from '@embarkai/ui-kit'
|
|
749
747
|
|
|
750
748
|
function CustomAuthButton() {
|
|
751
|
-
const { isOpen, open:
|
|
749
|
+
const { isOpen, open: openEmbarkAI, close } = useOpenPage()
|
|
752
750
|
|
|
753
751
|
return (
|
|
754
752
|
<div>
|
|
755
|
-
<button onClick={() =>
|
|
756
|
-
<button onClick={() =>
|
|
753
|
+
<button onClick={() => openEmbarkAI(PageKey.AUTH)}>Sign In</button>
|
|
754
|
+
<button onClick={() => openEmbarkAI(PageKey.RECEIVE)}>Receive LUMIA</button>
|
|
757
755
|
|
|
758
756
|
<button onClick={close}>Close Dialog</button>
|
|
759
757
|
</div>
|
|
@@ -763,7 +761,7 @@ function CustomAuthButton() {
|
|
|
763
761
|
|
|
764
762
|
### ThemeToggle - Quick Theme Switcher
|
|
765
763
|
|
|
766
|
-
Pre-built theme toggle button component to use in combo with
|
|
764
|
+
Pre-built theme toggle button component to use in combo with useColorMode.
|
|
767
765
|
|
|
768
766
|
```tsx
|
|
769
767
|
import { ThemeToggle } from '@embarkai/ui-kit'
|
|
@@ -837,14 +835,14 @@ Global Passport window view can be redefined via config prop by providing specif
|
|
|
837
835
|
|
|
838
836
|
box-shadow:
|
|
839
837
|
0 0 8px rgba(14, 14, 14, 0.1),
|
|
840
|
-
inset 0 0 0 1px var(--
|
|
838
|
+
inset 0 0 0 1px var(--account-abstraction-bd);
|
|
841
839
|
}
|
|
842
840
|
```
|
|
843
841
|
|
|
844
842
|
```tsx
|
|
845
843
|
import 'index.css'
|
|
846
844
|
|
|
847
|
-
<
|
|
845
|
+
<Provider
|
|
848
846
|
...
|
|
849
847
|
initialConfig={{
|
|
850
848
|
...
|
|
@@ -859,13 +857,13 @@ import 'index.css'
|
|
|
859
857
|
|
|
860
858
|
### Passport styles
|
|
861
859
|
|
|
862
|
-
Passport provides global hook for Light/Dark modes -
|
|
860
|
+
Passport provides global hook for Light/Dark modes - useColorMode - use it within yor application instead of any local mode declaration.
|
|
863
861
|
|
|
864
862
|
```tsx
|
|
865
|
-
import {
|
|
863
|
+
import { useColorMode } from '@embarkai/ui-kit'
|
|
866
864
|
|
|
867
865
|
function YourAnyComponent() {
|
|
868
|
-
const { colorMode, setColorMode } =
|
|
866
|
+
const { colorMode, setColorMode } = useColorMode()
|
|
869
867
|
|
|
870
868
|
return (
|
|
871
869
|
<div>
|
|
@@ -882,57 +880,57 @@ Values will be automatically applied according to selected colorMode.
|
|
|
882
880
|
The simpliest way to customize cssv is via app index.css file:
|
|
883
881
|
|
|
884
882
|
```css
|
|
885
|
-
.
|
|
886
|
-
.
|
|
883
|
+
.account-abstraction-ui-scope[data-current-theme-mode='light'],
|
|
884
|
+
.account-abstraction-ui-scope[data-current-theme-mode='dark'] {
|
|
887
885
|
/* fixed cssv */
|
|
888
|
-
--
|
|
889
|
-
--
|
|
890
|
-
--
|
|
891
|
-
--
|
|
892
|
-
--
|
|
886
|
+
--account-abstraction-maw: 384px;
|
|
887
|
+
--account-abstraction-pd: 12px;
|
|
888
|
+
--account-abstraction-gap: 10px;
|
|
889
|
+
--account-abstraction-bdrs: 20px;
|
|
890
|
+
--account-abstraction-element-bdrs: 10px;
|
|
893
891
|
|
|
894
892
|
/** overlay */
|
|
895
|
-
--
|
|
896
|
-
--
|
|
893
|
+
--account-abstraction-overlay: rgba(255, 255, 255, 0.8);
|
|
894
|
+
--account-abstraction-backdrop-blur: 10px;
|
|
897
895
|
|
|
898
896
|
/** surface backgrounds */
|
|
899
|
-
--
|
|
897
|
+
--account-abstraction-bg: #ffffff;
|
|
900
898
|
|
|
901
899
|
/** text */
|
|
902
|
-
--
|
|
903
|
-
--
|
|
904
|
-
--
|
|
905
|
-
--
|
|
906
|
-
--
|
|
900
|
+
--account-abstraction-fg: #000000;
|
|
901
|
+
--account-abstraction-fg-h: rgba(0, 0, 0, 0.6);
|
|
902
|
+
--account-abstraction-fg-a: rgba(0, 0, 0, 0.4);
|
|
903
|
+
--account-abstraction-fg-inverted: #ffffff;
|
|
904
|
+
--account-abstraction-fg-muted: rgba(0, 0, 0, 0.6);
|
|
907
905
|
|
|
908
906
|
/** backgrounds i.e. buttons bg etc */
|
|
909
|
-
--
|
|
910
|
-
--
|
|
911
|
-
--
|
|
907
|
+
--account-abstraction-primary: #000000;
|
|
908
|
+
--account-abstraction-primary-h: rgba(0, 0, 0, 0.8);
|
|
909
|
+
--account-abstraction-primary-a: rgba(0, 0, 0, 0.6);
|
|
912
910
|
|
|
913
|
-
--
|
|
914
|
-
--
|
|
915
|
-
--
|
|
911
|
+
--account-abstraction-secondary: #e4e4e4;
|
|
912
|
+
--account-abstraction-secondary-h: rgba(228, 228, 228, 0.8);
|
|
913
|
+
--account-abstraction-secondary-a: rgba(228, 228, 228, 0.6);
|
|
916
914
|
|
|
917
915
|
/** borders */
|
|
918
|
-
--
|
|
919
|
-
--
|
|
916
|
+
--account-abstraction-bd: #ebebeb;
|
|
917
|
+
--account-abstraction-bd-intense: rgb(169, 169, 169);
|
|
920
918
|
|
|
921
919
|
/** shadows */
|
|
922
|
-
--
|
|
920
|
+
--account-abstraction-shadow-c: rgba(0, 0, 0, 0.1);
|
|
923
921
|
|
|
924
922
|
/** highlight colors */
|
|
925
|
-
--
|
|
926
|
-
--
|
|
923
|
+
--account-abstraction-info: #000000;
|
|
924
|
+
--account-abstraction-bg-info: #e4e4e4;
|
|
927
925
|
|
|
928
|
-
--
|
|
929
|
-
--
|
|
926
|
+
--account-abstraction-success: #000000;
|
|
927
|
+
--account-abstraction-bg-success: #21ff51;
|
|
930
928
|
|
|
931
|
-
--
|
|
932
|
-
--
|
|
929
|
+
--account-abstraction-warning: #000000;
|
|
930
|
+
--account-abstraction-bg-warning: #e9fa00;
|
|
933
931
|
|
|
934
|
-
--
|
|
935
|
-
--
|
|
932
|
+
--account-abstraction-error: #ffffff;
|
|
933
|
+
--account-abstraction-bg-error: #d6204e;
|
|
936
934
|
}
|
|
937
935
|
```
|
|
938
936
|
|
|
@@ -941,7 +939,7 @@ The simpliest way to customize cssv is via app index.css file:
|
|
|
941
939
|
Full TypeScript support with exported types:
|
|
942
940
|
|
|
943
941
|
```tsx
|
|
944
|
-
import type { AuthProvider,
|
|
942
|
+
import type { AuthProvider, ProviderConfig, User, WalletInfo } from '@embarkai/ui-kit'
|
|
945
943
|
```
|
|
946
944
|
|
|
947
945
|
## Examples
|
package/dist/iframe/index.html
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
<meta http-equiv="X-Content-Type-Options" content="nosniff" />
|
|
16
16
|
<meta http-equiv="Referrer-Policy" content="strict-origin-when-cross-origin" />
|
|
17
17
|
|
|
18
|
-
<title>
|
|
18
|
+
<title>EmbarkAI Secure Wallet - iframe version 0.1.3</title>
|
|
19
19
|
|
|
20
20
|
<!-- Styles will be injected by build process -->
|
|
21
21
|
<style>
|