@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.js CHANGED
@@ -613,14 +613,11 @@ function isAsyncCallback(event) {
613
613
  return "AsyncCallback" in event;
614
614
  }
615
615
 
616
- // src/event-emitter.ts
616
+ // src/event.ts
617
617
  var TypedEventEmitter = class {
618
618
  constructor() {
619
619
  this.listeners = /* @__PURE__ */ new Map();
620
620
  }
621
- /**
622
- * Subscribe to an event type. Returns an unsubscribe function.
623
- */
624
621
  on(type, handler) {
625
622
  let set = this.listeners.get(type);
626
623
  if (!set) {
@@ -635,9 +632,6 @@ var TypedEventEmitter = class {
635
632
  }
636
633
  };
637
634
  }
638
- /**
639
- * Subscribe to an event type for a single emission, then auto-unsubscribe.
640
- */
641
635
  once(type, handler) {
642
636
  const wrapper = ((payload) => {
643
637
  unsub();
@@ -646,9 +640,6 @@ var TypedEventEmitter = class {
646
640
  const unsub = this.on(type, wrapper);
647
641
  return unsub;
648
642
  }
649
- /**
650
- * Emit an event to all listeners of `type` and wildcard `"*"` listeners.
651
- */
652
643
  emit(type, payload) {
653
644
  const typeSet = this.listeners.get(type);
654
645
  if (typeSet) {
@@ -665,9 +656,6 @@ var TypedEventEmitter = class {
665
656
  }
666
657
  }
667
658
  }
668
- /**
669
- * Remove a specific handler from an event type.
670
- */
671
659
  off(type, handler) {
672
660
  const set = this.listeners.get(type);
673
661
  if (set) {
@@ -677,15 +665,10 @@ var TypedEventEmitter = class {
677
665
  }
678
666
  }
679
667
  }
680
- /**
681
- * Remove all listeners for all event types.
682
- */
683
668
  removeAllListeners() {
684
669
  this.listeners.clear();
685
670
  }
686
671
  };
687
-
688
- // src/event-unwrap.ts
689
672
  function unwrapSystemEvent(event) {
690
673
  var _a;
691
674
  if (isInlineCall(event)) {
@@ -786,6 +769,15 @@ function normalizeEip712Payload(payload) {
786
769
  const description = typeof args.description === "string" ? args.description : void 0;
787
770
  return { typed_data: typedData, description };
788
771
  }
772
+ function toAAWalletCall(payload, defaultChainId = 1) {
773
+ var _a, _b;
774
+ return {
775
+ to: payload.to,
776
+ value: BigInt((_a = payload.value) != null ? _a : "0"),
777
+ data: payload.data ? payload.data : void 0,
778
+ chainId: (_b = payload.chainId) != null ? _b : defaultChainId
779
+ };
780
+ }
789
781
  function toViemSignTypedDataArgs(payload) {
790
782
  var _a;
791
783
  const typedData = payload.typed_data;
@@ -1074,8 +1066,37 @@ var ClientSession = class extends TypedEventEmitter {
1074
1066
  return state;
1075
1067
  }
1076
1068
  // ===========================================================================
1077
- // Internal — Polling (ported from PollingController)
1069
+ // Public API — Polling Control
1078
1070
  // ===========================================================================
1071
+ /** Whether the session is currently polling for state updates. */
1072
+ getIsPolling() {
1073
+ return this.pollTimer !== null;
1074
+ }
1075
+ /**
1076
+ * Fetch the current state from the backend (one-shot).
1077
+ * Automatically starts polling if the backend is processing.
1078
+ */
1079
+ async fetchCurrentState() {
1080
+ this.assertOpen();
1081
+ const state = await this.client.fetchState(
1082
+ this.sessionId,
1083
+ this.userState,
1084
+ this.clientId
1085
+ );
1086
+ this.assertUserStateAligned(state.user_state);
1087
+ this.applyState(state);
1088
+ if (state.is_processing && !this.pollTimer) {
1089
+ this._isProcessing = true;
1090
+ this.emit("processing_start", void 0);
1091
+ this.startPolling();
1092
+ } else if (!state.is_processing) {
1093
+ this._isProcessing = false;
1094
+ }
1095
+ }
1096
+ /**
1097
+ * Start polling for state updates. Idempotent — no-op if already polling.
1098
+ * Useful for resuming polling after resolving a wallet request.
1099
+ */
1079
1100
  startPolling() {
1080
1101
  var _a;
1081
1102
  if (this.pollTimer || this.closed) return;
@@ -1085,6 +1106,7 @@ var ClientSession = class extends TypedEventEmitter {
1085
1106
  void this.pollTick();
1086
1107
  }, this.pollIntervalMs);
1087
1108
  }
1109
+ /** Stop polling for state updates. Idempotent — no-op if not polling. */
1088
1110
  stopPolling() {
1089
1111
  var _a;
1090
1112
  if (this.pollTimer) {
@@ -1216,76 +1238,14 @@ var ClientSession = class extends TypedEventEmitter {
1216
1238
  if (!isSubsetMatch(this.userState, actualUserState)) {
1217
1239
  const expected = JSON.stringify(sortJson(this.userState));
1218
1240
  const actual = JSON.stringify(sortJson(actualUserState));
1219
- throw new Error(
1220
- `Backend user_state mismatch. expected subset=${expected} actual=${actual}`
1241
+ console.warn(
1242
+ `[session] Backend user_state mismatch (non-fatal). expected subset=${expected} actual=${actual}`
1221
1243
  );
1222
1244
  }
1223
1245
  }
1224
1246
  };
1225
1247
 
1226
1248
  // src/aa/types.ts
1227
- var MODES = /* @__PURE__ */ new Set(["4337", "7702"]);
1228
- var SPONSORSHIP_MODES = /* @__PURE__ */ new Set([
1229
- "disabled",
1230
- "optional",
1231
- "required"
1232
- ]);
1233
- function isObject(value) {
1234
- return typeof value === "object" && value !== null;
1235
- }
1236
- function assertChainConfig(value, index) {
1237
- if (!isObject(value)) {
1238
- throw new Error(`Invalid AA config chain at index ${index}: expected object`);
1239
- }
1240
- if (typeof value.chainId !== "number") {
1241
- throw new Error(`Invalid AA config chain at index ${index}: chainId must be a number`);
1242
- }
1243
- if (typeof value.enabled !== "boolean") {
1244
- throw new Error(`Invalid AA config chain ${value.chainId}: enabled must be a boolean`);
1245
- }
1246
- if (!MODES.has(value.defaultMode)) {
1247
- throw new Error(`Invalid AA config chain ${value.chainId}: unsupported defaultMode`);
1248
- }
1249
- if (!Array.isArray(value.supportedModes) || value.supportedModes.length === 0) {
1250
- throw new Error(`Invalid AA config chain ${value.chainId}: supportedModes must be a non-empty array`);
1251
- }
1252
- if (!value.supportedModes.every((mode) => MODES.has(mode))) {
1253
- throw new Error(`Invalid AA config chain ${value.chainId}: supportedModes contains an unsupported mode`);
1254
- }
1255
- if (!value.supportedModes.includes(value.defaultMode)) {
1256
- throw new Error(`Invalid AA config chain ${value.chainId}: defaultMode must be in supportedModes`);
1257
- }
1258
- if (typeof value.allowBatching !== "boolean") {
1259
- throw new Error(`Invalid AA config chain ${value.chainId}: allowBatching must be a boolean`);
1260
- }
1261
- if (!SPONSORSHIP_MODES.has(value.sponsorship)) {
1262
- throw new Error(`Invalid AA config chain ${value.chainId}: unsupported sponsorship mode`);
1263
- }
1264
- }
1265
- function parseAAConfig(value) {
1266
- if (!isObject(value)) {
1267
- throw new Error("Invalid AA config: expected object");
1268
- }
1269
- if (typeof value.enabled !== "boolean") {
1270
- throw new Error("Invalid AA config: enabled must be a boolean");
1271
- }
1272
- if (typeof value.provider !== "string" || !value.provider) {
1273
- throw new Error("Invalid AA config: provider must be a non-empty string");
1274
- }
1275
- if (typeof value.fallbackToEoa !== "boolean") {
1276
- throw new Error("Invalid AA config: fallbackToEoa must be a boolean");
1277
- }
1278
- if (!Array.isArray(value.chains)) {
1279
- throw new Error("Invalid AA config: chains must be an array");
1280
- }
1281
- value.chains.forEach((chain, index) => assertChainConfig(chain, index));
1282
- return {
1283
- enabled: value.enabled,
1284
- provider: value.provider,
1285
- fallbackToEoa: value.fallbackToEoa,
1286
- chains: value.chains
1287
- };
1288
- }
1289
1249
  function getAAChainConfig(config, calls, chainsById) {
1290
1250
  if (!config.enabled || calls.length === 0) {
1291
1251
  return null;
@@ -1322,14 +1282,7 @@ function buildAAExecutionPlan(config, chainConfig) {
1322
1282
  };
1323
1283
  }
1324
1284
  function getWalletExecutorReady(providerState) {
1325
- return !providerState.plan || !providerState.isPending && (Boolean(providerState.AA) || Boolean(providerState.error) || providerState.plan.fallbackToEoa);
1326
- }
1327
- function mapCall(call) {
1328
- return {
1329
- to: call.to,
1330
- value: BigInt(call.value),
1331
- data: call.data ? call.data : void 0
1332
- };
1285
+ return !providerState.resolved || !providerState.pending && (Boolean(providerState.account) || Boolean(providerState.error) || providerState.resolved.fallbackToEoa);
1333
1286
  }
1334
1287
  var DEFAULT_AA_CONFIG = {
1335
1288
  enabled: true,
@@ -1378,6 +1331,27 @@ var DEFAULT_AA_CONFIG = {
1378
1331
  }
1379
1332
  ]
1380
1333
  };
1334
+
1335
+ // src/chains.ts
1336
+ import { mainnet, polygon, arbitrum, optimism, base, sepolia } from "viem/chains";
1337
+ var ALCHEMY_CHAIN_SLUGS = {
1338
+ 1: "eth-mainnet",
1339
+ 137: "polygon-mainnet",
1340
+ 42161: "arb-mainnet",
1341
+ 8453: "base-mainnet",
1342
+ 10: "opt-mainnet",
1343
+ 11155111: "eth-sepolia"
1344
+ };
1345
+ var CHAINS_BY_ID = {
1346
+ 1: mainnet,
1347
+ 137: polygon,
1348
+ 42161: arbitrum,
1349
+ 10: optimism,
1350
+ 8453: base,
1351
+ 11155111: sepolia
1352
+ };
1353
+
1354
+ // src/aa/execute.ts
1381
1355
  async function executeWalletCalls(params) {
1382
1356
  const {
1383
1357
  callList,
@@ -1391,10 +1365,10 @@ async function executeWalletCalls(params) {
1391
1365
  chainsById,
1392
1366
  getPreferredRpcUrl
1393
1367
  } = params;
1394
- if (providerState.plan && providerState.AA) {
1368
+ if (providerState.resolved && providerState.account) {
1395
1369
  return executeViaAA(callList, providerState);
1396
1370
  }
1397
- if (providerState.plan && providerState.error && !providerState.plan.fallbackToEoa) {
1371
+ if (providerState.resolved && providerState.error && !providerState.resolved.fallbackToEoa) {
1398
1372
  throw providerState.error;
1399
1373
  }
1400
1374
  return executeViaEoa({
@@ -1411,26 +1385,26 @@ async function executeWalletCalls(params) {
1411
1385
  }
1412
1386
  async function executeViaAA(callList, providerState) {
1413
1387
  var _a;
1414
- const AA = providerState.AA;
1415
- const plan = providerState.plan;
1416
- if (!AA || !plan) {
1388
+ const account = providerState.account;
1389
+ const resolved = providerState.resolved;
1390
+ if (!account || !resolved) {
1417
1391
  throw (_a = providerState.error) != null ? _a : new Error("smart_account_unavailable");
1418
1392
  }
1419
- const callsPayload = callList.map(mapCall);
1420
- const receipt = callList.length > 1 ? await AA.sendBatchTransaction(callsPayload) : await AA.sendTransaction(callsPayload[0]);
1393
+ const callsPayload = callList.map(({ to, value, data }) => ({ to, value, data }));
1394
+ const receipt = callList.length > 1 ? await account.sendBatchTransaction(callsPayload) : await account.sendTransaction(callsPayload[0]);
1421
1395
  const txHash = receipt.transactionHash;
1422
- const providerPrefix = AA.provider.toLowerCase();
1423
- let delegationAddress = AA.mode === "7702" ? AA.delegationAddress : void 0;
1424
- if (AA.mode === "7702" && !delegationAddress) {
1396
+ const providerPrefix = account.provider.toLowerCase();
1397
+ let delegationAddress = account.mode === "7702" ? account.delegationAddress : void 0;
1398
+ if (account.mode === "7702" && !delegationAddress) {
1425
1399
  delegationAddress = await resolve7702Delegation(txHash, callList);
1426
1400
  }
1427
1401
  return {
1428
1402
  txHash,
1429
1403
  txHashes: [txHash],
1430
- executionKind: `${providerPrefix}_${AA.mode}`,
1404
+ executionKind: `${providerPrefix}_${account.mode}`,
1431
1405
  batched: callList.length > 1,
1432
- sponsored: plan.sponsorship !== "disabled",
1433
- AAAddress: AA.AAAddress,
1406
+ sponsored: resolved.sponsorship !== "disabled",
1407
+ AAAddress: account.AAAddress,
1434
1408
  delegationAddress
1435
1409
  };
1436
1410
  }
@@ -1440,15 +1414,7 @@ async function resolve7702Delegation(txHash, callList) {
1440
1414
  const { createPublicClient, http } = await import("viem");
1441
1415
  const chainId = (_a = callList[0]) == null ? void 0 : _a.chainId;
1442
1416
  if (!chainId) return void 0;
1443
- const { mainnet, polygon, arbitrum, optimism, base } = await import("viem/chains");
1444
- const knownChains = {
1445
- 1: mainnet,
1446
- 137: polygon,
1447
- 42161: arbitrum,
1448
- 10: optimism,
1449
- 8453: base
1450
- };
1451
- const chain = knownChains[chainId];
1417
+ const chain = CHAINS_BY_ID[chainId];
1452
1418
  if (!chain) return void 0;
1453
1419
  const client = createPublicClient({ chain, transport: http() });
1454
1420
  const tx = await client.getTransaction({ hash: txHash });
@@ -1474,7 +1440,7 @@ async function executeViaEoa({
1474
1440
  }) {
1475
1441
  var _a, _b;
1476
1442
  const { createPublicClient, createWalletClient, http } = await import("viem");
1477
- const { privateKeyToAccount: privateKeyToAccount2 } = await import("viem/accounts");
1443
+ const { privateKeyToAccount: privateKeyToAccount4 } = await import("viem/accounts");
1478
1444
  const hashes = [];
1479
1445
  if (localPrivateKey) {
1480
1446
  for (const call of callList) {
@@ -1486,7 +1452,7 @@ async function executeViaEoa({
1486
1452
  if (!rpcUrl) {
1487
1453
  throw new Error(`No RPC for chain ${call.chainId}`);
1488
1454
  }
1489
- const account = privateKeyToAccount2(localPrivateKey);
1455
+ const account = privateKeyToAccount4(localPrivateKey);
1490
1456
  const walletClient = createWalletClient({
1491
1457
  account,
1492
1458
  chain,
@@ -1495,8 +1461,8 @@ async function executeViaEoa({
1495
1461
  const hash = await walletClient.sendTransaction({
1496
1462
  account,
1497
1463
  to: call.to,
1498
- value: BigInt(call.value),
1499
- data: call.data ? call.data : void 0
1464
+ value: call.value,
1465
+ data: call.data
1500
1466
  });
1501
1467
  const publicClient = createPublicClient({
1502
1468
  chain,
@@ -1526,7 +1492,7 @@ async function executeViaEoa({
1526
1492
  const canUseSendCalls = atomicStatus === "supported" || atomicStatus === "ready";
1527
1493
  if (canUseSendCalls) {
1528
1494
  const batchResult = await sendCallsSyncAsync({
1529
- calls: callList.map(mapCall),
1495
+ calls: callList.map(({ to, value, data }) => ({ to, value, data })),
1530
1496
  capabilities: {
1531
1497
  atomic: {
1532
1498
  required: true
@@ -1544,8 +1510,8 @@ async function executeViaEoa({
1544
1510
  const hash = await sendTransactionAsync({
1545
1511
  chainId: call.chainId,
1546
1512
  to: call.to,
1547
- value: BigInt(call.value),
1548
- data: call.data ? call.data : void 0
1513
+ value: call.value,
1514
+ data: call.data
1549
1515
  });
1550
1516
  hashes.push(hash);
1551
1517
  }
@@ -1559,192 +1525,28 @@ async function executeViaEoa({
1559
1525
  };
1560
1526
  }
1561
1527
 
1562
- // src/aa/env.ts
1563
- var ALCHEMY_API_KEY_ENVS = [
1564
- "ALCHEMY_API_KEY",
1565
- "NEXT_PUBLIC_ALCHEMY_API_KEY"
1566
- ];
1567
- var ALCHEMY_GAS_POLICY_ENVS = [
1568
- "ALCHEMY_GAS_POLICY_ID",
1569
- "NEXT_PUBLIC_ALCHEMY_GAS_POLICY_ID"
1570
- ];
1571
- var PIMLICO_API_KEY_ENVS = [
1572
- "PIMLICO_API_KEY",
1573
- "NEXT_PUBLIC_PIMLICO_API_KEY"
1574
- ];
1575
- function readEnv(candidates, options = {}) {
1576
- var _a;
1577
- const { publicOnly = false } = options;
1578
- for (const name of candidates) {
1579
- if (publicOnly && !name.startsWith("NEXT_PUBLIC_")) {
1580
- continue;
1581
- }
1582
- const value = (_a = process.env[name]) == null ? void 0 : _a.trim();
1583
- if (value) return value;
1584
- }
1585
- return void 0;
1586
- }
1587
- function readGasPolicyEnv(chainId, chainSlugById, baseCandidates, options = {}) {
1588
- const slug = chainSlugById[chainId];
1589
- if (slug) {
1590
- const chainSpecific = baseCandidates.map(
1591
- (base) => `${base}_${slug.toUpperCase()}`
1592
- );
1593
- const found = readEnv(chainSpecific, options);
1594
- if (found) return found;
1595
- }
1596
- return readEnv(baseCandidates, options);
1597
- }
1598
- function isProviderConfigured(provider, options = {}) {
1599
- return provider === "alchemy" ? Boolean(readEnv(ALCHEMY_API_KEY_ENVS, options)) : Boolean(readEnv(PIMLICO_API_KEY_ENVS, options));
1600
- }
1601
- function resolveDefaultProvider(options = {}) {
1602
- if (isProviderConfigured("alchemy", options)) return "alchemy";
1603
- if (isProviderConfigured("pimlico", options)) return "pimlico";
1604
- throw new Error(
1605
- "AA requires provider credentials. Set ALCHEMY_API_KEY or PIMLICO_API_KEY, or use --eoa."
1606
- );
1607
- }
1608
-
1609
- // src/aa/resolve.ts
1610
- function resolveAlchemyConfig(options) {
1611
- const {
1612
- calls,
1613
- localPrivateKey,
1614
- accountAbstractionConfig = DEFAULT_AA_CONFIG,
1615
- chainsById,
1616
- chainSlugById = {},
1617
- getPreferredRpcUrl = (chain2) => {
1618
- var _a;
1619
- return (_a = chain2.rpcUrls.default.http[0]) != null ? _a : "";
1620
- },
1621
- modeOverride,
1622
- publicOnly = false,
1623
- throwOnMissingConfig = false,
1624
- apiKey: preResolvedApiKey,
1625
- gasPolicyId: preResolvedGasPolicyId
1626
- } = options;
1627
- if (!calls || localPrivateKey) {
1628
- return null;
1629
- }
1630
- const config = __spreadProps(__spreadValues({}, accountAbstractionConfig), {
1631
- provider: "alchemy"
1632
- });
1528
+ // src/aa/alchemy/provider.ts
1529
+ function resolveForHook(params) {
1530
+ var _a, _b;
1531
+ const { calls, localPrivateKey, accountAbstractionConfig, chainsById, getPreferredRpcUrl } = params;
1532
+ if (!calls || localPrivateKey) return null;
1533
+ const config = __spreadProps(__spreadValues({}, accountAbstractionConfig), { provider: "alchemy" });
1633
1534
  const chainConfig = getAAChainConfig(config, calls, chainsById);
1634
- if (!chainConfig) {
1635
- if (throwOnMissingConfig) {
1636
- const chainIds = Array.from(new Set(calls.map((c) => c.chainId)));
1637
- throw new Error(
1638
- `AA is not configured for chain ${chainIds[0]}, or batching is disabled for that chain.`
1639
- );
1640
- }
1641
- return null;
1642
- }
1643
- const apiKey = preResolvedApiKey != null ? preResolvedApiKey : readEnv(ALCHEMY_API_KEY_ENVS, { publicOnly });
1644
- if (!apiKey) {
1645
- if (throwOnMissingConfig) {
1646
- throw new Error("Alchemy AA requires ALCHEMY_API_KEY.");
1647
- }
1648
- return null;
1649
- }
1535
+ if (!chainConfig) return null;
1536
+ const apiKey = (_a = process.env.NEXT_PUBLIC_ALCHEMY_API_KEY) == null ? void 0 : _a.trim();
1537
+ if (!apiKey) return null;
1650
1538
  const chain = chainsById[chainConfig.chainId];
1651
- if (!chain) {
1652
- return null;
1653
- }
1654
- const gasPolicyId = preResolvedGasPolicyId != null ? preResolvedGasPolicyId : readGasPolicyEnv(
1655
- chainConfig.chainId,
1656
- chainSlugById,
1657
- ALCHEMY_GAS_POLICY_ENVS,
1658
- { publicOnly }
1659
- );
1660
- if (chainConfig.sponsorship === "required" && !gasPolicyId) {
1661
- if (throwOnMissingConfig) {
1662
- throw new Error(
1663
- `Alchemy gas policy required for chain ${chainConfig.chainId} but not configured.`
1664
- );
1665
- }
1666
- return null;
1667
- }
1668
- if (modeOverride && !chainConfig.supportedModes.includes(modeOverride)) {
1669
- if (throwOnMissingConfig) {
1670
- throw new Error(
1671
- `AA mode "${modeOverride}" is not supported on chain ${chainConfig.chainId}.`
1672
- );
1673
- }
1674
- return null;
1675
- }
1676
- const resolvedChainConfig = modeOverride ? __spreadProps(__spreadValues({}, chainConfig), { defaultMode: modeOverride }) : chainConfig;
1677
- const plan = buildAAExecutionPlan(config, resolvedChainConfig);
1678
- return {
1679
- chainConfig: resolvedChainConfig,
1680
- plan,
1539
+ if (!chain) return null;
1540
+ const gasPolicyId = (_b = process.env.NEXT_PUBLIC_ALCHEMY_GAS_POLICY_ID) == null ? void 0 : _b.trim();
1541
+ const resolved = buildAAExecutionPlan(config, chainConfig);
1542
+ return __spreadProps(__spreadValues({}, resolved), {
1681
1543
  apiKey,
1682
1544
  chain,
1683
1545
  rpcUrl: getPreferredRpcUrl(chain),
1684
1546
  gasPolicyId,
1685
- mode: resolvedChainConfig.defaultMode
1686
- };
1687
- }
1688
- function resolvePimlicoConfig(options) {
1689
- const {
1690
- calls,
1691
- localPrivateKey,
1692
- accountAbstractionConfig = DEFAULT_AA_CONFIG,
1693
- chainsById,
1694
- rpcUrl,
1695
- modeOverride,
1696
- publicOnly = false,
1697
- throwOnMissingConfig = false,
1698
- apiKey: preResolvedApiKey
1699
- } = options;
1700
- if (!calls || localPrivateKey) {
1701
- return null;
1702
- }
1703
- const config = __spreadProps(__spreadValues({}, accountAbstractionConfig), {
1704
- provider: "pimlico"
1547
+ mode: chainConfig.defaultMode
1705
1548
  });
1706
- const chainConfig = getAAChainConfig(config, calls, chainsById);
1707
- if (!chainConfig) {
1708
- if (throwOnMissingConfig) {
1709
- const chainIds = Array.from(new Set(calls.map((c) => c.chainId)));
1710
- throw new Error(
1711
- `AA is not configured for chain ${chainIds[0]}, or batching is disabled for that chain.`
1712
- );
1713
- }
1714
- return null;
1715
- }
1716
- const apiKey = preResolvedApiKey != null ? preResolvedApiKey : readEnv(PIMLICO_API_KEY_ENVS, { publicOnly });
1717
- if (!apiKey) {
1718
- if (throwOnMissingConfig) {
1719
- throw new Error("Pimlico AA requires PIMLICO_API_KEY.");
1720
- }
1721
- return null;
1722
- }
1723
- const chain = chainsById[chainConfig.chainId];
1724
- if (!chain) {
1725
- return null;
1726
- }
1727
- if (modeOverride && !chainConfig.supportedModes.includes(modeOverride)) {
1728
- if (throwOnMissingConfig) {
1729
- throw new Error(
1730
- `AA mode "${modeOverride}" is not supported on chain ${chainConfig.chainId}.`
1731
- );
1732
- }
1733
- return null;
1734
- }
1735
- const resolvedChainConfig = modeOverride ? __spreadProps(__spreadValues({}, chainConfig), { defaultMode: modeOverride }) : chainConfig;
1736
- const plan = buildAAExecutionPlan(config, resolvedChainConfig);
1737
- return {
1738
- chainConfig: resolvedChainConfig,
1739
- plan,
1740
- apiKey,
1741
- chain,
1742
- rpcUrl,
1743
- mode: resolvedChainConfig.defaultMode
1744
- };
1745
1549
  }
1746
-
1747
- // src/aa/alchemy.ts
1748
1550
  function createAlchemyAAProvider({
1749
1551
  accountAbstractionConfig = DEFAULT_AA_CONFIG,
1750
1552
  useAlchemyAA,
@@ -1753,15 +1555,14 @@ function createAlchemyAAProvider({
1753
1555
  getPreferredRpcUrl
1754
1556
  }) {
1755
1557
  return function useAlchemyAAProvider(calls, localPrivateKey) {
1756
- var _a, _b;
1757
- const resolved = resolveAlchemyConfig({
1558
+ var _a;
1559
+ const resolved = resolveForHook({
1758
1560
  calls,
1759
1561
  localPrivateKey,
1760
1562
  accountAbstractionConfig,
1761
1563
  chainsById,
1762
1564
  chainSlugById,
1763
- getPreferredRpcUrl,
1764
- publicOnly: true
1565
+ getPreferredRpcUrl
1765
1566
  });
1766
1567
  const params = resolved ? {
1767
1568
  enabled: true,
@@ -1773,49 +1574,16 @@ function createAlchemyAAProvider({
1773
1574
  } : void 0;
1774
1575
  const query = useAlchemyAA(params);
1775
1576
  return {
1776
- plan: (_a = resolved == null ? void 0 : resolved.plan) != null ? _a : null,
1777
- query,
1778
- AA: query.AA,
1779
- isPending: Boolean(resolved && query.isPending),
1780
- error: (_b = query.error) != null ? _b : null
1577
+ resolved: resolved != null ? resolved : null,
1578
+ account: query.account,
1579
+ pending: Boolean(resolved && query.pending),
1580
+ error: (_a = query.error) != null ? _a : null
1781
1581
  };
1782
1582
  };
1783
1583
  }
1784
1584
 
1785
- // src/aa/pimlico.ts
1786
- function createPimlicoAAProvider({
1787
- accountAbstractionConfig = DEFAULT_AA_CONFIG,
1788
- usePimlicoAA,
1789
- chainsById,
1790
- rpcUrl
1791
- }) {
1792
- return function usePimlicoAAProvider(calls, localPrivateKey) {
1793
- var _a, _b;
1794
- const resolved = resolvePimlicoConfig({
1795
- calls,
1796
- localPrivateKey,
1797
- accountAbstractionConfig,
1798
- chainsById,
1799
- rpcUrl,
1800
- publicOnly: true
1801
- });
1802
- const params = resolved ? {
1803
- enabled: true,
1804
- apiKey: resolved.apiKey,
1805
- chain: resolved.chain,
1806
- mode: resolved.mode,
1807
- rpcUrl: resolved.rpcUrl
1808
- } : void 0;
1809
- const query = usePimlicoAA(params);
1810
- return {
1811
- plan: (_a = resolved == null ? void 0 : resolved.plan) != null ? _a : null,
1812
- query,
1813
- AA: query.AA,
1814
- isPending: Boolean(resolved && query.isPending),
1815
- error: (_b = query.error) != null ? _b : null
1816
- };
1817
- };
1818
- }
1585
+ // src/aa/alchemy/create.ts
1586
+ import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
1819
1587
 
1820
1588
  // src/aa/adapt.ts
1821
1589
  function adaptSmartAccount(account) {
@@ -1841,33 +1609,8 @@ function isAlchemySponsorshipLimitError(error) {
1841
1609
  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");
1842
1610
  }
1843
1611
 
1844
- // src/aa/create.ts
1845
- import { createAlchemySmartAccount } from "@getpara/aa-alchemy";
1846
- import { createPimlicoSmartAccount } from "@getpara/aa-pimlico";
1612
+ // src/aa/owner.ts
1847
1613
  import { privateKeyToAccount } from "viem/accounts";
1848
- var ALCHEMY_7702_DELEGATION_ADDRESS = "0x69007702764179f14F51cdce752f4f775d74E139";
1849
- async function createAAProviderState(options) {
1850
- if (options.provider === "alchemy") {
1851
- return createAlchemyAAState({
1852
- chain: options.chain,
1853
- owner: options.owner,
1854
- rpcUrl: options.rpcUrl,
1855
- callList: options.callList,
1856
- mode: options.mode,
1857
- apiKey: options.apiKey,
1858
- gasPolicyId: options.gasPolicyId,
1859
- sponsored: options.sponsored
1860
- });
1861
- }
1862
- return createPimlicoAAState({
1863
- chain: options.chain,
1864
- owner: options.owner,
1865
- rpcUrl: options.rpcUrl,
1866
- callList: options.callList,
1867
- mode: options.mode,
1868
- apiKey: options.apiKey
1869
- });
1870
- }
1871
1614
  function getDirectOwnerParams(owner) {
1872
1615
  return {
1873
1616
  kind: "ready",
@@ -1913,210 +1656,654 @@ function getOwnerParams(owner) {
1913
1656
  return getSessionOwnerParams(owner);
1914
1657
  }
1915
1658
  }
1916
- function getMissingOwnerState(plan, provider) {
1659
+ function getMissingOwnerState(resolved, provider) {
1917
1660
  return {
1918
- plan,
1919
- AA: null,
1920
- isPending: false,
1661
+ resolved,
1662
+ account: null,
1663
+ pending: false,
1921
1664
  error: new Error(
1922
1665
  `${provider} AA account creation requires a direct owner or a supported session owner.`
1923
1666
  )
1924
1667
  };
1925
1668
  }
1926
- function getUnsupportedAdapterState(plan, adapter) {
1669
+ function getUnsupportedAdapterState(resolved, adapter) {
1927
1670
  return {
1928
- plan,
1929
- AA: null,
1930
- isPending: false,
1671
+ resolved,
1672
+ account: null,
1673
+ pending: false,
1931
1674
  error: new Error(`Session adapter "${adapter}" is not implemented.`)
1932
1675
  };
1933
1676
  }
1677
+
1678
+ // src/aa/alchemy/create.ts
1679
+ var ALCHEMY_7702_DELEGATION_ADDRESS = "0x69007702764179f14F51cdce752f4f775d74E139";
1680
+ var AA_DEBUG_ENABLED = process.env.AOMI_AA_DEBUG === "1";
1681
+ var EIP_7702_AUTH_GAS_OVERHEAD = BigInt(25e3);
1682
+ function alchemyRpcUrl(chainId, apiKey) {
1683
+ var _a;
1684
+ const slug = (_a = ALCHEMY_CHAIN_SLUGS[chainId]) != null ? _a : "eth-mainnet";
1685
+ return `https://${slug}.g.alchemy.com/v2/${apiKey}`;
1686
+ }
1687
+ function aaDebug(message, fields) {
1688
+ if (!AA_DEBUG_ENABLED) return;
1689
+ if (fields) {
1690
+ console.debug(`[aomi][aa][alchemy] ${message}`, fields);
1691
+ return;
1692
+ }
1693
+ console.debug(`[aomi][aa][alchemy] ${message}`);
1694
+ }
1695
+ function extractExistingAccountAddress(error) {
1696
+ var _a;
1697
+ const message = error instanceof Error ? error.message : String(error);
1698
+ const match = message.match(/Account with address (0x[a-fA-F0-9]{40}) already exists/);
1699
+ return (_a = match == null ? void 0 : match[1]) != null ? _a : null;
1700
+ }
1701
+ function deriveAlchemy4337AccountId(address) {
1702
+ var _a;
1703
+ const hex = address.toLowerCase().slice(2).padEnd(32, "0").slice(0, 32).split("");
1704
+ const namespace = ["4", "3", "3", "7", "5", "a", "a", "b"];
1705
+ for (let i = 0; i < namespace.length; i += 1) {
1706
+ hex[i] = namespace[i];
1707
+ }
1708
+ hex[12] = "4";
1709
+ const variant = Number.parseInt((_a = hex[16]) != null ? _a : "0", 16);
1710
+ hex[16] = (variant & 3 | 8).toString(16);
1711
+ return [
1712
+ hex.slice(0, 8).join(""),
1713
+ hex.slice(8, 12).join(""),
1714
+ hex.slice(12, 16).join(""),
1715
+ hex.slice(16, 20).join(""),
1716
+ hex.slice(20, 32).join("")
1717
+ ].join("-");
1718
+ }
1934
1719
  async function createAlchemyAAState(options) {
1935
1720
  var _a, _b;
1936
1721
  const {
1937
1722
  chain,
1938
1723
  owner,
1939
- rpcUrl,
1940
1724
  callList,
1941
1725
  mode,
1942
1726
  sponsored = true
1943
1727
  } = options;
1944
- const resolved = resolveAlchemyConfig({
1945
- calls: callList,
1946
- chainsById: { [chain.id]: chain },
1947
- modeOverride: mode,
1948
- throwOnMissingConfig: true,
1949
- getPreferredRpcUrl: () => rpcUrl,
1950
- apiKey: options.apiKey,
1951
- gasPolicyId: options.gasPolicyId
1728
+ const chainConfig = getAAChainConfig(DEFAULT_AA_CONFIG, callList, {
1729
+ [chain.id]: chain
1952
1730
  });
1953
- if (!resolved) {
1954
- throw new Error("Alchemy AA config resolution failed.");
1731
+ if (!chainConfig) {
1732
+ throw new Error(`AA is not configured for chain ${chain.id}.`);
1955
1733
  }
1956
- const apiKey = (_a = options.apiKey) != null ? _a : resolved.apiKey;
1957
- const gasPolicyId = sponsored ? (_b = options.gasPolicyId) != null ? _b : readEnv(ALCHEMY_GAS_POLICY_ENVS) : void 0;
1958
- const plan = __spreadProps(__spreadValues({}, resolved.plan), {
1959
- sponsorship: gasPolicyId ? resolved.plan.sponsorship : "disabled",
1734
+ const effectiveMode = mode != null ? mode : chainConfig.defaultMode;
1735
+ const plan = buildAAExecutionPlan(
1736
+ __spreadProps(__spreadValues({}, DEFAULT_AA_CONFIG), { provider: "alchemy" }),
1737
+ __spreadProps(__spreadValues({}, chainConfig), { defaultMode: effectiveMode })
1738
+ );
1739
+ const gasPolicyId = sponsored ? (_b = options.gasPolicyId) != null ? _b : (_a = process.env.ALCHEMY_GAS_POLICY_ID) == null ? void 0 : _a.trim() : void 0;
1740
+ const execution = __spreadProps(__spreadValues({}, plan), {
1741
+ mode: effectiveMode,
1742
+ sponsorship: gasPolicyId ? plan.sponsorship : "disabled",
1960
1743
  fallbackToEoa: false
1961
1744
  });
1962
1745
  const ownerParams = getOwnerParams(owner);
1963
1746
  if (ownerParams.kind === "missing") {
1964
- return getMissingOwnerState(plan, "alchemy");
1747
+ return getMissingOwnerState(execution, "alchemy");
1965
1748
  }
1966
1749
  if (ownerParams.kind === "unsupported_adapter") {
1967
- return getUnsupportedAdapterState(plan, ownerParams.adapter);
1750
+ return getUnsupportedAdapterState(execution, ownerParams.adapter);
1968
1751
  }
1969
1752
  if (owner.kind === "direct") {
1753
+ const directParams = {
1754
+ resolved: execution,
1755
+ chain,
1756
+ privateKey: owner.privateKey,
1757
+ apiKey: options.apiKey,
1758
+ proxyBaseUrl: options.proxyBaseUrl,
1759
+ gasPolicyId
1760
+ };
1970
1761
  try {
1971
- return await createAlchemyWalletApisState({
1972
- plan,
1973
- chain,
1974
- privateKey: owner.privateKey,
1975
- apiKey,
1976
- gasPolicyId,
1977
- mode: plan.mode
1978
- });
1762
+ return await (execution.mode === "7702" ? createAlchemy7702State(directParams) : createAlchemy4337State(directParams));
1979
1763
  } catch (error) {
1980
1764
  return {
1981
- plan,
1982
- AA: null,
1983
- isPending: false,
1765
+ resolved: execution,
1766
+ account: null,
1767
+ pending: false,
1984
1768
  error: error instanceof Error ? error : new Error(String(error))
1985
1769
  };
1986
1770
  }
1987
1771
  }
1772
+ if (!options.apiKey) {
1773
+ return {
1774
+ resolved: execution,
1775
+ account: null,
1776
+ pending: false,
1777
+ error: new Error(
1778
+ "Alchemy AA with session/adapter owner requires ALCHEMY_API_KEY."
1779
+ )
1780
+ };
1781
+ }
1988
1782
  try {
1783
+ const { createAlchemySmartAccount } = await import("@getpara/aa-alchemy");
1989
1784
  const smartAccount = await createAlchemySmartAccount(__spreadProps(__spreadValues({}, ownerParams.ownerParams), {
1990
- apiKey,
1785
+ apiKey: options.apiKey,
1991
1786
  gasPolicyId,
1992
1787
  chain,
1993
- rpcUrl,
1994
- mode: plan.mode
1788
+ rpcUrl: options.rpcUrl,
1789
+ mode: execution.mode
1995
1790
  }));
1996
1791
  if (!smartAccount) {
1997
1792
  return {
1998
- plan,
1999
- AA: null,
2000
- isPending: false,
1793
+ resolved: execution,
1794
+ account: null,
1795
+ pending: false,
2001
1796
  error: new Error("Alchemy AA account could not be initialized.")
2002
1797
  };
2003
1798
  }
2004
1799
  return {
2005
- plan,
2006
- AA: adaptSmartAccount(smartAccount),
2007
- isPending: false,
1800
+ resolved: execution,
1801
+ account: adaptSmartAccount(smartAccount),
1802
+ pending: false,
2008
1803
  error: null
2009
1804
  };
2010
1805
  } catch (error) {
2011
1806
  return {
2012
- plan,
2013
- AA: null,
2014
- isPending: false,
1807
+ resolved: execution,
1808
+ account: null,
1809
+ pending: false,
2015
1810
  error: error instanceof Error ? error : new Error(String(error))
2016
1811
  };
2017
1812
  }
2018
1813
  }
2019
- async function createAlchemyWalletApisState(params) {
1814
+ async function createAlchemy4337State(params) {
2020
1815
  const { createSmartWalletClient, alchemyWalletTransport } = await import("@alchemy/wallet-apis");
2021
- const signer = privateKeyToAccount(params.privateKey);
2022
- const walletClient = createSmartWalletClient(__spreadValues({
2023
- transport: alchemyWalletTransport({ apiKey: params.apiKey }),
1816
+ const transport = params.proxyBaseUrl ? alchemyWalletTransport({ url: params.proxyBaseUrl }) : alchemyWalletTransport({ apiKey: params.apiKey });
1817
+ const signer = privateKeyToAccount2(params.privateKey);
1818
+ const alchemyClient = createSmartWalletClient(__spreadValues({
1819
+ transport,
2024
1820
  chain: params.chain,
2025
1821
  signer
2026
1822
  }, params.gasPolicyId ? { paymaster: { policyId: params.gasPolicyId } } : {}));
2027
- let accountAddress = signer.address;
2028
- if (params.mode === "4337") {
2029
- const account = await walletClient.requestAccount();
2030
- accountAddress = account.address;
1823
+ const signerAddress = signer.address;
1824
+ const accountId = deriveAlchemy4337AccountId(signerAddress);
1825
+ aaDebug("4337:requestAccount:start", {
1826
+ signerAddress,
1827
+ chainId: params.chain.id,
1828
+ accountId,
1829
+ hasGasPolicyId: Boolean(params.gasPolicyId)
1830
+ });
1831
+ let account;
1832
+ try {
1833
+ account = await alchemyClient.requestAccount({
1834
+ signerAddress,
1835
+ id: accountId,
1836
+ creationHint: {
1837
+ accountType: "sma-b",
1838
+ createAdditional: true
1839
+ }
1840
+ });
1841
+ } catch (error) {
1842
+ const existingAccountAddress = extractExistingAccountAddress(error);
1843
+ if (!existingAccountAddress) {
1844
+ throw error;
1845
+ }
1846
+ aaDebug("4337:requestAccount:existing-account", {
1847
+ existingAccountAddress
1848
+ });
1849
+ account = await alchemyClient.requestAccount({
1850
+ accountAddress: existingAccountAddress
1851
+ });
2031
1852
  }
1853
+ const accountAddress = account.address;
1854
+ aaDebug("4337:requestAccount:done", { signerAddress, accountAddress });
2032
1855
  const sendCalls = async (calls) => {
2033
- var _a, _b;
2034
- const result = await walletClient.sendCalls(__spreadProps(__spreadValues({}, params.mode === "4337" ? { account: accountAddress } : {}), {
2035
- calls
2036
- }));
2037
- const status = await walletClient.waitForCallsStatus({ id: result.id });
2038
- const transactionHash = (_b = (_a = status.receipts) == null ? void 0 : _a[0]) == null ? void 0 : _b.transactionHash;
2039
- if (!transactionHash) {
2040
- throw new Error("Alchemy Wallets API did not return a transaction hash.");
1856
+ var _a, _b, _c, _d;
1857
+ aaDebug("4337:sendCalls:start", {
1858
+ signerAddress,
1859
+ accountAddress,
1860
+ chainId: params.chain.id,
1861
+ callCount: calls.length,
1862
+ hasGasPolicyId: Boolean(params.gasPolicyId)
1863
+ });
1864
+ try {
1865
+ const result = await alchemyClient.sendCalls({
1866
+ account: accountAddress,
1867
+ calls
1868
+ });
1869
+ aaDebug("4337:sendCalls:submitted", { callId: result.id });
1870
+ const status = await alchemyClient.waitForCallsStatus({ id: result.id });
1871
+ const transactionHash = (_b = (_a = status.receipts) == null ? void 0 : _a[0]) == null ? void 0 : _b.transactionHash;
1872
+ aaDebug("4337:sendCalls:receipt", {
1873
+ callId: result.id,
1874
+ hasTransactionHash: Boolean(transactionHash),
1875
+ receipts: (_d = (_c = status.receipts) == null ? void 0 : _c.length) != null ? _d : 0
1876
+ });
1877
+ if (!transactionHash) {
1878
+ throw new Error("Alchemy Wallets API did not return a transaction hash.");
1879
+ }
1880
+ return { transactionHash };
1881
+ } catch (error) {
1882
+ aaDebug("4337:sendCalls:error", {
1883
+ signerAddress,
1884
+ accountAddress,
1885
+ chainId: params.chain.id,
1886
+ error: error instanceof Error ? error.message : String(error)
1887
+ });
1888
+ throw error;
2041
1889
  }
2042
- return { transactionHash };
2043
1890
  };
2044
- const AA = {
1891
+ const smartAccount = {
2045
1892
  provider: "alchemy",
2046
- mode: params.mode,
1893
+ mode: "4337",
2047
1894
  AAAddress: accountAddress,
2048
- delegationAddress: params.mode === "7702" ? ALCHEMY_7702_DELEGATION_ADDRESS : void 0,
2049
1895
  sendTransaction: async (call) => sendCalls([call]),
2050
1896
  sendBatchTransaction: async (calls) => sendCalls(calls)
2051
1897
  };
2052
1898
  return {
2053
- plan: params.plan,
2054
- AA,
2055
- isPending: false,
1899
+ resolved: params.resolved,
1900
+ account: smartAccount,
1901
+ pending: false,
2056
1902
  error: null
2057
1903
  };
2058
1904
  }
2059
- async function createPimlicoAAState(options) {
2060
- var _a;
1905
+ async function createAlchemy7702State(params) {
1906
+ const { createWalletClient, createPublicClient, http } = await import("viem");
1907
+ const { encodeExecuteData } = await import("viem/experimental/erc7821");
1908
+ if (params.gasPolicyId) {
1909
+ aaDebug(
1910
+ "7702:gas-policy-ignored",
1911
+ { gasPolicyId: params.gasPolicyId }
1912
+ );
1913
+ console.warn(
1914
+ "\u26A0\uFE0F Gas policy is not supported for raw EIP-7702 transactions. The signer's EOA pays gas directly."
1915
+ );
1916
+ }
1917
+ const signer = privateKeyToAccount2(params.privateKey);
1918
+ const signerAddress = signer.address;
1919
+ let rpcUrl;
1920
+ if (params.proxyBaseUrl) {
1921
+ rpcUrl = params.proxyBaseUrl;
1922
+ } else if (params.apiKey) {
1923
+ rpcUrl = alchemyRpcUrl(params.chain.id, params.apiKey);
1924
+ }
1925
+ const walletClient = createWalletClient({
1926
+ account: signer,
1927
+ chain: params.chain,
1928
+ transport: http(rpcUrl)
1929
+ });
1930
+ const publicClient = createPublicClient({
1931
+ chain: params.chain,
1932
+ transport: http(rpcUrl)
1933
+ });
1934
+ const send7702 = async (calls) => {
1935
+ aaDebug("7702:send:start", {
1936
+ signerAddress,
1937
+ chainId: params.chain.id,
1938
+ callCount: calls.length,
1939
+ calls: calls.map((call) => {
1940
+ var _a;
1941
+ return {
1942
+ to: call.to,
1943
+ value: call.value.toString(),
1944
+ data: (_a = call.data) != null ? _a : "0x"
1945
+ };
1946
+ })
1947
+ });
1948
+ const authorization = await walletClient.signAuthorization({
1949
+ contractAddress: ALCHEMY_7702_DELEGATION_ADDRESS
1950
+ });
1951
+ aaDebug("7702:authorization-signed", {
1952
+ contractAddress: ALCHEMY_7702_DELEGATION_ADDRESS
1953
+ });
1954
+ const data = encodeExecuteData({
1955
+ calls: calls.map((call) => {
1956
+ var _a;
1957
+ return {
1958
+ to: call.to,
1959
+ value: call.value,
1960
+ data: (_a = call.data) != null ? _a : "0x"
1961
+ };
1962
+ })
1963
+ });
1964
+ aaDebug("7702:calldata-encoded", { dataLength: data.length });
1965
+ const gasEstimate = await publicClient.estimateGas({
1966
+ account: signer,
1967
+ to: signerAddress,
1968
+ data,
1969
+ authorizationList: [authorization]
1970
+ });
1971
+ const gas = gasEstimate + EIP_7702_AUTH_GAS_OVERHEAD;
1972
+ aaDebug("7702:gas-estimated", {
1973
+ estimate: gasEstimate.toString(),
1974
+ total: gas.toString()
1975
+ });
1976
+ const hash = await walletClient.sendTransaction({
1977
+ to: signerAddress,
1978
+ data,
1979
+ gas,
1980
+ authorizationList: [authorization]
1981
+ });
1982
+ aaDebug("7702:tx-sent", { hash });
1983
+ const receipt = await publicClient.waitForTransactionReceipt({ hash });
1984
+ aaDebug("7702:tx-confirmed", {
1985
+ hash,
1986
+ status: receipt.status,
1987
+ gasUsed: receipt.gasUsed.toString()
1988
+ });
1989
+ if (receipt.status === "reverted") {
1990
+ throw new Error(`EIP-7702 transaction reverted: ${hash}`);
1991
+ }
1992
+ return { transactionHash: hash };
1993
+ };
1994
+ const smartAccount = {
1995
+ provider: "alchemy",
1996
+ mode: "7702",
1997
+ AAAddress: signerAddress,
1998
+ delegationAddress: ALCHEMY_7702_DELEGATION_ADDRESS,
1999
+ sendTransaction: async (call) => send7702([call]),
2000
+ sendBatchTransaction: async (calls) => send7702(calls)
2001
+ };
2002
+ return {
2003
+ resolved: params.resolved,
2004
+ account: smartAccount,
2005
+ pending: false,
2006
+ error: null
2007
+ };
2008
+ }
2009
+
2010
+ // src/aa/pimlico/resolve.ts
2011
+ function resolvePimlicoConfig(options) {
2012
+ var _a, _b, _c;
2061
2013
  const {
2062
- chain,
2063
- owner,
2014
+ calls,
2015
+ localPrivateKey,
2016
+ accountAbstractionConfig = DEFAULT_AA_CONFIG,
2017
+ chainsById,
2064
2018
  rpcUrl,
2065
- callList,
2066
- mode
2019
+ modeOverride,
2020
+ publicOnly = false,
2021
+ throwOnMissingConfig = false,
2022
+ apiKey: preResolvedApiKey
2067
2023
  } = options;
2068
- const resolved = resolvePimlicoConfig({
2069
- calls: callList,
2070
- chainsById: { [chain.id]: chain },
2024
+ if (!calls || localPrivateKey) {
2025
+ return null;
2026
+ }
2027
+ const config = __spreadProps(__spreadValues({}, accountAbstractionConfig), {
2028
+ provider: "pimlico"
2029
+ });
2030
+ const chainConfig = getAAChainConfig(config, calls, chainsById);
2031
+ if (!chainConfig) {
2032
+ if (throwOnMissingConfig) {
2033
+ const chainIds = Array.from(new Set(calls.map((c) => c.chainId)));
2034
+ throw new Error(
2035
+ `AA is not configured for chain ${chainIds[0]}, or batching is disabled for that chain.`
2036
+ );
2037
+ }
2038
+ return null;
2039
+ }
2040
+ 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;
2041
+ if (!apiKey) {
2042
+ if (throwOnMissingConfig) {
2043
+ throw new Error("Pimlico AA requires PIMLICO_API_KEY.");
2044
+ }
2045
+ return null;
2046
+ }
2047
+ const chain = chainsById[chainConfig.chainId];
2048
+ if (!chain) {
2049
+ return null;
2050
+ }
2051
+ if (modeOverride && !chainConfig.supportedModes.includes(modeOverride)) {
2052
+ if (throwOnMissingConfig) {
2053
+ throw new Error(
2054
+ `AA mode "${modeOverride}" is not supported on chain ${chainConfig.chainId}.`
2055
+ );
2056
+ }
2057
+ return null;
2058
+ }
2059
+ const resolvedChainConfig = modeOverride ? __spreadProps(__spreadValues({}, chainConfig), { defaultMode: modeOverride }) : chainConfig;
2060
+ const resolved = buildAAExecutionPlan(config, resolvedChainConfig);
2061
+ return __spreadProps(__spreadValues({}, resolved), {
2062
+ apiKey,
2063
+ chain,
2071
2064
  rpcUrl,
2072
- modeOverride: mode,
2073
- throwOnMissingConfig: true,
2074
- apiKey: options.apiKey
2065
+ mode: resolvedChainConfig.defaultMode
2066
+ });
2067
+ }
2068
+
2069
+ // src/aa/pimlico/provider.ts
2070
+ function createPimlicoAAProvider({
2071
+ accountAbstractionConfig = DEFAULT_AA_CONFIG,
2072
+ usePimlicoAA,
2073
+ chainsById,
2074
+ rpcUrl
2075
+ }) {
2076
+ return function usePimlicoAAProvider(calls, localPrivateKey) {
2077
+ var _a;
2078
+ const resolved = resolvePimlicoConfig({
2079
+ calls,
2080
+ localPrivateKey,
2081
+ accountAbstractionConfig,
2082
+ chainsById,
2083
+ rpcUrl,
2084
+ publicOnly: true
2085
+ });
2086
+ const params = resolved ? {
2087
+ enabled: true,
2088
+ apiKey: resolved.apiKey,
2089
+ chain: resolved.chain,
2090
+ mode: resolved.mode,
2091
+ rpcUrl: resolved.rpcUrl
2092
+ } : void 0;
2093
+ const query = usePimlicoAA(params);
2094
+ return {
2095
+ resolved: resolved != null ? resolved : null,
2096
+ account: query.account,
2097
+ pending: Boolean(resolved && query.pending),
2098
+ error: (_a = query.error) != null ? _a : null
2099
+ };
2100
+ };
2101
+ }
2102
+
2103
+ // src/aa/pimlico/create.ts
2104
+ import { privateKeyToAccount as privateKeyToAccount3 } from "viem/accounts";
2105
+ var AA_DEBUG_ENABLED2 = process.env.AOMI_AA_DEBUG === "1";
2106
+ function pimDebug(message, fields) {
2107
+ if (!AA_DEBUG_ENABLED2) return;
2108
+ if (fields) {
2109
+ console.debug(`[aomi][aa][pimlico] ${message}`, fields);
2110
+ return;
2111
+ }
2112
+ console.debug(`[aomi][aa][pimlico] ${message}`);
2113
+ }
2114
+ async function createPimlicoAAState(options) {
2115
+ var _a, _b;
2116
+ const { chain, owner, callList, mode } = options;
2117
+ const chainConfig = getAAChainConfig(DEFAULT_AA_CONFIG, callList, {
2118
+ [chain.id]: chain
2075
2119
  });
2076
- if (!resolved) {
2077
- throw new Error("Pimlico AA config resolution failed.");
2120
+ if (!chainConfig) {
2121
+ throw new Error(`AA is not configured for chain ${chain.id}.`);
2122
+ }
2123
+ const effectiveMode = mode != null ? mode : chainConfig.defaultMode;
2124
+ const plan = buildAAExecutionPlan(
2125
+ __spreadProps(__spreadValues({}, DEFAULT_AA_CONFIG), { provider: "pimlico" }),
2126
+ __spreadProps(__spreadValues({}, chainConfig), { defaultMode: effectiveMode })
2127
+ );
2128
+ const apiKey = (_b = options.apiKey) != null ? _b : (_a = process.env.PIMLICO_API_KEY) == null ? void 0 : _a.trim();
2129
+ if (!apiKey) {
2130
+ throw new Error("Pimlico AA requires PIMLICO_API_KEY.");
2078
2131
  }
2079
- const apiKey = (_a = options.apiKey) != null ? _a : resolved.apiKey;
2080
- const plan = __spreadProps(__spreadValues({}, resolved.plan), {
2132
+ const execution = __spreadProps(__spreadValues({}, plan), {
2133
+ mode: effectiveMode,
2081
2134
  fallbackToEoa: false
2082
2135
  });
2083
2136
  const ownerParams = getOwnerParams(owner);
2084
2137
  if (ownerParams.kind === "missing") {
2085
- return getMissingOwnerState(plan, "pimlico");
2138
+ return getMissingOwnerState(execution, "pimlico");
2086
2139
  }
2087
2140
  if (ownerParams.kind === "unsupported_adapter") {
2088
- return getUnsupportedAdapterState(plan, ownerParams.adapter);
2141
+ return getUnsupportedAdapterState(execution, ownerParams.adapter);
2142
+ }
2143
+ if (owner.kind === "direct") {
2144
+ try {
2145
+ return await createPimlicoDirectState({
2146
+ resolved: execution,
2147
+ chain,
2148
+ privateKey: owner.privateKey,
2149
+ rpcUrl: options.rpcUrl,
2150
+ apiKey,
2151
+ mode: effectiveMode
2152
+ });
2153
+ } catch (error) {
2154
+ return {
2155
+ resolved: execution,
2156
+ account: null,
2157
+ pending: false,
2158
+ error: error instanceof Error ? error : new Error(String(error))
2159
+ };
2160
+ }
2089
2161
  }
2090
2162
  try {
2163
+ const { createPimlicoSmartAccount } = await import("@getpara/aa-pimlico");
2091
2164
  const smartAccount = await createPimlicoSmartAccount(__spreadProps(__spreadValues({}, ownerParams.ownerParams), {
2092
2165
  apiKey,
2093
2166
  chain,
2094
- rpcUrl,
2095
- mode: plan.mode
2167
+ rpcUrl: options.rpcUrl,
2168
+ mode: execution.mode
2096
2169
  }));
2097
2170
  if (!smartAccount) {
2098
2171
  return {
2099
- plan,
2100
- AA: null,
2101
- isPending: false,
2172
+ resolved: execution,
2173
+ account: null,
2174
+ pending: false,
2102
2175
  error: new Error("Pimlico AA account could not be initialized.")
2103
2176
  };
2104
2177
  }
2105
2178
  return {
2106
- plan,
2107
- AA: adaptSmartAccount(smartAccount),
2108
- isPending: false,
2179
+ resolved: execution,
2180
+ account: adaptSmartAccount(smartAccount),
2181
+ pending: false,
2109
2182
  error: null
2110
2183
  };
2111
2184
  } catch (error) {
2112
2185
  return {
2113
- plan,
2114
- AA: null,
2115
- isPending: false,
2186
+ resolved: execution,
2187
+ account: null,
2188
+ pending: false,
2116
2189
  error: error instanceof Error ? error : new Error(String(error))
2117
2190
  };
2118
2191
  }
2119
2192
  }
2193
+ function buildPimlicoRpcUrl(chain, apiKey) {
2194
+ const slug = chain.name.toLowerCase().replace(/\s+/g, "-");
2195
+ return `https://api.pimlico.io/v2/${slug}/rpc?apikey=${apiKey}`;
2196
+ }
2197
+ async function createPimlicoDirectState(params) {
2198
+ const { createSmartAccountClient } = await import("permissionless");
2199
+ const { toSimpleSmartAccount } = await import("permissionless/accounts");
2200
+ const { createPimlicoClient } = await import("permissionless/clients/pimlico");
2201
+ const { createPublicClient, http } = await import("viem");
2202
+ const { entryPoint07Address } = await import("viem/account-abstraction");
2203
+ const signer = privateKeyToAccount3(params.privateKey);
2204
+ const signerAddress = signer.address;
2205
+ const pimlicoRpcUrl = buildPimlicoRpcUrl(params.chain, params.apiKey);
2206
+ pimDebug("4337:start", {
2207
+ signerAddress,
2208
+ chainId: params.chain.id,
2209
+ pimlicoRpcUrl: pimlicoRpcUrl.replace(params.apiKey, "***")
2210
+ });
2211
+ const publicClient = createPublicClient({
2212
+ chain: params.chain,
2213
+ transport: http(params.rpcUrl)
2214
+ });
2215
+ const paymasterClient = createPimlicoClient({
2216
+ entryPoint: { address: entryPoint07Address, version: "0.7" },
2217
+ transport: http(pimlicoRpcUrl)
2218
+ });
2219
+ const smartAccount = await toSimpleSmartAccount({
2220
+ client: publicClient,
2221
+ owner: signer,
2222
+ entryPoint: { address: entryPoint07Address, version: "0.7" }
2223
+ });
2224
+ const accountAddress = smartAccount.address;
2225
+ pimDebug("4337:account-created", {
2226
+ signerAddress,
2227
+ accountAddress
2228
+ });
2229
+ const smartAccountClient = createSmartAccountClient({
2230
+ account: smartAccount,
2231
+ chain: params.chain,
2232
+ paymaster: paymasterClient,
2233
+ bundlerTransport: http(pimlicoRpcUrl),
2234
+ userOperation: {
2235
+ estimateFeesPerGas: async () => {
2236
+ const gasPrice = await paymasterClient.getUserOperationGasPrice();
2237
+ return gasPrice.fast;
2238
+ }
2239
+ }
2240
+ });
2241
+ const sendCalls = async (calls) => {
2242
+ pimDebug("4337:send:start", {
2243
+ accountAddress,
2244
+ chainId: params.chain.id,
2245
+ callCount: calls.length
2246
+ });
2247
+ const hash = await smartAccountClient.sendTransaction({
2248
+ account: smartAccount,
2249
+ calls: calls.map((c) => {
2250
+ var _a;
2251
+ return {
2252
+ to: c.to,
2253
+ value: c.value,
2254
+ data: (_a = c.data) != null ? _a : "0x"
2255
+ };
2256
+ })
2257
+ });
2258
+ pimDebug("4337:send:userOpHash", { hash });
2259
+ const receipt = await publicClient.waitForTransactionReceipt({
2260
+ hash
2261
+ });
2262
+ pimDebug("4337:send:confirmed", {
2263
+ transactionHash: receipt.transactionHash,
2264
+ status: receipt.status
2265
+ });
2266
+ return { transactionHash: receipt.transactionHash };
2267
+ };
2268
+ const account = {
2269
+ provider: "pimlico",
2270
+ mode: "4337",
2271
+ AAAddress: accountAddress,
2272
+ sendTransaction: async (call) => sendCalls([call]),
2273
+ sendBatchTransaction: async (calls) => sendCalls(calls)
2274
+ };
2275
+ return {
2276
+ resolved: params.resolved,
2277
+ account,
2278
+ pending: false,
2279
+ error: null
2280
+ };
2281
+ }
2282
+
2283
+ // src/aa/create.ts
2284
+ async function createAAProviderState(options) {
2285
+ if (options.provider === "alchemy") {
2286
+ return createAlchemyAAState({
2287
+ chain: options.chain,
2288
+ owner: options.owner,
2289
+ rpcUrl: options.rpcUrl,
2290
+ callList: options.callList,
2291
+ mode: options.mode,
2292
+ apiKey: options.apiKey,
2293
+ gasPolicyId: options.gasPolicyId,
2294
+ sponsored: options.sponsored,
2295
+ proxyBaseUrl: options.proxyBaseUrl
2296
+ });
2297
+ }
2298
+ return createPimlicoAAState({
2299
+ chain: options.chain,
2300
+ owner: options.owner,
2301
+ rpcUrl: options.rpcUrl,
2302
+ callList: options.callList,
2303
+ mode: options.mode,
2304
+ apiKey: options.apiKey
2305
+ });
2306
+ }
2120
2307
  export {
2121
2308
  AomiClient,
2122
2309
  CLIENT_TYPE_TS_CLI,
@@ -2136,16 +2323,12 @@ export {
2136
2323
  isAlchemySponsorshipLimitError,
2137
2324
  isAsyncCallback,
2138
2325
  isInlineCall,
2139
- isProviderConfigured,
2140
2326
  isSystemError,
2141
2327
  isSystemNotice,
2142
2328
  normalizeEip712Payload,
2143
2329
  normalizeTxPayload,
2144
- parseAAConfig,
2145
- readEnv,
2146
- resolveAlchemyConfig,
2147
- resolveDefaultProvider,
2148
2330
  resolvePimlicoConfig,
2331
+ toAAWalletCall,
2149
2332
  toViemSignTypedDataArgs,
2150
2333
  unwrapSystemEvent
2151
2334
  };