@aastar/sdk 0.20.6 → 0.20.7

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.
@@ -1,7 +1,8 @@
1
- import { ERC4337Utils, BLSManager, resolveTier, algIdForTier, ecdsa, ALG_CUMULATIVE_T3, ALG_CUMULATIVE_T2, ALG_P256, ALG_ECDSA, ALG_BLS, weierstrass, sha256 } from './chunk-FUU7RIIA.js';
2
- import { ethers } from 'ethers';
1
+ import { selectorFromId, keccak256, solidityPacked, ERC4337Utils, BLSManager, resolveTier, algIdForTier, encodeAbiParams, ecdsa, ALG_CUMULATIVE_T3, ALG_CUMULATIVE_T2, ALG_P256, ALG_ECDSA, ALG_BLS, weierstrass, sha256 } from './chunk-X3AMH53O.js';
2
+ import { parseAbi, createPublicClient, http, getContract, formatEther, parseUnits, parseEther, encodeFunctionData, concat, numberToHex, zeroAddress, hexToBytes, formatUnits, hashMessage as hashMessage$1, toRlp, keccak256 as keccak256$1, concatHex, recoverAddress as recoverAddress$1 } from 'viem';
3
3
  import axios from 'axios';
4
4
  import { createHash } from 'crypto';
5
+ import { privateKeyToAccount } from 'viem/accounts';
5
6
 
6
7
  // ../airaccount/src/server/constants/entrypoint.ts
