@iamnotdou/ccp 0.1.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/.env.example +29 -0
- package/dist/auditor/attest.js +141 -0
- package/dist/auditor/attest.js.map +1 -0
- package/dist/cli.js +1006 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.js +35 -0
- package/dist/client.js.map +1 -0
- package/dist/config.js +31 -0
- package/dist/config.js.map +1 -0
- package/dist/contracts/abis.js +2212 -0
- package/dist/contracts/abis.js.map +1 -0
- package/dist/contracts/index.js +2 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/demo.js +218 -0
- package/dist/demo.js.map +1 -0
- package/dist/ens/subnames.js +33 -0
- package/dist/ens/subnames.js.map +1 -0
- package/dist/ens/textRecords.js +111 -0
- package/dist/ens/textRecords.js.map +1 -0
- package/dist/hcs/listener.js +50 -0
- package/dist/hcs/listener.js.map +1 -0
- package/dist/hcs/publisher.js +126 -0
- package/dist/hcs/publisher.js.map +1 -0
- package/dist/hedera/mirrorNode.js +75 -0
- package/dist/hedera/mirrorNode.js.map +1 -0
- package/dist/ledger/cosigner.js +79 -0
- package/dist/ledger/cosigner.js.map +1 -0
- package/dist/mcp.js +648 -0
- package/dist/mcp.js.map +1 -0
- package/dist/setup.js +222 -0
- package/dist/setup.js.map +1 -0
- package/package.json +47 -0
package/.env.example
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Hedera Testnet
|
|
2
|
+
HEDERA_ACCOUNT_ID=0.0.XXXXX
|
|
3
|
+
HEDERA_PRIVATE_KEY=302e...
|
|
4
|
+
HEDERA_NETWORK=testnet
|
|
5
|
+
|
|
6
|
+
# Hedera JSON-RPC (for EVM calls via viem)
|
|
7
|
+
HEDERA_RPC_URL=https://testnet.hashio.io/api
|
|
8
|
+
HEDERA_CHAIN_ID=296
|
|
9
|
+
|
|
10
|
+
# HCS Topic ID (created during setup)
|
|
11
|
+
HCS_TOPIC_ID=0.0.XXXXX
|
|
12
|
+
|
|
13
|
+
# Contract Addresses (deployed during setup)
|
|
14
|
+
REGISTRY_ADDRESS=0x...
|
|
15
|
+
RESERVE_VAULT_ADDRESS=0x...
|
|
16
|
+
SPENDING_LIMIT_ADDRESS=0x...
|
|
17
|
+
AUDITOR_STAKING_ADDRESS=0x...
|
|
18
|
+
FEE_ESCROW_ADDRESS=0x...
|
|
19
|
+
CHALLENGE_MANAGER_ADDRESS=0x...
|
|
20
|
+
USDC_ADDRESS=0x...
|
|
21
|
+
|
|
22
|
+
# Actor Private Keys (Hedera testnet only)
|
|
23
|
+
OPERATOR_PRIVATE_KEY=0x...
|
|
24
|
+
AUDITOR_PRIVATE_KEY=0x...
|
|
25
|
+
AGENT_PRIVATE_KEY=0x...
|
|
26
|
+
LEDGER_PRIVATE_KEY=0x...
|
|
27
|
+
|
|
28
|
+
# ENS (on Sepolia)
|
|
29
|
+
ENS_RPC_URL=https://sepolia.infura.io/v3/YOUR_KEY
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { formatUnits } from "viem";
|
|
2
|
+
import { publicClient, getWalletClient } from "../client.js";
|
|
3
|
+
import { AuditorStakingABI, ReserveVaultABI, SpendingLimitABI } from "../contracts/index.js";
|
|
4
|
+
import { addresses, keys } from "../config.js";
|
|
5
|
+
import { ledgerSignAttestation } from "../ledger/cosigner.js";
|
|
6
|
+
import { publishAttestationSigned } from "../hcs/publisher.js";
|
|
7
|
+
/**
|
|
8
|
+
* Automated containment audit checks.
|
|
9
|
+
* In production: auditor reviews these results + manual analysis.
|
|
10
|
+
* For demo: automated checks against SpendingLimit and ReserveVault.
|
|
11
|
+
*/
|
|
12
|
+
export async function auditContainment(spendingLimitAddress, reserveVaultAddress, expectedBound) {
|
|
13
|
+
const findings = [];
|
|
14
|
+
let passed = true;
|
|
15
|
+
console.log(" [Auditor] Starting containment audit...");
|
|
16
|
+
// Check 1: SpendingLimit configuration
|
|
17
|
+
const maxSingle = await publicClient.readContract({
|
|
18
|
+
address: spendingLimitAddress,
|
|
19
|
+
abi: SpendingLimitABI,
|
|
20
|
+
functionName: "maxSingleAction",
|
|
21
|
+
});
|
|
22
|
+
const maxPeriodic = await publicClient.readContract({
|
|
23
|
+
address: spendingLimitAddress,
|
|
24
|
+
abi: SpendingLimitABI,
|
|
25
|
+
functionName: "maxPeriodicLoss",
|
|
26
|
+
});
|
|
27
|
+
const cosignThreshold = await publicClient.readContract({
|
|
28
|
+
address: spendingLimitAddress,
|
|
29
|
+
abi: SpendingLimitABI,
|
|
30
|
+
functionName: "cosignThreshold",
|
|
31
|
+
});
|
|
32
|
+
const ledgerCosigner = await publicClient.readContract({
|
|
33
|
+
address: spendingLimitAddress,
|
|
34
|
+
abi: SpendingLimitABI,
|
|
35
|
+
functionName: "ledgerCosigner",
|
|
36
|
+
});
|
|
37
|
+
findings.push(` SpendingLimit: maxSingle=${formatUnits(maxSingle, 6)} USDC`);
|
|
38
|
+
findings.push(` SpendingLimit: maxPeriodic=${formatUnits(maxPeriodic, 6)} USDC`);
|
|
39
|
+
findings.push(` SpendingLimit: cosignThreshold=${formatUnits(cosignThreshold, 6)} USDC`);
|
|
40
|
+
findings.push(` SpendingLimit: ledgerCosigner=${ledgerCosigner}`);
|
|
41
|
+
// Verify containment bound matches
|
|
42
|
+
if (maxPeriodic > expectedBound) {
|
|
43
|
+
findings.push(" FAIL: maxPeriodicLoss > stated containment bound");
|
|
44
|
+
passed = false;
|
|
45
|
+
}
|
|
46
|
+
// Check 2: Ledger cosigner is set (agent-independent constraint)
|
|
47
|
+
if (ledgerCosigner === "0x0000000000000000000000000000000000000000") {
|
|
48
|
+
findings.push(" FAIL: No ledger cosigner configured — not agent-independent");
|
|
49
|
+
passed = false;
|
|
50
|
+
}
|
|
51
|
+
// Check 3: Reserve adequacy
|
|
52
|
+
const reserveBalance = await publicClient.readContract({
|
|
53
|
+
address: reserveVaultAddress,
|
|
54
|
+
abi: ReserveVaultABI,
|
|
55
|
+
functionName: "getReserveBalance",
|
|
56
|
+
});
|
|
57
|
+
const isAdequate = await publicClient.readContract({
|
|
58
|
+
address: reserveVaultAddress,
|
|
59
|
+
abi: ReserveVaultABI,
|
|
60
|
+
functionName: "isAdequate",
|
|
61
|
+
args: [expectedBound, 30000], // 3x for C2
|
|
62
|
+
});
|
|
63
|
+
const isLocked = await publicClient.readContract({
|
|
64
|
+
address: reserveVaultAddress,
|
|
65
|
+
abi: ReserveVaultABI,
|
|
66
|
+
functionName: "isLocked",
|
|
67
|
+
});
|
|
68
|
+
findings.push(` Reserve: balance=${formatUnits(reserveBalance, 6)} USDC`);
|
|
69
|
+
findings.push(` Reserve: adequate (3x)=${isAdequate}`);
|
|
70
|
+
findings.push(` Reserve: locked=${isLocked}`);
|
|
71
|
+
if (!isAdequate) {
|
|
72
|
+
findings.push(" FAIL: Reserve insufficient for C2 (need 3x containment bound)");
|
|
73
|
+
passed = false;
|
|
74
|
+
}
|
|
75
|
+
if (!isLocked) {
|
|
76
|
+
findings.push(" FAIL: Reserve not locked");
|
|
77
|
+
passed = false;
|
|
78
|
+
}
|
|
79
|
+
const certClass = passed ? "C2" : "UNCLASSIFIED";
|
|
80
|
+
console.log(` [Auditor] Audit ${passed ? "PASSED" : "FAILED"} — class: ${certClass}`);
|
|
81
|
+
findings.forEach((f) => console.log(` ${f}`));
|
|
82
|
+
return { passed, findings, certClass };
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Full auditor attestation workflow:
|
|
86
|
+
* 1. Audit containment (automated checks)
|
|
87
|
+
* 2. Stake capital
|
|
88
|
+
* 3. Sign attestation (via Ledger)
|
|
89
|
+
* 4. Publish HCS event
|
|
90
|
+
* 5. Return signature to operator
|
|
91
|
+
*/
|
|
92
|
+
export async function attestCertificate(certHash, spendingLimitAddress, reserveVaultAddress, containmentBound, stakeAmount) {
|
|
93
|
+
// Step 1: Audit
|
|
94
|
+
const auditResult = await auditContainment(spendingLimitAddress, reserveVaultAddress, containmentBound);
|
|
95
|
+
if (!auditResult.passed) {
|
|
96
|
+
throw new Error("Audit failed — cannot attest");
|
|
97
|
+
}
|
|
98
|
+
// Step 2: Stake
|
|
99
|
+
console.log(` [Auditor] Staking ${formatUnits(stakeAmount, 6)} USDC...`);
|
|
100
|
+
const auditorWallet = getWalletClient(keys.auditor);
|
|
101
|
+
// Approve staking contract
|
|
102
|
+
const erc20Abi = [
|
|
103
|
+
{
|
|
104
|
+
name: "approve",
|
|
105
|
+
type: "function",
|
|
106
|
+
inputs: [
|
|
107
|
+
{ name: "spender", type: "address" },
|
|
108
|
+
{ name: "amount", type: "uint256" },
|
|
109
|
+
],
|
|
110
|
+
outputs: [{ type: "bool" }],
|
|
111
|
+
stateMutability: "nonpayable",
|
|
112
|
+
},
|
|
113
|
+
];
|
|
114
|
+
const approveTx = await auditorWallet.writeContract({
|
|
115
|
+
address: addresses.usdc,
|
|
116
|
+
abi: erc20Abi,
|
|
117
|
+
functionName: "approve",
|
|
118
|
+
args: [addresses.auditorStaking, stakeAmount],
|
|
119
|
+
});
|
|
120
|
+
console.log(` [Auditor] Approve tx: ${approveTx}`);
|
|
121
|
+
await publicClient.waitForTransactionReceipt({ hash: approveTx });
|
|
122
|
+
const stakeTx = await auditorWallet.writeContract({
|
|
123
|
+
address: addresses.auditorStaking,
|
|
124
|
+
abi: AuditorStakingABI,
|
|
125
|
+
functionName: "stake",
|
|
126
|
+
args: [certHash, stakeAmount],
|
|
127
|
+
});
|
|
128
|
+
await publicClient.waitForTransactionReceipt({ hash: stakeTx });
|
|
129
|
+
console.log(` [Auditor] Staked ${formatUnits(stakeAmount, 6)} USDC for cert ${certHash.slice(0, 18)}...`);
|
|
130
|
+
// Step 3: Sign attestation (via Ledger)
|
|
131
|
+
const signature = await ledgerSignAttestation(certHash);
|
|
132
|
+
// Step 4: Publish HCS event (non-fatal — demo continues if HCS fails)
|
|
133
|
+
try {
|
|
134
|
+
await publishAttestationSigned(certHash, auditorWallet.account.address, auditResult.certClass);
|
|
135
|
+
}
|
|
136
|
+
catch (e) {
|
|
137
|
+
console.log(` [HCS] Event publish skipped: ${e.message?.slice(0, 60)}`);
|
|
138
|
+
}
|
|
139
|
+
return { signature, auditResult };
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=attest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attest.js","sourceRoot":"","sources":["../../src/auditor/attest.ts"],"names":[],"mappings":"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"}
|