@aomi-labs/client 0.1.21 → 0.1.23

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.cjs CHANGED
@@ -65,16 +65,12 @@ __export(index_exports, {
65
65
  isAlchemySponsorshipLimitError: () => isAlchemySponsorshipLimitError,
66
66
  isAsyncCallback: () => isAsyncCallback,
67
67
  isInlineCall: () => isInlineCall,
68
- isProviderConfigured: () => isProviderConfigured,
69
68
  isSystemError: () => isSystemError,
70
69
  isSystemNotice: () => isSystemNotice,
71
70
  normalizeEip712Payload: () => normalizeEip712Payload,
72
71
  normalizeTxPayload: () => normalizeTxPayload,
73
- parseAAConfig: () => parseAAConfig,
74
- readEnv: () => readEnv,
75
- resolveAlchemyConfig: () => resolveAlchemyConfig,
76
- resolveDefaultProvider: () => resolveDefaultProvider,
77
72
  resolvePimlicoConfig: () => resolvePimlicoConfig,
73
+ toAAWalletCall: () => toAAWalletCall,
78
74
  toViemSignTypedDataArgs: () => toViemSignTypedDataArgs,
79
75
  unwrapSystemEvent: () => unwrapSystemEvent
80
76
  });
@@ -675,14 +671,11 @@ function isAsyncCallback(event) {
675
671
  return "AsyncCallback" in event;
676
672
  }
677
673
 
