@lumiapassport/ui-kit 1.1.0 → 1.2.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/dist/index.d.cts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import React__default from 'react';
3
+ import { UserOperationV07, UserOperationV06 } from '@lumiapassport/core/bundler';
3
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
5
  import * as viem from 'viem';
5
6
  import { Chain, Hash as Hash$1, TransactionReceipt } from 'viem';
@@ -173,6 +174,22 @@ interface AccountSession$1 {
173
174
  address: `0x${string}`;
174
175
  }
175
176
  declare function sendUserOperation(session: AccountSession$1, callTarget: `0x${string}`, amountWei: string, innerData?: `0x${string}`, feeType?: 'economy' | 'standard' | 'fast', entryPointVersion?: 'v0.6' | 'v0.7'): Promise<`0x${string}`>;
177
+ /**
178
+ * Prepare and sign a UserOperation without sending it to the bundler.
179
+ * Returns the signed UserOp and its hash for backend verification and submission.
180
+ *
181
+ * @param session - Account session with signing credentials
182
+ * @param callTarget - Target address for the transaction
183
+ * @param amountWei - Amount in wei to send
184
+ * @param innerData - Call data for the transaction
185
+ * @param feeType - Fee tier: 'economy', 'standard', or 'fast'
186
+ * @param entryPointVersion - EntryPoint version: 'v0.6' or 'v0.7'
187
+ * @returns Object with signed UserOperation and its hash
188
+ */
189
+ declare function prepareUserOperation(session: AccountSession$1, callTarget: `0x${string}`, amountWei: string, innerData?: `0x${string}`, feeType?: 'economy' | 'standard' | 'fast', entryPointVersion?: 'v0.6' | 'v0.7'): Promise<{
190
+ userOp: UserOperationV07 | UserOperationV06;
191
+ userOpHash: `0x${string}`;
192
+ }>;
176
193
 
177
194
  type AccountSession = AccountSession$1;
