@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.
- package/dist/airaccount.d.ts +3 -3
- package/dist/airaccount.js +2 -2
- package/dist/{chunk-KISL64KW.js → chunk-UIFMIVDK.js} +967 -617
- package/dist/chunk-UIFMIVDK.js.map +1 -0
- package/dist/{chunk-FUU7RIIA.js → chunk-X3AMH53O.js} +146 -104
- package/dist/chunk-X3AMH53O.js.map +1 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.js +1 -1
- package/dist/kms.d.ts +173 -105
- package/dist/kms.js +2 -2
- package/dist/{tier-router-DLiMxs0h.d.ts → tier-router-DeeVg69O.d.ts} +60 -11
- package/package.json +1 -2
- package/dist/chunk-FUU7RIIA.js.map +0 -1
- package/dist/chunk-KISL64KW.js.map +0 -1
|
@@ -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-
|
|
2
|
-
import {
|
|
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
|
-
|
|
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 =
|
|
449
|
-
this.bundlerProvider =
|
|
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
|
|
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
|
|
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
|
|
524
|
+
return this.contractAt(address, VALIDATOR_ABI);
|
|
499
525
|
}
|
|
500
526
|
getAccountContract(address) {
|
|
501
|
-
return
|
|
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
|
|
533
|
+
return this.contractAt(address, AGENT_SESSION_KEY_VALIDATOR_ABI);
|
|
508
534
|
}
|
|
509
535
|
getTierGuardHookContract(address = AIRACCOUNT_ADDRESSES.sepolia.tierGuardHookM7r4) {
|
|
510
|
-
return
|
|
536
|
+
return this.contractAt(address, TIER_GUARD_HOOK_ABI);
|
|
511
537
|
}
|
|
512
538
|
getCompositeValidatorContract(address = AIRACCOUNT_ADDRESSES.sepolia.compositeValidatorM7r4) {
|
|
513
|
-
return
|
|
539
|
+
return this.contractAt(address, AIR_ACCOUNT_COMPOSITE_VALIDATOR_ABI);
|
|
514
540
|
}
|
|
515
541
|
getForceExitModuleContract(address) {
|
|
516
|
-
return
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
612
|
-
const baseFee = feeData.maxFeePerGas ||
|
|
613
|
-
const priorityFee = feeData.maxPriorityFeePerGas ||
|
|
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" +
|
|
623
|
-
|
|
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).
|
|
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
|
-
[
|
|
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
|
|
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.
|
|
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:
|
|
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
|
|
749
|
-
|
|
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
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
tier2,
|
|
771
|
-
|
|
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.
|
|
808
|
-
const accountAddress = await
|
|
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 =
|
|
848
|
-
|
|
849
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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,
|
|
940
|
-
const
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
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 =
|
|
959
|
-
formattedAddress,
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
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
|
|
1085
|
+
return concat([
|
|
980
1086
|
formattedAddress,
|
|
981
|
-
|
|
982
|
-
|
|
1087
|
+
numberToHex(verGas, { size: 16 }),
|
|
1088
|
+
numberToHex(postGas, { size: 16 }),
|
|
983
1089
|
operatorAddress,
|
|
984
|
-
|
|
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 =
|
|
995
|
-
formattedAddress,
|
|
996
|
-
PAYMASTER_PRICE_ABI,
|
|
997
|
-
provider
|
|
998
|
-
);
|
|
999
|
-
tokenAddress = await pmContract.token();
|
|
1000
|
-
if (tokenAddress ===
|
|
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
|
-
|
|
1011
|
-
|
|
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
|
|
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
|
|
1177
|
+
return concat([
|
|
1072
1178
|
result.result.paymaster,
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
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
|
|
1135
|
-
accountAddress,
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
);
|
|
1139
|
-
|
|
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
|
|
1216
|
-
|
|
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 =
|
|
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 :
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
-
[
|
|
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 =
|
|
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 =
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
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 =
|
|
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 =
|
|
1472
|
-
tokenAddress,
|
|
1473
|
-
0,
|
|
1474
|
-
transferCalldata
|
|
1475
|
-
]);
|
|
1584
|
+
callData = encodeFn(AIRACCOUNT_ABI_PARSED, "execute", [tokenAddress, 0n, transferCalldata]);
|
|
1476
1585
|
} else {
|
|
1477
|
-
callData =
|
|
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
|
|
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
|
|
1763
|
-
|
|
1764
|
-
|
|
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
|
|
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
|
-
|
|
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(
|
|
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
|
|
1837
|
-
const
|
|
1950
|
+
const client = this.ethereum.getProvider();
|
|
1951
|
+
const address = tokenAddress;
|
|
1838
1952
|
const [name, symbol, decimals] = await Promise.all([
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
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
|
|
1852
|
-
const contract = new ethers.Contract(tokenAddress, ERC20_ABI, provider);
|
|
1965
|
+
const client = this.ethereum.getProvider();
|
|
1853
1966
|
try {
|
|
1854
|
-
const balance = await
|
|
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 =
|
|
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
|
|
1868
|
-
|
|
1869
|
-
|
|
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
|
|
1874
|
-
const
|
|
1994
|
+
const client = this.ethereum.getProvider();
|
|
1995
|
+
const address = tokenAddress;
|
|
1875
1996
|
const [name, symbol, decimals] = await Promise.race([
|
|
1876
|
-
Promise.all([
|
|
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
|
|
1906
|
-
return this.signer.
|
|
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
|
|
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 =
|
|
1951
|
-
const raw =
|
|
1952
|
-
|
|
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
|
|
2105
|
+
return hashMessage(hexToBytes(raw));
|
|
1958
2106
|
}
|
|
1959
2107
|
function buildUninstallModuleHash(chainId, account, moduleTypeId, module) {
|
|
1960
|
-
const raw =
|
|
1961
|
-
|
|
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
|
|
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 ?
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
params.module,
|
|
1987
|
-
|
|
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 =
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
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
|
-
|
|
2011
|
-
|
|
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 ??
|
|
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
|
|
2211
|
+
const expiry = Number(s.expiry);
|
|
2060
2212
|
const now = Math.floor(Date.now() / 1e3);
|
|
2061
2213
|
return {
|
|
2062
2214
|
expiry,
|
|
2063
|
-
contractScope: s
|
|
2064
|
-
selectorScope: s
|
|
2065
|
-
revoked: s
|
|
2066
|
-
velocityLimit: Number(s
|
|
2067
|
-
velocityWindow: Number(s
|
|
2068
|
-
callTargets: [...s
|
|
2069
|
-
selectorAllowlist: [...s
|
|
2070
|
-
active: expiry > now && !s
|
|
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.
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
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
|
|
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
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
cfg,
|
|
2132
|
-
|
|
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
|
|
2136
|
-
|
|
2137
|
-
|
|
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
|
-
|
|
2144
|
-
|
|
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
|
|
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
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
params.keyY,
|
|
2193
|
-
|
|
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
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
params.keyY,
|
|
2201
|
-
|
|
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
|
-
|
|
2207
|
-
|
|
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
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
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
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
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
|
-
|
|
2253
|
-
|
|
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 =
|
|
2324
|
-
const guardAddress = await account.guard();
|
|
2325
|
-
if (guardAddress ===
|
|
2326
|
-
const guard =
|
|
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(
|
|
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 =
|
|
2352
|
-
const guardAddress = await account.guard();
|
|
2353
|
-
if (guardAddress ===
|
|
2354
|
-
const guard =
|
|
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 =
|
|
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 =
|
|
2397
|
-
return BigInt(
|
|
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
|
|
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
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
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
|
|
2439
|
-
|
|
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
|
|
2454
|
-
const
|
|
2455
|
-
|
|
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:
|
|
2634
|
+
guardAddress: zeroAddress,
|
|
2461
2635
|
dailyLimit: 0n,
|
|
2462
2636
|
dailyRemaining: 0n
|
|
2463
2637
|
};
|
|
2464
2638
|
}
|
|
2465
|
-
const guard =
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
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
|
|
2474
|
-
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
|
|
2496
|
-
const
|
|
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,
|
|
2718
|
+
constructor(moduleAddress, client) {
|
|
2544
2719
|
this.moduleAddress = moduleAddress;
|
|
2545
|
-
this.contract =
|
|
2546
|
-
|
|
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
|
|
2586
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
2800
|
+
return encodeFunctionData({
|
|
2801
|
+
abi: FORCE_EXIT_PARSED_ABI,
|
|
2802
|
+
functionName: "executeForceExit",
|
|
2803
|
+
args: [account]
|
|
2804
|
+
});
|
|
2608
2805
|
}
|
|
2609
2806
|
encodeCancelForceExit(account) {
|
|
2610
|
-
return
|
|
2807
|
+
return encodeFunctionData({
|
|
2808
|
+
abi: FORCE_EXIT_PARSED_ABI,
|
|
2809
|
+
functionName: "cancelForceExit",
|
|
2810
|
+
args: [account]
|
|
2811
|
+
});
|
|
2611
2812
|
}
|
|
2612
|
-
// ── Convenience: send transactions (requires
|
|
2813
|
+
// ── Convenience: send transactions (requires a WalletClient) ──────────
|
|
2613
2814
|
async proposeForceExit(target, value, data) {
|
|
2614
|
-
return this.contract.proposeForceExit(
|
|
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(
|
|
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
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
2705
|
-
|
|
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 !==
|
|
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
|
|
2727
|
-
|
|
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
|
|
2741
|
-
|
|
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
|
|
2745
|
-
|
|
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,
|
|
3026
|
+
constructor(delegateAddress = AIR_ACCOUNT_DELEGATE_ADDRESS, client) {
|
|
2774
3027
|
this.delegateAddress = delegateAddress;
|
|
2775
|
-
this.
|
|
2776
|
-
|
|
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
|
-
|
|
2783
|
-
|
|
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
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
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
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
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
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
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
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
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,
|
|
3198
|
+
constructor(accountAddress, client) {
|
|
2928
3199
|
this.accountAddress = accountAddress;
|
|
2929
|
-
this.
|
|
2930
|
-
this.
|
|
3200
|
+
this.client = client;
|
|
3201
|
+
this.address = accountAddress;
|
|
2931
3202
|
}
|
|
2932
|
-
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
3010
|
-
* @param registryAddress
|
|
3307
|
+
* @param client viem PublicClient for on-chain reads (e.g. `ethereum.getProvider()`).
|
|
3308
|
+
* @param registryAddress deployed AgentRegistry contract address.
|
|
3011
3309
|
*/
|
|
3012
|
-
constructor(
|
|
3310
|
+
constructor(client, registryAddress) {
|
|
3013
3311
|
this.registryAddress = registryAddress;
|
|
3014
|
-
this.
|
|
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
|
-
|
|
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
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
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
|
|
3040
|
-
|
|
3041
|
-
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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(
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
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
|
|
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
|
-
|
|
3152
|
-
factoryAddress,
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
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
|
-
|
|
3161
|
-
factoryAddress,
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
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
|
-
|
|
3557
|
+
abi;
|
|
3197
3558
|
provider;
|
|
3198
3559
|
constructor(provider) {
|
|
3199
|
-
this.
|
|
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
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
params.agentRegistry,
|
|
3219
|
-
|
|
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
|
|
3234
|
-
|
|
3235
|
-
|
|
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
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
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
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
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 =
|
|
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
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
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 =
|
|
3312
|
-
|
|
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
|
|
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" ?
|
|
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(
|
|
3479
|
-
return
|
|
3865
|
+
function beginAuthenticationChallenge(http2, keyId) {
|
|
3866
|
+
return http2.post("/BeginAuthentication", { KeyId: keyId });
|
|
3480
3867
|
}
|
|
3481
|
-
function beginGrantSessionChallenge(
|
|
3482
|
-
return
|
|
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(
|
|
3487
|
-
return runWebAuthnCeremony(() => beginAuthenticationChallenge(
|
|
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(
|
|
3493
|
-
return runWebAuthnCeremony(() => beginGrantSessionChallenge(
|
|
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
|
|
4181
|
+
createKmsSigner(keyId, address, assertionProvider) {
|
|
3795
4182
|
this.ensureEnabled();
|
|
3796
|
-
return new KmsSigner(keyId, address, this, assertionProvider
|
|
4183
|
+
return new KmsSigner(keyId, address, this, assertionProvider);
|
|
3797
4184
|
}
|
|
3798
4185
|
};
|
|
3799
|
-
var KmsSigner = class
|
|
3800
|
-
constructor(keyId, _address, kmsManager, assertionProvider
|
|
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
|
|
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(
|
|
3859
|
-
this.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(
|
|
3950
|
-
this.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(
|
|
4027
|
-
this.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(
|
|
4070
|
-
this.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
|
-
|
|
4224
|
-
constructor(privateKey
|
|
4225
|
-
this.
|
|
4573
|
+
account;
|
|
4574
|
+
constructor(privateKey) {
|
|
4575
|
+
this.account = privateKeyToAccount(privateKey);
|
|
4226
4576
|
}
|
|
4227
4577
|
async getAddress(_userId) {
|
|
4228
|
-
return this.
|
|
4578
|
+
return this.account.address;
|
|
4229
4579
|
}
|
|
4230
|
-
async
|
|
4231
|
-
return this.
|
|
4580
|
+
async signMessage(_userId, message, _ctx) {
|
|
4581
|
+
return this.account.signMessage({ message: { raw: message } });
|
|
4232
4582
|
}
|
|
4233
4583
|
async ensureSigner(_userId) {
|
|
4234
|
-
return {
|
|
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-
|
|
4245
|
-
//# sourceMappingURL=chunk-
|
|
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
|