@lumiapassport/ui-kit 1.8.0 → 1.9.0
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 +56 -0
- package/dist/iframe/index.html +1 -1
- package/dist/iframe/main.js +36 -11
- package/dist/iframe/main.js.map +1 -1
- package/dist/index.cjs +40 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -1
- package/dist/index.d.ts +33 -1
- package/dist/index.js +39 -11
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -340,6 +340,62 @@ function DirectTransactionExample() {
|
|
|
340
340
|
- ✅ Use `useSendTransaction()` hook for React components (automatic session management)
|
|
341
341
|
- ✅ Use `sendUserOperation()` function for custom logic, utility functions, or non-React code
|
|
342
342
|
|
|
343
|
+
### deployAccount - Deploy Smart Account (Optional)
|
|
344
|
+
|
|
345
|
+
Deploy the smart account contract immediately after registration. This is **optional** - accounts are automatically deployed on first transaction.
|
|
346
|
+
|
|
347
|
+
**Smart behavior:** Automatically checks if account is already deployed and skips transaction to save gas.
|
|
348
|
+
|
|
349
|
+
```tsx
|
|
350
|
+
import { deployAccount, useLumiaPassportSession } from '@lumiapassport/ui-kit';
|
|
351
|
+
|
|
352
|
+
function DeployAccountExample() {
|
|
353
|
+
const { session } = useLumiaPassportSession();
|
|
354
|
+
|
|
355
|
+
const handleDeploy = async () => {
|
|
356
|
+
if (!session) return;
|
|
357
|
+
|
|
358
|
+
try {
|
|
359
|
+
// Deploy account with minimal gas cost (skips if already deployed)
|
|
360
|
+
const userOpHash = await deployAccount(session, 'economy');
|
|
361
|
+
|
|
362
|
+
if (userOpHash) {
|
|
363
|
+
console.log('Account deployed:', userOpHash);
|
|
364
|
+
} else {
|
|
365
|
+
console.log('Account already deployed, skipped');
|
|
366
|
+
}
|
|
367
|
+
} catch (error) {
|
|
368
|
+
console.error('Deployment failed:', error);
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
return <button onClick={handleDeploy}>Deploy Account</button>;
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
**Return values:**
|
|
377
|
+
- Returns `userOpHash` (string) - if deployment was needed and executed
|
|
378
|
+
- Returns `null` - if account already deployed (saves gas)
|
|
379
|
+
|
|
380
|
+
**Advanced usage:**
|
|
381
|
+
```tsx
|
|
382
|
+
// Force deployment even if already deployed (not recommended)
|
|
383
|
+
const hash = await deployAccount(session, 'economy', { force: true });
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
**Why use this?**
|
|
387
|
+
- ✅ **Pre-deploy** account before first real transaction
|
|
388
|
+
- ✅ **No user consent** required (safe minimal operation)
|
|
389
|
+
- ✅ **Cleaner UX** - separate deployment from first payment
|
|
390
|
+
- ✅ **Smart gas savings** - auto-skips if already deployed
|
|
391
|
+
- ⚠️ **Optional** - accounts auto-deploy on first transaction anyway
|
|
392
|
+
|
|
393
|
+
**How it works:**
|
|
394
|
+
1. Checks if smart account contract exists on-chain
|
|
395
|
+
2. If exists: returns `null` immediately (no gas cost)
|
|
396
|
+
3. If not exists: sends minimal UserOperation (`to=0x0, value=0, data=0x`)
|
|
397
|
+
4. Factory deploys contract without user confirmation
|
|
398
|
+
|
|
343
399
|
### signTypedData - Sign EIP712 Structured Messages
|
|
344
400
|
|
|
345
401
|
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).
|
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>Lumia Passport Secure Wallet - iframe version 1.
|
|
18
|
+
<title>Lumia Passport Secure Wallet - iframe version 1.9.0</title>
|
|
19
19
|
|
|
20
20
|
<!-- Styles will be injected by build process -->
|
|
21
21
|
<style>
|
package/dist/iframe/main.js
CHANGED
|
@@ -1085,7 +1085,6 @@ async function uploadShareToVault(encryptedShare, accessToken) {
|
|
|
1085
1085
|
"Authorization": `Bearer ${token}`,
|
|
1086
1086
|
"Idempotency-Key": idempotencyKey
|
|
1087
1087
|
},
|
|
1088
|
-
credentials: "include",
|
|
1089
1088
|
body: JSON.stringify(encryptedShare)
|
|
1090
1089
|
});
|
|
1091
1090
|
if (!response.ok) {
|
|
@@ -1110,8 +1109,7 @@ async function downloadShareFromVault(accessToken) {
|
|
|
1110
1109
|
"Authorization": `Bearer ${token}`,
|
|
1111
1110
|
"X-Client-Device-Id": "lumia-ui-kit",
|
|
1112
1111
|
"X-Client-Device-Name": "Lumia UI Kit"
|
|
1113
|
-
}
|
|
1114
|
-
credentials: "include"
|
|
1112
|
+
}
|
|
1115
1113
|
});
|
|
1116
1114
|
if (!response.ok) {
|
|
1117
1115
|
if (response.status === 404) {
|
|
@@ -2620,6 +2618,34 @@ var SigningManager = class extends TokenRefreshApiClient {
|
|
|
2620
2618
|
throw new Error("Failed to initialize signing WASM module");
|
|
2621
2619
|
}
|
|
2622
2620
|
}
|
|
2621
|
+
/**
|
|
2622
|
+
* Check if transaction is a minimal safe operation (account deployment)
|
|
2623
|
+
*
|
|
2624
|
+
* Minimal operations are safe to auto-approve without user consent:
|
|
2625
|
+
* - to: 0x0000000000000000000000000000000000000000 (burn address)
|
|
2626
|
+
* - value: 0 (no funds transfer)
|
|
2627
|
+
* - data: 0x (no contract call)
|
|
2628
|
+
*
|
|
2629
|
+
* This is used for smart account deployment without spending any funds.
|
|
2630
|
+
*/
|
|
2631
|
+
isMinimalSafeOperation(transaction) {
|
|
2632
|
+
const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
2633
|
+
const ZERO_VALUE = "0";
|
|
2634
|
+
const EMPTY_DATA = "0x";
|
|
2635
|
+
const to = transaction.to?.toLowerCase();
|
|
2636
|
+
const value = transaction.value?.toString() || "0";
|
|
2637
|
+
const data = transaction.data?.toLowerCase() || "0x";
|
|
2638
|
+
const isMinimal = to === ZERO_ADDRESS.toLowerCase() && (value === ZERO_VALUE || value === "0x0") && (data === EMPTY_DATA || data === "0x0");
|
|
2639
|
+
if (isMinimal) {
|
|
2640
|
+
console.log("[iframe][Sign] Detected minimal safe operation:", {
|
|
2641
|
+
to,
|
|
2642
|
+
value,
|
|
2643
|
+
data,
|
|
2644
|
+
reason: "Account deployment - no funds at risk"
|
|
2645
|
+
});
|
|
2646
|
+
}
|
|
2647
|
+
return isMinimal;
|
|
2648
|
+
}
|
|
2623
2649
|
/**
|
|
2624
2650
|
* Fetch project metadata from public API (with caching)
|
|
2625
2651
|
*/
|
|
@@ -2631,9 +2657,7 @@ var SigningManager = class extends TokenRefreshApiClient {
|
|
|
2631
2657
|
return cached.data;
|
|
2632
2658
|
}
|
|
2633
2659
|
try {
|
|
2634
|
-
const response = await fetch(`${this.METADATA_API_URL}/${projectId}/metadata
|
|
2635
|
-
credentials: "include"
|
|
2636
|
-
});
|
|
2660
|
+
const response = await fetch(`${this.METADATA_API_URL}/${projectId}/metadata`);
|
|
2637
2661
|
if (!response.ok) {
|
|
2638
2662
|
console.warn(`[iframe][Sign] Failed to fetch project metadata: ${response.status}`);
|
|
2639
2663
|
return null;
|
|
@@ -2668,8 +2692,9 @@ var SigningManager = class extends TokenRefreshApiClient {
|
|
|
2668
2692
|
website: origin,
|
|
2669
2693
|
domains: [origin]
|
|
2670
2694
|
};
|
|
2695
|
+
const isMinimalOperation = this.isMinimalSafeOperation(transaction);
|
|
2671
2696
|
const isTrusted = this.trustedApps.isTrusted(userId, projectId, origin);
|
|
2672
|
-
if (!isTrusted) {
|
|
2697
|
+
if (!isTrusted && !isMinimalOperation) {
|
|
2673
2698
|
const risk = await this.assessRisk(transaction);
|
|
2674
2699
|
const confirmResult = await this.showConfirmationDialog(
|
|
2675
2700
|
userId,
|
|
@@ -2685,6 +2710,8 @@ var SigningManager = class extends TokenRefreshApiClient {
|
|
|
2685
2710
|
if (confirmResult.trustApp) {
|
|
2686
2711
|
this.trustedApps.addTrustedApp(userId, projectId, origin);
|
|
2687
2712
|
}
|
|
2713
|
+
} else if (isMinimalOperation) {
|
|
2714
|
+
console.log("[iframe][Sign] Auto-approving minimal safe operation (account deployment)");
|
|
2688
2715
|
}
|
|
2689
2716
|
const digest32 = transaction.digest32 || this.computeTransactionHash(transaction);
|
|
2690
2717
|
const signature = await this.performMPCSigning(userId, keyshareData, digest32, projectId, accessToken);
|
|
@@ -3191,9 +3218,7 @@ var AuthorizationManager = class {
|
|
|
3191
3218
|
return cached.data;
|
|
3192
3219
|
}
|
|
3193
3220
|
try {
|
|
3194
|
-
const response = await fetch(`${this.METADATA_API_URL}/${projectId}/metadata
|
|
3195
|
-
credentials: "include"
|
|
3196
|
-
});
|
|
3221
|
+
const response = await fetch(`${this.METADATA_API_URL}/${projectId}/metadata`);
|
|
3197
3222
|
if (!response.ok) {
|
|
3198
3223
|
console.warn(`[iframe][Auth] Failed to fetch project metadata: ${response.status}`);
|
|
3199
3224
|
return null;
|
|
@@ -3930,7 +3955,7 @@ var BackupManager = class {
|
|
|
3930
3955
|
};
|
|
3931
3956
|
|
|
3932
3957
|
// src/iframe/main.ts
|
|
3933
|
-
var IFRAME_VERSION = "1.
|
|
3958
|
+
var IFRAME_VERSION = "1.9.0";
|
|
3934
3959
|
var IframeWallet = class {
|
|
3935
3960
|
constructor() {
|
|
3936
3961
|
console.log("=".repeat(60));
|