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