678
- // src/event-emitter.ts
674
+ // src/event.ts
679
675
  var TypedEventEmitter = class {
680
676
  constructor() {
681
677
  this.listeners = /* @__PURE__ */ new Map();
682
678
  }
683
- /**
684
- * Subscribe to an event type. Returns an unsubscribe function.
685
- */
686
679
  on(type, handler) {
687
680
  let set = this.listeners.get(type);
688
681
  if (!set) {
@@ -697,9 +690,6 @@ var TypedEventEmitter = class {
697
690
  }
698
691
  };
699
692
  }
700
- /**
701
- * Subscribe to an event type for a single emission, then auto-unsubscribe.
702
- */
703
693
  once(type, handler) {
704
694
  const wrapper = ((payload) => {
705
695
  unsub();
@@ -708,9 +698,6 @@ var TypedEventEmitter = class {
708
698
  const unsub = this.on(type, wrapper);
709
699
  return unsub;
710
700
  }
711
- /**
712
- * Emit an event to all listeners of `type` and wildcard `"*"` listeners.
713
- */
714
701
  emit(type, payload) {
715
702
  const typeSet = this.listeners.get(type);
716
703
  if (typeSet) {
@@ -727,9 +714,6 @@ var TypedEventEmitter = class {
727
714
  }
728
715
  }
729
716
  }
730
- /**
731
- * Remove a specific handler from an event type.
732
- */
733
717
  off(type, handler) {
734
718
  const set = this.listeners.get(type);
735
719
  if (set) {
@@ -739,15 +723,10 @@ var TypedEventEmitter = class {
739
723
  }
740
724
  }
741
725
  }
742
- /**
743
- * Remove all listeners for all event types.
744
- */
745
726
  removeAllListeners() {
746
727
  this.listeners.clear();
747
728
  }
748
729
  };
749
-
750
- // src/event-unwrap.ts
751
730
  function unwrapSystemEvent(event) {
752
731
  var _a;
753
732
  if (isInlineCall(event)) {
@@ -848,6 +827,15 @@ function normalizeEip712Payload(payload) {
848
827
  const description = typeof args.description === "string" ? args.description : void 0;
849
828
  return { typed_data: typedData, description };
850
829
  }
830
+ function toAAWalletCall(payload, defaultChainId = 1) {
831
+ var _a, _b;
832
+ return {
833
+ to: payload.to,
834
+ value: BigInt((_a = payload.value) != null ? _a : "0"),
835
+ data: payload.data ? payload.data : void 0,
836
+ chainId: (_b = payload.chainId) != null ? _b : defaultChainId
837
+ };
838
+ }
851
839
  function toViemSignTypedDataArgs(payload) {
852
840
  var _a;
853
841
  const typedData = payload.typed_data;
@@ -1136,8 +1124,37 @@ var ClientSession = class extends TypedEventEmitter {
1136
1124
  return state;
1137
1125
  }
1138
1126
  // ===========================================================================
1139
- // Internal — Polling (ported from PollingController)
1127
+ // Public API — Polling Control
1140
1128
  // ===========================================================================
1129
+ /** Whether the session is currently polling for state updates. */
1130
+ getIsPolling() {
1131
+ return this.pollTimer !== null;
1132
+ }
1133
+ /**
1134
+ * Fetch the current state from the backend (one-shot).
1135
+ * Automatically starts polling if the backend is processing.
1136
+ */
1137
+ async fetchCurrentState() {
1138
+ this.assertOpen();
1139
+ const state = await this.client.fetchState(
1140
+ this.sessionId,
1141
+ this.userState,
1142
+ this.clientId
1143
+ );
1144
+ this.assertUserStateAligned(state.user_state);
1145
+ this.applyState(state);
1146
+ if (state.is_processing && !this.pollTimer) {
1147
+ this._isProcessing = true;
1148
+ this.emit("processing_start", void 0);
1149
+ this.startPolling();
1150
+ } else if (!state.is_processing) {
1151
+ this._isProcessing = false;
1152
+ }
1153
+ }
1154
+ /**
1155
+ * Start polling for state updates. Idempotent — no-op if already polling.
1156
+ * Useful for resuming polling after resolving a wallet request.
1157
+ */
1141
1158
  startPolling() {
1142
1159
  var _a;
1143
1160
  if (this.pollTimer || this.closed) return;
@@ -1147,6 +1164,7 @@ var ClientSession = class extends TypedEventEmitter {
1147
1164
  void this.pollTick();
1148
1165
  }, this.pollIntervalMs);
1149
1166
  }
1167
+ /** Stop polling for state updates. Idempotent — no-op if not polling. */
1150
1168
  stopPolling() {
1151
1169
  var _a;
1152
1170
  if (this.pollTimer) {
@@ -1278,76 +1296,14 @@ var ClientSession = class extends TypedEventEmitter {
1278
1296
  if (!isSubsetMatch(this.userState, actualUserState)) {
1279
1297
  const expected = JSON.stringify(sortJson(this.userState));
1280
1298
  const actual = JSON.stringify(sortJson(actualUserState));
1281
- throw new Error(
1282
- `Backend user_state mismatch. expected subset=${expected} actual=${actual}`
1299
+ console.warn(
1300
+ `[session] Backend user_state mismatch (non-fatal). expected subset=${expected} actual=${actual}`
1283
1301
  );
1284
1302
  }
1285
1303
  }
1286
1304
  };
1287
1305
 
1288
1306
  // src/aa/types.ts
1289
- var MODES = /* @__PURE__ */ new Set(["4337", "7702"]);
1290
- var SPONSORSHIP_MODES = /* @__PURE__ */ new Set([
1291
- "disabled",
1292
- "optional",
1293
- "required"
1294
- ]);
1295
- function isObject(value) {
1296
- return typeof value === "object" && value !== null;
1297
- }
1298
- function assertChainConfig(value, index) {
1299
- if (!isObject(value)) {
1300
- throw new Error(`Invalid AA config chain at index ${index}: expected object`);
1301
- }
1302
- if (typeof value.chainId !== "number") {
1303
- throw new Error(`Invalid AA config chain at index ${index}: chainId must be a number`);
1304
- }
1305
- if (typeof value.enabled !== "boolean") {
1306
- throw new Error(`Invalid AA config chain ${value.chainId}: enabled must be a boolean`);
1307
- }
1308
- if (!MODES.has(value.defaultMode)) {
1309
- throw new Error(`Invalid AA config chain ${value.chainId}: unsupported defaultMode`);
1310
- }
1311
- if (!Array.isArray(value.supportedModes) || value.supportedModes.length === 0) {
1312
- throw new Error(`Invalid AA config chain ${value.chainId}: supportedModes must be a non-empty array`);
1313
- }
1314
- if (!value.supportedModes.every((mode) => MODES.has(mode))) {
1315
- throw new Error(`Invalid AA config chain ${value.chainId}: supportedModes contains an unsupported mode`);
1316
- }
1317
- if (!value.supportedModes.includes(value.defaultMode)) {
1318
- throw new Error(`Invalid AA config chain ${value.chainId}: defaultMode must be in supportedModes`);
1319
- }
1320
- if (typeof value.allowBatching !== "boolean") {
1321
- throw new Error(`Invalid AA config chain ${value.chainId}: allowBatching must be a boolean`);
1322
- }
1323
- if (!SPONSORSHIP_MODES.has(value.sponsorship)) {
1324
- throw new Error(`Invalid AA config chain ${value.chainId}: unsupported sponsorship mode`);
1325
- }
1326
- }
1327
- function parseAAConfig(value) {
1328
- if (!isObject(value)) {
1329
- throw new Error("Invalid AA config: expected object");
1330
- }
1331
- if (typeof value.enabled !== "boolean") {
1332
- throw new Error("Invalid AA config: enabled must be a boolean");
1333
- }
1334
- if (typeof value.provider !== "string" || !value.provider) {
1335
- throw new Error("Invalid AA config: provider must be a non-empty string");
1336
- }
1337
- if (typeof value.fallbackToEoa !== "boolean") {
1338
- throw new Error("Invalid AA config: fallbackToEoa must be a boolean");
1339
- }
1340
- if (!Array.isArray(value.chains)) {
1341
- throw new Error("Invalid AA config: chains must be an array");
1342
- }
1343
- value.chains.forEach((chain, index) => assertChainConfig(chain, index));
1344
- return {
1345
- enabled: value.enabled,
1346
- provider: value.provider,
1347
- fallbackToEoa: value.fallbackToEoa,
1348
- chains: value.chains
1349
- };
1350
- }
1351
1307
  function getAAChainConfig(config, calls, chainsById) {
1352
1308
  if (!config.enabled || calls.length === 0) {
1353
1309
  return null;
@@ -1384,14 +1340,7 @@ function buildAAExecutionPlan(config, chainConfig) {
1384
1340
  };
1385
1341
  }
1386
1342
  function getWalletExecutorReady(providerState) {
1387
- return !providerState.plan || !providerState.isPending && (Boolean(providerState.AA) || Boolean(providerState.error) || providerState.plan.fallbackToEoa);
1388
- }
1389
- function mapCall(call) {
1390
- return {
1391
- to: call.to,
1392
- value: BigInt(call.value),
1393
- data: call.data ? call.data : void 0
1394
- };
1343
+ return !providerState.resolved || !providerState.pending && (Boolean(providerState.account) || Boolean(providerState.error) || providerState.resolved.fallbackToEoa);
1395
1344
  }
1396
1345
  var DEFAULT_AA_CONFIG = {
1397
1346
  enabled: true,
@@ -1440,6 +1389,27 @@ var DEFAULT_AA_CONFIG = {
1440
1389
  }
1441
1390
  ]
1442
1391
  };
1392
+
1393
+ // src/chains.ts
1394
+ var import_chains = require("viem/chains");
1395
+ var ALCHEMY_CHAIN_SLUGS = {
1396
+ 1: "eth-mainnet",
1397
+ 137: "polygon-mainnet",
1398
+ 42161: "arb-mainnet",
1399
+ 8453: "base-mainnet",
1400
+ 10: "opt-mainnet",
1401
+ 11155111: "eth-sepolia"
1402
+ };
1403
+ var CHAINS_BY_ID = {
1404
+ 1: import_chains.mainnet,
1405
+ 137: import_chains.polygon,
1406
+ 42161: import_chains.arbitrum,
1407
+ 10: import_chains.optimism,
1408
+ 8453: import_chains.base,
1409
+ 11155111: import_chains.sepolia
1410
+ };
1411
+
1412
+ // src/aa/execute.ts
1443
1413
  async function executeWalletCalls(params) {
1444
1414
  const {
1445
1415
  callList,
@@ -1453,10 +1423,10 @@ async function executeWalletCalls(params) {
1453
1423
  chainsById,
1454
1424
  getPreferredRpcUrl
1455
1425
  } = params;
1456
- if (providerState.plan && providerState.AA) {
1426
+ if (providerState.resolved && providerState.account) {
1457
1427
  return executeViaAA(callList, providerState);
1458
1428
  }
1459
- if (providerState.plan && providerState.error && !providerState.plan.fallbackToEoa) {
1429
+ if (providerState.resolved && providerState.error && !providerState.resolved.fallbackToEoa) {
1460
1430
  throw providerState.error;
1461
1431
  }
1462
1432
  return executeViaEoa({
@@ -1473,26 +1443,26 @@ async function executeWalletCalls(params) {
1473
1443
  }
1474
1444
  async function executeViaAA(callList, providerState) {
1475
1445
  var _a;
1476
- const AA = providerState.AA;
1477
- const plan = providerState.plan;
1478
- if (!AA || !plan) {
1446
+ const account = providerState.account;
1447
+ const resolved = providerState.resolved;
1448
+ if (!account || !resolved) {
1479
1449
  throw (_a = providerState.error) != null ? _a : new Error("smart_account_unavailable");
1480
1450
  }
1481
- const callsPayload = callList.map(mapCall);
1482
- const receipt = callList.length > 1 ? await AA.sendBatchTransaction(callsPayload) : await AA.sendTransaction(callsPayload[0]);
1451
+ const callsPayload = callList.map(({ to, value, data }) => ({ to, value, data }));
1452
+ const receipt = callList.length > 1 ? await account.sendBatchTransaction(callsPayload) : await account.sendTransaction(callsPayload[0]);
1483
1453
  const txHash = receipt.transactionHash;
1484
- const providerPrefix = AA.provider.toLowerCase();
1485
- let delegationAddress = AA.mode === "7702" ? AA.delegationAddress : void 0;
1486
- if (AA.mode === "7702" && !delegationAddress) {
1454
+ const providerPrefix = account.provider.toLowerCase();
1455
+ let delegationAddress = account.mode === "7702" ? account.delegationAddress : void 0;
1456
+ if (account.mode === "7702" && !delegationAddress) {
1487
1457
  delegationAddress = await resolve7702Delegation(txHash, callList);
1488
1458
  }
1489
1459
  return {
1490
1460
  txHash,
1491
1461
  txHashes: [txHash],
1492
- executionKind: `${providerPrefix}_${AA.mode}`,
1462
+ executionKind: `${providerPrefix}_${account.mode}`,
1493
1463
  batched: callList.length > 1,
1494
- sponsored: plan.sponsorship !== "disabled",
1495
- AAAddress: AA.AAAddress,
1464
+ sponsored: resolved.sponsorship !== "disabled",
1465
+ AAAddress: account.AAAddress,
1496
1466
  delegationAddress
1497
1467
  };
1498
1468
  }
@@ -1502,15 +1472,7 @@ async function resolve7702Delegation(txHash, callList) {
1502
1472
  const { createPublicClient, http } = await import("viem");
1503
1473
  const chainId = (_a = callList[0]) == null ? void 0 : _a.chainId;
1504
1474
  if (!chainId) return void 0;
1505
- const { mainnet, polygon, arbitrum, optimism, base } = await import("viem/chains");
1506
- const knownChains = {
1507
- 1: mainnet,
1508
- 137: polygon,
1509
- 42161: arbitrum,
1510
- 10: optimism,
1511
- 8453: base
1512
- };
1513
- const chain = knownChains[chainId];
1475
+ const chain = CHAINS_BY_ID[chainId];
1514
1476
  if (!chain) return void 0;
1515
1477
  const client = createPublicClient({ chain, transport: http() });
1516
1478
  const tx = await client.getTransaction({ hash: txHash });
@@ -1536,7 +1498,7 @@ async function executeViaEoa({
1536
1498
  }) {
1537
1499
  var _a, _b;
1538
1500
  const { createPublicClient, createWalletClient, http } = await import("viem");
1539
- const { privateKeyToAccount: privateKeyToAccount2 } = await import("viem/accounts");
1501
+ const { privateKeyToAccount: privateKeyToAccount4 } = await import("viem/accounts");
1540
1502
  const hashes = [];
1541
1503
  if (localPrivateKey) {
1542
1504
  for (const call of callList) {
@@ -1548,7 +1510,7 @@ async function executeViaEoa({
1548
1510
  if (!rpcUrl) {
1549
1511
  throw new Error(`No RPC for chain ${call.chainId}`);
1550
1512
  }
1551
- const account = privateKeyToAccount2(localPrivateKey);
1513
+ const account = privateKeyToAccount4(localPrivateKey);
1552
1514
  const walletClient = createWalletClient({
1553
1515
  account,
1554
1516
  chain,
@@ -1557,8 +1519,8 @@ async function executeViaEoa({
1557
1519
  const hash = await walletClient.sendTransaction({
1558
1520
  account,
1559
1521
  to: call.to,
1560
- value: BigInt(call.value),
1561
- data: call.data ? call.data : void 0
1522
+ value: call.value,
1523
+ data: call.data
1562
1524
  });
1563
1525
  const publicClient = createPublicClient({
1564
1526
  chain,
@@ -1588,7 +1550,7 @@ async function executeViaEoa({
1588
1550
  const canUseSendCalls = atomicStatus === "supported" || atomicStatus === "ready";
1589
1551
  if (canUseSendCalls) {
1590
1552
  const batchResult = await sendCallsSyncAsync({
1591
- calls: callList.map(mapCall),
1553
+ calls: callList.map(({ to, value, data }) => ({ to, value, data })),
1592
1554
  capabilities: {
1593
1555
  atomic: {
1594
1556
  required: true
@@ -1606,8 +1568,8 @@ async function executeViaEoa({
1606
1568
  const hash = await sendTransactionAsync({
1607
1569
  chainId: call.chainId,
1608
1570
  to: call.to,
1609
- value: BigInt(call.value),
1610
- data: call.data ? call.data : void 0
1571
+ value: call.value,
1572
+ data: call.data
1611
1573
  });
1612
1574
  hashes.push(hash);
1613
1575
  }
@@ -1621,192 +1583,28 @@ async function executeViaEoa({
1621
1583
  };
1622
1584
  }
1623
1585
 
1624
- // src/aa/env.ts
1625
- var ALCHEMY_API_KEY_ENVS = [
1626
- "ALCHEMY_API_KEY",
1627
- "NEXT_PUBLIC_ALCHEMY_API_KEY"
1628
- ];
1629
- var ALCHEMY_GAS_POLICY_ENVS = [
1630
- "ALCHEMY_GAS_POLICY_ID",
1631
- "NEXT_PUBLIC_ALCHEMY_GAS_POLICY_ID"
1632
- ];
1633
- var PIMLICO_API_KEY_ENVS = [
1634
- "PIMLICO_API_KEY",
1635
- "NEXT_PUBLIC_PIMLICO_API_KEY"
1636
- ];
1637
- function readEnv(candidates, options = {}) {
1638
- var _a;
1639
- const { publicOnly = false } = options;
1640
- for (const name of candidates) {
1641
- if (publicOnly && !name.startsWith("NEXT_PUBLIC_")) {
1642
- continue;
1643
- }
1644
- const value = (_a = process.env[name]) == null ? void 0 : _a.trim();
1645
- if (value) return value;
1646
- }
1647
- return void 0;
1648
- }
1649
- function readGasPolicyEnv(chainId, chainSlugById, baseCandidates, options = {}) {
1650
- const slug = chainSlugById[chainId];
1651
- if (slug) {
1652
- const chainSpecific = baseCandidates.map(
1653
- (base) => `${base}_${slug.toUpperCase()}`
1654
- );
1655
- const found = readEnv(chainSpecific, options);
1656
- if (found) return found;
1657
- }
1658
- return readEnv(baseCandidates, options);
1659
- }
1660
- function isProviderConfigured(provider, options = {}) {
1661
- return provider === "alchemy" ? Boolean(readEnv(ALCHEMY_API_KEY_ENVS, options)) : Boolean(readEnv(PIMLICO_API_KEY_ENVS, options));
1662
- }
1663
- function resolveDefaultProvider(options = {}) {
1664
- if (isProviderConfigured("alchemy", options)) return "alchemy";
1665
- if (isProviderConfigured("pimlico", options)) return "pimlico";
1666
- throw new Error(
1667
- "AA requires provider credentials. Set ALCHEMY_API_KEY or PIMLICO_API_KEY, or use --eoa."
1668
- );
1669
- }
1670
-
1671
- // src/aa/resolve.ts
1672
- function resolveAlchemyConfig(options) {
1673
- const {
1674
- calls,
1675
- localPrivateKey,
1676
- accountAbstractionConfig = DEFAULT_AA_CONFIG,
1677
- chainsById,
1678
- chainSlugById = {},
1679
- getPreferredRpcUrl = (chain2) => {
1680
- var _a;
1681
- return (_a = chain2.rpcUrls.default.http[0]) != null ? _a : "";
1682
- },
1683
- modeOverride,
1684
- publicOnly = false,
1685
- throwOnMissingConfig = false,
1686
- apiKey: preResolvedApiKey,
1687
- gasPolicyId: preResolvedGasPolicyId
1688
- } = options;
1689
- if (!calls || localPrivateKey) {
1690
- return null;
1691
- }
1692
- const config = __spreadProps(__spreadValues({}, accountAbstractionConfig), {
1693
- provider: "alchemy"
1694
- });
1586
+ // src/aa/alchemy/provider.ts
1587
+ function resolveForHook(params) {
1588
+ var _a, _b;
1589
+ const { calls, localPrivateKey, accountAbstractionConfig, chainsById, getPreferredRpcUrl } = params;
1590
+ if (!calls || localPrivateKey) return null;
1591
+ const config = __spreadProps(__spreadValues({}, accountAbstractionConfig), { provider: "alchemy" });
1695
1592
  const chainConfig = getAAChainConfig(config, calls, chainsById);
1696
- if (!chainConfig) {
1697
- if (throwOnMissingConfig) {
1698
- const chainIds = Array.from(new Set(calls.map((c) => c.chainId)));
1699
- throw new Error(
1700
- `AA is not configured for chain ${chainIds[0]}, or batching is disabled for that chain.`
1701
- );
1702
- }
1703
- return null;
1704
- }
1705
- const apiKey = preResolvedApiKey != null ? preResolvedApiKey : readEnv(ALCHEMY_API_KEY_ENVS, { publicOnly });
1706
- if (!apiKey) {
1707
- if (throwOnMissingConfig) {
1708
- throw new Error("Alchemy AA requires ALCHEMY_API_KEY.");
1709
- }
1710
- return null;
1711
- }
1593
+ if (!chainConfig) return null;
1594
+ const apiKey = (_a = process.env.NEXT_PUBLIC_ALCHEMY_API_KEY) == null ? void 0 : _a.trim();
1595
+ if (!apiKey) return null;
1712
1596
  const chain = chainsById[chainConfig.chainId];
1713
- if (!chain) {
1714
- return null;
1715
- }
1716
- const gasPolicyId = preResolvedGasPolicyId != null ? preResolvedGasPolicyId : readGasPolicyEnv(
1717
- chainConfig.chainId,
1718
- chainSlugById,
1719
- ALCHEMY_GAS_POLICY_ENVS,
1720
- { publicOnly }
1721
- );
1722
- if (chainConfig.sponsorship === "required" && !gasPolicyId) {
1723
- if (throwOnMissingConfig) {
1724
- throw new Error(
1725
- `Alchemy gas policy required for chain ${chainConfig.chainId} but not configured.`
1726
- );
1727
- }
1728
- return null;
1729
- }
1730
- if (modeOverride && !chainConfig.supportedModes.includes(modeOverride)) {
1731
- if (throwOnMissingConfig) {
1732
- throw new Error(
1733
- `AA mode "${modeOverride}" is not supported on chain ${chainConfig.chainId}.`
1734
- );
1735
- }
1736
- return null;
1737
- }
1738
- const resolvedChainConfig = modeOverride ? __spreadProps(__spreadValues({}, chainConfig), { defaultMode: modeOverride }) : chainConfig;
1739
- const plan = buildAAExecutionPlan(config, resolvedChainConfig);
1740
- return {
1741
- chainConfig: resolvedChainConfig,
1742
- plan,
1597
+ if (!chain) return null;
1598
+ const gasPolicyId = (_b = process.env.NEXT_PUBLIC_ALCHEMY_GAS_POLICY_ID) == null ? void 0 : _b.trim();
1599
+ const resolved = buildAAExecutionPlan(config, chainConfig);
1600
+ return __spreadProps(__spreadValues({}, resolved), {
1743
1601
  apiKey,
1744
1602
  chain,
1745
1603
  rpcUrl: getPreferredRpcUrl(chain),
1746
1604
  gasPolicyId,
1747
- mode: resolvedChainConfig.defaultMode
1748
- };
1749
- }
1750
- function resolvePimlicoConfig(options) {
1751
- const {
1752
- calls,
1753
- localPrivateKey,
1754
- accountAbstractionConfig = DEFAULT_AA_CONFIG,
1755
- chainsById,
1756
- rpcUrl,
1757
- modeOverride,
1758
- publicOnly = false,
1759
- throwOnMissingConfig = false,
1760
- apiKey: preResolvedApiKey
1761
- } = options;
1762
- if (!calls || localPrivateKey) {
1763
- return null;
1764
- }
1765
- const config = __spreadProps(__spreadValues({}, accountAbstractionConfig), {
1766
- provider: "pimlico"
1605
+ mode: chainConfig.defaultMode
1767
1606
  });
1768
- const chainConfig = getAAChainConfig(config, calls, chainsById);
1769
- if (!chainConfig) {
1770
- if (throwOnMissingConfig) {
1771
- const chainIds = Array.from(new Set(calls.map((c) => c.chainId)));
1772
- throw new Error(
1773
- `AA is not configured for chain ${chainIds[0]}, or batching is disabled for that chain.`
1774
- );
1775
- }
1776
- return null;
1777
- }
1778
- const apiKey = preResolvedApiKey != null ? preResolvedApiKey : readEnv(PIMLICO_API_KEY_ENVS, { publicOnly });
1779
- if (!apiKey) {
1780
- if (throwOnMissingConfig) {
1781
- throw new Error("Pimlico AA requires PIMLICO_API_KEY.");
1782
- }
1783
- return null;
1784
- }
1785
- const chain = chainsById[chainConfig.chainId];
1786
- if (!chain) {
1787
- return null;
1788
- }
1789
- if (modeOverride && !chainConfig.supportedModes.includes(modeOverride)) {
1790
- if (throwOnMissingConfig) {
1791
- throw new Error(
1792
- `AA mode "${modeOverride}" is not supported on chain ${chainConfig.chainId}.`
1793
- );
1794
- }
1795
- return null;
1796
- }
1797
- const resolvedChainConfig = modeOverride ? __spreadProps(__spreadValues({}, chainConfig), { defaultMode: modeOverride }) : chainConfig;
1798
- const plan = buildAAExecutionPlan(config, resolvedChainConfig);
1799
- return {
1800
- chainConfig: resolvedChainConfig,
1801
- plan,
1802
- apiKey,
1803
- chain,
1804
- rpcUrl,
1805
- mode: resolvedChainConfig.defaultMode
1806
- };
1807
1607
  }
1808
-
1809
- // src/aa/alchemy.ts
1810
1608
  function createAlchemyAAProvider({
1811
1609
  accountAbstractionConfig = DEFAULT_AA_CONFIG,
1812
1610
  useAlchemyAA,
@@ -1815,15 +1613,14 @@ function createAlchemyAAProvider({
1815
1613
  getPreferredRpcUrl
1816
1614
  }) {
1817
1615
  return function useAlchemyAAProvider(calls, localPrivateKey) {
1818
- var _a, _b;
1819
- const resolved = resolveAlchemyConfig({
1616
+ var _a;
1617
+ const resolved = resolveForHook({
1820
1618
  calls,
1821
1619
  localPrivateKey,
1822
1620
  accountAbstractionConfig,
1823
1621
  chainsById,
1824
1622
  chainSlugById,
1825
- getPreferredRpcUrl,
1826
- publicOnly: true
1623
+ getPreferredRpcUrl
1827
1624
  });
1828
1625
  const params = resolved ? {
1829
1626
  enabled: true,
@@ -1835,49 +1632,16 @@ function createAlchemyAAProvider({
1835
1632
  } : void 0;
1836
1633
  const query = useAlchemyAA(params);
1837
1634
  return {
1838
- plan: (_a = resolved == null ? void 0 : resolved.plan) != null ? _a : null,
1839
- query,
1840
- AA: query.AA,
1841
- isPending: Boolean(resolved && query.isPending),
1842
- error: (_b = query.error) != null ? _b : null
1635
+ resolved: resolved != null ? resolved : null,
1636
+ account: query.account,
1637
+ pending: Boolean(resolved && query.pending),
1638
+ error: (_a = query.error) != null ? _a : null
1843
1639
  };
1844
1640
  };
1845
1641
  }
1846
1642
 
1847
- // src/aa/pimlico.ts
1848
- function createPimlicoAAProvider({
1849
- accountAbstractionConfig = DEFAULT_AA_CONFIG,
1850
- usePimlicoAA,
1851
- chainsById,
1852
- rpcUrl
1853
- }) {
1854
- return function usePimlicoAAProvider(calls, localPrivateKey) {
1855
- var _a, _b;
1856
- const resolved = resolvePimlicoConfig({
1857
- calls,
1858
- localPrivateKey,
1859
- accountAbstractionConfig,
1860
- chainsById,
1861
- rpcUrl,
1862
- publicOnly: true
1863
- });
1864
- const params = resolved ? {
1865
- enabled: true,
1866
- apiKey: resolved.apiKey,
1867
- chain: resolved.chain,
1868
- mode: resolved.mode,
1869
- rpcUrl: resolved.rpcUrl
1870
- } : void 0;
1871
- const query = usePimlicoAA(params);
1872
- return {
1873
- plan: (_a = resolved == null ? void 0 : resolved.plan) != null ? _a : null,
1874
- query,
1875
- AA: query.AA,
1876
- isPending: Boolean(resolved && query.isPending),
1877
- error: (_b = query.error) != null ? _b : null
1878
- };
1879
- };
1880
- }
1643
+ // src/aa/alchemy/create.ts
1644
+ var import_accounts2 = require("viem/accounts");
1881
1645
 
1882
1646
  // src/aa/adapt.ts
1883
1647
  function adaptSmartAccount(account) {
@@ -1903,33 +1667,8 @@ function isAlchemySponsorshipLimitError(error) {
1903
1667
  return normalized.includes("gas sponsorship limit") || normalized.includes("put your team over your gas sponsorship limit") || normalized.includes("buy gas credits in your gas manager dashboard");
1904
1668
  }
1905
1669
 
1906
- // src/aa/create.ts
1907
- var import_aa_alchemy = require("@getpara/aa-alchemy");
1908
- var import_aa_pimlico = require("@getpara/aa-pimlico");
1670
+ // src/aa/owner.ts
1909
1671
  var import_accounts = require("viem/accounts");
1910
- var ALCHEMY_7702_DELEGATION_ADDRESS = "0x69007702764179f14F51cdce752f4f775d74E139";
1911
- async function createAAProviderState(options) {
1912
- if (options.provider === "alchemy") {
1913
- return createAlchemyAAState({
1914
- chain: options.chain,
1915
- owner: options.owner,
1916
- rpcUrl: options.rpcUrl,
1917
- callList: options.callList,
1918
- mode: options.mode,
1919
- apiKey: options.apiKey,
1920
- gasPolicyId: options.gasPolicyId,
1921
- sponsored: options.sponsored
1922
- });
1923
- }
1924
- return createPimlicoAAState({
1925
- chain: options.chain,
1926
- owner: options.owner,
1927
- rpcUrl: options.rpcUrl,
1928
- callList: options.callList,
1929
- mode: options.mode,
1930
- apiKey: options.apiKey
1931
- });
1932
- }
1933
1672
  function getDirectOwnerParams(owner) {
1934
1673
  return {
1935
1674
  kind: "ready",
@@ -1975,210 +1714,654 @@ function getOwnerParams(owner) {
1975
1714
  return getSessionOwnerParams(owner);
1976
1715
  }
1977
1716
  }
1978
- function getMissingOwnerState(plan, provider) {
1717
+ function getMissingOwnerState(resolved, provider) {
1979
1718
  return {
1980
- plan,
1981
- AA: null,
1982
- isPending: false,
1719
+ resolved,
1720
+ account: null,
1721
+ pending: false,
1983
1722
  error: new Error(
1984
1723
  `${provider} AA account creation requires a direct owner or a supported session owner.`
1985
1724
  )
1986
1725
  };
1987
1726
  }
1988
- function getUnsupportedAdapterState(plan, adapter) {
1727
+ function getUnsupportedAdapterState(resolved, adapter) {
1989
1728
  return {
1990
- plan,
1991
- AA: null,
1992
- isPending: false,
1729
+ resolved,
1730
+ account: null,
1731
+ pending: false,
1993
1732
  error: new Error(`Session adapter "${adapter}" is not implemented.`)
1994
1733
  };
1995
1734
  }
1735
+
1736
+ // src/aa/alchemy/create.ts
1737
+ var ALCHEMY_7702_DELEGATION_ADDRESS = "0x69007702764179f14F51cdce752f4f775d74E139";
1738
+ var AA_DEBUG_ENABLED = process.env.AOMI_AA_DEBUG === "1";
1739
+ var EIP_7702_AUTH_GAS_OVERHEAD = BigInt(25e3);
1740
+ function alchemyRpcUrl(chainId, apiKey) {
1741
+ var _a;
1742
+ const slug = (_a = ALCHEMY_CHAIN_SLUGS[chainId]) != null ? _a : "eth-mainnet";
1743
+ return `https://${slug}.g.alchemy.com/v2/${apiKey}`;
1744
+ }
1745
+ function aaDebug(message, fields) {
1746
+ if (!AA_DEBUG_ENABLED) return;
1747
+ if (fields) {
1748
+ console.debug(`[aomi][aa][alchemy] ${message}`, fields);
1749
+ return;
1750
+ }
1751
+ console.debug(`[aomi][aa][alchemy] ${message}`);
1752
+ }
1753
+ function extractExistingAccountAddress(error) {
1754
+ var _a;
1755
+ const message = error instanceof Error ? error.message : String(error);
1756
+ const match = message.match(/Account with address (0x[a-fA-F0-9]{40}) already exists/);
1757
+ return (_a = match == null ? void 0 : match[1]) != null ? _a : null;
1758
+ }
1759
+ function deriveAlchemy4337AccountId(address) {
1760
+ var _a;
1761
+ const hex = address.toLowerCase().slice(2).padEnd(32, "0").slice(0, 32).split("");
1762
+ const namespace = ["4", "3", "3", "7", "5", "a", "a", "b"];
1763
+ for (let i = 0; i < namespace.length; i += 1) {
1764
+ hex[i] = namespace[i];
1765
+ }
1766
+ hex[12] = "4";
1767
+ const variant = Number.parseInt((_a = hex[16]) != null ? _a : "0", 16);
1768
+ hex[16] = (variant & 3 | 8).toString(16);
1769
+ return [
1770
+ hex.slice(0, 8).join(""),
1771
+ hex.slice(8, 12).join(""),
1772
+ hex.slice(12, 16).join(""),
1773
+ hex.slice(16, 20).join(""),
1774
+ hex.slice(20, 32).join("")
1775
+ ].join("-");
1776
+ }
1996
1777
  async function createAlchemyAAState(options) {
1997
1778
  var _a, _b;
1998
1779
  const {
1999
1780
  chain,
2000
1781
  owner,
2001
- rpcUrl,
2002
1782
  callList,
2003
1783
  mode,
2004
1784
  sponsored = true
2005
1785
  } = options;
2006
- const resolved = resolveAlchemyConfig({
2007
- calls: callList,
2008
- chainsById: { [chain.id]: chain },
2009
- modeOverride: mode,
2010
- throwOnMissingConfig: true,
2011
- getPreferredRpcUrl: () => rpcUrl,
2012
- apiKey: options.apiKey,
2013
- gasPolicyId: options.gasPolicyId
1786
+ const chainConfig = getAAChainConfig(DEFAULT_AA_CONFIG, callList, {
1787
+ [chain.id]: chain
2014
1788
  });
2015
- if (!resolved) {
2016
- throw new Error("Alchemy AA config resolution failed.");
1789
+ if (!chainConfig) {
1790
+ throw new Error(`AA is not configured for chain ${chain.id}.`);
2017
1791
  }
2018
- const apiKey = (_a = options.apiKey) != null ? _a : resolved.apiKey;
2019
- const gasPolicyId = sponsored ? (_b = options.gasPolicyId) != null ? _b : readEnv(ALCHEMY_GAS_POLICY_ENVS) : void 0;
2020
- const plan = __spreadProps(__spreadValues({}, resolved.plan), {
2021
- sponsorship: gasPolicyId ? resolved.plan.sponsorship : "disabled",
1792
+ const effectiveMode = mode != null ? mode : chainConfig.defaultMode;
1793
+ const plan = buildAAExecutionPlan(
1794
+ __spreadProps(__spreadValues({}, DEFAULT_AA_CONFIG), { provider: "alchemy" }),
1795
+ __spreadProps(__spreadValues({}, chainConfig), { defaultMode: effectiveMode })
1796
+ );
1797
+ const gasPolicyId = sponsored ? (_b = options.gasPolicyId) != null ? _b : (_a = process.env.ALCHEMY_GAS_POLICY_ID) == null ? void 0 : _a.trim() : void 0;
1798
+ const execution = __spreadProps(__spreadValues({}, plan), {
1799
+ mode: effectiveMode,
1800
+ sponsorship: gasPolicyId ? plan.sponsorship : "disabled",
2022
1801
  fallbackToEoa: false
2023
1802
  });
2024
1803
  const ownerParams = getOwnerParams(owner);
2025
1804
  if (ownerParams.kind === "missing") {
2026
- return getMissingOwnerState(plan, "alchemy");
1805
+ return getMissingOwnerState(execution, "alchemy");
2027
1806
  }
2028
1807
  if (ownerParams.kind === "unsupported_adapter") {
2029
- return getUnsupportedAdapterState(plan, ownerParams.adapter);
1808
+ return getUnsupportedAdapterState(execution, ownerParams.adapter);
2030
1809
  }
2031
1810
  if (owner.kind === "direct") {
1811
+ const directParams = {
1812
+ resolved: execution,
1813
+ chain,
1814
+ privateKey: owner.privateKey,
1815
+ apiKey: options.apiKey,
1816
+ proxyBaseUrl: options.proxyBaseUrl,
1817
+ gasPolicyId
1818
+ };
2032
1819
  try {
2033
- return await createAlchemyWalletApisState({
2034
- plan,
2035
- chain,
2036
- privateKey: owner.privateKey,
2037
- apiKey,
2038
- gasPolicyId,
2039
- mode: plan.mode
2040
- });
1820
+ return await (execution.mode === "7702" ? createAlchemy7702State(directParams) : createAlchemy4337State(directParams));
2041
1821
  } catch (error) {
2042
1822
  return {
2043
- plan,
2044
- AA: null,
2045
- isPending: false,
1823
+ resolved: execution,
1824
+ account: null,
1825
+ pending: false,
2046
1826
  error: error instanceof Error ? error : new Error(String(error))
2047
1827
  };
2048
1828
  }
2049
1829
  }
1830
+ if (!options.apiKey) {
1831
+ return {
1832
+ resolved: execution,
1833
+ account: null,
1834
+ pending: false,
1835
+ error: new Error(
1836
+ "Alchemy AA with session/adapter owner requires ALCHEMY_API_KEY."
1837
+ )
1838
+ };
1839
+ }
2050
1840
  try {
2051
- const smartAccount = await (0, import_aa_alchemy.createAlchemySmartAccount)(__spreadProps(__spreadValues({}, ownerParams.ownerParams), {
2052
- apiKey,
1841
+ const { createAlchemySmartAccount } = await import("@getpara/aa-alchemy");
1842
+ const smartAccount = await createAlchemySmartAccount(__spreadProps(__spreadValues({}, ownerParams.ownerParams), {
1843
+ apiKey: options.apiKey,
2053
1844
  gasPolicyId,
2054
1845
  chain,
2055
- rpcUrl,
2056
- mode: plan.mode
1846
+ rpcUrl: options.rpcUrl,
1847
+ mode: execution.mode
2057
1848
  }));
2058
1849
  if (!smartAccount) {
2059
1850
  return {
2060
- plan,
2061
- AA: null,
2062
- isPending: false,
1851
+ resolved: execution,
1852
+ account: null,
1853
+ pending: false,
2063
1854
  error: new Error("Alchemy AA account could not be initialized.")
2064
1855
  };
2065
1856
  }
2066
1857
  return {
2067
- plan,
2068
- AA: adaptSmartAccount(smartAccount),
2069
- isPending: false,
1858
+ resolved: execution,
1859
+ account: adaptSmartAccount(smartAccount),
1860
+ pending: false,
2070
1861
  error: null
2071
1862
  };
2072
1863
  } catch (error) {
2073
1864
  return {
2074
- plan,
2075
- AA: null,
2076
- isPending: false,
1865
+ resolved: execution,
1866
+ account: null,
1867
+ pending: false,
2077
1868
  error: error instanceof Error ? error : new Error(String(error))
2078
1869
  };
2079
1870
  }
2080
1871
  }
2081
- async function createAlchemyWalletApisState(params) {
1872
+ async function createAlchemy4337State(params) {
2082
1873
  const { createSmartWalletClient, alchemyWalletTransport } = await import("@alchemy/wallet-apis");
2083
- const signer = (0, import_accounts.privateKeyToAccount)(params.privateKey);
2084
- const walletClient = createSmartWalletClient(__spreadValues({
2085
- transport: alchemyWalletTransport({ apiKey: params.apiKey }),
1874
+ const transport = params.proxyBaseUrl ? alchemyWalletTransport({ url: params.proxyBaseUrl }) : alchemyWalletTransport({ apiKey: params.apiKey });
1875
+ const signer = (0, import_accounts2.privateKeyToAccount)(params.privateKey);
1876
+ const alchemyClient = createSmartWalletClient(__spreadValues({
1877
+ transport,
2086
1878
  chain: params.chain,
2087
1879
  signer
2088
1880
  }, params.gasPolicyId ? { paymaster: { policyId: params.gasPolicyId } } : {}));
2089
- let accountAddress = signer.address;
2090
- if (params.mode === "4337") {
2091
- const account = await walletClient.requestAccount();
2092
- accountAddress = account.address;
1881
+ const signerAddress = signer.address;
1882
+ const accountId = deriveAlchemy4337AccountId(signerAddress);
1883
+ aaDebug("4337:requestAccount:start", {
1884
+ signerAddress,
1885
+ chainId: params.chain.id,
1886
+ accountId,
1887
+ hasGasPolicyId: Boolean(params.gasPolicyId)
1888
+ });
1889
+ let account;
1890
+ try {
1891
+ account = await alchemyClient.requestAccount({
1892
+ signerAddress,
1893
+ id: accountId,
1894
+ creationHint: {
1895
+ accountType: "sma-b",
1896
+ createAdditional: true
1897
+ }
1898
+ });
1899
+ } catch (error) {
1900
+ const existingAccountAddress = extractExistingAccountAddress(error);
1901
+ if (!existingAccountAddress) {
1902
+ throw error;
1903
+ }
1904
+ aaDebug("4337:requestAccount:existing-account", {
1905
+ existingAccountAddress
1906
+ });
1907
+ account = await alchemyClient.requestAccount({
1908
+ accountAddress: existingAccountAddress
1909
+ });
2093
1910
  }
1911
+ const accountAddress = account.address;
1912
+ aaDebug("4337:requestAccount:done", { signerAddress, accountAddress });
2094
1913
  const sendCalls = async (calls) => {
2095
- var _a, _b;
2096
- const result = await walletClient.sendCalls(__spreadProps(__spreadValues({}, params.mode === "4337" ? { account: accountAddress } : {}), {
2097
- calls
2098
- }));
2099
- const status = await walletClient.waitForCallsStatus({ id: result.id });
2100
- const transactionHash = (_b = (_a = status.receipts) == null ? void 0 : _a[0]) == null ? void 0 : _b.transactionHash;
2101
- if (!transactionHash) {
2102
- throw new Error("Alchemy Wallets API did not return a transaction hash.");
1914
+ var _a, _b, _c, _d;
1915
+ aaDebug("4337:sendCalls:start", {
1916
+ signerAddress,
1917
+ accountAddress,
1918
+ chainId: params.chain.id,
1919
+ callCount: calls.length,
1920
+ hasGasPolicyId: Boolean(params.gasPolicyId)
1921
+ });
1922
+ try {
1923
+ const result = await alchemyClient.sendCalls({
1924
+ account: accountAddress,
1925
+ calls
1926
+ });
1927
+ aaDebug("4337:sendCalls:submitted", { callId: result.id });
1928
+ const status = await alchemyClient.waitForCallsStatus({ id: result.id });
1929
+ const transactionHash = (_b = (_a = status.receipts) == null ? void 0 : _a[0]) == null ? void 0 : _b.transactionHash;
1930
+ aaDebug("4337:sendCalls:receipt", {
1931
+ callId: result.id,
1932
+ hasTransactionHash: Boolean(transactionHash),
1933
+ receipts: (_d = (_c = status.receipts) == null ? void 0 : _c.length) != null ? _d : 0
1934
+ });
1935
+ if (!transactionHash) {
1936
+ throw new Error("Alchemy Wallets API did not return a transaction hash.");
1937
+ }
1938
+ return { transactionHash };
1939
+ } catch (error) {
1940
+ aaDebug("4337:sendCalls:error", {
1941
+ signerAddress,
1942
+ accountAddress,
1943
+ chainId: params.chain.id,
1944
+ error: error instanceof Error ? error.message : String(error)
1945
+ });
1946
+ throw error;
2103
1947
  }
2104
- return { transactionHash };
2105
1948
  };
2106
- const AA = {
1949
+ const smartAccount = {
2107
1950
  provider: "alchemy",
2108
- mode: params.mode,
1951
+ mode: "4337",
2109
1952
  AAAddress: accountAddress,
2110
- delegationAddress: params.mode === "7702" ? ALCHEMY_7702_DELEGATION_ADDRESS : void 0,
2111
1953
  sendTransaction: async (call) => sendCalls([call]),
2112
1954
  sendBatchTransaction: async (calls) => sendCalls(calls)
2113
1955
  };
2114
1956
  return {
2115
- plan: params.plan,
2116
- AA,
2117
- isPending: false,
1957
+ resolved: params.resolved,
1958
+ account: smartAccount,
1959
+ pending: false,
2118
1960
  error: null
2119
1961
  };
2120
1962
  }
2121
- async function createPimlicoAAState(options) {
2122
- var _a;
1963
+ async function createAlchemy7702State(params) {
1964
+ const { createWalletClient, createPublicClient, http } = await import("viem");
1965
+ const { encodeExecuteData } = await import("viem/experimental/erc7821");
1966
+ if (params.gasPolicyId) {
1967
+ aaDebug(
1968
+ "7702:gas-policy-ignored",
1969
+ { gasPolicyId: params.gasPolicyId }
1970
+ );
1971
+ console.warn(
1972
+ "\u26A0\uFE0F Gas policy is not supported for raw EIP-7702 transactions. The signer's EOA pays gas directly."
1973
+ );
1974
+ }
1975
+ const signer = (0, import_accounts2.privateKeyToAccount)(params.privateKey);
1976
+ const signerAddress = signer.address;
1977
+ let rpcUrl;
1978
+ if (params.proxyBaseUrl) {
1979
+ rpcUrl = params.proxyBaseUrl;
1980
+ } else if (params.apiKey) {
1981
+ rpcUrl = alchemyRpcUrl(params.chain.id, params.apiKey);
1982
+ }
1983
+ const walletClient = createWalletClient({
1984
+ account: signer,
1985
+ chain: params.chain,
1986
+ transport: http(rpcUrl)
1987
+ });
1988
+ const publicClient = createPublicClient({
1989
+ chain: params.chain,
1990
+ transport: http(rpcUrl)
1991
+ });
1992
+ const send7702 = async (calls) => {
1993
+ aaDebug("7702:send:start", {
1994
+ signerAddress,
1995
+ chainId: params.chain.id,
1996
+ callCount: calls.length,
1997
+ calls: calls.map((call) => {
1998
+ var _a;
1999
+ return {
2000
+ to: call.to,
2001
+ value: call.value.toString(),
2002
+ data: (_a = call.data) != null ? _a : "0x"
2003
+ };
2004
+ })
2005
+ });
2006
+ const authorization = await walletClient.signAuthorization({
2007
+ contractAddress: ALCHEMY_7702_DELEGATION_ADDRESS
2008
+ });
2009
+ aaDebug("7702:authorization-signed", {
2010
+ contractAddress: ALCHEMY_7702_DELEGATION_ADDRESS
2011
+ });
2012
+ const data = encodeExecuteData({
2013
+ calls: calls.map((call) => {
2014
+ var _a;
2015
+ return {
2016
+ to: call.to,
2017
+ value: call.value,
2018
+ data: (_a = call.data) != null ? _a : "0x"
2019
+ };
2020
+ })
2021
+ });
2022
+ aaDebug("7702:calldata-encoded", { dataLength: data.length });
2023
+ const gasEstimate = await publicClient.estimateGas({
2024
+ account: signer,
2025
+ to: signerAddress,
2026
+ data,
2027
+ authorizationList: [authorization]
2028
+ });
2029
+ const gas = gasEstimate + EIP_7702_AUTH_GAS_OVERHEAD;
2030
+ aaDebug("7702:gas-estimated", {
2031
+ estimate: gasEstimate.toString(),
2032
+ total: gas.toString()
2033
+ });
2034
+ const hash = await walletClient.sendTransaction({
2035
+ to: signerAddress,
2036
+ data,
2037
+ gas,
2038
+ authorizationList: [authorization]
2039
+ });
2040
+ aaDebug("7702:tx-sent", { hash });
2041
+ const receipt = await publicClient.waitForTransactionReceipt({ hash });
2042
+ aaDebug("7702:tx-confirmed", {
2043
+ hash,
2044
+ status: receipt.status,
2045
+ gasUsed: receipt.gasUsed.toString()
2046
+ });
2047
+ if (receipt.status === "reverted") {
2048
+ throw new Error(`EIP-7702 transaction reverted: ${hash}`);
2049
+ }
2050
+ return { transactionHash: hash };
2051
+ };
2052
+ const smartAccount = {
2053
+ provider: "alchemy",
2054
+ mode: "7702",
2055
+ AAAddress: signerAddress,
2056
+ delegationAddress: ALCHEMY_7702_DELEGATION_ADDRESS,
2057
+ sendTransaction: async (call) => send7702([call]),
2058
+ sendBatchTransaction: async (calls) => send7702(calls)
2059
+ };
2060
+ return {
2061
+ resolved: params.resolved,
2062
+ account: smartAccount,
2063
+ pending: false,
2064
+ error: null
2065
+ };
2066
+ }
2067
+
2068
+ // src/aa/pimlico/resolve.ts
2069
+ function resolvePimlicoConfig(options) {
2070
+ var _a, _b, _c;
2123
2071
  const {
2124
- chain,
2125
- owner,
2072
+ calls,
2073
+ localPrivateKey,
2074
+ accountAbstractionConfig = DEFAULT_AA_CONFIG,
2075
+ chainsById,
2126
2076
  rpcUrl,
2127
- callList,
2128
- mode
2077
+ modeOverride,
2078
+ publicOnly = false,
2079
+ throwOnMissingConfig = false,
2080
+ apiKey: preResolvedApiKey
2129
2081
  } = options;
2130
- const resolved = resolvePimlicoConfig({
2131
- calls: callList,
2132
- chainsById: { [chain.id]: chain },
2082
+ if (!calls || localPrivateKey) {
2083
+ return null;
2084
+ }
2085
+ const config = __spreadProps(__spreadValues({}, accountAbstractionConfig), {
2086
+ provider: "pimlico"
2087
+ });
2088
+ const chainConfig = getAAChainConfig(config, calls, chainsById);
2089
+ if (!chainConfig) {
2090
+ if (throwOnMissingConfig) {
2091
+ const chainIds = Array.from(new Set(calls.map((c) => c.chainId)));
2092
+ throw new Error(
2093
+ `AA is not configured for chain ${chainIds[0]}, or batching is disabled for that chain.`
2094
+ );
2095
+ }
2096
+ return null;
2097
+ }
2098
+ const apiKey = (_c = preResolvedApiKey != null ? preResolvedApiKey : (_a = process.env.PIMLICO_API_KEY) == null ? void 0 : _a.trim()) != null ? _c : publicOnly ? (_b = process.env.NEXT_PUBLIC_PIMLICO_API_KEY) == null ? void 0 : _b.trim() : void 0;
2099
+ if (!apiKey) {
2100
+ if (throwOnMissingConfig) {
2101
+ throw new Error("Pimlico AA requires PIMLICO_API_KEY.");
2102
+ }
2103
+ return null;
2104
+ }
2105
+ const chain = chainsById[chainConfig.chainId];
2106
+ if (!chain) {
2107
+ return null;
2108
+ }
2109
+ if (modeOverride && !chainConfig.supportedModes.includes(modeOverride)) {
2110
+ if (throwOnMissingConfig) {
2111
+ throw new Error(
2112
+ `AA mode "${modeOverride}" is not supported on chain ${chainConfig.chainId}.`
2113
+ );
2114
+ }
2115
+ return null;
2116
+ }
2117
+ const resolvedChainConfig = modeOverride ? __spreadProps(__spreadValues({}, chainConfig), { defaultMode: modeOverride }) : chainConfig;
2118
+ const resolved = buildAAExecutionPlan(config, resolvedChainConfig);
2119
+ return __spreadProps(__spreadValues({}, resolved), {
2120
+ apiKey,
2121
+ chain,
2133
2122
  rpcUrl,
2134
- modeOverride: mode,
2135
- throwOnMissingConfig: true,
2136
- apiKey: options.apiKey
2123
+ mode: resolvedChainConfig.defaultMode
2124
+ });
2125
+ }
2126
+
2127
+ // src/aa/pimlico/provider.ts
2128
+ function createPimlicoAAProvider({
2129
+ accountAbstractionConfig = DEFAULT_AA_CONFIG,
2130
+ usePimlicoAA,
2131
+ chainsById,
2132
+ rpcUrl
2133
+ }) {
2134
+ return function usePimlicoAAProvider(calls, localPrivateKey) {
2135
+ var _a;
2136
+ const resolved = resolvePimlicoConfig({
2137
+ calls,
2138
+ localPrivateKey,
2139
+ accountAbstractionConfig,
2140
+ chainsById,
2141
+ rpcUrl,
2142
+ publicOnly: true
2143
+ });
2144
+ const params = resolved ? {
2145
+ enabled: true,
2146
+ apiKey: resolved.apiKey,
2147
+ chain: resolved.chain,
2148
+ mode: resolved.mode,
2149
+ rpcUrl: resolved.rpcUrl
2150
+ } : void 0;
2151
+ const query = usePimlicoAA(params);
2152
+ return {
2153
+ resolved: resolved != null ? resolved : null,
2154
+ account: query.account,
2155
+ pending: Boolean(resolved && query.pending),
2156
+ error: (_a = query.error) != null ? _a : null
2157
+ };
2158
+ };
2159
+ }
2160
+
2161
+ // src/aa/pimlico/create.ts
2162
+ var import_accounts3 = require("viem/accounts");
2163
+ var AA_DEBUG_ENABLED2 = process.env.AOMI_AA_DEBUG === "1";
2164
+ function pimDebug(message, fields) {
2165
+ if (!AA_DEBUG_ENABLED2) return;
2166
+ if (fields) {
2167
+ console.debug(`[aomi][aa][pimlico] ${message}`, fields);
2168
+ return;
2169
+ }
2170
+ console.debug(`[aomi][aa][pimlico] ${message}`);
2171
+ }
2172
+ async function createPimlicoAAState(options) {
2173
+ var _a, _b;
2174
+ const { chain, owner, callList, mode } = options;
2175
+ const chainConfig = getAAChainConfig(DEFAULT_AA_CONFIG, callList, {
2176
+ [chain.id]: chain
2137
2177
  });
2138
- if (!resolved) {
2139
- throw new Error("Pimlico AA config resolution failed.");
2178
+ if (!chainConfig) {
2179
+ throw new Error(`AA is not configured for chain ${chain.id}.`);
2180
+ }
2181
+ const effectiveMode = mode != null ? mode : chainConfig.defaultMode;
2182
+ const plan = buildAAExecutionPlan(
2183
+ __spreadProps(__spreadValues({}, DEFAULT_AA_CONFIG), { provider: "pimlico" }),
2184
+ __spreadProps(__spreadValues({}, chainConfig), { defaultMode: effectiveMode })
2185
+ );
2186
+ const apiKey = (_b = options.apiKey) != null ? _b : (_a = process.env.PIMLICO_API_KEY) == null ? void 0 : _a.trim();
2187
+ if (!apiKey) {
2188
+ throw new Error("Pimlico AA requires PIMLICO_API_KEY.");
2140
2189
  }
2141
- const apiKey = (_a = options.apiKey) != null ? _a : resolved.apiKey;
2142
- const plan = __spreadProps(__spreadValues({}, resolved.plan), {
2190
+ const execution = __spreadProps(__spreadValues({}, plan), {
2191
+ mode: effectiveMode,
2143
2192
  fallbackToEoa: false
2144
2193
  });
2145
2194
  const ownerParams = getOwnerParams(owner);
2146
2195
  if (ownerParams.kind === "missing") {
2147
- return getMissingOwnerState(plan, "pimlico");
2196
+ return getMissingOwnerState(execution, "pimlico");
2148
2197
  }
2149
2198
  if (ownerParams.kind === "unsupported_adapter") {
2150
- return getUnsupportedAdapterState(plan, ownerParams.adapter);
2199
+ return getUnsupportedAdapterState(execution, ownerParams.adapter);
2200
+ }
2201
+ if (owner.kind === "direct") {
2202
+ try {
2203
+ return await createPimlicoDirectState({
2204
+ resolved: execution,
2205
+ chain,
2206
+ privateKey: owner.privateKey,
2207
+ rpcUrl: options.rpcUrl,
2208
+ apiKey,
2209
+ mode: effectiveMode
2210
+ });
2211
+ } catch (error) {
2212
+ return {
2213
+ resolved: execution,
2214
+ account: null,
2215
+ pending: false,
2216
+ error: error instanceof Error ? error : new Error(String(error))
2217
+ };
2218
+ }
2151
2219
  }
2152
2220
  try {
2153
- const smartAccount = await (0, import_aa_pimlico.createPimlicoSmartAccount)(__spreadProps(__spreadValues({}, ownerParams.ownerParams), {
2221
+ const { createPimlicoSmartAccount } = await import("@getpara/aa-pimlico");
2222
+ const smartAccount = await createPimlicoSmartAccount(__spreadProps(__spreadValues({}, ownerParams.ownerParams), {
2154
2223
  apiKey,
2155
2224
  chain,
2156
- rpcUrl,
2157
- mode: plan.mode
2225
+ rpcUrl: options.rpcUrl,
2226
+ mode: execution.mode
2158
2227
  }));
2159
2228
  if (!smartAccount) {
2160
2229
  return {
2161
- plan,
2162
- AA: null,
2163
- isPending: false,
2230
+ resolved: execution,
2231
+ account: null,
2232
+ pending: false,
2164
2233
  error: new Error("Pimlico AA account could not be initialized.")
2165
2234
  };
2166
2235
  }
2167
2236
  return {
2168
- plan,
2169
- AA: adaptSmartAccount(smartAccount),
2170
- isPending: false,
2237
+ resolved: execution,
2238
+ account: adaptSmartAccount(smartAccount),
2239
+ pending: false,
2171
2240
  error: null
2172
2241
  };
2173
2242
  } catch (error) {
2174
2243
  return {
2175
- plan,
2176
- AA: null,
2177
- isPending: false,
2244
+ resolved: execution,
2245
+ account: null,
2246
+ pending: false,
2178
2247
  error: error instanceof Error ? error : new Error(String(error))
2179
2248
  };
2180
2249
  }
2181
2250
  }
2251
+ function buildPimlicoRpcUrl(chain, apiKey) {
2252
+ const slug = chain.name.toLowerCase().replace(/\s+/g, "-");
2253
+ return `https://api.pimlico.io/v2/${slug}/rpc?apikey=${apiKey}`;
2254
+ }
2255
+ async function createPimlicoDirectState(params) {
2256
+ const { createSmartAccountClient } = await import("permissionless");
2257
+ const { toSimpleSmartAccount } = await import("permissionless/accounts");
2258
+ const { createPimlicoClient } = await import("permissionless/clients/pimlico");
2259
+ const { createPublicClient, http } = await import("viem");
2260
+ const { entryPoint07Address } = await import("viem/account-abstraction");
2261
+ const signer = (0, import_accounts3.privateKeyToAccount)(params.privateKey);
2262
+ const signerAddress = signer.address;
2263
+ const pimlicoRpcUrl = buildPimlicoRpcUrl(params.chain, params.apiKey);
2264
+ pimDebug("4337:start", {
2265
+ signerAddress,
2266
+ chainId: params.chain.id,
2267
+ pimlicoRpcUrl: pimlicoRpcUrl.replace(params.apiKey, "***")
2268
+ });
2269
+ const publicClient = createPublicClient({
2270
+ chain: params.chain,
2271
+ transport: http(params.rpcUrl)
2272
+ });
2273
+ const paymasterClient = createPimlicoClient({
2274
+ entryPoint: { address: entryPoint07Address, version: "0.7" },
2275
+ transport: http(pimlicoRpcUrl)
2276
+ });
2277
+ const smartAccount = await toSimpleSmartAccount({
2278
+ client: publicClient,
2279
+ owner: signer,
2280
+ entryPoint: { address: entryPoint07Address, version: "0.7" }
2281
+ });
2282
+ const accountAddress = smartAccount.address;
2283
+ pimDebug("4337:account-created", {
2284
+ signerAddress,
2285
+ accountAddress
2286
+ });
2287
+ const smartAccountClient = createSmartAccountClient({
2288
+ account: smartAccount,
2289
+ chain: params.chain,
2290
+ paymaster: paymasterClient,
2291
+ bundlerTransport: http(pimlicoRpcUrl),
2292
+ userOperation: {
2293
+ estimateFeesPerGas: async () => {
2294
+ const gasPrice = await paymasterClient.getUserOperationGasPrice();
2295
+ return gasPrice.fast;
2296
+ }
2297
+ }
2298
+ });
2299
+ const sendCalls = async (calls) => {
2300
+ pimDebug("4337:send:start", {
2301
+ accountAddress,
2302
+ chainId: params.chain.id,
2303
+ callCount: calls.length
2304
+ });
2305
+ const hash = await smartAccountClient.sendTransaction({
2306
+ account: smartAccount,
2307
+ calls: calls.map((c) => {
2308
+ var _a;
2309
+ return {
2310
+ to: c.to,
2311
+ value: c.value,
2312
+ data: (_a = c.data) != null ? _a : "0x"
2313
+ };
2314
+ })
2315
+ });
2316
+ pimDebug("4337:send:userOpHash", { hash });
2317
+ const receipt = await publicClient.waitForTransactionReceipt({
2318
+ hash
2319
+ });
2320
+ pimDebug("4337:send:confirmed", {
2321
+ transactionHash: receipt.transactionHash,
2322
+ status: receipt.status
2323
+ });
2324
+ return { transactionHash: receipt.transactionHash };
2325
+ };
2326
+ const account = {
2327
+ provider: "pimlico",
2328
+ mode: "4337",
2329
+ AAAddress: accountAddress,
2330
+ sendTransaction: async (call) => sendCalls([call]),
2331
+ sendBatchTransaction: async (calls) => sendCalls(calls)
2332
+ };
2333
+ return {
2334
+ resolved: params.resolved,
2335
+ account,
2336
+ pending: false,
2337
+ error: null
2338
+ };
2339
+ }
2340
+
2341
+ // src/aa/create.ts
2342
+ async function createAAProviderState(options) {
2343
+ if (options.provider === "alchemy") {
2344
+ return createAlchemyAAState({
2345
+ chain: options.chain,
2346
+ owner: options.owner,
2347
+ rpcUrl: options.rpcUrl,
2348
+ callList: options.callList,
2349
+ mode: options.mode,
2350
+ apiKey: options.apiKey,
2351
+ gasPolicyId: options.gasPolicyId,
2352
+ sponsored: options.sponsored,
2353
+ proxyBaseUrl: options.proxyBaseUrl
2354
+ });
2355
+ }
2356
+ return createPimlicoAAState({
2357
+ chain: options.chain,
2358
+ owner: options.owner,
2359
+ rpcUrl: options.rpcUrl,
2360
+ callList: options.callList,
2361
+ mode: options.mode,
2362
+ apiKey: options.apiKey
2363
+ });
2364
+ }
2182
2365
  // Annotate the CommonJS export names for ESM import in node:
2183
2366
  0 && (module.exports = {
2184
2367
  AomiClient,
@@ -2199,16 +2382,12 @@ async function createPimlicoAAState(options) {
2199
2382
  isAlchemySponsorshipLimitError,
2200
2383
  isAsyncCallback,
2201
2384
  isInlineCall,
2202
- isProviderConfigured,
2203
2385
  isSystemError,
2204
2386
  isSystemNotice,
2205
2387
  normalizeEip712Payload,
2206
2388
  normalizeTxPayload,
2207
- parseAAConfig,
2208
- readEnv,
2209
- resolveAlchemyConfig,
2210
- resolveDefaultProvider,
2211
2389
  resolvePimlicoConfig,
2390
+ toAAWalletCall,
2212
2391
  toViemSignTypedDataArgs,
2213
2392
  unwrapSystemEvent
2214
2393
  });