178
195
  interface SessionState {
@@ -795,4 +812,4 @@ declare function useLumiaPassportLinkedProfiles(): {
795
812
  readonly refresh: () => Promise<void>;
796
813
  };
797
814
 
798
- export { type AccountSession$1 as AccountSession, Address, type AddressProps, type Asset, ConnectWalletButton, type ConnectWalletButtonProps, Hash, type HashProps, KeyshareBackup, LUMIA_EXPLORER_URL, LumiaLogo, type LumiaPassportCallbacks, type LumiaPassportConfig, LumiaPassportProvider, type LumiaPassportProviderProps, LumiaRainbowKitProvider, type LumiaRainbowKitProviderProps, LumiaSessionProvider, type LumiaSessionProviderProps, LumiaWagmiProvider, type SendTransactionParams, type SendTransactionResult, type Theme, ThemeToggle, type TokenBalance, type Transaction, TransactionsList, type UpdateProfileRequest, type UseSendTransactionReturn, type UseUserOpStatusOptions, type UseUserOpStatusReturn, type UserOpMempool, type UserOpReceipt, type SendTransactionParams$1 as UserOpSendTransactionParams, type UserOpState, UserOpStatus, type UserOpStatusProps, type UserOperation, type UserProfile, getUserProfile, lumiaBeam, queryClient, sendUserOperation, updateUserProfile, useAssets, useLumiaPassportConfig, useLumiaPassportLinkedProfiles, useLumiaSession, useSendTransaction, useSmartAccountTransactions, useTheme, useTokenBalance, useTokenInfo, useTransactions, useUserOpStatus, wagmiConfig };
815
+ export { type AccountSession$1 as AccountSession, Address, type AddressProps, type Asset, ConnectWalletButton, type ConnectWalletButtonProps, Hash, type HashProps, KeyshareBackup, LUMIA_EXPLORER_URL, LumiaLogo, type LumiaPassportCallbacks, type LumiaPassportConfig, LumiaPassportProvider, type LumiaPassportProviderProps, LumiaRainbowKitProvider, type LumiaRainbowKitProviderProps, LumiaSessionProvider, type LumiaSessionProviderProps, LumiaWagmiProvider, type SendTransactionParams, type SendTransactionResult, type Theme, ThemeToggle, type TokenBalance, type Transaction, TransactionsList, type UpdateProfileRequest, type UseSendTransactionReturn, type UseUserOpStatusOptions, type UseUserOpStatusReturn, type UserOpMempool, type UserOpReceipt, type SendTransactionParams$1 as UserOpSendTransactionParams, type UserOpState, UserOpStatus, type UserOpStatusProps, type UserOperation, type UserProfile, getUserProfile, lumiaBeam, prepareUserOperation, queryClient, sendUserOperation, updateUserProfile, useAssets, useLumiaPassportConfig, useLumiaPassportLinkedProfiles, useLumiaSession, useSendTransaction, useSmartAccountTransactions, useTheme, useTokenBalance, useTokenInfo, useTransactions, useUserOpStatus, wagmiConfig };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import React__default from 'react';
3
+ import { UserOperationV07, UserOperationV06 } from '@lumiapassport/core/bundler';
3
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
5
  import * as viem from 'viem';
5
6
  import { Chain, Hash as Hash$1, TransactionReceipt } from 'viem';
@@ -173,6 +174,22 @@ interface AccountSession$1 {
173
174
  address: `0x${string}`;
174
175
  }
175
176
  declare function sendUserOperation(session: AccountSession$1, callTarget: `0x${string}`, amountWei: string, innerData?: `0x${string}`, feeType?: 'economy' | 'standard' | 'fast', entryPointVersion?: 'v0.6' | 'v0.7'): Promise<`0x${string}`>;
177
+ /**
178
+ * Prepare and sign a UserOperation without sending it to the bundler.
179
+ * Returns the signed UserOp and its hash for backend verification and submission.
180
+ *
181
+ * @param session - Account session with signing credentials
182
+ * @param callTarget - Target address for the transaction
183
+ * @param amountWei - Amount in wei to send
184
+ * @param innerData - Call data for the transaction
185
+ * @param feeType - Fee tier: 'economy', 'standard', or 'fast'
186
+ * @param entryPointVersion - EntryPoint version: 'v0.6' or 'v0.7'
187
+ * @returns Object with signed UserOperation and its hash
188
+ */
189
+ declare function prepareUserOperation(session: AccountSession$1, callTarget: `0x${string}`, amountWei: string, innerData?: `0x${string}`, feeType?: 'economy' | 'standard' | 'fast', entryPointVersion?: 'v0.6' | 'v0.7'): Promise<{
190
+ userOp: UserOperationV07 | UserOperationV06;
191
+ userOpHash: `0x${string}`;
192
+ }>;
176
193
 
177
194
  type AccountSession = AccountSession$1;
178
195
  interface SessionState {
@@ -795,4 +812,4 @@ declare function useLumiaPassportLinkedProfiles(): {
795
812
  readonly refresh: () => Promise<void>;
796
813
  };
797
814
 
798
- export { type AccountSession$1 as AccountSession, Address, type AddressProps, type Asset, ConnectWalletButton, type ConnectWalletButtonProps, Hash, type HashProps, KeyshareBackup, LUMIA_EXPLORER_URL, LumiaLogo, type LumiaPassportCallbacks, type LumiaPassportConfig, LumiaPassportProvider, type LumiaPassportProviderProps, LumiaRainbowKitProvider, type LumiaRainbowKitProviderProps, LumiaSessionProvider, type LumiaSessionProviderProps, LumiaWagmiProvider, type SendTransactionParams, type SendTransactionResult, type Theme, ThemeToggle, type TokenBalance, type Transaction, TransactionsList, type UpdateProfileRequest, type UseSendTransactionReturn, type UseUserOpStatusOptions, type UseUserOpStatusReturn, type UserOpMempool, type UserOpReceipt, type SendTransactionParams$1 as UserOpSendTransactionParams, type UserOpState, UserOpStatus, type UserOpStatusProps, type UserOperation, type UserProfile, getUserProfile, lumiaBeam, queryClient, sendUserOperation, updateUserProfile, useAssets, useLumiaPassportConfig, useLumiaPassportLinkedProfiles, useLumiaSession, useSendTransaction, useSmartAccountTransactions, useTheme, useTokenBalance, useTokenInfo, useTransactions, useUserOpStatus, wagmiConfig };
815
+ export { type AccountSession$1 as AccountSession, Address, type AddressProps, type Asset, ConnectWalletButton, type ConnectWalletButtonProps, Hash, type HashProps, KeyshareBackup, LUMIA_EXPLORER_URL, LumiaLogo, type LumiaPassportCallbacks, type LumiaPassportConfig, LumiaPassportProvider, type LumiaPassportProviderProps, LumiaRainbowKitProvider, type LumiaRainbowKitProviderProps, LumiaSessionProvider, type LumiaSessionProviderProps, LumiaWagmiProvider, type SendTransactionParams, type SendTransactionResult, type Theme, ThemeToggle, type TokenBalance, type Transaction, TransactionsList, type UpdateProfileRequest, type UseSendTransactionReturn, type UseUserOpStatusOptions, type UseUserOpStatusReturn, type UserOpMempool, type UserOpReceipt, type SendTransactionParams$1 as UserOpSendTransactionParams, type UserOpState, UserOpStatus, type UserOpStatusProps, type UserOperation, type UserProfile, getUserProfile, lumiaBeam, prepareUserOperation, queryClient, sendUserOperation, updateUserProfile, useAssets, useLumiaPassportConfig, useLumiaPassportLinkedProfiles, useLumiaSession, useSendTransaction, useSmartAccountTransactions, useTheme, useTokenBalance, useTokenInfo, useTransactions, useUserOpStatus, wagmiConfig };
package/dist/index.js CHANGED
@@ -5272,6 +5272,208 @@ async function sendUserOperation(session, callTarget, amountWei, innerData = "0x
5272
5272
  }
5273
5273
  return hash;
5274
5274
  }
5275
+ async function prepareUserOperation(session, callTarget, amountWei, innerData = "0x", feeType = "standard", entryPointVersion = "v0.7") {
5276
+ const entryPointAddress = entryPointVersion === "v0.6" ? ENTRYPOINT_V06 : ENTRYPOINT_V07;
5277
+ const amountWeiBigInt = BigInt(amountWei);
5278
+ const isMinimalTest = callTarget === "0x0000000000000000000000000000000000000000" && amountWei === "0" && innerData === "0x";
5279
+ let callData;
5280
+ if (isMinimalTest) {
5281
+ callData = "0x";
5282
+ } else {
5283
+ callData = encodeFunctionData({ abi: executeAbi, functionName: "execute", args: [callTarget, amountWeiBigInt, innerData] });
5284
+ }
5285
+ let isDeployed = false;
5286
+ let deploymentMethod = "unknown";
5287
+ try {
5288
+ const code = await publicClient.getCode({ address: session.smartAccountAddress });
5289
+ if (code && code !== "0x" && code.length > 2) {
5290
+ isDeployed = true;
5291
+ deploymentMethod = "getCode";
5292
+ }
5293
+ } catch {
5294
+ }
5295
+ const nonce = await fetchEntryPointNonce(session.smartAccountAddress, entryPointAddress);
5296
+ const nonceValue = BigInt(nonce);
5297
+ if (!isDeployed && nonceValue !== 0n) throw new Error(`Undeployed account has non-zero nonce: ${nonce}. This will cause CodeHashChanged error.`);
5298
+ const shouldIncludeFactory = !isDeployed;
5299
+ let userOp;
5300
+ if (shouldIncludeFactory) {
5301
+ const compatCreateAbi = [{ type: "function", name: "createAccount", stateMutability: "payable", inputs: [{ name: "owner", type: "address" }, { name: "salt", type: "bytes32" }], outputs: [{ name: "", type: "address" }] }];
5302
+ const saltZero = "0x0000000000000000000000000000000000000000000000000000000000000000";
5303
+ const factoryData = encodeFunctionData({ abi: compatCreateAbi, functionName: "createAccount", args: [session.ownerAddress, saltZero] });
5304
+ userOp = await createUserOperationWithDynamicFees(
5305
+ session.smartAccountAddress,
5306
+ nonce,
5307
+ callData,
5308
+ true,
5309
+ session.factoryAddress,
5310
+ factoryData,
5311
+ feeType
5312
+ );
5313
+ } else {
5314
+ userOp = await createUserOperationWithDynamicFees(
5315
+ session.smartAccountAddress,
5316
+ nonce,
5317
+ callData,
5318
+ false,
5319
+ void 0,
5320
+ void 0,
5321
+ feeType
5322
+ );
5323
+ }
5324
+ const ensureGenerousDefaults = () => {
5325
+ const toHex2 = (v) => `0x${v.toString(16)}`;
5326
+ const minCallGas = 0x493e0n;
5327
+ const minVerificationGas = 0x989680n;
5328
+ const minPreVerificationGas = 0x30d40n;
5329
+ if (BigInt(userOp.callGasLimit || "0x0") < minCallGas) userOp.callGasLimit = toHex2(minCallGas);
5330
+ if (BigInt(userOp.verificationGasLimit || "0x0") < minVerificationGas) userOp.verificationGasLimit = toHex2(minVerificationGas);
5331
+ if (BigInt(userOp.preVerificationGas || "0x0") < minPreVerificationGas) userOp.preVerificationGas = toHex2(minPreVerificationGas);
5332
+ };
5333
+ const enforceCaps = (usePaymaster) => {
5334
+ try {
5335
+ const envCaps = typeof import.meta !== "undefined" && import.meta.env || {};
5336
+ const maxBundlerVerifGas = envCaps.VITE_MAX_VERIFICATION_GAS ? BigInt(envCaps.VITE_MAX_VERIFICATION_GAS) : MAX_BUNDLER_VERIFICATION_GAS;
5337
+ const maxCallGas = envCaps.VITE_MAX_CALL_GAS_LIMIT ? BigInt(envCaps.VITE_MAX_CALL_GAS_LIMIT) : 0x7a120n;
5338
+ const toHex2 = (v) => `0x${v.toString(16)}`;
5339
+ const maxAccountVerifGas = usePaymaster ? maxBundlerVerifGas - PAYMASTER_VERIFICATION_GAS : maxBundlerVerifGas;
5340
+ const verGas = BigInt(userOp.verificationGasLimit || "0x0");
5341
+ if (verGas > maxAccountVerifGas) userOp.verificationGasLimit = toHex2(maxAccountVerifGas);
5342
+ const callGas = BigInt(userOp.callGasLimit || "0x0");
5343
+ if (callGas > maxCallGas) userOp.callGasLimit = toHex2(maxCallGas);
5344
+ } catch {
5345
+ }
5346
+ };
5347
+ let estimated = false;
5348
+ try {
5349
+ const gasEst = await estimateUserOperationGas({ ...userOp, signature: `0x${"00".repeat(65)}` });
5350
+ userOp.callGasLimit = gasEst.callGasLimit;
5351
+ userOp.verificationGasLimit = gasEst.verificationGasLimit;
5352
+ userOp.preVerificationGas = gasEst.preVerificationGas;
5353
+ ensureGenerousDefaults();
5354
+ enforceCaps(session.usePaymaster);
5355
+ estimated = true;
5356
+ } catch {
5357
+ ensureGenerousDefaults();
5358
+ enforceCaps(session.usePaymaster);
5359
+ }
5360
+ try {
5361
+ const toHex2 = (v) => `0x${v.toString(16)}`;
5362
+ const isContractCall = !!userOp.callData && userOp.callData !== "0x";
5363
+ if (isContractCall) {
5364
+ const currentVer = BigInt(userOp.verificationGasLimit || "0x0");
5365
+ const call = BigInt(userOp.callGasLimit || "0x0");
5366
+ const postOp = 150000n;
5367
+ const safety10k = 10000n;
5368
+ let buffer = call + postOp + safety10k;
5369
+ buffer += buffer / 63n;
5370
+ const newVer = currentVer + buffer;
5371
+ userOp.verificationGasLimit = toHex2(newVer);
5372
+ enforceCaps(session.usePaymaster);
5373
+ }
5374
+ } catch {
5375
+ }
5376
+ if (session.usePaymaster && LUMIA_PAYMASTER_ADDRESS) {
5377
+ userOp.paymaster = LUMIA_PAYMASTER_ADDRESS;
5378
+ userOp.paymasterData = "0x";
5379
+ userOp.paymasterVerificationGasLimit = PAYMASTER_VERIFICATION_GAS_LIMIT;
5380
+ userOp.paymasterPostOpGasLimit = PAYMASTER_POSTOP_GAS_LIMIT;
5381
+ }
5382
+ userOp.nonce = nonce;
5383
+ let opHash;
5384
+ if (entryPointVersion === "v0.6") {
5385
+ const userOpV06 = convertUserOpV07ToV06(userOp);
5386
+ opHash = await publicClient.readContract({
5387
+ address: entryPointAddress,
5388
+ abi: [{ type: "function", name: "getUserOpHash", inputs: [{ name: "userOp", type: "tuple", components: [{ name: "sender", type: "address" }, { name: "nonce", type: "uint256" }, { name: "initCode", type: "bytes" }, { name: "callData", type: "bytes" }, { name: "callGasLimit", type: "uint256" }, { name: "verificationGasLimit", type: "uint256" }, { name: "preVerificationGas", type: "uint256" }, { name: "maxFeePerGas", type: "uint256" }, { name: "maxPriorityFeePerGas", type: "uint256" }, { name: "paymasterAndData", type: "bytes" }, { name: "signature", type: "bytes" }] }], outputs: [{ name: "", type: "bytes32" }] }],
5389
+ functionName: "getUserOpHash",
5390
+ args: [{
5391
+ sender: userOpV06.sender,
5392
+ nonce: BigInt(userOpV06.nonce),
5393
+ initCode: userOpV06.initCode,
5394
+ callData: userOpV06.callData,
5395
+ callGasLimit: BigInt(userOpV06.callGasLimit),
5396
+ verificationGasLimit: BigInt(userOpV06.verificationGasLimit),
5397
+ preVerificationGas: BigInt(userOpV06.preVerificationGas),
5398
+ maxFeePerGas: BigInt(userOpV06.maxFeePerGas),
5399
+ maxPriorityFeePerGas: BigInt(userOpV06.maxPriorityFeePerGas),
5400
+ paymasterAndData: userOpV06.paymasterAndData,
5401
+ signature: "0x"
5402
+ }]
5403
+ });
5404
+ } else {
5405
+ const hasFactoryData = !!(userOp.factory && userOp.factoryData);
5406
+ const initCode = hasFactoryData ? (() => {
5407
+ const factoryAddr = userOp.factory.startsWith("0x") ? userOp.factory.slice(2) : userOp.factory;
5408
+ const factoryDataClean = userOp.factoryData.startsWith("0x") ? userOp.factoryData.slice(2) : userOp.factoryData;
5409
+ return `0x${factoryAddr}${factoryDataClean}`;
5410
+ })() : "0x";
5411
+ const accountGasLimits = pack2x128(BigInt(userOp.verificationGasLimit), BigInt(userOp.callGasLimit));
5412
+ const gasFees = pack2x128(BigInt(userOp.maxPriorityFeePerGas), BigInt(userOp.maxFeePerGas));
5413
+ let paymasterAndData = "0x";
5414
+ if (userOp.paymaster && userOp.paymaster !== "0x0000000000000000000000000000000000000000") {
5415
+ const verificationGasLimit = userOp.paymasterVerificationGasLimit || "0x186a0";
5416
+ const postOpGasLimit = userOp.paymasterPostOpGasLimit || "0x186a0";
5417
+ const paymasterDataField = userOp.paymasterData || "0x";
5418
+ const packedPaymasterGasLimits = pack2x128(BigInt(verificationGasLimit), BigInt(postOpGasLimit));
5419
+ const paymasterAddr = userOp.paymaster.startsWith("0x") ? userOp.paymaster.slice(2) : userOp.paymaster;
5420
+ const paymasterDataClean = paymasterDataField === "0x" ? "" : paymasterDataField.startsWith("0x") ? paymasterDataField.slice(2) : paymasterDataField;
5421
+ paymasterAndData = `0x${paymasterAddr}${packedPaymasterGasLimits.slice(2)}${paymasterDataClean}`;
5422
+ }
5423
+ const packedForHash = {
5424
+ sender: session.smartAccountAddress,
5425
+ nonce: BigInt(nonce),
5426
+ initCode,
5427
+ callData,
5428
+ accountGasLimits,
5429
+ preVerificationGas: BigInt(userOp.preVerificationGas),
5430
+ gasFees,
5431
+ paymasterAndData,
5432
+ signature: "0x"
5433
+ };
5434
+ opHash = await publicClient.readContract({
5435
+ address: entryPointAddress,
5436
+ abi: entryPoint07Abi,
5437
+ functionName: "getUserOpHash",
5438
+ args: [packedForHash]
5439
+ });
5440
+ }
5441
+ let signature;
5442
+ if (session.mpcUserId) {
5443
+ const mpcSig = await signDigestWithMpc(session.mpcUserId, opHash, {
5444
+ sender: userOp.sender,
5445
+ nonce: userOp.nonce,
5446
+ callData: userOp.callData,
5447
+ callGasLimit: userOp.callGasLimit,
5448
+ verificationGasLimit: userOp.verificationGasLimit,
5449
+ preVerificationGas: userOp.preVerificationGas,
5450
+ maxFeePerGas: userOp.maxFeePerGas,
5451
+ maxPriorityFeePerGas: userOp.maxPriorityFeePerGas,
5452
+ paymaster: userOp.paymaster,
5453
+ factory: userOp.factory,
5454
+ factoryData: userOp.factoryData
5455
+ });
5456
+ if (!mpcSig) throw new Error("MPC signing failed");
5457
+ signature = mpcSig;
5458
+ } else if (session.ownerPrivateKey) {
5459
+ const account = privateKeyToAccount(session.ownerPrivateKey);
5460
+ const rawSig = await account.sign({ hash: opHash });
5461
+ signature = normalizeSignature(rawSig);
5462
+ } else {
5463
+ throw new Error("No signing method available");
5464
+ }
5465
+ userOp.signature = signature;
5466
+ if (typeof userOp.sender !== "string") {
5467
+ userOp.sender = session.smartAccountAddress;
5468
+ }
5469
+ console.log("[Account] \u2705 Prepared signed UserOp (not sent):", JSON.stringify(userOp, (key, value) => typeof value === "bigint" ? `0x${value.toString(16)}` : value, 2));
5470
+ console.log("[Account] \u{1F511} UserOp Hash:", opHash);
5471
+ if (entryPointVersion === "v0.6") {
5472
+ const userOpV06 = convertUserOpV07ToV06(userOp);
5473
+ return { userOp: userOpV06, userOpHash: opHash };
5474
+ }
5475
+ return { userOp, userOpHash: opHash };
5476
+ }
5275
5477
  async function getEntryPointDeposit(address, entryPointVersion = "v0.7") {
5276
5478
  const entryPointAddress = entryPointVersion === "v0.6" ? ENTRYPOINT_V06 : ENTRYPOINT_V07;
5277
5479
  const depositAbi = [{ type: "function", name: "balanceOf", stateMutability: "view", inputs: [{ name: "account", type: "address" }], outputs: [{ name: "", type: "uint256" }] }];
@@ -9501,6 +9703,7 @@ export {
9501
9703
  UserOpStatus,
9502
9704
  getUserProfile,
9503
9705
  lumiaBeam,
9706
+ prepareUserOperation,
9504
9707
  queryClient,
9505
9708
  sendUserOperation,
9506
9709
  updateUserProfile,