7
8
  var EntryPointVersion = /* @__PURE__ */ ((EntryPointVersion2) => {
@@ -139,7 +140,9 @@ var AIRACCOUNT_ABI = [
139
140
  "function guardians(uint256 index) external view returns (address)",
140
141
  "function p256KeyX() external view returns (bytes32)",
141
142
  "function p256KeyY() external view returns (bytes32)",
142
- "function getConfigDescription() external view returns (tuple(address accountOwner, address guardAddress, uint256 dailyLimit, uint256 dailyRemaining, uint256 tier1Limit, uint256 tier2Limit, address[3] guardianAddresses, uint8 guardianCount, bool hasP256Key, bool hasValidator, bool hasAggregator, bool hasActiveRecovery))",
143
+ // abitype/viem human-readable ABIs use a bare parenthesised tuple `(...)`, not the
144
+ // ethers-style `tuple(...)` keyword (which parseAbi rejects with "Invalid ABI parameter").
145
+ "function getConfigDescription() external view returns ((address accountOwner, address guardAddress, uint256 dailyLimit, uint256 dailyRemaining, uint256 tier1Limit, uint256 tier2Limit, address[3] guardianAddresses, uint8 guardianCount, bool hasP256Key, bool hasValidator, bool hasAggregator, bool hasActiveRecovery))",
143
146
  // ── Owner / key management ──
144
147
  "function setValidator(address _validator) external",
145
148
  "function setP256Key(bytes32 _x, bytes32 _y) external",
@@ -438,22 +441,37 @@ var SilentLogger = class {
438
441
  }
439
442
  };
440
443
  var EthereumProvider = class {
444
+ /** Main-network read client. Pass to viem getContract / readContract calls. */
441
445
  provider;
446
+ /** Bundler client — used only for raw eth_ / pimlico_ userOp JSON-RPC. */
442
447
  bundlerProvider;
443
448
  config;
444
449
  logger;
445
450
  constructor(config) {
446
451
  this.config = config;
447
452
  this.logger = config.logger ?? new ConsoleLogger("[EthereumProvider]");
448
- this.provider = new ethers.JsonRpcProvider(config.rpcUrl);
449
- this.bundlerProvider = new ethers.JsonRpcProvider(config.bundlerRpcUrl);
453
+ this.provider = createPublicClient({ transport: http(config.rpcUrl) });
454
+ this.bundlerProvider = createPublicClient({ transport: http(config.bundlerRpcUrl) });
450
455
  }
456
+ /** Returns the viem PublicClient for the main network RPC. */
451
457
  getProvider() {
452
458
  return this.provider;
453
459
  }
460
+ /** Returns the viem PublicClient bound to the bundler RPC (raw .request only). */
454
461
  getBundlerProvider() {
455
462
  return this.bundlerProvider;
456
463
  }
464
+ /**
465
+ * Raw bundler JSON-RPC call. The bundler exposes non-standard methods
466
+ * (eth_sendUserOperation, pimlico_getUserOperationGasPrice, ...) that are not in
467
+ * viem's typed RPC schema, so we go through the transport's request fn untyped.
468
+ */
469
+ async bundlerRequest(method, params) {
470
+ return await this.bundlerProvider.request({
471
+ method,
472
+ params
473
+ });
474
+ }
457
475
  // ── Config helpers ──────────────────────────────────────────────
458
476
  getVersionConfig(version) {
459
477
  const map = {
@@ -483,86 +501,98 @@ var EthereumProvider = class {
483
501
  return "0.6" /* V0_6 */;
484
502
  }
485
503
  // ── Contract factories ──────────────────────────────────────────
504
+ /** Build a read-only viem contract bound to the main-network PublicClient. */
505
+ contractAt(address, abi) {
506
+ return getContract({
507
+ address,
508
+ abi: parseAbi(abi),
509
+ client: this.provider
510
+ });
511
+ }
486
512
  getFactoryContract(version = "0.6" /* V0_6 */) {
487
513
  const address = this.getFactoryAddress(version);
488
514
  const abi = version === "0.6" /* V0_6 */ ? FACTORY_ABI_V6 : AIRACCOUNT_FACTORY_ABI;
489
- return new ethers.Contract(address, abi, this.provider);
515
+ return this.contractAt(address, abi);
490
516
  }
491
517
  getEntryPointContract(version = "0.6" /* V0_6 */) {
492
518
  const address = this.getEntryPointAddress(version);
493
519
  const abi = version === "0.6" /* V0_6 */ ? ENTRYPOINT_ABI_V6 : ENTRYPOINT_ABI_V7_V8;
494
- return new ethers.Contract(address, abi, this.provider);
520
+ return this.contractAt(address, abi);
495
521
  }
496
522
  getValidatorContract(version = "0.6" /* V0_6 */) {
497
523
  const address = this.getValidatorAddress(version);
498
- return new ethers.Contract(address, VALIDATOR_ABI, this.provider);
524
+ return this.contractAt(address, VALIDATOR_ABI);
499
525
  }
500
526
  getAccountContract(address) {
501
- return new ethers.Contract(address, AIRACCOUNT_ABI, this.provider);
527
+ return this.contractAt(address, AIRACCOUNT_ABI);
502
528
  }
503
529
  // ── M7 Module contracts ─────────────────────────────────────────
504
530
  // M7 r4 module helpers — addresses renamed to *M7r4 suffix in beta.3 to avoid ambiguity.
505
531
  // These methods are retained for backwards compatibility; callers should pass an explicit address.
506
532
  getAgentSessionKeyValidatorContract(address = AIRACCOUNT_ADDRESSES.sepolia.agentSessionKeyValidatorM7r4) {
507
- return new ethers.Contract(address, AGENT_SESSION_KEY_VALIDATOR_ABI, this.provider);
533
+ return this.contractAt(address, AGENT_SESSION_KEY_VALIDATOR_ABI);
508
534
  }
509
535
  getTierGuardHookContract(address = AIRACCOUNT_ADDRESSES.sepolia.tierGuardHookM7r4) {
510
- return new ethers.Contract(address, TIER_GUARD_HOOK_ABI, this.provider);
536
+ return this.contractAt(address, TIER_GUARD_HOOK_ABI);
511
537
  }
512
538
  getCompositeValidatorContract(address = AIRACCOUNT_ADDRESSES.sepolia.compositeValidatorM7r4) {
513
- return new ethers.Contract(address, AIR_ACCOUNT_COMPOSITE_VALIDATOR_ABI, this.provider);
539
+ return this.contractAt(address, AIR_ACCOUNT_COMPOSITE_VALIDATOR_ABI);
514
540
  }
515
541
  getForceExitModuleContract(address) {
516
- return new ethers.Contract(address, FORCE_EXIT_MODULE_ABI, this.provider);
542
+ return this.contractAt(address, FORCE_EXIT_MODULE_ABI);
517
543
  }
518
544
  // ── On-chain queries ────────────────────────────────────────────
519
545
  async getBalance(address) {
520
- const balance = await this.provider.getBalance(address);
521
- return ethers.formatEther(balance);
546
+ const balance = await this.provider.getBalance({ address });
547
+ return formatEther(balance);
522
548
  }
523
549
  async getNonce(accountAddress, key = 0, version = "0.6" /* V0_6 */) {
524
550
  const entryPoint = this.getEntryPointContract(version);
525
- return await entryPoint.getNonce(accountAddress, key);
551
+ return await entryPoint.read.getNonce([
552
+ accountAddress,
553
+ BigInt(key)
554
+ ]);
526
555
  }
527
556
  async getUserOpHash(userOp, version = "0.6" /* V0_6 */) {
528
557
  const entryPoint = this.getEntryPointContract(version);
558
+ const read = entryPoint.read;
529
559
  if (version === "0.6" /* V0_6 */) {
530
560
  const op = userOp;
531
561
  const userOpArray = [
532
562
  op.sender,
533
- op.nonce,
563
+ BigInt(op.nonce),
534
564
  op.initCode || "0x",
535
565
  op.callData,
536
- op.callGasLimit,
537
- op.verificationGasLimit,
538
- op.preVerificationGas,
539
- op.maxFeePerGas,
540
- op.maxPriorityFeePerGas,
566
+ BigInt(op.callGasLimit),
567
+ BigInt(op.verificationGasLimit),
568
+ BigInt(op.preVerificationGas),
569
+ BigInt(op.maxFeePerGas),
570
+ BigInt(op.maxPriorityFeePerGas),
541
571
  op.paymasterAndData || "0x",
542
572
  "0x"
543
573
  // Always use empty signature for hash calculation
544
574
  ];
545
- return await entryPoint.getUserOpHash(userOpArray);
575
+ return await read.getUserOpHash([userOpArray]);
546
576
  } else {
547
577
  const packedOp = userOp;
548
578
  const packedOpArray = [
549
579
  packedOp.sender,
550
- packedOp.nonce,
580
+ BigInt(packedOp.nonce),
551
581
  packedOp.initCode || "0x",
552
582
  packedOp.callData,
553
583
  packedOp.accountGasLimits,
554
- packedOp.preVerificationGas,
584
+ BigInt(packedOp.preVerificationGas),
555
585
  packedOp.gasFees,
556
586
  packedOp.paymasterAndData || "0x",
557
587
  "0x"
558
588
  ];
559
- return await entryPoint.getUserOpHash(packedOpArray);
589
+ return await read.getUserOpHash([packedOpArray]);
560
590
  }
561
591
  }
562
592
  // ── Bundler RPC ─────────────────────────────────────────────────
563
593
  async estimateUserOperationGas(userOp, version = "0.6" /* V0_6 */) {
564
594
  try {
565
- return await this.bundlerProvider.send("eth_estimateUserOperationGas", [
595
+ return await this.bundlerRequest("eth_estimateUserOperationGas", [
566
596
  userOp,
567
597
  this.getEntryPointAddress(version)
568
598
  ]);
@@ -576,13 +606,13 @@ var EthereumProvider = class {
576
606
  }
577
607
  }
578
608
  async sendUserOperation(userOp, version = "0.6" /* V0_6 */) {
579
- return await this.bundlerProvider.send("eth_sendUserOperation", [
609
+ return await this.bundlerRequest("eth_sendUserOperation", [
580
610
  userOp,
581
611
  this.getEntryPointAddress(version)
582
612
  ]);
583
613
  }
584
614
  async getUserOperationReceipt(userOpHash) {
585
- return await this.bundlerProvider.send("eth_getUserOperationReceipt", [userOpHash]);
615
+ return await this.bundlerRequest("eth_getUserOperationReceipt", [userOpHash]);
586
616
  }
587
617
  async waitForUserOp(userOpHash, maxAttempts = 60) {
588
618
  const pollInterval = 2e3;
@@ -601,16 +631,16 @@ var EthereumProvider = class {
601
631
  }
602
632
  async getUserOperationGasPrice() {
603
633
  try {
604
- const gasPrice = await this.bundlerProvider.send("pimlico_getUserOperationGasPrice", []);
634
+ const gasPrice = await this.bundlerRequest("pimlico_getUserOperationGasPrice", []);
605
635
  return {
606
636
  maxFeePerGas: gasPrice.fast.maxFeePerGas,
607
637
  maxPriorityFeePerGas: gasPrice.fast.maxPriorityFeePerGas
608
638
  };
609
639
  } catch {
610
640
  try {
611
- const feeData = await this.provider.getFeeData();
612
- const baseFee = feeData.maxFeePerGas || ethers.parseUnits("20", "gwei");
613
- const priorityFee = feeData.maxPriorityFeePerGas || ethers.parseUnits("2", "gwei");
641
+ const feeData = await this.provider.estimateFeesPerGas();
642
+ const baseFee = feeData.maxFeePerGas || parseUnits("20", 9);
643
+ const priorityFee = feeData.maxPriorityFeePerGas || parseUnits("2", 9);
614
644
  const maxFeePerGas = baseFee * 3n / 2n;
615
645
  const maxPriorityFeePerGas = priorityFee * 3n / 2n;
616
646
  return {
@@ -619,13 +649,64 @@ var EthereumProvider = class {
619
649
  };
620
650
  } catch {
621
651
  return {
622
- maxFeePerGas: "0x" + ethers.parseUnits("3", "gwei").toString(16),
623
- maxPriorityFeePerGas: "0x" + ethers.parseUnits("1", "gwei").toString(16)
652
+ maxFeePerGas: "0x" + parseUnits("3", 9).toString(16),
653
+ // gwei
654
+ maxPriorityFeePerGas: "0x" + parseUnits("1", 9).toString(16)
655
+ // gwei
624
656
  };
625
657
  }
626
658
  }
627
659
  }
628
660
  };
661
+
662
+ // ../airaccount/src/server/providers/typed-reads.ts
663
+ function readFn(contract, name) {
664
+ return contract.read[name];
665
+ }
666
+ function readValidatorGasEstimate(validator, nodeCount) {
667
+ return readFn(validator, "getGasEstimate")([nodeCount]);
668
+ }
669
+ function readPredictedAddress(factory, owner, salt, config) {
670
+ return readFn(factory, "getAddress")([owner, salt, config]);
671
+ }
672
+ function readPredictedAddressWithDefaults(factory, owner, salt, guardian1, guardian2, dailyLimit) {
673
+ return readFn(factory, "getAddressWithDefaults")([
674
+ owner,
675
+ salt,
676
+ guardian1,
677
+ guardian2,
678
+ dailyLimit
679
+ ]);
680
+ }
681
+ async function readAccountTierLimits(account) {
682
+ const [tier1Limit, tier2Limit] = await Promise.all([
683
+ readFn(account, "tier1Limit")([]),
684
+ readFn(account, "tier2Limit")([])
685
+ ]);
686
+ return { tier1Limit, tier2Limit };
687
+ }
688
+ function readAlgorithmApproved(account, algId) {
689
+ return readFn(account, "approvedAlgorithms")([algId]);
690
+ }
691
+ async function readAccountGuardAddress(account) {
692
+ const config = await readFn(account, "getConfigDescription")([]);
693
+ return config.guardAddress;
694
+ }
695
+ async function readGuardDailyAllowance(guard) {
696
+ const [dailyLimit, dailyRemaining] = await Promise.all([
697
+ readFn(guard, "dailyLimit")([]),
698
+ readFn(guard, "remainingDailyAllowance")([])
699
+ ]);
700
+ return { dailyLimit, dailyRemaining };
701
+ }
702
+ function readBuildGrantHash(validator, account, sessionKey, cfg) {
703
+ return readFn(validator, "buildGrantHash")([account, sessionKey, cfg]);
704
+ }
705
+ function readBuildP256GrantHash(validator, account, keyX, keyY, cfg) {
706
+ return readFn(validator, "buildP256GrantHash")([account, keyX, keyY, cfg]);
707
+ }
708
+
709
+ // ../airaccount/src/server/services/account-manager.ts
629
710
  var AccountManager = class {
630
711
  constructor(ethereum, storage, signer, logger) {
631
712
  this.ethereum = ethereum;
@@ -643,12 +724,12 @@ var AccountManager = class {
643
724
  );
644
725
  if (existing) return existing;
645
726
  const factory = this.ethereum.getFactoryContract(version);
646
- const validatorAddress = this.ethereum.getValidatorContract(version).target || this.ethereum.getValidatorAddress(version);
727
+ const validatorAddress = this.ethereum.getValidatorContract(version).address || this.ethereum.getValidatorAddress(version);
647
728
  const { address: signerAddress } = await this.signer.ensureSigner(userId);
648
729
  const salt = options?.salt ?? Math.floor(Math.random() * 1e6);
649
730
  const dailyLimitValue = options?.dailyLimit ?? 0n;
650
731
  const minimalConfig = [
651
- [ethers.ZeroAddress, ethers.ZeroAddress, ethers.ZeroAddress],
732
+ [zeroAddress, zeroAddress, zeroAddress],
652
733
  // guardians (address[3])
653
734
  dailyLimitValue,
654
735
  // dailyLimit (0 = no guard)
@@ -661,11 +742,16 @@ var AccountManager = class {
661
742
  []
662
743
  // initialTokenConfigs
663
744
  ];
664
- const accountAddress = await factory.getFunction("getAddress")(signerAddress, salt, minimalConfig);
745
+ const accountAddress = await readPredictedAddress(
746
+ factory,
747
+ signerAddress,
748
+ BigInt(salt),
749
+ minimalConfig
750
+ );
665
751
  let deployed = false;
666
752
  try {
667
- const code = await this.ethereum.getProvider().getCode(accountAddress);
668
- deployed = code !== "0x";
753
+ const code = await this.ethereum.getProvider().getCode({ address: accountAddress });
754
+ deployed = !!code && code !== "0x";
669
755
  } catch {
670
756
  }
671
757
  const account = {
@@ -677,7 +763,7 @@ var AccountManager = class {
677
763
  deploymentTxHash: null,
678
764
  validatorAddress,
679
765
  entryPointVersion: versionStr,
680
- factoryAddress: factory.target || this.ethereum.getFactoryAddress(version),
766
+ factoryAddress: factory.address || this.ethereum.getFactoryAddress(version),
681
767
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
682
768
  // Persist dailyLimit so buildUserOperation can reconstruct identical initCode at deploy time.
683
769
  ...dailyLimitValue > 0n ? { dailyLimit: dailyLimitValue.toString() } : {}
@@ -709,7 +795,7 @@ var AccountManager = class {
709
795
  return {
710
796
  address: account.address,
711
797
  balance,
712
- balanceInWei: ethers.parseEther(balance).toString()
798
+ balanceInWei: parseEther(balance).toString()
713
799
  };
714
800
  }
715
801
  async getAccountNonce(userId) {
@@ -745,10 +831,10 @@ var AccountManager = class {
745
831
  `salt value ${salt} exceeds Number.MAX_SAFE_INTEGER; pass as bigint to avoid precision loss`
746
832
  );
747
833
  }
748
- return ethers.keccak256(
749
- ethers.solidityPacked(
834
+ return keccak256(
835
+ solidityPacked(
750
836
  ["string", "uint256", "address", "address", "uint256", "uint256"],
751
- ["ACCEPT_GUARDIAN", chainId, factoryAddress, owner, salt, dailyLimit]
837
+ ["ACCEPT_GUARDIAN", BigInt(chainId), factoryAddress, owner, BigInt(salt), dailyLimit]
752
838
  )
753
839
  );
754
840
  }
@@ -764,13 +850,11 @@ var AccountManager = class {
764
850
  * @param guardianSigs 65-byte EIP-191 hex signatures from required guardians
765
851
  */
766
852
  encodeModifyTierLimits(tier1, tier2, deadline, guardianSigs) {
767
- const iface = new ethers.Interface(AIRACCOUNT_ABI);
768
- return iface.encodeFunctionData("modifyTierLimitsWithGuardians", [
769
- tier1,
770
- tier2,
771
- deadline,
772
- guardianSigs
773
- ]);
853
+ return encodeFunctionData({
854
+ abi: parseAbi(AIRACCOUNT_ABI),
855
+ functionName: "modifyTierLimitsWithGuardians",
856
+ args: [tier1, tier2, deadline, guardianSigs]
857
+ });
774
858
  }
775
859
  /**
776
860
  * Create an AirAccount with 3 on-chain guardians:
@@ -804,18 +888,19 @@ var AccountManager = class {
804
888
  const { address: signerAddress } = await this.signer.ensureSigner(userId);
805
889
  const salt = params.salt ?? Math.floor(Math.random() * 1e6);
806
890
  const factory = this.ethereum.getFactoryContract(version);
807
- const factoryAddress = factory.target ?? this.ethereum.getFactoryAddress(version);
808
- const accountAddress = await factory.getFunction("getAddressWithDefaults")(
891
+ const factoryAddress = factory.address ?? this.ethereum.getFactoryAddress(version);
892
+ const accountAddress = await readPredictedAddressWithDefaults(
893
+ factory,
809
894
  signerAddress,
810
- salt,
895
+ BigInt(salt),
811
896
  params.guardian1,
812
897
  params.guardian2,
813
898
  params.dailyLimit
814
899
  );
815
900
  let deployed = false;
816
901
  try {
817
- const code = await this.ethereum.getProvider().getCode(accountAddress);
818
- deployed = code !== "0x";
902
+ const code = await this.ethereum.getProvider().getCode({ address: accountAddress });
903
+ deployed = !!code && code !== "0x";
819
904
  } catch {
820
905
  }
821
906
  const validatorAddress = this.ethereum.getValidatorAddress(version);
@@ -844,9 +929,13 @@ var AccountManager = class {
844
929
  return account;
845
930
  }
846
931
  };
847
- var EXECUTE_USER_OP_SELECTOR = ethers.id("executeUserOp((address,uint256,bytes,bytes,bytes32,uint256,bytes32,bytes,bytes),bytes32)").slice(0, 10);
848
- var EXECUTE_SELECTOR = ethers.id("execute(address,uint256,bytes)").slice(0, 10);
849
- var EXECUTE_BATCH_SELECTOR = ethers.id("executeBatch(address[],uint256[],bytes[])").slice(0, 10);
932
+ var EXECUTE_USER_OP_SELECTOR = selectorFromId(
933
+ "executeUserOp((address,uint256,bytes,bytes,bytes32,uint256,bytes32,bytes,bytes),bytes32)"
934
+ );
935
+ var EXECUTE_SELECTOR = selectorFromId("execute(address,uint256,bytes)");
936
+ var EXECUTE_BATCH_SELECTOR = selectorFromId(
937
+ "executeBatch(address[],uint256[],bytes[])"
938
+ );
850
939
  function wrapExecuteUserOp(innerCallData) {
851
940
  if (!/^0x[0-9a-fA-F]*$/.test(innerCallData) || innerCallData.length < 10) {
852
941
  throw new Error("wrapExecuteUserOp: innerCallData must be 0x-prefixed calldata with a 4-byte selector");
@@ -857,7 +946,7 @@ function wrapExecuteUserOp(innerCallData) {
857
946
  `wrapExecuteUserOp: only execute()/executeBatch() may be wrapped (got selector ${sel}); the account reverts UnsupportedInnerSelector otherwise`
858
947
  );
859
948
  }
860
- return ethers.concat([EXECUTE_USER_OP_SELECTOR, innerCallData]);
949
+ return concat([EXECUTE_USER_OP_SELECTOR, innerCallData]);
861
950
  }
862
951
  function isExecuteUserOpWrapped(callData) {
863
952
  return callData.slice(0, 10).toLowerCase() === EXECUTE_USER_OP_SELECTOR;
@@ -873,12 +962,16 @@ var PaymasterPriceStalenessError = class extends Error {
873
962
  this.name = "PaymasterPriceStalenessError";
874
963
  }
875
964
  };
876
- var PAYMASTER_PRICE_ABI = [
965
+ var PAYMASTER_PRICE_ABI = parseAbi([
877
966
  "function token() view returns (address)",
878
967
  "function cachedPriceTimestamp() view returns (uint256)",
879
968
  "function priceStalenessThreshold() view returns (uint256)",
880
969
  "function updatePrice() external"
881
- ];
970
+ ]);
971
+ var SUPER_PAYMASTER_DETECT_ABI = parseAbi([
972
+ "function owner() view returns (address)",
973
+ "function operators(address) view returns (bool,uint256,address,uint256)"
974
+ ]);
882
975
  var PaymasterManager = class {
883
976
  constructor(ethereum, storage, logger) {
884
977
  this.ethereum = ethereum;
@@ -916,10 +1009,14 @@ var PaymasterManager = class {
916
1009
  */
917
1010
  async checkPriceFreshness(paymasterAddress) {
918
1011
  const provider = this.ethereum.getProvider();
919
- const contract = new ethers.Contract(paymasterAddress, PAYMASTER_PRICE_ABI, provider);
1012
+ const contract = getContract({
1013
+ address: paymasterAddress,
1014
+ abi: PAYMASTER_PRICE_ABI,
1015
+ client: provider
1016
+ });
920
1017
  const [timestamp, threshold] = await Promise.all([
921
- contract.cachedPriceTimestamp(),
922
- contract.priceStalenessThreshold()
1018
+ contract.read.cachedPriceTimestamp(),
1019
+ contract.read.priceStalenessThreshold()
923
1020
  ]);
924
1021
  const nowSeconds = Math.floor(Date.now() / 1e3);
925
1022
  const ageSeconds = nowSeconds - Number(timestamp);
@@ -934,14 +1031,26 @@ var PaymasterManager = class {
934
1031
  * Call `updatePrice()` on a paymaster contract (permissionless).
935
1032
  * Useful when `checkPriceFreshness()` reports stale price.
936
1033
  *
937
- * @param signer - An ethers Signer that will send the transaction (must have gas).
1034
+ * @param walletClient - A viem WalletClient (with an account) that will send
1035
+ * the transaction (must have gas). Replaces the former ethers Signer param.
938
1036
  */
939
- async updatePrice(paymasterAddress, signer) {
940
- const contract = new ethers.Contract(paymasterAddress, PAYMASTER_PRICE_ABI, signer);
941
- const tx = await contract.updatePrice({ gasLimit: 3e5 });
942
- await tx.wait();
943
- this.logger.log(`Paymaster ${paymasterAddress} price updated, tx: ${tx.hash}`);
944
- return tx.hash;
1037
+ async updatePrice(paymasterAddress, walletClient) {
1038
+ const account = walletClient.account;
1039
+ if (!account) {
1040
+ throw new Error("updatePrice requires a WalletClient with a configured account");
1041
+ }
1042
+ const hash = await walletClient.writeContract({
1043
+ address: paymasterAddress,
1044
+ abi: PAYMASTER_PRICE_ABI,
1045
+ functionName: "updatePrice",
1046
+ args: [],
1047
+ gas: BigInt(3e5),
1048
+ account,
1049
+ chain: walletClient.chain
1050
+ });
1051
+ await this.ethereum.getProvider().waitForTransactionReceipt({ hash });
1052
+ this.logger.log(`Paymaster ${paymasterAddress} price updated, tx: ${hash}`);
1053
+ return hash;
945
1054
  }
946
1055
  async getPaymasterData(userId, paymasterName, userOp, entryPoint, customAddress, options) {
947
1056
  if (paymasterName === "custom-user-provided" && customAddress) {
@@ -955,16 +1064,13 @@ var PaymasterManager = class {
955
1064
  let isSuperPaymaster = false;
956
1065
  let operatorAddress = "0x";
957
1066
  try {
958
- const spContract = new ethers.Contract(
959
- formattedAddress,
960
- [
961
- "function owner() view returns (address)",
962
- "function operators(address) view returns (bool,uint256,address,uint256)"
963
- ],
964
- provider
965
- );
966
- const owner = await spContract.owner();
967
- const opInfo = await spContract.operators(owner);
1067
+ const spContract = getContract({
1068
+ address: formattedAddress,
1069
+ abi: SUPER_PAYMASTER_DETECT_ABI,
1070
+ client: provider
1071
+ });
1072
+ const owner = await spContract.read.owner();
1073
+ const opInfo = await spContract.read.operators([owner]);
968
1074
  if (opInfo && opInfo[0] === true) {
969
1075
  isSuperPaymaster = true;
970
1076
  operatorAddress = owner;
@@ -976,12 +1082,12 @@ var PaymasterManager = class {
976
1082
  const verGas = BigInt(8e4);
977
1083
  const postGas = BigInt(3e5);
978
1084
  const maxRate = (BigInt(1) << BigInt(256)) - BigInt(1);
979
- return ethers.concat([
1085
+ return concat([
980
1086
  formattedAddress,
981
- ethers.zeroPadValue(ethers.toBeHex(verGas), 16),
982
- ethers.zeroPadValue(ethers.toBeHex(postGas), 16),
1087
+ numberToHex(verGas, { size: 16 }),
1088
+ numberToHex(postGas, { size: 16 }),
983
1089
  operatorAddress,
984
- ethers.zeroPadValue(ethers.toBeHex(maxRate), 32)
1090
+ numberToHex(maxRate, { size: 32 })
985
1091
  ]);
986
1092
  }
987
1093
  const paymasterVerificationGasLimit = BigInt(196608);
@@ -991,13 +1097,13 @@ var PaymasterManager = class {
991
1097
  this.logger.log(`PaymasterV4 token from options: ${tokenAddress}`);
992
1098
  } else {
993
1099
  try {
994
- const pmContract = new ethers.Contract(
995
- formattedAddress,
996
- PAYMASTER_PRICE_ABI,
997
- provider
998
- );
999
- tokenAddress = await pmContract.token();
1000
- if (tokenAddress === ethers.ZeroAddress) tokenAddress = null;
1100
+ const pmContract = getContract({
1101
+ address: formattedAddress,
1102
+ abi: PAYMASTER_PRICE_ABI,
1103
+ client: provider
1104
+ });
1105
+ tokenAddress = await pmContract.read.token();
1106
+ if (tokenAddress === zeroAddress) tokenAddress = null;
1001
1107
  if (tokenAddress) {
1002
1108
  this.logger.log(`PaymasterV4 token auto-detected: ${tokenAddress}`);
1003
1109
  }
@@ -1007,13 +1113,13 @@ var PaymasterManager = class {
1007
1113
  }
1008
1114
  const parts = [
1009
1115
  formattedAddress,
1010
- ethers.zeroPadValue(ethers.toBeHex(paymasterVerificationGasLimit), 16),
1011
- ethers.zeroPadValue(ethers.toBeHex(paymasterPostOpGasLimit), 16)
1116
+ numberToHex(paymasterVerificationGasLimit, { size: 16 }),
1117
+ numberToHex(paymasterPostOpGasLimit, { size: 16 })
1012
1118
  ];
1013
1119
  if (tokenAddress) {
1014
1120
  parts.push(tokenAddress);
1015
1121
  }
1016
- return ethers.concat(parts);
1122
+ return concat(parts);
1017
1123
  }
1018
1124
  return formattedAddress;
1019
1125
  }
@@ -1068,16 +1174,12 @@ var PaymasterManager = class {
1068
1174
  return result.result.paymasterAndData;
1069
1175
  }
1070
1176
  if (result.result.paymaster) {
1071
- return ethers.concat([
1177
+ return concat([
1072
1178
  result.result.paymaster,
1073
- ethers.zeroPadValue(
1074
- ethers.toBeHex(BigInt(result.result.paymasterVerificationGasLimit || "0x30000")),
1075
- 16
1076
- ),
1077
- ethers.zeroPadValue(
1078
- ethers.toBeHex(BigInt(result.result.paymasterPostOpGasLimit || "0x30000")),
1079
- 16
1080
- ),
1179
+ numberToHex(BigInt(result.result.paymasterVerificationGasLimit || "0x30000"), {
1180
+ size: 16
1181
+ }),
1182
+ numberToHex(BigInt(result.result.paymasterPostOpGasLimit || "0x30000"), { size: 16 }),
1081
1183
  result.result.paymasterData || "0x"
1082
1184
  ]);
1083
1185
  }
@@ -1125,19 +1227,25 @@ var PaymasterManager = class {
1125
1227
  };
1126
1228
 
1127
1229
  // ../airaccount/src/server/services/transfer-manager.ts
1230
+ var AIRACCOUNT_ABI_PARSED = parseAbi(AIRACCOUNT_ABI);
1231
+ var AIRACCOUNT_FACTORY_ABI_PARSED = parseAbi(AIRACCOUNT_FACTORY_ABI);
1232
+ var FACTORY_ABI_V6_PARSED = parseAbi(FACTORY_ABI_V6);
1233
+ var VALIDATOR_GETTER_ABI = parseAbi(["function validator() view returns (address)"]);
1234
+ function encodeFn(abi, functionName, args) {
1235
+ return encodeFunctionData({ abi, functionName, args });
1236
+ }
1128
1237
  async function detectSignatureStrategy(provider, accountAddress) {
1129
1238
  try {
1130
- const accountCode = await provider.getCode(accountAddress);
1131
- if (accountCode === "0x") {
1239
+ const accountCode = await provider.getCode({ address: accountAddress });
1240
+ if (!accountCode || accountCode === "0x") {
1132
1241
  return { useECDSA: true, isCompositeValidator: true };
1133
1242
  }
1134
- const acc = new ethers.Contract(
1135
- accountAddress,
1136
- ["function validator() view returns (address)"],
1137
- provider
1138
- );
1139
- const v = await acc.validator();
1140
- return { useECDSA: v === ethers.ZeroAddress, isCompositeValidator: true };
1243
+ const v = await provider.readContract({
1244
+ address: accountAddress,
1245
+ abi: VALIDATOR_GETTER_ABI,
1246
+ functionName: "validator"
1247
+ });
1248
+ return { useECDSA: v === zeroAddress, isCompositeValidator: true };
1141
1249
  } catch {
1142
1250
  return { useECDSA: true, isCompositeValidator: false };
1143
1251
  }
@@ -1163,8 +1271,8 @@ var TransferManager = class {
1163
1271
  async executeTransfer(userId, params) {
1164
1272
  const account = await this.accountManager.getAccountByUserId(userId);
1165
1273
  if (!account) throw new Error("User account not found");
1166
- const code = await this.ethereum.getProvider().getCode(account.address);
1167
- const needsDeployment = code === "0x";
1274
+ const code = await this.ethereum.getProvider().getCode({ address: account.address });
1275
+ const needsDeployment = !code || code === "0x";
1168
1276
  if (needsDeployment) {
1169
1277
  this.logger.log("Account needs deployment, will deploy with first transaction");
1170
1278
  }
@@ -1212,17 +1320,23 @@ var TransferManager = class {
1212
1320
  ));
1213
1321
  }
1214
1322
  if (useECDSA) {
1215
- const signer = await this.signer.getSigner(userId, assertionCtx);
1216
- const ecdsaSig = await signer.signMessage(ethers.getBytes(userOpHash));
1323
+ const ecdsaSig = await this.signer.signMessage(
1324
+ userId,
1325
+ hexToBytes(userOpHash),
1326
+ assertionCtx
1327
+ );
1217
1328
  if (isCompositeValidator) {
1218
1329
  this.logger.log("ECDSA path for compositeValidator: prepending algId prefix");
1219
- userOp.signature = ethers.concat([ethers.toBeHex(ALG_ID.ECDSA, 1), ecdsaSig]);
1330
+ userOp.signature = concat([
1331
+ numberToHex(ALG_ID.ECDSA, { size: 1 }),
1332
+ ecdsaSig
1333
+ ]);
1220
1334
  } else {
1221
1335
  this.logger.log("ECDSA path for non-compositeValidator: raw signature");
1222
1336
  userOp.signature = ecdsaSig;
1223
1337
  }
1224
1338
  } else if (params.useAirAccountTiering && this.guardChecker) {
1225
- const transferValue = params.tokenAddress ? 0n : ethers.parseEther(params.amount);
1339
+ const transferValue = params.tokenAddress ? 0n : parseEther(params.amount);
1226
1340
  const preCheck = await this.guardChecker.preCheck(account.address, transferValue);
1227
1341
  if (!preCheck.ok) {
1228
1342
  throw new Error(`Guard pre-check failed: ${preCheck.errors.join("; ")}`);
@@ -1241,7 +1355,10 @@ var TransferManager = class {
1241
1355
  } else {
1242
1356
  const blsData = await this.blsService.generateBLSSignature(userId, userOpHash, assertionCtx);
1243
1357
  const packedBls = await this.blsService.packSignature(blsData);
1244
- userOp.signature = ethers.concat([ethers.toBeHex(ALG_ID.BLS, 1), packedBls]);
1358
+ userOp.signature = concat([
1359
+ numberToHex(ALG_ID.BLS, { size: 1 }),
1360
+ packedBls
1361
+ ]);
1245
1362
  }
1246
1363
  const transferId = generateId();
1247
1364
  let tokenSymbol = "ETH";
@@ -1294,8 +1411,8 @@ var TransferManager = class {
1294
1411
  status: "completed",
1295
1412
  completedAt: (/* @__PURE__ */ new Date()).toISOString()
1296
1413
  });
1297
- const code = await this.ethereum.getProvider().getCode(from);
1298
- if (code !== "0x") {
1414
+ const code = await this.ethereum.getProvider().getCode({ address: from });
1415
+ if (code && code !== "0x") {
1299
1416
  const account = (await this.storage.getAccounts()).find((a) => a.address === from);
1300
1417
  if (account && !account.deployed) {
1301
1418
  await this.storage.updateAccount(account.userId, {
@@ -1347,7 +1464,7 @@ var TransferManager = class {
1347
1464
  const gasEstimates = await this.ethereum.estimateUserOperationGas(formatted, version);
1348
1465
  const gasPrices = await this.ethereum.getUserOperationGasPrice();
1349
1466
  const validatorContract = this.ethereum.getValidatorContract(version);
1350
- const validatorGasEstimate = await validatorContract.getGasEstimate(3);
1467
+ const validatorGasEstimate = await readValidatorGasEstimate(validatorContract, 3n);
1351
1468
  return {
1352
1469
  callGasLimit: gasEstimates.callGasLimit,
1353
1470
  verificationGasLimit: gasEstimates.verificationGasLimit,
@@ -1398,27 +1515,26 @@ var TransferManager = class {
1398
1515
  }
1399
1516
  // ── Private helpers ─────────────────────────────────────────────
1400
1517
  async buildUserOperation(userId, sender, to, amount, data, usePaymaster, paymasterAddress, _paymasterData, tokenAddress, version = "0.6" /* V0_6 */, paymasterTokenAddress, wrapExecuteUserOpFlag = false) {
1401
- const accountContract = this.ethereum.getAccountContract(sender);
1402
1518
  const nonce = await this.ethereum.getNonce(sender, 0, version);
1403
1519
  const provider = this.ethereum.getProvider();
1404
- const code = await provider.getCode(sender);
1405
- const needsDeployment = code === "0x";
1520
+ const code = await provider.getCode({ address: sender });
1521
+ const needsDeployment = !code || code === "0x";
1406
1522
  let initCode = "0x";
1407
1523
  if (needsDeployment) {
1408
1524
  const accounts = await this.storage.getAccounts();
1409
1525
  const account = accounts.find((a) => a.address === sender);
1410
1526
  if (account) {
1411
1527
  const factory = this.ethereum.getFactoryContract(version);
1412
- const factoryAddress = await factory.getAddress();
1528
+ const factoryAddress = factory.address;
1413
1529
  let deployCalldata;
1414
1530
  if (version === "0.7" /* V0_7 */ || version === "0.8" /* V0_8 */) {
1415
1531
  const storedDailyLimit = account.dailyLimit ? BigInt(account.dailyLimit) : 0n;
1416
1532
  if (account.guardian1 && account.guardian2 && account.guardian1Sig && account.guardian2Sig) {
1417
1533
  const sig1 = account.guardian1Sig.startsWith("0x") ? account.guardian1Sig : `0x${account.guardian1Sig}`;
1418
1534
  const sig2 = account.guardian2Sig.startsWith("0x") ? account.guardian2Sig : `0x${account.guardian2Sig}`;
1419
- deployCalldata = factory.interface.encodeFunctionData("createAccountWithDefaults", [
1535
+ deployCalldata = encodeFn(AIRACCOUNT_FACTORY_ABI_PARSED, "createAccountWithDefaults", [
1420
1536
  account.signerAddress,
1421
- account.salt,
1537
+ BigInt(account.salt),
1422
1538
  account.guardian1,
1423
1539
  sig1,
1424
1540
  account.guardian2,
@@ -1427,7 +1543,7 @@ var TransferManager = class {
1427
1543
  ]);
1428
1544
  } else {
1429
1545
  const minimalConfig = [
1430
- [ethers.ZeroAddress, ethers.ZeroAddress, ethers.ZeroAddress],
1546
+ [zeroAddress, zeroAddress, zeroAddress],
1431
1547
  // guardians (address[3])
1432
1548
  storedDailyLimit,
1433
1549
  [],
@@ -1439,25 +1555,22 @@ var TransferManager = class {
1439
1555
  []
1440
1556
  // initialTokenConfigs
1441
1557
  ];
1442
- deployCalldata = factory.interface.encodeFunctionData("createAccount", [
1558
+ deployCalldata = encodeFn(AIRACCOUNT_FACTORY_ABI_PARSED, "createAccount", [
1443
1559
  account.signerAddress,
1444
- account.salt,
1560
+ BigInt(account.salt),
1445
1561
  minimalConfig
1446
1562
  ]);
1447
1563
  }
1448
1564
  } else {
1449
- deployCalldata = factory.interface.encodeFunctionData(
1450
- "createAccountWithAAStarValidator",
1451
- [
1452
- account.signerAddress,
1453
- account.signerAddress,
1454
- account.validatorAddress,
1455
- true,
1456
- account.salt
1457
- ]
1458
- );
1565
+ deployCalldata = encodeFn(FACTORY_ABI_V6_PARSED, "createAccountWithAAStarValidator", [
1566
+ account.signerAddress,
1567
+ account.signerAddress,
1568
+ account.validatorAddress,
1569
+ true,
1570
+ BigInt(account.salt)
1571
+ ]);
1459
1572
  }
1460
- initCode = ethers.concat([factoryAddress, deployCalldata]);
1573
+ initCode = concat([factoryAddress, deployCalldata]);
1461
1574
  }
1462
1575
  }
1463
1576
  let callData;
@@ -1468,17 +1581,9 @@ var TransferManager = class {
1468
1581
  amount,
1469
1582
  tokenInfo.decimals
1470
1583
  );
1471
- callData = accountContract.interface.encodeFunctionData("execute", [
1472
- tokenAddress,
1473
- 0,
1474
- transferCalldata
1475
- ]);
1584
+ callData = encodeFn(AIRACCOUNT_ABI_PARSED, "execute", [tokenAddress, 0n, transferCalldata]);
1476
1585
  } else {
1477
- callData = accountContract.interface.encodeFunctionData("execute", [
1478
- to,
1479
- ethers.parseEther(amount),
1480
- data
1481
- ]);
1586
+ callData = encodeFn(AIRACCOUNT_ABI_PARSED, "execute", [to, parseEther(amount), data]);
1482
1587
  }
1483
1588
  if (wrapExecuteUserOpFlag) {
1484
1589
  callData = wrapExecuteUserOp(callData);
@@ -1752,16 +1857,23 @@ var BLSSignatureService = class {
1752
1857
  if (!account) {
1753
1858
  throw new Error(`User account not found for userId: ${userId}`);
1754
1859
  }
1755
- const wallet = await this.signer.getSigner(userId, ctx);
1756
- const walletAddress = await wallet.getAddress();
1860
+ const walletAddress = await this.signer.getAddress(userId);
1757
1861
  if (walletAddress.toLowerCase() !== account.signerAddress.toLowerCase()) {
1758
1862
  throw new Error(
1759
1863
  `Wallet address mismatch! Wallet: ${walletAddress}, Expected: ${account.signerAddress}`
1760
1864
  );
1761
1865
  }
1762
- const aaSignature = await wallet.signMessage(ethers.getBytes(userOpHash));
1763
- const messagePointHash = ethers.keccak256(messagePoint);
1764
- const messagePointSignature = await wallet.signMessage(ethers.getBytes(messagePointHash));
1866
+ const aaSignature = await this.signer.signMessage(
1867
+ userId,
1868
+ hexToBytes(userOpHash),
1869
+ ctx
1870
+ );
1871
+ const messagePointHash = keccak256(messagePoint);
1872
+ const messagePointSignature = await this.signer.signMessage(
1873
+ userId,
1874
+ hexToBytes(messagePointHash),
1875
+ ctx
1876
+ );
1765
1877
  return {
1766
1878
  nodeIds: signerNodeIds,
1767
1879
  signature: aggregatedSignature,
@@ -1787,7 +1899,7 @@ var BLSSignatureService = class {
1787
1899
  * @param userId - User ID for account lookup
1788
1900
  * @param userOpHash - The UserOp hash to sign
1789
1901
  * @param p256Signature - P256 passkey signature (64 bytes, required for tier 2/3)
1790
- * @param guardianSigner - Guardian ethers.Signer (required for tier 3)
1902
+ * @param guardianSigner - Guardian signer (required for tier 3)
1791
1903
  * @param ctx - Optional passkey assertion context for KMS signing
1792
1904
  */
1793
1905
  async generateTieredSignature(params) {
@@ -1796,8 +1908,7 @@ var BLSSignatureService = class {
1796
1908
  if (tier === 1) {
1797
1909
  const account = await this.storage.findAccountByUserId(userId);
1798
1910
  if (!account) throw new Error(`User account not found for userId: ${userId}`);
1799
- const wallet = await this.signer.getSigner(userId, ctx);
1800
- return wallet.signMessage(ethers.getBytes(userOpHash));
1911
+ return this.signer.signMessage(userId, hexToBytes(userOpHash), ctx);
1801
1912
  }
1802
1913
  if (!p256Signature) {
1803
1914
  throw new Error(`P256 signature required for Tier ${tier}`);
@@ -1816,7 +1927,9 @@ var BLSSignatureService = class {
1816
1927
  if (!guardianSigner) {
1817
1928
  throw new Error("Guardian signer required for Tier 3");
1818
1929
  }
1819
- const guardianSignature = await guardianSigner.signMessage(ethers.getBytes(userOpHash));
1930
+ const guardianSignature = await guardianSigner.signMessage(
1931
+ hexToBytes(userOpHash)
1932
+ );
1820
1933
  const t3Data = {
1821
1934
  p256Signature,
1822
1935
  nodeIds: blsData.nodeIds,
@@ -1828,17 +1941,18 @@ var BLSSignatureService = class {
1828
1941
  return manager.packCumulativeT3Signature(t3Data);
1829
1942
  }
1830
1943
  };
1944
+ var ERC20_ABI_PARSED = parseAbi(ERC20_ABI);
1831
1945
  var TokenService = class {
1832
1946
  constructor(ethereum) {
1833
1947
  this.ethereum = ethereum;
1834
1948
  }
1835
1949
  async getTokenInfo(tokenAddress) {
1836
- const provider = this.ethereum.getProvider();
1837
- const contract = new ethers.Contract(tokenAddress, ERC20_ABI, provider);
1950
+ const client = this.ethereum.getProvider();
1951
+ const address = tokenAddress;
1838
1952
  const [name, symbol, decimals] = await Promise.all([
1839
- contract.name(),
1840
- contract.symbol(),
1841
- contract.decimals()
1953
+ client.readContract({ address, abi: ERC20_ABI_PARSED, functionName: "name" }),
1954
+ client.readContract({ address, abi: ERC20_ABI_PARSED, functionName: "symbol" }),
1955
+ client.readContract({ address, abi: ERC20_ABI_PARSED, functionName: "decimals" })
1842
1956
  ]);
1843
1957
  return {
1844
1958
  address: tokenAddress.toLowerCase(),
@@ -1848,10 +1962,14 @@ var TokenService = class {
1848
1962
  };
1849
1963
  }
1850
1964
  async getTokenBalance(tokenAddress, walletAddress) {
1851
- const provider = this.ethereum.getProvider();
1852
- const contract = new ethers.Contract(tokenAddress, ERC20_ABI, provider);
1965
+ const client = this.ethereum.getProvider();
1853
1966
  try {
1854
- const balance = await contract.balanceOf(walletAddress);
1967
+ const balance = await client.readContract({
1968
+ address: tokenAddress,
1969
+ abi: ERC20_ABI_PARSED,
1970
+ functionName: "balanceOf",
1971
+ args: [walletAddress]
1972
+ });
1855
1973
  return balance.toString();
1856
1974
  } catch {
1857
1975
  return "0";
@@ -1860,20 +1978,27 @@ var TokenService = class {
1860
1978
  async getFormattedTokenBalance(tokenAddress, walletAddress) {
1861
1979
  const tokenInfo = await this.getTokenInfo(tokenAddress);
1862
1980
  const rawBalance = await this.getTokenBalance(tokenAddress, walletAddress);
1863
- const formattedBalance = ethers.formatUnits(rawBalance, tokenInfo.decimals);
1981
+ const formattedBalance = formatUnits(BigInt(rawBalance), tokenInfo.decimals);
1864
1982
  return { token: tokenInfo, balance: rawBalance, formattedBalance };
1865
1983
  }
1866
1984
  generateTransferCalldata(to, amount, decimals) {
1867
- const contract = new ethers.Contract(ethers.ZeroAddress, ERC20_ABI);
1868
- const parsedAmount = ethers.parseUnits(amount, decimals);
1869
- return contract.interface.encodeFunctionData("transfer", [to, parsedAmount]);
1985
+ const parsedAmount = parseUnits(amount, decimals);
1986
+ return encodeFunctionData({
1987
+ abi: ERC20_ABI_PARSED,
1988
+ functionName: "transfer",
1989
+ args: [to, parsedAmount]
1990
+ });
1870
1991
  }
1871
1992
  async validateToken(tokenAddress) {
1872
1993
  try {
1873
- const provider = this.ethereum.getProvider();
1874
- const contract = new ethers.Contract(tokenAddress, ERC20_ABI, provider);
1994
+ const client = this.ethereum.getProvider();
1995
+ const address = tokenAddress;
1875
1996
  const [name, symbol, decimals] = await Promise.race([
1876
- Promise.all([contract.name(), contract.symbol(), contract.decimals()]),
1997
+ Promise.all([
1998
+ client.readContract({ address, abi: ERC20_ABI_PARSED, functionName: "name" }),
1999
+ client.readContract({ address, abi: ERC20_ABI_PARSED, functionName: "symbol" }),
2000
+ client.readContract({ address, abi: ERC20_ABI_PARSED, functionName: "decimals" })
2001
+ ]),
1877
2002
  new Promise((_, reject) => setTimeout(() => reject(new Error("Timeout")), 1e4))
1878
2003
  ]);
1879
2004
  return {
@@ -1902,8 +2027,8 @@ var WalletManager = class {
1902
2027
  async getAddress(userId) {
1903
2028
  return this.signer.getAddress(userId);
1904
2029
  }
1905
- async getSigner(userId) {
1906
- return this.signer.getSigner(userId);
2030
+ async signMessage(userId, message, ctx) {
2031
+ return this.signer.signMessage(userId, message, ctx);
1907
2032
  }
1908
2033
  async ensureSigner(userId) {
1909
2034
  return this.signer.ensureSigner(userId);
@@ -1911,7 +2036,7 @@ var WalletManager = class {
1911
2036
  };
1912
2037
 
1913
2038
  // ../airaccount/src/server/server-client.ts
1914
- var YAAAServerClient = class {
2039
+ var AirAccountServerClient = class {
1915
2040
  ethereum;
1916
2041
  accounts;
1917
2042
  transfers;
@@ -1946,24 +2071,47 @@ var YAAAServerClient = class {
1946
2071
  );
1947
2072
  }
1948
2073
  };
2074
+ var YAAAServerClient = AirAccountServerClient;
2075
+ function hashMessage(message) {
2076
+ if (typeof message === "string") return hashMessage$1(message);
2077
+ return hashMessage$1({ raw: message });
2078
+ }
2079
+ async function recoverAddress(hash, signature) {
2080
+ return recoverAddress$1({ hash, signature });
2081
+ }
2082
+ function buildAuthorizationHash(chainId, nonce, delegateAddress) {
2083
+ const encoded = toRlp([
2084
+ chainId === 0 ? "0x" : numberToHex(chainId),
2085
+ delegateAddress,
2086
+ nonce === 0n ? "0x" : numberToHex(nonce)
2087
+ ]);
2088
+ return keccak256$1(concatHex(["0x05", encoded]));
2089
+ }
2090
+ async function verifyAuthorization(eoa, chainId, nonce, signature, delegateAddress) {
2091
+ const hash = buildAuthorizationHash(chainId, nonce, delegateAddress);
2092
+ const recovered = await recoverAddress(hash, signature);
2093
+ return recovered.toLowerCase() === eoa.toLowerCase();
2094
+ }
2095
+
2096
+ // ../airaccount/src/server/services/module-manager.ts
1949
2097
  function buildInstallModuleHash(chainId, account, moduleTypeId, module, moduleInitData = "0x") {
1950
- const moduleInitDataHash = ethers.keccak256(moduleInitData);
1951
- const raw = ethers.keccak256(
1952
- ethers.solidityPacked(
2098
+ const moduleInitDataHash = keccak256(moduleInitData);
2099
+ const raw = keccak256(
2100
+ solidityPacked(
1953
2101
  ["string", "uint256", "address", "uint256", "address", "bytes32"],
1954
- ["INSTALL_MODULE", chainId, account, moduleTypeId, module, moduleInitDataHash]
2102
+ ["INSTALL_MODULE", BigInt(chainId), account, BigInt(moduleTypeId), module, moduleInitDataHash]
1955
2103
  )
1956
2104
  );
1957
- return ethers.hashMessage(ethers.getBytes(raw));
2105
+ return hashMessage(hexToBytes(raw));
1958
2106
  }
1959
2107
  function buildUninstallModuleHash(chainId, account, moduleTypeId, module) {
1960
- const raw = ethers.keccak256(
1961
- ethers.solidityPacked(
2108
+ const raw = keccak256(
2109
+ solidityPacked(
1962
2110
  ["string", "uint256", "address", "uint256", "address"],
1963
- ["UNINSTALL_MODULE", chainId, account, moduleTypeId, module]
2111
+ ["UNINSTALL_MODULE", BigInt(chainId), account, BigInt(moduleTypeId), module]
1964
2112
  )
1965
2113
  );
1966
- return ethers.hashMessage(ethers.getBytes(raw));
2114
+ return hashMessage(hexToBytes(raw));
1967
2115
  }
1968
2116
  var ModuleManager = class {
1969
2117
  provider;
@@ -1979,13 +2127,12 @@ var ModuleManager = class {
1979
2127
  encodeInstall(params) {
1980
2128
  const sigs = params.guardianSigs ?? [];
1981
2129
  const initData = params.moduleInitData ?? "0x";
1982
- const packed = sigs.length > 0 ? ethers.concat([...sigs.map((s) => ethers.getBytes(s)), ethers.getBytes(initData)]) : ethers.getBytes(initData);
1983
- const iface = new ethers.Interface(AIRACCOUNT_ABI);
1984
- return iface.encodeFunctionData("installModule", [
1985
- params.moduleTypeId,
1986
- params.module,
1987
- packed
1988
- ]);
2130
+ const packed = sigs.length > 0 ? concat([...sigs, initData]) : initData;
2131
+ return encodeFunctionData({
2132
+ abi: parseAbi(AIRACCOUNT_ABI),
2133
+ functionName: "installModule",
2134
+ args: [BigInt(params.moduleTypeId), params.module, packed]
2135
+ });
1989
2136
  }
1990
2137
  /**
1991
2138
  * Encode calldata for uninstallModule().
@@ -1993,22 +2140,25 @@ var ModuleManager = class {
1993
2140
  */
1994
2141
  encodeUninstall(params) {
1995
2142
  const deInitData = params.moduleDeInitData ?? "0x";
1996
- const packed = ethers.concat([
1997
- ethers.getBytes(params.guardianSig1),
1998
- ethers.getBytes(params.guardianSig2),
1999
- ethers.getBytes(deInitData)
2000
- ]);
2001
- const iface = new ethers.Interface(AIRACCOUNT_ABI);
2002
- return iface.encodeFunctionData("uninstallModule", [
2003
- params.moduleTypeId,
2004
- params.module,
2005
- packed
2143
+ const packed = concat([
2144
+ params.guardianSig1,
2145
+ params.guardianSig2,
2146
+ deInitData
2006
2147
  ]);
2148
+ return encodeFunctionData({
2149
+ abi: parseAbi(AIRACCOUNT_ABI),
2150
+ functionName: "uninstallModule",
2151
+ args: [BigInt(params.moduleTypeId), params.module, packed]
2152
+ });
2007
2153
  }
2008
2154
  /** Check if a module is currently installed on the account. */
2009
2155
  async isInstalled(account, moduleTypeId, module) {
2010
- const contract = new ethers.Contract(account, AIRACCOUNT_ABI, this.provider);
2011
- return contract.isModuleInstalled(moduleTypeId, module, "0x");
2156
+ return await this.provider.readContract({
2157
+ address: account,
2158
+ abi: parseAbi(AIRACCOUNT_ABI),
2159
+ functionName: "isModuleInstalled",
2160
+ args: [BigInt(moduleTypeId), module, "0x"]
2161
+ });
2012
2162
  }
2013
2163
  /** Return the install hash for a guardian to sign (r5 format, includes moduleInitData hash). */
2014
2164
  installHash(account, moduleTypeId, module, moduleInitData = "0x") {
@@ -2042,10 +2192,12 @@ var ModuleManager = class {
2042
2192
  };
2043
2193
  }
2044
2194
  };
2195
+ var SESSION_KEY_VALIDATOR_VIEM_ABI = parseAbi(SESSION_KEY_VALIDATOR_ABI);
2196
+ var AGENT_SESSION_KEY_VALIDATOR_VIEM_ABI = parseAbi(AGENT_SESSION_KEY_VALIDATOR_ABI);
2045
2197
  function buildSessionStruct(params) {
2046
2198
  return {
2047
2199
  expiry: params.expiry,
2048
- contractScope: params.contractScope ?? ethers.ZeroAddress,
2200
+ contractScope: params.contractScope ?? zeroAddress,
2049
2201
  selectorScope: params.selectorScope ?? "0x00000000",
2050
2202
  revoked: false,
2051
2203
  velocityLimit: params.velocityLimit ?? 0,
@@ -2056,36 +2208,34 @@ function buildSessionStruct(params) {
2056
2208
  }
2057
2209
  function decodeSessionInfo(session) {
2058
2210
  const s = session;
2059
- const expiry = Number(s[0]);
2211
+ const expiry = Number(s.expiry);
2060
2212
  const now = Math.floor(Date.now() / 1e3);
2061
2213
  return {
2062
2214
  expiry,
2063
- contractScope: s[1],
2064
- selectorScope: s[2],
2065
- revoked: s[3],
2066
- velocityLimit: Number(s[4]),
2067
- velocityWindow: Number(s[5]),
2068
- callTargets: [...s[6] ?? []],
2069
- selectorAllowlist: [...s[7] ?? []],
2070
- active: expiry > now && !s[3]
2215
+ contractScope: s.contractScope,
2216
+ selectorScope: s.selectorScope,
2217
+ revoked: s.revoked,
2218
+ velocityLimit: Number(s.velocityLimit),
2219
+ velocityWindow: Number(s.velocityWindow),
2220
+ callTargets: [...s.callTargets ?? []],
2221
+ selectorAllowlist: [...s.selectorAllowlist ?? []],
2222
+ active: expiry > now && !s.revoked
2071
2223
  };
2072
2224
  }
2073
2225
  var SessionKeyService = class {
2074
- provider;
2075
2226
  skValidator;
2076
2227
  askValidator;
2077
2228
  constructor(provider, sessionKeyValidatorAddress, agentSessionKeyValidatorAddress) {
2078
- this.provider = provider;
2079
- this.skValidator = new ethers.Contract(
2080
- sessionKeyValidatorAddress,
2081
- SESSION_KEY_VALIDATOR_ABI,
2082
- provider
2083
- );
2084
- this.askValidator = new ethers.Contract(
2085
- agentSessionKeyValidatorAddress,
2086
- AGENT_SESSION_KEY_VALIDATOR_ABI,
2087
- provider
2088
- );
2229
+ this.skValidator = getContract({
2230
+ address: sessionKeyValidatorAddress,
2231
+ abi: SESSION_KEY_VALIDATOR_VIEM_ABI,
2232
+ client: provider
2233
+ });
2234
+ this.askValidator = getContract({
2235
+ address: agentSessionKeyValidatorAddress,
2236
+ abi: AGENT_SESSION_KEY_VALIDATOR_VIEM_ABI,
2237
+ client: provider
2238
+ });
2089
2239
  }
2090
2240
  // ── M6: Basic Session Keys ────────────────────────────────────
2091
2241
  /**
@@ -2093,7 +2243,8 @@ var SessionKeyService = class {
2093
2243
  * Use grantSession() with this sig, or grantSessionDirect() from the account itself.
2094
2244
  */
2095
2245
  async buildGrantHash(params) {
2096
- return this.skValidator.buildGrantHash(
2246
+ return readBuildGrantHash(
2247
+ this.skValidator,
2097
2248
  params.account,
2098
2249
  params.sessionKey,
2099
2250
  buildSessionStruct(params)
@@ -2101,12 +2252,12 @@ var SessionKeyService = class {
2101
2252
  }
2102
2253
  /** Query an ECDSA session key state (decodes the 8-field Session tuple). */
2103
2254
  async getSession(account, sessionKey) {
2104
- const session = await this.skValidator.getSession(account, sessionKey);
2255
+ const session = await this.skValidator.read.getSession([account, sessionKey]);
2105
2256
  return decodeSessionInfo(session);
2106
2257
  }
2107
2258
  /** Check if an ECDSA session is currently active. */
2108
2259
  async isSessionActive(account, sessionKey) {
2109
- return this.skValidator.isSessionActive(account, sessionKey);
2260
+ return this.skValidator.read.isSessionActive([account, sessionKey]);
2110
2261
  }
2111
2262
  /**
2112
2263
  * Encode calldata for session grant.
@@ -2122,26 +2273,27 @@ var SessionKeyService = class {
2122
2273
  * Do NOT encode this for a UserOp callData; the EntryPoint is not the owner EOA.
2123
2274
  */
2124
2275
  encodeGrantSession(params) {
2125
- const iface = new ethers.Interface(SESSION_KEY_VALIDATOR_ABI);
2126
2276
  const cfg = buildSessionStruct(params);
2127
2277
  if (params.ownerSig) {
2128
- return iface.encodeFunctionData("grantSession", [
2129
- params.account,
2130
- params.sessionKey,
2131
- cfg,
2132
- params.ownerSig
2133
- ]);
2278
+ return encodeFunctionData({
2279
+ abi: SESSION_KEY_VALIDATOR_VIEM_ABI,
2280
+ functionName: "grantSession",
2281
+ args: [params.account, params.sessionKey, cfg, params.ownerSig]
2282
+ });
2134
2283
  }
2135
- return iface.encodeFunctionData("grantSessionDirect", [
2136
- params.account,
2137
- params.sessionKey,
2138
- cfg
2139
- ]);
2284
+ return encodeFunctionData({
2285
+ abi: SESSION_KEY_VALIDATOR_VIEM_ABI,
2286
+ functionName: "grantSessionDirect",
2287
+ args: [params.account, params.sessionKey, cfg]
2288
+ });
2140
2289
  }
2141
2290
  /** Encode calldata for revokeSession(). */
2142
2291
  encodeRevokeSession(account, sessionKey) {
2143
- const iface = new ethers.Interface(SESSION_KEY_VALIDATOR_ABI);
2144
- return iface.encodeFunctionData("revokeSession", [account, sessionKey]);
2292
+ return encodeFunctionData({
2293
+ abi: SESSION_KEY_VALIDATOR_VIEM_ABI,
2294
+ functionName: "revokeSession",
2295
+ args: [account, sessionKey]
2296
+ });
2145
2297
  }
2146
2298
  // ── M6: P256 / Passkey Session Keys ───────────────────────────
2147
2299
  /**
@@ -2150,7 +2302,8 @@ var SessionKeyService = class {
2150
2302
  * The owner/KMS signs this hash to authorize a gasless grantP256Session().
2151
2303
  */
2152
2304
  async buildP256GrantHash(params) {
2153
- return this.skValidator.buildP256GrantHash(
2305
+ return readBuildP256GrantHash(
2306
+ this.skValidator,
2154
2307
  params.account,
2155
2308
  params.keyX,
2156
2309
  params.keyY,
@@ -2162,12 +2315,12 @@ var SessionKeyService = class {
2162
2315
  * @param keyHash The keccak256 hash of (keyX, keyY) used as the on-chain session id.
2163
2316
  */
2164
2317
  async getP256Session(account, keyHash) {
2165
- const session = await this.skValidator.getP256Session(account, keyHash);
2318
+ const session = await this.skValidator.read.getP256Session([account, keyHash]);
2166
2319
  return decodeSessionInfo(session);
2167
2320
  }
2168
2321
  /** Check if a P256 session is currently active. */
2169
2322
  async isP256SessionActive(account, keyX, keyY) {
2170
- return this.skValidator.isP256SessionActive(account, keyX, keyY);
2323
+ return this.skValidator.read.isP256SessionActive([account, keyX, keyY]);
2171
2324
  }
2172
2325
  /**
2173
2326
  * Encode calldata for a P256/passkey session grant.
@@ -2183,28 +2336,27 @@ var SessionKeyService = class {
2183
2336
  * Do NOT encode this for a UserOp callData; the EntryPoint is not the owner EOA.
2184
2337
  */
2185
2338
  encodeGrantP256Session(params) {
2186
- const iface = new ethers.Interface(SESSION_KEY_VALIDATOR_ABI);
2187
2339
  const cfg = buildSessionStruct(params);
2188
2340
  if (params.ownerSig) {
2189
- return iface.encodeFunctionData("grantP256Session", [
2190
- params.account,
2191
- params.keyX,
2192
- params.keyY,
2193
- cfg,
2194
- params.ownerSig
2195
- ]);
2341
+ return encodeFunctionData({
2342
+ abi: SESSION_KEY_VALIDATOR_VIEM_ABI,
2343
+ functionName: "grantP256Session",
2344
+ args: [params.account, params.keyX, params.keyY, cfg, params.ownerSig]
2345
+ });
2196
2346
  }
2197
- return iface.encodeFunctionData("grantP256SessionDirect", [
2198
- params.account,
2199
- params.keyX,
2200
- params.keyY,
2201
- cfg
2202
- ]);
2347
+ return encodeFunctionData({
2348
+ abi: SESSION_KEY_VALIDATOR_VIEM_ABI,
2349
+ functionName: "grantP256SessionDirect",
2350
+ args: [params.account, params.keyX, params.keyY, cfg]
2351
+ });
2203
2352
  }
2204
2353
  /** Encode calldata for revokeP256Session(). */
2205
2354
  encodeRevokeP256Session(account, keyX, keyY) {
2206
- const iface = new ethers.Interface(SESSION_KEY_VALIDATOR_ABI);
2207
- return iface.encodeFunctionData("revokeP256Session", [account, keyX, keyY]);
2355
+ return encodeFunctionData({
2356
+ abi: SESSION_KEY_VALIDATOR_VIEM_ABI,
2357
+ functionName: "revokeP256Session",
2358
+ args: [account, keyX, keyY]
2359
+ });
2208
2360
  }
2209
2361
  // ── M7: Agent Session Keys ────────────────────────────────────
2210
2362
  /**
@@ -2213,18 +2365,21 @@ var SessionKeyService = class {
2213
2365
  * The contract uses msg.sender as the account — no account param needed.
2214
2366
  */
2215
2367
  encodeGrantAgentSession(sessionKey, cfg) {
2216
- const iface = new ethers.Interface(AGENT_SESSION_KEY_VALIDATOR_ABI);
2217
- return iface.encodeFunctionData("grantAgentSession", [
2218
- sessionKey,
2219
- {
2220
- expiry: cfg.expiry,
2221
- velocityLimit: cfg.velocityLimit,
2222
- velocityWindow: cfg.velocityWindow,
2223
- revoked: false,
2224
- callTargets: cfg.callTargets,
2225
- selectorAllowlist: cfg.selectorAllowlist
2226
- }
2227
- ]);
2368
+ return encodeFunctionData({
2369
+ abi: AGENT_SESSION_KEY_VALIDATOR_VIEM_ABI,
2370
+ functionName: "grantAgentSession",
2371
+ args: [
2372
+ sessionKey,
2373
+ {
2374
+ expiry: cfg.expiry,
2375
+ velocityLimit: cfg.velocityLimit,
2376
+ velocityWindow: cfg.velocityWindow,
2377
+ revoked: false,
2378
+ callTargets: cfg.callTargets,
2379
+ selectorAllowlist: cfg.selectorAllowlist
2380
+ }
2381
+ ]
2382
+ });
2228
2383
  }
2229
2384
  /**
2230
2385
  * Encode calldata for delegateSession() — sub-agent delegation.
@@ -2233,29 +2388,35 @@ var SessionKeyService = class {
2233
2388
  * @param account The smart account under which the parent session was granted.
2234
2389
  */
2235
2390
  encodeDelegateSession(account, subKey, subCfg) {
2236
- const iface = new ethers.Interface(AGENT_SESSION_KEY_VALIDATOR_ABI);
2237
- return iface.encodeFunctionData("delegateSession", [
2238
- account,
2239
- subKey,
2240
- {
2241
- expiry: subCfg.expiry,
2242
- velocityLimit: subCfg.velocityLimit,
2243
- velocityWindow: subCfg.velocityWindow,
2244
- revoked: false,
2245
- callTargets: subCfg.callTargets,
2246
- selectorAllowlist: subCfg.selectorAllowlist
2247
- }
2248
- ]);
2391
+ return encodeFunctionData({
2392
+ abi: AGENT_SESSION_KEY_VALIDATOR_VIEM_ABI,
2393
+ functionName: "delegateSession",
2394
+ args: [
2395
+ account,
2396
+ subKey,
2397
+ {
2398
+ expiry: subCfg.expiry,
2399
+ velocityLimit: subCfg.velocityLimit,
2400
+ velocityWindow: subCfg.velocityWindow,
2401
+ revoked: false,
2402
+ callTargets: subCfg.callTargets,
2403
+ selectorAllowlist: subCfg.selectorAllowlist
2404
+ }
2405
+ ]
2406
+ });
2249
2407
  }
2250
2408
  /** Encode calldata for revokeAgentSession(). */
2251
2409
  encodeRevokeAgentSession(sessionKey) {
2252
- const iface = new ethers.Interface(AGENT_SESSION_KEY_VALIDATOR_ABI);
2253
- return iface.encodeFunctionData("revokeAgentSession", [sessionKey]);
2410
+ return encodeFunctionData({
2411
+ abi: AGENT_SESSION_KEY_VALIDATOR_VIEM_ABI,
2412
+ functionName: "revokeAgentSession",
2413
+ args: [sessionKey]
2414
+ });
2254
2415
  }
2255
2416
  /** Query agent session config + runtime state. */
2256
2417
  async getAgentSession(account, sessionKey) {
2257
- const [expiry, velocityLimit, velocityWindow, revoked, callTargets, selectorAllowlist] = await this.askValidator.agentSessions(account, sessionKey);
2258
- const [callCount, windowStart] = await this.askValidator.sessionStates(account, sessionKey);
2418
+ const [expiry, velocityLimit, velocityWindow, revoked, callTargets, selectorAllowlist] = await this.askValidator.read.agentSessions([account, sessionKey]);
2419
+ const [callCount, windowStart] = await this.askValidator.read.sessionStates([account, sessionKey]);
2259
2420
  return {
2260
2421
  expiry: Number(expiry),
2261
2422
  velocityLimit: Number(velocityLimit),
@@ -2274,11 +2435,11 @@ var SessionKeyService = class {
2274
2435
  }
2275
2436
  /** Return the parent account of a delegated session key. */
2276
2437
  async getSessionKeyOwner(sessionKey) {
2277
- return this.askValidator.sessionKeyOwner(sessionKey);
2438
+ return this.askValidator.read.sessionKeyOwner([sessionKey]);
2278
2439
  }
2279
2440
  /** Return the parent key that delegated to subKey, or ZeroAddress if not delegated. */
2280
2441
  async getDelegatedBy(account, subKey) {
2281
- return this.askValidator.delegatedBy(account, subKey);
2442
+ return this.askValidator.read.delegatedBy([account, subKey]);
2282
2443
  }
2283
2444
  };
2284
2445
  function packSecp256k1SessionSignature(account, sessionKey, signature) {
@@ -2315,28 +2476,46 @@ var GuardStateReader = class {
2315
2476
  constructor(provider) {
2316
2477
  this.provider = provider;
2317
2478
  }
2479
+ accountContract(accountAddress) {
2480
+ return getContract({
2481
+ address: accountAddress,
2482
+ abi: parseAbi(AIRACCOUNT_ABI),
2483
+ client: this.provider
2484
+ });
2485
+ }
2486
+ guardContract(guardAddress) {
2487
+ return getContract({
2488
+ address: guardAddress,
2489
+ abi: parseAbi(EXTENDED_GUARD_ABI),
2490
+ client: this.provider
2491
+ });
2492
+ }
2318
2493
  /**
2319
2494
  * Read the full ETH guard state for an account.
2320
2495
  * Returns null if the account has no guard (dailyLimit=0).
2321
2496
  */
2322
2497
  async getGuardState(accountAddress) {
2323
- const account = new ethers.Contract(accountAddress, AIRACCOUNT_ABI, this.provider);
2324
- const guardAddress = await account.guard();
2325
- if (guardAddress === ethers.ZeroAddress) return null;
2326
- const guard = new ethers.Contract(guardAddress, EXTENDED_GUARD_ABI, this.provider);
2498
+ const account = this.accountContract(accountAddress).read;
2499
+ const guardAddress = await account.guard([]);
2500
+ if (guardAddress === zeroAddress) return null;
2501
+ const guard = this.guardContract(guardAddress).read;
2327
2502
  const [dailyLimit, remaining, todaySpent, tier1Limit, tier2Limit, minDailyLimit] = await Promise.all([
2328
- guard.dailyLimit(),
2329
- guard.remainingDailyAllowance(),
2330
- guard.todaySpent(),
2331
- guard.tier1Limit().catch(() => 0n),
2332
- guard.tier2Limit().catch(() => 0n),
2333
- guard.minDailyLimit().catch(() => 0n)
2503
+ guard.dailyLimit([]),
2504
+ guard.remainingDailyAllowance([]),
2505
+ guard.todaySpent([]),
2506
+ guard.tier1Limit([]).catch(() => 0n),
2507
+ guard.tier2Limit([]).catch(() => 0n),
2508
+ guard.minDailyLimit([]).catch(() => 0n)
2334
2509
  ]);
2335
2510
  return {
2336
2511
  dailyLimit: BigInt(dailyLimit),
2337
2512
  todaySpent: BigInt(todaySpent),
2338
2513
  remaining: BigInt(remaining),
2339
- currentTier: resolveTierFromSpend(BigInt(todaySpent), BigInt(tier1Limit), BigInt(tier2Limit)),
2514
+ currentTier: resolveTierFromSpend(
2515
+ BigInt(todaySpent),
2516
+ BigInt(tier1Limit),
2517
+ BigInt(tier2Limit)
2518
+ ),
2340
2519
  tier1Limit: BigInt(tier1Limit),
2341
2520
  tier2Limit: BigInt(tier2Limit),
2342
2521
  minDailyLimit: BigInt(minDailyLimit),
@@ -2348,12 +2527,12 @@ var GuardStateReader = class {
2348
2527
  * Returns null if the token is not configured on the guard.
2349
2528
  */
2350
2529
  async getTokenGuardState(accountAddress, token) {
2351
- const account = new ethers.Contract(accountAddress, AIRACCOUNT_ABI, this.provider);
2352
- const guardAddress = await account.guard();
2353
- if (guardAddress === ethers.ZeroAddress) return null;
2354
- const guard = new ethers.Contract(guardAddress, EXTENDED_GUARD_ABI, this.provider);
2530
+ const account = this.accountContract(accountAddress).read;
2531
+ const guardAddress = await account.guard([]);
2532
+ if (guardAddress === zeroAddress) return null;
2533
+ const guard = this.guardContract(guardAddress).read;
2355
2534
  try {
2356
- const todaySpent = await guard.tokenTodaySpent(token);
2535
+ const todaySpent = await guard.tokenTodaySpent([token]);
2357
2536
  return {
2358
2537
  token,
2359
2538
  todaySpent: BigInt(todaySpent),
@@ -2382,8 +2561,8 @@ var GuardStateReader = class {
2382
2561
  * Check if a given algorithm ID is approved on the guard.
2383
2562
  */
2384
2563
  async isAlgorithmApproved(accountAddress, algId) {
2385
- const account = new ethers.Contract(accountAddress, AIRACCOUNT_ABI, this.provider);
2386
- return account.approvedAlgorithms(algId);
2564
+ const account = this.accountContract(accountAddress).read;
2565
+ return await account.approvedAlgorithms([BigInt(algId)]);
2387
2566
  }
2388
2567
  };
2389
2568
  function resolveTierFromSpend(spent, tier1Limit, tier2Limit) {
@@ -2392,31 +2571,36 @@ function resolveTierFromSpend(spent, tier1Limit, tier2Limit) {
2392
2571
  if (tier2Limit === 0n || spent < tier2Limit) return 2;
2393
2572
  return 3;
2394
2573
  }
2574
+ var FACTORY_ABI = parseAbi(AIRACCOUNT_FACTORY_ABI);
2395
2575
  function computeOapdSalt(owner, dappId) {
2396
- const packed = ethers.solidityPacked(["address", "string"], [owner, dappId]);
2397
- return BigInt(ethers.keccak256(packed));
2576
+ const packed = solidityPacked(["address", "string"], [owner, dappId]);
2577
+ return BigInt(keccak256(packed));
2398
2578
  }
2399
2579
  async function getOapdAddress(provider, config) {
2400
2580
  const factoryAddress = config.factoryAddress ?? AIRACCOUNT_ADDRESSES.sepolia.factory;
2401
- const factory = new ethers.Contract(factoryAddress, AIRACCOUNT_FACTORY_ABI, provider);
2402
2581
  const salt = computeOapdSalt(config.owner, config.dappId);
2403
- return factory.getFunction("getAddress")(config.owner, salt, config.initConfig);
2582
+ return provider.readContract({
2583
+ address: factoryAddress,
2584
+ abi: FACTORY_ABI,
2585
+ functionName: "getAddress",
2586
+ args: [config.owner, salt, config.initConfig]
2587
+ });
2404
2588
  }
2405
2589
  async function getOapdAddressWithChainId(provider, config) {
2406
2590
  const factoryAddress = config.factoryAddress ?? AIRACCOUNT_ADDRESSES.sepolia.factory;
2407
- const factory = new ethers.Contract(factoryAddress, AIRACCOUNT_FACTORY_ABI, provider);
2408
2591
  const salt = computeOapdSalt(config.owner, config.dappId);
2409
- const result = await factory.getFunction("getAddressWithChainId")(
2410
- config.owner,
2411
- salt,
2412
- config.initConfig
2413
- );
2592
+ const result = await provider.readContract({
2593
+ address: factoryAddress,
2594
+ abi: FACTORY_ABI,
2595
+ functionName: "getAddressWithChainId",
2596
+ args: [config.owner, salt, config.initConfig]
2597
+ });
2414
2598
  return { address: result[0], chainQualified: result[1] };
2415
2599
  }
2416
2600
  async function isOapdDeployed(provider, config) {
2417
2601
  const address = await getOapdAddress(provider, config);
2418
- const code = await provider.getCode(address);
2419
- return code !== "0x";
2602
+ const code = await provider.getCode({ address });
2603
+ return code !== void 0 && code !== "0x";
2420
2604
  }
2421
2605
  var ALG_NAMES = {
2422
2606
  [ALG_BLS]: "BLS (0x01)",
@@ -2435,43 +2619,34 @@ var GuardChecker = class {
2435
2619
  * Fetch tier limits from an AirAccount contract.
2436
2620
  */
2437
2621
  async fetchTierConfig(accountAddress) {
2438
- const provider = this.ethereum.getProvider();
2439
- const account = new ethers.Contract(accountAddress, AIRACCOUNT_ABI, provider);
2440
- const [tier1Limit, tier2Limit] = await Promise.all([
2441
- account.tier1Limit(),
2442
- account.tier2Limit()
2443
- ]);
2444
- return {
2445
- tier1Limit: BigInt(tier1Limit),
2446
- tier2Limit: BigInt(tier2Limit)
2447
- };
2622
+ const account = this.ethereum.getAccountContract(accountAddress);
2623
+ return readAccountTierLimits(account);
2448
2624
  }
2449
2625
  /**
2450
2626
  * Fetch guard status from the account's GlobalGuard.
2451
2627
  */
2452
2628
  async fetchGuardStatus(accountAddress) {
2453
- const provider = this.ethereum.getProvider();
2454
- const account = new ethers.Contract(accountAddress, AIRACCOUNT_ABI, provider);
2455
- const config = await account.getConfigDescription();
2456
- const guardAddress = config.guardAddress;
2457
- if (guardAddress === ethers.ZeroAddress) {
2629
+ const account = this.ethereum.getAccountContract(accountAddress);
2630
+ const guardAddress = await readAccountGuardAddress(account);
2631
+ if (guardAddress === zeroAddress) {
2458
2632
  return {
2459
2633
  hasGuard: false,
2460
- guardAddress: ethers.ZeroAddress,
2634
+ guardAddress: zeroAddress,
2461
2635
  dailyLimit: 0n,
2462
2636
  dailyRemaining: 0n
2463
2637
  };
2464
2638
  }
2465
- const guard = new ethers.Contract(guardAddress, GLOBAL_GUARD_ABI, provider);
2466
- const [dailyLimit, dailyRemaining] = await Promise.all([
2467
- guard.dailyLimit(),
2468
- guard.remainingDailyAllowance()
2469
- ]);
2639
+ const guard = getContract({
2640
+ address: guardAddress,
2641
+ abi: parseAbi(GLOBAL_GUARD_ABI),
2642
+ client: this.ethereum.getProvider()
2643
+ });
2644
+ const { dailyLimit, dailyRemaining } = await readGuardDailyAllowance(guard);
2470
2645
  return {
2471
2646
  hasGuard: true,
2472
2647
  guardAddress,
2473
- dailyLimit: BigInt(dailyLimit),
2474
- dailyRemaining: BigInt(dailyRemaining)
2648
+ dailyLimit,
2649
+ dailyRemaining
2475
2650
  };
2476
2651
  }
2477
2652
  /**
@@ -2492,9 +2667,8 @@ var GuardChecker = class {
2492
2667
  `Daily limit exceeded: requesting ${value} wei but only ${guard.dailyRemaining} remaining (limit: ${guard.dailyLimit})`
2493
2668
  );
2494
2669
  }
2495
- const provider = this.ethereum.getProvider();
2496
- const accountContract = new ethers.Contract(accountAddress, AIRACCOUNT_ABI, provider);
2497
- const isApproved = await accountContract.approvedAlgorithms(algId);
2670
+ const accountContract = this.ethereum.getAccountContract(accountAddress);
2671
+ const isApproved = await readAlgorithmApproved(accountContract, algId);
2498
2672
  if (!isApproved) {
2499
2673
  errors.push(
2500
2674
  `Algorithm ${ALG_NAMES[algId] ?? `0x${algId.toString(16)}`} is not approved by the account`
@@ -2535,24 +2709,29 @@ var FORCE_EXIT_ABI = [
2535
2709
  "error SignerNoLongerGuardian()",
2536
2710
  "error UnsupportedL2Type()"
2537
2711
  ];
2712
+ var FORCE_EXIT_PARSED_ABI = parseAbi(FORCE_EXIT_ABI);
2538
2713
  var L2_TYPE = {
2539
2714
  OPTIMISM: 1,
2540
2715
  ARBITRUM: 2
2541
2716
  };
2542
2717
  var ForceExitService = class {
2543
- constructor(moduleAddress, providerOrSigner) {
2718
+ constructor(moduleAddress, client) {
2544
2719
  this.moduleAddress = moduleAddress;
2545
- this.contract = new ethers.Contract(moduleAddress, FORCE_EXIT_ABI, providerOrSigner);
2546
- this.iface = new ethers.Interface(FORCE_EXIT_ABI);
2720
+ this.contract = getContract({
2721
+ address: moduleAddress,
2722
+ abi: FORCE_EXIT_PARSED_ABI,
2723
+ // viem inspects the client's actions at runtime to expose read/write; the
2724
+ // cast only satisfies the static union — a wallet client still yields writes.
2725
+ client
2726
+ });
2547
2727
  }
2548
2728
  contract;
2549
- iface;
2550
2729
  // ── On-chain reads ──────────────────────────────────────────────
2551
2730
  async isInitialized(smartAccount) {
2552
- return this.contract.isInitialized(smartAccount);
2731
+ return await this.contract.read.isInitialized([smartAccount]);
2553
2732
  }
2554
2733
  async getPendingExit(account) {
2555
- const [target, value, data, proposedAt, approvalBitmap, guardians] = await this.contract.getPendingExit(account);
2734
+ const [target, value, data, proposedAt, approvalBitmap, guardians] = await this.contract.read.getPendingExit([account]);
2556
2735
  return {
2557
2736
  target,
2558
2737
  value: BigInt(value),
@@ -2563,13 +2742,13 @@ var ForceExitService = class {
2563
2742
  };
2564
2743
  }
2565
2744
  async getAccountL2Type(account) {
2566
- return Number(await this.contract.accountL2Type(account));
2745
+ return Number(await this.contract.read.accountL2Type([account]));
2567
2746
  }
2568
2747
  async getApprovalThreshold() {
2569
- return Number(await this.contract.APPROVAL_THRESHOLD());
2748
+ return Number(await this.contract.read.APPROVAL_THRESHOLD([]));
2570
2749
  }
2571
2750
  async getModuleVersion() {
2572
- return this.contract.MODULE_VERSION();
2751
+ return await this.contract.read.MODULE_VERSION([]);
2573
2752
  }
2574
2753
  // ── Calldata encoders (for UserOp or direct tx submission) ─────
2575
2754
  /**
@@ -2582,47 +2761,77 @@ var ForceExitService = class {
2582
2761
  * // account.installModule(2, forceExitModuleAddress, calldata)
2583
2762
  */
2584
2763
  encodeOnInstall(l2Type) {
2585
- return this.iface.encodeFunctionData("onInstall", [
2586
- ethers.AbiCoder.defaultAbiCoder().encode(["uint8"], [l2Type])
2587
- ]);
2764
+ return encodeFunctionData({
2765
+ abi: FORCE_EXIT_PARSED_ABI,
2766
+ functionName: "onInstall",
2767
+ args: [encodeAbiParams(["uint8"], [l2Type])]
2768
+ });
2588
2769
  }
2589
2770
  encodeOnUninstall() {
2590
- return this.iface.encodeFunctionData("onUninstall", ["0x"]);
2771
+ return encodeFunctionData({
2772
+ abi: FORCE_EXIT_PARSED_ABI,
2773
+ functionName: "onUninstall",
2774
+ args: ["0x"]
2775
+ });
2591
2776
  }
2592
2777
  /**
2593
2778
  * Encode calldata for proposeForceExit — the exit payload to bridge out of L2.
2594
2779
  * `target` is the L2→L1 bridge contract; `data` is the bridge call payload.
2595
2780
  */
2596
2781
  encodeProposeForceExit(target, value, data) {
2597
- return this.iface.encodeFunctionData("proposeForceExit", [target, value, data]);
2782
+ return encodeFunctionData({
2783
+ abi: FORCE_EXIT_PARSED_ABI,
2784
+ functionName: "proposeForceExit",
2785
+ args: [target, value, data]
2786
+ });
2598
2787
  }
2599
2788
  /**
2600
2789
  * Encode calldata for approveForceExit — guardian signs off on the pending proposal.
2601
2790
  * `guardianSig` must be an EIP-191 personal_sign over the proposal hash.
2602
2791
  */
2603
2792
  encodeApproveForceExit(account, guardianSig) {
2604
- return this.iface.encodeFunctionData("approveForceExit", [account, guardianSig]);
2793
+ return encodeFunctionData({
2794
+ abi: FORCE_EXIT_PARSED_ABI,
2795
+ functionName: "approveForceExit",
2796
+ args: [account, guardianSig]
2797
+ });
2605
2798
  }
2606
2799
  encodeExecuteForceExit(account) {
2607
- return this.iface.encodeFunctionData("executeForceExit", [account]);
2800
+ return encodeFunctionData({
2801
+ abi: FORCE_EXIT_PARSED_ABI,
2802
+ functionName: "executeForceExit",
2803
+ args: [account]
2804
+ });
2608
2805
  }
2609
2806
  encodeCancelForceExit(account) {
2610
- return this.iface.encodeFunctionData("cancelForceExit", [account]);
2807
+ return encodeFunctionData({
2808
+ abi: FORCE_EXIT_PARSED_ABI,
2809
+ functionName: "cancelForceExit",
2810
+ args: [account]
2811
+ });
2611
2812
  }
2612
- // ── Convenience: send transactions (requires Signer) ──────────
2813
+ // ── Convenience: send transactions (requires a WalletClient) ──────────
2613
2814
  async proposeForceExit(target, value, data) {
2614
- return this.contract.proposeForceExit(target, value, data);
2815
+ return await this.contract.write.proposeForceExit([
2816
+ target,
2817
+ value,
2818
+ data
2819
+ ]);
2615
2820
  }
2616
2821
  async approveForceExit(account, guardianSig) {
2617
- return this.contract.approveForceExit(account, guardianSig);
2822
+ return await this.contract.write.approveForceExit([
2823
+ account,
2824
+ guardianSig
2825
+ ]);
2618
2826
  }
2619
2827
  async executeForceExit(account) {
2620
- return this.contract.executeForceExit(account);
2828
+ return await this.contract.write.executeForceExit([account]);
2621
2829
  }
2622
2830
  async cancelForceExit(account) {
2623
- return this.contract.cancelForceExit(account);
2831
+ return await this.contract.write.cancelForceExit([account]);
2624
2832
  }
2625
2833
  };
2834
+ var AIRACCOUNT_ABI_PARSED2 = parseAbi(AIRACCOUNT_ABI);
2626
2835
  var RECOVERY_THRESHOLD = 2;
2627
2836
  var MAX_GUARDIANS = 3;
2628
2837
  var RECOVERY_TIMELOCK_SECONDS = 2n * 24n * 60n * 60n;
@@ -2636,11 +2845,14 @@ function popcount(value) {
2636
2845
  return count;
2637
2846
  }
2638
2847
  var RecoveryService = class {
2639
- constructor(providerOrSigner) {
2640
- this.providerOrSigner = providerOrSigner;
2641
- this.iface = new ethers.Interface(AIRACCOUNT_ABI);
2848
+ /**
2849
+ * @param client viem read client (was `ethers.Provider | ethers.Signer`). Only
2850
+ * on-chain reads are performed here; calldata encoders are pure and never
2851
+ * touch the client.
2852
+ */
2853
+ constructor(client) {
2854
+ this.client = client;
2642
2855
  }
2643
- iface;
2644
2856
  // ── Calldata encoders (submit TO the account address) ─────────────
2645
2857
  /**
2646
2858
  * Encode `addGuardian(guardian)` calldata. **Owner only.**
@@ -2648,7 +2860,11 @@ var RecoveryService = class {
2648
2860
  * guardian is `address(0)`, the owner, or already registered.
2649
2861
  */
2650
2862
  encodeAddGuardian(guardian) {
2651
- return this.iface.encodeFunctionData("addGuardian", [guardian]);
2863
+ return encodeFunctionData({
2864
+ abi: AIRACCOUNT_ABI_PARSED2,
2865
+ functionName: "addGuardian",
2866
+ args: [guardian]
2867
+ });
2652
2868
  }
2653
2869
  /**
2654
2870
  * Encode `removeGuardian(index, guardianSigs)` calldata. **Owner only**, and
@@ -2659,7 +2875,11 @@ var RecoveryService = class {
2659
2875
  * @param guardianSigs EIP-191 guardian signatures over the removal hash.
2660
2876
  */
2661
2877
  encodeRemoveGuardian(index, guardianSigs) {
2662
- return this.iface.encodeFunctionData("removeGuardian", [index, guardianSigs]);
2878
+ return encodeFunctionData({
2879
+ abi: AIRACCOUNT_ABI_PARSED2,
2880
+ functionName: "removeGuardian",
2881
+ args: [index, guardianSigs]
2882
+ });
2663
2883
  }
2664
2884
  /**
2665
2885
  * Encode `proposeRecovery(newOwner)` calldata. **Any guardian** may call.
@@ -2667,14 +2887,22 @@ var RecoveryService = class {
2667
2887
  * proposer's approval (1 of {@link RECOVERY_THRESHOLD}).
2668
2888
  */
2669
2889
  encodeProposeRecovery(newOwner) {
2670
- return this.iface.encodeFunctionData("proposeRecovery", [newOwner]);
2890
+ return encodeFunctionData({
2891
+ abi: AIRACCOUNT_ABI_PARSED2,
2892
+ functionName: "proposeRecovery",
2893
+ args: [newOwner]
2894
+ });
2671
2895
  }
2672
2896
  /**
2673
2897
  * Encode `approveRecovery()` calldata. **Another guardian** approves the
2674
2898
  * active proposal, setting its bit in `approvalBitmap`.
2675
2899
  */
2676
2900
  encodeApproveRecovery() {
2677
- return this.iface.encodeFunctionData("approveRecovery", []);
2901
+ return encodeFunctionData({
2902
+ abi: AIRACCOUNT_ABI_PARSED2,
2903
+ functionName: "approveRecovery",
2904
+ args: []
2905
+ });
2678
2906
  }
2679
2907
  /**
2680
2908
  * Encode `cancelRecovery()` calldata. **Guardians only** — each call is one
@@ -2682,7 +2910,11 @@ var RecoveryService = class {
2682
2910
  * reached. The owner cannot cancel.
2683
2911
  */
2684
2912
  encodeCancelRecovery() {
2685
- return this.iface.encodeFunctionData("cancelRecovery", []);
2913
+ return encodeFunctionData({
2914
+ abi: AIRACCOUNT_ABI_PARSED2,
2915
+ functionName: "cancelRecovery",
2916
+ args: []
2917
+ });
2686
2918
  }
2687
2919
  /**
2688
2920
  * Encode `executeRecovery()` calldata. **Anyone** may call, but it only
@@ -2690,7 +2922,11 @@ var RecoveryService = class {
2690
2922
  * Rotates the account owner to the proposed `newOwner`.
2691
2923
  */
2692
2924
  encodeExecuteRecovery() {
2693
- return this.iface.encodeFunctionData("executeRecovery", []);
2925
+ return encodeFunctionData({
2926
+ abi: AIRACCOUNT_ABI_PARSED2,
2927
+ functionName: "executeRecovery",
2928
+ args: []
2929
+ });
2694
2930
  }
2695
2931
  // ── On-chain reads (against the account address) ──────────────────
2696
2932
  /**
@@ -2701,8 +2937,11 @@ var RecoveryService = class {
2701
2937
  * @param account The AirAccount address to query.
2702
2938
  */
2703
2939
  async getActiveRecovery(account) {
2704
- const contract = new ethers.Contract(account, AIRACCOUNT_ABI, this.providerOrSigner);
2705
- const [newOwner, proposedAt, approvalBitmap, cancellationBitmap] = await contract.activeRecovery();
2940
+ const [newOwner, proposedAt, approvalBitmap, cancellationBitmap] = await this.client.readContract({
2941
+ address: account,
2942
+ abi: AIRACCOUNT_ABI_PARSED2,
2943
+ functionName: "activeRecovery"
2944
+ });
2706
2945
  const proposedAtBn = BigInt(proposedAt);
2707
2946
  const approvalBitmapBn = BigInt(approvalBitmap);
2708
2947
  const cancellationBitmapBn = BigInt(cancellationBitmap);
@@ -2714,7 +2953,7 @@ var RecoveryService = class {
2714
2953
  approvalCount: popcount(approvalBitmapBn),
2715
2954
  cancellationCount: popcount(cancellationBitmapBn),
2716
2955
  executeAfter: proposedAtBn + RECOVERY_TIMELOCK_SECONDS,
2717
- isActive: newOwner !== ethers.ZeroAddress
2956
+ isActive: newOwner.toLowerCase() !== zeroAddress
2718
2957
  };
2719
2958
  }
2720
2959
  /**
@@ -2723,8 +2962,12 @@ var RecoveryService = class {
2723
2962
  * @param account The AirAccount address to query.
2724
2963
  */
2725
2964
  async getGuardianCount(account) {
2726
- const contract = new ethers.Contract(account, AIRACCOUNT_ABI, this.providerOrSigner);
2727
- return Number(await contract.guardianCount());
2965
+ const count = await this.client.readContract({
2966
+ address: account,
2967
+ abi: AIRACCOUNT_ABI_PARSED2,
2968
+ functionName: "guardianCount"
2969
+ });
2970
+ return Number(count);
2728
2971
  }
2729
2972
  /**
2730
2973
  * Read the full guardian address list.
@@ -2737,12 +2980,22 @@ var RecoveryService = class {
2737
2980
  * @param account The AirAccount address to query.
2738
2981
  */
2739
2982
  async getGuardians(account) {
2740
- const contract = new ethers.Contract(account, AIRACCOUNT_ABI, this.providerOrSigner);
2741
- const count = Number(await contract.guardianCount());
2983
+ const count = Number(
2984
+ await this.client.readContract({
2985
+ address: account,
2986
+ abi: AIRACCOUNT_ABI_PARSED2,
2987
+ functionName: "guardianCount"
2988
+ })
2989
+ );
2742
2990
  const guardians = [];
2743
2991
  for (let i = 0; i < count; i++) {
2744
- const g = await contract.guardians(i);
2745
- if (g !== ethers.ZeroAddress) guardians.push(g);
2992
+ const g = await this.client.readContract({
2993
+ address: account,
2994
+ abi: AIRACCOUNT_ABI_PARSED2,
2995
+ functionName: "guardians",
2996
+ args: [BigInt(i)]
2997
+ });
2998
+ if (g.toLowerCase() !== zeroAddress) guardians.push(g);
2746
2999
  }
2747
3000
  return guardians;
2748
3001
  }
@@ -2770,17 +3023,15 @@ var DELEGATE_ABI = [
2770
3023
  ];
2771
3024
  var AIR_ACCOUNT_DELEGATE_ADDRESS = "0x8603AAF6C3f07fdae810B323c95a198D796EC52E";
2772
3025
  var EIP7702DelegateService = class {
2773
- constructor(delegateAddress = AIR_ACCOUNT_DELEGATE_ADDRESS, providerOrSigner) {
3026
+ constructor(delegateAddress = AIR_ACCOUNT_DELEGATE_ADDRESS, client) {
2774
3027
  this.delegateAddress = delegateAddress;
2775
- this.iface = new ethers.Interface(DELEGATE_ABI);
2776
- if (providerOrSigner) {
2777
- this.contract = new ethers.Contract(delegateAddress, DELEGATE_ABI, providerOrSigner);
2778
- } else {
2779
- this.contract = new ethers.Contract(delegateAddress, DELEGATE_ABI);
2780
- }
3028
+ this.abi = parseAbi(DELEGATE_ABI);
3029
+ this.client = client;
2781
3030
  }
2782
- iface;
2783
- contract;
3031
+ /** Parsed ABI (loose viem `Abi` shape) used for encoding calldata and on-chain reads. */
3032
+ abi;
3033
+ /** Optional viem read client (was `ethers.Provider | ethers.Signer`). Required only for on-chain reads. */
3034
+ client;
2784
3035
  // ── Calldata encoders ─────────────────────────────────────────
2785
3036
  /**
2786
3037
  * Encode initialize() calldata for the first post-delegation UserOp.
@@ -2788,19 +3039,31 @@ var EIP7702DelegateService = class {
2788
3039
  * Guardian acceptance sigs follow the same EIP-712 scheme as AirAccountV7 createAccount.
2789
3040
  */
2790
3041
  encodeInitialize(params) {
2791
- return this.iface.encodeFunctionData("initialize", [
2792
- params.guardian1,
2793
- params.guardian1Sig,
2794
- params.guardian2,
2795
- params.guardian2Sig,
2796
- params.dailyLimit
2797
- ]);
3042
+ return encodeFunctionData({
3043
+ abi: this.abi,
3044
+ functionName: "initialize",
3045
+ args: [
3046
+ params.guardian1,
3047
+ params.guardian1Sig,
3048
+ params.guardian2,
3049
+ params.guardian2Sig,
3050
+ params.dailyLimit
3051
+ ]
3052
+ });
2798
3053
  }
2799
3054
  encodeExecute(dest, value, data) {
2800
- return this.iface.encodeFunctionData("execute", [dest, value, data]);
3055
+ return encodeFunctionData({
3056
+ abi: this.abi,
3057
+ functionName: "execute",
3058
+ args: [dest, value, data]
3059
+ });
2801
3060
  }
2802
3061
  encodeExecuteBatch(dests, values, datas) {
2803
- return this.iface.encodeFunctionData("executeBatch", [dests, values, datas]);
3062
+ return encodeFunctionData({
3063
+ abi: this.abi,
3064
+ functionName: "executeBatch",
3065
+ args: [dests, values, datas]
3066
+ });
2804
3067
  }
2805
3068
  // ── EIP-7702 authorization hash construction ──────────────────
2806
3069
  /**
@@ -2810,19 +3073,14 @@ var EIP7702DelegateService = class {
2810
3073
  *
2811
3074
  * This is the hash the private key signs to delegate code execution to
2812
3075
  * AirAccountDelegate. Use this hash with your KMS sign-hash endpoint or
2813
- * local ethers Signer.
3076
+ * local viem account.
2814
3077
  *
2815
3078
  * @param chainId - Target chain ID (11155111 for Sepolia)
2816
3079
  * @param nonce - EOA's current transaction nonce
2817
3080
  * @returns 32-byte hash (0x-prefixed) ready for signing
2818
3081
  */
2819
3082
  buildAuthorizationHash(chainId, nonce) {
2820
- const encoded = ethers.encodeRlp([
2821
- chainId === 0 ? "0x" : ethers.toBeHex(chainId),
2822
- this.delegateAddress,
2823
- nonce === 0n ? "0x" : ethers.toBeHex(nonce)
2824
- ]);
2825
- return ethers.keccak256(ethers.concat(["0x05", encoded]));
3083
+ return buildAuthorizationHash(chainId, nonce, this.delegateAddress);
2826
3084
  }
2827
3085
  /**
2828
3086
  * Build the full EIP-7702 authorization object for relay submission.
@@ -2843,30 +3101,42 @@ var EIP7702DelegateService = class {
2843
3101
  /**
2844
3102
  * Verify that a signature is a valid EIP-7702 authorization for the given EOA address.
2845
3103
  * Recovers the signer from the authorization hash and checks it matches `eoa`.
3104
+ *
3105
+ * NOTE: now async — viem's `recoverAddress` is asynchronous (ethers' was sync).
2846
3106
  */
2847
3107
  verifyAuthorization(eoa, chainId, nonce, signature) {
2848
- const hash = this.buildAuthorizationHash(chainId, nonce);
2849
- const recovered = ethers.recoverAddress(hash, signature);
2850
- return recovered.toLowerCase() === eoa.toLowerCase();
3108
+ return verifyAuthorization(
3109
+ eoa,
3110
+ chainId,
3111
+ nonce,
3112
+ signature,
3113
+ this.delegateAddress
3114
+ );
2851
3115
  }
2852
3116
  // ── On-chain reads (requires provider) ───────────────────────
2853
3117
  async isInitialized(eoa) {
2854
- const provider = this.contract.runner;
2855
- if (!provider) throw new Error("EIP7702DelegateService: provider required for on-chain reads");
2856
- const c = new ethers.Contract(eoa, DELEGATE_ABI, provider);
2857
- return c.isInitialized();
3118
+ if (!this.client) throw new Error("EIP7702DelegateService: provider required for on-chain reads");
3119
+ return await this.client.readContract({
3120
+ address: eoa,
3121
+ abi: this.abi,
3122
+ functionName: "isInitialized"
3123
+ });
2858
3124
  }
2859
3125
  async getOwner(eoa) {
2860
- const provider = this.contract.runner;
2861
- if (!provider) throw new Error("EIP7702DelegateService: provider required for on-chain reads");
2862
- const c = new ethers.Contract(eoa, DELEGATE_ABI, provider);
2863
- return c.owner();
3126
+ if (!this.client) throw new Error("EIP7702DelegateService: provider required for on-chain reads");
3127
+ return await this.client.readContract({
3128
+ address: eoa,
3129
+ abi: this.abi,
3130
+ functionName: "owner"
3131
+ });
2864
3132
  }
2865
3133
  async getGuardians(eoa) {
2866
- const provider = this.contract.runner;
2867
- if (!provider) throw new Error("EIP7702DelegateService: provider required for on-chain reads");
2868
- const c = new ethers.Contract(eoa, DELEGATE_ABI, provider);
2869
- return c.getGuardians();
3134
+ if (!this.client) throw new Error("EIP7702DelegateService: provider required for on-chain reads");
3135
+ return await this.client.readContract({
3136
+ address: eoa,
3137
+ abi: this.abi,
3138
+ functionName: "getGuardians"
3139
+ });
2870
3140
  }
2871
3141
  };
2872
3142
  var WEIGHTED_SIGNATURE_ABI = [
@@ -2889,6 +3159,7 @@ var WEIGHTED_SIGNATURE_ABI = [
2889
3159
  "error WeightChangeNotApproved()",
2890
3160
  "error WeightChangeTimelockNotExpired()"
2891
3161
  ];
3162
+ var WEIGHTED_SIGNATURE_ABI_PARSED = parseAbi(WEIGHTED_SIGNATURE_ABI);
2892
3163
  var WEIGHT_CHANGE_TIMELOCK_SECONDS = 2 * 24 * 60 * 60;
2893
3164
  var WEIGHT_CHANGE_THRESHOLD = 2;
2894
3165
  var WEIGHT_CHANGE_EXPIRY_SECONDS = 30 * 24 * 60 * 60;
@@ -2924,17 +3195,20 @@ function fromConfigResult(result) {
2924
3195
  };
2925
3196
  }
2926
3197
  var WeightedSignatureService = class {
2927
- constructor(accountAddress, providerOrSigner) {
3198
+ constructor(accountAddress, client) {
2928
3199
  this.accountAddress = accountAddress;
2929
- this.contract = new ethers.Contract(accountAddress, WEIGHTED_SIGNATURE_ABI, providerOrSigner);
2930
- this.iface = new ethers.Interface(WEIGHTED_SIGNATURE_ABI);
3200
+ this.client = client;
3201
+ this.address = accountAddress;
2931
3202
  }
2932
- contract;
2933
- iface;
3203
+ address;
2934
3204
  // ── On-chain reads ──────────────────────────────────────────────
2935
3205
  /** Read the account's current active WeightConfig. */
2936
3206
  async getWeightConfig() {
2937
- const result = await this.contract.weightConfig();
3207
+ const result = await this.client.readContract({
3208
+ address: this.address,
3209
+ abi: WEIGHTED_SIGNATURE_ABI_PARSED,
3210
+ functionName: "weightConfig"
3211
+ });
2938
3212
  return fromConfigResult(result);
2939
3213
  }
2940
3214
  /**
@@ -2942,7 +3216,11 @@ var WeightedSignatureService = class {
2942
3216
  * active proposal (the returned `proposed` config will be all zeros).
2943
3217
  */
2944
3218
  async getPendingWeightChange() {
2945
- const [proposed, proposedAt, approvalBitmap] = await this.contract.pendingWeightChange();
3219
+ const [proposed, proposedAt, approvalBitmap] = await this.client.readContract({
3220
+ address: this.address,
3221
+ abi: WEIGHTED_SIGNATURE_ABI_PARSED,
3222
+ functionName: "pendingWeightChange"
3223
+ });
2946
3224
  return {
2947
3225
  proposed: fromConfigResult(proposed),
2948
3226
  proposedAt: BigInt(proposedAt),
@@ -2955,29 +3233,46 @@ var WeightedSignatureService = class {
2955
3233
  * Weakening an existing config must go through encodeProposeWeightChange instead.
2956
3234
  */
2957
3235
  encodeSetWeightConfig(config) {
2958
- return this.iface.encodeFunctionData("setWeightConfig", [toConfigTuple(config)]);
3236
+ return encodeFunctionData({
3237
+ abi: WEIGHTED_SIGNATURE_ABI_PARSED,
3238
+ functionName: "setWeightConfig",
3239
+ args: [toConfigTuple(config)]
3240
+ });
2959
3241
  }
2960
3242
  /**
2961
3243
  * Encode proposeWeightChange calldata. OWNER only; opens a guardian-governed proposal
2962
3244
  * (required for any weakening). Subject to 2-of-3 approval + 2-day timelock before execute.
2963
3245
  */
2964
3246
  encodeProposeWeightChange(config) {
2965
- return this.iface.encodeFunctionData("proposeWeightChange", [toConfigTuple(config)]);
3247
+ return encodeFunctionData({
3248
+ abi: WEIGHTED_SIGNATURE_ABI_PARSED,
3249
+ functionName: "proposeWeightChange",
3250
+ args: [toConfigTuple(config)]
3251
+ });
2966
3252
  }
2967
3253
  /** Encode approveWeightChange calldata. GUARDIAN only; each guardian may approve once. */
2968
3254
  encodeApproveWeightChange() {
2969
- return this.iface.encodeFunctionData("approveWeightChange", []);
3255
+ return encodeFunctionData({
3256
+ abi: WEIGHTED_SIGNATURE_ABI_PARSED,
3257
+ functionName: "approveWeightChange"
3258
+ });
2970
3259
  }
2971
3260
  /** Encode cancelWeightChange calldata. OWNER or any GUARDIAN may cancel a pending proposal. */
2972
3261
  encodeCancelWeightChange() {
2973
- return this.iface.encodeFunctionData("cancelWeightChange", []);
3262
+ return encodeFunctionData({
3263
+ abi: WEIGHTED_SIGNATURE_ABI_PARSED,
3264
+ functionName: "cancelWeightChange"
3265
+ });
2974
3266
  }
2975
3267
  /**
2976
3268
  * Encode executeWeightChange calldata. Callable by anyone, but only succeeds once the
2977
3269
  * threshold (2-of-3) and timelock (2 days) are both satisfied and the proposal has not expired.
2978
3270
  */
2979
3271
  encodeExecuteWeightChange() {
2980
- return this.iface.encodeFunctionData("executeWeightChange", []);
3272
+ return encodeFunctionData({
3273
+ abi: WEIGHTED_SIGNATURE_ABI_PARSED,
3274
+ functionName: "executeWeightChange"
3275
+ });
2981
3276
  }
2982
3277
  };
2983
3278
  var AGENT_REGISTRY_ABI = [
@@ -3004,43 +3299,42 @@ var AGENT_REGISTRY_ABI = [
3004
3299
  "error NotAgentOwner()",
3005
3300
  "error SelfRegistrationForbidden()"
3006
3301
  ];
3302
+ var REGISTRY_ABI = parseAbi(AGENT_REGISTRY_ABI);
3303
+ var FACTORY_ABI2 = parseAbi(AIRACCOUNT_FACTORY_ABI);
3304
+ var ACCOUNT_ABI3 = parseAbi(AIRACCOUNT_ABI);
3007
3305
  var AgentRegistryService = class {
3008
3306
  /**
3009
- * @param providerOrSigner ethers Provider (reads only) or Signer (reads + sends).
3010
- * @param registryAddress deployed AgentRegistry contract address.
3307
+ * @param client viem PublicClient for on-chain reads (e.g. `ethereum.getProvider()`).
3308
+ * @param registryAddress deployed AgentRegistry contract address.
3011
3309
  */
3012
- constructor(providerOrSigner, registryAddress) {
3310
+ constructor(client, registryAddress) {
3013
3311
  this.registryAddress = registryAddress;
3014
- this.providerOrSigner = providerOrSigner;
3015
- this.contract = new ethers.Contract(registryAddress, AGENT_REGISTRY_ABI, providerOrSigner);
3016
- this.iface = new ethers.Interface(AGENT_REGISTRY_ABI);
3017
- this.factoryIface = new ethers.Interface(AIRACCOUNT_FACTORY_ABI);
3018
- this.accountIface = new ethers.Interface(AIRACCOUNT_ABI);
3312
+ this.client = client;
3019
3313
  }
3020
- contract;
3021
- iface;
3022
- factoryIface;
3023
- accountIface;
3024
- providerOrSigner;
3314
+ client;
3025
3315
  // ── Composed register/revoke-via-account scenario encoders ──────────────────
3026
3316
  // registerAgent/revokeAgent require msg.sender == the agent account, so they are delivered
3027
3317
  // through the account's execute(registry, 0, calldata). These return the FULL execute
3028
3318
  // calldata to submit TO the agent account (owner-signed) — the scenario-level entry point.
3029
3319
  /** Encode `account.execute(registry, 0, registerAgent(agentWallet, agentWalletSig))`. */
3030
3320
  encodeRegisterAgentViaAccount(agentWallet, agentWalletSig) {
3031
- return this.accountIface.encodeFunctionData("execute", [
3032
- this.registryAddress,
3033
- 0n,
3034
- this.encodeRegisterAgent(agentWallet, agentWalletSig)
3035
- ]);
3321
+ return encodeFunctionData({
3322
+ abi: ACCOUNT_ABI3,
3323
+ functionName: "execute",
3324
+ args: [
3325
+ this.registryAddress,
3326
+ 0n,
3327
+ this.encodeRegisterAgent(agentWallet, agentWalletSig)
3328
+ ]
3329
+ });
3036
3330
  }
3037
3331
  /** Encode `account.execute(registry, 0, revokeAgent(agentWallet))`. */
3038
3332
  encodeRevokeAgentViaAccount(agentWallet) {
3039
- return this.accountIface.encodeFunctionData("execute", [
3040
- this.registryAddress,
3041
- 0n,
3042
- this.encodeRevokeAgent(agentWallet)
3043
- ]);
3333
+ return encodeFunctionData({
3334
+ abi: ACCOUNT_ABI3,
3335
+ functionName: "execute",
3336
+ args: [this.registryAddress, 0n, this.encodeRevokeAgent(agentWallet)]
3337
+ });
3044
3338
  }
3045
3339
  // ── AgentRegistry calldata encoders ─────────────────────────────────────────
3046
3340
  /**
@@ -3052,7 +3346,11 @@ var AgentRegistryService = class {
3052
3346
  * if the wallet is already bound.
3053
3347
  */
3054
3348
  encodeRegisterAgent(agentWallet, agentWalletSig) {
3055
- return this.iface.encodeFunctionData("registerAgent", [agentWallet, agentWalletSig]);
3349
+ return encodeFunctionData({
3350
+ abi: REGISTRY_ABI,
3351
+ functionName: "registerAgent",
3352
+ args: [agentWallet, agentWalletSig]
3353
+ });
3056
3354
  }
3057
3355
  /**
3058
3356
  * Encode calldata for `revokeAgent(agentWallet)`.
@@ -3061,7 +3359,11 @@ var AgentRegistryService = class {
3061
3359
  * agent's human owner (else `NotAgentOwner`).
3062
3360
  */
3063
3361
  encodeRevokeAgent(agentWallet) {
3064
- return this.iface.encodeFunctionData("revokeAgent", [agentWallet]);
3362
+ return encodeFunctionData({
3363
+ abi: REGISTRY_ABI,
3364
+ functionName: "revokeAgent",
3365
+ args: [agentWallet]
3366
+ });
3065
3367
  }
3066
3368
  /**
3067
3369
  * Encode calldata for `deregisterAgent(agentWallet)`.
@@ -3070,32 +3372,68 @@ var AgentRegistryService = class {
3070
3372
  * lighter-weight `revokeAgent`). Caller must be the agent's human owner.
3071
3373
  */
3072
3374
  encodeDeregisterAgent(agentWallet) {
3073
- return this.iface.encodeFunctionData("deregisterAgent", [agentWallet]);
3375
+ return encodeFunctionData({
3376
+ abi: REGISTRY_ABI,
3377
+ functionName: "deregisterAgent",
3378
+ args: [agentWallet]
3379
+ });
3074
3380
  }
3075
3381
  // ── AgentRegistry on-chain reads ────────────────────────────────────────────
3076
3382
  /** Whether `agentWallet` is currently registered in the registry. */
3077
3383
  async isRegisteredAgent(agentWallet) {
3078
- return this.contract.isRegisteredAgent(agentWallet);
3384
+ return await this.client.readContract({
3385
+ address: this.registryAddress,
3386
+ abi: REGISTRY_ABI,
3387
+ functionName: "isRegisteredAgent",
3388
+ args: [agentWallet]
3389
+ });
3079
3390
  }
3080
3391
  /** Whether `account` has been marked valid (e.g. an AirAccount minted by the bound factory). */
3081
3392
  async isValidAccount(account) {
3082
- return this.contract.isValidAccount(account);
3393
+ return await this.client.readContract({
3394
+ address: this.registryAddress,
3395
+ abi: REGISTRY_ABI,
3396
+ functionName: "isValidAccount",
3397
+ args: [account]
3398
+ });
3083
3399
  }
3084
3400
  /** The human owner bound to `agentWallet` (ZeroAddress if unregistered). */
3085
3401
  async getHumanOwner(agentWallet) {
3086
- return this.contract.getHumanOwner(agentWallet);
3402
+ return await this.client.readContract({
3403
+ address: this.registryAddress,
3404
+ abi: REGISTRY_ABI,
3405
+ functionName: "getHumanOwner",
3406
+ args: [agentWallet]
3407
+ });
3087
3408
  }
3088
3409
  /** Number of agents registered under `owner`. */
3089
3410
  async getAgentCount(owner) {
3090
- return BigInt(await this.contract.getAgentCount(owner));
3411
+ return BigInt(
3412
+ await this.client.readContract({
3413
+ address: this.registryAddress,
3414
+ abi: REGISTRY_ABI,
3415
+ functionName: "getAgentCount",
3416
+ args: [owner]
3417
+ })
3418
+ );
3091
3419
  }
3092
3420
  /** The agent wallet at `index` in `owner`'s agent list. */
3093
3421
  async getAgentByIndex(owner, index) {
3094
- return this.contract.getAgentByIndex(owner, index);
3422
+ return await this.client.readContract({
3423
+ address: this.registryAddress,
3424
+ abi: REGISTRY_ABI,
3425
+ functionName: "getAgentByIndex",
3426
+ args: [owner, BigInt(index)]
3427
+ });
3095
3428
  }
3096
3429
  /** Full list of agent wallets registered under `humanOwner`. */
3097
3430
  async getAgents(humanOwner) {
3098
- const result = await this.contract.getAgents(humanOwner);
3431
+ const result = await this.client.readContract({
3432
+ address: this.registryAddress,
3433
+ abi: REGISTRY_ABI,
3434
+ functionName: "getAgents",
3435
+ args: [humanOwner]
3436
+ });
3099
3437
  return Array.from(result);
3100
3438
  }
3101
3439
  /**
@@ -3103,16 +3441,31 @@ var AgentRegistryService = class {
3103
3441
  * The contract clamps `count` to the remaining length, so the returned array may be shorter.
3104
3442
  */
3105
3443
  async getAgentsPage(owner, start, count) {
3106
- const result = await this.contract.getAgentsPage(owner, start, count);
3444
+ const result = await this.client.readContract({
3445
+ address: this.registryAddress,
3446
+ abi: REGISTRY_ABI,
3447
+ functionName: "getAgentsPage",
3448
+ args: [owner, BigInt(start), BigInt(count)]
3449
+ });
3107
3450
  return Array.from(result);
3108
3451
  }
3109
3452
  /** Raw `agentWalletOwner` mapping read (agentWallet → owner). */
3110
3453
  async agentWalletOwner(agentWallet) {
3111
- return this.contract.agentWalletOwner(agentWallet);
3454
+ return await this.client.readContract({
3455
+ address: this.registryAddress,
3456
+ abi: REGISTRY_ABI,
3457
+ functionName: "agentWalletOwner",
3458
+ args: [agentWallet]
3459
+ });
3112
3460
  }
3113
3461
  /** Raw `ownerAgents` array read (owner, index → agentWallet). */
3114
3462
  async ownerAgents(owner, index) {
3115
- return this.contract.ownerAgents(owner, index);
3463
+ return await this.client.readContract({
3464
+ address: this.registryAddress,
3465
+ abi: REGISTRY_ABI,
3466
+ functionName: "ownerAgents",
3467
+ args: [owner, BigInt(index)]
3468
+ });
3116
3469
  }
3117
3470
  // ── Factory agent-account helpers (AAStarAirAccountFactoryV7) ───────────────
3118
3471
  /**
@@ -3123,21 +3476,29 @@ var AgentRegistryService = class {
3123
3476
  * calldata to the factory address (direct tx or via a relayer).
3124
3477
  */
3125
3478
  encodeCreateAgentAccount(params) {
3126
- return this.factoryIface.encodeFunctionData("createAgentAccount", [
3127
- params.agentKey,
3128
- params.agentId,
3129
- params.guardian2,
3130
- params.guardian2Sig,
3131
- params.agentKeySig,
3132
- params.deadline,
3133
- params.dailyLimit
3134
- ]);
3479
+ return encodeFunctionData({
3480
+ abi: FACTORY_ABI2,
3481
+ functionName: "createAgentAccount",
3482
+ args: [
3483
+ params.agentKey,
3484
+ params.agentId,
3485
+ params.guardian2,
3486
+ params.guardian2Sig,
3487
+ params.agentKeySig,
3488
+ BigInt(params.deadline),
3489
+ params.dailyLimit
3490
+ ]
3491
+ });
3135
3492
  }
3136
3493
  /**
3137
3494
  * Encode calldata for the factory's `setAgentRegistry(_agentRegistry)` (factory-admin only).
3138
3495
  */
3139
3496
  encodeSetAgentRegistry(agentRegistry) {
3140
- return this.factoryIface.encodeFunctionData("setAgentRegistry", [agentRegistry]);
3497
+ return encodeFunctionData({
3498
+ abi: FACTORY_ABI2,
3499
+ functionName: "setAgentRegistry",
3500
+ args: [agentRegistry]
3501
+ });
3141
3502
  }
3142
3503
  /**
3143
3504
  * Predict the CREATE2 address of an agent account via the factory's `getAgentAddress(...)`.
@@ -3148,21 +3509,21 @@ var AgentRegistryService = class {
3148
3509
  * @param agentId the bytes32 agent identifier.
3149
3510
  */
3150
3511
  async getAgentAccountAddress(factoryAddress, humanOwner, agentKey, agentId) {
3151
- const factory = new ethers.Contract(
3152
- factoryAddress,
3153
- AIRACCOUNT_FACTORY_ABI,
3154
- this.providerOrSigner
3155
- );
3156
- return factory.getAgentAddress(humanOwner, agentKey, agentId);
3512
+ return await this.client.readContract({
3513
+ address: factoryAddress,
3514
+ abi: FACTORY_ABI2,
3515
+ functionName: "getAgentAddress",
3516
+ args: [humanOwner, agentKey, agentId]
3517
+ });
3157
3518
  }
3158
3519
  /** Read the AgentRegistry address currently bound to the factory. */
3159
3520
  async getFactoryAgentRegistry(factoryAddress) {
3160
- const factory = new ethers.Contract(
3161
- factoryAddress,
3162
- AIRACCOUNT_FACTORY_ABI,
3163
- this.providerOrSigner
3164
- );
3165
- return factory.agentRegistry();
3521
+ return await this.client.readContract({
3522
+ address: factoryAddress,
3523
+ abi: FACTORY_ABI2,
3524
+ functionName: "agentRegistry",
3525
+ args: []
3526
+ });
3166
3527
  }
3167
3528
  };
3168
3529
  var ERC8004_ABI = [
@@ -3193,12 +3554,25 @@ function erc8004AddressesForChain(chainId) {
3193
3554
  throw new Error(`ERC-8004: unsupported chain ${chainId}`);
3194
3555
  }
3195
3556
  var ERC8004Service = class {
3196
- iface;
3557
+ abi;
3197
3558
  provider;
3198
3559
  constructor(provider) {
3199
- this.iface = new ethers.Interface(ERC8004_ABI);
3560
+ this.abi = parseAbi(ERC8004_ABI);
3200
3561
  this.provider = provider;
3201
3562
  }
3563
+ /**
3564
+ * Build a read-only viem contract bound to the account address. The ABI is loaded from
3565
+ * human-readable signatures via `parseAbi` (loose `Abi`), so `read` methods are indexed by
3566
+ * name and return `unknown` — cast at the call site. Mirrors the dynamic surface that
3567
+ * `ethers.Contract` previously exposed. Caller must ensure `this.provider` is set.
3568
+ */
3569
+ contractAt(accountAddress) {
3570
+ return getContract({
3571
+ address: accountAddress,
3572
+ abi: this.abi,
3573
+ client: this.provider
3574
+ });
3575
+ }
3202
3576
  // ── AAStar AgentRegistry path ─────────────────────────────────────────────
3203
3577
  /**
3204
3578
  * Encode calldata for `setAgentWallet`.
@@ -3212,12 +3586,11 @@ var ERC8004Service = class {
3212
3586
  * Callable: owner EOA direct tx OR via UserOp (gasless).
3213
3587
  */
3214
3588
  encodeSetAgentWallet(params) {
3215
- return this.iface.encodeFunctionData("setAgentWallet", [
3216
- params.agentId,
3217
- params.agentWallet,
3218
- params.agentRegistry,
3219
- params.agentWalletSig
3220
- ]);
3589
+ return encodeFunctionData({
3590
+ abi: this.abi,
3591
+ functionName: "setAgentWallet",
3592
+ args: [params.agentId, params.agentWallet, params.agentRegistry, params.agentWalletSig]
3593
+ });
3221
3594
  }
3222
3595
  // ── Official ERC-8004 identity path ──────────────────────────────────────
3223
3596
  /**
@@ -3230,10 +3603,11 @@ var ERC8004Service = class {
3230
3603
  * Callable: owner EOA direct tx OR via UserOp (gasless).
3231
3604
  */
3232
3605
  encodeMintAgentIdentity(params) {
3233
- return this.iface.encodeFunctionData("mintAgentIdentity", [
3234
- params.identityRegistry,
3235
- params.agentURI
3236
- ]);
3606
+ return encodeFunctionData({
3607
+ abi: this.abi,
3608
+ functionName: "mintAgentIdentity",
3609
+ args: [params.identityRegistry, params.agentURI]
3610
+ });
3237
3611
  }
3238
3612
  /**
3239
3613
  * Encode calldata for `bindERC8004AgentWallet`.
@@ -3245,13 +3619,17 @@ var ERC8004Service = class {
3245
3619
  * Callable: owner EOA direct tx OR via UserOp (gasless).
3246
3620
  */
3247
3621
  encodeBindERC8004AgentWallet(params) {
3248
- return this.iface.encodeFunctionData("bindERC8004AgentWallet", [
3249
- params.identityRegistry,
3250
- params.agentId,
3251
- params.agentWallet,
3252
- params.deadline,
3253
- params.signature
3254
- ]);
3622
+ return encodeFunctionData({
3623
+ abi: this.abi,
3624
+ functionName: "bindERC8004AgentWallet",
3625
+ args: [
3626
+ params.identityRegistry,
3627
+ params.agentId,
3628
+ params.agentWallet,
3629
+ params.deadline,
3630
+ params.signature
3631
+ ]
3632
+ });
3255
3633
  }
3256
3634
  // ── Reputation ────────────────────────────────────────────────────────────
3257
3635
  /**
@@ -3263,17 +3641,21 @@ var ERC8004Service = class {
3263
3641
  * Callable: owner EOA direct tx OR via UserOp (gasless).
3264
3642
  */
3265
3643
  encodeSubmitAgentReputation(params) {
3266
- return this.iface.encodeFunctionData("submitAgentReputation", [
3267
- params.reputationRegistry,
3268
- params.agentId,
3269
- params.value,
3270
- params.valueDecimals,
3271
- params.tag1,
3272
- params.tag2,
3273
- params.endpoint,
3274
- params.feedbackURI,
3275
- params.feedbackHash
3276
- ]);
3644
+ return encodeFunctionData({
3645
+ abi: this.abi,
3646
+ functionName: "submitAgentReputation",
3647
+ args: [
3648
+ params.reputationRegistry,
3649
+ params.agentId,
3650
+ params.value,
3651
+ params.valueDecimals,
3652
+ params.tag1,
3653
+ params.tag2,
3654
+ params.endpoint,
3655
+ params.feedbackURI,
3656
+ params.feedbackHash
3657
+ ]
3658
+ });
3277
3659
  }
3278
3660
  /**
3279
3661
  * Query aggregated reputation for an agent from the official ERC-8004 ReputationRegistry.
@@ -3281,35 +3663,40 @@ var ERC8004Service = class {
3281
3663
  */
3282
3664
  async queryAgentReputation(accountAddress, params) {
3283
3665
  if (!this.provider) throw new Error("ERC8004Service: provider required for on-chain reads");
3284
- const contract = new ethers.Contract(accountAddress, ERC8004_ABI, this.provider);
3285
- const [count, summaryValue, summaryDecimals] = await contract.queryAgentReputation(
3666
+ const contract = this.contractAt(accountAddress);
3667
+ const [count, summaryValue, summaryDecimals] = await contract.read.queryAgentReputation([
3286
3668
  params.reputationRegistry,
3287
3669
  params.agentId,
3288
3670
  params.clientAddresses,
3289
3671
  params.tag1,
3290
3672
  params.tag2
3291
- );
3673
+ ]);
3292
3674
  return { count: BigInt(count), summaryValue: BigInt(summaryValue), summaryDecimals: Number(summaryDecimals) };
3293
3675
  }
3294
3676
  /**
3295
3677
  * Encode calldata for `queryAgentReputation` (for static-call or eth_call without a signer).
3296
3678
  */
3297
3679
  encodeQueryAgentReputation(params) {
3298
- return this.iface.encodeFunctionData("queryAgentReputation", [
3299
- params.reputationRegistry,
3300
- params.agentId,
3301
- params.clientAddresses,
3302
- params.tag1,
3303
- params.tag2
3304
- ]);
3680
+ return encodeFunctionData({
3681
+ abi: this.abi,
3682
+ functionName: "queryAgentReputation",
3683
+ args: [
3684
+ params.reputationRegistry,
3685
+ params.agentId,
3686
+ params.clientAddresses,
3687
+ params.tag1,
3688
+ params.tag2
3689
+ ]
3690
+ });
3305
3691
  }
3306
3692
  /**
3307
3693
  * Read the agentExtension implementation address from a deployed AirAccount.
3308
3694
  */
3309
3695
  async getAgentExtensionAddress(accountAddress) {
3310
3696
  if (!this.provider) throw new Error("ERC8004Service: provider required for on-chain reads");
3311
- const contract = new ethers.Contract(accountAddress, ERC8004_ABI, this.provider);
3312
- return contract.agentExtension();
3697
+ const contract = this.contractAt(accountAddress);
3698
+ const extension = await contract.read.agentExtension([]);
3699
+ return extension;
3313
3700
  }
3314
3701
  };
3315
3702
  var DEFAULT_KMS_ENDPOINT = "https://kms.aastar.io";
@@ -3390,7 +3777,7 @@ function base64UrlEncode(bytes) {
3390
3777
  function base64UrlDecode(value) {
3391
3778
  return new Uint8Array(Buffer.from(value, "base64url"));
3392
3779
  }
3393
- function hexToBytes(hex) {
3780
+ function hexToBytes4(hex) {
3394
3781
  const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
3395
3782
  if (clean.length % 2 !== 0) {
3396
3783
  throw new Error("hexToBytes: odd-length hex string");
@@ -3409,7 +3796,7 @@ var P256PasskeySigner = class {
3409
3796
  * @param credentialId base64url credential id (defaults to the reference fixture).
3410
3797
  */
3411
3798
  constructor(privateKey, credentialId = DEFAULT_CREDENTIAL_ID) {
3412
- this.privateKey = typeof privateKey === "string" ? hexToBytes(privateKey) : privateKey;
3799
+ this.privateKey = typeof privateKey === "string" ? hexToBytes4(privateKey) : privateKey;
3413
3800
  this.credentialId = credentialId;
3414
3801
  }
3415
3802
  /**
@@ -3475,22 +3862,22 @@ async function runWebAuthnCeremony(begin, options) {
3475
3862
  });
3476
3863
  return { ChallengeId: begun.ChallengeId, Credential: credential };
3477
3864
  }
3478
- function beginAuthenticationChallenge(http, keyId) {
3479
- return http.post("/BeginAuthentication", { KeyId: keyId });
3865
+ function beginAuthenticationChallenge(http2, keyId) {
3866
+ return http2.post("/BeginAuthentication", { KeyId: keyId });
3480
3867
  }
3481
- function beginGrantSessionChallenge(http, keyId) {
3482
- return http.get("/kms/begin-grant-session-auth", {
3868
+ function beginGrantSessionChallenge(http2, keyId) {
3869
+ return http2.get("/kms/begin-grant-session-auth", {
3483
3870
  params: { keyId }
3484
3871
  });
3485
3872
  }
3486
- function runAuthenticationCeremony(http, keyId, signer, options) {
3487
- return runWebAuthnCeremony(() => beginAuthenticationChallenge(http, keyId), {
3873
+ function runAuthenticationCeremony(http2, keyId, signer, options) {
3874
+ return runWebAuthnCeremony(() => beginAuthenticationChallenge(http2, keyId), {
3488
3875
  signer,
3489
3876
  ...options
3490
3877
  });
3491
3878
  }
3492
- function runGrantSessionCeremony(http, keyId, signer, options) {
3493
- return runWebAuthnCeremony(() => beginGrantSessionChallenge(http, keyId), {
3879
+ function runGrantSessionCeremony(http2, keyId, signer, options) {
3880
+ return runWebAuthnCeremony(() => beginGrantSessionChallenge(http2, keyId), {
3494
3881
  signer,
3495
3882
  ...options
3496
3883
  });
@@ -3791,14 +4178,13 @@ var KmsManager = class {
3791
4178
  return this.client.post("/BeginAuthentication", { KeyId: keyId });
3792
4179
  }
3793
4180
  // ── Factory ─────────────────────────────────────────────────────
3794
- createKmsSigner(keyId, address, assertionProvider, provider) {
4181
+ createKmsSigner(keyId, address, assertionProvider) {
3795
4182
  this.ensureEnabled();
3796
- return new KmsSigner(keyId, address, this, assertionProvider, provider);
4183
+ return new KmsSigner(keyId, address, this, assertionProvider);
3797
4184
  }
3798
4185
  };
3799
- var KmsSigner = class _KmsSigner extends ethers.AbstractSigner {
3800
- constructor(keyId, _address, kmsManager, assertionProvider, provider) {
3801
- super(provider);
4186
+ var KmsSigner = class {
4187
+ constructor(keyId, _address, kmsManager, assertionProvider) {
3802
4188
  this.keyId = keyId;
3803
4189
  this._address = _address;
3804
4190
  this.kmsManager = kmsManager;
@@ -3808,55 +4194,19 @@ var KmsSigner = class _KmsSigner extends ethers.AbstractSigner {
3808
4194
  return this._address;
3809
4195
  }
3810
4196
  async signMessage(message) {
3811
- const messageBytes = typeof message === "string" ? ethers.toUtf8Bytes(message) : message;
3812
- const messageHash = ethers.hashMessage(messageBytes);
4197
+ const messageHash = hashMessage(message);
3813
4198
  const assertion = await this.assertionProvider();
3814
4199
  const signResponse = await this.kmsManager.signHash(messageHash, assertion, {
3815
4200
  Address: this._address
3816
4201
  });
3817
4202
  return "0x" + signResponse.Signature;
3818
4203
  }
3819
- async signTransaction(tx) {
3820
- if (!this.provider) {
3821
- throw new Error("Provider is required for signing transactions");
3822
- }
3823
- const populated = await this.populateTransaction(tx);
3824
- const unsignedTx = ethers.Transaction.from(populated);
3825
- const txHash = unsignedTx.hash;
3826
- if (!txHash) {
3827
- throw new Error("Failed to compute transaction hash");
3828
- }
3829
- const assertion = await this.assertionProvider();
3830
- const signResponse = await this.kmsManager.signHash(txHash, assertion, {
3831
- Address: this._address
3832
- });
3833
- const sig = ethers.Signature.from("0x" + signResponse.Signature);
3834
- unsignedTx.signature = sig;
3835
- return unsignedTx.serialized;
3836
- }
3837
- async signTypedData(domain, types, value) {
3838
- const hash = ethers.TypedDataEncoder.hash(domain, types, value);
3839
- const assertion = await this.assertionProvider();
3840
- const signResponse = await this.kmsManager.signHash(hash, assertion, {
3841
- Address: this._address
3842
- });
3843
- return "0x" + signResponse.Signature;
3844
- }
3845
- connect(provider) {
3846
- return new _KmsSigner(
3847
- this.keyId,
3848
- this._address,
3849
- this.kmsManager,
3850
- this.assertionProvider,
3851
- provider
3852
- );
3853
- }
3854
4204
  };
3855
4205
 
3856
4206
  // ../airaccount/src/server/services/kms-agent-service.ts
3857
4207
  var KmsAgentService = class {
3858
- constructor(http) {
3859
- this.http = http;
4208
+ constructor(http2) {
4209
+ this.http = http2;
3860
4210
  }
3861
4211
  /**
3862
4212
  * Mint a new agent key under an existing human key (WebAuthn-gated).
@@ -3946,8 +4296,8 @@ var KmsAgentService = class {
3946
4296
 
3947
4297
  // ../airaccount/src/server/services/kms-session-service.ts
3948
4298
  var KmsSessionService = class {
3949
- constructor(http) {
3950
- this.http = http;
4299
+ constructor(http2) {
4300
+ this.http = http2;
3951
4301
  }
3952
4302
  /**
3953
4303
  * Create a P-256 session key under a human key (WebAuthn-gated).
@@ -4023,8 +4373,8 @@ var KmsSessionService = class {
4023
4373
 
4024
4374
  // ../airaccount/src/server/services/kms-payment-signer.ts
4025
4375
  var KmsPaymentSigner = class {
4026
- constructor(http) {
4027
- this.http = http;
4376
+ constructor(http2) {
4377
+ this.http = http2;
4028
4378
  }
4029
4379
  /**
4030
4380
  * Dispatch a payment-signing request with the chosen auth mode.
@@ -4066,8 +4416,8 @@ var KmsPaymentSigner = class {
4066
4416
 
4067
4417
  // ../airaccount/src/server/services/kms-monitor-service.ts
4068
4418
  var KmsMonitorService = class {
4069
- constructor(http) {
4070
- this.http = http;
4419
+ constructor(http2) {
4420
+ this.http = http2;
4071
4421
  }
4072
4422
  /**
4073
4423
  * Liveness probe (`GET /health`, no auth). Does NOT require the KMS feature
@@ -4220,18 +4570,18 @@ var MemoryStorage = class {
4220
4570
  }
4221
4571
  };
4222
4572
  var LocalWalletSigner = class {
4223
- wallet;
4224
- constructor(privateKey, provider) {
4225
- this.wallet = new ethers.Wallet(privateKey, provider);
4573
+ account;
4574
+ constructor(privateKey) {
4575
+ this.account = privateKeyToAccount(privateKey);
4226
4576
  }
4227
4577
  async getAddress(_userId) {
4228
- return this.wallet.address;
4578
+ return this.account.address;
4229
4579
  }
4230
- async getSigner(_userId, _ctx) {
4231
- return this.wallet;
4580
+ async signMessage(_userId, message, _ctx) {
4581
+ return this.account.signMessage({ message: { raw: message } });
4232
4582
  }
4233
4583
  async ensureSigner(_userId) {
4234
- return { signer: this.wallet, address: this.wallet.address };
4584
+ return { address: this.account.address };
4235
4585
  }
4236
4586
  };
4237
4587
  /*! Bundled license information:
@@ -4240,6 +4590,6 @@ var LocalWalletSigner = class {
4240
4590
  (*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
4241
4591
  */
4242
4592
 
4243
- export { ACCOUNT_ABI, AGENT_SESSION_KEY_VALIDATOR_ABI, AIRACCOUNT_ABI, AIRACCOUNT_ADDRESSES, AIRACCOUNT_FACTORY_ABI, AIR_ACCOUNT_COMPOSITE_VALIDATOR_ABI, AIR_ACCOUNT_DELEGATE_ABI, AIR_ACCOUNT_DELEGATE_ADDRESS, ALG_ID, AccountManager, AgentRegistryService, BLSSignatureService, CALLDATA_PARSER_REGISTRY_ABI, ConsoleLogger, DEFAULT_CREDENTIAL_ID, DEFAULT_KMS_ENDPOINT, DEFAULT_ORIGIN, DEFAULT_RP_ID, DvtPendingConfirmationError, EIP7702DelegateService, ENTRYPOINT_ABI_V6, ENTRYPOINT_ABI_V7_V8, ENTRYPOINT_ADDRESSES, ERC20_ABI, ERC8004Service, ERC8004_ADDRESSES, EXECUTE_BATCH_SELECTOR, EXECUTE_SELECTOR, EXECUTE_USER_OP_SELECTOR, EntryPointVersion, EthereumProvider, FACTORY_ABI_V6, FACTORY_ABI_V7_V8, FORCE_EXIT_MODULE_ABI, ForceExitService, GLOBAL_GUARD_ABI, GuardChecker, GuardStateReader, KmsAgentService, KmsHttpClient, KmsManager, KmsMonitorService, KmsPaymentSigner, KmsSessionService, KmsSigner, L2_TYPE, LocalWalletSigner, MAX_GUARDIANS, MODULE_TYPE, MemoryStorage, ModuleManager, P256PasskeySigner, PaymasterManager, PaymasterPriceStalenessError, RECOVERY_THRESHOLD, RECOVERY_TIMELOCK_SECONDS, RecoveryService, SESSION_KEY_VALIDATOR_ABI, SessionKeyService, SilentLogger, TIER_GUARD_HOOK_ABI, TokenService, TransferManager, VALIDATOR_ABI, WEIGHT_CHANGE_EXPIRY_SECONDS, WEIGHT_CHANGE_THRESHOLD, WEIGHT_CHANGE_TIMELOCK_SECONDS, WalletManager, WeightedSignatureService, YAAAServerClient, base64UrlDecode, base64UrlEncode, beginAuthenticationChallenge, beginGrantSessionChallenge, buildAuthenticationCredential, buildAuthenticatorData, buildClientDataJSON, buildInstallModuleHash, buildUninstallModuleHash, computeOapdSalt, erc8004AddressesForChain, getOapdAddress, getOapdAddressWithChainId, isExecuteUserOpWrapped, isOapdDeployed, isPendingConfirmation, packP256SessionSignature, packSecp256k1SessionSignature, runAuthenticationCeremony, runGrantSessionCeremony, runWebAuthnCeremony, sepoliaV07Config, validateConfig, wrapExecuteUserOp };
4244
- //# sourceMappingURL=chunk-KISL64KW.js.map
4245
- //# sourceMappingURL=chunk-KISL64KW.js.map
4593
+ export { ACCOUNT_ABI, AGENT_SESSION_KEY_VALIDATOR_ABI, AIRACCOUNT_ABI, AIRACCOUNT_ADDRESSES, AIRACCOUNT_FACTORY_ABI, AIR_ACCOUNT_COMPOSITE_VALIDATOR_ABI, AIR_ACCOUNT_DELEGATE_ABI, AIR_ACCOUNT_DELEGATE_ADDRESS, ALG_ID, AccountManager, AgentRegistryService, AirAccountServerClient, BLSSignatureService, CALLDATA_PARSER_REGISTRY_ABI, ConsoleLogger, DEFAULT_CREDENTIAL_ID, DEFAULT_KMS_ENDPOINT, DEFAULT_ORIGIN, DEFAULT_RP_ID, DvtPendingConfirmationError, EIP7702DelegateService, ENTRYPOINT_ABI_V6, ENTRYPOINT_ABI_V7_V8, ENTRYPOINT_ADDRESSES, ERC20_ABI, ERC8004Service, ERC8004_ADDRESSES, EXECUTE_BATCH_SELECTOR, EXECUTE_SELECTOR, EXECUTE_USER_OP_SELECTOR, EntryPointVersion, EthereumProvider, FACTORY_ABI_V6, FACTORY_ABI_V7_V8, FORCE_EXIT_MODULE_ABI, ForceExitService, GLOBAL_GUARD_ABI, GuardChecker, GuardStateReader, KmsAgentService, KmsHttpClient, KmsManager, KmsMonitorService, KmsPaymentSigner, KmsSessionService, KmsSigner, L2_TYPE, LocalWalletSigner, MAX_GUARDIANS, MODULE_TYPE, MemoryStorage, ModuleManager, P256PasskeySigner, PaymasterManager, PaymasterPriceStalenessError, RECOVERY_THRESHOLD, RECOVERY_TIMELOCK_SECONDS, RecoveryService, SESSION_KEY_VALIDATOR_ABI, SessionKeyService, SilentLogger, TIER_GUARD_HOOK_ABI, TokenService, TransferManager, VALIDATOR_ABI, WEIGHT_CHANGE_EXPIRY_SECONDS, WEIGHT_CHANGE_THRESHOLD, WEIGHT_CHANGE_TIMELOCK_SECONDS, WalletManager, WeightedSignatureService, YAAAServerClient, base64UrlDecode, base64UrlEncode, beginAuthenticationChallenge, beginGrantSessionChallenge, buildAuthenticationCredential, buildAuthenticatorData, buildClientDataJSON, buildInstallModuleHash, buildUninstallModuleHash, computeOapdSalt, erc8004AddressesForChain, getOapdAddress, getOapdAddressWithChainId, isExecuteUserOpWrapped, isOapdDeployed, isPendingConfirmation, packP256SessionSignature, packSecp256k1SessionSignature, runAuthenticationCeremony, runGrantSessionCeremony, runWebAuthnCeremony, sepoliaV07Config, validateConfig, wrapExecuteUserOp };
4594
+ //# sourceMappingURL=chunk-UIFMIVDK.js.map
4595
+ //# sourceMappingURL=chunk-UIFMIVDK.js.map