safehands-pharos 1.4.0 → 1.5.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 +174 -63
- package/dist/cli.d.ts +5 -5
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +126 -124
- package/dist/cli.js.map +1 -1
- package/dist/demo.d.ts +1 -1
- package/dist/demo.js +171 -171
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +73 -65
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +1 -1
- package/dist/init.js +65 -65
- package/dist/lib/constants.d.ts +303 -291
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +302 -292
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/dodoApi.d.ts +78 -78
- package/dist/lib/dodoApi.js +196 -196
- package/dist/lib/envLoader.d.ts +2 -0
- package/dist/lib/envLoader.d.ts.map +1 -0
- package/dist/lib/envLoader.js +44 -0
- package/dist/lib/envLoader.js.map +1 -0
- package/dist/lib/http.d.ts +14 -14
- package/dist/lib/http.js +118 -118
- package/dist/lib/pharosClient.d.ts +58 -58
- package/dist/lib/pharosClient.js +63 -63
- package/dist/lib/policy/actionPolicyEngine.d.ts +53 -53
- package/dist/lib/policy/actionPolicyEngine.js +212 -212
- package/dist/lib/riskEngine.d.ts +26 -26
- package/dist/lib/riskEngine.d.ts.map +1 -1
- package/dist/lib/riskEngine.js +288 -283
- package/dist/lib/riskEngine.js.map +1 -1
- package/dist/lib/signer/index.d.ts +24 -24
- package/dist/lib/signer/index.js +88 -88
- package/dist/lib/testDodoLive.d.ts +1 -1
- package/dist/lib/testDodoLive.js +104 -104
- package/dist/lib/testLiveSafehands.d.ts +1 -1
- package/dist/lib/testLiveSafehands.js +92 -92
- package/dist/lib/testRpcLive.d.ts +1 -1
- package/dist/lib/testRpcLive.js +88 -88
- package/dist/lib/testTools.js +397 -398
- package/dist/lib/testX402Live.d.ts +1 -1
- package/dist/lib/testX402Live.js +159 -159
- package/dist/lib/toolResponse.d.ts +25 -25
- package/dist/lib/toolResponse.js +53 -53
- package/dist/lib/wallet/index.d.ts +37 -37
- package/dist/lib/wallet/index.js +128 -128
- package/dist/scripts/checkDeploy.d.ts +1 -1
- package/dist/scripts/checkDeploy.js +24 -24
- package/dist/scripts/deployRegistry.d.ts +1 -1
- package/dist/scripts/deployRegistry.js +100 -100
- package/dist/scripts/testRegistry.d.ts +1 -1
- package/dist/scripts/testRegistry.js +43 -43
- package/dist/tools/approveToken.d.ts +45 -45
- package/dist/tools/approveToken.js +85 -85
- package/dist/tools/assessRisk.d.ts +79 -79
- package/dist/tools/assessRisk.js +104 -104
- package/dist/tools/checkAllowance.d.ts +43 -43
- package/dist/tools/checkAllowance.js +56 -56
- package/dist/tools/checkTokenSecurity.d.ts +46 -46
- package/dist/tools/checkTokenSecurity.js +95 -95
- package/dist/tools/createAgentWallet.d.ts +28 -26
- package/dist/tools/createAgentWallet.d.ts.map +1 -1
- package/dist/tools/createAgentWallet.js +82 -58
- package/dist/tools/createAgentWallet.js.map +1 -1
- package/dist/tools/estimateGas.d.ts +79 -79
- package/dist/tools/estimateGas.js +124 -124
- package/dist/tools/executeSwap.d.ts +61 -61
- package/dist/tools/executeSwap.js +141 -141
- package/dist/tools/explainRisk.d.ts +29 -29
- package/dist/tools/explainRisk.js +32 -32
- package/dist/tools/getAgentWallet.d.ts +21 -21
- package/dist/tools/getAgentWallet.js +27 -27
- package/dist/tools/getAgentWalletBalance.d.ts +11 -11
- package/dist/tools/getAgentWalletBalance.js +70 -70
- package/dist/tools/getExecutionHistory.d.ts +49 -49
- package/dist/tools/getExecutionHistory.js +154 -154
- package/dist/tools/getGasPrice.d.ts +43 -43
- package/dist/tools/getGasPrice.js +59 -59
- package/dist/tools/getPoolInfo.d.ts +75 -75
- package/dist/tools/getPoolInfo.js +137 -137
- package/dist/tools/getTokenPrice.d.ts +113 -113
- package/dist/tools/getTokenPrice.js +117 -117
- package/dist/tools/getTransactionStatus.d.ts +43 -43
- package/dist/tools/getTransactionStatus.js +59 -59
- package/dist/tools/getWalletBalance.d.ts +68 -68
- package/dist/tools/getWalletBalance.js +87 -87
- package/dist/tools/publishRiskScore.d.ts +63 -63
- package/dist/tools/publishRiskScore.js +88 -88
- package/dist/tools/queryRiskRegistry.d.ts +38 -38
- package/dist/tools/queryRiskRegistry.js +55 -55
- package/dist/tools/safehandsPreflightCheck.d.ts +77 -77
- package/dist/tools/safehandsPreflightCheck.js +47 -47
- package/dist/tools/safehandsRiskReport.d.ts +81 -81
- package/dist/tools/safehandsRiskReport.js +28 -28
- package/dist/tools/safehandsSafeExecute.d.ts +20 -20
- package/dist/tools/safehandsSafeExecute.js +81 -81
- package/dist/tools/safehandsWalletHealth.d.ts +14 -14
- package/dist/tools/safehandsWalletHealth.js +103 -103
- package/dist/tools/safehandsX402Preflight.d.ts +26 -26
- package/dist/tools/safehandsX402Preflight.js +65 -65
- package/dist/tools/sendPayment.d.ts +57 -57
- package/dist/tools/sendPayment.js +117 -117
- package/dist/tools/simulateTransaction.d.ts +60 -60
- package/dist/tools/simulateTransaction.js +83 -83
- package/dist/tools/tokenRegistryStatus.d.ts +26 -26
- package/dist/tools/tokenRegistryStatus.js +96 -96
- package/dist/tools/x402PayAndFetch.d.ts +81 -81
- package/dist/tools/x402PayAndFetch.js +152 -152
- package/dist/x402Server.d.ts +1 -1
- package/dist/x402Server.js +300 -252
- package/dist/x402Server.js.map +1 -1
- package/package.json +6 -16
- package/examples/dashboard/index.html +0 -337
- package/examples/pharos-skill-engine/SKILL.safehands.md +0 -85
- package/examples/pharos-skill-engine/assets/safehands/example-actions.json +0 -49
- package/examples/pharos-skill-engine/assets/safehands/policy-defaults.json +0 -11
- package/examples/pharos-skill-engine/references/safehands.md +0 -345
- package/examples/scenario-hack.ts +0 -38
- package/skill/SKILL.md +0 -133
- package/skill/assets/safehands/example-actions.json +0 -49
- package/skill/assets/safehands/policy-defaults.json +0 -11
- package/skill/references/safehands.md +0 -345
package/dist/lib/wallet/index.js
CHANGED
|
@@ -1,129 +1,129 @@
|
|
|
1
|
-
// ─── WalletStore ────────────────────────────────────────────────────────
|
|
2
|
-
// Abstraction for storing managed testnet agent wallets.
|
|
3
|
-
// Private keys are AES-256-GCM encrypted before storage.
|
|
4
|
-
// Legacy XOR-obfuscated keys (starting with "0x") are transparently migrated
|
|
5
|
-
// on first read. NOT mainnet-grade KMS — testnet only.
|
|
6
|
-
// ────────────────────────────────────────────────────────────────────────
|
|
7
|
-
import { readFileSync, writeFileSync, renameSync, existsSync } from "fs";
|
|
8
|
-
import { randomBytes, createCipheriv, createDecipheriv, createHash } from "node:crypto";
|
|
9
|
-
// ─── In-Memory Store (tests + default) ─────────────────────────────────
|
|
10
|
-
class InMemoryWalletStore {
|
|
11
|
-
store = new Map();
|
|
12
|
-
async get(agentId) {
|
|
13
|
-
return this.store.get(agentId) ?? null;
|
|
14
|
-
}
|
|
15
|
-
async set(agentId, wallet) {
|
|
16
|
-
this.store.set(agentId, wallet);
|
|
17
|
-
}
|
|
18
|
-
async has(agentId) {
|
|
19
|
-
return this.store.has(agentId);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
// ─── File Store (local dev) ─────────────────────────────────────────────
|
|
23
|
-
class FileWalletStore {
|
|
24
|
-
path;
|
|
25
|
-
data = {};
|
|
26
|
-
constructor(path) {
|
|
27
|
-
this.path = path;
|
|
28
|
-
if (existsSync(path)) {
|
|
29
|
-
try {
|
|
30
|
-
this.data = JSON.parse(readFileSync(path, "utf-8"));
|
|
31
|
-
}
|
|
32
|
-
catch {
|
|
33
|
-
this.data = {};
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
async get(agentId) {
|
|
38
|
-
return this.data[agentId] ?? null;
|
|
39
|
-
}
|
|
40
|
-
async set(agentId, wallet) {
|
|
41
|
-
this.data[agentId] = wallet;
|
|
42
|
-
// Atomic write: write to .tmp then rename to avoid corruption on crash
|
|
43
|
-
const tmpPath = `${this.path}.tmp`;
|
|
44
|
-
writeFileSync(tmpPath, JSON.stringify(this.data, null, 2), "utf-8");
|
|
45
|
-
renameSync(tmpPath, this.path);
|
|
46
|
-
}
|
|
47
|
-
async has(agentId) {
|
|
48
|
-
return agentId in this.data;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
// ─── AES-256-GCM Encryption ────────────────────────────────────────────
|
|
52
|
-
function deriveKey(encryptionKey) {
|
|
53
|
-
return createHash("sha256").update(encryptionKey).digest();
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Encrypts a private key with AES-256-GCM.
|
|
57
|
-
* Output format: <iv(12B)><tag(16B)><ciphertext> as hex string (no 0x prefix).
|
|
58
|
-
*/
|
|
59
|
-
export function encryptKey(privateKey, encryptionKey) {
|
|
60
|
-
const key = deriveKey(encryptionKey);
|
|
61
|
-
const iv = randomBytes(12);
|
|
62
|
-
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
63
|
-
const plain = Buffer.from(privateKey.replace(/^0x/, ""), "hex");
|
|
64
|
-
const encrypted = Buffer.concat([cipher.update(plain), cipher.final()]);
|
|
65
|
-
const tag = cipher.getAuthTag();
|
|
66
|
-
return Buffer.concat([iv, tag, encrypted]).toString("hex");
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Decrypts a private key. Handles both:
|
|
70
|
-
* - New AES-256-GCM format (pure hex, no 0x prefix)
|
|
71
|
-
* - Legacy XOR format (starts with "0x") — transparently supported for migration
|
|
72
|
-
*/
|
|
73
|
-
export function decryptKey(encrypted, encryptionKey) {
|
|
74
|
-
if (encrypted.startsWith("0x")) {
|
|
75
|
-
// Legacy XOR path — symmetric, same operation
|
|
76
|
-
return _xorObfuscate(encrypted, encryptionKey);
|
|
77
|
-
}
|
|
78
|
-
const key = deriveKey(encryptionKey);
|
|
79
|
-
const data = Buffer.from(encrypted, "hex");
|
|
80
|
-
const iv = data.subarray(0, 12);
|
|
81
|
-
const tag = data.subarray(12, 28);
|
|
82
|
-
const ciphertext = data.subarray(28);
|
|
83
|
-
const decipher = createDecipheriv("aes-256-gcm", key, iv);
|
|
84
|
-
decipher.setAuthTag(tag);
|
|
85
|
-
const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
|
|
86
|
-
return "0x" + decrypted.toString("hex");
|
|
87
|
-
}
|
|
88
|
-
// ─── Legacy XOR helpers (kept for migration read path only) ────────────
|
|
89
|
-
function _xorObfuscate(privateKey, encryptionKey) {
|
|
90
|
-
const keyBytes = Buffer.from(encryptionKey.padEnd(32, "0").slice(0, 32));
|
|
91
|
-
const pkBytes = Buffer.from(privateKey.replace("0x", ""), "hex");
|
|
92
|
-
const result = Buffer.alloc(pkBytes.length);
|
|
93
|
-
for (let i = 0; i < pkBytes.length; i++) {
|
|
94
|
-
result[i] = pkBytes[i] ^ keyBytes[i % keyBytes.length];
|
|
95
|
-
}
|
|
96
|
-
return "0x" + result.toString("hex");
|
|
97
|
-
}
|
|
98
|
-
/** @deprecated Use encryptKey / decryptKey. Kept for callers that haven't migrated yet. */
|
|
99
|
-
export function obfuscateKey(privateKey, encryptionKey) {
|
|
100
|
-
return _xorObfuscate(privateKey, encryptionKey);
|
|
101
|
-
}
|
|
102
|
-
/** @deprecated Use decryptKey. */
|
|
103
|
-
export function deobfuscateKey(obfuscated, encryptionKey) {
|
|
104
|
-
return _xorObfuscate(obfuscated, encryptionKey);
|
|
105
|
-
}
|
|
106
|
-
// ─── Encryption key resolution ─────────────────────────────────────────
|
|
107
|
-
// Random per-process fallback key — never hardcoded, never reused across restarts
|
|
108
|
-
const IN_MEMORY_FALLBACK_KEY = randomBytes(32).toString("hex");
|
|
109
|
-
/**
|
|
110
|
-
* Returns the effective encryption key.
|
|
111
|
-
* - Persistent store: WALLET_ENCRYPTION_KEY must be set (wallets won't survive restarts otherwise).
|
|
112
|
-
* - In-memory store: falls back to a random per-process key.
|
|
113
|
-
*/
|
|
114
|
-
export function getEffectiveEncryptionKey() {
|
|
115
|
-
return process.env.WALLET_ENCRYPTION_KEY || IN_MEMORY_FALLBACK_KEY;
|
|
116
|
-
}
|
|
117
|
-
// ─── Factory ────────────────────────────────────────────────────────────
|
|
118
|
-
function createWalletStore() {
|
|
119
|
-
const storePath = process.env.WALLET_STORE_PATH;
|
|
120
|
-
if (storePath) {
|
|
121
|
-
return new FileWalletStore(storePath);
|
|
122
|
-
}
|
|
123
|
-
return new InMemoryWalletStore();
|
|
124
|
-
}
|
|
125
|
-
export function usesPersistentWalletStore() {
|
|
126
|
-
return Boolean(process.env.WALLET_STORE_PATH);
|
|
127
|
-
}
|
|
128
|
-
export const walletStore = createWalletStore();
|
|
1
|
+
// ─── WalletStore ────────────────────────────────────────────────────────
|
|
2
|
+
// Abstraction for storing managed testnet agent wallets.
|
|
3
|
+
// Private keys are AES-256-GCM encrypted before storage.
|
|
4
|
+
// Legacy XOR-obfuscated keys (starting with "0x") are transparently migrated
|
|
5
|
+
// on first read. NOT mainnet-grade KMS — testnet only.
|
|
6
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
7
|
+
import { readFileSync, writeFileSync, renameSync, existsSync } from "fs";
|
|
8
|
+
import { randomBytes, createCipheriv, createDecipheriv, createHash } from "node:crypto";
|
|
9
|
+
// ─── In-Memory Store (tests + default) ─────────────────────────────────
|
|
10
|
+
class InMemoryWalletStore {
|
|
11
|
+
store = new Map();
|
|
12
|
+
async get(agentId) {
|
|
13
|
+
return this.store.get(agentId) ?? null;
|
|
14
|
+
}
|
|
15
|
+
async set(agentId, wallet) {
|
|
16
|
+
this.store.set(agentId, wallet);
|
|
17
|
+
}
|
|
18
|
+
async has(agentId) {
|
|
19
|
+
return this.store.has(agentId);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// ─── File Store (local dev) ─────────────────────────────────────────────
|
|
23
|
+
class FileWalletStore {
|
|
24
|
+
path;
|
|
25
|
+
data = {};
|
|
26
|
+
constructor(path) {
|
|
27
|
+
this.path = path;
|
|
28
|
+
if (existsSync(path)) {
|
|
29
|
+
try {
|
|
30
|
+
this.data = JSON.parse(readFileSync(path, "utf-8"));
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
this.data = {};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async get(agentId) {
|
|
38
|
+
return this.data[agentId] ?? null;
|
|
39
|
+
}
|
|
40
|
+
async set(agentId, wallet) {
|
|
41
|
+
this.data[agentId] = wallet;
|
|
42
|
+
// Atomic write: write to .tmp then rename to avoid corruption on crash
|
|
43
|
+
const tmpPath = `${this.path}.tmp`;
|
|
44
|
+
writeFileSync(tmpPath, JSON.stringify(this.data, null, 2), "utf-8");
|
|
45
|
+
renameSync(tmpPath, this.path);
|
|
46
|
+
}
|
|
47
|
+
async has(agentId) {
|
|
48
|
+
return agentId in this.data;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// ─── AES-256-GCM Encryption ────────────────────────────────────────────
|
|
52
|
+
function deriveKey(encryptionKey) {
|
|
53
|
+
return createHash("sha256").update(encryptionKey).digest();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Encrypts a private key with AES-256-GCM.
|
|
57
|
+
* Output format: <iv(12B)><tag(16B)><ciphertext> as hex string (no 0x prefix).
|
|
58
|
+
*/
|
|
59
|
+
export function encryptKey(privateKey, encryptionKey) {
|
|
60
|
+
const key = deriveKey(encryptionKey);
|
|
61
|
+
const iv = randomBytes(12);
|
|
62
|
+
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
63
|
+
const plain = Buffer.from(privateKey.replace(/^0x/, ""), "hex");
|
|
64
|
+
const encrypted = Buffer.concat([cipher.update(plain), cipher.final()]);
|
|
65
|
+
const tag = cipher.getAuthTag();
|
|
66
|
+
return Buffer.concat([iv, tag, encrypted]).toString("hex");
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Decrypts a private key. Handles both:
|
|
70
|
+
* - New AES-256-GCM format (pure hex, no 0x prefix)
|
|
71
|
+
* - Legacy XOR format (starts with "0x") — transparently supported for migration
|
|
72
|
+
*/
|
|
73
|
+
export function decryptKey(encrypted, encryptionKey) {
|
|
74
|
+
if (encrypted.startsWith("0x")) {
|
|
75
|
+
// Legacy XOR path — symmetric, same operation
|
|
76
|
+
return _xorObfuscate(encrypted, encryptionKey);
|
|
77
|
+
}
|
|
78
|
+
const key = deriveKey(encryptionKey);
|
|
79
|
+
const data = Buffer.from(encrypted, "hex");
|
|
80
|
+
const iv = data.subarray(0, 12);
|
|
81
|
+
const tag = data.subarray(12, 28);
|
|
82
|
+
const ciphertext = data.subarray(28);
|
|
83
|
+
const decipher = createDecipheriv("aes-256-gcm", key, iv);
|
|
84
|
+
decipher.setAuthTag(tag);
|
|
85
|
+
const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
|
|
86
|
+
return "0x" + decrypted.toString("hex");
|
|
87
|
+
}
|
|
88
|
+
// ─── Legacy XOR helpers (kept for migration read path only) ────────────
|
|
89
|
+
function _xorObfuscate(privateKey, encryptionKey) {
|
|
90
|
+
const keyBytes = Buffer.from(encryptionKey.padEnd(32, "0").slice(0, 32));
|
|
91
|
+
const pkBytes = Buffer.from(privateKey.replace("0x", ""), "hex");
|
|
92
|
+
const result = Buffer.alloc(pkBytes.length);
|
|
93
|
+
for (let i = 0; i < pkBytes.length; i++) {
|
|
94
|
+
result[i] = pkBytes[i] ^ keyBytes[i % keyBytes.length];
|
|
95
|
+
}
|
|
96
|
+
return "0x" + result.toString("hex");
|
|
97
|
+
}
|
|
98
|
+
/** @deprecated Use encryptKey / decryptKey. Kept for callers that haven't migrated yet. */
|
|
99
|
+
export function obfuscateKey(privateKey, encryptionKey) {
|
|
100
|
+
return _xorObfuscate(privateKey, encryptionKey);
|
|
101
|
+
}
|
|
102
|
+
/** @deprecated Use decryptKey. */
|
|
103
|
+
export function deobfuscateKey(obfuscated, encryptionKey) {
|
|
104
|
+
return _xorObfuscate(obfuscated, encryptionKey);
|
|
105
|
+
}
|
|
106
|
+
// ─── Encryption key resolution ─────────────────────────────────────────
|
|
107
|
+
// Random per-process fallback key — never hardcoded, never reused across restarts
|
|
108
|
+
const IN_MEMORY_FALLBACK_KEY = randomBytes(32).toString("hex");
|
|
109
|
+
/**
|
|
110
|
+
* Returns the effective encryption key.
|
|
111
|
+
* - Persistent store: WALLET_ENCRYPTION_KEY must be set (wallets won't survive restarts otherwise).
|
|
112
|
+
* - In-memory store: falls back to a random per-process key.
|
|
113
|
+
*/
|
|
114
|
+
export function getEffectiveEncryptionKey() {
|
|
115
|
+
return process.env.WALLET_ENCRYPTION_KEY || IN_MEMORY_FALLBACK_KEY;
|
|
116
|
+
}
|
|
117
|
+
// ─── Factory ────────────────────────────────────────────────────────────
|
|
118
|
+
function createWalletStore() {
|
|
119
|
+
const storePath = process.env.WALLET_STORE_PATH;
|
|
120
|
+
if (storePath) {
|
|
121
|
+
return new FileWalletStore(storePath);
|
|
122
|
+
}
|
|
123
|
+
return new InMemoryWalletStore();
|
|
124
|
+
}
|
|
125
|
+
export function usesPersistentWalletStore() {
|
|
126
|
+
return Boolean(process.env.WALLET_STORE_PATH);
|
|
127
|
+
}
|
|
128
|
+
export const walletStore = createWalletStore();
|
|
129
129
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
2
2
|
//# sourceMappingURL=checkDeploy.d.ts.map
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
// Quick script to fetch the receipt for the deploy tx
|
|
2
|
-
import { publicClient } from "../lib/pharosClient.js";
|
|
3
|
-
import { readFileSync, writeFileSync } from "fs";
|
|
4
|
-
import { resolve } from "path";
|
|
5
|
-
const TX_HASH = "0x7f2106b5bc8c5eddcd2ea7782669ccb0b4a107da4943cffd5d49357ab5820d2e";
|
|
6
|
-
async function main() {
|
|
7
|
-
console.log("Fetching receipt for deploy tx...");
|
|
8
|
-
console.log(`TX: ${TX_HASH}`);
|
|
9
|
-
const receipt = await publicClient.getTransactionReceipt({ hash: TX_HASH });
|
|
10
|
-
console.log(`Status: ${receipt.status}`);
|
|
11
|
-
console.log(`Contract: ${receipt.contractAddress}`);
|
|
12
|
-
console.log(`Block: ${receipt.blockNumber}`);
|
|
13
|
-
console.log(`Gas Used: ${receipt.gasUsed}`);
|
|
14
|
-
if (receipt.contractAddress) {
|
|
15
|
-
// Update .env
|
|
16
|
-
const envPath = resolve(process.cwd(), ".env");
|
|
17
|
-
let envContent = readFileSync(envPath, "utf-8");
|
|
18
|
-
envContent = envContent.replace(/\nRISK_REGISTRY_ADDRESS=.*/, "");
|
|
19
|
-
envContent = envContent.trimEnd() + `\n\n# Risk Registry\nRISK_REGISTRY_ADDRESS=${receipt.contractAddress}\n`;
|
|
20
|
-
writeFileSync(envPath, envContent);
|
|
21
|
-
console.log(`\n✅ .env updated with RISK_REGISTRY_ADDRESS=${receipt.contractAddress}`);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
main().catch(console.error);
|
|
1
|
+
// Quick script to fetch the receipt for the deploy tx
|
|
2
|
+
import { publicClient } from "../lib/pharosClient.js";
|
|
3
|
+
import { readFileSync, writeFileSync } from "fs";
|
|
4
|
+
import { resolve } from "path";
|
|
5
|
+
const TX_HASH = "0x7f2106b5bc8c5eddcd2ea7782669ccb0b4a107da4943cffd5d49357ab5820d2e";
|
|
6
|
+
async function main() {
|
|
7
|
+
console.log("Fetching receipt for deploy tx...");
|
|
8
|
+
console.log(`TX: ${TX_HASH}`);
|
|
9
|
+
const receipt = await publicClient.getTransactionReceipt({ hash: TX_HASH });
|
|
10
|
+
console.log(`Status: ${receipt.status}`);
|
|
11
|
+
console.log(`Contract: ${receipt.contractAddress}`);
|
|
12
|
+
console.log(`Block: ${receipt.blockNumber}`);
|
|
13
|
+
console.log(`Gas Used: ${receipt.gasUsed}`);
|
|
14
|
+
if (receipt.contractAddress) {
|
|
15
|
+
// Update .env
|
|
16
|
+
const envPath = resolve(process.cwd(), ".env");
|
|
17
|
+
let envContent = readFileSync(envPath, "utf-8");
|
|
18
|
+
envContent = envContent.replace(/\nRISK_REGISTRY_ADDRESS=.*/, "");
|
|
19
|
+
envContent = envContent.trimEnd() + `\n\n# Risk Registry\nRISK_REGISTRY_ADDRESS=${receipt.contractAddress}\n`;
|
|
20
|
+
writeFileSync(envPath, envContent);
|
|
21
|
+
console.log(`\n✅ .env updated with RISK_REGISTRY_ADDRESS=${receipt.contractAddress}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
main().catch(console.error);
|
|
25
25
|
//# sourceMappingURL=checkDeploy.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
2
2
|
//# sourceMappingURL=deployRegistry.d.ts.map
|
|
@@ -1,101 +1,101 @@
|
|
|
1
|
-
// ─── Compile & Deploy RiskRegistry ─────────────────────────────────────
|
|
2
|
-
// Compiles the Solidity contract with solc and deploys to Pharos Atlantic.
|
|
3
|
-
// ────────────────────────────────────────────────────────────────────────
|
|
4
|
-
import { readFileSync, writeFileSync } from "fs";
|
|
5
|
-
import { resolve } from "path";
|
|
6
|
-
import solc from "solc";
|
|
7
|
-
import { createPharosWalletClient, publicClient } from "../lib/pharosClient.js";
|
|
8
|
-
// ─── Load .env ─────────────────────────────────────────────────────────
|
|
9
|
-
function loadEnv() {
|
|
10
|
-
const envPath = resolve(process.cwd(), ".env");
|
|
11
|
-
const envFile = readFileSync(envPath, "utf-8");
|
|
12
|
-
const vars = {};
|
|
13
|
-
for (const line of envFile.split("\n")) {
|
|
14
|
-
const trimmed = line.trim();
|
|
15
|
-
if (!trimmed || trimmed.startsWith("#"))
|
|
16
|
-
continue;
|
|
17
|
-
const eqIdx = trimmed.indexOf("=");
|
|
18
|
-
if (eqIdx === -1)
|
|
19
|
-
continue;
|
|
20
|
-
vars[trimmed.slice(0, eqIdx).trim()] = trimmed.slice(eqIdx + 1).trim();
|
|
21
|
-
}
|
|
22
|
-
return vars;
|
|
23
|
-
}
|
|
24
|
-
const env = loadEnv();
|
|
25
|
-
const PRIVATE_KEY = env.PRIVATE_KEY;
|
|
26
|
-
if (!PRIVATE_KEY) {
|
|
27
|
-
console.error("❌ PRIVATE_KEY not found in .env");
|
|
28
|
-
process.exit(1);
|
|
29
|
-
}
|
|
30
|
-
// ─── Compile ───────────────────────────────────────────────────────────
|
|
31
|
-
console.log("📝 Compiling RiskRegistry.sol...");
|
|
32
|
-
const contractPath = resolve(process.cwd(), "contracts", "RiskRegistry.sol");
|
|
33
|
-
const source = readFileSync(contractPath, "utf-8");
|
|
34
|
-
const input = JSON.stringify({
|
|
35
|
-
language: "Solidity",
|
|
36
|
-
sources: {
|
|
37
|
-
"RiskRegistry.sol": { content: source },
|
|
38
|
-
},
|
|
39
|
-
settings: {
|
|
40
|
-
outputSelection: {
|
|
41
|
-
"*": {
|
|
42
|
-
"*": ["abi", "evm.bytecode.object"],
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
optimizer: { enabled: true, runs: 200 },
|
|
46
|
-
},
|
|
47
|
-
});
|
|
48
|
-
const output = JSON.parse(solc.compile(input));
|
|
49
|
-
if (output.errors) {
|
|
50
|
-
const errors = output.errors.filter((e) => e.severity === "error");
|
|
51
|
-
if (errors.length > 0) {
|
|
52
|
-
console.error("❌ Compilation errors:");
|
|
53
|
-
errors.forEach((e) => console.error(e.formattedMessage));
|
|
54
|
-
process.exit(1);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
const contract = output.contracts["RiskRegistry.sol"]["RiskRegistry"];
|
|
58
|
-
const abi = contract.abi;
|
|
59
|
-
const bytecode = `0x${contract.evm.bytecode.object}`;
|
|
60
|
-
console.log("✅ Compiled successfully");
|
|
61
|
-
console.log(` ABI: ${abi.length} functions/events`);
|
|
62
|
-
console.log(` Bytecode: ${bytecode.length} chars`);
|
|
63
|
-
// Save ABI for reference
|
|
64
|
-
const artifactPath = resolve(process.cwd(), "contracts", "RiskRegistry.json");
|
|
65
|
-
writeFileSync(artifactPath, JSON.stringify({ abi, bytecode }, null, 2));
|
|
66
|
-
console.log(` Artifact saved: contracts/RiskRegistry.json`);
|
|
67
|
-
// ─── Deploy ────────────────────────────────────────────────────────────
|
|
68
|
-
console.log("\n🚀 Deploying to Pharos Atlantic Testnet...");
|
|
69
|
-
const wallet = createPharosWalletClient(PRIVATE_KEY);
|
|
70
|
-
const account = wallet.account;
|
|
71
|
-
console.log(` Deployer: ${account.address}`);
|
|
72
|
-
const balance = await publicClient.getBalance({ address: account.address });
|
|
73
|
-
console.log(` Balance: ${Number(balance) / 1e18} PHRS`);
|
|
74
|
-
// Deploy using viem
|
|
75
|
-
const hash = await wallet.deployContract({
|
|
76
|
-
abi,
|
|
77
|
-
bytecode,
|
|
78
|
-
args: [],
|
|
79
|
-
});
|
|
80
|
-
console.log(` TX Hash: ${hash}`);
|
|
81
|
-
console.log(" Waiting for confirmation...");
|
|
82
|
-
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
83
|
-
if (receipt.status !== "success") {
|
|
84
|
-
console.error("❌ Deployment failed!");
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
87
|
-
const contractAddress = receipt.contractAddress;
|
|
88
|
-
console.log(`\n✅ RiskRegistry deployed successfully!`);
|
|
89
|
-
console.log(` Contract: ${contractAddress}`);
|
|
90
|
-
console.log(` Block: ${receipt.blockNumber}`);
|
|
91
|
-
console.log(` Gas Used: ${receipt.gasUsed}`);
|
|
92
|
-
console.log(` Explorer: https://atlantic.pharosscan.xyz/tx/${hash}`);
|
|
93
|
-
// ─── Update .env ───────────────────────────────────────────────────────
|
|
94
|
-
const envPath = resolve(process.cwd(), ".env");
|
|
95
|
-
let envContent = readFileSync(envPath, "utf-8");
|
|
96
|
-
// Remove old entry if exists
|
|
97
|
-
envContent = envContent.replace(/\nRISK_REGISTRY_ADDRESS=.*/, "");
|
|
98
|
-
envContent = envContent.trimEnd() + `\n\n# Risk Registry\nRISK_REGISTRY_ADDRESS=${contractAddress}\n`;
|
|
99
|
-
writeFileSync(envPath, envContent);
|
|
100
|
-
console.log(`\n📝 Updated .env with RISK_REGISTRY_ADDRESS=${contractAddress}`);
|
|
1
|
+
// ─── Compile & Deploy RiskRegistry ─────────────────────────────────────
|
|
2
|
+
// Compiles the Solidity contract with solc and deploys to Pharos Atlantic.
|
|
3
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
4
|
+
import { readFileSync, writeFileSync } from "fs";
|
|
5
|
+
import { resolve } from "path";
|
|
6
|
+
import solc from "solc";
|
|
7
|
+
import { createPharosWalletClient, publicClient } from "../lib/pharosClient.js";
|
|
8
|
+
// ─── Load .env ─────────────────────────────────────────────────────────
|
|
9
|
+
function loadEnv() {
|
|
10
|
+
const envPath = resolve(process.cwd(), ".env");
|
|
11
|
+
const envFile = readFileSync(envPath, "utf-8");
|
|
12
|
+
const vars = {};
|
|
13
|
+
for (const line of envFile.split("\n")) {
|
|
14
|
+
const trimmed = line.trim();
|
|
15
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
16
|
+
continue;
|
|
17
|
+
const eqIdx = trimmed.indexOf("=");
|
|
18
|
+
if (eqIdx === -1)
|
|
19
|
+
continue;
|
|
20
|
+
vars[trimmed.slice(0, eqIdx).trim()] = trimmed.slice(eqIdx + 1).trim();
|
|
21
|
+
}
|
|
22
|
+
return vars;
|
|
23
|
+
}
|
|
24
|
+
const env = loadEnv();
|
|
25
|
+
const PRIVATE_KEY = env.PRIVATE_KEY;
|
|
26
|
+
if (!PRIVATE_KEY) {
|
|
27
|
+
console.error("❌ PRIVATE_KEY not found in .env");
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
// ─── Compile ───────────────────────────────────────────────────────────
|
|
31
|
+
console.log("📝 Compiling RiskRegistry.sol...");
|
|
32
|
+
const contractPath = resolve(process.cwd(), "contracts", "RiskRegistry.sol");
|
|
33
|
+
const source = readFileSync(contractPath, "utf-8");
|
|
34
|
+
const input = JSON.stringify({
|
|
35
|
+
language: "Solidity",
|
|
36
|
+
sources: {
|
|
37
|
+
"RiskRegistry.sol": { content: source },
|
|
38
|
+
},
|
|
39
|
+
settings: {
|
|
40
|
+
outputSelection: {
|
|
41
|
+
"*": {
|
|
42
|
+
"*": ["abi", "evm.bytecode.object"],
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
optimizer: { enabled: true, runs: 200 },
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
const output = JSON.parse(solc.compile(input));
|
|
49
|
+
if (output.errors) {
|
|
50
|
+
const errors = output.errors.filter((e) => e.severity === "error");
|
|
51
|
+
if (errors.length > 0) {
|
|
52
|
+
console.error("❌ Compilation errors:");
|
|
53
|
+
errors.forEach((e) => console.error(e.formattedMessage));
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const contract = output.contracts["RiskRegistry.sol"]["RiskRegistry"];
|
|
58
|
+
const abi = contract.abi;
|
|
59
|
+
const bytecode = `0x${contract.evm.bytecode.object}`;
|
|
60
|
+
console.log("✅ Compiled successfully");
|
|
61
|
+
console.log(` ABI: ${abi.length} functions/events`);
|
|
62
|
+
console.log(` Bytecode: ${bytecode.length} chars`);
|
|
63
|
+
// Save ABI for reference
|
|
64
|
+
const artifactPath = resolve(process.cwd(), "contracts", "RiskRegistry.json");
|
|
65
|
+
writeFileSync(artifactPath, JSON.stringify({ abi, bytecode }, null, 2));
|
|
66
|
+
console.log(` Artifact saved: contracts/RiskRegistry.json`);
|
|
67
|
+
// ─── Deploy ────────────────────────────────────────────────────────────
|
|
68
|
+
console.log("\n🚀 Deploying to Pharos Atlantic Testnet...");
|
|
69
|
+
const wallet = createPharosWalletClient(PRIVATE_KEY);
|
|
70
|
+
const account = wallet.account;
|
|
71
|
+
console.log(` Deployer: ${account.address}`);
|
|
72
|
+
const balance = await publicClient.getBalance({ address: account.address });
|
|
73
|
+
console.log(` Balance: ${Number(balance) / 1e18} PHRS`);
|
|
74
|
+
// Deploy using viem
|
|
75
|
+
const hash = await wallet.deployContract({
|
|
76
|
+
abi,
|
|
77
|
+
bytecode,
|
|
78
|
+
args: [],
|
|
79
|
+
});
|
|
80
|
+
console.log(` TX Hash: ${hash}`);
|
|
81
|
+
console.log(" Waiting for confirmation...");
|
|
82
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
83
|
+
if (receipt.status !== "success") {
|
|
84
|
+
console.error("❌ Deployment failed!");
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
const contractAddress = receipt.contractAddress;
|
|
88
|
+
console.log(`\n✅ RiskRegistry deployed successfully!`);
|
|
89
|
+
console.log(` Contract: ${contractAddress}`);
|
|
90
|
+
console.log(` Block: ${receipt.blockNumber}`);
|
|
91
|
+
console.log(` Gas Used: ${receipt.gasUsed}`);
|
|
92
|
+
console.log(` Explorer: https://atlantic.pharosscan.xyz/tx/${hash}`);
|
|
93
|
+
// ─── Update .env ───────────────────────────────────────────────────────
|
|
94
|
+
const envPath = resolve(process.cwd(), ".env");
|
|
95
|
+
let envContent = readFileSync(envPath, "utf-8");
|
|
96
|
+
// Remove old entry if exists
|
|
97
|
+
envContent = envContent.replace(/\nRISK_REGISTRY_ADDRESS=.*/, "");
|
|
98
|
+
envContent = envContent.trimEnd() + `\n\n# Risk Registry\nRISK_REGISTRY_ADDRESS=${contractAddress}\n`;
|
|
99
|
+
writeFileSync(envPath, envContent);
|
|
100
|
+
console.log(`\n📝 Updated .env with RISK_REGISTRY_ADDRESS=${contractAddress}`);
|
|
101
101
|
//# sourceMappingURL=deployRegistry.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
2
2
|
//# sourceMappingURL=testRegistry.d.ts.map
|
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
// ─── Quick test: RiskRegistry publish + query ──────────────────────────
|
|
2
|
-
import { readFileSync } from "fs";
|
|
3
|
-
import { resolve } from "path";
|
|
4
|
-
import { handleAssessRisk } from "../tools/assessRisk.js";
|
|
5
|
-
import { handleQueryRiskRegistry } from "../tools/queryRiskRegistry.js";
|
|
6
|
-
function loadEnv() {
|
|
7
|
-
const envPath = resolve(process.cwd(), ".env");
|
|
8
|
-
const envFile = readFileSync(envPath, "utf-8");
|
|
9
|
-
const vars = {};
|
|
10
|
-
for (const line of envFile.split("\n")) {
|
|
11
|
-
const trimmed = line.trim();
|
|
12
|
-
if (!trimmed || trimmed.startsWith("#"))
|
|
13
|
-
continue;
|
|
14
|
-
const eqIdx = trimmed.indexOf("=");
|
|
15
|
-
if (eqIdx === -1)
|
|
16
|
-
continue;
|
|
17
|
-
vars[trimmed.slice(0, eqIdx).trim()] = trimmed.slice(eqIdx + 1).trim();
|
|
18
|
-
}
|
|
19
|
-
return vars;
|
|
20
|
-
}
|
|
21
|
-
const env = loadEnv();
|
|
22
|
-
async function main() {
|
|
23
|
-
console.log("🧪 Testing RiskRegistry: assess + publish + query\n");
|
|
24
|
-
// 1. assess_risk WITH privateKey → auto-publishes
|
|
25
|
-
console.log("1️⃣ assess_risk with auto-publish...");
|
|
26
|
-
const assessment = await handleAssessRisk({
|
|
27
|
-
action: "swap",
|
|
28
|
-
tokenIn: "PHRS",
|
|
29
|
-
tokenOut: "USDC",
|
|
30
|
-
amount: "1",
|
|
31
|
-
walletAddress: env.WALLET_ADDRESS,
|
|
32
|
-
privateKey: env.PRIVATE_KEY,
|
|
33
|
-
});
|
|
34
|
-
console.log(JSON.stringify(assessment, null, 2));
|
|
35
|
-
// 2. query_risk_registry
|
|
36
|
-
console.log("\n2️⃣ query_risk_registry...");
|
|
37
|
-
const query = await handleQueryRiskRegistry({
|
|
38
|
-
walletAddress: env.WALLET_ADDRESS,
|
|
39
|
-
});
|
|
40
|
-
console.log(JSON.stringify(query, null, 2));
|
|
41
|
-
console.log("\n✅ RiskRegistry end-to-end test complete!");
|
|
42
|
-
}
|
|
43
|
-
main().catch(console.error);
|
|
1
|
+
// ─── Quick test: RiskRegistry publish + query ──────────────────────────
|
|
2
|
+
import { readFileSync } from "fs";
|
|
3
|
+
import { resolve } from "path";
|
|
4
|
+
import { handleAssessRisk } from "../tools/assessRisk.js";
|
|
5
|
+
import { handleQueryRiskRegistry } from "../tools/queryRiskRegistry.js";
|
|
6
|
+
function loadEnv() {
|
|
7
|
+
const envPath = resolve(process.cwd(), ".env");
|
|
8
|
+
const envFile = readFileSync(envPath, "utf-8");
|
|
9
|
+
const vars = {};
|
|
10
|
+
for (const line of envFile.split("\n")) {
|
|
11
|
+
const trimmed = line.trim();
|
|
12
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
13
|
+
continue;
|
|
14
|
+
const eqIdx = trimmed.indexOf("=");
|
|
15
|
+
if (eqIdx === -1)
|
|
16
|
+
continue;
|
|
17
|
+
vars[trimmed.slice(0, eqIdx).trim()] = trimmed.slice(eqIdx + 1).trim();
|
|
18
|
+
}
|
|
19
|
+
return vars;
|
|
20
|
+
}
|
|
21
|
+
const env = loadEnv();
|
|
22
|
+
async function main() {
|
|
23
|
+
console.log("🧪 Testing RiskRegistry: assess + publish + query\n");
|
|
24
|
+
// 1. assess_risk WITH privateKey → auto-publishes
|
|
25
|
+
console.log("1️⃣ assess_risk with auto-publish...");
|
|
26
|
+
const assessment = await handleAssessRisk({
|
|
27
|
+
action: "swap",
|
|
28
|
+
tokenIn: "PHRS",
|
|
29
|
+
tokenOut: "USDC",
|
|
30
|
+
amount: "1",
|
|
31
|
+
walletAddress: env.WALLET_ADDRESS,
|
|
32
|
+
privateKey: env.PRIVATE_KEY,
|
|
33
|
+
});
|
|
34
|
+
console.log(JSON.stringify(assessment, null, 2));
|
|
35
|
+
// 2. query_risk_registry
|
|
36
|
+
console.log("\n2️⃣ query_risk_registry...");
|
|
37
|
+
const query = await handleQueryRiskRegistry({
|
|
38
|
+
walletAddress: env.WALLET_ADDRESS,
|
|
39
|
+
});
|
|
40
|
+
console.log(JSON.stringify(query, null, 2));
|
|
41
|
+
console.log("\n✅ RiskRegistry end-to-end test complete!");
|
|
42
|
+
}
|
|
43
|
+
main().catch(console.error);
|
|
44
44
|
//# sourceMappingURL=testRegistry.js.map
|