arc402-cli 0.9.19 → 0.10.0
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/README.md +41 -2
- package/dist/abis.d.ts +1 -0
- package/dist/abis.d.ts.map +1 -1
- package/dist/abis.js +45 -14
- package/dist/abis.js.map +1 -1
- package/dist/bundler.d.ts +1 -1
- package/dist/bundler.d.ts.map +1 -1
- package/dist/bundler.js +61 -27
- package/dist/bundler.js.map +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +9 -5
- package/dist/client.js.map +1 -1
- package/dist/coinbase-smart-wallet.js +4 -1
- package/dist/coinbase-smart-wallet.js.map +1 -1
- package/dist/commands/accept.js +28 -25
- package/dist/commands/accept.js.map +1 -1
- package/dist/commands/agent-handshake.js +18 -15
- package/dist/commands/agent-handshake.js.map +1 -1
- package/dist/commands/agent.js +104 -98
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/agreements.js +98 -62
- package/dist/commands/agreements.js.map +1 -1
- package/dist/commands/arbitrator.js +81 -45
- package/dist/commands/arbitrator.js.map +1 -1
- package/dist/commands/arena-handshake.d.ts.map +1 -1
- package/dist/commands/arena-handshake.js +35 -53
- package/dist/commands/arena-handshake.js.map +1 -1
- package/dist/commands/arena.js +18 -12
- package/dist/commands/arena.js.map +1 -1
- package/dist/commands/backup.js +36 -30
- package/dist/commands/backup.js.map +1 -1
- package/dist/commands/cancel.js +18 -15
- package/dist/commands/cancel.js.map +1 -1
- package/dist/commands/channel.js +81 -45
- package/dist/commands/channel.js.map +1 -1
- package/dist/commands/coldstart.js +34 -31
- package/dist/commands/coldstart.js.map +1 -1
- package/dist/commands/compute.d.ts +14 -0
- package/dist/commands/compute.d.ts.map +1 -0
- package/dist/commands/compute.js +466 -0
- package/dist/commands/compute.js.map +1 -0
- package/dist/commands/config.js +30 -24
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/contract-interaction.js +15 -12
- package/dist/commands/contract-interaction.js.map +1 -1
- package/dist/commands/daemon.d.ts.map +1 -1
- package/dist/commands/daemon.js +135 -98
- package/dist/commands/daemon.js.map +1 -1
- package/dist/commands/deliver.js +76 -37
- package/dist/commands/deliver.js.map +1 -1
- package/dist/commands/discover.js +27 -24
- package/dist/commands/discover.js.map +1 -1
- package/dist/commands/dispute.js +110 -104
- package/dist/commands/dispute.js.map +1 -1
- package/dist/commands/doctor.js +55 -16
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/endpoint.js +95 -56
- package/dist/commands/endpoint.js.map +1 -1
- package/dist/commands/feed.js +18 -11
- package/dist/commands/feed.js.map +1 -1
- package/dist/commands/hire.js +40 -37
- package/dist/commands/hire.js.map +1 -1
- package/dist/commands/migrate.js +33 -30
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/negotiate.d.ts.map +1 -1
- package/dist/commands/negotiate.js +36 -34
- package/dist/commands/negotiate.js.map +1 -1
- package/dist/commands/openshell.js +104 -68
- package/dist/commands/openshell.js.map +1 -1
- package/dist/commands/owner.js +20 -17
- package/dist/commands/owner.js.map +1 -1
- package/dist/commands/policy.js +43 -41
- package/dist/commands/policy.js.map +1 -1
- package/dist/commands/relay.d.ts.map +1 -1
- package/dist/commands/relay.js +51 -18
- package/dist/commands/relay.js.map +1 -1
- package/dist/commands/remediate.js +23 -20
- package/dist/commands/remediate.js.map +1 -1
- package/dist/commands/reputation.js +27 -25
- package/dist/commands/reputation.js.map +1 -1
- package/dist/commands/setup.js +104 -65
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/trust.js +20 -17
- package/dist/commands/trust.js.map +1 -1
- package/dist/commands/verify.js +21 -18
- package/dist/commands/verify.js.map +1 -1
- package/dist/commands/wallet.d.ts.map +1 -1
- package/dist/commands/wallet.js +645 -679
- package/dist/commands/wallet.js.map +1 -1
- package/dist/commands/watch.js +36 -33
- package/dist/commands/watch.js.map +1 -1
- package/dist/commands/watchtower.js +73 -37
- package/dist/commands/watchtower.js.map +1 -1
- package/dist/commands/workroom.d.ts.map +1 -1
- package/dist/commands/workroom.js +282 -143
- package/dist/commands/workroom.js.map +1 -1
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +71 -22
- package/dist/config.js.map +1 -1
- package/dist/daemon/compute-metering.d.ts +61 -0
- package/dist/daemon/compute-metering.d.ts.map +1 -0
- package/dist/daemon/compute-metering.js +299 -0
- package/dist/daemon/compute-metering.js.map +1 -0
- package/dist/daemon/compute-session.d.ts +100 -0
- package/dist/daemon/compute-session.d.ts.map +1 -0
- package/dist/daemon/compute-session.js +231 -0
- package/dist/daemon/compute-session.js.map +1 -0
- package/dist/daemon/config.d.ts +19 -1
- package/dist/daemon/config.d.ts.map +1 -1
- package/dist/daemon/config.js +90 -16
- package/dist/daemon/config.js.map +1 -1
- package/dist/daemon/credentials.d.ts +24 -0
- package/dist/daemon/credentials.d.ts.map +1 -0
- package/dist/daemon/credentials.js +80 -0
- package/dist/daemon/credentials.js.map +1 -0
- package/dist/daemon/delivery-client.d.ts +35 -0
- package/dist/daemon/delivery-client.d.ts.map +1 -0
- package/dist/daemon/delivery-client.js +231 -0
- package/dist/daemon/delivery-client.js.map +1 -0
- package/dist/daemon/file-delivery.d.ts +98 -0
- package/dist/daemon/file-delivery.d.ts.map +1 -0
- package/dist/daemon/file-delivery.js +461 -0
- package/dist/daemon/file-delivery.js.map +1 -0
- package/dist/daemon/hire-listener.d.ts +3 -3
- package/dist/daemon/hire-listener.d.ts.map +1 -1
- package/dist/daemon/hire-listener.js +47 -13
- package/dist/daemon/hire-listener.js.map +1 -1
- package/dist/daemon/index.d.ts +2 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +526 -53
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/job-lifecycle.d.ts +1 -1
- package/dist/daemon/job-lifecycle.d.ts.map +1 -1
- package/dist/daemon/job-lifecycle.js +51 -11
- package/dist/daemon/job-lifecycle.js.map +1 -1
- package/dist/daemon/notify.d.ts +1 -1
- package/dist/daemon/notify.d.ts.map +1 -1
- package/dist/daemon/notify.js +53 -19
- package/dist/daemon/notify.js.map +1 -1
- package/dist/daemon/token-metering.js +47 -8
- package/dist/daemon/token-metering.js.map +1 -1
- package/dist/daemon/userops.d.ts +2 -2
- package/dist/daemon/userops.d.ts.map +1 -1
- package/dist/daemon/userops.js +27 -23
- package/dist/daemon/userops.js.map +1 -1
- package/dist/daemon/wallet-monitor.d.ts +1 -1
- package/dist/daemon/wallet-monitor.d.ts.map +1 -1
- package/dist/daemon/wallet-monitor.js +12 -8
- package/dist/daemon/wallet-monitor.js.map +1 -1
- package/dist/daemon/worker-executor.d.ts +71 -0
- package/dist/daemon/worker-executor.d.ts.map +1 -0
- package/dist/daemon/worker-executor.js +382 -0
- package/dist/daemon/worker-executor.js.map +1 -0
- package/dist/drain-v4.js +64 -26
- package/dist/drain-v4.js.map +1 -1
- package/dist/endpoint-config.js +63 -20
- package/dist/endpoint-config.js.map +1 -1
- package/dist/endpoint-notify.d.ts.map +1 -1
- package/dist/endpoint-notify.js +49 -15
- package/dist/endpoint-notify.js.map +1 -1
- package/dist/index.js +50 -18
- package/dist/index.js.map +1 -1
- package/dist/openshell-runtime.d.ts.map +1 -1
- package/dist/openshell-runtime.js +82 -38
- package/dist/openshell-runtime.js.map +1 -1
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +85 -78
- package/dist/program.js.map +1 -1
- package/dist/repl.js +31 -25
- package/dist/repl.js.map +1 -1
- package/dist/signing.js +6 -3
- package/dist/signing.js.map +1 -1
- package/dist/telegram-notify.js +40 -3
- package/dist/telegram-notify.js.map +1 -1
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +56 -89
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/Footer.js +7 -4
- package/dist/tui/Footer.js.map +1 -1
- package/dist/tui/Header.d.ts +1 -1
- package/dist/tui/Header.d.ts.map +1 -1
- package/dist/tui/Header.js +14 -9
- package/dist/tui/Header.js.map +1 -1
- package/dist/tui/InputLine.d.ts +2 -1
- package/dist/tui/InputLine.d.ts.map +1 -1
- package/dist/tui/InputLine.js +47 -97
- package/dist/tui/InputLine.js.map +1 -1
- package/dist/tui/Viewport.d.ts +1 -2
- package/dist/tui/Viewport.d.ts.map +1 -1
- package/dist/tui/Viewport.js +26 -6
- package/dist/tui/Viewport.js.map +1 -1
- package/dist/tui/WalletConnectPairing.js +19 -16
- package/dist/tui/WalletConnectPairing.js.map +1 -1
- package/dist/tui/components/Button.js +9 -6
- package/dist/tui/components/Button.js.map +1 -1
- package/dist/tui/components/CeremonyView.js +8 -5
- package/dist/tui/components/CeremonyView.js.map +1 -1
- package/dist/tui/components/CompletionDropdown.js +9 -6
- package/dist/tui/components/CompletionDropdown.js.map +1 -1
- package/dist/tui/components/ConfirmPrompt.js +8 -5
- package/dist/tui/components/ConfirmPrompt.js.map +1 -1
- package/dist/tui/components/CustomTextInput.js +14 -11
- package/dist/tui/components/CustomTextInput.js.map +1 -1
- package/dist/tui/components/InteractiveTable.js +12 -9
- package/dist/tui/components/InteractiveTable.js.map +1 -1
- package/dist/tui/components/StepSpinner.js +13 -10
- package/dist/tui/components/StepSpinner.js.map +1 -1
- package/dist/tui/components/Toast.js +12 -8
- package/dist/tui/components/Toast.js.map +1 -1
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +21 -28
- package/dist/tui/index.js.map +1 -1
- package/dist/tui/useChat.js +19 -13
- package/dist/tui/useChat.js.map +1 -1
- package/dist/tui/useCommand.d.ts +2 -3
- package/dist/tui/useCommand.d.ts.map +1 -1
- package/dist/tui/useCommand.js +24 -100
- package/dist/tui/useCommand.js.map +1 -1
- package/dist/tui/useNotifications.js +8 -5
- package/dist/tui/useNotifications.js.map +1 -1
- package/dist/tui/useScroll.d.ts.map +1 -1
- package/dist/tui/useScroll.js +12 -15
- package/dist/tui/useScroll.js.map +1 -1
- package/dist/ui/banner.d.ts +0 -12
- package/dist/ui/banner.d.ts.map +1 -1
- package/dist/ui/banner.js +19 -35
- package/dist/ui/banner.js.map +1 -1
- package/dist/ui/colors.js +19 -13
- package/dist/ui/colors.js.map +1 -1
- package/dist/ui/format.js +14 -6
- package/dist/ui/format.js.map +1 -1
- package/dist/ui/qr-render.js +11 -4
- package/dist/ui/qr-render.js.map +1 -1
- package/dist/ui/rpc-fallback.js +11 -6
- package/dist/ui/rpc-fallback.js.map +1 -1
- package/dist/ui/spinner.js +12 -6
- package/dist/ui/spinner.js.map +1 -1
- package/dist/ui/tree.js +6 -3
- package/dist/ui/tree.js.map +1 -1
- package/dist/utils/format.js +41 -27
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/hash.js +42 -4
- package/dist/utils/hash.js.map +1 -1
- package/dist/utils/time.js +6 -2
- package/dist/utils/time.js.map +1 -1
- package/dist/wallet-router.d.ts +1 -1
- package/dist/wallet-router.d.ts.map +1 -1
- package/dist/wallet-router.js +19 -12
- package/dist/wallet-router.js.map +1 -1
- package/dist/walletconnect-session.d.ts +1 -1
- package/dist/walletconnect-session.d.ts.map +1 -1
- package/dist/walletconnect-session.js +11 -6
- package/dist/walletconnect-session.js.map +1 -1
- package/dist/walletconnect.d.ts +5 -6
- package/dist/walletconnect.d.ts.map +1 -1
- package/dist/walletconnect.js +35 -32
- package/dist/walletconnect.js.map +1 -1
- package/package.json +11 -10
- package/INK6-UX-SPEC.md +0 -446
- package/MIGRATION-SPEC.md +0 -108
- package/TUI-SPEC.md +0 -214
- package/scripts/authorize-machine-key.ts +0 -43
- package/scripts/drain-wallet.ts +0 -149
- package/scripts/execute-spend-only.ts +0 -81
- package/scripts/register-agent-userop.ts +0 -186
- package/src/abis.ts +0 -187
- package/src/bundler.ts +0 -235
- package/src/client.ts +0 -36
- package/src/coinbase-smart-wallet.ts +0 -51
- package/src/commands/accept.ts +0 -64
- package/src/commands/agent-handshake.ts +0 -72
- package/src/commands/agent.ts +0 -691
- package/src/commands/agreements.ts +0 -350
- package/src/commands/arbitrator.ts +0 -180
- package/src/commands/arena-handshake.ts +0 -274
- package/src/commands/arena.ts +0 -122
- package/src/commands/backup.ts +0 -117
- package/src/commands/cancel.ts +0 -35
- package/src/commands/channel.ts +0 -218
- package/src/commands/coldstart.ts +0 -165
- package/src/commands/config.ts +0 -68
- package/src/commands/contract-interaction.ts +0 -166
- package/src/commands/daemon.ts +0 -1054
- package/src/commands/deliver.ts +0 -148
- package/src/commands/discover.ts +0 -350
- package/src/commands/dispute.ts +0 -375
- package/src/commands/doctor.ts +0 -172
- package/src/commands/endpoint.ts +0 -620
- package/src/commands/feed.ts +0 -229
- package/src/commands/hire.ts +0 -245
- package/src/commands/migrate.ts +0 -177
- package/src/commands/negotiate.ts +0 -272
- package/src/commands/openshell.ts +0 -1055
- package/src/commands/owner.ts +0 -35
- package/src/commands/policy.ts +0 -263
- package/src/commands/relay.ts +0 -277
- package/src/commands/remediate.ts +0 -24
- package/src/commands/reputation.ts +0 -79
- package/src/commands/setup.ts +0 -343
- package/src/commands/trust.ts +0 -27
- package/src/commands/verify.ts +0 -91
- package/src/commands/wallet.ts +0 -3548
- package/src/commands/watch.ts +0 -220
- package/src/commands/watchtower.ts +0 -248
- package/src/commands/workroom.ts +0 -963
- package/src/config.ts +0 -220
- package/src/daemon/config.ts +0 -344
- package/src/daemon/hire-listener.ts +0 -226
- package/src/daemon/index.ts +0 -1089
- package/src/daemon/job-lifecycle.ts +0 -215
- package/src/daemon/notify.ts +0 -297
- package/src/daemon/token-metering.ts +0 -183
- package/src/daemon/userops.ts +0 -119
- package/src/daemon/wallet-monitor.ts +0 -90
- package/src/drain-v4.ts +0 -159
- package/src/endpoint-config.ts +0 -83
- package/src/endpoint-notify.ts +0 -134
- package/src/index.ts +0 -74
- package/src/openshell-runtime.ts +0 -281
- package/src/program.ts +0 -88
- package/src/repl.ts +0 -178
- package/src/signing.ts +0 -28
- package/src/telegram-notify.ts +0 -88
- package/src/tui/App.tsx +0 -263
- package/src/tui/Footer.tsx +0 -18
- package/src/tui/Header.tsx +0 -45
- package/src/tui/InputLine.tsx +0 -243
- package/src/tui/Viewport.tsx +0 -51
- package/src/tui/WalletConnectPairing.tsx +0 -114
- package/src/tui/components/Button.tsx +0 -38
- package/src/tui/components/CeremonyView.tsx +0 -39
- package/src/tui/components/CompletionDropdown.tsx +0 -56
- package/src/tui/components/ConfirmPrompt.tsx +0 -36
- package/src/tui/components/CustomTextInput.tsx +0 -132
- package/src/tui/components/InteractiveTable.tsx +0 -106
- package/src/tui/components/StepSpinner.tsx +0 -84
- package/src/tui/components/Toast.tsx +0 -59
- package/src/tui/index.tsx +0 -90
- package/src/tui/useChat.ts +0 -103
- package/src/tui/useCommand.ts +0 -238
- package/src/tui/useNotifications.ts +0 -28
- package/src/tui/useScroll.ts +0 -69
- package/src/ui/banner.ts +0 -78
- package/src/ui/colors.ts +0 -30
- package/src/ui/format.ts +0 -78
- package/src/ui/qr-render.ts +0 -92
- package/src/ui/rpc-fallback.ts +0 -59
- package/src/ui/spinner.ts +0 -56
- package/src/ui/tree.ts +0 -16
- package/src/utils/format.ts +0 -48
- package/src/utils/hash.ts +0 -5
- package/src/utils/time.ts +0 -15
- package/src/wallet-router.ts +0 -178
- package/src/walletconnect-session.ts +0 -27
- package/src/walletconnect.ts +0 -309
- package/test/time.test.js +0 -11
- package/tsconfig.json +0 -33
package/dist/commands/wallet.js
CHANGED
|
@@ -1,36 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
const
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.registerWalletCommands = registerWalletCommands;
|
|
7
|
+
const sdk_1 = require("@arc402/sdk");
|
|
8
|
+
const ethers_1 = require("ethers");
|
|
9
|
+
const prompts_1 = __importDefault(require("prompts"));
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const os_1 = __importDefault(require("os"));
|
|
13
|
+
const child_process_1 = require("child_process");
|
|
14
|
+
const config_1 = require("../config");
|
|
15
|
+
const client_1 = require("../client");
|
|
16
|
+
const format_1 = require("../utils/format");
|
|
17
|
+
const abis_1 = require("../abis");
|
|
18
|
+
const config_2 = require("../config");
|
|
19
|
+
const walletconnect_1 = require("../walletconnect");
|
|
20
|
+
const bundler_1 = require("../bundler");
|
|
21
|
+
const walletconnect_session_1 = require("../walletconnect-session");
|
|
22
|
+
const wallet_router_1 = require("../wallet-router");
|
|
23
|
+
const coinbase_smart_wallet_1 = require("../coinbase-smart-wallet");
|
|
24
|
+
const telegram_notify_1 = require("../telegram-notify");
|
|
25
|
+
const tree_1 = require("../ui/tree");
|
|
26
|
+
const spinner_1 = require("../ui/spinner");
|
|
27
|
+
const colors_1 = require("../ui/colors");
|
|
28
|
+
const POLICY_ENGINE_DEFAULT = "0x44102e70c2A366632d98Fe40d892a2501fC7fFF2";
|
|
29
|
+
const GUARDIAN_KEY_PATH = path_1.default.join(os_1.default.homedir(), ".arc402", "guardian.key");
|
|
25
30
|
/** Save guardian private key to a restricted standalone file (never to config.json). */
|
|
26
31
|
function saveGuardianKey(privateKey) {
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
fs_1.default.mkdirSync(path_1.default.dirname(GUARDIAN_KEY_PATH), { recursive: true, mode: 0o700 });
|
|
33
|
+
fs_1.default.writeFileSync(GUARDIAN_KEY_PATH, privateKey + "\n", { mode: 0o400 });
|
|
29
34
|
}
|
|
30
35
|
/** Load guardian private key from file, falling back to config for backwards compat. */
|
|
31
36
|
function loadGuardianKey(config) {
|
|
32
37
|
try {
|
|
33
|
-
return
|
|
38
|
+
return fs_1.default.readFileSync(GUARDIAN_KEY_PATH, "utf-8").trim();
|
|
34
39
|
}
|
|
35
40
|
catch {
|
|
36
41
|
// Migration: if key still in config, migrate it to the file now
|
|
@@ -44,7 +49,7 @@ function loadGuardianKey(config) {
|
|
|
44
49
|
function parseAmount(raw) {
|
|
45
50
|
const lower = raw.toLowerCase();
|
|
46
51
|
if (lower.endsWith("eth")) {
|
|
47
|
-
return ethers.parseEther(lower.slice(0, -3).trim());
|
|
52
|
+
return ethers_1.ethers.parseEther(lower.slice(0, -3).trim());
|
|
48
53
|
}
|
|
49
54
|
return BigInt(raw);
|
|
50
55
|
}
|
|
@@ -63,25 +68,25 @@ const ONBOARDING_CATEGORIES = [
|
|
|
63
68
|
*/
|
|
64
69
|
async function runWalletOnboardingCeremony(walletAddress, ownerAddress, config, provider, sendTx) {
|
|
65
70
|
const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
|
|
66
|
-
const executeIface = new ethers.Interface(ARC402_WALLET_EXECUTE_ABI);
|
|
67
|
-
const govIface = new ethers.Interface(POLICY_ENGINE_GOVERNANCE_ABI);
|
|
68
|
-
const limitsIface = new ethers.Interface(POLICY_ENGINE_LIMITS_ABI);
|
|
69
|
-
const policyGov = new ethers.Contract(policyAddress, POLICY_ENGINE_GOVERNANCE_ABI, provider);
|
|
71
|
+
const executeIface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_EXECUTE_ABI);
|
|
72
|
+
const govIface = new ethers_1.ethers.Interface(abis_1.POLICY_ENGINE_GOVERNANCE_ABI);
|
|
73
|
+
const limitsIface = new ethers_1.ethers.Interface(abis_1.POLICY_ENGINE_LIMITS_ABI);
|
|
74
|
+
const policyGov = new ethers_1.ethers.Contract(policyAddress, abis_1.POLICY_ENGINE_GOVERNANCE_ABI, provider);
|
|
70
75
|
// Check what's already done (constructor may have done registerWallet + enableDefiAccess)
|
|
71
76
|
let alreadyRegistered = false;
|
|
72
77
|
let alreadyDefiEnabled = false;
|
|
73
78
|
try {
|
|
74
79
|
const registeredOwner = await policyGov.walletOwners(walletAddress);
|
|
75
|
-
alreadyRegistered = registeredOwner !== ethers.ZeroAddress;
|
|
80
|
+
alreadyRegistered = registeredOwner !== ethers_1.ethers.ZeroAddress;
|
|
76
81
|
}
|
|
77
82
|
catch { /* older PolicyEngine without this getter — assume not registered */ }
|
|
78
83
|
try {
|
|
79
84
|
alreadyDefiEnabled = await policyGov.defiAccessEnabled(walletAddress);
|
|
80
85
|
}
|
|
81
86
|
catch { /* assume not enabled */ }
|
|
82
|
-
console.log("\n" + c.dim("── Onboarding ceremony ────────────────────────────────────────"));
|
|
83
|
-
console.log(" " + c.dim("PolicyEngine:") + " " + c.white(policyAddress));
|
|
84
|
-
console.log(" " + c.dim("Wallet: ") + " " + c.white(walletAddress));
|
|
87
|
+
console.log("\n" + colors_1.c.dim("── Onboarding ceremony ────────────────────────────────────────"));
|
|
88
|
+
console.log(" " + colors_1.c.dim("PolicyEngine:") + " " + colors_1.c.white(policyAddress));
|
|
89
|
+
console.log(" " + colors_1.c.dim("Wallet: ") + " " + colors_1.c.white(walletAddress));
|
|
85
90
|
// Step 1: registerWallet (if not already done)
|
|
86
91
|
if (!alreadyRegistered) {
|
|
87
92
|
const registerCalldata = govIface.encodeFunctionData("registerWallet", [walletAddress, ownerAddress]);
|
|
@@ -93,13 +98,13 @@ async function runWalletOnboardingCeremony(walletAddress, ownerAddress, config,
|
|
|
93
98
|
value: 0n,
|
|
94
99
|
minReturnValue: 0n,
|
|
95
100
|
maxApprovalAmount: 0n,
|
|
96
|
-
approvalToken: ethers.ZeroAddress,
|
|
101
|
+
approvalToken: ethers_1.ethers.ZeroAddress,
|
|
97
102
|
}]),
|
|
98
103
|
value: "0x0",
|
|
99
104
|
}, "registerWallet on PolicyEngine");
|
|
100
105
|
}
|
|
101
106
|
else {
|
|
102
|
-
console.log(" " + c.success + c.dim(" registerWallet — already done by constructor"));
|
|
107
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(" registerWallet — already done by constructor"));
|
|
103
108
|
}
|
|
104
109
|
// Step 2: enableDefiAccess (if not already done)
|
|
105
110
|
if (!alreadyDefiEnabled) {
|
|
@@ -110,7 +115,7 @@ async function runWalletOnboardingCeremony(walletAddress, ownerAddress, config,
|
|
|
110
115
|
}, "enableDefiAccess on PolicyEngine");
|
|
111
116
|
}
|
|
112
117
|
else {
|
|
113
|
-
console.log(" " + c.success + c.dim(" enableDefiAccess — already done by constructor"));
|
|
118
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(" enableDefiAccess — already done by constructor"));
|
|
114
119
|
}
|
|
115
120
|
// Steps 3–6: category limits (always set — idempotent)
|
|
116
121
|
for (const { name, amountEth } of ONBOARDING_CATEGORIES) {
|
|
@@ -119,15 +124,15 @@ async function runWalletOnboardingCeremony(walletAddress, ownerAddress, config,
|
|
|
119
124
|
data: limitsIface.encodeFunctionData("setCategoryLimitFor", [
|
|
120
125
|
walletAddress,
|
|
121
126
|
name,
|
|
122
|
-
ethers.parseEther(amountEth),
|
|
127
|
+
ethers_1.ethers.parseEther(amountEth),
|
|
123
128
|
]),
|
|
124
129
|
value: "0x0",
|
|
125
130
|
}, `setCategoryLimitFor: ${name} → ${amountEth} ETH`);
|
|
126
131
|
}
|
|
127
|
-
console.log(c.dim("── Onboarding complete ─────────────────────────────────────────"));
|
|
128
|
-
console.log(c.dim("Tip: For production security, also configure:"));
|
|
129
|
-
console.log(" " + c.dim("arc402 wallet set-velocity-limit <eth> — wallet-level hourly ETH cap"));
|
|
130
|
-
console.log(" " + c.dim("arc402 wallet policy set-daily-limit --category general --amount <eth> — daily per-category cap"));
|
|
132
|
+
console.log(colors_1.c.dim("── Onboarding complete ─────────────────────────────────────────"));
|
|
133
|
+
console.log(colors_1.c.dim("Tip: For production security, also configure:"));
|
|
134
|
+
console.log(" " + colors_1.c.dim("arc402 wallet set-velocity-limit <eth> — wallet-level hourly ETH cap"));
|
|
135
|
+
console.log(" " + colors_1.c.dim("arc402 wallet policy set-daily-limit --category general --amount <eth> — daily per-category cap"));
|
|
131
136
|
}
|
|
132
137
|
/**
|
|
133
138
|
* Complete ARC-402 onboarding ceremony — matches web flow at app.arc402.xyz/onboard.
|
|
@@ -143,116 +148,116 @@ async function runWalletOnboardingCeremony(walletAddress, ownerAddress, config,
|
|
|
143
148
|
async function runCompleteOnboardingCeremony(walletAddress, ownerAddress, config, provider, sendTx) {
|
|
144
149
|
const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
|
|
145
150
|
const agentRegistryAddress = config.agentRegistryV2Address ??
|
|
146
|
-
NETWORK_DEFAULTS[config.network]?.agentRegistryV2Address;
|
|
151
|
+
config_1.NETWORK_DEFAULTS[config.network]?.agentRegistryV2Address;
|
|
147
152
|
const handshakeAddress = config.handshakeAddress ??
|
|
148
|
-
NETWORK_DEFAULTS[config.network]?.handshakeAddress ??
|
|
153
|
+
config_1.NETWORK_DEFAULTS[config.network]?.handshakeAddress ??
|
|
149
154
|
"0x4F5A38Bb746d7E5d49d8fd26CA6beD141Ec2DDb3";
|
|
150
155
|
// ── Step 2: Machine Key ────────────────────────────────────────────────────
|
|
151
|
-
console.log("\n" + c.dim("── Step 2: Machine Key ────────────────────────────────────────"));
|
|
156
|
+
console.log("\n" + colors_1.c.dim("── Step 2: Machine Key ────────────────────────────────────────"));
|
|
152
157
|
let machineKeyAddress;
|
|
153
158
|
if (config.privateKey) {
|
|
154
|
-
machineKeyAddress = new ethers.Wallet(config.privateKey).address;
|
|
159
|
+
machineKeyAddress = new ethers_1.ethers.Wallet(config.privateKey).address;
|
|
155
160
|
}
|
|
156
161
|
else {
|
|
157
|
-
const mk = ethers.Wallet.createRandom();
|
|
162
|
+
const mk = ethers_1.ethers.Wallet.createRandom();
|
|
158
163
|
machineKeyAddress = mk.address;
|
|
159
164
|
config.privateKey = mk.privateKey;
|
|
160
|
-
saveConfig(config);
|
|
161
|
-
console.log(" " + c.dim("Machine key generated: ") + c.white(machineKeyAddress));
|
|
162
|
-
console.log(" " + c.dim("Private key saved to ~/.arc402/config.json (chmod 600)"));
|
|
165
|
+
(0, config_1.saveConfig)(config);
|
|
166
|
+
console.log(" " + colors_1.c.dim("Machine key generated: ") + colors_1.c.white(machineKeyAddress));
|
|
167
|
+
console.log(" " + colors_1.c.dim("Private key saved to ~/.arc402/config.json (chmod 600)"));
|
|
163
168
|
}
|
|
164
169
|
let mkAlreadyAuthorized = false;
|
|
165
170
|
try {
|
|
166
|
-
const mkContract = new ethers.Contract(walletAddress, ARC402_WALLET_MACHINE_KEY_ABI, provider);
|
|
171
|
+
const mkContract = new ethers_1.ethers.Contract(walletAddress, abis_1.ARC402_WALLET_MACHINE_KEY_ABI, provider);
|
|
167
172
|
mkAlreadyAuthorized = await mkContract.authorizedMachineKeys(machineKeyAddress);
|
|
168
173
|
}
|
|
169
174
|
catch { /* older wallet — will try to authorize */ }
|
|
170
175
|
if (mkAlreadyAuthorized) {
|
|
171
|
-
console.log(" " + c.success + c.dim(" Machine key already authorized: ") + c.white(machineKeyAddress));
|
|
176
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(" Machine key already authorized: ") + colors_1.c.white(machineKeyAddress));
|
|
172
177
|
}
|
|
173
178
|
else {
|
|
174
|
-
console.log(" " + c.dim("Authorizing machine key: ") + c.white(machineKeyAddress));
|
|
175
|
-
const mkIface = new ethers.Interface(ARC402_WALLET_MACHINE_KEY_ABI);
|
|
179
|
+
console.log(" " + colors_1.c.dim("Authorizing machine key: ") + colors_1.c.white(machineKeyAddress));
|
|
180
|
+
const mkIface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_MACHINE_KEY_ABI);
|
|
176
181
|
await sendTx({ to: walletAddress, data: mkIface.encodeFunctionData("authorizeMachineKey", [machineKeyAddress]), value: "0x0" }, "authorizeMachineKey");
|
|
177
|
-
console.log(" " + c.success + " Machine key authorized");
|
|
182
|
+
console.log(" " + colors_1.c.success + " Machine key authorized");
|
|
178
183
|
}
|
|
179
184
|
// Save progress after machine key step
|
|
180
185
|
config.onboardingProgress = { walletAddress, step: 2, completedSteps: ["machineKey"] };
|
|
181
|
-
saveConfig(config);
|
|
186
|
+
(0, config_1.saveConfig)(config);
|
|
182
187
|
// ── Step 3: Passkey ───────────────────────────────────────────────────────
|
|
183
|
-
console.log("\n" + c.dim("── Step 3: Passkey (Face ID / WebAuthn) ──────────────────────"));
|
|
188
|
+
console.log("\n" + colors_1.c.dim("── Step 3: Passkey (Face ID / WebAuthn) ──────────────────────"));
|
|
184
189
|
let passkeyActive = false;
|
|
185
190
|
try {
|
|
186
|
-
const walletC = new ethers.Contract(walletAddress, ARC402_WALLET_PASSKEY_ABI, provider);
|
|
191
|
+
const walletC = new ethers_1.ethers.Contract(walletAddress, abis_1.ARC402_WALLET_PASSKEY_ABI, provider);
|
|
187
192
|
const auth = await walletC.ownerAuth();
|
|
188
193
|
passkeyActive = Number(auth[0]) === 1;
|
|
189
194
|
}
|
|
190
195
|
catch { /* ignore */ }
|
|
191
196
|
if (passkeyActive) {
|
|
192
|
-
console.log(" " + c.success + c.dim(" Passkey already active"));
|
|
197
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(" Passkey already active"));
|
|
193
198
|
}
|
|
194
199
|
else {
|
|
195
200
|
const passkeyUrl = `https://app.arc402.xyz/passkey-setup?wallet=${walletAddress}`;
|
|
196
|
-
console.log("\n " + c.white("Open this URL in your browser to set up Face ID:"));
|
|
197
|
-
console.log(" " + c.cyan(passkeyUrl));
|
|
198
|
-
console.log(" " + c.dim("Complete Face ID registration, then press Enter. Type 'n' + Enter to skip.\n"));
|
|
199
|
-
const passkeyAns = await
|
|
201
|
+
console.log("\n " + colors_1.c.white("Open this URL in your browser to set up Face ID:"));
|
|
202
|
+
console.log(" " + colors_1.c.cyan(passkeyUrl));
|
|
203
|
+
console.log(" " + colors_1.c.dim("Complete Face ID registration, then press Enter. Type 'n' + Enter to skip.\n"));
|
|
204
|
+
const passkeyAns = await (0, prompts_1.default)({
|
|
200
205
|
type: "text",
|
|
201
206
|
name: "done",
|
|
202
207
|
message: "Press Enter when done (or type 'n' to skip)",
|
|
203
208
|
initial: "",
|
|
204
209
|
});
|
|
205
210
|
if (passkeyAns.done?.toLowerCase() === "n") {
|
|
206
|
-
console.log(" " + c.warning + " Passkey skipped");
|
|
211
|
+
console.log(" " + colors_1.c.warning + " Passkey skipped");
|
|
207
212
|
}
|
|
208
213
|
else {
|
|
209
214
|
passkeyActive = true;
|
|
210
|
-
console.log(" " + c.success + " Passkey set (via browser)");
|
|
215
|
+
console.log(" " + colors_1.c.success + " Passkey set (via browser)");
|
|
211
216
|
}
|
|
212
217
|
}
|
|
213
218
|
// Save progress after passkey step
|
|
214
219
|
config.onboardingProgress = { walletAddress, step: 3, completedSteps: ["machineKey", "passkey"] };
|
|
215
|
-
saveConfig(config);
|
|
220
|
+
(0, config_1.saveConfig)(config);
|
|
216
221
|
// ── Step 4: Policy ────────────────────────────────────────────────────────
|
|
217
|
-
console.log("\n" + c.dim("── Step 4: Policy ─────────────────────────────────────────────"));
|
|
222
|
+
console.log("\n" + colors_1.c.dim("── Step 4: Policy ─────────────────────────────────────────────"));
|
|
218
223
|
// 4a) setVelocityLimit
|
|
219
224
|
let velocityLimitEth = "0.05";
|
|
220
225
|
let velocityAlreadySet = false;
|
|
221
226
|
try {
|
|
222
|
-
const ownerC = new ethers.Contract(walletAddress, ARC402_WALLET_OWNER_ABI, provider);
|
|
227
|
+
const ownerC = new ethers_1.ethers.Contract(walletAddress, abis_1.ARC402_WALLET_OWNER_ABI, provider);
|
|
223
228
|
const existing = await ownerC.velocityLimit();
|
|
224
229
|
if (existing > 0n) {
|
|
225
230
|
velocityAlreadySet = true;
|
|
226
|
-
velocityLimitEth = ethers.formatEther(existing);
|
|
227
|
-
console.log(" " + c.success + c.dim(` Velocity limit already set: ${velocityLimitEth} ETH`));
|
|
231
|
+
velocityLimitEth = ethers_1.ethers.formatEther(existing);
|
|
232
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(` Velocity limit already set: ${velocityLimitEth} ETH`));
|
|
228
233
|
}
|
|
229
234
|
}
|
|
230
235
|
catch { /* ignore */ }
|
|
231
236
|
if (!velocityAlreadySet) {
|
|
232
|
-
const velAns = await
|
|
237
|
+
const velAns = await (0, prompts_1.default)({
|
|
233
238
|
type: "text",
|
|
234
239
|
name: "limit",
|
|
235
240
|
message: "Velocity limit (ETH / rolling window)?",
|
|
236
241
|
initial: "0.05",
|
|
237
242
|
});
|
|
238
243
|
velocityLimitEth = velAns.limit || "0.05";
|
|
239
|
-
const velIface = new ethers.Interface(["function setVelocityLimit(uint256 limit) external"]);
|
|
240
|
-
await sendTx({ to: walletAddress, data: velIface.encodeFunctionData("setVelocityLimit", [ethers.parseEther(velocityLimitEth)]), value: "0x0" }, `setVelocityLimit: ${velocityLimitEth} ETH`);
|
|
241
|
-
saveConfig(config);
|
|
244
|
+
const velIface = new ethers_1.ethers.Interface(["function setVelocityLimit(uint256 limit) external"]);
|
|
245
|
+
await sendTx({ to: walletAddress, data: velIface.encodeFunctionData("setVelocityLimit", [ethers_1.ethers.parseEther(velocityLimitEth)]), value: "0x0" }, `setVelocityLimit: ${velocityLimitEth} ETH`);
|
|
246
|
+
(0, config_1.saveConfig)(config);
|
|
242
247
|
}
|
|
243
248
|
// 4b) setGuardian (optional — address, 'g' to generate, or skip)
|
|
244
249
|
let guardianAddress = null;
|
|
245
250
|
try {
|
|
246
|
-
const guardianC = new ethers.Contract(walletAddress, ARC402_WALLET_GUARDIAN_ABI, provider);
|
|
251
|
+
const guardianC = new ethers_1.ethers.Contract(walletAddress, abis_1.ARC402_WALLET_GUARDIAN_ABI, provider);
|
|
247
252
|
const existing = await guardianC.guardian();
|
|
248
|
-
if (existing && existing !== ethers.ZeroAddress) {
|
|
253
|
+
if (existing && existing !== ethers_1.ethers.ZeroAddress) {
|
|
249
254
|
guardianAddress = existing;
|
|
250
|
-
console.log(" " + c.success + c.dim(` Guardian already set: ${existing}`));
|
|
255
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(` Guardian already set: ${existing}`));
|
|
251
256
|
}
|
|
252
257
|
}
|
|
253
258
|
catch { /* ignore */ }
|
|
254
259
|
if (!guardianAddress) {
|
|
255
|
-
const guardianAns = await
|
|
260
|
+
const guardianAns = await (0, prompts_1.default)({
|
|
256
261
|
type: "text",
|
|
257
262
|
name: "guardian",
|
|
258
263
|
message: "Guardian address? (address, 'g' to generate, Enter to skip)",
|
|
@@ -260,119 +265,93 @@ async function runCompleteOnboardingCeremony(walletAddress, ownerAddress, config
|
|
|
260
265
|
});
|
|
261
266
|
const guardianInput = guardianAns.guardian?.trim() ?? "";
|
|
262
267
|
if (guardianInput.toLowerCase() === "g") {
|
|
263
|
-
const generatedGuardian = ethers.Wallet.createRandom();
|
|
268
|
+
const generatedGuardian = ethers_1.ethers.Wallet.createRandom();
|
|
264
269
|
// Save guardian private key to a separate restricted file, NOT config.json
|
|
265
|
-
const guardianKeyPath =
|
|
266
|
-
|
|
267
|
-
|
|
270
|
+
const guardianKeyPath = path_1.default.join(os_1.default.homedir(), ".arc402", "guardian.key");
|
|
271
|
+
fs_1.default.mkdirSync(path_1.default.dirname(guardianKeyPath), { recursive: true, mode: 0o700 });
|
|
272
|
+
fs_1.default.writeFileSync(guardianKeyPath, generatedGuardian.privateKey + "\n", { mode: 0o400 });
|
|
268
273
|
// Only save address (not private key) to config
|
|
269
274
|
config.guardianAddress = generatedGuardian.address;
|
|
270
|
-
saveConfig(config);
|
|
275
|
+
(0, config_1.saveConfig)(config);
|
|
271
276
|
guardianAddress = generatedGuardian.address;
|
|
272
|
-
console.log("\n " + c.warning + " Guardian key saved to ~/.arc402/guardian.key — move offline for security");
|
|
273
|
-
console.log(" " + c.dim("Address: ") + c.white(generatedGuardian.address) + "\n");
|
|
274
|
-
const guardianIface = new ethers.Interface(["function setGuardian(address _guardian) external"]);
|
|
277
|
+
console.log("\n " + colors_1.c.warning + " Guardian key saved to ~/.arc402/guardian.key — move offline for security");
|
|
278
|
+
console.log(" " + colors_1.c.dim("Address: ") + colors_1.c.white(generatedGuardian.address) + "\n");
|
|
279
|
+
const guardianIface = new ethers_1.ethers.Interface(["function setGuardian(address _guardian) external"]);
|
|
275
280
|
await sendTx({ to: walletAddress, data: guardianIface.encodeFunctionData("setGuardian", [guardianAddress]), value: "0x0" }, "setGuardian");
|
|
276
|
-
saveConfig(config);
|
|
281
|
+
(0, config_1.saveConfig)(config);
|
|
277
282
|
}
|
|
278
|
-
else if (guardianInput && ethers.isAddress(guardianInput)) {
|
|
283
|
+
else if (guardianInput && ethers_1.ethers.isAddress(guardianInput)) {
|
|
279
284
|
guardianAddress = guardianInput;
|
|
280
285
|
config.guardianAddress = guardianInput;
|
|
281
|
-
const guardianIface = new ethers.Interface(["function setGuardian(address _guardian) external"]);
|
|
286
|
+
const guardianIface = new ethers_1.ethers.Interface(["function setGuardian(address _guardian) external"]);
|
|
282
287
|
await sendTx({ to: walletAddress, data: guardianIface.encodeFunctionData("setGuardian", [guardianAddress]), value: "0x0" }, "setGuardian");
|
|
283
|
-
saveConfig(config);
|
|
288
|
+
(0, config_1.saveConfig)(config);
|
|
284
289
|
}
|
|
285
290
|
else if (guardianInput) {
|
|
286
|
-
console.log(" " + c.warning + " Invalid address — guardian skipped");
|
|
291
|
+
console.log(" " + colors_1.c.warning + " Invalid address — guardian skipped");
|
|
287
292
|
}
|
|
288
293
|
}
|
|
289
294
|
// 4c) setCategoryLimitFor('hire')
|
|
290
295
|
let hireLimit = "0.1";
|
|
291
296
|
let hireLimitAlreadySet = false;
|
|
292
297
|
try {
|
|
293
|
-
const limitsContract = new ethers.Contract(policyAddress, POLICY_ENGINE_LIMITS_ABI, provider);
|
|
298
|
+
const limitsContract = new ethers_1.ethers.Contract(policyAddress, abis_1.POLICY_ENGINE_LIMITS_ABI, provider);
|
|
294
299
|
const existing = await limitsContract.categoryLimits(walletAddress, "hire");
|
|
295
300
|
if (existing > 0n) {
|
|
296
301
|
hireLimitAlreadySet = true;
|
|
297
|
-
hireLimit = ethers.formatEther(existing);
|
|
298
|
-
console.log(" " + c.success + c.dim(` Hire limit already set: ${hireLimit} ETH`));
|
|
302
|
+
hireLimit = ethers_1.ethers.formatEther(existing);
|
|
303
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(` Hire limit already set: ${hireLimit} ETH`));
|
|
299
304
|
}
|
|
300
305
|
}
|
|
301
306
|
catch { /* ignore */ }
|
|
302
307
|
if (!hireLimitAlreadySet) {
|
|
303
|
-
const limitAns = await
|
|
308
|
+
const limitAns = await (0, prompts_1.default)({
|
|
304
309
|
type: "text",
|
|
305
310
|
name: "limit",
|
|
306
311
|
message: "Max price per hire (ETH)?",
|
|
307
312
|
initial: "0.1",
|
|
308
313
|
});
|
|
309
314
|
hireLimit = limitAns.limit || "0.1";
|
|
310
|
-
const hireLimitWei = ethers.parseEther(hireLimit);
|
|
311
|
-
const policyIface = new ethers.Interface([
|
|
315
|
+
const hireLimitWei = ethers_1.ethers.parseEther(hireLimit);
|
|
316
|
+
const policyIface = new ethers_1.ethers.Interface([
|
|
312
317
|
"function setCategoryLimitFor(address wallet, string category, uint256 limitPerTx) external",
|
|
313
318
|
]);
|
|
314
319
|
await sendTx({ to: policyAddress, data: policyIface.encodeFunctionData("setCategoryLimitFor", [walletAddress, "hire", hireLimitWei]), value: "0x0" }, `setCategoryLimitFor: hire → ${hireLimit} ETH`);
|
|
315
|
-
saveConfig(config);
|
|
320
|
+
(0, config_1.saveConfig)(config);
|
|
316
321
|
}
|
|
317
|
-
// 4d)
|
|
318
|
-
const contractInteractionIface = new ethers.Interface([
|
|
319
|
-
"function
|
|
320
|
-
"function isContractWhitelisted(address wallet, address target) external view returns (bool)",
|
|
322
|
+
// 4d) enableContractInteraction(wallet, Handshake)
|
|
323
|
+
const contractInteractionIface = new ethers_1.ethers.Interface([
|
|
324
|
+
"function enableContractInteraction(address wallet, address target) external",
|
|
321
325
|
]);
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
}).catch(() => false);
|
|
326
|
-
if (!hsAlreadyWhitelisted) {
|
|
327
|
-
try {
|
|
328
|
-
await sendTx({ to: policyAddress, data: contractInteractionIface.encodeFunctionData("whitelistContract", [walletAddress, handshakeAddress]), value: "0x0" }, "whitelistContract: Handshake");
|
|
329
|
-
}
|
|
330
|
-
catch (e) {
|
|
331
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
332
|
-
if (msg.includes("already whitelisted") || msg.includes("cancel")) {
|
|
333
|
-
console.log(" " + c.success + c.dim(" Handshake contract already whitelisted"));
|
|
334
|
-
}
|
|
335
|
-
else {
|
|
336
|
-
console.log(" " + c.warning + c.dim(` whitelistContract skipped: ${msg.slice(0, 80)}`));
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
else {
|
|
341
|
-
console.log(" " + c.success + c.dim(" Handshake contract already whitelisted"));
|
|
342
|
-
}
|
|
343
|
-
saveConfig(config);
|
|
344
|
-
console.log(" " + c.success + " Policy configured");
|
|
326
|
+
await sendTx({ to: policyAddress, data: contractInteractionIface.encodeFunctionData("enableContractInteraction", [walletAddress, handshakeAddress]), value: "0x0" }, "enableContractInteraction: Handshake");
|
|
327
|
+
(0, config_1.saveConfig)(config);
|
|
328
|
+
console.log(" " + colors_1.c.success + " Policy configured");
|
|
345
329
|
// Save progress after policy step
|
|
346
330
|
config.onboardingProgress = { walletAddress, step: 4, completedSteps: ["machineKey", "passkey", "policy"] };
|
|
347
|
-
saveConfig(config);
|
|
331
|
+
(0, config_1.saveConfig)(config);
|
|
348
332
|
// ── Step 5: Agent Registration ─────────────────────────────────────────────
|
|
349
|
-
console.log("\n" + c.dim("── Step 5: Agent Registration ─────────────────────────────────"));
|
|
333
|
+
console.log("\n" + colors_1.c.dim("── Step 5: Agent Registration ─────────────────────────────────"));
|
|
350
334
|
let agentAlreadyRegistered = false;
|
|
351
335
|
let agentName = "";
|
|
352
336
|
let agentServiceType = "";
|
|
353
337
|
let agentEndpoint = "";
|
|
354
338
|
if (agentRegistryAddress) {
|
|
355
339
|
try {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
return await reg.isRegistered(walletAddress);
|
|
359
|
-
});
|
|
340
|
+
const regContract = new ethers_1.ethers.Contract(agentRegistryAddress, abis_1.AGENT_REGISTRY_ABI, provider);
|
|
341
|
+
agentAlreadyRegistered = await regContract.isRegistered(walletAddress);
|
|
360
342
|
if (agentAlreadyRegistered) {
|
|
361
|
-
const info = await
|
|
362
|
-
const reg = new ethers.Contract(agentRegistryAddress, AGENT_REGISTRY_ABI, p);
|
|
363
|
-
return await reg.getAgent(walletAddress);
|
|
364
|
-
});
|
|
343
|
+
const info = await regContract.getAgent(walletAddress);
|
|
365
344
|
agentName = info.name;
|
|
366
345
|
agentServiceType = info.serviceType;
|
|
367
346
|
agentEndpoint = info.endpoint;
|
|
368
|
-
console.log(" " + c.success + c.dim(` Agent already registered: ${agentName}`));
|
|
347
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(` Agent already registered: ${agentName}`));
|
|
369
348
|
}
|
|
370
349
|
}
|
|
371
350
|
catch { /* ignore */ }
|
|
372
351
|
if (!agentAlreadyRegistered) {
|
|
373
|
-
const rawHostname =
|
|
352
|
+
const rawHostname = os_1.default.hostname();
|
|
374
353
|
const cleanHostname = rawHostname.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
375
|
-
const answers = await
|
|
354
|
+
const answers = await (0, prompts_1.default)([
|
|
376
355
|
{ type: "text", name: "name", message: "Agent name?", initial: cleanHostname },
|
|
377
356
|
{ type: "text", name: "serviceType", message: "Service type?", initial: "intelligence" },
|
|
378
357
|
{ type: "text", name: "caps", message: "Capabilities? (comma-separated)", initial: "research" },
|
|
@@ -384,33 +363,33 @@ async function runCompleteOnboardingCeremony(walletAddress, ownerAddress, config
|
|
|
384
363
|
const capabilities = (answers.caps || "research")
|
|
385
364
|
.split(",").map((s) => s.trim()).filter(Boolean);
|
|
386
365
|
// 5a) enableDefiAccess (check first)
|
|
387
|
-
const peExtIface = new ethers.Interface([
|
|
366
|
+
const peExtIface = new ethers_1.ethers.Interface([
|
|
388
367
|
"function enableDefiAccess(address wallet) external",
|
|
389
368
|
"function whitelistContract(address wallet, address target) external",
|
|
390
369
|
"function defiAccessEnabled(address) external view returns (bool)",
|
|
391
370
|
"function isContractWhitelisted(address wallet, address target) external view returns (bool)",
|
|
392
371
|
]);
|
|
393
|
-
const peContract = new ethers.Contract(policyAddress, peExtIface, provider);
|
|
372
|
+
const peContract = new ethers_1.ethers.Contract(policyAddress, peExtIface, provider);
|
|
394
373
|
const defiEnabled = await peContract.defiAccessEnabled(walletAddress).catch(() => false);
|
|
395
374
|
if (!defiEnabled) {
|
|
396
375
|
await sendTx({ to: policyAddress, data: peExtIface.encodeFunctionData("enableDefiAccess", [walletAddress]), value: "0x0" }, "enableDefiAccess on PolicyEngine");
|
|
397
|
-
saveConfig(config);
|
|
376
|
+
(0, config_1.saveConfig)(config);
|
|
398
377
|
}
|
|
399
378
|
else {
|
|
400
|
-
console.log(" " + c.success + c.dim(" enableDefiAccess — already done"));
|
|
379
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(" enableDefiAccess — already done"));
|
|
401
380
|
}
|
|
402
381
|
// 5b) whitelistContract for AgentRegistry (check first)
|
|
403
382
|
const whitelisted = await peContract.isContractWhitelisted(walletAddress, agentRegistryAddress).catch(() => false);
|
|
404
383
|
if (!whitelisted) {
|
|
405
384
|
await sendTx({ to: policyAddress, data: peExtIface.encodeFunctionData("whitelistContract", [walletAddress, agentRegistryAddress]), value: "0x0" }, "whitelistContract: AgentRegistry on PolicyEngine");
|
|
406
|
-
saveConfig(config);
|
|
385
|
+
(0, config_1.saveConfig)(config);
|
|
407
386
|
}
|
|
408
387
|
else {
|
|
409
|
-
console.log(" " + c.success + c.dim(" whitelistContract(AgentRegistry) — already done"));
|
|
388
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(" whitelistContract(AgentRegistry) — already done"));
|
|
410
389
|
}
|
|
411
390
|
// 5c+d) executeContractCall → register
|
|
412
|
-
const regIface = new ethers.Interface(AGENT_REGISTRY_ABI);
|
|
413
|
-
const execIface = new ethers.Interface(ARC402_WALLET_EXECUTE_ABI);
|
|
391
|
+
const regIface = new ethers_1.ethers.Interface(abis_1.AGENT_REGISTRY_ABI);
|
|
392
|
+
const execIface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_EXECUTE_ABI);
|
|
414
393
|
const regData = regIface.encodeFunctionData("register", [agentName, capabilities, agentServiceType, agentEndpoint, ""]);
|
|
415
394
|
const execData = execIface.encodeFunctionData("executeContractCall", [{
|
|
416
395
|
target: agentRegistryAddress,
|
|
@@ -418,103 +397,103 @@ async function runCompleteOnboardingCeremony(walletAddress, ownerAddress, config
|
|
|
418
397
|
value: 0n,
|
|
419
398
|
minReturnValue: 0n,
|
|
420
399
|
maxApprovalAmount: 0n,
|
|
421
|
-
approvalToken: ethers.ZeroAddress,
|
|
400
|
+
approvalToken: ethers_1.ethers.ZeroAddress,
|
|
422
401
|
}]);
|
|
423
402
|
await sendTx({ to: walletAddress, data: execData, value: "0x0" }, `register agent: ${agentName}`);
|
|
424
|
-
console.log(" " + c.success + " Agent registered: " + agentName);
|
|
403
|
+
console.log(" " + colors_1.c.success + " Agent registered: " + agentName);
|
|
425
404
|
}
|
|
426
405
|
}
|
|
427
406
|
else {
|
|
428
|
-
console.log(" " + c.warning + " AgentRegistry address not configured — skipping");
|
|
407
|
+
console.log(" " + colors_1.c.warning + " AgentRegistry address not configured — skipping");
|
|
429
408
|
}
|
|
430
409
|
// Save progress after agent step, then clear on ceremony complete
|
|
431
410
|
config.onboardingProgress = { walletAddress, step: 5, completedSteps: ["machineKey", "passkey", "policy", "agent"] };
|
|
432
|
-
saveConfig(config);
|
|
411
|
+
(0, config_1.saveConfig)(config);
|
|
433
412
|
// ── Step 7: Workroom Init ─────────────────────────────────────────────────
|
|
434
|
-
console.log("\n" + c.dim("── Step 7: Workroom ────────────────────────────────────────────"));
|
|
413
|
+
console.log("\n" + colors_1.c.dim("── Step 7: Workroom ────────────────────────────────────────────"));
|
|
435
414
|
let workroomInitialized = false;
|
|
436
415
|
let dockerFound = false;
|
|
437
416
|
try {
|
|
438
|
-
const dockerCheck = spawnSync("docker", ["--version"], { encoding: "utf-8", timeout: 5000 });
|
|
417
|
+
const dockerCheck = (0, child_process_1.spawnSync)("docker", ["--version"], { encoding: "utf-8", timeout: 5000 });
|
|
439
418
|
dockerFound = dockerCheck.status === 0;
|
|
440
419
|
}
|
|
441
420
|
catch {
|
|
442
421
|
dockerFound = false;
|
|
443
422
|
}
|
|
444
423
|
if (dockerFound) {
|
|
445
|
-
console.log(" " + c.dim("Docker found — initializing workroom..."));
|
|
424
|
+
console.log(" " + colors_1.c.dim("Docker found — initializing workroom..."));
|
|
446
425
|
try {
|
|
447
|
-
const initResult = spawnSync(process.execPath, [process.argv[1], "workroom", "init"], {
|
|
426
|
+
const initResult = (0, child_process_1.spawnSync)(process.execPath, [process.argv[1], "workroom", "init"], {
|
|
448
427
|
encoding: "utf-8",
|
|
449
428
|
timeout: 120000,
|
|
450
429
|
env: { ...process.env },
|
|
451
430
|
});
|
|
452
431
|
workroomInitialized = initResult.status === 0;
|
|
453
432
|
if (workroomInitialized) {
|
|
454
|
-
console.log(" " + c.success + " Workroom initialized");
|
|
433
|
+
console.log(" " + colors_1.c.success + " Workroom initialized");
|
|
455
434
|
}
|
|
456
435
|
else {
|
|
457
|
-
console.log(" " + c.warning + " Workroom init incomplete — run: arc402 workroom init");
|
|
436
|
+
console.log(" " + colors_1.c.warning + " Workroom init incomplete — run: arc402 workroom init");
|
|
458
437
|
}
|
|
459
438
|
}
|
|
460
439
|
catch {
|
|
461
|
-
console.log(" " + c.warning + " Workroom init failed — run: arc402 workroom init");
|
|
440
|
+
console.log(" " + colors_1.c.warning + " Workroom init failed — run: arc402 workroom init");
|
|
462
441
|
}
|
|
463
442
|
}
|
|
464
443
|
else {
|
|
465
|
-
console.log(" " + c.warning + " Docker not found");
|
|
444
|
+
console.log(" " + colors_1.c.warning + " Docker not found");
|
|
466
445
|
console.log(" Install Docker: https://docs.docker.com/get-docker/");
|
|
467
|
-
console.log(" Or run daemon in host mode: " + c.white("arc402 daemon start --host"));
|
|
446
|
+
console.log(" Or run daemon in host mode: " + colors_1.c.white("arc402 daemon start --host"));
|
|
468
447
|
}
|
|
469
448
|
// ── Step 8: Daemon Start ──────────────────────────────────────────────────
|
|
470
|
-
console.log("\n" + c.dim("── Step 8: Daemon ──────────────────────────────────────────────"));
|
|
449
|
+
console.log("\n" + colors_1.c.dim("── Step 8: Daemon ──────────────────────────────────────────────"));
|
|
471
450
|
let daemonRunning = false;
|
|
472
451
|
const relayPort = 4402;
|
|
473
452
|
if (workroomInitialized) {
|
|
474
453
|
try {
|
|
475
|
-
const startResult = spawnSync(process.execPath, [process.argv[1], "workroom", "start"], {
|
|
454
|
+
const startResult = (0, child_process_1.spawnSync)(process.execPath, [process.argv[1], "workroom", "start"], {
|
|
476
455
|
encoding: "utf-8",
|
|
477
456
|
timeout: 30000,
|
|
478
457
|
env: { ...process.env },
|
|
479
458
|
});
|
|
480
459
|
daemonRunning = startResult.status === 0;
|
|
481
460
|
if (daemonRunning) {
|
|
482
|
-
console.log(" " + c.success + " Daemon online (port " + relayPort + ")");
|
|
461
|
+
console.log(" " + colors_1.c.success + " Daemon online (port " + relayPort + ")");
|
|
483
462
|
}
|
|
484
463
|
else {
|
|
485
|
-
console.log(" " + c.warning + " Daemon start failed — run: arc402 workroom start");
|
|
464
|
+
console.log(" " + colors_1.c.warning + " Daemon start failed — run: arc402 workroom start");
|
|
486
465
|
}
|
|
487
466
|
}
|
|
488
467
|
catch {
|
|
489
|
-
console.log(" " + c.warning + " Daemon start failed — run: arc402 workroom start");
|
|
468
|
+
console.log(" " + colors_1.c.warning + " Daemon start failed — run: arc402 workroom start");
|
|
490
469
|
}
|
|
491
470
|
}
|
|
492
471
|
else if (!dockerFound) {
|
|
493
472
|
try {
|
|
494
|
-
const startResult = spawnSync(process.execPath, [process.argv[1], "daemon", "start", "--host"], {
|
|
473
|
+
const startResult = (0, child_process_1.spawnSync)(process.execPath, [process.argv[1], "daemon", "start", "--host"], {
|
|
495
474
|
encoding: "utf-8",
|
|
496
475
|
timeout: 30000,
|
|
497
476
|
env: { ...process.env },
|
|
498
477
|
});
|
|
499
478
|
daemonRunning = startResult.status === 0;
|
|
500
479
|
if (daemonRunning) {
|
|
501
|
-
console.log(" " + c.success + " Daemon online — host mode (port " + relayPort + ")");
|
|
480
|
+
console.log(" " + colors_1.c.success + " Daemon online — host mode (port " + relayPort + ")");
|
|
502
481
|
}
|
|
503
482
|
else {
|
|
504
|
-
console.log(" " + c.warning + " Daemon not started — run: arc402 daemon start --host");
|
|
483
|
+
console.log(" " + colors_1.c.warning + " Daemon not started — run: arc402 daemon start --host");
|
|
505
484
|
}
|
|
506
485
|
}
|
|
507
486
|
catch {
|
|
508
|
-
console.log(" " + c.warning + " Daemon not started — run: arc402 daemon start --host");
|
|
487
|
+
console.log(" " + colors_1.c.warning + " Daemon not started — run: arc402 daemon start --host");
|
|
509
488
|
}
|
|
510
489
|
}
|
|
511
490
|
else {
|
|
512
|
-
console.log(" " + c.warning + " Daemon not started — run: arc402 workroom init first");
|
|
491
|
+
console.log(" " + colors_1.c.warning + " Daemon not started — run: arc402 workroom init first");
|
|
513
492
|
}
|
|
514
493
|
// ── Step 6: Summary ───────────────────────────────────────────────────────
|
|
515
494
|
const trustScore = await (async () => {
|
|
516
495
|
try {
|
|
517
|
-
const trust = new ethers.Contract(config.trustRegistryAddress, TRUST_REGISTRY_ABI, provider);
|
|
496
|
+
const trust = new ethers_1.ethers.Contract(config.trustRegistryAddress, abis_1.TRUST_REGISTRY_ABI, provider);
|
|
518
497
|
const s = await trust.getScore(walletAddress);
|
|
519
498
|
return s.toString();
|
|
520
499
|
}
|
|
@@ -523,37 +502,37 @@ async function runCompleteOnboardingCeremony(walletAddress, ownerAddress, config
|
|
|
523
502
|
}
|
|
524
503
|
})();
|
|
525
504
|
const workroomLabel = dockerFound
|
|
526
|
-
? (workroomInitialized ? (daemonRunning ? c.green("✓ Running") : c.yellow("✓ Initialized")) : c.yellow("⚠ Init needed"))
|
|
527
|
-
: c.yellow("⚠ No Docker");
|
|
505
|
+
? (workroomInitialized ? (daemonRunning ? colors_1.c.green("✓ Running") : colors_1.c.yellow("✓ Initialized")) : colors_1.c.yellow("⚠ Init needed"))
|
|
506
|
+
: colors_1.c.yellow("⚠ No Docker");
|
|
528
507
|
const daemonLabel = daemonRunning
|
|
529
|
-
? c.green("✓ Online (port " + relayPort + ")")
|
|
530
|
-
: c.dim("not started");
|
|
508
|
+
? colors_1.c.green("✓ Online (port " + relayPort + ")")
|
|
509
|
+
: colors_1.c.dim("not started");
|
|
531
510
|
const endpointLabel = agentEndpoint
|
|
532
|
-
? c.white(agentEndpoint) + c.dim(` → localhost:${relayPort}`)
|
|
533
|
-
: c.dim("—");
|
|
511
|
+
? colors_1.c.white(agentEndpoint) + colors_1.c.dim(` → localhost:${relayPort}`)
|
|
512
|
+
: colors_1.c.dim("—");
|
|
534
513
|
// Clear onboarding progress — ceremony complete
|
|
535
514
|
delete config.onboardingProgress;
|
|
536
|
-
saveConfig(config);
|
|
537
|
-
console.log("\n " + c.success + c.white(" Onboarding complete"));
|
|
538
|
-
renderTree([
|
|
539
|
-
{ label: "Wallet", value: c.white(walletAddress) },
|
|
540
|
-
{ label: "Owner", value: c.white(ownerAddress) },
|
|
541
|
-
{ label: "Machine", value: c.white(machineKeyAddress) + c.dim(" (authorized)") },
|
|
542
|
-
{ label: "Passkey", value: passkeyActive ? c.green("✓ set") : c.yellow("⚠ skipped") },
|
|
543
|
-
{ label: "Velocity", value: c.white(velocityLimitEth + " ETH") },
|
|
544
|
-
{ label: "Guardian", value: guardianAddress ? c.white(guardianAddress) : c.dim("none") },
|
|
545
|
-
{ label: "Hire limit", value: c.white(hireLimit + " ETH") },
|
|
546
|
-
{ label: "Agent", value: agentName ? c.white(agentName) : c.dim("not registered") },
|
|
547
|
-
{ label: "Service", value: agentServiceType ? c.white(agentServiceType) : c.dim("—") },
|
|
515
|
+
(0, config_1.saveConfig)(config);
|
|
516
|
+
console.log("\n " + colors_1.c.success + colors_1.c.white(" Onboarding complete"));
|
|
517
|
+
(0, tree_1.renderTree)([
|
|
518
|
+
{ label: "Wallet", value: colors_1.c.white(walletAddress) },
|
|
519
|
+
{ label: "Owner", value: colors_1.c.white(ownerAddress) },
|
|
520
|
+
{ label: "Machine", value: colors_1.c.white(machineKeyAddress) + colors_1.c.dim(" (authorized)") },
|
|
521
|
+
{ label: "Passkey", value: passkeyActive ? colors_1.c.green("✓ set") : colors_1.c.yellow("⚠ skipped") },
|
|
522
|
+
{ label: "Velocity", value: colors_1.c.white(velocityLimitEth + " ETH") },
|
|
523
|
+
{ label: "Guardian", value: guardianAddress ? colors_1.c.white(guardianAddress) : colors_1.c.dim("none") },
|
|
524
|
+
{ label: "Hire limit", value: colors_1.c.white(hireLimit + " ETH") },
|
|
525
|
+
{ label: "Agent", value: agentName ? colors_1.c.white(agentName) : colors_1.c.dim("not registered") },
|
|
526
|
+
{ label: "Service", value: agentServiceType ? colors_1.c.white(agentServiceType) : colors_1.c.dim("—") },
|
|
548
527
|
{ label: "Workroom", value: workroomLabel },
|
|
549
528
|
{ label: "Daemon", value: daemonLabel },
|
|
550
529
|
{ label: "Endpoint", value: endpointLabel },
|
|
551
|
-
{ label: "Trust", value: c.white(`${trustScore}`), last: true },
|
|
530
|
+
{ label: "Trust", value: colors_1.c.white(`${trustScore}`), last: true },
|
|
552
531
|
]);
|
|
553
|
-
console.log("\n " + c.dim("Next: fund your wallet with 0.002 ETH on Base"));
|
|
532
|
+
console.log("\n " + colors_1.c.dim("Next: fund your wallet with 0.002 ETH on Base"));
|
|
554
533
|
}
|
|
555
534
|
function printOpenShellHint() {
|
|
556
|
-
const r = spawnSync("which", ["openshell"], { encoding: "utf-8" });
|
|
535
|
+
const r = (0, child_process_1.spawnSync)("which", ["openshell"], { encoding: "utf-8" });
|
|
557
536
|
if (r.status === 0 && r.stdout.trim()) {
|
|
558
537
|
console.log("\nOpenShell detected. Run: arc402 openshell init");
|
|
559
538
|
}
|
|
@@ -561,28 +540,37 @@ function printOpenShellHint() {
|
|
|
561
540
|
console.log("\nOptional: install OpenShell for sandboxed execution: arc402 openshell install");
|
|
562
541
|
}
|
|
563
542
|
}
|
|
564
|
-
|
|
543
|
+
function registerWalletCommands(program) {
|
|
565
544
|
const wallet = program.command("wallet").description("Wallet utilities");
|
|
566
545
|
// ─── status ────────────────────────────────────────────────────────────────
|
|
567
546
|
wallet.command("status").description("Show address, balances, contract wallet, guardian, and frozen status").option("--json").action(async (opts) => {
|
|
568
|
-
const config = loadConfig();
|
|
569
|
-
const { provider, address } = await getClient(config);
|
|
547
|
+
const config = (0, config_1.loadConfig)();
|
|
548
|
+
const { provider, address } = await (0, client_1.getClient)(config);
|
|
570
549
|
if (!address)
|
|
571
550
|
throw new Error("No wallet configured");
|
|
572
|
-
const usdcAddress = getUsdcAddress(config);
|
|
573
|
-
const usdc = new ethers.Contract(usdcAddress, ["function balanceOf(address owner) external view returns (uint256)"], provider);
|
|
574
|
-
const trust = new TrustClient(config.trustRegistryAddress, provider);
|
|
575
|
-
const
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
551
|
+
const usdcAddress = (0, config_1.getUsdcAddress)(config);
|
|
552
|
+
const usdc = new ethers_1.ethers.Contract(usdcAddress, ["function balanceOf(address owner) external view returns (uint256)"], provider);
|
|
553
|
+
const trust = new sdk_1.TrustClient(config.trustRegistryAddress, provider);
|
|
554
|
+
const statusSpinner = opts.json ? null : (0, spinner_1.startSpinner)("Loading wallet status…");
|
|
555
|
+
let ethBalance, usdcBalance, score;
|
|
556
|
+
try {
|
|
557
|
+
[ethBalance, usdcBalance, score] = await Promise.all([
|
|
558
|
+
provider.getBalance(address),
|
|
559
|
+
usdc.balanceOf(address),
|
|
560
|
+
trust.getScore(address),
|
|
561
|
+
]);
|
|
562
|
+
statusSpinner?.succeed("Wallet status loaded");
|
|
563
|
+
}
|
|
564
|
+
catch (err) {
|
|
565
|
+
statusSpinner?.fail("Failed to load wallet status");
|
|
566
|
+
throw err;
|
|
567
|
+
}
|
|
580
568
|
// Query contract wallet for frozen/guardian state if deployed
|
|
581
569
|
let contractFrozen = null;
|
|
582
570
|
let contractGuardian = null;
|
|
583
571
|
if (config.walletContractAddress) {
|
|
584
572
|
try {
|
|
585
|
-
const walletContract = new ethers.Contract(config.walletContractAddress, ARC402_WALLET_GUARDIAN_ABI, provider);
|
|
573
|
+
const walletContract = new ethers_1.ethers.Contract(config.walletContractAddress, abis_1.ARC402_WALLET_GUARDIAN_ABI, provider);
|
|
586
574
|
[contractFrozen, contractGuardian] = await Promise.all([
|
|
587
575
|
walletContract.frozen(),
|
|
588
576
|
walletContract.guardian(),
|
|
@@ -593,10 +581,10 @@ export function registerWalletCommands(program) {
|
|
|
593
581
|
const payload = {
|
|
594
582
|
address,
|
|
595
583
|
network: config.network,
|
|
596
|
-
ethBalance: ethers.formatEther(ethBalance),
|
|
584
|
+
ethBalance: ethers_1.ethers.formatEther(ethBalance),
|
|
597
585
|
usdcBalance: (Number(usdcBalance) / 1e6).toFixed(2),
|
|
598
586
|
trustScore: score.score,
|
|
599
|
-
trustTier: getTrustTier(score.score),
|
|
587
|
+
trustTier: (0, format_1.getTrustTier)(score.score),
|
|
600
588
|
walletContractAddress: config.walletContractAddress ?? null,
|
|
601
589
|
frozen: contractFrozen,
|
|
602
590
|
guardian: contractGuardian,
|
|
@@ -616,11 +604,11 @@ export function registerWalletCommands(program) {
|
|
|
616
604
|
if (payload.walletContractAddress)
|
|
617
605
|
treeItems.push({ label: "Contract", value: payload.walletContractAddress });
|
|
618
606
|
if (contractFrozen !== null)
|
|
619
|
-
treeItems.push({ label: "Frozen", value: contractFrozen ? c.red("YES") : c.green("no") });
|
|
620
|
-
if (contractGuardian && contractGuardian !== ethers.ZeroAddress)
|
|
607
|
+
treeItems.push({ label: "Frozen", value: contractFrozen ? colors_1.c.red("YES") : colors_1.c.green("no") });
|
|
608
|
+
if (contractGuardian && contractGuardian !== ethers_1.ethers.ZeroAddress)
|
|
621
609
|
treeItems.push({ label: "Guardian", value: contractGuardian });
|
|
622
610
|
treeItems[treeItems.length - 1].last = true;
|
|
623
|
-
renderTree(treeItems);
|
|
611
|
+
(0, tree_1.renderTree)(treeItems);
|
|
624
612
|
}
|
|
625
613
|
});
|
|
626
614
|
// ─── wc-reset ──────────────────────────────────────────────────────────────
|
|
@@ -633,16 +621,16 @@ export function registerWalletCommands(program) {
|
|
|
633
621
|
.description("Clear stale WalletConnect session — forces a fresh QR pairing on next connection")
|
|
634
622
|
.option("--json")
|
|
635
623
|
.action(async (opts) => {
|
|
636
|
-
const config = loadConfig();
|
|
624
|
+
const config = (0, config_1.loadConfig)();
|
|
637
625
|
const hadSession = !!config.wcSession;
|
|
638
626
|
// 1. Clear from config
|
|
639
|
-
clearWCSession(config);
|
|
627
|
+
(0, walletconnect_session_1.clearWCSession)(config);
|
|
640
628
|
// 2. Wipe WC SDK storage (may be a file or a directory depending on SDK version)
|
|
641
|
-
const wcStoragePath =
|
|
629
|
+
const wcStoragePath = path_1.default.join(os_1.default.homedir(), ".arc402", "wc-storage.json");
|
|
642
630
|
let storageWiped = false;
|
|
643
631
|
try {
|
|
644
|
-
if (
|
|
645
|
-
|
|
632
|
+
if (fs_1.default.existsSync(wcStoragePath)) {
|
|
633
|
+
fs_1.default.rmSync(wcStoragePath, { recursive: true, force: true });
|
|
646
634
|
storageWiped = true;
|
|
647
635
|
}
|
|
648
636
|
}
|
|
@@ -652,7 +640,7 @@ export function registerWalletCommands(program) {
|
|
|
652
640
|
console.log(JSON.stringify({ ok: false, error: `Could not delete ${wcStoragePath}: ${msg}` }));
|
|
653
641
|
}
|
|
654
642
|
else {
|
|
655
|
-
console.warn(" " + c.warning + " " + c.yellow(`Could not delete ${wcStoragePath}: ${msg}`));
|
|
643
|
+
console.warn(" " + colors_1.c.warning + " " + colors_1.c.yellow(`Could not delete ${wcStoragePath}: ${msg}`));
|
|
656
644
|
console.warn(" You may need to delete it manually.");
|
|
657
645
|
}
|
|
658
646
|
return;
|
|
@@ -661,12 +649,12 @@ export function registerWalletCommands(program) {
|
|
|
661
649
|
console.log(JSON.stringify({ ok: true, hadSession, storageWiped }));
|
|
662
650
|
}
|
|
663
651
|
else {
|
|
664
|
-
console.log(" " + c.success + c.white(" WalletConnect session cleared"));
|
|
652
|
+
console.log(" " + colors_1.c.success + colors_1.c.white(" WalletConnect session cleared"));
|
|
665
653
|
if (storageWiped)
|
|
666
|
-
console.log(" " + c.dim("Storage wiped:") + " " + c.white(wcStoragePath));
|
|
654
|
+
console.log(" " + colors_1.c.dim("Storage wiped:") + " " + colors_1.c.white(wcStoragePath));
|
|
667
655
|
else
|
|
668
|
-
console.log(" " + c.dim("(No storage file found — already clean)"));
|
|
669
|
-
console.log("\n" + c.dim("Next: run any wallet command and scan the fresh QR code."));
|
|
656
|
+
console.log(" " + colors_1.c.dim("(No storage file found — already clean)"));
|
|
657
|
+
console.log("\n" + colors_1.c.dim("Next: run any wallet command and scan the fresh QR code."));
|
|
670
658
|
}
|
|
671
659
|
});
|
|
672
660
|
// ─── new ───────────────────────────────────────────────────────────────────
|
|
@@ -675,12 +663,12 @@ export function registerWalletCommands(program) {
|
|
|
675
663
|
.option("--network <network>", "Network (base-mainnet or base-sepolia)", "base-sepolia")
|
|
676
664
|
.action(async (opts) => {
|
|
677
665
|
const network = opts.network;
|
|
678
|
-
const defaults = NETWORK_DEFAULTS[network];
|
|
666
|
+
const defaults = config_1.NETWORK_DEFAULTS[network];
|
|
679
667
|
if (!defaults) {
|
|
680
668
|
console.error(`Unknown network: ${network}. Use base-mainnet or base-sepolia.`);
|
|
681
669
|
process.exit(1);
|
|
682
670
|
}
|
|
683
|
-
const generated = ethers.Wallet.createRandom();
|
|
671
|
+
const generated = ethers_1.ethers.Wallet.createRandom();
|
|
684
672
|
const config = {
|
|
685
673
|
network,
|
|
686
674
|
rpcUrl: defaults.rpcUrl,
|
|
@@ -688,12 +676,12 @@ export function registerWalletCommands(program) {
|
|
|
688
676
|
trustRegistryAddress: defaults.trustRegistryAddress,
|
|
689
677
|
walletFactoryAddress: defaults.walletFactoryAddress,
|
|
690
678
|
};
|
|
691
|
-
saveConfig(config);
|
|
692
|
-
renderTree([
|
|
679
|
+
(0, config_1.saveConfig)(config);
|
|
680
|
+
(0, tree_1.renderTree)([
|
|
693
681
|
{ label: "Address", value: generated.address },
|
|
694
|
-
{ label: "Config", value: getConfigPath(), last: true },
|
|
682
|
+
{ label: "Config", value: (0, config_1.getConfigPath)(), last: true },
|
|
695
683
|
]);
|
|
696
|
-
console.log(c.dim("Next: fund your wallet with ETH, then run: arc402 wallet deploy"));
|
|
684
|
+
console.log(colors_1.c.dim("Next: fund your wallet with ETH, then run: arc402 wallet deploy"));
|
|
697
685
|
});
|
|
698
686
|
// ─── import ────────────────────────────────────────────────────────────────
|
|
699
687
|
wallet.command("import")
|
|
@@ -702,7 +690,7 @@ export function registerWalletCommands(program) {
|
|
|
702
690
|
.option("--key-file <path>", "Read private key from file instead of prompting")
|
|
703
691
|
.action(async (opts) => {
|
|
704
692
|
const network = opts.network;
|
|
705
|
-
const defaults = NETWORK_DEFAULTS[network];
|
|
693
|
+
const defaults = config_1.NETWORK_DEFAULTS[network];
|
|
706
694
|
if (!defaults) {
|
|
707
695
|
console.error(`Unknown network: ${network}. Use base-mainnet or base-sepolia.`);
|
|
708
696
|
process.exit(1);
|
|
@@ -710,7 +698,7 @@ export function registerWalletCommands(program) {
|
|
|
710
698
|
let privateKey;
|
|
711
699
|
if (opts.keyFile) {
|
|
712
700
|
try {
|
|
713
|
-
privateKey =
|
|
701
|
+
privateKey = fs_1.default.readFileSync(opts.keyFile, "utf-8").trim();
|
|
714
702
|
}
|
|
715
703
|
catch (e) {
|
|
716
704
|
console.error(`Cannot read key file: ${e instanceof Error ? e.message : String(e)}`);
|
|
@@ -719,7 +707,7 @@ export function registerWalletCommands(program) {
|
|
|
719
707
|
}
|
|
720
708
|
else {
|
|
721
709
|
// Interactive prompt — hidden input avoids shell history
|
|
722
|
-
const answer = await
|
|
710
|
+
const answer = await (0, prompts_1.default)({
|
|
723
711
|
type: "password",
|
|
724
712
|
name: "key",
|
|
725
713
|
message: "Paste private key (hidden):",
|
|
@@ -732,7 +720,7 @@ export function registerWalletCommands(program) {
|
|
|
732
720
|
}
|
|
733
721
|
let imported;
|
|
734
722
|
try {
|
|
735
|
-
imported = new ethers.Wallet(privateKey);
|
|
723
|
+
imported = new ethers_1.ethers.Wallet(privateKey);
|
|
736
724
|
}
|
|
737
725
|
catch {
|
|
738
726
|
console.error("Invalid private key. Must be a 0x-prefixed hex string.");
|
|
@@ -745,24 +733,24 @@ export function registerWalletCommands(program) {
|
|
|
745
733
|
trustRegistryAddress: defaults.trustRegistryAddress,
|
|
746
734
|
walletFactoryAddress: defaults.walletFactoryAddress,
|
|
747
735
|
};
|
|
748
|
-
saveConfig(config);
|
|
749
|
-
renderTree([
|
|
736
|
+
(0, config_1.saveConfig)(config);
|
|
737
|
+
(0, tree_1.renderTree)([
|
|
750
738
|
{ label: "Address", value: imported.address },
|
|
751
|
-
{ label: "Config", value: getConfigPath(), last: true },
|
|
739
|
+
{ label: "Config", value: (0, config_1.getConfigPath)(), last: true },
|
|
752
740
|
]);
|
|
753
|
-
console.warn(" " + c.warning + " " + c.yellow("Store your private key safely — anyone with it controls your wallet"));
|
|
741
|
+
console.warn(" " + colors_1.c.warning + " " + colors_1.c.yellow("Store your private key safely — anyone with it controls your wallet"));
|
|
754
742
|
});
|
|
755
743
|
// ─── fund ──────────────────────────────────────────────────────────────────
|
|
756
744
|
wallet.command("fund")
|
|
757
745
|
.description("Show how to get ETH onto your wallet")
|
|
758
746
|
.action(async () => {
|
|
759
|
-
const config = loadConfig();
|
|
760
|
-
const { provider, address } = await getClient(config);
|
|
747
|
+
const config = (0, config_1.loadConfig)();
|
|
748
|
+
const { provider, address } = await (0, client_1.getClient)(config);
|
|
761
749
|
if (!address)
|
|
762
750
|
throw new Error("No wallet configured");
|
|
763
751
|
const ethBalance = await provider.getBalance(address);
|
|
764
752
|
console.log(`\nYour wallet address:\n ${address}`);
|
|
765
|
-
console.log(`\nCurrent balance: ${ethers.formatEther(ethBalance)} ETH`);
|
|
753
|
+
console.log(`\nCurrent balance: ${ethers_1.ethers.formatEther(ethBalance)} ETH`);
|
|
766
754
|
console.log(`\nFunding options:`);
|
|
767
755
|
console.log(` Bridge (Base mainnet): https://bridge.base.org`);
|
|
768
756
|
console.log(` Coinbase: If you use Coinbase, you can withdraw directly to Base mainnet`);
|
|
@@ -775,17 +763,17 @@ export function registerWalletCommands(program) {
|
|
|
775
763
|
.description("Check ETH balance on Base")
|
|
776
764
|
.option("--json")
|
|
777
765
|
.action(async (opts) => {
|
|
778
|
-
const config = loadConfig();
|
|
779
|
-
const { provider, address } = await getClient(config);
|
|
766
|
+
const config = (0, config_1.loadConfig)();
|
|
767
|
+
const { provider, address } = await (0, client_1.getClient)(config);
|
|
780
768
|
if (!address)
|
|
781
769
|
throw new Error("No wallet configured");
|
|
782
770
|
const ethBalance = await provider.getBalance(address);
|
|
783
|
-
const formatted = ethers.formatEther(ethBalance);
|
|
771
|
+
const formatted = ethers_1.ethers.formatEther(ethBalance);
|
|
784
772
|
if (opts.json) {
|
|
785
773
|
console.log(JSON.stringify({ address, balance: formatted, balanceWei: ethBalance.toString() }));
|
|
786
774
|
}
|
|
787
775
|
else {
|
|
788
|
-
renderTree([
|
|
776
|
+
(0, tree_1.renderTree)([
|
|
789
777
|
{ label: "Address", value: address },
|
|
790
778
|
{ label: "Balance", value: `${formatted} ETH`, last: true },
|
|
791
779
|
]);
|
|
@@ -797,8 +785,8 @@ export function registerWalletCommands(program) {
|
|
|
797
785
|
.option("--owner <address>", "Master key address to query (defaults to config.ownerAddress)")
|
|
798
786
|
.option("--json")
|
|
799
787
|
.action(async (opts) => {
|
|
800
|
-
const config = loadConfig();
|
|
801
|
-
const factoryAddress = config.walletFactoryAddress ?? NETWORK_DEFAULTS[config.network]?.walletFactoryAddress;
|
|
788
|
+
const config = (0, config_1.loadConfig)();
|
|
789
|
+
const factoryAddress = config.walletFactoryAddress ?? config_1.NETWORK_DEFAULTS[config.network]?.walletFactoryAddress;
|
|
802
790
|
if (!factoryAddress) {
|
|
803
791
|
console.error("walletFactoryAddress not found in config or NETWORK_DEFAULTS.");
|
|
804
792
|
process.exit(1);
|
|
@@ -808,12 +796,12 @@ export function registerWalletCommands(program) {
|
|
|
808
796
|
console.error("No owner address. Pass --owner <address> or set ownerAddress in config (run `arc402 wallet deploy` first).");
|
|
809
797
|
process.exit(1);
|
|
810
798
|
}
|
|
811
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
812
|
-
const factory = new ethers.Contract(factoryAddress, WALLET_FACTORY_ABI, provider);
|
|
799
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
800
|
+
const factory = new ethers_1.ethers.Contract(factoryAddress, abis_1.WALLET_FACTORY_ABI, provider);
|
|
813
801
|
const wallets = await factory.getWallets(ownerAddress);
|
|
814
802
|
const results = await Promise.all(wallets.map(async (addr) => {
|
|
815
|
-
const walletContract = new ethers.Contract(addr, ARC402_WALLET_GUARDIAN_ABI, provider);
|
|
816
|
-
const trustContract = new ethers.Contract(config.trustRegistryAddress, TRUST_REGISTRY_ABI, provider);
|
|
803
|
+
const walletContract = new ethers_1.ethers.Contract(addr, abis_1.ARC402_WALLET_GUARDIAN_ABI, provider);
|
|
804
|
+
const trustContract = new ethers_1.ethers.Contract(config.trustRegistryAddress, abis_1.TRUST_REGISTRY_ABI, provider);
|
|
817
805
|
const [frozen, score] = await Promise.all([
|
|
818
806
|
walletContract.frozen().catch(() => null),
|
|
819
807
|
trustContract.getScore(addr).catch(() => BigInt(0)),
|
|
@@ -846,18 +834,18 @@ export function registerWalletCommands(program) {
|
|
|
846
834
|
.action(async (address) => {
|
|
847
835
|
let checksumAddress;
|
|
848
836
|
try {
|
|
849
|
-
checksumAddress = ethers.getAddress(address);
|
|
837
|
+
checksumAddress = ethers_1.ethers.getAddress(address);
|
|
850
838
|
}
|
|
851
839
|
catch {
|
|
852
840
|
console.error(`Invalid address: ${address}`);
|
|
853
841
|
process.exit(1);
|
|
854
842
|
}
|
|
855
|
-
const config = loadConfig();
|
|
856
|
-
const factoryAddress = config.walletFactoryAddress ?? NETWORK_DEFAULTS[config.network]?.walletFactoryAddress;
|
|
843
|
+
const config = (0, config_1.loadConfig)();
|
|
844
|
+
const factoryAddress = config.walletFactoryAddress ?? config_1.NETWORK_DEFAULTS[config.network]?.walletFactoryAddress;
|
|
857
845
|
if (factoryAddress && config.ownerAddress) {
|
|
858
846
|
try {
|
|
859
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
860
|
-
const factory = new ethers.Contract(factoryAddress, WALLET_FACTORY_ABI, provider);
|
|
847
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
848
|
+
const factory = new ethers_1.ethers.Contract(factoryAddress, abis_1.WALLET_FACTORY_ABI, provider);
|
|
861
849
|
const wallets = await factory.getWallets(config.ownerAddress);
|
|
862
850
|
const found = wallets.some((w) => w.toLowerCase() === checksumAddress.toLowerCase());
|
|
863
851
|
if (!found) {
|
|
@@ -868,7 +856,7 @@ export function registerWalletCommands(program) {
|
|
|
868
856
|
catch { /* allow override if factory call fails */ }
|
|
869
857
|
}
|
|
870
858
|
config.walletContractAddress = checksumAddress;
|
|
871
|
-
saveConfig(config);
|
|
859
|
+
(0, config_1.saveConfig)(config);
|
|
872
860
|
console.log(`Active wallet set to ${checksumAddress}`);
|
|
873
861
|
});
|
|
874
862
|
// ─── deploy ────────────────────────────────────────────────────────────────
|
|
@@ -878,83 +866,61 @@ export function registerWalletCommands(program) {
|
|
|
878
866
|
.option("--hardware", "Hardware wallet mode: show raw wc: URI only (for Ledger Live, Trezor Suite, etc.)")
|
|
879
867
|
.option("--sponsored", "Use CDP paymaster for gas sponsorship (requires paymasterUrl + cdpKeyName + CDP_PRIVATE_KEY env)")
|
|
880
868
|
.option("--dry-run", "Simulate the deployment ceremony without sending transactions")
|
|
881
|
-
.option("--force", "Deploy even if a wallet is already configured")
|
|
882
869
|
.action(async (opts) => {
|
|
883
|
-
const config = loadConfig();
|
|
884
|
-
// ── Check for existing wallet (allow resume if onboarding incomplete) ──
|
|
885
|
-
if (config.walletContractAddress && !config.onboardingProgress) {
|
|
886
|
-
const addr = config.walletContractAddress;
|
|
887
|
-
console.log();
|
|
888
|
-
console.log(` ${c.mark} Wallet already deployed at ${c.white(addr)}`);
|
|
889
|
-
console.log(` Use ${c.white("wallet status")} to check it.`);
|
|
890
|
-
console.log(` Use ${c.white("wallet deploy --force")} to deploy another wallet.`);
|
|
891
|
-
console.log();
|
|
892
|
-
if (!opts.force)
|
|
893
|
-
return;
|
|
894
|
-
console.log(` ${c.warning} Deploying a second wallet (--force)...`);
|
|
895
|
-
console.log();
|
|
896
|
-
}
|
|
897
|
-
else if (config.walletContractAddress && config.onboardingProgress) {
|
|
898
|
-
const step = config.onboardingProgress.step ?? 0;
|
|
899
|
-
const completed = config.onboardingProgress.completedSteps ?? [];
|
|
900
|
-
console.log();
|
|
901
|
-
console.log(` ${c.dim("◈")} Resuming onboarding for ${c.white(config.walletContractAddress)}`);
|
|
902
|
-
console.log(` Completed: ${completed.join(", ") || "none"} (step ${step})`);
|
|
903
|
-
console.log();
|
|
904
|
-
}
|
|
870
|
+
const config = (0, config_1.loadConfig)();
|
|
905
871
|
if (opts.dryRun) {
|
|
906
|
-
const factoryAddr = config.walletFactoryAddress ?? NETWORK_DEFAULTS[config.network]?.walletFactoryAddress ?? "(not configured)";
|
|
872
|
+
const factoryAddr = config.walletFactoryAddress ?? config_1.NETWORK_DEFAULTS[config.network]?.walletFactoryAddress ?? "(not configured)";
|
|
907
873
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
908
874
|
console.log();
|
|
909
|
-
console.log(" " + c.dim("── Dry run: wallet deploy ──────────────────────────────────────"));
|
|
910
|
-
console.log(" " + c.dim("Network: ") + c.white(config.network));
|
|
911
|
-
console.log(" " + c.dim("Chain ID: ") + c.white(String(chainId)));
|
|
912
|
-
console.log(" " + c.dim("RPC: ") + c.white(config.rpcUrl));
|
|
913
|
-
console.log(" " + c.dim("WalletFactory: ") + c.white(factoryAddr));
|
|
914
|
-
console.log(" " + c.dim("Signing method: ") + c.white(opts.smartWallet ? "Base Smart Wallet" : opts.hardware ? "Hardware (WC URI)" : "WalletConnect"));
|
|
915
|
-
console.log(" " + c.dim("Sponsored: ") + c.white(opts.sponsored ? "yes" : "no"));
|
|
875
|
+
console.log(" " + colors_1.c.dim("── Dry run: wallet deploy ──────────────────────────────────────"));
|
|
876
|
+
console.log(" " + colors_1.c.dim("Network: ") + colors_1.c.white(config.network));
|
|
877
|
+
console.log(" " + colors_1.c.dim("Chain ID: ") + colors_1.c.white(String(chainId)));
|
|
878
|
+
console.log(" " + colors_1.c.dim("RPC: ") + colors_1.c.white(config.rpcUrl));
|
|
879
|
+
console.log(" " + colors_1.c.dim("WalletFactory: ") + colors_1.c.white(factoryAddr));
|
|
880
|
+
console.log(" " + colors_1.c.dim("Signing method: ") + colors_1.c.white(opts.smartWallet ? "Base Smart Wallet" : opts.hardware ? "Hardware (WC URI)" : "WalletConnect"));
|
|
881
|
+
console.log(" " + colors_1.c.dim("Sponsored: ") + colors_1.c.white(opts.sponsored ? "yes" : "no"));
|
|
916
882
|
console.log();
|
|
917
|
-
console.log(" " + c.dim("Steps that would run:"));
|
|
883
|
+
console.log(" " + colors_1.c.dim("Steps that would run:"));
|
|
918
884
|
console.log(" 1. Connect " + (opts.smartWallet ? "Coinbase Smart Wallet" : "WalletConnect") + " session");
|
|
919
885
|
console.log(" 2. Call WalletFactory.createWallet() → deploy ARC402Wallet");
|
|
920
886
|
console.log(" 3. Save walletContractAddress to config");
|
|
921
887
|
console.log(" 4. Run onboarding ceremony (PolicyEngine, machine key, agent registration)");
|
|
922
888
|
console.log();
|
|
923
|
-
console.log(" " + c.dim("No transactions sent (--dry-run mode)."));
|
|
889
|
+
console.log(" " + colors_1.c.dim("No transactions sent (--dry-run mode)."));
|
|
924
890
|
console.log();
|
|
925
891
|
return;
|
|
926
892
|
}
|
|
927
|
-
const factoryAddress = config.walletFactoryAddress ?? NETWORK_DEFAULTS[config.network]?.walletFactoryAddress;
|
|
893
|
+
const factoryAddress = config.walletFactoryAddress ?? config_1.NETWORK_DEFAULTS[config.network]?.walletFactoryAddress;
|
|
928
894
|
if (!factoryAddress) {
|
|
929
895
|
console.error("walletFactoryAddress not found in config or NETWORK_DEFAULTS. Add walletFactoryAddress to your config.");
|
|
930
896
|
process.exit(1);
|
|
931
897
|
}
|
|
932
898
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
933
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
934
|
-
const factoryInterface = new ethers.Interface(WALLET_FACTORY_ABI);
|
|
899
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
900
|
+
const factoryInterface = new ethers_1.ethers.Interface(abis_1.WALLET_FACTORY_ABI);
|
|
935
901
|
if (opts.sponsored) {
|
|
936
902
|
// ── Sponsored deploy via CDP paymaster + ERC-4337 bundler ─────────────
|
|
937
903
|
// Note: WalletFactoryV3/V4 use msg.sender as wallet owner. In ERC-4337
|
|
938
904
|
// context msg.sender = EntryPoint. A factory upgrade with explicit owner
|
|
939
905
|
// param is needed for fully correct sponsored deployment. Until then,
|
|
940
906
|
// this path is available for testing and future-proofing.
|
|
941
|
-
const paymasterUrl = config.paymasterUrl ?? NETWORK_DEFAULTS[config.network]?.paymasterUrl;
|
|
907
|
+
const paymasterUrl = config.paymasterUrl ?? config_1.NETWORK_DEFAULTS[config.network]?.paymasterUrl;
|
|
942
908
|
const cdpKeyName = config.cdpKeyName ?? process.env.CDP_KEY_NAME;
|
|
943
909
|
const cdpPrivateKey = config.cdpPrivateKey ?? process.env.CDP_PRIVATE_KEY;
|
|
944
910
|
if (!paymasterUrl) {
|
|
945
911
|
console.error("paymasterUrl not configured. Add it to config or set NEXT_PUBLIC_PAYMASTER_URL.");
|
|
946
912
|
process.exit(1);
|
|
947
913
|
}
|
|
948
|
-
const { signer, address: ownerAddress } = await requireSigner(config);
|
|
914
|
+
const { signer, address: ownerAddress } = await (0, client_1.requireSigner)(config);
|
|
949
915
|
const bundlerUrl = process.env.BUNDLER_URL ?? "https://api.pimlico.io/v2/base/rpc";
|
|
950
|
-
const pm = new PaymasterClient(paymasterUrl, cdpKeyName, cdpPrivateKey);
|
|
951
|
-
const bundler = new BundlerClient(bundlerUrl, DEFAULT_ENTRY_POINT, chainId);
|
|
916
|
+
const pm = new bundler_1.PaymasterClient(paymasterUrl, cdpKeyName, cdpPrivateKey);
|
|
917
|
+
const bundler = new bundler_1.BundlerClient(bundlerUrl, bundler_1.DEFAULT_ENTRY_POINT, chainId);
|
|
952
918
|
console.log(`Sponsoring deploy via ${paymasterUrl}...`);
|
|
953
|
-
const factoryIface = new ethers.Interface(WALLET_FACTORY_ABI);
|
|
954
|
-
const factoryData = factoryIface.encodeFunctionData("createWallet", [DEFAULT_ENTRY_POINT]);
|
|
919
|
+
const factoryIface = new ethers_1.ethers.Interface(abis_1.WALLET_FACTORY_ABI);
|
|
920
|
+
const factoryData = factoryIface.encodeFunctionData("createWallet", [bundler_1.DEFAULT_ENTRY_POINT]);
|
|
955
921
|
// Predict counterfactual sender address using EntryPoint.getSenderAddress
|
|
956
|
-
const entryPoint = new ethers.Contract(DEFAULT_ENTRY_POINT, ["function getSenderAddress(bytes calldata initCode) external"], provider);
|
|
957
|
-
const initCodePacked = ethers.concat([factoryAddress, factoryData]);
|
|
922
|
+
const entryPoint = new ethers_1.ethers.Contract(bundler_1.DEFAULT_ENTRY_POINT, ["function getSenderAddress(bytes calldata initCode) external"], provider);
|
|
923
|
+
const initCodePacked = ethers_1.ethers.concat([factoryAddress, factoryData]);
|
|
958
924
|
let senderAddress;
|
|
959
925
|
try {
|
|
960
926
|
// getSenderAddress always reverts with SenderAddressResult(address)
|
|
@@ -968,7 +934,7 @@ export function registerWalletCommands(program) {
|
|
|
968
934
|
console.error("Could not predict wallet address:", msg);
|
|
969
935
|
process.exit(1);
|
|
970
936
|
}
|
|
971
|
-
senderAddress = ethers.getAddress("0x" + match[1].slice(24));
|
|
937
|
+
senderAddress = ethers_1.ethers.getAddress("0x" + match[1].slice(24));
|
|
972
938
|
}
|
|
973
939
|
console.log(`Predicted wallet address: ${senderAddress}`);
|
|
974
940
|
const userOp = await pm.sponsorUserOperation({
|
|
@@ -977,22 +943,22 @@ export function registerWalletCommands(program) {
|
|
|
977
943
|
callData: "0x",
|
|
978
944
|
factory: factoryAddress,
|
|
979
945
|
factoryData,
|
|
980
|
-
callGasLimit: ethers.toBeHex(
|
|
981
|
-
verificationGasLimit: ethers.toBeHex(
|
|
982
|
-
preVerificationGas: ethers.toBeHex(
|
|
983
|
-
maxFeePerGas: ethers.toBeHex((await provider.getFeeData()).maxFeePerGas ?? BigInt(
|
|
984
|
-
maxPriorityFeePerGas: ethers.toBeHex((await provider.getFeeData()).maxPriorityFeePerGas ?? BigInt(
|
|
946
|
+
callGasLimit: ethers_1.ethers.toBeHex(300000),
|
|
947
|
+
verificationGasLimit: ethers_1.ethers.toBeHex(400000),
|
|
948
|
+
preVerificationGas: ethers_1.ethers.toBeHex(60000),
|
|
949
|
+
maxFeePerGas: ethers_1.ethers.toBeHex((await provider.getFeeData()).maxFeePerGas ?? BigInt(1000000000)),
|
|
950
|
+
maxPriorityFeePerGas: ethers_1.ethers.toBeHex((await provider.getFeeData()).maxPriorityFeePerGas ?? BigInt(100000000)),
|
|
985
951
|
signature: "0x",
|
|
986
|
-
}, DEFAULT_ENTRY_POINT);
|
|
952
|
+
}, bundler_1.DEFAULT_ENTRY_POINT);
|
|
987
953
|
// Sign UserOp with owner key
|
|
988
|
-
const userOpHash = ethers.keccak256(ethers.AbiCoder.defaultAbiCoder().encode(["address", "uint256", "bytes32", "bytes32", "bytes32", "uint256", "bytes32", "bytes32"], [
|
|
954
|
+
const userOpHash = ethers_1.ethers.keccak256(ethers_1.ethers.AbiCoder.defaultAbiCoder().encode(["address", "uint256", "bytes32", "bytes32", "bytes32", "uint256", "bytes32", "bytes32"], [
|
|
989
955
|
userOp.sender, BigInt(userOp.nonce),
|
|
990
|
-
ethers.keccak256(userOp.factory ? ethers.concat([userOp.factory, userOp.factoryData ?? "0x"]) : "0x"),
|
|
991
|
-
ethers.keccak256(userOp.callData),
|
|
992
|
-
ethers.keccak256(ethers.AbiCoder.defaultAbiCoder().encode(["uint256", "uint256", "uint256", "uint256", "uint256", "address", "bytes"], [userOp.verificationGasLimit, userOp.callGasLimit, userOp.preVerificationGas, userOp.maxFeePerGas, userOp.maxPriorityFeePerGas, userOp.paymaster ?? ethers.ZeroAddress, userOp.paymasterData ?? "0x"])),
|
|
993
|
-
BigInt(chainId), DEFAULT_ENTRY_POINT, ethers.ZeroHash,
|
|
956
|
+
ethers_1.ethers.keccak256(userOp.factory ? ethers_1.ethers.concat([userOp.factory, userOp.factoryData ?? "0x"]) : "0x"),
|
|
957
|
+
ethers_1.ethers.keccak256(userOp.callData),
|
|
958
|
+
ethers_1.ethers.keccak256(ethers_1.ethers.AbiCoder.defaultAbiCoder().encode(["uint256", "uint256", "uint256", "uint256", "uint256", "address", "bytes"], [userOp.verificationGasLimit, userOp.callGasLimit, userOp.preVerificationGas, userOp.maxFeePerGas, userOp.maxPriorityFeePerGas, userOp.paymaster ?? ethers_1.ethers.ZeroAddress, userOp.paymasterData ?? "0x"])),
|
|
959
|
+
BigInt(chainId), bundler_1.DEFAULT_ENTRY_POINT, ethers_1.ethers.ZeroHash,
|
|
994
960
|
]));
|
|
995
|
-
userOp.signature = await signer.signMessage(ethers.getBytes(userOpHash));
|
|
961
|
+
userOp.signature = await signer.signMessage(ethers_1.ethers.getBytes(userOpHash));
|
|
996
962
|
const userOpHash2 = await bundler.sendUserOperation(userOp);
|
|
997
963
|
console.log(`UserOp submitted: ${userOpHash2}`);
|
|
998
964
|
console.log("Waiting for confirmation...");
|
|
@@ -1003,24 +969,24 @@ export function registerWalletCommands(program) {
|
|
|
1003
969
|
}
|
|
1004
970
|
config.walletContractAddress = senderAddress;
|
|
1005
971
|
config.ownerAddress = ownerAddress;
|
|
1006
|
-
saveConfig(config);
|
|
1007
|
-
console.log("\n" + c.success + c.white(" ARC402Wallet deployed (sponsored)"));
|
|
1008
|
-
renderTree([
|
|
972
|
+
(0, config_1.saveConfig)(config);
|
|
973
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(" ARC402Wallet deployed (sponsored)"));
|
|
974
|
+
(0, tree_1.renderTree)([
|
|
1009
975
|
{ label: "Wallet", value: senderAddress },
|
|
1010
976
|
{ label: "Owner", value: ownerAddress },
|
|
1011
977
|
{ label: "Gas", value: "Sponsorship active — initial setup ops are free", last: true },
|
|
1012
978
|
]);
|
|
1013
|
-
console.log(" " + c.warning + " " + c.yellow("IMPORTANT: Onboarding ceremony was not run on this wallet."));
|
|
1014
|
-
console.log(c.dim(" Category spend limits have NOT been configured. All executeSpend and"));
|
|
1015
|
-
console.log(c.dim(` executeTokenSpend calls will fail with "PolicyEngine: category not configured"`));
|
|
1016
|
-
console.log(c.dim(" until you run governance setup manually via WalletConnect:"));
|
|
1017
|
-
console.log("\n" + c.dim(" arc402 wallet governance setup"));
|
|
1018
|
-
console.log("\n" + c.dim(" This must be done before making any spend from this wallet."));
|
|
1019
|
-
console.log("\n" + c.dim("Next: arc402 wallet set-passkey <x> <y> --sponsored"));
|
|
979
|
+
console.log(" " + colors_1.c.warning + " " + colors_1.c.yellow("IMPORTANT: Onboarding ceremony was not run on this wallet."));
|
|
980
|
+
console.log(colors_1.c.dim(" Category spend limits have NOT been configured. All executeSpend and"));
|
|
981
|
+
console.log(colors_1.c.dim(` executeTokenSpend calls will fail with "PolicyEngine: category not configured"`));
|
|
982
|
+
console.log(colors_1.c.dim(" until you run governance setup manually via WalletConnect:"));
|
|
983
|
+
console.log("\n" + colors_1.c.dim(" arc402 wallet governance setup"));
|
|
984
|
+
console.log("\n" + colors_1.c.dim(" This must be done before making any spend from this wallet."));
|
|
985
|
+
console.log("\n" + colors_1.c.dim("Next: arc402 wallet set-passkey <x> <y> --sponsored"));
|
|
1020
986
|
printOpenShellHint();
|
|
1021
987
|
}
|
|
1022
988
|
else if (opts.smartWallet) {
|
|
1023
|
-
const { txHash, account } = await requestCoinbaseSmartWalletSignature(chainId, (ownerAccount) => ({
|
|
989
|
+
const { txHash, account } = await (0, coinbase_smart_wallet_1.requestCoinbaseSmartWalletSignature)(chainId, (ownerAccount) => ({
|
|
1024
990
|
to: factoryAddress,
|
|
1025
991
|
data: factoryInterface.encodeFunctionData("createWallet", ["0x0000000071727De22E5E9d8BAf0edAc6f37da032"]),
|
|
1026
992
|
value: "0x0",
|
|
@@ -1033,7 +999,7 @@ export function registerWalletCommands(program) {
|
|
|
1033
999
|
process.exit(1);
|
|
1034
1000
|
}
|
|
1035
1001
|
let walletAddress = null;
|
|
1036
|
-
const factoryContract = new ethers.Contract(factoryAddress, WALLET_FACTORY_ABI, provider);
|
|
1002
|
+
const factoryContract = new ethers_1.ethers.Contract(factoryAddress, abis_1.WALLET_FACTORY_ABI, provider);
|
|
1037
1003
|
for (const log of receipt.logs) {
|
|
1038
1004
|
try {
|
|
1039
1005
|
const parsed = factoryContract.interface.parseLog(log);
|
|
@@ -1050,14 +1016,14 @@ export function registerWalletCommands(program) {
|
|
|
1050
1016
|
}
|
|
1051
1017
|
config.walletContractAddress = walletAddress;
|
|
1052
1018
|
config.ownerAddress = account;
|
|
1053
|
-
saveConfig(config);
|
|
1054
|
-
console.log("\n" + c.success + c.white(" ARC402Wallet deployed"));
|
|
1055
|
-
renderTree([
|
|
1019
|
+
(0, config_1.saveConfig)(config);
|
|
1020
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(" ARC402Wallet deployed"));
|
|
1021
|
+
(0, tree_1.renderTree)([
|
|
1056
1022
|
{ label: "Wallet", value: walletAddress },
|
|
1057
|
-
{ label: "Owner", value: account + c.dim(" (Base Smart Wallet)"), last: true },
|
|
1023
|
+
{ label: "Owner", value: account + colors_1.c.dim(" (Base Smart Wallet)"), last: true },
|
|
1058
1024
|
]);
|
|
1059
|
-
console.log(c.dim("Your wallet contract is ready for policy enforcement"));
|
|
1060
|
-
console.log(c.dim("\nNext: run 'arc402 wallet set-guardian' to configure the emergency guardian key."));
|
|
1025
|
+
console.log(colors_1.c.dim("Your wallet contract is ready for policy enforcement"));
|
|
1026
|
+
console.log(colors_1.c.dim("\nNext: run 'arc402 wallet set-guardian' to configure the emergency guardian key."));
|
|
1061
1027
|
printOpenShellHint();
|
|
1062
1028
|
}
|
|
1063
1029
|
else if (config.walletConnectProjectId) {
|
|
@@ -1074,37 +1040,37 @@ export function registerWalletCommands(program) {
|
|
|
1074
1040
|
2: "machine key", 3: "passkey", 4: "policy setup", 5: "agent registration",
|
|
1075
1041
|
};
|
|
1076
1042
|
const nextStep = (resumeProgress.step ?? 1) + 1;
|
|
1077
|
-
console.log(" " + c.dim(`◈ Resuming onboarding from step ${nextStep} (${stepNames[nextStep] ?? "ceremony"})...`));
|
|
1043
|
+
console.log(" " + colors_1.c.dim(`◈ Resuming onboarding from step ${nextStep} (${stepNames[nextStep] ?? "ceremony"})...`));
|
|
1078
1044
|
}
|
|
1079
1045
|
// ── Gas estimation ─────────────────────────────────────────────────────
|
|
1080
1046
|
if (!isResuming) {
|
|
1081
1047
|
let gasMsg = "~0.003 ETH (6 transactions on Base)";
|
|
1082
1048
|
try {
|
|
1083
1049
|
const feeData = await provider.getFeeData();
|
|
1084
|
-
const gasPrice = feeData.maxFeePerGas ?? feeData.gasPrice ?? BigInt(
|
|
1050
|
+
const gasPrice = feeData.maxFeePerGas ?? feeData.gasPrice ?? BigInt(1500000000);
|
|
1085
1051
|
const deployGas = await provider.estimateGas({
|
|
1086
1052
|
to: factoryAddress,
|
|
1087
1053
|
data: factoryInterface.encodeFunctionData("createWallet", ["0x0000000071727De22E5E9d8BAf0edAc6f37da032"]),
|
|
1088
|
-
}).catch(() => BigInt(
|
|
1089
|
-
const ceremonyGas = BigInt(
|
|
1090
|
-
const totalGasEth = parseFloat(ethers.formatEther((deployGas + ceremonyGas) * gasPrice));
|
|
1054
|
+
}).catch(() => BigInt(280000));
|
|
1055
|
+
const ceremonyGas = BigInt(700000); // ~5 ceremony txs × ~140k each
|
|
1056
|
+
const totalGasEth = parseFloat(ethers_1.ethers.formatEther((deployGas + ceremonyGas) * gasPrice));
|
|
1091
1057
|
gasMsg = `~${totalGasEth.toFixed(4)} ETH (6 transactions on Base)`;
|
|
1092
1058
|
}
|
|
1093
1059
|
catch { /* use default */ }
|
|
1094
|
-
console.log(" " + c.dim(`◈ Estimated gas: ${gasMsg}`));
|
|
1060
|
+
console.log(" " + colors_1.c.dim(`◈ Estimated gas: ${gasMsg}`));
|
|
1095
1061
|
}
|
|
1096
1062
|
// ── Step 1: Connect ────────────────────────────────────────────────────
|
|
1097
1063
|
const connectPrompt = isResuming
|
|
1098
1064
|
? "Connect wallet to resume onboarding"
|
|
1099
1065
|
: "Approve ARC402Wallet deployment — you will be set as owner";
|
|
1100
|
-
const { client, session, account } = await connectPhoneWallet(config.walletConnectProjectId, chainId, config, { telegramOpts, prompt: connectPrompt, hardware: !!opts.hardware });
|
|
1066
|
+
const { client, session, account } = await (0, walletconnect_1.connectPhoneWallet)(config.walletConnectProjectId, chainId, config, { telegramOpts, prompt: connectPrompt, hardware: !!opts.hardware });
|
|
1101
1067
|
const networkName = chainId === 8453 ? "Base" : "Base Sepolia";
|
|
1102
1068
|
const shortAddr = `${account.slice(0, 6)}...${account.slice(-5)}`;
|
|
1103
|
-
console.log("\n" + c.success + c.white(` Connected: ${shortAddr} on ${networkName}`));
|
|
1069
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(` Connected: ${shortAddr} on ${networkName}`));
|
|
1104
1070
|
if (telegramOpts && !isResuming) {
|
|
1105
1071
|
// Send "connected" message with a deploy confirmation button.
|
|
1106
1072
|
// TODO: wire up full callback_data round-trip when a persistent bot process is available.
|
|
1107
|
-
await sendTelegramMessage({
|
|
1073
|
+
await (0, telegram_notify_1.sendTelegramMessage)({
|
|
1108
1074
|
botToken: telegramOpts.botToken,
|
|
1109
1075
|
chatId: telegramOpts.chatId,
|
|
1110
1076
|
threadId: telegramOpts.threadId,
|
|
@@ -1116,13 +1082,13 @@ export function registerWalletCommands(program) {
|
|
|
1116
1082
|
if (isResuming) {
|
|
1117
1083
|
// Resume: skip deploy, use existing wallet
|
|
1118
1084
|
walletAddress = config.walletContractAddress;
|
|
1119
|
-
console.log(" " + c.dim(`◈ Using existing wallet: ${walletAddress}`));
|
|
1085
|
+
console.log(" " + colors_1.c.dim(`◈ Using existing wallet: ${walletAddress}`));
|
|
1120
1086
|
}
|
|
1121
1087
|
else {
|
|
1122
1088
|
// ── Step 2: Confirm & Deploy ─────────────────────────────────────────
|
|
1123
1089
|
// WalletConnect approval already confirmed intent — sending automatically
|
|
1124
1090
|
console.log("Deploying...");
|
|
1125
|
-
const txHash = await sendTransactionWithSession(client, session, account, chainId, {
|
|
1091
|
+
const txHash = await (0, walletconnect_1.sendTransactionWithSession)(client, session, account, chainId, {
|
|
1126
1092
|
to: factoryAddress,
|
|
1127
1093
|
data: factoryInterface.encodeFunctionData("createWallet", ["0x0000000071727De22E5E9d8BAf0edAc6f37da032"]),
|
|
1128
1094
|
value: "0x0",
|
|
@@ -1135,7 +1101,7 @@ export function registerWalletCommands(program) {
|
|
|
1135
1101
|
process.exit(1);
|
|
1136
1102
|
}
|
|
1137
1103
|
let deployedWallet = null;
|
|
1138
|
-
const factoryContract = new ethers.Contract(factoryAddress, WALLET_FACTORY_ABI, provider);
|
|
1104
|
+
const factoryContract = new ethers_1.ethers.Contract(factoryAddress, abis_1.WALLET_FACTORY_ABI, provider);
|
|
1139
1105
|
for (const log of receipt.logs) {
|
|
1140
1106
|
try {
|
|
1141
1107
|
const parsed = factoryContract.interface.parseLog(log);
|
|
@@ -1154,24 +1120,24 @@ export function registerWalletCommands(program) {
|
|
|
1154
1120
|
// ── Step 1 complete: save wallet + owner immediately ─────────────────
|
|
1155
1121
|
config.walletContractAddress = walletAddress;
|
|
1156
1122
|
config.ownerAddress = account;
|
|
1157
|
-
saveConfig(config);
|
|
1123
|
+
(0, config_1.saveConfig)(config);
|
|
1158
1124
|
try {
|
|
1159
|
-
|
|
1125
|
+
fs_1.default.chmodSync((0, config_1.getConfigPath)(), 0o600);
|
|
1160
1126
|
}
|
|
1161
1127
|
catch { /* best-effort */ }
|
|
1162
|
-
console.log("\n " + c.success + c.white(" Wallet deployed"));
|
|
1163
|
-
renderTree([
|
|
1128
|
+
console.log("\n " + colors_1.c.success + colors_1.c.white(" Wallet deployed"));
|
|
1129
|
+
(0, tree_1.renderTree)([
|
|
1164
1130
|
{ label: "Wallet", value: walletAddress },
|
|
1165
1131
|
{ label: "Owner", value: account, last: true },
|
|
1166
1132
|
]);
|
|
1167
1133
|
}
|
|
1168
1134
|
// ── Steps 2–6: Complete onboarding ceremony (same WalletConnect session)
|
|
1169
1135
|
const sendTxCeremony = async (call, description) => {
|
|
1170
|
-
console.log(" " + c.dim(`◈ ${description}`));
|
|
1171
|
-
const hash = await sendTransactionWithSession(client, session, account, chainId, call);
|
|
1172
|
-
console.log(" " + c.dim(" waiting for confirmation..."));
|
|
1136
|
+
console.log(" " + colors_1.c.dim(`◈ ${description}`));
|
|
1137
|
+
const hash = await (0, walletconnect_1.sendTransactionWithSession)(client, session, account, chainId, call);
|
|
1138
|
+
console.log(" " + colors_1.c.dim(" waiting for confirmation..."));
|
|
1173
1139
|
await provider.waitForTransaction(hash, 1);
|
|
1174
|
-
console.log(" " + c.success + " " + c.white(description));
|
|
1140
|
+
console.log(" " + colors_1.c.success + " " + colors_1.c.white(description));
|
|
1175
1141
|
return hash;
|
|
1176
1142
|
};
|
|
1177
1143
|
await runCompleteOnboardingCeremony(walletAddress, account, config, provider, sendTxCeremony);
|
|
@@ -1180,9 +1146,9 @@ export function registerWalletCommands(program) {
|
|
|
1180
1146
|
else {
|
|
1181
1147
|
console.warn("⚠ WalletConnect not configured. Using stored private key (insecure).");
|
|
1182
1148
|
console.warn(" Run `arc402 config set walletConnectProjectId <id>` to enable phone wallet signing.");
|
|
1183
|
-
const { signer, address } = await requireSigner(config);
|
|
1184
|
-
const factory = new ethers.Contract(factoryAddress, WALLET_FACTORY_ABI, signer);
|
|
1185
|
-
const deploySpinner = startSpinner(`Deploying ARC402Wallet via factory at ${factoryAddress}...`);
|
|
1149
|
+
const { signer, address } = await (0, client_1.requireSigner)(config);
|
|
1150
|
+
const factory = new ethers_1.ethers.Contract(factoryAddress, abis_1.WALLET_FACTORY_ABI, signer);
|
|
1151
|
+
const deploySpinner = (0, spinner_1.startSpinner)(`Deploying ARC402Wallet via factory at ${factoryAddress}...`);
|
|
1186
1152
|
const tx = await factory.createWallet("0x0000000071727De22E5E9d8BAf0edAc6f37da032");
|
|
1187
1153
|
const receipt = await tx.wait();
|
|
1188
1154
|
let walletAddress = null;
|
|
@@ -1202,7 +1168,7 @@ export function registerWalletCommands(program) {
|
|
|
1202
1168
|
}
|
|
1203
1169
|
deploySpinner.succeed("Wallet deployed");
|
|
1204
1170
|
// Generate guardian key (separate from hot key) and call setGuardian
|
|
1205
|
-
const guardianWallet = ethers.Wallet.createRandom();
|
|
1171
|
+
const guardianWallet = ethers_1.ethers.Wallet.createRandom();
|
|
1206
1172
|
config.walletContractAddress = walletAddress;
|
|
1207
1173
|
config.ownerAddress = address;
|
|
1208
1174
|
config.guardianAddress = guardianWallet.address;
|
|
@@ -1210,23 +1176,23 @@ export function registerWalletCommands(program) {
|
|
|
1210
1176
|
saveGuardianKey(guardianWallet.privateKey);
|
|
1211
1177
|
if (config.guardianPrivateKey)
|
|
1212
1178
|
delete config.guardianPrivateKey;
|
|
1213
|
-
saveConfig(config);
|
|
1179
|
+
(0, config_1.saveConfig)(config);
|
|
1214
1180
|
// Call setGuardian on the deployed wallet
|
|
1215
|
-
const walletContract = new ethers.Contract(walletAddress, ARC402_WALLET_GUARDIAN_ABI, signer);
|
|
1181
|
+
const walletContract = new ethers_1.ethers.Contract(walletAddress, abis_1.ARC402_WALLET_GUARDIAN_ABI, signer);
|
|
1216
1182
|
const setGuardianTx = await walletContract.setGuardian(guardianWallet.address);
|
|
1217
1183
|
await setGuardianTx.wait();
|
|
1218
1184
|
// ── Mandatory onboarding ceremony (private key path) ──────────────────
|
|
1219
1185
|
console.log("\nRunning mandatory onboarding ceremony...");
|
|
1220
|
-
const provider2 = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
1186
|
+
const provider2 = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
1221
1187
|
await runWalletOnboardingCeremony(walletAddress, address, config, provider2, async (call, description) => {
|
|
1222
|
-
console.log(" " + c.dim(`Sending: ${description}`));
|
|
1188
|
+
console.log(" " + colors_1.c.dim(`Sending: ${description}`));
|
|
1223
1189
|
const tx2 = await signer.sendTransaction({ to: call.to, data: call.data, value: call.value === "0x0" ? 0n : BigInt(call.value) });
|
|
1224
1190
|
await tx2.wait(1);
|
|
1225
|
-
console.log(" " + c.success + " " + c.dim(description) + " " + c.dim(tx2.hash));
|
|
1191
|
+
console.log(" " + colors_1.c.success + " " + colors_1.c.dim(description) + " " + colors_1.c.dim(tx2.hash));
|
|
1226
1192
|
return tx2.hash;
|
|
1227
1193
|
});
|
|
1228
|
-
console.log(` ${c.success} ARC402Wallet deployed`);
|
|
1229
|
-
renderTree([
|
|
1194
|
+
console.log(` ${colors_1.c.success} ARC402Wallet deployed`);
|
|
1195
|
+
(0, tree_1.renderTree)([
|
|
1230
1196
|
{ label: "Wallet", value: walletAddress },
|
|
1231
1197
|
{ label: "Guardian", value: guardianWallet.address, last: true },
|
|
1232
1198
|
]);
|
|
@@ -1240,12 +1206,12 @@ export function registerWalletCommands(program) {
|
|
|
1240
1206
|
.description("Send ETH from configured wallet (amount: '0.001eth' or wei)")
|
|
1241
1207
|
.option("--json")
|
|
1242
1208
|
.action(async (to, amountRaw, opts) => {
|
|
1243
|
-
const config = loadConfig();
|
|
1244
|
-
const { signer } = await requireSigner(config);
|
|
1209
|
+
const config = (0, config_1.loadConfig)();
|
|
1210
|
+
const { signer } = await (0, client_1.requireSigner)(config);
|
|
1245
1211
|
const value = parseAmount(amountRaw);
|
|
1246
1212
|
const tx = await signer.sendTransaction({ to, value });
|
|
1247
1213
|
if (opts.json) {
|
|
1248
|
-
console.log(JSON.stringify({ txHash: tx.hash, to, amount: ethers.formatEther(value) }));
|
|
1214
|
+
console.log(JSON.stringify({ txHash: tx.hash, to, amount: ethers_1.ethers.formatEther(value) }));
|
|
1249
1215
|
}
|
|
1250
1216
|
else {
|
|
1251
1217
|
console.log(`Tx hash: ${tx.hash}`);
|
|
@@ -1257,22 +1223,22 @@ export function registerWalletCommands(program) {
|
|
|
1257
1223
|
.description("Show per-tx and daily spending limits for a category")
|
|
1258
1224
|
.requiredOption("--category <cat>", "Category name (e.g. code.review)")
|
|
1259
1225
|
.action(async (opts) => {
|
|
1260
|
-
const config = loadConfig();
|
|
1226
|
+
const config = (0, config_1.loadConfig)();
|
|
1261
1227
|
const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
|
|
1262
1228
|
const walletAddr = config.walletContractAddress;
|
|
1263
1229
|
if (!walletAddr) {
|
|
1264
1230
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
1265
1231
|
process.exit(1);
|
|
1266
1232
|
}
|
|
1267
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
1268
|
-
const contract = new ethers.Contract(policyAddress, POLICY_ENGINE_LIMITS_ABI, provider);
|
|
1233
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
1234
|
+
const contract = new ethers_1.ethers.Contract(policyAddress, abis_1.POLICY_ENGINE_LIMITS_ABI, provider);
|
|
1269
1235
|
const [perTxLimit, dailyLimit] = await Promise.all([
|
|
1270
1236
|
contract.categoryLimits(walletAddr, opts.category),
|
|
1271
1237
|
contract.dailyCategoryLimit(walletAddr, opts.category),
|
|
1272
1238
|
]);
|
|
1273
1239
|
console.log(`Category: ${opts.category}`);
|
|
1274
|
-
console.log(`Per-tx: ${perTxLimit === 0n ? "(not set)" : ethers.formatEther(perTxLimit) + " ETH"}`);
|
|
1275
|
-
console.log(`Daily: ${dailyLimit === 0n ? "(not set)" : ethers.formatEther(dailyLimit) + " ETH"}`);
|
|
1240
|
+
console.log(`Per-tx: ${perTxLimit === 0n ? "(not set)" : ethers_1.ethers.formatEther(perTxLimit) + " ETH"}`);
|
|
1241
|
+
console.log(`Daily: ${dailyLimit === 0n ? "(not set)" : ethers_1.ethers.formatEther(dailyLimit) + " ETH"}`);
|
|
1276
1242
|
if (dailyLimit > 0n) {
|
|
1277
1243
|
console.log(`\nNote: Daily limits use two 12-hour buckets (current + previous window).`);
|
|
1278
1244
|
console.log(` The effective limit applies across a rolling 12-24 hour period, not a strict calendar day.`);
|
|
@@ -1283,19 +1249,19 @@ export function registerWalletCommands(program) {
|
|
|
1283
1249
|
.requiredOption("--category <cat>", "Category name (e.g. code.review)")
|
|
1284
1250
|
.requiredOption("--amount <eth>", "Limit in ETH (e.g. 0.1)")
|
|
1285
1251
|
.action(async (opts) => {
|
|
1286
|
-
const config = loadConfig();
|
|
1252
|
+
const config = (0, config_1.loadConfig)();
|
|
1287
1253
|
const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
|
|
1288
1254
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
1289
|
-
const amount = ethers.parseEther(opts.amount);
|
|
1290
|
-
const policyInterface = new ethers.Interface(POLICY_ENGINE_LIMITS_ABI);
|
|
1255
|
+
const amount = ethers_1.ethers.parseEther(opts.amount);
|
|
1256
|
+
const policyInterface = new ethers_1.ethers.Interface(abis_1.POLICY_ENGINE_LIMITS_ABI);
|
|
1291
1257
|
if (config.walletConnectProjectId) {
|
|
1292
1258
|
const walletAddr = config.walletContractAddress;
|
|
1293
1259
|
if (!walletAddr) {
|
|
1294
1260
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
1295
1261
|
process.exit(1);
|
|
1296
1262
|
}
|
|
1297
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
1298
|
-
const { txHash } = await requestPhoneWalletSignature(config.walletConnectProjectId, chainId, (account) => ({
|
|
1263
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
1264
|
+
const { txHash } = await (0, walletconnect_1.requestPhoneWalletSignature)(config.walletConnectProjectId, chainId, (account) => ({
|
|
1299
1265
|
to: policyAddress,
|
|
1300
1266
|
data: policyInterface.encodeFunctionData("setCategoryLimitFor", [walletAddr, opts.category, amount]),
|
|
1301
1267
|
value: "0x0",
|
|
@@ -1311,8 +1277,8 @@ export function registerWalletCommands(program) {
|
|
|
1311
1277
|
else {
|
|
1312
1278
|
console.warn("⚠ WalletConnect not configured. Using stored private key (insecure).");
|
|
1313
1279
|
console.warn(" Run `arc402 config set walletConnectProjectId <id>` to enable phone wallet signing.");
|
|
1314
|
-
const { signer, address } = await requireSigner(config);
|
|
1315
|
-
const contract = new ethers.Contract(policyAddress, POLICY_ENGINE_LIMITS_ABI, signer);
|
|
1280
|
+
const { signer, address } = await (0, client_1.requireSigner)(config);
|
|
1281
|
+
const contract = new ethers_1.ethers.Contract(policyAddress, abis_1.POLICY_ENGINE_LIMITS_ABI, signer);
|
|
1316
1282
|
await (await contract.setCategoryLimitFor(address, opts.category, amount)).wait();
|
|
1317
1283
|
console.log(`Spend limit for ${opts.category} set to ${opts.amount} ETH`);
|
|
1318
1284
|
}
|
|
@@ -1327,7 +1293,7 @@ export function registerWalletCommands(program) {
|
|
|
1327
1293
|
.requiredOption("--category <cat>", "Category name (e.g. compute)")
|
|
1328
1294
|
.requiredOption("--amount <eth>", "Daily limit in ETH (e.g. 0.5)")
|
|
1329
1295
|
.action(async (opts) => {
|
|
1330
|
-
const config = loadConfig();
|
|
1296
|
+
const config = (0, config_1.loadConfig)();
|
|
1331
1297
|
console.log(`\nNote: ARC-402 has two independent velocity limit layers:`);
|
|
1332
1298
|
console.log(` 1. Wallet-level (arc402 wallet set-velocity-limit): ETH cap per rolling hour, enforced by ARC402Wallet contract. Breach auto-freezes wallet.`);
|
|
1333
1299
|
console.log(` 2. PolicyEngine-level (arc402 wallet policy set-daily-limit): Per-category daily cap, enforced by PolicyEngine. Breach returns a soft error without freezing.`);
|
|
@@ -1339,14 +1305,14 @@ export function registerWalletCommands(program) {
|
|
|
1339
1305
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
1340
1306
|
process.exit(1);
|
|
1341
1307
|
}
|
|
1342
|
-
const amount = ethers.parseEther(opts.amount);
|
|
1308
|
+
const amount = ethers_1.ethers.parseEther(opts.amount);
|
|
1343
1309
|
console.log(`\nNote: Daily limits use two 12-hour buckets (current + previous window).`);
|
|
1344
1310
|
console.log(` The effective limit applies across a rolling 12-24 hour period, not a strict calendar day.`);
|
|
1345
1311
|
console.log(` Setting daily limit for category "${opts.category}" to ${opts.amount} ETH.\n`);
|
|
1346
|
-
const policyInterface = new ethers.Interface(POLICY_ENGINE_LIMITS_ABI);
|
|
1312
|
+
const policyInterface = new ethers_1.ethers.Interface(abis_1.POLICY_ENGINE_LIMITS_ABI);
|
|
1347
1313
|
if (config.walletConnectProjectId) {
|
|
1348
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
1349
|
-
const { txHash } = await requestPhoneWalletSignature(config.walletConnectProjectId, chainId, () => ({
|
|
1314
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
1315
|
+
const { txHash } = await (0, walletconnect_1.requestPhoneWalletSignature)(config.walletConnectProjectId, chainId, () => ({
|
|
1350
1316
|
to: policyAddress,
|
|
1351
1317
|
data: policyInterface.encodeFunctionData("setDailyLimitFor", [walletAddr, opts.category, amount]),
|
|
1352
1318
|
value: "0x0",
|
|
@@ -1360,8 +1326,8 @@ export function registerWalletCommands(program) {
|
|
|
1360
1326
|
}
|
|
1361
1327
|
else {
|
|
1362
1328
|
console.warn("⚠ WalletConnect not configured. Using stored private key (insecure).");
|
|
1363
|
-
const { signer, address } = await requireSigner(config);
|
|
1364
|
-
const contract = new ethers.Contract(policyAddress, POLICY_ENGINE_LIMITS_ABI, signer);
|
|
1329
|
+
const { signer, address } = await (0, client_1.requireSigner)(config);
|
|
1330
|
+
const contract = new ethers_1.ethers.Contract(policyAddress, abis_1.POLICY_ENGINE_LIMITS_ABI, signer);
|
|
1365
1331
|
await (await contract.setDailyLimitFor(address, opts.category, amount)).wait();
|
|
1366
1332
|
console.log(`Daily limit for ${opts.category} set to ${opts.amount} ETH (12/24h rolling window)`);
|
|
1367
1333
|
}
|
|
@@ -1369,7 +1335,7 @@ export function registerWalletCommands(program) {
|
|
|
1369
1335
|
walletPolicy.command("set <policyId>")
|
|
1370
1336
|
.description("Set the active policy ID on ARC402Wallet (phone wallet signs via WalletConnect)")
|
|
1371
1337
|
.action(async (policyId) => {
|
|
1372
|
-
const config = loadConfig();
|
|
1338
|
+
const config = (0, config_1.loadConfig)();
|
|
1373
1339
|
if (!config.walletContractAddress) {
|
|
1374
1340
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
1375
1341
|
process.exit(1);
|
|
@@ -1381,18 +1347,18 @@ export function registerWalletCommands(program) {
|
|
|
1381
1347
|
// Normalise policyId to bytes32 hex
|
|
1382
1348
|
let policyIdHex;
|
|
1383
1349
|
try {
|
|
1384
|
-
policyIdHex = ethers.zeroPadValue(ethers.hexlify(policyId.startsWith("0x") ? policyId : ethers.toUtf8Bytes(policyId)), 32);
|
|
1350
|
+
policyIdHex = ethers_1.ethers.zeroPadValue(ethers_1.ethers.hexlify(policyId.startsWith("0x") ? policyId : ethers_1.ethers.toUtf8Bytes(policyId)), 32);
|
|
1385
1351
|
}
|
|
1386
1352
|
catch {
|
|
1387
1353
|
console.error("Invalid policyId — must be a hex string (0x…) or UTF-8 label.");
|
|
1388
1354
|
process.exit(1);
|
|
1389
1355
|
}
|
|
1390
1356
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
1391
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
1392
|
-
const ownerInterface = new ethers.Interface(ARC402_WALLET_OWNER_ABI);
|
|
1357
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
1358
|
+
const ownerInterface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_OWNER_ABI);
|
|
1393
1359
|
let currentPolicy = "(unknown)";
|
|
1394
1360
|
try {
|
|
1395
|
-
const walletContract = new ethers.Contract(config.walletContractAddress, ARC402_WALLET_OWNER_ABI, provider);
|
|
1361
|
+
const walletContract = new ethers_1.ethers.Contract(config.walletContractAddress, abis_1.ARC402_WALLET_OWNER_ABI, provider);
|
|
1396
1362
|
currentPolicy = await walletContract.activePolicyId();
|
|
1397
1363
|
}
|
|
1398
1364
|
catch { /* contract may not be deployed yet */ }
|
|
@@ -1402,15 +1368,15 @@ export function registerWalletCommands(program) {
|
|
|
1402
1368
|
const telegramOpts = config.telegramBotToken && config.telegramChatId
|
|
1403
1369
|
? { botToken: config.telegramBotToken, chatId: config.telegramChatId, threadId: config.telegramThreadId }
|
|
1404
1370
|
: undefined;
|
|
1405
|
-
const { txHash } = await requestPhoneWalletSignature(config.walletConnectProjectId, chainId, () => ({
|
|
1371
|
+
const { txHash } = await (0, walletconnect_1.requestPhoneWalletSignature)(config.walletConnectProjectId, chainId, () => ({
|
|
1406
1372
|
to: config.walletContractAddress,
|
|
1407
1373
|
data: ownerInterface.encodeFunctionData("updatePolicy", [policyIdHex]),
|
|
1408
1374
|
value: "0x0",
|
|
1409
1375
|
}), `Approve: update policy to ${policyIdHex}`, telegramOpts, config);
|
|
1410
1376
|
await provider.waitForTransaction(txHash);
|
|
1411
|
-
console.log("\n" + c.success + c.white(" Active policy updated"));
|
|
1412
|
-
console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
|
|
1413
|
-
console.log(" " + c.dim("Policy:") + " " + c.white(policyIdHex));
|
|
1377
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(" Active policy updated"));
|
|
1378
|
+
console.log(" " + colors_1.c.dim("Tx:") + " " + colors_1.c.white(txHash));
|
|
1379
|
+
console.log(" " + colors_1.c.dim("Policy:") + " " + colors_1.c.white(policyIdHex));
|
|
1414
1380
|
});
|
|
1415
1381
|
// ─── freeze (guardian key — emergency wallet freeze) ──────────────────────
|
|
1416
1382
|
//
|
|
@@ -1422,7 +1388,7 @@ export function registerWalletCommands(program) {
|
|
|
1422
1388
|
.option("--drain", "Also drain all ETH to owner address (use when machine compromise is suspected)")
|
|
1423
1389
|
.option("--json")
|
|
1424
1390
|
.action(async (opts) => {
|
|
1425
|
-
const config = loadConfig();
|
|
1391
|
+
const config = (0, config_1.loadConfig)();
|
|
1426
1392
|
if (!config.walletContractAddress) {
|
|
1427
1393
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
1428
1394
|
process.exit(1);
|
|
@@ -1432,9 +1398,9 @@ export function registerWalletCommands(program) {
|
|
|
1432
1398
|
console.error(`Guardian key not found. Expected at ~/.arc402/guardian.key (or guardianPrivateKey in config for legacy setups).`);
|
|
1433
1399
|
process.exit(1);
|
|
1434
1400
|
}
|
|
1435
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
1436
|
-
const guardianSigner = new ethers.Wallet(guardianKey, provider);
|
|
1437
|
-
const walletContract = new ethers.Contract(config.walletContractAddress, ARC402_WALLET_GUARDIAN_ABI, guardianSigner);
|
|
1401
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
1402
|
+
const guardianSigner = new ethers_1.ethers.Wallet(guardianKey, provider);
|
|
1403
|
+
const walletContract = new ethers_1.ethers.Contract(config.walletContractAddress, abis_1.ARC402_WALLET_GUARDIAN_ABI, guardianSigner);
|
|
1438
1404
|
let tx;
|
|
1439
1405
|
if (opts.drain) {
|
|
1440
1406
|
console.log("Triggering freeze-and-drain via guardian key...");
|
|
@@ -1465,7 +1431,7 @@ export function registerWalletCommands(program) {
|
|
|
1465
1431
|
.option("--hardware", "Hardware wallet mode: show raw wc: URI only")
|
|
1466
1432
|
.option("--json")
|
|
1467
1433
|
.action(async (opts) => {
|
|
1468
|
-
const config = loadConfig();
|
|
1434
|
+
const config = (0, config_1.loadConfig)();
|
|
1469
1435
|
if (!config.walletContractAddress) {
|
|
1470
1436
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
1471
1437
|
process.exit(1);
|
|
@@ -1475,19 +1441,19 @@ export function registerWalletCommands(program) {
|
|
|
1475
1441
|
process.exit(1);
|
|
1476
1442
|
}
|
|
1477
1443
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
1478
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
1479
|
-
const walletInterface = new ethers.Interface(ARC402_WALLET_GUARDIAN_ABI);
|
|
1444
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
1445
|
+
const walletInterface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_GUARDIAN_ABI);
|
|
1480
1446
|
const telegramOpts = config.telegramBotToken && config.telegramChatId
|
|
1481
1447
|
? { botToken: config.telegramBotToken, chatId: config.telegramChatId, threadId: config.telegramThreadId }
|
|
1482
1448
|
: undefined;
|
|
1483
|
-
const { client, session, account } = await connectPhoneWallet(config.walletConnectProjectId, chainId, config, { telegramOpts, prompt: "Approve: unfreeze ARC402Wallet", hardware: !!opts.hardware });
|
|
1449
|
+
const { client, session, account } = await (0, walletconnect_1.connectPhoneWallet)(config.walletConnectProjectId, chainId, config, { telegramOpts, prompt: "Approve: unfreeze ARC402Wallet", hardware: !!opts.hardware });
|
|
1484
1450
|
const networkName = chainId === 8453 ? "Base" : "Base Sepolia";
|
|
1485
1451
|
const shortAddr = `${account.slice(0, 6)}...${account.slice(-5)}`;
|
|
1486
|
-
console.log("\n" + c.success + c.white(` Connected: ${shortAddr} on ${networkName}`));
|
|
1487
|
-
console.log("\n" + c.dim("Wallet to unfreeze:") + " " + c.white(config.walletContractAddress ?? ""));
|
|
1452
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(` Connected: ${shortAddr} on ${networkName}`));
|
|
1453
|
+
console.log("\n" + colors_1.c.dim("Wallet to unfreeze:") + " " + colors_1.c.white(config.walletContractAddress ?? ""));
|
|
1488
1454
|
// WalletConnect approval already confirmed intent — sending automatically
|
|
1489
|
-
console.log(c.dim("Sending transaction..."));
|
|
1490
|
-
const txHash = await sendTransactionWithSession(client, session, account, chainId, {
|
|
1455
|
+
console.log(colors_1.c.dim("Sending transaction..."));
|
|
1456
|
+
const txHash = await (0, walletconnect_1.sendTransactionWithSession)(client, session, account, chainId, {
|
|
1491
1457
|
to: config.walletContractAddress,
|
|
1492
1458
|
data: walletInterface.encodeFunctionData("unfreeze", []),
|
|
1493
1459
|
value: "0x0",
|
|
@@ -1497,8 +1463,8 @@ export function registerWalletCommands(program) {
|
|
|
1497
1463
|
console.log(JSON.stringify({ txHash, walletAddress: config.walletContractAddress }));
|
|
1498
1464
|
}
|
|
1499
1465
|
else {
|
|
1500
|
-
console.log("\n" + c.success + c.white(` Wallet ${config.walletContractAddress} unfrozen`));
|
|
1501
|
-
console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
|
|
1466
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(` Wallet ${config.walletContractAddress} unfrozen`));
|
|
1467
|
+
console.log(" " + colors_1.c.dim("Tx:") + " " + colors_1.c.white(txHash));
|
|
1502
1468
|
}
|
|
1503
1469
|
});
|
|
1504
1470
|
// ─── set-guardian ──────────────────────────────────────────────────────────
|
|
@@ -1510,7 +1476,7 @@ export function registerWalletCommands(program) {
|
|
|
1510
1476
|
.option("--guardian-key <key>", "Use an existing private key as the guardian (optional)")
|
|
1511
1477
|
.option("--hardware", "Hardware wallet mode: show raw wc: URI only")
|
|
1512
1478
|
.action(async (opts) => {
|
|
1513
|
-
const config = loadConfig();
|
|
1479
|
+
const config = (0, config_1.loadConfig)();
|
|
1514
1480
|
if (!config.walletContractAddress) {
|
|
1515
1481
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
1516
1482
|
process.exit(1);
|
|
@@ -1522,7 +1488,7 @@ export function registerWalletCommands(program) {
|
|
|
1522
1488
|
let guardianWallet;
|
|
1523
1489
|
if (opts.guardianKey) {
|
|
1524
1490
|
try {
|
|
1525
|
-
guardianWallet = new ethers.Wallet(opts.guardianKey);
|
|
1491
|
+
guardianWallet = new ethers_1.ethers.Wallet(opts.guardianKey);
|
|
1526
1492
|
}
|
|
1527
1493
|
catch {
|
|
1528
1494
|
console.error("Invalid guardian key. Must be a 0x-prefixed hex string.");
|
|
@@ -1530,24 +1496,24 @@ export function registerWalletCommands(program) {
|
|
|
1530
1496
|
}
|
|
1531
1497
|
}
|
|
1532
1498
|
else {
|
|
1533
|
-
guardianWallet = new ethers.Wallet(ethers.Wallet.createRandom().privateKey);
|
|
1499
|
+
guardianWallet = new ethers_1.ethers.Wallet(ethers_1.ethers.Wallet.createRandom().privateKey);
|
|
1534
1500
|
console.log("Generated new guardian key.");
|
|
1535
1501
|
}
|
|
1536
1502
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
1537
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
1538
|
-
const walletInterface = new ethers.Interface(ARC402_WALLET_GUARDIAN_ABI);
|
|
1503
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
1504
|
+
const walletInterface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_GUARDIAN_ABI);
|
|
1539
1505
|
console.log(`\nGuardian address: ${guardianWallet.address}`);
|
|
1540
1506
|
console.log(`Wallet contract: ${config.walletContractAddress}`);
|
|
1541
1507
|
const telegramOpts = config.telegramBotToken && config.telegramChatId
|
|
1542
1508
|
? { botToken: config.telegramBotToken, chatId: config.telegramChatId, threadId: config.telegramThreadId }
|
|
1543
1509
|
: undefined;
|
|
1544
|
-
const { client, session, account } = await connectPhoneWallet(config.walletConnectProjectId, chainId, config, { telegramOpts, prompt: `Approve: set guardian to ${guardianWallet.address}`, hardware: !!opts.hardware });
|
|
1510
|
+
const { client, session, account } = await (0, walletconnect_1.connectPhoneWallet)(config.walletConnectProjectId, chainId, config, { telegramOpts, prompt: `Approve: set guardian to ${guardianWallet.address}`, hardware: !!opts.hardware });
|
|
1545
1511
|
const networkName = chainId === 8453 ? "Base" : "Base Sepolia";
|
|
1546
1512
|
const shortAddr = `${account.slice(0, 6)}...${account.slice(-5)}`;
|
|
1547
|
-
console.log("\n" + c.success + c.white(` Connected: ${shortAddr} on ${networkName}`));
|
|
1513
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(` Connected: ${shortAddr} on ${networkName}`));
|
|
1548
1514
|
// WalletConnect approval already confirmed intent — sending automatically
|
|
1549
|
-
console.log(c.dim("Sending transaction..."));
|
|
1550
|
-
const txHash = await sendTransactionWithSession(client, session, account, chainId, {
|
|
1515
|
+
console.log(colors_1.c.dim("Sending transaction..."));
|
|
1516
|
+
const txHash = await (0, walletconnect_1.sendTransactionWithSession)(client, session, account, chainId, {
|
|
1551
1517
|
to: config.walletContractAddress,
|
|
1552
1518
|
data: walletInterface.encodeFunctionData("setGuardian", [guardianWallet.address]),
|
|
1553
1519
|
value: "0x0",
|
|
@@ -1557,32 +1523,32 @@ export function registerWalletCommands(program) {
|
|
|
1557
1523
|
if (config.guardianPrivateKey)
|
|
1558
1524
|
delete config.guardianPrivateKey;
|
|
1559
1525
|
config.guardianAddress = guardianWallet.address;
|
|
1560
|
-
saveConfig(config);
|
|
1561
|
-
console.log("\n" + c.success + c.white(` Guardian set to: ${guardianWallet.address}`));
|
|
1562
|
-
console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
|
|
1563
|
-
console.log(" " + c.dim("Guardian private key saved to ~/.arc402/guardian.key (chmod 400)."));
|
|
1564
|
-
console.log(" " + c.warning + " " + c.yellow("The guardian key can freeze your wallet. Store it separately from your hot key."));
|
|
1526
|
+
(0, config_1.saveConfig)(config);
|
|
1527
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(` Guardian set to: ${guardianWallet.address}`));
|
|
1528
|
+
console.log(" " + colors_1.c.dim("Tx:") + " " + colors_1.c.white(txHash));
|
|
1529
|
+
console.log(" " + colors_1.c.dim("Guardian private key saved to ~/.arc402/guardian.key (chmod 400)."));
|
|
1530
|
+
console.log(" " + colors_1.c.warning + " " + colors_1.c.yellow("The guardian key can freeze your wallet. Store it separately from your hot key."));
|
|
1565
1531
|
});
|
|
1566
1532
|
// ─── policy-engine freeze / unfreeze (legacy — for PolicyEngine-level freeze) ──
|
|
1567
1533
|
wallet.command("freeze-policy <walletAddress>")
|
|
1568
1534
|
.description("Freeze PolicyEngine spend for a wallet address (authorized freeze agents only)")
|
|
1569
1535
|
.action(async (walletAddress) => {
|
|
1570
|
-
const config = loadConfig();
|
|
1536
|
+
const config = (0, config_1.loadConfig)();
|
|
1571
1537
|
if (!config.policyEngineAddress)
|
|
1572
1538
|
throw new Error("policyEngineAddress missing in config");
|
|
1573
|
-
const { signer } = await requireSigner(config);
|
|
1574
|
-
const client = new PolicyClient(config.policyEngineAddress, signer);
|
|
1539
|
+
const { signer } = await (0, client_1.requireSigner)(config);
|
|
1540
|
+
const client = new sdk_1.PolicyClient(config.policyEngineAddress, signer);
|
|
1575
1541
|
await client.freezeSpend(walletAddress);
|
|
1576
1542
|
console.log(`wallet ${walletAddress} spend frozen (PolicyEngine)`);
|
|
1577
1543
|
});
|
|
1578
1544
|
wallet.command("unfreeze-policy <walletAddress>")
|
|
1579
1545
|
.description("Unfreeze PolicyEngine spend for a wallet. Only callable by the wallet or its registered owner.")
|
|
1580
1546
|
.action(async (walletAddress) => {
|
|
1581
|
-
const config = loadConfig();
|
|
1547
|
+
const config = (0, config_1.loadConfig)();
|
|
1582
1548
|
if (!config.policyEngineAddress)
|
|
1583
1549
|
throw new Error("policyEngineAddress missing in config");
|
|
1584
|
-
const { signer } = await requireSigner(config);
|
|
1585
|
-
const client = new PolicyClient(config.policyEngineAddress, signer);
|
|
1550
|
+
const { signer } = await (0, client_1.requireSigner)(config);
|
|
1551
|
+
const client = new sdk_1.PolicyClient(config.policyEngineAddress, signer);
|
|
1586
1552
|
await client.unfreeze(walletAddress);
|
|
1587
1553
|
console.log(`wallet ${walletAddress} spend unfrozen (PolicyEngine)`);
|
|
1588
1554
|
});
|
|
@@ -1592,7 +1558,7 @@ export function registerWalletCommands(program) {
|
|
|
1592
1558
|
.option("--dry-run", "Show calldata without connecting to wallet")
|
|
1593
1559
|
.option("--hardware", "Hardware wallet mode: show raw wc: URI only")
|
|
1594
1560
|
.action(async (newRegistryAddress, opts) => {
|
|
1595
|
-
const config = loadConfig();
|
|
1561
|
+
const config = (0, config_1.loadConfig)();
|
|
1596
1562
|
if (!config.walletContractAddress) {
|
|
1597
1563
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
1598
1564
|
process.exit(1);
|
|
@@ -1603,18 +1569,18 @@ export function registerWalletCommands(program) {
|
|
|
1603
1569
|
}
|
|
1604
1570
|
let checksumAddress;
|
|
1605
1571
|
try {
|
|
1606
|
-
checksumAddress = ethers.getAddress(newRegistryAddress);
|
|
1572
|
+
checksumAddress = ethers_1.ethers.getAddress(newRegistryAddress);
|
|
1607
1573
|
}
|
|
1608
1574
|
catch {
|
|
1609
1575
|
console.error(`Invalid address: ${newRegistryAddress}`);
|
|
1610
1576
|
process.exit(1);
|
|
1611
1577
|
}
|
|
1612
1578
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
1613
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
1614
|
-
const walletInterface = new ethers.Interface(ARC402_WALLET_REGISTRY_ABI);
|
|
1579
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
1580
|
+
const walletInterface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_REGISTRY_ABI);
|
|
1615
1581
|
let currentRegistry = "(unknown)";
|
|
1616
1582
|
try {
|
|
1617
|
-
const walletContract = new ethers.Contract(config.walletContractAddress, ARC402_WALLET_REGISTRY_ABI, provider);
|
|
1583
|
+
const walletContract = new ethers_1.ethers.Contract(config.walletContractAddress, abis_1.ARC402_WALLET_REGISTRY_ABI, provider);
|
|
1618
1584
|
currentRegistry = await walletContract.registry();
|
|
1619
1585
|
}
|
|
1620
1586
|
catch { /* contract may not expose registry() */ }
|
|
@@ -1640,21 +1606,21 @@ export function registerWalletCommands(program) {
|
|
|
1640
1606
|
const telegramOpts = config.telegramBotToken && config.telegramChatId
|
|
1641
1607
|
? { botToken: config.telegramBotToken, chatId: config.telegramChatId, threadId: config.telegramThreadId }
|
|
1642
1608
|
: undefined;
|
|
1643
|
-
const { client, session, account } = await connectPhoneWallet(config.walletConnectProjectId, chainId, config, { telegramOpts, prompt: "Approve registry upgrade proposal on ARC402Wallet", hardware: !!opts.hardware });
|
|
1609
|
+
const { client, session, account } = await (0, walletconnect_1.connectPhoneWallet)(config.walletConnectProjectId, chainId, config, { telegramOpts, prompt: "Approve registry upgrade proposal on ARC402Wallet", hardware: !!opts.hardware });
|
|
1644
1610
|
const networkName = chainId === 8453 ? "Base" : "Base Sepolia";
|
|
1645
1611
|
const shortAddr = `${account.slice(0, 6)}...${account.slice(-5)}`;
|
|
1646
|
-
console.log("\n" + c.success + c.white(` Connected: ${shortAddr} on ${networkName}`));
|
|
1612
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(` Connected: ${shortAddr} on ${networkName}`));
|
|
1647
1613
|
// WalletConnect approval already confirmed intent — sending automatically
|
|
1648
|
-
console.log(c.dim("Sending transaction..."));
|
|
1649
|
-
const txHash = await sendTransactionWithSession(client, session, account, chainId, {
|
|
1614
|
+
console.log(colors_1.c.dim("Sending transaction..."));
|
|
1615
|
+
const txHash = await (0, walletconnect_1.sendTransactionWithSession)(client, session, account, chainId, {
|
|
1650
1616
|
to: config.walletContractAddress,
|
|
1651
1617
|
data: calldata,
|
|
1652
1618
|
value: "0x0",
|
|
1653
1619
|
});
|
|
1654
1620
|
const unlockAt = new Date(Date.now() + 2 * 24 * 60 * 60 * 1000);
|
|
1655
|
-
console.log("\n" + c.success + c.white(" Registry upgrade proposed"));
|
|
1656
|
-
console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
|
|
1657
|
-
console.log(" " + c.dim("Unlock at:") + " " + c.white(unlockAt.toISOString()) + c.dim(" (approximately)"));
|
|
1621
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(" Registry upgrade proposed"));
|
|
1622
|
+
console.log(" " + colors_1.c.dim("Tx:") + " " + colors_1.c.white(txHash));
|
|
1623
|
+
console.log(" " + colors_1.c.dim("Unlock at:") + " " + colors_1.c.white(unlockAt.toISOString()) + colors_1.c.dim(" (approximately)"));
|
|
1658
1624
|
console.log(`\nNext steps:`);
|
|
1659
1625
|
console.log(` Wait 2 days, then run:`);
|
|
1660
1626
|
console.log(` arc402 wallet execute-registry-upgrade`);
|
|
@@ -1665,7 +1631,7 @@ export function registerWalletCommands(program) {
|
|
|
1665
1631
|
wallet.command("execute-registry-upgrade")
|
|
1666
1632
|
.description("Execute a pending registry upgrade after the 2-day timelock (phone wallet signs via WalletConnect)")
|
|
1667
1633
|
.action(async () => {
|
|
1668
|
-
const config = loadConfig();
|
|
1634
|
+
const config = (0, config_1.loadConfig)();
|
|
1669
1635
|
if (!config.walletContractAddress) {
|
|
1670
1636
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
1671
1637
|
process.exit(1);
|
|
@@ -1675,8 +1641,8 @@ export function registerWalletCommands(program) {
|
|
|
1675
1641
|
process.exit(1);
|
|
1676
1642
|
}
|
|
1677
1643
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
1678
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
1679
|
-
const walletContract = new ethers.Contract(config.walletContractAddress, ARC402_WALLET_REGISTRY_ABI, provider);
|
|
1644
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
1645
|
+
const walletContract = new ethers_1.ethers.Contract(config.walletContractAddress, abis_1.ARC402_WALLET_REGISTRY_ABI, provider);
|
|
1680
1646
|
let pendingRegistry;
|
|
1681
1647
|
let unlockAt;
|
|
1682
1648
|
try {
|
|
@@ -1689,7 +1655,7 @@ export function registerWalletCommands(program) {
|
|
|
1689
1655
|
console.error("Failed to read pending registry from contract:", e);
|
|
1690
1656
|
process.exit(1);
|
|
1691
1657
|
}
|
|
1692
|
-
if (pendingRegistry === ethers.ZeroAddress) {
|
|
1658
|
+
if (pendingRegistry === ethers_1.ethers.ZeroAddress) {
|
|
1693
1659
|
console.log("No pending registry upgrade.");
|
|
1694
1660
|
return;
|
|
1695
1661
|
}
|
|
@@ -1709,8 +1675,8 @@ export function registerWalletCommands(program) {
|
|
|
1709
1675
|
const telegramOpts = config.telegramBotToken && config.telegramChatId
|
|
1710
1676
|
? { botToken: config.telegramBotToken, chatId: config.telegramChatId, threadId: config.telegramThreadId }
|
|
1711
1677
|
: undefined;
|
|
1712
|
-
const walletInterface = new ethers.Interface(ARC402_WALLET_REGISTRY_ABI);
|
|
1713
|
-
const { txHash } = await requestPhoneWalletSignature(config.walletConnectProjectId, chainId, () => ({
|
|
1678
|
+
const walletInterface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_REGISTRY_ABI);
|
|
1679
|
+
const { txHash } = await (0, walletconnect_1.requestPhoneWalletSignature)(config.walletConnectProjectId, chainId, () => ({
|
|
1714
1680
|
to: config.walletContractAddress,
|
|
1715
1681
|
data: walletInterface.encodeFunctionData("executeRegistryUpdate", []),
|
|
1716
1682
|
value: "0x0",
|
|
@@ -1722,9 +1688,9 @@ export function registerWalletCommands(program) {
|
|
|
1722
1688
|
confirmedRegistry = await walletContract.registry();
|
|
1723
1689
|
}
|
|
1724
1690
|
catch { /* use pendingRegistry as fallback */ }
|
|
1725
|
-
console.log("\n" + c.success + c.white(" Registry upgrade executed"));
|
|
1726
|
-
console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
|
|
1727
|
-
console.log(" " + c.dim("New registry:") + " " + c.white(confirmedRegistry));
|
|
1691
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(" Registry upgrade executed"));
|
|
1692
|
+
console.log(" " + colors_1.c.dim("Tx:") + " " + colors_1.c.white(txHash));
|
|
1693
|
+
console.log(" " + colors_1.c.dim("New registry:") + " " + colors_1.c.white(confirmedRegistry));
|
|
1728
1694
|
if (confirmedRegistry.toLowerCase() === pendingRegistry.toLowerCase()) {
|
|
1729
1695
|
console.log(` Registry updated successfully — addresses now resolve through new registry.`);
|
|
1730
1696
|
}
|
|
@@ -1743,7 +1709,7 @@ export function registerWalletCommands(program) {
|
|
|
1743
1709
|
.option("--hardware", "Hardware wallet mode: show raw wc: URI only")
|
|
1744
1710
|
.option("--json")
|
|
1745
1711
|
.action(async (target, opts) => {
|
|
1746
|
-
const config = loadConfig();
|
|
1712
|
+
const config = (0, config_1.loadConfig)();
|
|
1747
1713
|
if (!config.walletContractAddress) {
|
|
1748
1714
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
1749
1715
|
process.exit(1);
|
|
@@ -1754,7 +1720,7 @@ export function registerWalletCommands(program) {
|
|
|
1754
1720
|
}
|
|
1755
1721
|
let checksumTarget;
|
|
1756
1722
|
try {
|
|
1757
|
-
checksumTarget = ethers.getAddress(target);
|
|
1723
|
+
checksumTarget = ethers_1.ethers.getAddress(target);
|
|
1758
1724
|
}
|
|
1759
1725
|
catch {
|
|
1760
1726
|
console.error(`Invalid address: ${target}`);
|
|
@@ -1762,20 +1728,20 @@ export function registerWalletCommands(program) {
|
|
|
1762
1728
|
}
|
|
1763
1729
|
const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
|
|
1764
1730
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
1765
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
1731
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
1766
1732
|
// Check if already whitelisted
|
|
1767
1733
|
const peAbi = [
|
|
1768
1734
|
"function whitelistContract(address wallet, address target) external",
|
|
1769
1735
|
"function isContractWhitelisted(address wallet, address target) external view returns (bool)",
|
|
1770
1736
|
];
|
|
1771
|
-
const pe = new ethers.Contract(policyAddress, peAbi, provider);
|
|
1737
|
+
const pe = new ethers_1.ethers.Contract(policyAddress, peAbi, provider);
|
|
1772
1738
|
let alreadyWhitelisted = false;
|
|
1773
1739
|
try {
|
|
1774
1740
|
alreadyWhitelisted = await pe.isContractWhitelisted(config.walletContractAddress, checksumTarget);
|
|
1775
1741
|
}
|
|
1776
1742
|
catch { /* ignore */ }
|
|
1777
1743
|
if (alreadyWhitelisted) {
|
|
1778
|
-
console.log(" " + c.success + " " + c.white(checksumTarget) + c.dim(` is already whitelisted for ${config.walletContractAddress}`));
|
|
1744
|
+
console.log(" " + colors_1.c.success + " " + colors_1.c.white(checksumTarget) + colors_1.c.dim(` is already whitelisted for ${config.walletContractAddress}`));
|
|
1779
1745
|
process.exit(0);
|
|
1780
1746
|
}
|
|
1781
1747
|
console.log(`\nWallet: ${config.walletContractAddress}`);
|
|
@@ -1784,8 +1750,8 @@ export function registerWalletCommands(program) {
|
|
|
1784
1750
|
const telegramOpts = config.telegramBotToken && config.telegramChatId
|
|
1785
1751
|
? { botToken: config.telegramBotToken, chatId: config.telegramChatId, threadId: config.telegramThreadId }
|
|
1786
1752
|
: undefined;
|
|
1787
|
-
const policyIface = new ethers.Interface(peAbi);
|
|
1788
|
-
const { txHash } = await requestPhoneWalletSignature(config.walletConnectProjectId, chainId, () => ({
|
|
1753
|
+
const policyIface = new ethers_1.ethers.Interface(peAbi);
|
|
1754
|
+
const { txHash } = await (0, walletconnect_1.requestPhoneWalletSignature)(config.walletConnectProjectId, chainId, () => ({
|
|
1789
1755
|
to: policyAddress,
|
|
1790
1756
|
data: policyIface.encodeFunctionData("whitelistContract", [
|
|
1791
1757
|
config.walletContractAddress,
|
|
@@ -1798,8 +1764,8 @@ export function registerWalletCommands(program) {
|
|
|
1798
1764
|
console.log(JSON.stringify({ ok: true, txHash, wallet: config.walletContractAddress, target: checksumTarget }));
|
|
1799
1765
|
}
|
|
1800
1766
|
else {
|
|
1801
|
-
console.log("\n" + c.success + c.white(" Contract whitelisted"));
|
|
1802
|
-
renderTree([
|
|
1767
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(" Contract whitelisted"));
|
|
1768
|
+
(0, tree_1.renderTree)([
|
|
1803
1769
|
{ label: "Tx", value: txHash },
|
|
1804
1770
|
{ label: "Wallet", value: config.walletContractAddress ?? "" },
|
|
1805
1771
|
{ label: "Target", value: checksumTarget, last: true },
|
|
@@ -1810,7 +1776,7 @@ export function registerWalletCommands(program) {
|
|
|
1810
1776
|
wallet.command("set-interceptor <address>")
|
|
1811
1777
|
.description("Set the authorized X402 interceptor address on ARC402Wallet (phone wallet signs via WalletConnect)")
|
|
1812
1778
|
.action(async (interceptorAddress) => {
|
|
1813
|
-
const config = loadConfig();
|
|
1779
|
+
const config = (0, config_1.loadConfig)();
|
|
1814
1780
|
if (!config.walletContractAddress) {
|
|
1815
1781
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
1816
1782
|
process.exit(1);
|
|
@@ -1821,18 +1787,18 @@ export function registerWalletCommands(program) {
|
|
|
1821
1787
|
}
|
|
1822
1788
|
let checksumAddress;
|
|
1823
1789
|
try {
|
|
1824
|
-
checksumAddress = ethers.getAddress(interceptorAddress);
|
|
1790
|
+
checksumAddress = ethers_1.ethers.getAddress(interceptorAddress);
|
|
1825
1791
|
}
|
|
1826
1792
|
catch {
|
|
1827
1793
|
console.error(`Invalid address: ${interceptorAddress}`);
|
|
1828
1794
|
process.exit(1);
|
|
1829
1795
|
}
|
|
1830
1796
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
1831
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
1832
|
-
const ownerInterface = new ethers.Interface(ARC402_WALLET_OWNER_ABI);
|
|
1797
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
1798
|
+
const ownerInterface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_OWNER_ABI);
|
|
1833
1799
|
let currentInterceptor = "(unknown)";
|
|
1834
1800
|
try {
|
|
1835
|
-
const walletContract = new ethers.Contract(config.walletContractAddress, ARC402_WALLET_OWNER_ABI, provider);
|
|
1801
|
+
const walletContract = new ethers_1.ethers.Contract(config.walletContractAddress, abis_1.ARC402_WALLET_OWNER_ABI, provider);
|
|
1836
1802
|
currentInterceptor = await walletContract.authorizedInterceptor();
|
|
1837
1803
|
}
|
|
1838
1804
|
catch { /* contract may not be deployed yet */ }
|
|
@@ -1842,21 +1808,21 @@ export function registerWalletCommands(program) {
|
|
|
1842
1808
|
const telegramOpts = config.telegramBotToken && config.telegramChatId
|
|
1843
1809
|
? { botToken: config.telegramBotToken, chatId: config.telegramChatId, threadId: config.telegramThreadId }
|
|
1844
1810
|
: undefined;
|
|
1845
|
-
const { txHash } = await requestPhoneWalletSignature(config.walletConnectProjectId, chainId, () => ({
|
|
1811
|
+
const { txHash } = await (0, walletconnect_1.requestPhoneWalletSignature)(config.walletConnectProjectId, chainId, () => ({
|
|
1846
1812
|
to: config.walletContractAddress,
|
|
1847
1813
|
data: ownerInterface.encodeFunctionData("setAuthorizedInterceptor", [checksumAddress]),
|
|
1848
1814
|
value: "0x0",
|
|
1849
1815
|
}), `Approve: set X402 interceptor to ${checksumAddress}`, telegramOpts, config);
|
|
1850
1816
|
await provider.waitForTransaction(txHash);
|
|
1851
|
-
console.log("\n" + c.success + c.white(" X402 interceptor updated"));
|
|
1852
|
-
console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
|
|
1853
|
-
console.log(" " + c.dim("Interceptor:") + " " + c.white(checksumAddress));
|
|
1817
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(" X402 interceptor updated"));
|
|
1818
|
+
console.log(" " + colors_1.c.dim("Tx:") + " " + colors_1.c.white(txHash));
|
|
1819
|
+
console.log(" " + colors_1.c.dim("Interceptor:") + " " + colors_1.c.white(checksumAddress));
|
|
1854
1820
|
});
|
|
1855
1821
|
// ─── set-velocity-limit ────────────────────────────────────────────────────
|
|
1856
1822
|
wallet.command("set-velocity-limit <limit>")
|
|
1857
1823
|
.description("Set the per-rolling-window ETH velocity limit on ARC402Wallet (limit in ETH, phone wallet signs via WalletConnect)")
|
|
1858
1824
|
.action(async (limitEth) => {
|
|
1859
|
-
const config = loadConfig();
|
|
1825
|
+
const config = (0, config_1.loadConfig)();
|
|
1860
1826
|
console.log(`\nNote: ARC-402 has two independent velocity limit layers:`);
|
|
1861
1827
|
console.log(` 1. Wallet-level (arc402 wallet set-velocity-limit): ETH cap per rolling hour, enforced by ARC402Wallet contract. Breach auto-freezes wallet.`);
|
|
1862
1828
|
console.log(` 2. PolicyEngine-level (arc402 wallet policy set-daily-limit): Per-category daily cap, enforced by PolicyEngine. Breach returns a soft error without freezing.`);
|
|
@@ -1871,20 +1837,20 @@ export function registerWalletCommands(program) {
|
|
|
1871
1837
|
}
|
|
1872
1838
|
let limitWei;
|
|
1873
1839
|
try {
|
|
1874
|
-
limitWei = ethers.parseEther(limitEth);
|
|
1840
|
+
limitWei = ethers_1.ethers.parseEther(limitEth);
|
|
1875
1841
|
}
|
|
1876
1842
|
catch {
|
|
1877
1843
|
console.error(`Invalid limit: ${limitEth}. Provide a value in ETH (e.g. 0.5)`);
|
|
1878
1844
|
process.exit(1);
|
|
1879
1845
|
}
|
|
1880
1846
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
1881
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
1882
|
-
const ownerInterface = new ethers.Interface(ARC402_WALLET_OWNER_ABI);
|
|
1847
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
1848
|
+
const ownerInterface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_OWNER_ABI);
|
|
1883
1849
|
let currentLimit = "(unknown)";
|
|
1884
1850
|
try {
|
|
1885
|
-
const walletContract = new ethers.Contract(config.walletContractAddress, ARC402_WALLET_OWNER_ABI, provider);
|
|
1851
|
+
const walletContract = new ethers_1.ethers.Contract(config.walletContractAddress, abis_1.ARC402_WALLET_OWNER_ABI, provider);
|
|
1886
1852
|
const raw = await walletContract.velocityLimit();
|
|
1887
|
-
currentLimit = raw === 0n ? "disabled" : `${ethers.formatEther(raw)} ETH`;
|
|
1853
|
+
currentLimit = raw === 0n ? "disabled" : `${ethers_1.ethers.formatEther(raw)} ETH`;
|
|
1888
1854
|
}
|
|
1889
1855
|
catch { /* contract may not be deployed yet */ }
|
|
1890
1856
|
console.log(`\nWallet: ${config.walletContractAddress}`);
|
|
@@ -1893,15 +1859,15 @@ export function registerWalletCommands(program) {
|
|
|
1893
1859
|
const telegramOpts = config.telegramBotToken && config.telegramChatId
|
|
1894
1860
|
? { botToken: config.telegramBotToken, chatId: config.telegramChatId, threadId: config.telegramThreadId }
|
|
1895
1861
|
: undefined;
|
|
1896
|
-
const { txHash } = await requestPhoneWalletSignature(config.walletConnectProjectId, chainId, () => ({
|
|
1862
|
+
const { txHash } = await (0, walletconnect_1.requestPhoneWalletSignature)(config.walletConnectProjectId, chainId, () => ({
|
|
1897
1863
|
to: config.walletContractAddress,
|
|
1898
1864
|
data: ownerInterface.encodeFunctionData("setVelocityLimit", [limitWei]),
|
|
1899
1865
|
value: "0x0",
|
|
1900
1866
|
}), `Approve: set velocity limit to ${limitEth} ETH`, telegramOpts, config);
|
|
1901
1867
|
await provider.waitForTransaction(txHash);
|
|
1902
|
-
console.log("\n" + c.success + c.white(" Velocity limit updated"));
|
|
1903
|
-
console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
|
|
1904
|
-
console.log(" " + c.dim("New limit:") + " " + c.white(`${limitEth} ETH per rolling window`));
|
|
1868
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(" Velocity limit updated"));
|
|
1869
|
+
console.log(" " + colors_1.c.dim("Tx:") + " " + colors_1.c.white(txHash));
|
|
1870
|
+
console.log(" " + colors_1.c.dim("New limit:") + " " + colors_1.c.white(`${limitEth} ETH per rolling window`));
|
|
1905
1871
|
});
|
|
1906
1872
|
// ─── register-policy ───────────────────────────────────────────────────────
|
|
1907
1873
|
//
|
|
@@ -1912,7 +1878,7 @@ export function registerWalletCommands(program) {
|
|
|
1912
1878
|
.description("Register this wallet on PolicyEngine (required before spend limits can be set)")
|
|
1913
1879
|
.option("--hardware", "Hardware wallet mode: show raw wc: URI only")
|
|
1914
1880
|
.action(async (opts) => {
|
|
1915
|
-
const config = loadConfig();
|
|
1881
|
+
const config = (0, config_1.loadConfig)();
|
|
1916
1882
|
if (!config.walletContractAddress) {
|
|
1917
1883
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
1918
1884
|
process.exit(1);
|
|
@@ -1923,20 +1889,20 @@ export function registerWalletCommands(program) {
|
|
|
1923
1889
|
}
|
|
1924
1890
|
const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
|
|
1925
1891
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
1926
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
1892
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
1927
1893
|
let ownerAddress = config.ownerAddress;
|
|
1928
1894
|
if (!ownerAddress) {
|
|
1929
1895
|
// Fallback 1: WalletConnect session account
|
|
1930
1896
|
if (config.wcSession?.account) {
|
|
1931
1897
|
ownerAddress = config.wcSession.account;
|
|
1932
|
-
console.log(c.dim(`Owner resolved from WalletConnect session: ${ownerAddress}`));
|
|
1898
|
+
console.log(colors_1.c.dim(`Owner resolved from WalletConnect session: ${ownerAddress}`));
|
|
1933
1899
|
}
|
|
1934
1900
|
else {
|
|
1935
1901
|
// Fallback 2: call owner() on the wallet contract
|
|
1936
1902
|
try {
|
|
1937
|
-
const walletOwnerContract = new ethers.Contract(config.walletContractAddress, ["function owner() external view returns (address)"], provider);
|
|
1903
|
+
const walletOwnerContract = new ethers_1.ethers.Contract(config.walletContractAddress, ["function owner() external view returns (address)"], provider);
|
|
1938
1904
|
ownerAddress = await walletOwnerContract.owner();
|
|
1939
|
-
console.log(c.dim(`Owner resolved from contract: ${ownerAddress}`));
|
|
1905
|
+
console.log(colors_1.c.dim(`Owner resolved from contract: ${ownerAddress}`));
|
|
1940
1906
|
}
|
|
1941
1907
|
catch {
|
|
1942
1908
|
console.error("ownerAddress not set in config and could not be resolved from contract or WalletConnect session.");
|
|
@@ -1945,21 +1911,21 @@ export function registerWalletCommands(program) {
|
|
|
1945
1911
|
}
|
|
1946
1912
|
}
|
|
1947
1913
|
// Encode registerWallet(wallet, owner) calldata — called on PolicyEngine
|
|
1948
|
-
const policyInterface = new ethers.Interface([
|
|
1914
|
+
const policyInterface = new ethers_1.ethers.Interface([
|
|
1949
1915
|
"function registerWallet(address wallet, address owner) external",
|
|
1950
1916
|
]);
|
|
1951
1917
|
const registerCalldata = policyInterface.encodeFunctionData("registerWallet", [
|
|
1952
1918
|
config.walletContractAddress,
|
|
1953
1919
|
ownerAddress,
|
|
1954
1920
|
]);
|
|
1955
|
-
const executeInterface = new ethers.Interface(ARC402_WALLET_EXECUTE_ABI);
|
|
1921
|
+
const executeInterface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_EXECUTE_ABI);
|
|
1956
1922
|
console.log(`\nWallet: ${config.walletContractAddress}`);
|
|
1957
1923
|
console.log(`PolicyEngine: ${policyAddress}`);
|
|
1958
1924
|
console.log(`Owner: ${ownerAddress}`);
|
|
1959
1925
|
const telegramOpts = config.telegramBotToken && config.telegramChatId
|
|
1960
1926
|
? { botToken: config.telegramBotToken, chatId: config.telegramChatId, threadId: config.telegramThreadId }
|
|
1961
1927
|
: undefined;
|
|
1962
|
-
const { txHash } = await requestPhoneWalletSignature(config.walletConnectProjectId, chainId, () => ({
|
|
1928
|
+
const { txHash } = await (0, walletconnect_1.requestPhoneWalletSignature)(config.walletConnectProjectId, chainId, () => ({
|
|
1963
1929
|
to: config.walletContractAddress,
|
|
1964
1930
|
data: executeInterface.encodeFunctionData("executeContractCall", [{
|
|
1965
1931
|
target: policyAddress,
|
|
@@ -1967,20 +1933,20 @@ export function registerWalletCommands(program) {
|
|
|
1967
1933
|
value: 0n,
|
|
1968
1934
|
minReturnValue: 0n,
|
|
1969
1935
|
maxApprovalAmount: 0n,
|
|
1970
|
-
approvalToken: ethers.ZeroAddress,
|
|
1936
|
+
approvalToken: ethers_1.ethers.ZeroAddress,
|
|
1971
1937
|
}]),
|
|
1972
1938
|
value: "0x0",
|
|
1973
1939
|
}), `Approve: register wallet on PolicyEngine`, telegramOpts, config);
|
|
1974
1940
|
await provider.waitForTransaction(txHash);
|
|
1975
|
-
console.log("\n" + c.success + c.white(" Wallet registered on PolicyEngine"));
|
|
1976
|
-
console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
|
|
1977
|
-
console.log(c.dim("\nNext: run 'arc402 wallet policy set-limit' to configure spending limits."));
|
|
1941
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(" Wallet registered on PolicyEngine"));
|
|
1942
|
+
console.log(" " + colors_1.c.dim("Tx:") + " " + colors_1.c.white(txHash));
|
|
1943
|
+
console.log(colors_1.c.dim("\nNext: run 'arc402 wallet policy set-limit' to configure spending limits."));
|
|
1978
1944
|
});
|
|
1979
1945
|
// ─── cancel-registry-upgrade ───────────────────────────────────────────────
|
|
1980
1946
|
wallet.command("cancel-registry-upgrade")
|
|
1981
1947
|
.description("Cancel a pending registry upgrade before it executes (phone wallet signs via WalletConnect)")
|
|
1982
1948
|
.action(async () => {
|
|
1983
|
-
const config = loadConfig();
|
|
1949
|
+
const config = (0, config_1.loadConfig)();
|
|
1984
1950
|
if (!config.walletContractAddress) {
|
|
1985
1951
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
1986
1952
|
process.exit(1);
|
|
@@ -1990,8 +1956,8 @@ export function registerWalletCommands(program) {
|
|
|
1990
1956
|
process.exit(1);
|
|
1991
1957
|
}
|
|
1992
1958
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
1993
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
1994
|
-
const walletContract = new ethers.Contract(config.walletContractAddress, ARC402_WALLET_REGISTRY_ABI, provider);
|
|
1959
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
1960
|
+
const walletContract = new ethers_1.ethers.Contract(config.walletContractAddress, abis_1.ARC402_WALLET_REGISTRY_ABI, provider);
|
|
1995
1961
|
let pendingRegistry;
|
|
1996
1962
|
let unlockAtCancel = 0n;
|
|
1997
1963
|
try {
|
|
@@ -2004,7 +1970,7 @@ export function registerWalletCommands(program) {
|
|
|
2004
1970
|
console.error("Failed to read pending registry from contract:", e);
|
|
2005
1971
|
process.exit(1);
|
|
2006
1972
|
}
|
|
2007
|
-
if (pendingRegistry === ethers.ZeroAddress) {
|
|
1973
|
+
if (pendingRegistry === ethers_1.ethers.ZeroAddress) {
|
|
2008
1974
|
console.log("No pending registry upgrade to cancel.");
|
|
2009
1975
|
return;
|
|
2010
1976
|
}
|
|
@@ -2022,14 +1988,14 @@ export function registerWalletCommands(program) {
|
|
|
2022
1988
|
const telegramOpts = config.telegramBotToken && config.telegramChatId
|
|
2023
1989
|
? { botToken: config.telegramBotToken, chatId: config.telegramChatId, threadId: config.telegramThreadId }
|
|
2024
1990
|
: undefined;
|
|
2025
|
-
const walletInterface = new ethers.Interface(ARC402_WALLET_REGISTRY_ABI);
|
|
2026
|
-
const { txHash } = await requestPhoneWalletSignature(config.walletConnectProjectId, chainId, () => ({
|
|
1991
|
+
const walletInterface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_REGISTRY_ABI);
|
|
1992
|
+
const { txHash } = await (0, walletconnect_1.requestPhoneWalletSignature)(config.walletConnectProjectId, chainId, () => ({
|
|
2027
1993
|
to: config.walletContractAddress,
|
|
2028
1994
|
data: walletInterface.encodeFunctionData("cancelRegistryUpdate", []),
|
|
2029
1995
|
value: "0x0",
|
|
2030
1996
|
}), "Approve registry upgrade cancellation on ARC402Wallet", telegramOpts, config);
|
|
2031
|
-
console.log("\n" + c.success + c.white(" Registry upgrade cancelled"));
|
|
2032
|
-
console.log(" " + c.dim("Tx:") + " " + c.white(txHash));
|
|
1997
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(" Registry upgrade cancelled"));
|
|
1998
|
+
console.log(" " + colors_1.c.dim("Tx:") + " " + colors_1.c.white(txHash));
|
|
2033
1999
|
});
|
|
2034
2000
|
// ─── governance setup ──────────────────────────────────────────────────────
|
|
2035
2001
|
//
|
|
@@ -2040,7 +2006,7 @@ export function registerWalletCommands(program) {
|
|
|
2040
2006
|
governance.command("setup")
|
|
2041
2007
|
.description("Interactive governance setup — velocity limit, guardian key, and spending limits in one WalletConnect session")
|
|
2042
2008
|
.action(async () => {
|
|
2043
|
-
const config = loadConfig();
|
|
2009
|
+
const config = (0, config_1.loadConfig)();
|
|
2044
2010
|
if (!config.walletContractAddress) {
|
|
2045
2011
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
2046
2012
|
process.exit(1);
|
|
@@ -2052,14 +2018,14 @@ export function registerWalletCommands(program) {
|
|
|
2052
2018
|
const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
|
|
2053
2019
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
2054
2020
|
// ── Step 1: velocity limit ────────────────────────────────────────────
|
|
2055
|
-
const { velocityEth } = await
|
|
2021
|
+
const { velocityEth } = await (0, prompts_1.default)({
|
|
2056
2022
|
type: "text",
|
|
2057
2023
|
name: "velocityEth",
|
|
2058
2024
|
message: "Velocity limit (max ETH per rolling window)",
|
|
2059
2025
|
initial: "0.05",
|
|
2060
2026
|
validate: (v) => {
|
|
2061
2027
|
try {
|
|
2062
|
-
ethers.parseEther(v);
|
|
2028
|
+
ethers_1.ethers.parseEther(v);
|
|
2063
2029
|
return true;
|
|
2064
2030
|
}
|
|
2065
2031
|
catch {
|
|
@@ -2072,7 +2038,7 @@ export function registerWalletCommands(program) {
|
|
|
2072
2038
|
return;
|
|
2073
2039
|
}
|
|
2074
2040
|
// ── Step 2: guardian key ──────────────────────────────────────────────
|
|
2075
|
-
const { wantGuardian } = await
|
|
2041
|
+
const { wantGuardian } = await (0, prompts_1.default)({
|
|
2076
2042
|
type: "confirm",
|
|
2077
2043
|
name: "wantGuardian",
|
|
2078
2044
|
message: "Set guardian key?",
|
|
@@ -2084,7 +2050,7 @@ export function registerWalletCommands(program) {
|
|
|
2084
2050
|
}
|
|
2085
2051
|
let guardianWallet = null;
|
|
2086
2052
|
if (wantGuardian) {
|
|
2087
|
-
guardianWallet = new ethers.Wallet(ethers.Wallet.createRandom().privateKey);
|
|
2053
|
+
guardianWallet = new ethers_1.ethers.Wallet(ethers_1.ethers.Wallet.createRandom().privateKey);
|
|
2088
2054
|
console.log(` Generated guardian address: ${guardianWallet.address}`);
|
|
2089
2055
|
}
|
|
2090
2056
|
const categories = [];
|
|
@@ -2095,7 +2061,7 @@ export function registerWalletCommands(program) {
|
|
|
2095
2061
|
];
|
|
2096
2062
|
console.log("\nSpending categories — press Enter to skip any:");
|
|
2097
2063
|
for (const { label, default: def } of defaultCategories) {
|
|
2098
|
-
const { amountRaw } = await
|
|
2064
|
+
const { amountRaw } = await (0, prompts_1.default)({
|
|
2099
2065
|
type: "text",
|
|
2100
2066
|
name: "amountRaw",
|
|
2101
2067
|
message: ` ${label} limit in ETH`,
|
|
@@ -2111,7 +2077,7 @@ export function registerWalletCommands(program) {
|
|
|
2111
2077
|
}
|
|
2112
2078
|
// Custom categories loop
|
|
2113
2079
|
while (true) {
|
|
2114
|
-
const { customName } = await
|
|
2080
|
+
const { customName } = await (0, prompts_1.default)({
|
|
2115
2081
|
type: "text",
|
|
2116
2082
|
name: "customName",
|
|
2117
2083
|
message: " Add custom category? [name or Enter to skip]",
|
|
@@ -2119,14 +2085,14 @@ export function registerWalletCommands(program) {
|
|
|
2119
2085
|
});
|
|
2120
2086
|
if (customName === undefined || customName.trim() === "")
|
|
2121
2087
|
break;
|
|
2122
|
-
const { customAmount } = await
|
|
2088
|
+
const { customAmount } = await (0, prompts_1.default)({
|
|
2123
2089
|
type: "text",
|
|
2124
2090
|
name: "customAmount",
|
|
2125
2091
|
message: ` ${customName.trim()} limit in ETH`,
|
|
2126
2092
|
initial: "0.05",
|
|
2127
2093
|
validate: (v) => {
|
|
2128
2094
|
try {
|
|
2129
|
-
ethers.parseEther(v);
|
|
2095
|
+
ethers_1.ethers.parseEther(v);
|
|
2130
2096
|
return true;
|
|
2131
2097
|
}
|
|
2132
2098
|
catch {
|
|
@@ -2157,7 +2123,7 @@ export function registerWalletCommands(program) {
|
|
|
2157
2123
|
console.log(` Transactions: ${1 + (guardianWallet ? 1 : 0) + categories.length} + onboarding (registerWallet, enableDefiAccess) total`);
|
|
2158
2124
|
console.log("─────────────────────────────────────────────────────");
|
|
2159
2125
|
// ── Step 5: confirm ───────────────────────────────────────────────────
|
|
2160
|
-
const { confirmed } = await
|
|
2126
|
+
const { confirmed } = await (0, prompts_1.default)({
|
|
2161
2127
|
type: "confirm",
|
|
2162
2128
|
name: "confirmed",
|
|
2163
2129
|
message: "Confirm and sign with your wallet?",
|
|
@@ -2172,14 +2138,14 @@ export function registerWalletCommands(program) {
|
|
|
2172
2138
|
? { botToken: config.telegramBotToken, chatId: config.telegramChatId, threadId: config.telegramThreadId }
|
|
2173
2139
|
: undefined;
|
|
2174
2140
|
console.log("\nConnecting wallet...");
|
|
2175
|
-
const { client, session, account } = await connectPhoneWallet(config.walletConnectProjectId, chainId, config, { telegramOpts, prompt: "Approve governance setup transactions on ARC402Wallet" });
|
|
2176
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
2177
|
-
const ownerInterface = new ethers.Interface(ARC402_WALLET_OWNER_ABI);
|
|
2178
|
-
const guardianInterface = new ethers.Interface(ARC402_WALLET_GUARDIAN_ABI);
|
|
2179
|
-
const policyInterface = new ethers.Interface(POLICY_ENGINE_LIMITS_ABI);
|
|
2180
|
-
const executeInterface = new ethers.Interface(ARC402_WALLET_EXECUTE_ABI);
|
|
2181
|
-
const govInterface = new ethers.Interface(POLICY_ENGINE_GOVERNANCE_ABI);
|
|
2182
|
-
const policyGovContract = new ethers.Contract(policyAddress, POLICY_ENGINE_GOVERNANCE_ABI, provider);
|
|
2141
|
+
const { client, session, account } = await (0, walletconnect_1.connectPhoneWallet)(config.walletConnectProjectId, chainId, config, { telegramOpts, prompt: "Approve governance setup transactions on ARC402Wallet" });
|
|
2142
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
2143
|
+
const ownerInterface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_OWNER_ABI);
|
|
2144
|
+
const guardianInterface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_GUARDIAN_ABI);
|
|
2145
|
+
const policyInterface = new ethers_1.ethers.Interface(abis_1.POLICY_ENGINE_LIMITS_ABI);
|
|
2146
|
+
const executeInterface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_EXECUTE_ABI);
|
|
2147
|
+
const govInterface = new ethers_1.ethers.Interface(abis_1.POLICY_ENGINE_GOVERNANCE_ABI);
|
|
2148
|
+
const policyGovContract = new ethers_1.ethers.Contract(policyAddress, abis_1.POLICY_ENGINE_GOVERNANCE_ABI, provider);
|
|
2183
2149
|
const calls = [];
|
|
2184
2150
|
// ── P0: mandatory onboarding calls (registerWallet + enableDefiAccess) ──
|
|
2185
2151
|
// Check what the constructor already did to avoid double-registration reverts
|
|
@@ -2187,7 +2153,7 @@ export function registerWalletCommands(program) {
|
|
|
2187
2153
|
let govAlreadyDefiEnabled = false;
|
|
2188
2154
|
try {
|
|
2189
2155
|
const registeredOwner = await policyGovContract.walletOwners(config.walletContractAddress);
|
|
2190
|
-
govAlreadyRegistered = registeredOwner !== ethers.ZeroAddress;
|
|
2156
|
+
govAlreadyRegistered = registeredOwner !== ethers_1.ethers.ZeroAddress;
|
|
2191
2157
|
}
|
|
2192
2158
|
catch { /* assume not registered */ }
|
|
2193
2159
|
try {
|
|
@@ -2204,7 +2170,7 @@ export function registerWalletCommands(program) {
|
|
|
2204
2170
|
value: 0n,
|
|
2205
2171
|
minReturnValue: 0n,
|
|
2206
2172
|
maxApprovalAmount: 0n,
|
|
2207
|
-
approvalToken: ethers.ZeroAddress,
|
|
2173
|
+
approvalToken: ethers_1.ethers.ZeroAddress,
|
|
2208
2174
|
}]),
|
|
2209
2175
|
value: "0x0",
|
|
2210
2176
|
});
|
|
@@ -2219,7 +2185,7 @@ export function registerWalletCommands(program) {
|
|
|
2219
2185
|
// velocity limit
|
|
2220
2186
|
calls.push({
|
|
2221
2187
|
to: config.walletContractAddress,
|
|
2222
|
-
data: ownerInterface.encodeFunctionData("setVelocityLimit", [ethers.parseEther(velocityEth)]),
|
|
2188
|
+
data: ownerInterface.encodeFunctionData("setVelocityLimit", [ethers_1.ethers.parseEther(velocityEth)]),
|
|
2223
2189
|
value: "0x0",
|
|
2224
2190
|
});
|
|
2225
2191
|
// guardian
|
|
@@ -2237,7 +2203,7 @@ export function registerWalletCommands(program) {
|
|
|
2237
2203
|
data: policyInterface.encodeFunctionData("setCategoryLimitFor", [
|
|
2238
2204
|
config.walletContractAddress,
|
|
2239
2205
|
category,
|
|
2240
|
-
ethers.parseEther(amountEth),
|
|
2206
|
+
ethers_1.ethers.parseEther(amountEth),
|
|
2241
2207
|
]),
|
|
2242
2208
|
value: "0x0",
|
|
2243
2209
|
});
|
|
@@ -2267,7 +2233,7 @@ export function registerWalletCommands(program) {
|
|
|
2267
2233
|
console.log(" (wallet_sendCalls not supported — sending sequentially)");
|
|
2268
2234
|
for (let i = 0; i < calls.length; i++) {
|
|
2269
2235
|
console.log(` Sending transaction ${i + 1}/${calls.length}...`);
|
|
2270
|
-
const txHash = await sendTransactionWithSession(client, session, account, chainId, calls[i]);
|
|
2236
|
+
const txHash = await (0, walletconnect_1.sendTransactionWithSession)(client, session, account, chainId, calls[i]);
|
|
2271
2237
|
txHashes.push(txHash);
|
|
2272
2238
|
}
|
|
2273
2239
|
}
|
|
@@ -2277,26 +2243,26 @@ export function registerWalletCommands(program) {
|
|
|
2277
2243
|
if (config.guardianPrivateKey)
|
|
2278
2244
|
delete config.guardianPrivateKey;
|
|
2279
2245
|
config.guardianAddress = guardianWallet.address;
|
|
2280
|
-
saveConfig(config);
|
|
2246
|
+
(0, config_1.saveConfig)(config);
|
|
2281
2247
|
}
|
|
2282
|
-
console.log("\n" + c.success + c.white(" Governance setup complete"));
|
|
2248
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(" Governance setup complete"));
|
|
2283
2249
|
if (usedBatch) {
|
|
2284
|
-
console.log(" " + c.dim("Batch tx:") + " " + c.white(txHashes[0]));
|
|
2250
|
+
console.log(" " + colors_1.c.dim("Batch tx:") + " " + colors_1.c.white(txHashes[0]));
|
|
2285
2251
|
}
|
|
2286
2252
|
else {
|
|
2287
|
-
txHashes.forEach((h, i) => console.log(" " + c.dim(`Tx ${i + 1}:`) + " " + c.white(h)));
|
|
2253
|
+
txHashes.forEach((h, i) => console.log(" " + colors_1.c.dim(`Tx ${i + 1}:`) + " " + colors_1.c.white(h)));
|
|
2288
2254
|
}
|
|
2289
2255
|
if (guardianWallet) {
|
|
2290
|
-
console.log(" " + c.success + c.dim(` Guardian key saved to ~/.arc402/guardian.key — address: ${guardianWallet.address}`));
|
|
2291
|
-
console.log(" " + c.warning + " " + c.yellow("Store the guardian private key separately from your hot key."));
|
|
2256
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(` Guardian key saved to ~/.arc402/guardian.key — address: ${guardianWallet.address}`));
|
|
2257
|
+
console.log(" " + colors_1.c.warning + " " + colors_1.c.yellow("Store the guardian private key separately from your hot key."));
|
|
2292
2258
|
}
|
|
2293
|
-
console.log(c.dim("\nVerify with: arc402 wallet status && arc402 wallet policy show"));
|
|
2259
|
+
console.log(colors_1.c.dim("\nVerify with: arc402 wallet status && arc402 wallet policy show"));
|
|
2294
2260
|
});
|
|
2295
2261
|
// ─── authorize-machine-key ─────────────────────────────────────────────────
|
|
2296
2262
|
wallet.command("authorize-machine-key <key>")
|
|
2297
2263
|
.description("Authorize a machine key (hot key) on your ARC402Wallet (phone wallet signs via WalletConnect)")
|
|
2298
2264
|
.action(async (keyAddress) => {
|
|
2299
|
-
const config = loadConfig();
|
|
2265
|
+
const config = (0, config_1.loadConfig)();
|
|
2300
2266
|
if (!config.walletContractAddress) {
|
|
2301
2267
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
2302
2268
|
process.exit(1);
|
|
@@ -2307,23 +2273,23 @@ export function registerWalletCommands(program) {
|
|
|
2307
2273
|
}
|
|
2308
2274
|
let checksumKey;
|
|
2309
2275
|
try {
|
|
2310
|
-
checksumKey = ethers.getAddress(keyAddress);
|
|
2276
|
+
checksumKey = ethers_1.ethers.getAddress(keyAddress);
|
|
2311
2277
|
}
|
|
2312
2278
|
catch {
|
|
2313
2279
|
console.error(`Invalid address: ${keyAddress}`);
|
|
2314
2280
|
process.exit(1);
|
|
2315
2281
|
}
|
|
2316
2282
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
2317
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
2283
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
2318
2284
|
const machineKeyAbi = ["function authorizeMachineKey(address key) external", "function authorizedMachineKeys(address) external view returns (bool)"];
|
|
2319
|
-
const walletContract = new ethers.Contract(config.walletContractAddress, machineKeyAbi, provider);
|
|
2285
|
+
const walletContract = new ethers_1.ethers.Contract(config.walletContractAddress, machineKeyAbi, provider);
|
|
2320
2286
|
let alreadyAuthorized = false;
|
|
2321
2287
|
try {
|
|
2322
2288
|
alreadyAuthorized = await walletContract.authorizedMachineKeys(checksumKey);
|
|
2323
2289
|
}
|
|
2324
2290
|
catch { /* ignore */ }
|
|
2325
2291
|
if (alreadyAuthorized) {
|
|
2326
|
-
console.log("\n" + c.success + " " + c.white(checksumKey) + c.dim(` is already authorized as a machine key on ${config.walletContractAddress}`));
|
|
2292
|
+
console.log("\n" + colors_1.c.success + " " + colors_1.c.white(checksumKey) + colors_1.c.dim(` is already authorized as a machine key on ${config.walletContractAddress}`));
|
|
2327
2293
|
process.exit(0);
|
|
2328
2294
|
}
|
|
2329
2295
|
console.log(`\nWallet: ${config.walletContractAddress}`);
|
|
@@ -2331,29 +2297,29 @@ export function registerWalletCommands(program) {
|
|
|
2331
2297
|
const telegramOpts = config.telegramBotToken && config.telegramChatId
|
|
2332
2298
|
? { botToken: config.telegramBotToken, chatId: config.telegramChatId, threadId: config.telegramThreadId }
|
|
2333
2299
|
: undefined;
|
|
2334
|
-
const walletInterface = new ethers.Interface(machineKeyAbi);
|
|
2300
|
+
const walletInterface = new ethers_1.ethers.Interface(machineKeyAbi);
|
|
2335
2301
|
const txData = {
|
|
2336
2302
|
to: config.walletContractAddress,
|
|
2337
2303
|
data: walletInterface.encodeFunctionData("authorizeMachineKey", [checksumKey]),
|
|
2338
2304
|
value: "0x0",
|
|
2339
2305
|
};
|
|
2340
|
-
const { client, session, account } = await connectPhoneWallet(config.walletConnectProjectId, chainId, config, {
|
|
2306
|
+
const { client, session, account } = await (0, walletconnect_1.connectPhoneWallet)(config.walletConnectProjectId, chainId, config, {
|
|
2341
2307
|
telegramOpts,
|
|
2342
2308
|
prompt: `Authorize machine key ${checksumKey} on ARC402Wallet — allows autonomous protocol ops`,
|
|
2343
2309
|
});
|
|
2344
|
-
console.log("\n" + c.success + c.white(` Connected: ${account}`));
|
|
2345
|
-
console.log(c.dim("Sending authorizeMachineKey transaction..."));
|
|
2346
|
-
const hash = await sendTransactionWithSession(client, session, account, chainId, txData);
|
|
2347
|
-
console.log("\n" + c.dim("Transaction submitted:") + " " + c.white(hash));
|
|
2348
|
-
console.log(c.dim("Waiting for confirmation..."));
|
|
2310
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(` Connected: ${account}`));
|
|
2311
|
+
console.log(colors_1.c.dim("Sending authorizeMachineKey transaction..."));
|
|
2312
|
+
const hash = await (0, walletconnect_1.sendTransactionWithSession)(client, session, account, chainId, txData);
|
|
2313
|
+
console.log("\n" + colors_1.c.dim("Transaction submitted:") + " " + colors_1.c.white(hash));
|
|
2314
|
+
console.log(colors_1.c.dim("Waiting for confirmation..."));
|
|
2349
2315
|
const receipt = await provider.waitForTransaction(hash, 1, 60000);
|
|
2350
2316
|
if (!receipt || receipt.status !== 1) {
|
|
2351
|
-
console.error(c.failure + " " + c.red("Transaction failed."));
|
|
2317
|
+
console.error(colors_1.c.failure + " " + colors_1.c.red("Transaction failed."));
|
|
2352
2318
|
process.exit(1);
|
|
2353
2319
|
}
|
|
2354
2320
|
const confirmed = await walletContract.authorizedMachineKeys(checksumKey);
|
|
2355
|
-
console.log("\n" + c.success + c.white(` Machine key authorized: ${confirmed ? "YES" : "NO"}`));
|
|
2356
|
-
renderTree([
|
|
2321
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(` Machine key authorized: ${confirmed ? "YES" : "NO"}`));
|
|
2322
|
+
(0, tree_1.renderTree)([
|
|
2357
2323
|
{ label: "Wallet", value: config.walletContractAddress ?? "" },
|
|
2358
2324
|
{ label: "Machine key", value: checksumKey },
|
|
2359
2325
|
{ label: "Tx", value: hash, last: true },
|
|
@@ -2368,7 +2334,7 @@ export function registerWalletCommands(program) {
|
|
|
2368
2334
|
wallet.command("revoke-machine-key <address>")
|
|
2369
2335
|
.description("Revoke an authorized machine key on ARC402Wallet (phone wallet signs via WalletConnect)")
|
|
2370
2336
|
.action(async (keyAddress) => {
|
|
2371
|
-
const config = loadConfig();
|
|
2337
|
+
const config = (0, config_1.loadConfig)();
|
|
2372
2338
|
if (!config.walletContractAddress) {
|
|
2373
2339
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
2374
2340
|
process.exit(1);
|
|
@@ -2379,15 +2345,15 @@ export function registerWalletCommands(program) {
|
|
|
2379
2345
|
}
|
|
2380
2346
|
let checksumKey;
|
|
2381
2347
|
try {
|
|
2382
|
-
checksumKey = ethers.getAddress(keyAddress);
|
|
2348
|
+
checksumKey = ethers_1.ethers.getAddress(keyAddress);
|
|
2383
2349
|
}
|
|
2384
2350
|
catch {
|
|
2385
2351
|
console.error(`Invalid address: ${keyAddress}`);
|
|
2386
2352
|
process.exit(1);
|
|
2387
2353
|
}
|
|
2388
2354
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
2389
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
2390
|
-
const walletContract = new ethers.Contract(config.walletContractAddress, ARC402_WALLET_MACHINE_KEY_ABI, provider);
|
|
2355
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
2356
|
+
const walletContract = new ethers_1.ethers.Contract(config.walletContractAddress, abis_1.ARC402_WALLET_MACHINE_KEY_ABI, provider);
|
|
2391
2357
|
// Pre-check: verify the key IS currently authorized
|
|
2392
2358
|
let isAuthorized = false;
|
|
2393
2359
|
try {
|
|
@@ -2404,25 +2370,25 @@ export function registerWalletCommands(program) {
|
|
|
2404
2370
|
const telegramOpts = config.telegramBotToken && config.telegramChatId
|
|
2405
2371
|
? { botToken: config.telegramBotToken, chatId: config.telegramChatId, threadId: config.telegramThreadId }
|
|
2406
2372
|
: undefined;
|
|
2407
|
-
const walletInterface = new ethers.Interface(ARC402_WALLET_MACHINE_KEY_ABI);
|
|
2408
|
-
const { client, session, account } = await connectPhoneWallet(config.walletConnectProjectId, chainId, config, { telegramOpts, prompt: `Revoke machine key ${checksumKey} on ARC402Wallet` });
|
|
2409
|
-
console.log("\n" + c.success + c.white(` Connected: ${account}`));
|
|
2410
|
-
console.log(c.dim("Sending revokeMachineKey transaction..."));
|
|
2411
|
-
const hash = await sendTransactionWithSession(client, session, account, chainId, {
|
|
2373
|
+
const walletInterface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_MACHINE_KEY_ABI);
|
|
2374
|
+
const { client, session, account } = await (0, walletconnect_1.connectPhoneWallet)(config.walletConnectProjectId, chainId, config, { telegramOpts, prompt: `Revoke machine key ${checksumKey} on ARC402Wallet` });
|
|
2375
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(` Connected: ${account}`));
|
|
2376
|
+
console.log(colors_1.c.dim("Sending revokeMachineKey transaction..."));
|
|
2377
|
+
const hash = await (0, walletconnect_1.sendTransactionWithSession)(client, session, account, chainId, {
|
|
2412
2378
|
to: config.walletContractAddress,
|
|
2413
2379
|
data: walletInterface.encodeFunctionData("revokeMachineKey", [checksumKey]),
|
|
2414
2380
|
value: "0x0",
|
|
2415
2381
|
});
|
|
2416
|
-
console.log("\n" + c.dim("Transaction submitted:") + " " + c.white(hash));
|
|
2417
|
-
console.log(c.dim("Waiting for confirmation..."));
|
|
2382
|
+
console.log("\n" + colors_1.c.dim("Transaction submitted:") + " " + colors_1.c.white(hash));
|
|
2383
|
+
console.log(colors_1.c.dim("Waiting for confirmation..."));
|
|
2418
2384
|
const receipt = await provider.waitForTransaction(hash, 1, 60000);
|
|
2419
2385
|
if (!receipt || receipt.status !== 1) {
|
|
2420
|
-
console.error(c.failure + " " + c.red("Transaction failed."));
|
|
2386
|
+
console.error(colors_1.c.failure + " " + colors_1.c.red("Transaction failed."));
|
|
2421
2387
|
process.exit(1);
|
|
2422
2388
|
}
|
|
2423
2389
|
const stillAuthorized = await walletContract.authorizedMachineKeys(checksumKey);
|
|
2424
|
-
console.log("\n" + c.success + c.white(` Machine key revoked: ${stillAuthorized ? "NO (still authorized — check tx)" : "YES"}`));
|
|
2425
|
-
renderTree([
|
|
2390
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(` Machine key revoked: ${stillAuthorized ? "NO (still authorized — check tx)" : "YES"}`));
|
|
2391
|
+
(0, tree_1.renderTree)([
|
|
2426
2392
|
{ label: "Wallet", value: config.walletContractAddress ?? "" },
|
|
2427
2393
|
{ label: "Machine key", value: checksumKey },
|
|
2428
2394
|
{ label: "Tx", value: hash, last: true },
|
|
@@ -2438,17 +2404,17 @@ export function registerWalletCommands(program) {
|
|
|
2438
2404
|
.description("List authorized machine keys by scanning contract events")
|
|
2439
2405
|
.option("--json")
|
|
2440
2406
|
.action(async (opts) => {
|
|
2441
|
-
const config = loadConfig();
|
|
2407
|
+
const config = (0, config_1.loadConfig)();
|
|
2442
2408
|
const walletAddr = config.walletContractAddress;
|
|
2443
2409
|
if (!walletAddr) {
|
|
2444
2410
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
2445
2411
|
process.exit(1);
|
|
2446
2412
|
}
|
|
2447
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
2448
|
-
const walletContract = new ethers.Contract(walletAddr, ARC402_WALLET_MACHINE_KEY_ABI, provider);
|
|
2413
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
2414
|
+
const walletContract = new ethers_1.ethers.Contract(walletAddr, abis_1.ARC402_WALLET_MACHINE_KEY_ABI, provider);
|
|
2449
2415
|
// Scan for MachineKeyAuthorized and MachineKeyRevoked events
|
|
2450
|
-
const authorizedTopic = ethers.id("MachineKeyAuthorized(address)");
|
|
2451
|
-
const revokedTopic = ethers.id("MachineKeyRevoked(address)");
|
|
2416
|
+
const authorizedTopic = ethers_1.ethers.id("MachineKeyAuthorized(address)");
|
|
2417
|
+
const revokedTopic = ethers_1.ethers.id("MachineKeyRevoked(address)");
|
|
2452
2418
|
const authorizedKeys = new Set();
|
|
2453
2419
|
const revokedKeys = new Set();
|
|
2454
2420
|
try {
|
|
@@ -2457,11 +2423,11 @@ export function registerWalletCommands(program) {
|
|
|
2457
2423
|
provider.getLogs({ address: walletAddr, topics: [revokedTopic], fromBlock: 0 }),
|
|
2458
2424
|
]);
|
|
2459
2425
|
for (const log of authLogs) {
|
|
2460
|
-
const key = ethers.getAddress("0x" + log.topics[1].slice(26));
|
|
2426
|
+
const key = ethers_1.ethers.getAddress("0x" + log.topics[1].slice(26));
|
|
2461
2427
|
authorizedKeys.add(key);
|
|
2462
2428
|
}
|
|
2463
2429
|
for (const log of revokeLogs) {
|
|
2464
|
-
const key = ethers.getAddress("0x" + log.topics[1].slice(26));
|
|
2430
|
+
const key = ethers_1.ethers.getAddress("0x" + log.topics[1].slice(26));
|
|
2465
2431
|
revokedKeys.add(key);
|
|
2466
2432
|
}
|
|
2467
2433
|
}
|
|
@@ -2469,7 +2435,7 @@ export function registerWalletCommands(program) {
|
|
|
2469
2435
|
// Build active key list: authorized but not revoked
|
|
2470
2436
|
const activeFromEvents = [...authorizedKeys].filter((k) => !revokedKeys.has(k));
|
|
2471
2437
|
// Also check configured machine key
|
|
2472
|
-
const configMachineKey = config.privateKey ? new ethers.Wallet(config.privateKey).address : null;
|
|
2438
|
+
const configMachineKey = config.privateKey ? new ethers_1.ethers.Wallet(config.privateKey).address : null;
|
|
2473
2439
|
// Verify each candidate against chain
|
|
2474
2440
|
const candidates = new Set(activeFromEvents);
|
|
2475
2441
|
if (configMachineKey)
|
|
@@ -2511,8 +2477,8 @@ export function registerWalletCommands(program) {
|
|
|
2511
2477
|
.option("--task-type <type>", "Task type string for the context", "general")
|
|
2512
2478
|
.option("--json")
|
|
2513
2479
|
.action(async (opts) => {
|
|
2514
|
-
const config = loadConfig();
|
|
2515
|
-
warnIfPublicRpc(config);
|
|
2480
|
+
const config = (0, config_1.loadConfig)();
|
|
2481
|
+
(0, config_2.warnIfPublicRpc)(config);
|
|
2516
2482
|
const walletAddr = config.walletContractAddress;
|
|
2517
2483
|
if (!walletAddr) {
|
|
2518
2484
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
@@ -2522,9 +2488,9 @@ export function registerWalletCommands(program) {
|
|
|
2522
2488
|
console.error("privateKey not set in config — machine key required for open-context.");
|
|
2523
2489
|
process.exit(1);
|
|
2524
2490
|
}
|
|
2525
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
2526
|
-
const machineKey = new ethers.Wallet(config.privateKey, provider);
|
|
2527
|
-
const walletContract = new ethers.Contract(walletAddr, ARC402_WALLET_PROTOCOL_ABI, machineKey);
|
|
2491
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
2492
|
+
const machineKey = new ethers_1.ethers.Wallet(config.privateKey, provider);
|
|
2493
|
+
const walletContract = new ethers_1.ethers.Contract(walletAddr, abis_1.ARC402_WALLET_PROTOCOL_ABI, machineKey);
|
|
2528
2494
|
// Check context isn't already open
|
|
2529
2495
|
const isOpen = await walletContract.contextOpen();
|
|
2530
2496
|
if (isOpen) {
|
|
@@ -2532,7 +2498,7 @@ export function registerWalletCommands(program) {
|
|
|
2532
2498
|
console.error("Close it first: arc402 wallet close-context");
|
|
2533
2499
|
process.exit(1);
|
|
2534
2500
|
}
|
|
2535
|
-
const contextId = ethers.hexlify(ethers.randomBytes(32));
|
|
2501
|
+
const contextId = ethers_1.ethers.hexlify(ethers_1.ethers.randomBytes(32));
|
|
2536
2502
|
console.log(`Opening context (taskType: ${opts.taskType})...`);
|
|
2537
2503
|
const tx = await walletContract.openContext(contextId, opts.taskType);
|
|
2538
2504
|
const receipt = await tx.wait(1);
|
|
@@ -2540,13 +2506,13 @@ export function registerWalletCommands(program) {
|
|
|
2540
2506
|
console.log(JSON.stringify({ walletAddress: walletAddr, contextId, taskType: opts.taskType, txHash: receipt?.hash }));
|
|
2541
2507
|
}
|
|
2542
2508
|
else {
|
|
2543
|
-
console.log(" " + c.success + c.white(" Context opened"));
|
|
2544
|
-
renderTree([
|
|
2509
|
+
console.log(" " + colors_1.c.success + colors_1.c.white(" Context opened"));
|
|
2510
|
+
(0, tree_1.renderTree)([
|
|
2545
2511
|
{ label: "contextId", value: contextId },
|
|
2546
2512
|
{ label: "taskType", value: opts.taskType },
|
|
2547
2513
|
{ label: "Tx", value: receipt?.hash ?? "", last: true },
|
|
2548
2514
|
]);
|
|
2549
|
-
console.log(c.dim("\nNote: Each context allows only one spend. Call `arc402 wallet attest` then `arc402 wallet drain` (or executeSpend directly)."));
|
|
2515
|
+
console.log(colors_1.c.dim("\nNote: Each context allows only one spend. Call `arc402 wallet attest` then `arc402 wallet drain` (or executeSpend directly)."));
|
|
2550
2516
|
}
|
|
2551
2517
|
});
|
|
2552
2518
|
// ─── attest (J1-03) ────────────────────────────────────────────────────────
|
|
@@ -2562,8 +2528,8 @@ export function registerWalletCommands(program) {
|
|
|
2562
2528
|
.option("--ttl <seconds>", "Attestation TTL in seconds (default: 600)", "600")
|
|
2563
2529
|
.option("--json")
|
|
2564
2530
|
.action(async (opts) => {
|
|
2565
|
-
const config = loadConfig();
|
|
2566
|
-
warnIfPublicRpc(config);
|
|
2531
|
+
const config = (0, config_1.loadConfig)();
|
|
2532
|
+
(0, config_2.warnIfPublicRpc)(config);
|
|
2567
2533
|
const walletAddr = config.walletContractAddress;
|
|
2568
2534
|
if (!walletAddr) {
|
|
2569
2535
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
@@ -2575,19 +2541,19 @@ export function registerWalletCommands(program) {
|
|
|
2575
2541
|
}
|
|
2576
2542
|
let checksumRecipient;
|
|
2577
2543
|
try {
|
|
2578
|
-
checksumRecipient = ethers.getAddress(opts.recipient);
|
|
2544
|
+
checksumRecipient = ethers_1.ethers.getAddress(opts.recipient);
|
|
2579
2545
|
}
|
|
2580
2546
|
catch {
|
|
2581
2547
|
console.error(`Invalid recipient address: ${opts.recipient}`);
|
|
2582
2548
|
process.exit(1);
|
|
2583
2549
|
}
|
|
2584
|
-
const tokenAddress = opts.token ? ethers.getAddress(opts.token) : ethers.ZeroAddress;
|
|
2585
|
-
const amount = ethers.parseEther(opts.amount);
|
|
2550
|
+
const tokenAddress = opts.token ? ethers_1.ethers.getAddress(opts.token) : ethers_1.ethers.ZeroAddress;
|
|
2551
|
+
const amount = ethers_1.ethers.parseEther(opts.amount);
|
|
2586
2552
|
const expiresAt = Math.floor(Date.now() / 1000) + parseInt(opts.ttl, 10);
|
|
2587
|
-
const attestationId = ethers.hexlify(ethers.randomBytes(32));
|
|
2588
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
2589
|
-
const machineKey = new ethers.Wallet(config.privateKey, provider);
|
|
2590
|
-
const walletContract = new ethers.Contract(walletAddr, ARC402_WALLET_PROTOCOL_ABI, machineKey);
|
|
2553
|
+
const attestationId = ethers_1.ethers.hexlify(ethers_1.ethers.randomBytes(32));
|
|
2554
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
2555
|
+
const machineKey = new ethers_1.ethers.Wallet(config.privateKey, provider);
|
|
2556
|
+
const walletContract = new ethers_1.ethers.Contract(walletAddr, abis_1.ARC402_WALLET_PROTOCOL_ABI, machineKey);
|
|
2591
2557
|
console.log(`Creating attestation...`);
|
|
2592
2558
|
const tx = await walletContract.attest(attestationId, opts.category, `cli attest: ${opts.category} to ${checksumRecipient}`, checksumRecipient, amount, tokenAddress, expiresAt);
|
|
2593
2559
|
const receipt = await tx.wait(1);
|
|
@@ -2604,16 +2570,16 @@ export function registerWalletCommands(program) {
|
|
|
2604
2570
|
}));
|
|
2605
2571
|
}
|
|
2606
2572
|
else {
|
|
2607
|
-
console.log(" " + c.success + c.white(" Attestation created"));
|
|
2608
|
-
renderTree([
|
|
2573
|
+
console.log(" " + colors_1.c.success + colors_1.c.white(" Attestation created"));
|
|
2574
|
+
(0, tree_1.renderTree)([
|
|
2609
2575
|
{ label: "attestationId", value: attestationId },
|
|
2610
2576
|
{ label: "recipient", value: checksumRecipient },
|
|
2611
2577
|
{ label: "amount", value: opts.amount + " ETH" },
|
|
2612
|
-
{ label: "token", value: tokenAddress === ethers.ZeroAddress ? "ETH" : tokenAddress },
|
|
2578
|
+
{ label: "token", value: tokenAddress === ethers_1.ethers.ZeroAddress ? "ETH" : tokenAddress },
|
|
2613
2579
|
{ label: "expiresAt", value: new Date(expiresAt * 1000).toISOString() },
|
|
2614
2580
|
{ label: "Tx", value: receipt?.hash ?? "", last: true },
|
|
2615
2581
|
]);
|
|
2616
|
-
console.log(c.dim("\nUse this attestationId in `arc402 wallet drain` or your spend flow."));
|
|
2582
|
+
console.log(colors_1.c.dim("\nUse this attestationId in `arc402 wallet drain` or your spend flow."));
|
|
2617
2583
|
}
|
|
2618
2584
|
});
|
|
2619
2585
|
// ─── velocity-status (J8-03) ───────────────────────────────────────────────
|
|
@@ -2623,14 +2589,14 @@ export function registerWalletCommands(program) {
|
|
|
2623
2589
|
.description("Show wallet-level velocity limit, current window spend, and remaining budget")
|
|
2624
2590
|
.option("--json")
|
|
2625
2591
|
.action(async (opts) => {
|
|
2626
|
-
const config = loadConfig();
|
|
2592
|
+
const config = (0, config_1.loadConfig)();
|
|
2627
2593
|
const walletAddr = config.walletContractAddress;
|
|
2628
2594
|
if (!walletAddr) {
|
|
2629
2595
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
2630
2596
|
process.exit(1);
|
|
2631
2597
|
}
|
|
2632
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
2633
|
-
const walletContract = new ethers.Contract(walletAddr, ARC402_WALLET_OWNER_ABI, provider);
|
|
2598
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
2599
|
+
const walletContract = new ethers_1.ethers.Contract(walletAddr, abis_1.ARC402_WALLET_OWNER_ABI, provider);
|
|
2634
2600
|
let velocityLimit = 0n;
|
|
2635
2601
|
let velocityWindowStart = 0n;
|
|
2636
2602
|
let cumulativeSpend = 0n;
|
|
@@ -2650,11 +2616,11 @@ export function registerWalletCommands(program) {
|
|
|
2650
2616
|
if (opts.json) {
|
|
2651
2617
|
console.log(JSON.stringify({
|
|
2652
2618
|
walletAddress: walletAddr,
|
|
2653
|
-
velocityLimit: ethers.formatEther(velocityLimit),
|
|
2619
|
+
velocityLimit: ethers_1.ethers.formatEther(velocityLimit),
|
|
2654
2620
|
velocityLimitEnabled: velocityLimit > 0n,
|
|
2655
2621
|
velocityWindowStart: windowStartDate?.toISOString() ?? null,
|
|
2656
|
-
cumulativeSpend: ethers.formatEther(cumulativeSpend),
|
|
2657
|
-
remaining: remaining !== null ? ethers.formatEther(remaining) : null,
|
|
2622
|
+
cumulativeSpend: ethers_1.ethers.formatEther(cumulativeSpend),
|
|
2623
|
+
remaining: remaining !== null ? ethers_1.ethers.formatEther(remaining) : null,
|
|
2658
2624
|
}, null, 2));
|
|
2659
2625
|
}
|
|
2660
2626
|
else {
|
|
@@ -2663,10 +2629,10 @@ export function registerWalletCommands(program) {
|
|
|
2663
2629
|
console.log(` Velocity limit: disabled (set with \`arc402 wallet set-velocity-limit <eth>\`)`);
|
|
2664
2630
|
}
|
|
2665
2631
|
else {
|
|
2666
|
-
console.log(` Limit: ${ethers.formatEther(velocityLimit)} ETH per rolling window`);
|
|
2632
|
+
console.log(` Limit: ${ethers_1.ethers.formatEther(velocityLimit)} ETH per rolling window`);
|
|
2667
2633
|
console.log(` Window start: ${windowStartDate?.toISOString() ?? "(no window yet)"}`);
|
|
2668
|
-
console.log(` Spent: ${ethers.formatEther(cumulativeSpend)} ETH`);
|
|
2669
|
-
console.log(` Remaining: ${remaining !== null ? ethers.formatEther(remaining) + " ETH" : "N/A"}`);
|
|
2634
|
+
console.log(` Spent: ${ethers_1.ethers.formatEther(cumulativeSpend)} ETH`);
|
|
2635
|
+
console.log(` Remaining: ${remaining !== null ? ethers_1.ethers.formatEther(remaining) + " ETH" : "N/A"}`);
|
|
2670
2636
|
}
|
|
2671
2637
|
}
|
|
2672
2638
|
});
|
|
@@ -2677,15 +2643,15 @@ export function registerWalletCommands(program) {
|
|
|
2677
2643
|
.description("Check whether the wallet's spend context is currently open (uses Alchemy RPC)")
|
|
2678
2644
|
.option("--json")
|
|
2679
2645
|
.action(async (opts) => {
|
|
2680
|
-
const config = loadConfig();
|
|
2681
|
-
warnIfPublicRpc(config);
|
|
2646
|
+
const config = (0, config_1.loadConfig)();
|
|
2647
|
+
(0, config_2.warnIfPublicRpc)(config);
|
|
2682
2648
|
const walletAddr = config.walletContractAddress;
|
|
2683
2649
|
if (!walletAddr) {
|
|
2684
2650
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
2685
2651
|
process.exit(1);
|
|
2686
2652
|
}
|
|
2687
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
2688
|
-
const walletContract = new ethers.Contract(walletAddr, ARC402_WALLET_PROTOCOL_ABI, provider);
|
|
2653
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
2654
|
+
const walletContract = new ethers_1.ethers.Contract(walletAddr, abis_1.ARC402_WALLET_PROTOCOL_ABI, provider);
|
|
2689
2655
|
const isOpen = await walletContract.contextOpen();
|
|
2690
2656
|
if (opts.json) {
|
|
2691
2657
|
console.log(JSON.stringify({ walletAddress: walletAddr, contextOpen: isOpen }));
|
|
@@ -2703,8 +2669,8 @@ export function registerWalletCommands(program) {
|
|
|
2703
2669
|
.description("Force-close a stale open context on the wallet (machine key signs — onlyOwnerOrMachineKey)")
|
|
2704
2670
|
.option("--json")
|
|
2705
2671
|
.action(async (opts) => {
|
|
2706
|
-
const config = loadConfig();
|
|
2707
|
-
warnIfPublicRpc(config);
|
|
2672
|
+
const config = (0, config_1.loadConfig)();
|
|
2673
|
+
(0, config_2.warnIfPublicRpc)(config);
|
|
2708
2674
|
const walletAddr = config.walletContractAddress;
|
|
2709
2675
|
if (!walletAddr) {
|
|
2710
2676
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
@@ -2714,9 +2680,9 @@ export function registerWalletCommands(program) {
|
|
|
2714
2680
|
console.error("privateKey not set in config — machine key required for close-context.");
|
|
2715
2681
|
process.exit(1);
|
|
2716
2682
|
}
|
|
2717
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
2718
|
-
const machineKey = new ethers.Wallet(config.privateKey, provider);
|
|
2719
|
-
const walletContract = new ethers.Contract(walletAddr, ARC402_WALLET_PROTOCOL_ABI, machineKey);
|
|
2683
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
2684
|
+
const machineKey = new ethers_1.ethers.Wallet(config.privateKey, provider);
|
|
2685
|
+
const walletContract = new ethers_1.ethers.Contract(walletAddr, abis_1.ARC402_WALLET_PROTOCOL_ABI, machineKey);
|
|
2720
2686
|
const isOpen = await walletContract.contextOpen();
|
|
2721
2687
|
if (!isOpen) {
|
|
2722
2688
|
if (opts.json) {
|
|
@@ -2734,9 +2700,9 @@ export function registerWalletCommands(program) {
|
|
|
2734
2700
|
console.log(JSON.stringify({ walletAddress: walletAddr, txHash: receipt?.hash, contextOpen: false }));
|
|
2735
2701
|
}
|
|
2736
2702
|
else {
|
|
2737
|
-
console.log(" " + c.success + c.white(" Context closed"));
|
|
2738
|
-
console.log(" " + c.dim("Tx:") + " " + c.white(receipt?.hash ?? ""));
|
|
2739
|
-
console.log(" " + c.dim("Wallet:") + " " + c.white(walletAddr));
|
|
2703
|
+
console.log(" " + colors_1.c.success + colors_1.c.white(" Context closed"));
|
|
2704
|
+
console.log(" " + colors_1.c.dim("Tx:") + " " + colors_1.c.white(receipt?.hash ?? ""));
|
|
2705
|
+
console.log(" " + colors_1.c.dim("Wallet:") + " " + colors_1.c.white(walletAddr));
|
|
2740
2706
|
}
|
|
2741
2707
|
});
|
|
2742
2708
|
// ─── drain ─────────────────────────────────────────────────────────────────
|
|
@@ -2751,8 +2717,8 @@ export function registerWalletCommands(program) {
|
|
|
2751
2717
|
.option("--category <cat>", "Spend category (default: general)", "general")
|
|
2752
2718
|
.option("--json")
|
|
2753
2719
|
.action(async (recipientArg, opts) => {
|
|
2754
|
-
const config = loadConfig();
|
|
2755
|
-
warnIfPublicRpc(config);
|
|
2720
|
+
const config = (0, config_1.loadConfig)();
|
|
2721
|
+
(0, config_2.warnIfPublicRpc)(config);
|
|
2756
2722
|
const walletAddr = config.walletContractAddress;
|
|
2757
2723
|
if (!walletAddr) {
|
|
2758
2724
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
@@ -2769,26 +2735,26 @@ export function registerWalletCommands(program) {
|
|
|
2769
2735
|
}
|
|
2770
2736
|
let checksumRecipient;
|
|
2771
2737
|
try {
|
|
2772
|
-
checksumRecipient = ethers.getAddress(recipient);
|
|
2738
|
+
checksumRecipient = ethers_1.ethers.getAddress(recipient);
|
|
2773
2739
|
}
|
|
2774
2740
|
catch {
|
|
2775
2741
|
console.error(`Invalid recipient address: ${recipient}`);
|
|
2776
2742
|
process.exit(1);
|
|
2777
2743
|
}
|
|
2778
|
-
const GAS_RESERVE = ethers.parseEther("0.00005");
|
|
2779
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
2780
|
-
const machineKey = new ethers.Wallet(config.privateKey, provider);
|
|
2781
|
-
const walletContract = new ethers.Contract(walletAddr, ARC402_WALLET_PROTOCOL_ABI, machineKey);
|
|
2744
|
+
const GAS_RESERVE = ethers_1.ethers.parseEther("0.00005");
|
|
2745
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
2746
|
+
const machineKey = new ethers_1.ethers.Wallet(config.privateKey, provider);
|
|
2747
|
+
const walletContract = new ethers_1.ethers.Contract(walletAddr, abis_1.ARC402_WALLET_PROTOCOL_ABI, machineKey);
|
|
2782
2748
|
// ── Pre-flight checks ──────────────────────────────────────────────────
|
|
2783
2749
|
const balance = await provider.getBalance(walletAddr);
|
|
2784
|
-
console.log(`Wallet balance: ${ethers.formatEther(balance)} ETH`);
|
|
2750
|
+
console.log(`Wallet balance: ${ethers_1.ethers.formatEther(balance)} ETH`);
|
|
2785
2751
|
if (balance <= GAS_RESERVE) {
|
|
2786
|
-
console.error(`Insufficient balance: ${ethers.formatEther(balance)} ETH — need more than ${ethers.formatEther(GAS_RESERVE)} ETH reserve`);
|
|
2752
|
+
console.error(`Insufficient balance: ${ethers_1.ethers.formatEther(balance)} ETH — need more than ${ethers_1.ethers.formatEther(GAS_RESERVE)} ETH reserve`);
|
|
2787
2753
|
process.exit(1);
|
|
2788
2754
|
}
|
|
2789
2755
|
// Check category is configured on PolicyEngine
|
|
2790
2756
|
const policyAddress = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
|
|
2791
|
-
const policyContract = new ethers.Contract(policyAddress, POLICY_ENGINE_LIMITS_ABI, provider);
|
|
2757
|
+
const policyContract = new ethers_1.ethers.Contract(policyAddress, abis_1.POLICY_ENGINE_LIMITS_ABI, provider);
|
|
2792
2758
|
const categoryLimit = await policyContract.categoryLimits(walletAddr, opts.category);
|
|
2793
2759
|
if (categoryLimit === 0n) {
|
|
2794
2760
|
console.error(`Category "${opts.category}" is not configured on PolicyEngine for this wallet.`);
|
|
@@ -2797,7 +2763,7 @@ export function registerWalletCommands(program) {
|
|
|
2797
2763
|
}
|
|
2798
2764
|
// Verify machine key is authorized
|
|
2799
2765
|
const machineKeyAbi = ["function authorizedMachineKeys(address) external view returns (bool)"];
|
|
2800
|
-
const walletCheck = new ethers.Contract(walletAddr, machineKeyAbi, provider);
|
|
2766
|
+
const walletCheck = new ethers_1.ethers.Contract(walletAddr, machineKeyAbi, provider);
|
|
2801
2767
|
let isAuthorized = false;
|
|
2802
2768
|
try {
|
|
2803
2769
|
isAuthorized = await walletCheck.authorizedMachineKeys(machineKey.address);
|
|
@@ -2813,46 +2779,46 @@ export function registerWalletCommands(program) {
|
|
|
2813
2779
|
// Compute drain amount
|
|
2814
2780
|
let drainAmount;
|
|
2815
2781
|
if (opts.amount) {
|
|
2816
|
-
drainAmount = ethers.parseEther(opts.amount);
|
|
2782
|
+
drainAmount = ethers_1.ethers.parseEther(opts.amount);
|
|
2817
2783
|
}
|
|
2818
2784
|
else {
|
|
2819
2785
|
drainAmount = balance - GAS_RESERVE;
|
|
2820
2786
|
}
|
|
2821
2787
|
if (drainAmount > categoryLimit) {
|
|
2822
|
-
console.warn(`WARN: drainAmount (${ethers.formatEther(drainAmount)} ETH) exceeds category limit (${ethers.formatEther(categoryLimit)} ETH)`);
|
|
2788
|
+
console.warn(`WARN: drainAmount (${ethers_1.ethers.formatEther(drainAmount)} ETH) exceeds category limit (${ethers_1.ethers.formatEther(categoryLimit)} ETH)`);
|
|
2823
2789
|
console.warn(` Capping at category limit.`);
|
|
2824
2790
|
drainAmount = categoryLimit;
|
|
2825
2791
|
}
|
|
2826
2792
|
console.log(`\nDrain plan:`);
|
|
2827
2793
|
console.log(` Wallet: ${walletAddr}`);
|
|
2828
2794
|
console.log(` Recipient: ${checksumRecipient}`);
|
|
2829
|
-
console.log(` Amount: ${ethers.formatEther(drainAmount)} ETH`);
|
|
2795
|
+
console.log(` Amount: ${ethers_1.ethers.formatEther(drainAmount)} ETH`);
|
|
2830
2796
|
console.log(` Category: ${opts.category}`);
|
|
2831
2797
|
console.log(` MachineKey: ${machineKey.address}`);
|
|
2832
2798
|
console.log(`\nNote: Each context allows exactly one spend. A new context is opened for each drain call.\n`);
|
|
2833
2799
|
// ── Step 1: context cleanup ────────────────────────────────────────────
|
|
2834
2800
|
const isOpen = await walletContract.contextOpen();
|
|
2835
2801
|
if (isOpen) {
|
|
2836
|
-
console.log(c.dim("Stale context found — closing it first..."));
|
|
2802
|
+
console.log(colors_1.c.dim("Stale context found — closing it first..."));
|
|
2837
2803
|
const closeTx = await walletContract.closeContext();
|
|
2838
2804
|
await closeTx.wait(2);
|
|
2839
|
-
console.log(" " + c.success + c.dim(` Closed: ${closeTx.hash}`));
|
|
2805
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(` Closed: ${closeTx.hash}`));
|
|
2840
2806
|
}
|
|
2841
2807
|
// ── Step 2: openContext ────────────────────────────────────────────────
|
|
2842
|
-
const contextId = ethers.keccak256(ethers.toUtf8Bytes(`drain-${Date.now()}`));
|
|
2843
|
-
console.log(c.dim("Opening context..."));
|
|
2808
|
+
const contextId = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(`drain-${Date.now()}`));
|
|
2809
|
+
console.log(colors_1.c.dim("Opening context..."));
|
|
2844
2810
|
const openTx = await walletContract.openContext(contextId, "drain");
|
|
2845
2811
|
const openReceipt = await openTx.wait(1);
|
|
2846
|
-
console.log(" " + c.success + c.dim(` openContext: ${openReceipt?.hash}`));
|
|
2812
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(` openContext: ${openReceipt?.hash}`));
|
|
2847
2813
|
// ── Step 3: attest (direct on wallet — onlyOwnerOrMachineKey, NOT via executeContractCall)
|
|
2848
|
-
const attestationId = ethers.hexlify(ethers.randomBytes(32));
|
|
2814
|
+
const attestationId = ethers_1.ethers.hexlify(ethers_1.ethers.randomBytes(32));
|
|
2849
2815
|
const expiry = Math.floor(Date.now() / 1000) + 600; // 10 min TTL
|
|
2850
|
-
console.log(c.dim("Creating attestation (direct on wallet)..."));
|
|
2851
|
-
const attestTx = await walletContract.attest(attestationId, "spend", `drain to ${checksumRecipient}`, checksumRecipient, drainAmount, ethers.ZeroAddress, expiry);
|
|
2816
|
+
console.log(colors_1.c.dim("Creating attestation (direct on wallet)..."));
|
|
2817
|
+
const attestTx = await walletContract.attest(attestationId, "spend", `drain to ${checksumRecipient}`, checksumRecipient, drainAmount, ethers_1.ethers.ZeroAddress, expiry);
|
|
2852
2818
|
const attestReceipt = await attestTx.wait(1);
|
|
2853
|
-
console.log(" " + c.success + c.dim(` attest: ${attestReceipt?.hash}`));
|
|
2819
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(` attest: ${attestReceipt?.hash}`));
|
|
2854
2820
|
// ── Step 4: executeSpend ───────────────────────────────────────────────
|
|
2855
|
-
console.log(c.dim("Executing spend..."));
|
|
2821
|
+
console.log(colors_1.c.dim("Executing spend..."));
|
|
2856
2822
|
let spendReceiptHash;
|
|
2857
2823
|
try {
|
|
2858
2824
|
const spendTx = await walletContract.executeSpend(checksumRecipient, drainAmount, opts.category, attestationId);
|
|
@@ -2860,21 +2826,21 @@ export function registerWalletCommands(program) {
|
|
|
2860
2826
|
spendReceiptHash = spendReceipt?.hash;
|
|
2861
2827
|
}
|
|
2862
2828
|
catch (e) {
|
|
2863
|
-
handleWalletError(e);
|
|
2829
|
+
(0, wallet_router_1.handleWalletError)(e);
|
|
2864
2830
|
}
|
|
2865
|
-
console.log(" " + c.success + c.dim(` executeSpend: ${spendReceiptHash}`));
|
|
2831
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(` executeSpend: ${spendReceiptHash}`));
|
|
2866
2832
|
// ── Step 5: closeContext ───────────────────────────────────────────────
|
|
2867
|
-
console.log(c.dim("Closing context..."));
|
|
2833
|
+
console.log(colors_1.c.dim("Closing context..."));
|
|
2868
2834
|
const closeTx2 = await walletContract.closeContext();
|
|
2869
2835
|
const closeReceipt = await closeTx2.wait(1);
|
|
2870
|
-
console.log(" " + c.success + c.dim(` closeContext: ${closeReceipt?.hash}`));
|
|
2836
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(` closeContext: ${closeReceipt?.hash}`));
|
|
2871
2837
|
const newBalance = await provider.getBalance(walletAddr);
|
|
2872
2838
|
if (opts.json) {
|
|
2873
2839
|
console.log(JSON.stringify({
|
|
2874
2840
|
ok: true,
|
|
2875
2841
|
walletAddress: walletAddr,
|
|
2876
2842
|
recipient: checksumRecipient,
|
|
2877
|
-
amount: ethers.formatEther(drainAmount),
|
|
2843
|
+
amount: ethers_1.ethers.formatEther(drainAmount),
|
|
2878
2844
|
category: opts.category,
|
|
2879
2845
|
txHashes: {
|
|
2880
2846
|
openContext: openReceipt?.hash,
|
|
@@ -2882,14 +2848,14 @@ export function registerWalletCommands(program) {
|
|
|
2882
2848
|
executeSpend: spendReceiptHash,
|
|
2883
2849
|
closeContext: closeReceipt?.hash,
|
|
2884
2850
|
},
|
|
2885
|
-
remainingBalance: ethers.formatEther(newBalance),
|
|
2851
|
+
remainingBalance: ethers_1.ethers.formatEther(newBalance),
|
|
2886
2852
|
}));
|
|
2887
2853
|
}
|
|
2888
2854
|
else {
|
|
2889
|
-
console.log("\n" + c.success + c.white(" Drain complete"));
|
|
2890
|
-
renderTree([
|
|
2891
|
-
{ label: "Sent", value: `${ethers.formatEther(drainAmount)} ETH → ${checksumRecipient}` },
|
|
2892
|
-
{ label: "Remaining", value: `${ethers.formatEther(newBalance)} ETH`, last: true },
|
|
2855
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(" Drain complete"));
|
|
2856
|
+
(0, tree_1.renderTree)([
|
|
2857
|
+
{ label: "Sent", value: `${ethers_1.ethers.formatEther(drainAmount)} ETH → ${checksumRecipient}` },
|
|
2858
|
+
{ label: "Remaining", value: `${ethers_1.ethers.formatEther(newBalance)} ETH`, last: true },
|
|
2893
2859
|
]);
|
|
2894
2860
|
}
|
|
2895
2861
|
});
|
|
@@ -2909,8 +2875,8 @@ export function registerWalletCommands(program) {
|
|
|
2909
2875
|
.option("--decimals <n>", "Token decimals override (default: auto-detect from contract)", "auto")
|
|
2910
2876
|
.option("--json")
|
|
2911
2877
|
.action(async (recipientArg, amountArg, opts) => {
|
|
2912
|
-
const config = loadConfig();
|
|
2913
|
-
warnIfPublicRpc(config);
|
|
2878
|
+
const config = (0, config_1.loadConfig)();
|
|
2879
|
+
(0, config_2.warnIfPublicRpc)(config);
|
|
2914
2880
|
const walletAddr = config.walletContractAddress;
|
|
2915
2881
|
if (!walletAddr) {
|
|
2916
2882
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
@@ -2923,11 +2889,11 @@ export function registerWalletCommands(program) {
|
|
|
2923
2889
|
// Resolve token address
|
|
2924
2890
|
let tokenAddress;
|
|
2925
2891
|
if (opts.token.toLowerCase() === "usdc") {
|
|
2926
|
-
tokenAddress = getUsdcAddress(config);
|
|
2892
|
+
tokenAddress = (0, config_1.getUsdcAddress)(config);
|
|
2927
2893
|
}
|
|
2928
2894
|
else {
|
|
2929
2895
|
try {
|
|
2930
|
-
tokenAddress = ethers.getAddress(opts.token);
|
|
2896
|
+
tokenAddress = ethers_1.ethers.getAddress(opts.token);
|
|
2931
2897
|
}
|
|
2932
2898
|
catch {
|
|
2933
2899
|
console.error(`Invalid token address: ${opts.token}`);
|
|
@@ -2936,20 +2902,20 @@ export function registerWalletCommands(program) {
|
|
|
2936
2902
|
}
|
|
2937
2903
|
let checksumRecipient;
|
|
2938
2904
|
try {
|
|
2939
|
-
checksumRecipient = ethers.getAddress(recipientArg);
|
|
2905
|
+
checksumRecipient = ethers_1.ethers.getAddress(recipientArg);
|
|
2940
2906
|
}
|
|
2941
2907
|
catch {
|
|
2942
2908
|
console.error(`Invalid recipient address: ${recipientArg}`);
|
|
2943
2909
|
process.exit(1);
|
|
2944
2910
|
}
|
|
2945
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
2946
|
-
const machineKey = new ethers.Wallet(config.privateKey, provider);
|
|
2911
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
2912
|
+
const machineKey = new ethers_1.ethers.Wallet(config.privateKey, provider);
|
|
2947
2913
|
// Determine token decimals
|
|
2948
2914
|
const erc20Abi = [
|
|
2949
2915
|
"function decimals() external view returns (uint8)",
|
|
2950
2916
|
"function balanceOf(address owner) external view returns (uint256)",
|
|
2951
2917
|
];
|
|
2952
|
-
const erc20 = new ethers.Contract(tokenAddress, erc20Abi, provider);
|
|
2918
|
+
const erc20 = new ethers_1.ethers.Contract(tokenAddress, erc20Abi, provider);
|
|
2953
2919
|
let decimals;
|
|
2954
2920
|
if (opts.decimals !== "auto") {
|
|
2955
2921
|
decimals = parseInt(opts.decimals, 10);
|
|
@@ -2964,7 +2930,7 @@ export function registerWalletCommands(program) {
|
|
|
2964
2930
|
}
|
|
2965
2931
|
let tokenAmount;
|
|
2966
2932
|
try {
|
|
2967
|
-
tokenAmount = ethers.parseUnits(amountArg, decimals);
|
|
2933
|
+
tokenAmount = ethers_1.ethers.parseUnits(amountArg, decimals);
|
|
2968
2934
|
}
|
|
2969
2935
|
catch {
|
|
2970
2936
|
console.error(`Invalid amount: ${amountArg}. Provide a decimal value (e.g. 1.5).`);
|
|
@@ -2973,12 +2939,12 @@ export function registerWalletCommands(program) {
|
|
|
2973
2939
|
// Check token balance
|
|
2974
2940
|
const tokenBalance = await erc20.balanceOf(walletAddr);
|
|
2975
2941
|
if (tokenBalance < tokenAmount) {
|
|
2976
|
-
console.error(`Insufficient token balance: ${ethers.formatUnits(tokenBalance, decimals)} < ${amountArg}`);
|
|
2942
|
+
console.error(`Insufficient token balance: ${ethers_1.ethers.formatUnits(tokenBalance, decimals)} < ${amountArg}`);
|
|
2977
2943
|
process.exit(1);
|
|
2978
2944
|
}
|
|
2979
2945
|
// Check category is configured on PolicyEngine
|
|
2980
2946
|
const policyAddressT = config.policyEngineAddress ?? POLICY_ENGINE_DEFAULT;
|
|
2981
|
-
const policyContractT = new ethers.Contract(policyAddressT, POLICY_ENGINE_LIMITS_ABI, provider);
|
|
2947
|
+
const policyContractT = new ethers_1.ethers.Contract(policyAddressT, abis_1.POLICY_ENGINE_LIMITS_ABI, provider);
|
|
2982
2948
|
const categoryLimitT = await policyContractT.categoryLimits(walletAddr, opts.category);
|
|
2983
2949
|
if (categoryLimitT === 0n) {
|
|
2984
2950
|
console.error(`Category "${opts.category}" is not configured on PolicyEngine for this wallet.`);
|
|
@@ -2987,7 +2953,7 @@ export function registerWalletCommands(program) {
|
|
|
2987
2953
|
}
|
|
2988
2954
|
// Verify machine key is authorized
|
|
2989
2955
|
const mkAbi = ["function authorizedMachineKeys(address) external view returns (bool)"];
|
|
2990
|
-
const walletCheckT = new ethers.Contract(walletAddr, mkAbi, provider);
|
|
2956
|
+
const walletCheckT = new ethers_1.ethers.Contract(walletAddr, mkAbi, provider);
|
|
2991
2957
|
let isAuthorizedT = false;
|
|
2992
2958
|
try {
|
|
2993
2959
|
isAuthorizedT = await walletCheckT.authorizedMachineKeys(machineKey.address);
|
|
@@ -3000,7 +2966,7 @@ export function registerWalletCommands(program) {
|
|
|
3000
2966
|
console.error(`Fix: arc402 wallet authorize-machine-key ${machineKey.address}`);
|
|
3001
2967
|
process.exit(1);
|
|
3002
2968
|
}
|
|
3003
|
-
const walletContractT = new ethers.Contract(walletAddr, ARC402_WALLET_PROTOCOL_ABI, machineKey);
|
|
2969
|
+
const walletContractT = new ethers_1.ethers.Contract(walletAddr, abis_1.ARC402_WALLET_PROTOCOL_ABI, machineKey);
|
|
3004
2970
|
console.log(`\nDrain token plan:`);
|
|
3005
2971
|
console.log(` Wallet: ${walletAddr}`);
|
|
3006
2972
|
console.log(` Recipient: ${checksumRecipient}`);
|
|
@@ -3012,34 +2978,34 @@ export function registerWalletCommands(program) {
|
|
|
3012
2978
|
// ── Step 1: context cleanup ──────────────────────────────────────────────
|
|
3013
2979
|
const isOpenT = await walletContractT.contextOpen();
|
|
3014
2980
|
if (isOpenT) {
|
|
3015
|
-
console.log(c.dim("Stale context found — closing it first..."));
|
|
2981
|
+
console.log(colors_1.c.dim("Stale context found — closing it first..."));
|
|
3016
2982
|
const closeTxT = await walletContractT.closeContext();
|
|
3017
2983
|
await closeTxT.wait(2);
|
|
3018
|
-
console.log(" " + c.success + c.dim(` Closed: ${closeTxT.hash}`));
|
|
2984
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(` Closed: ${closeTxT.hash}`));
|
|
3019
2985
|
}
|
|
3020
2986
|
// ── Step 2: openContext ──────────────────────────────────────────────────
|
|
3021
|
-
const contextIdT = ethers.keccak256(ethers.toUtf8Bytes(`drain-token-${Date.now()}`));
|
|
3022
|
-
console.log(c.dim("Opening context..."));
|
|
2987
|
+
const contextIdT = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(`drain-token-${Date.now()}`));
|
|
2988
|
+
console.log(colors_1.c.dim("Opening context..."));
|
|
3023
2989
|
const openTxT = await walletContractT.openContext(contextIdT, "drain");
|
|
3024
2990
|
const openReceiptT = await openTxT.wait(1);
|
|
3025
|
-
console.log(" " + c.success + c.dim(` openContext: ${openReceiptT?.hash}`));
|
|
2991
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(` openContext: ${openReceiptT?.hash}`));
|
|
3026
2992
|
// ── Step 3: attest with token address ────────────────────────────────────
|
|
3027
|
-
const attestationIdT = ethers.hexlify(ethers.randomBytes(32));
|
|
2993
|
+
const attestationIdT = ethers_1.ethers.hexlify(ethers_1.ethers.randomBytes(32));
|
|
3028
2994
|
const expiryT = Math.floor(Date.now() / 1000) + 600; // 10 min TTL
|
|
3029
|
-
console.log(c.dim("Creating attestation (with token address)..."));
|
|
2995
|
+
console.log(colors_1.c.dim("Creating attestation (with token address)..."));
|
|
3030
2996
|
const attestTxT = await walletContractT.attest(attestationIdT, "spend", `token drain to ${checksumRecipient}`, checksumRecipient, tokenAmount, tokenAddress, expiryT);
|
|
3031
2997
|
const attestReceiptT = await attestTxT.wait(1);
|
|
3032
|
-
console.log(" " + c.success + c.dim(` attest: ${attestReceiptT?.hash}`));
|
|
2998
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(` attest: ${attestReceiptT?.hash}`));
|
|
3033
2999
|
// ── Step 4: executeTokenSpend ────────────────────────────────────────────
|
|
3034
|
-
console.log(c.dim("Executing token spend..."));
|
|
3000
|
+
console.log(colors_1.c.dim("Executing token spend..."));
|
|
3035
3001
|
const spendTxT = await walletContractT.executeTokenSpend(checksumRecipient, tokenAmount, tokenAddress, opts.category, attestationIdT);
|
|
3036
3002
|
const spendReceiptT = await spendTxT.wait(1);
|
|
3037
|
-
console.log(" " + c.success + c.dim(` executeTokenSpend: ${spendReceiptT?.hash}`));
|
|
3003
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(` executeTokenSpend: ${spendReceiptT?.hash}`));
|
|
3038
3004
|
// ── Step 5: closeContext ─────────────────────────────────────────────────
|
|
3039
|
-
console.log(c.dim("Closing context..."));
|
|
3005
|
+
console.log(colors_1.c.dim("Closing context..."));
|
|
3040
3006
|
const closeTxT2 = await walletContractT.closeContext();
|
|
3041
3007
|
const closeReceiptT = await closeTxT2.wait(1);
|
|
3042
|
-
console.log(" " + c.success + c.dim(` closeContext: ${closeReceiptT?.hash}`));
|
|
3008
|
+
console.log(" " + colors_1.c.success + colors_1.c.dim(` closeContext: ${closeReceiptT?.hash}`));
|
|
3043
3009
|
const newTokenBalance = await erc20.balanceOf(walletAddr);
|
|
3044
3010
|
if (opts.json) {
|
|
3045
3011
|
console.log(JSON.stringify({
|
|
@@ -3055,15 +3021,15 @@ export function registerWalletCommands(program) {
|
|
|
3055
3021
|
executeTokenSpend: spendReceiptT?.hash,
|
|
3056
3022
|
closeContext: closeReceiptT?.hash,
|
|
3057
3023
|
},
|
|
3058
|
-
remainingTokenBalance: ethers.formatUnits(newTokenBalance, decimals),
|
|
3024
|
+
remainingTokenBalance: ethers_1.ethers.formatUnits(newTokenBalance, decimals),
|
|
3059
3025
|
}));
|
|
3060
3026
|
}
|
|
3061
3027
|
else {
|
|
3062
|
-
console.log("\n" + c.success + c.white(" Token drain complete"));
|
|
3063
|
-
renderTree([
|
|
3028
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(" Token drain complete"));
|
|
3029
|
+
(0, tree_1.renderTree)([
|
|
3064
3030
|
{ label: "Sent", value: `${amountArg} → ${checksumRecipient}` },
|
|
3065
3031
|
{ label: "Token", value: tokenAddress },
|
|
3066
|
-
{ label: "Remaining", value: ethers.formatUnits(newTokenBalance, decimals), last: true },
|
|
3032
|
+
{ label: "Remaining", value: ethers_1.ethers.formatUnits(newTokenBalance, decimals), last: true },
|
|
3067
3033
|
]);
|
|
3068
3034
|
}
|
|
3069
3035
|
});
|
|
@@ -3076,7 +3042,7 @@ export function registerWalletCommands(program) {
|
|
|
3076
3042
|
wallet.command("set-passkey <pubKeyX> <pubKeyY>")
|
|
3077
3043
|
.description("Activate passkey (Face ID) on ARC402Wallet — takes P256 x/y coords from passkey setup (phone wallet signs via WalletConnect)")
|
|
3078
3044
|
.action(async (pubKeyX, pubKeyY) => {
|
|
3079
|
-
const config = loadConfig();
|
|
3045
|
+
const config = (0, config_1.loadConfig)();
|
|
3080
3046
|
if (!config.walletContractAddress) {
|
|
3081
3047
|
console.error("walletContractAddress not set in config. Run `arc402 wallet deploy` first.");
|
|
3082
3048
|
process.exit(1);
|
|
@@ -3096,8 +3062,8 @@ export function registerWalletCommands(program) {
|
|
|
3096
3062
|
process.exit(1);
|
|
3097
3063
|
}
|
|
3098
3064
|
const chainId = config.network === "base-mainnet" ? 8453 : 84532;
|
|
3099
|
-
const provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
3100
|
-
const walletInterface = new ethers.Interface(ARC402_WALLET_PASSKEY_ABI);
|
|
3065
|
+
const provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
|
|
3066
|
+
const walletInterface = new ethers_1.ethers.Interface(abis_1.ARC402_WALLET_PASSKEY_ABI);
|
|
3101
3067
|
console.log(`\nWallet: ${config.walletContractAddress}`);
|
|
3102
3068
|
console.log(`pubKeyX: ${pubKeyX}`);
|
|
3103
3069
|
console.log(`pubKeyY: ${pubKeyY}`);
|
|
@@ -3109,28 +3075,28 @@ export function registerWalletCommands(program) {
|
|
|
3109
3075
|
data: walletInterface.encodeFunctionData("setPasskey", [pubKeyX, pubKeyY]),
|
|
3110
3076
|
value: "0x0",
|
|
3111
3077
|
};
|
|
3112
|
-
const { client, session, account } = await connectPhoneWallet(config.walletConnectProjectId, chainId, config, {
|
|
3078
|
+
const { client, session, account } = await (0, walletconnect_1.connectPhoneWallet)(config.walletConnectProjectId, chainId, config, {
|
|
3113
3079
|
telegramOpts,
|
|
3114
3080
|
prompt: `Activate passkey (Face ID) on ARC402Wallet — enables P256 governance signing`,
|
|
3115
3081
|
});
|
|
3116
|
-
console.log("\n" + c.success + c.white(` Connected: ${account}`));
|
|
3117
|
-
console.log(c.dim("Sending setPasskey transaction..."));
|
|
3118
|
-
const hash = await sendTransactionWithSession(client, session, account, chainId, txData);
|
|
3119
|
-
console.log("\n" + c.dim("Transaction submitted:") + " " + c.white(hash));
|
|
3120
|
-
console.log(c.dim("Waiting for confirmation..."));
|
|
3082
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(` Connected: ${account}`));
|
|
3083
|
+
console.log(colors_1.c.dim("Sending setPasskey transaction..."));
|
|
3084
|
+
const hash = await (0, walletconnect_1.sendTransactionWithSession)(client, session, account, chainId, txData);
|
|
3085
|
+
console.log("\n" + colors_1.c.dim("Transaction submitted:") + " " + colors_1.c.white(hash));
|
|
3086
|
+
console.log(colors_1.c.dim("Waiting for confirmation..."));
|
|
3121
3087
|
const receipt = await provider.waitForTransaction(hash, 1, 60000);
|
|
3122
3088
|
if (!receipt || receipt.status !== 1) {
|
|
3123
|
-
console.error(c.failure + " " + c.red("Transaction failed."));
|
|
3089
|
+
console.error(colors_1.c.failure + " " + colors_1.c.red("Transaction failed."));
|
|
3124
3090
|
process.exit(1);
|
|
3125
3091
|
}
|
|
3126
|
-
console.log("\n" + c.success + c.white(" Passkey activated on ARC402Wallet"));
|
|
3127
|
-
renderTree([
|
|
3092
|
+
console.log("\n" + colors_1.c.success + colors_1.c.white(" Passkey activated on ARC402Wallet"));
|
|
3093
|
+
(0, tree_1.renderTree)([
|
|
3128
3094
|
{ label: "Wallet", value: config.walletContractAddress ?? "" },
|
|
3129
3095
|
{ label: "pubKeyX", value: pubKeyX },
|
|
3130
3096
|
{ label: "pubKeyY", value: pubKeyY },
|
|
3131
3097
|
{ label: "Tx", value: hash, last: true },
|
|
3132
3098
|
]);
|
|
3133
|
-
console.log(c.dim("\nGovernance ops now require Face ID instead of MetaMask."));
|
|
3099
|
+
console.log(colors_1.c.dim("\nGovernance ops now require Face ID instead of MetaMask."));
|
|
3134
3100
|
await client.disconnect({ topic: session.topic, reason: { code: 6000, message: "done" } });
|
|
3135
3101
|
process.exit(0);
|
|
3136
3102
|
});
|