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
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { ethers } from "ethers";
|
|
3
|
-
import { loadConfig, getUsdcAddress } from "../config.js";
|
|
4
|
-
import { requireSigner } from "../client.js";
|
|
5
|
-
import { AGENT_REGISTRY_ABI } from "../abis.js";
|
|
6
|
-
import { startSpinner } from "../ui/spinner.js";
|
|
7
|
-
import { renderTree } from "../ui/tree.js";
|
|
8
|
-
import { c } from "../ui/colors.js";
|
|
9
|
-
|
|
10
|
-
const DEFAULT_REGISTRY_ADDRESS = "0xD5c2851B00090c92Ba7F4723FB548bb30C9B6865";
|
|
11
|
-
|
|
12
|
-
async function pingHandshakeEndpoint(
|
|
13
|
-
agentAddress: string,
|
|
14
|
-
payload: Record<string, unknown>,
|
|
15
|
-
registryAddress: string,
|
|
16
|
-
provider: ethers.Provider
|
|
17
|
-
): Promise<void> {
|
|
18
|
-
const registry = new ethers.Contract(registryAddress, AGENT_REGISTRY_ABI, provider);
|
|
19
|
-
const agentData = await registry.getAgent(agentAddress);
|
|
20
|
-
const endpoint = agentData.endpoint as string;
|
|
21
|
-
if (!endpoint) return;
|
|
22
|
-
await fetch(`${endpoint}/handshake`, {
|
|
23
|
-
method: "POST",
|
|
24
|
-
headers: { "Content-Type": "application/json" },
|
|
25
|
-
body: JSON.stringify(payload),
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// ─── Handshake Contract ABI (from Handshake.sol) ─────────────────────────────
|
|
30
|
-
|
|
31
|
-
const HANDSHAKE_ABI = [
|
|
32
|
-
"function sendHandshake(address to, uint8 hsType, string note) payable",
|
|
33
|
-
"function sendHandshakeWithToken(address to, uint8 hsType, string note, address token, uint256 tokenAmount)",
|
|
34
|
-
"function sendBatch(address[] recipients, uint8[] hsTypes, string[] notes)",
|
|
35
|
-
"function hasConnection(address from, address to) view returns (bool)",
|
|
36
|
-
"function isMutual(address a, address b) view returns (bool)",
|
|
37
|
-
"function getStats(address agent) view returns (uint256 sent, uint256 received, uint256 uniqueInbound)",
|
|
38
|
-
"function sentCount(address) view returns (uint256)",
|
|
39
|
-
"function receivedCount(address) view returns (uint256)",
|
|
40
|
-
"function uniqueSenders(address) view returns (uint256)",
|
|
41
|
-
"function totalHandshakes() view returns (uint256)",
|
|
42
|
-
"function allowedTokens(address) view returns (bool)",
|
|
43
|
-
"event HandshakeSent(uint256 indexed handshakeId, address indexed from, address indexed to, uint8 hsType, address token, uint256 amount, string note, uint256 timestamp)",
|
|
44
|
-
"event NewConnection(address indexed from, address indexed to, uint256 handshakeId)",
|
|
45
|
-
];
|
|
46
|
-
|
|
47
|
-
const POLICY_ENGINE_ABI = [
|
|
48
|
-
"function isContractWhitelisted(address wallet, address target) view returns (bool)",
|
|
49
|
-
"function whitelistContract(address wallet, address target)",
|
|
50
|
-
];
|
|
51
|
-
|
|
52
|
-
const HANDSHAKE_TYPES: Record<string, number> = {
|
|
53
|
-
respect: 0,
|
|
54
|
-
curiosity: 1,
|
|
55
|
-
endorsement: 2,
|
|
56
|
-
thanks: 3,
|
|
57
|
-
collaboration: 4,
|
|
58
|
-
challenge: 5,
|
|
59
|
-
referral: 6,
|
|
60
|
-
hello: 7,
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
// ─── Auto-Whitelist ──────────────────────────────────────────────────────────
|
|
64
|
-
|
|
65
|
-
async function ensureWhitelisted(
|
|
66
|
-
signer: ethers.Signer,
|
|
67
|
-
provider: ethers.Provider,
|
|
68
|
-
walletAddress: string,
|
|
69
|
-
policyEngineAddress: string,
|
|
70
|
-
handshakeAddress: string
|
|
71
|
-
): Promise<void> {
|
|
72
|
-
// Check whitelist with RPC fallback (public RPCs often fail on eth_call)
|
|
73
|
-
const { callWithFallback } = await import("../ui/rpc-fallback.js");
|
|
74
|
-
const rpcUrl = (provider as ethers.JsonRpcProvider)._getConnection?.()?.url ?? "https://mainnet.base.org";
|
|
75
|
-
const isWhitelisted = await callWithFallback(rpcUrl, async (p) => {
|
|
76
|
-
const pe = new ethers.Contract(policyEngineAddress, POLICY_ENGINE_ABI, p);
|
|
77
|
-
return await pe.isContractWhitelisted(walletAddress, handshakeAddress) as boolean;
|
|
78
|
-
}).catch(() => true); // If all RPCs fail, assume whitelisted and let the tx itself fail if not
|
|
79
|
-
|
|
80
|
-
if (!isWhitelisted) {
|
|
81
|
-
console.log("Handshake contract not yet whitelisted on your wallet.");
|
|
82
|
-
console.log("Whitelisting now (one-time setup)...");
|
|
83
|
-
try {
|
|
84
|
-
const peSigner = new ethers.Contract(policyEngineAddress, POLICY_ENGINE_ABI, signer);
|
|
85
|
-
const tx = await peSigner.whitelistContract(walletAddress, handshakeAddress);
|
|
86
|
-
console.log(` tx: ${tx.hash}`);
|
|
87
|
-
await tx.wait();
|
|
88
|
-
console.log(" ✓ Handshake contract whitelisted\n");
|
|
89
|
-
} catch (e) {
|
|
90
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
91
|
-
if (msg.includes("already whitelisted")) {
|
|
92
|
-
console.log(" ✓ Handshake contract already whitelisted\n");
|
|
93
|
-
} else if (msg.includes("insufficient funds")) {
|
|
94
|
-
console.log(" ⚠ Machine key has no ETH for whitelisting. Use WalletConnect:");
|
|
95
|
-
console.log(` arc402 wallet whitelist-contract ${handshakeAddress}\n`);
|
|
96
|
-
return;
|
|
97
|
-
} else {
|
|
98
|
-
throw e;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// ─── Commands ────────────────────────────────────────────────────────────────
|
|
105
|
-
|
|
106
|
-
export function registerArenaHandshakeCommands(program: Command): void {
|
|
107
|
-
const hs = program
|
|
108
|
-
.command("shake")
|
|
109
|
-
.description("ARC Arena social handshake — send a typed trust signal to another agent.");
|
|
110
|
-
|
|
111
|
-
// ── send ──────────────────────────────────────────────────────────────────
|
|
112
|
-
hs.command("send <agentAddress>")
|
|
113
|
-
.description("Send a handshake to another agent.")
|
|
114
|
-
.option("--type <type>", "Handshake type: respect, curiosity, endorsement, thanks, collaboration, challenge, referral, hello", "hello")
|
|
115
|
-
.option("--note <note>", "Short message (max 280 chars)", "")
|
|
116
|
-
.option("--tip <amount>", "ETH tip to attach (e.g. 0.01)")
|
|
117
|
-
.option("--usdc <amount>", "USDC tip to attach (e.g. 5.00)")
|
|
118
|
-
.option("--json", "Output as JSON")
|
|
119
|
-
.action(async (agentAddress: string, opts) => {
|
|
120
|
-
const config = loadConfig();
|
|
121
|
-
const { signer, provider } = await requireSigner(config);
|
|
122
|
-
const myAddress = await signer.getAddress();
|
|
123
|
-
|
|
124
|
-
if (!config.handshakeAddress) {
|
|
125
|
-
console.error("handshakeAddress not configured. Run: arc402 config set handshakeAddress <address>");
|
|
126
|
-
process.exit(1);
|
|
127
|
-
}
|
|
128
|
-
if (!config.policyEngineAddress) {
|
|
129
|
-
console.error("policyEngineAddress not configured.");
|
|
130
|
-
process.exit(1);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Auto-whitelist check
|
|
134
|
-
await ensureWhitelisted(signer, provider, myAddress, config.policyEngineAddress, config.handshakeAddress);
|
|
135
|
-
|
|
136
|
-
const hsType = HANDSHAKE_TYPES[opts.type.toLowerCase()];
|
|
137
|
-
if (hsType === undefined) {
|
|
138
|
-
console.error(`Unknown handshake type: ${opts.type}`);
|
|
139
|
-
console.error(`Valid types: ${Object.keys(HANDSHAKE_TYPES).join(", ")}`);
|
|
140
|
-
process.exit(1);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const handshake = new ethers.Contract(config.handshakeAddress, HANDSHAKE_ABI, signer);
|
|
144
|
-
|
|
145
|
-
const hsSpinner = startSpinner(`Sending ${opts.type} handshake...`);
|
|
146
|
-
let tx;
|
|
147
|
-
if (opts.usdc) {
|
|
148
|
-
// USDC handshake
|
|
149
|
-
const usdcAddress = getUsdcAddress(config);
|
|
150
|
-
const amount = ethers.parseUnits(opts.usdc, 6);
|
|
151
|
-
tx = await handshake.sendHandshakeWithToken(agentAddress, hsType, opts.note, usdcAddress, amount);
|
|
152
|
-
} else {
|
|
153
|
-
// ETH handshake (with optional tip)
|
|
154
|
-
const value = opts.tip ? ethers.parseEther(opts.tip) : 0n;
|
|
155
|
-
tx = await handshake.sendHandshake(agentAddress, hsType, opts.note, { value });
|
|
156
|
-
}
|
|
157
|
-
hsSpinner.succeed("Handshake sent");
|
|
158
|
-
|
|
159
|
-
// Notify recipient's HTTP endpoint (non-blocking)
|
|
160
|
-
const registryAddress = config.agentRegistryV2Address ?? config.agentRegistryAddress ?? DEFAULT_REGISTRY_ADDRESS;
|
|
161
|
-
try {
|
|
162
|
-
await pingHandshakeEndpoint(
|
|
163
|
-
agentAddress,
|
|
164
|
-
{ from: myAddress, type: opts.type, note: opts.note, txHash: tx.hash },
|
|
165
|
-
registryAddress,
|
|
166
|
-
provider
|
|
167
|
-
);
|
|
168
|
-
} catch (err) {
|
|
169
|
-
console.warn(`Warning: could not notify recipient endpoint: ${err instanceof Error ? err.message : String(err)}`);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (opts.json) {
|
|
173
|
-
console.log(JSON.stringify({ tx: tx.hash, from: myAddress, to: agentAddress, type: opts.type, note: opts.note }));
|
|
174
|
-
} else {
|
|
175
|
-
const treeItems = [
|
|
176
|
-
{ label: "From", value: myAddress },
|
|
177
|
-
{ label: "To", value: agentAddress },
|
|
178
|
-
{ label: "Type", value: opts.type },
|
|
179
|
-
...(opts.note ? [{ label: "Note", value: opts.note as string }] : []),
|
|
180
|
-
...(opts.tip ? [{ label: "Tip", value: `${opts.tip as string} ETH` }] : []),
|
|
181
|
-
...(opts.usdc ? [{ label: "Tip", value: `${opts.usdc as string} USDC` }] : []),
|
|
182
|
-
{ label: "Tx", value: tx.hash as string, last: true },
|
|
183
|
-
];
|
|
184
|
-
renderTree(treeItems);
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
// ── batch ─────────────────────────────────────────────────────────────────
|
|
189
|
-
hs.command("batch")
|
|
190
|
-
.description("Send handshakes to multiple agents at once (onboarding ritual).")
|
|
191
|
-
.argument("<agents...>", "Agent addresses to handshake (up to 10)")
|
|
192
|
-
.option("--type <type>", "Handshake type for all", "hello")
|
|
193
|
-
.option("--note <note>", "Note for all", "")
|
|
194
|
-
.action(async (agents: string[], opts) => {
|
|
195
|
-
const config = loadConfig();
|
|
196
|
-
const { signer, provider } = await requireSigner(config);
|
|
197
|
-
const myAddress = await signer.getAddress();
|
|
198
|
-
|
|
199
|
-
if (!config.handshakeAddress || !config.policyEngineAddress) {
|
|
200
|
-
console.error("handshakeAddress or policyEngineAddress not configured.");
|
|
201
|
-
process.exit(1);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
await ensureWhitelisted(signer, provider, myAddress, config.policyEngineAddress, config.handshakeAddress);
|
|
205
|
-
|
|
206
|
-
const hsType = HANDSHAKE_TYPES[opts.type.toLowerCase()];
|
|
207
|
-
if (hsType === undefined) {
|
|
208
|
-
console.error(`Unknown type: ${opts.type}. Valid: ${Object.keys(HANDSHAKE_TYPES).join(", ")}`);
|
|
209
|
-
process.exit(1);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if (agents.length > 10) {
|
|
213
|
-
console.error("Max 10 agents per batch.");
|
|
214
|
-
process.exit(1);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
const handshake = new ethers.Contract(config.handshakeAddress, HANDSHAKE_ABI, signer);
|
|
218
|
-
const types = agents.map(() => hsType);
|
|
219
|
-
const notes = agents.map(() => opts.note);
|
|
220
|
-
|
|
221
|
-
const tx = await handshake.sendBatch(agents, types, notes);
|
|
222
|
-
console.log(`✓ Batch handshake sent to ${agents.length} agents`);
|
|
223
|
-
agents.forEach(a => console.log(` → ${a}`));
|
|
224
|
-
console.log(` tx: ${tx.hash}`);
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
// ── stats ─────────────────────────────────────────────────────────────────
|
|
228
|
-
hs.command("stats [address]")
|
|
229
|
-
.description("View handshake stats for an agent.")
|
|
230
|
-
.action(async (address?: string) => {
|
|
231
|
-
const config = loadConfig();
|
|
232
|
-
const { signer, provider } = await requireSigner(config);
|
|
233
|
-
const target = address || await signer.getAddress();
|
|
234
|
-
|
|
235
|
-
if (!config.handshakeAddress) {
|
|
236
|
-
console.error("handshakeAddress not configured.");
|
|
237
|
-
process.exit(1);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const handshake = new ethers.Contract(config.handshakeAddress, HANDSHAKE_ABI, provider);
|
|
241
|
-
const [sent, received, unique] = await handshake.getStats(target);
|
|
242
|
-
const total = await handshake.totalHandshakes();
|
|
243
|
-
|
|
244
|
-
console.log(`Handshake Stats: ${target}`);
|
|
245
|
-
console.log(` Sent: ${sent}`);
|
|
246
|
-
console.log(` Received: ${received}`);
|
|
247
|
-
console.log(` Unique senders: ${unique}`);
|
|
248
|
-
console.log(` Network total: ${total}`);
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
// ── check ─────────────────────────────────────────────────────────────────
|
|
252
|
-
hs.command("check <agentAddress>")
|
|
253
|
-
.description("Check if a connection or mutual handshake exists with an agent.")
|
|
254
|
-
.action(async (agentAddress: string) => {
|
|
255
|
-
const config = loadConfig();
|
|
256
|
-
const { signer, provider } = await requireSigner(config);
|
|
257
|
-
const myAddress = await signer.getAddress();
|
|
258
|
-
|
|
259
|
-
if (!config.handshakeAddress) {
|
|
260
|
-
console.error("handshakeAddress not configured.");
|
|
261
|
-
process.exit(1);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const handshake = new ethers.Contract(config.handshakeAddress, HANDSHAKE_ABI, provider);
|
|
265
|
-
const iSent = await handshake.hasConnection(myAddress, agentAddress);
|
|
266
|
-
const theySent = await handshake.hasConnection(agentAddress, myAddress);
|
|
267
|
-
const mutual = await handshake.isMutual(myAddress, agentAddress);
|
|
268
|
-
|
|
269
|
-
console.log(`Connection: ${myAddress} ↔ ${agentAddress}`);
|
|
270
|
-
console.log(` You → them: ${iSent ? "✓ handshaked" : "✗ no handshake"}`);
|
|
271
|
-
console.log(` Them → you: ${theySent ? "✓ handshaked" : "✗ no handshake"}`);
|
|
272
|
-
console.log(` Mutual: ${mutual ? "✓ yes" : "✗ no"}`);
|
|
273
|
-
});
|
|
274
|
-
}
|
package/src/commands/arena.ts
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import chalk from "chalk";
|
|
3
|
-
import { runFeed, FeedOptions } from "./feed.js";
|
|
4
|
-
import { c } from "../ui/colors.js";
|
|
5
|
-
|
|
6
|
-
const SUBGRAPH_URL = "https://api.studio.thegraph.com/query/1744310/arc-402/v0.2.0";
|
|
7
|
-
|
|
8
|
-
async function gql(query: string): Promise<Record<string, unknown>> {
|
|
9
|
-
const res = await fetch(SUBGRAPH_URL, {
|
|
10
|
-
method: "POST",
|
|
11
|
-
headers: { "Content-Type": "application/json" },
|
|
12
|
-
body: JSON.stringify({ query }),
|
|
13
|
-
});
|
|
14
|
-
if (!res.ok) throw new Error(`Subgraph HTTP ${res.status}`);
|
|
15
|
-
const json = (await res.json()) as { data?: Record<string, unknown>; errors?: unknown[] };
|
|
16
|
-
if (json.errors?.length) throw new Error(`Subgraph error: ${JSON.stringify(json.errors[0])}`);
|
|
17
|
-
return json.data ?? {};
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function registerArenaCommands(program: Command): void {
|
|
21
|
-
const arena = program.command("arena").description("Arena network commands");
|
|
22
|
-
|
|
23
|
-
// ─── arena stats ───────────────────────────────────────────────────────────
|
|
24
|
-
|
|
25
|
-
arena
|
|
26
|
-
.command("stats")
|
|
27
|
-
.description("Show Arena network statistics")
|
|
28
|
-
.option("--json", "Output as JSON")
|
|
29
|
-
.action(async (opts) => {
|
|
30
|
-
try {
|
|
31
|
-
const data = await gql(`{
|
|
32
|
-
protocolStats(id: "global") {
|
|
33
|
-
totalAgents
|
|
34
|
-
totalWallets
|
|
35
|
-
totalAgreements
|
|
36
|
-
totalHandshakes
|
|
37
|
-
totalConnections
|
|
38
|
-
totalVouches
|
|
39
|
-
totalCapabilityClaims
|
|
40
|
-
}
|
|
41
|
-
}`);
|
|
42
|
-
|
|
43
|
-
const stats = data["protocolStats"] as Record<string, unknown> | null;
|
|
44
|
-
if (!stats) {
|
|
45
|
-
const msg = "No stats available — subgraph may still be syncing.";
|
|
46
|
-
if (opts.json) {
|
|
47
|
-
console.log(JSON.stringify({ error: msg }));
|
|
48
|
-
} else {
|
|
49
|
-
console.error(' ' + c.warning + c.white(` ${msg}`));
|
|
50
|
-
}
|
|
51
|
-
process.exit(1);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Try to count active agreements separately — non-fatal if it fails
|
|
55
|
-
let activeAgreements = 0;
|
|
56
|
-
try {
|
|
57
|
-
const agData = await gql(`{
|
|
58
|
-
proposals: agreements(where: { state: 0 }, first: 1000) { id }
|
|
59
|
-
accepted: agreements(where: { state: 1 }, first: 1000) { id }
|
|
60
|
-
}`);
|
|
61
|
-
activeAgreements =
|
|
62
|
-
((agData["proposals"] as unknown[]) ?? []).length +
|
|
63
|
-
((agData["accepted"] as unknown[]) ?? []).length;
|
|
64
|
-
} catch {
|
|
65
|
-
// ignore — active count just stays 0
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (opts.json) {
|
|
69
|
-
console.log(JSON.stringify({ ...stats, activeAgreements }, null, 2));
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const pad = (v: unknown) => String(v ?? 0).padStart(6);
|
|
74
|
-
console.log(chalk.bold("╔══════════════════════════════════════╗"));
|
|
75
|
-
console.log(chalk.bold("║ ARC Arena — Network Stats ║"));
|
|
76
|
-
console.log(chalk.bold("╚══════════════════════════════════════╝"));
|
|
77
|
-
console.log();
|
|
78
|
-
console.log(` Agents ${pad(stats["totalAgents"])} registered`);
|
|
79
|
-
console.log(` Wallets ${pad(stats["totalWallets"])} deployed`);
|
|
80
|
-
console.log(
|
|
81
|
-
` Agreements ${pad(stats["totalAgreements"])} total (${activeAgreements} active)`,
|
|
82
|
-
);
|
|
83
|
-
console.log(` Handshakes ${pad(stats["totalHandshakes"])} sent`);
|
|
84
|
-
console.log(` Connections ${pad(stats["totalConnections"])} unique pairs`);
|
|
85
|
-
console.log(` Vouches ${pad(stats["totalVouches"])} active`);
|
|
86
|
-
console.log(` Capabilities ${pad(stats["totalCapabilityClaims"])} claimed`);
|
|
87
|
-
console.log();
|
|
88
|
-
console.log(chalk.dim(" Subgraph: v0.2.0 · synced"));
|
|
89
|
-
} catch (err) {
|
|
90
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
91
|
-
if (opts.json) {
|
|
92
|
-
console.log(JSON.stringify({ error: "Subgraph unavailable", details: msg }));
|
|
93
|
-
} else {
|
|
94
|
-
console.error(' ' + c.failure + c.white(` Subgraph unavailable: ${msg}`));
|
|
95
|
-
}
|
|
96
|
-
process.exit(1);
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// ─── arena feed (alias) ─────────────────────────────────────────────────────
|
|
101
|
-
|
|
102
|
-
arena
|
|
103
|
-
.command("feed")
|
|
104
|
-
.description("Live terminal feed of recent Arena events (alias for arc402 feed)")
|
|
105
|
-
.option("--limit <n>", "Number of events to show", "20")
|
|
106
|
-
.option("--live", "Poll every 30s for new events")
|
|
107
|
-
.option("--type <type>", "Filter by event type: handshake|hire|fulfill|vouch")
|
|
108
|
-
.option("--json", "Output as JSON")
|
|
109
|
-
.action(async (opts) => {
|
|
110
|
-
try {
|
|
111
|
-
await runFeed(opts as FeedOptions);
|
|
112
|
-
} catch (err) {
|
|
113
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
114
|
-
if ((opts as FeedOptions).json) {
|
|
115
|
-
console.log(JSON.stringify({ error: "Subgraph unavailable", details: msg }));
|
|
116
|
-
} else {
|
|
117
|
-
console.error(' ' + c.failure + c.white(` Subgraph unavailable: ${msg}`));
|
|
118
|
-
}
|
|
119
|
-
process.exit(1);
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
}
|
package/src/commands/backup.ts
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { execSync } from "child_process";
|
|
3
|
-
import fs from "fs";
|
|
4
|
-
import path from "path";
|
|
5
|
-
import os from "os";
|
|
6
|
-
import { c } from "../ui/colors.js";
|
|
7
|
-
|
|
8
|
-
const ARC402_DIR = path.join(os.homedir(), ".arc402");
|
|
9
|
-
|
|
10
|
-
// Files/patterns to exclude from backup
|
|
11
|
-
const EXCLUDE_PATTERNS = [
|
|
12
|
-
"daemon.db",
|
|
13
|
-
"daemon.log",
|
|
14
|
-
"daemon.pid",
|
|
15
|
-
"daemon.sock",
|
|
16
|
-
"repl_history",
|
|
17
|
-
];
|
|
18
|
-
|
|
19
|
-
function todayStr(): string {
|
|
20
|
-
const d = new Date();
|
|
21
|
-
const y = d.getFullYear();
|
|
22
|
-
const m = (d.getMonth() + 1).toString().padStart(2, "0");
|
|
23
|
-
const day = d.getDate().toString().padStart(2, "0");
|
|
24
|
-
return `${y}-${m}-${day}`;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function registerBackupCommand(program: Command): void {
|
|
28
|
-
// ── backup ─────────────────────────────────────────────────────────────────
|
|
29
|
-
program
|
|
30
|
-
.command("backup")
|
|
31
|
-
.description("Backup ~/.arc402/ config, keys, and wallet storage to a tar.gz archive")
|
|
32
|
-
.option("--output <path>", "Output file path (default: arc402-backup-YYYY-MM-DD.tar.gz)")
|
|
33
|
-
.action((opts: { output?: string }) => {
|
|
34
|
-
if (!fs.existsSync(ARC402_DIR)) {
|
|
35
|
-
console.error(` ${c.failure} No ~/.arc402/ directory found. Nothing to back up.`);
|
|
36
|
-
process.exit(1);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const outFile = opts.output ?? `arc402-backup-${todayStr()}.tar.gz`;
|
|
40
|
-
const absOut = path.isAbsolute(outFile) ? outFile : path.join(process.cwd(), outFile);
|
|
41
|
-
|
|
42
|
-
// Build --exclude flags
|
|
43
|
-
const excludeFlags = EXCLUDE_PATTERNS.map((p) => `--exclude='.arc402/${p}'`).join(" ");
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
execSync(
|
|
47
|
-
`tar -czf "${absOut}" ${excludeFlags} -C "${os.homedir()}" .arc402`,
|
|
48
|
-
{ stdio: "pipe" }
|
|
49
|
-
);
|
|
50
|
-
} catch (err) {
|
|
51
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
52
|
-
console.error(` ${c.failure} Backup failed: ${msg}`);
|
|
53
|
-
process.exit(1);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Verify the file was created
|
|
57
|
-
if (!fs.existsSync(absOut)) {
|
|
58
|
-
console.error(` ${c.failure} Archive not found after tar completed.`);
|
|
59
|
-
process.exit(1);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const sizeBytes = fs.statSync(absOut).size;
|
|
63
|
-
const sizeStr = sizeBytes < 1024
|
|
64
|
-
? `${sizeBytes} B`
|
|
65
|
-
: sizeBytes < 1024 * 1024
|
|
66
|
-
? `${(sizeBytes / 1024).toFixed(1)} KB`
|
|
67
|
-
: `${(sizeBytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
68
|
-
|
|
69
|
-
console.log(` ${c.success} Backup saved to ${c.white(path.basename(absOut))} ${c.dim(`(${sizeStr})`)}`);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
// ── restore ────────────────────────────────────────────────────────────────
|
|
73
|
-
program
|
|
74
|
-
.command("restore")
|
|
75
|
-
.description("Restore ~/.arc402/ from a backup archive")
|
|
76
|
-
.argument("<archive>", "Path to arc402-backup-*.tar.gz")
|
|
77
|
-
.action((archive: string) => {
|
|
78
|
-
const absArchive = path.isAbsolute(archive) ? archive : path.join(process.cwd(), archive);
|
|
79
|
-
|
|
80
|
-
if (!fs.existsSync(absArchive)) {
|
|
81
|
-
console.error(` ${c.failure} Archive not found: ${absArchive}`);
|
|
82
|
-
process.exit(1);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Warn if ~/.arc402/ already exists
|
|
86
|
-
if (fs.existsSync(ARC402_DIR)) {
|
|
87
|
-
const existing = fs.readdirSync(ARC402_DIR);
|
|
88
|
-
if (existing.length > 0) {
|
|
89
|
-
console.warn(` ${c.warning} Existing ~/.arc402/ has ${existing.length} file(s) — merging (existing files take precedence for conflicts).`);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
try {
|
|
94
|
-
// Extract to home dir — tar archive has .arc402/ as the root entry
|
|
95
|
-
execSync(`tar -xzf "${absArchive}" -C "${os.homedir()}"`, { stdio: "pipe" });
|
|
96
|
-
} catch (err) {
|
|
97
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
98
|
-
console.error(` ${c.failure} Restore failed: ${msg}`);
|
|
99
|
-
process.exit(1);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Verify config.json is present
|
|
103
|
-
const configPath = path.join(ARC402_DIR, "config.json");
|
|
104
|
-
if (!fs.existsSync(configPath)) {
|
|
105
|
-
console.error(` ${c.failure} config.json not found after restore — archive may be incomplete.`);
|
|
106
|
-
process.exit(1);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Fix permissions on restored directory
|
|
110
|
-
try {
|
|
111
|
-
fs.chmodSync(ARC402_DIR, 0o700);
|
|
112
|
-
fs.chmodSync(configPath, 0o600);
|
|
113
|
-
} catch { /* best-effort */ }
|
|
114
|
-
|
|
115
|
-
console.log(` ${c.success} Config restored. Run ${c.white("arc402 doctor")} to verify.`);
|
|
116
|
-
});
|
|
117
|
-
}
|
package/src/commands/cancel.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { ServiceAgreementClient } from "@arc402/sdk";
|
|
3
|
-
import { loadConfig } from "../config.js";
|
|
4
|
-
import { requireSigner } from "../client.js";
|
|
5
|
-
import { printSenderInfo, executeContractWriteViaWallet } from "../wallet-router.js";
|
|
6
|
-
import { SERVICE_AGREEMENT_ABI } from "../abis.js";
|
|
7
|
-
import { c } from "../ui/colors.js";
|
|
8
|
-
import { startSpinner } from "../ui/spinner.js";
|
|
9
|
-
|
|
10
|
-
export function registerCancelCommand(program: Command): void {
|
|
11
|
-
program.command("cancel <id>").description("Cancel a proposed agreement; use --expired for post-deadline recovery paths").option("--expired", "Call expiredCancel()", false).action(async (id, opts) => {
|
|
12
|
-
const config = loadConfig();
|
|
13
|
-
if (!config.serviceAgreementAddress) throw new Error("serviceAgreementAddress missing in config");
|
|
14
|
-
const { signer } = await requireSigner(config);
|
|
15
|
-
printSenderInfo(config);
|
|
16
|
-
const spinner = startSpinner("Submitting transaction...");
|
|
17
|
-
try {
|
|
18
|
-
if (config.walletContractAddress) {
|
|
19
|
-
const fn = opts.expired ? "expiredCancel" : "cancel";
|
|
20
|
-
await executeContractWriteViaWallet(
|
|
21
|
-
config.walletContractAddress, signer, config.serviceAgreementAddress,
|
|
22
|
-
SERVICE_AGREEMENT_ABI, fn, [BigInt(id)],
|
|
23
|
-
);
|
|
24
|
-
} else {
|
|
25
|
-
const client = new ServiceAgreementClient(config.serviceAgreementAddress, signer);
|
|
26
|
-
if (opts.expired) await client.expiredCancel(BigInt(id)); else await client.cancel(BigInt(id));
|
|
27
|
-
}
|
|
28
|
-
spinner.succeed();
|
|
29
|
-
} catch (err) {
|
|
30
|
-
spinner.fail();
|
|
31
|
-
throw err;
|
|
32
|
-
}
|
|
33
|
-
console.log(' ' + c.success + c.white(` Cancelled — agreement #${id}`));
|
|
34
|
-
});
|
|
35
|
-
}
|