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