@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
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Client, TopicMessageSubmitTransaction, TopicCreateTransaction, TopicId, PrivateKey, AccountId, } from "@hashgraph/sdk";
|
|
2
|
+
import { hederaConfig } from "../config.js";
|
|
3
|
+
let hederaClient = null;
|
|
4
|
+
let topicId = null;
|
|
5
|
+
function getClient() {
|
|
6
|
+
if (!hederaClient) {
|
|
7
|
+
hederaClient =
|
|
8
|
+
hederaConfig.network === "testnet" ? Client.forTestnet() : Client.forMainnet();
|
|
9
|
+
// Prefer ED25519 (DER) key for native Hedera operations (HCS)
|
|
10
|
+
if (hederaConfig.hcsAccountId && hederaConfig.hcsPrivateKeyDer) {
|
|
11
|
+
hederaClient.setOperator(AccountId.fromString(hederaConfig.hcsAccountId), PrivateKey.fromStringDer(hederaConfig.hcsPrivateKeyDer));
|
|
12
|
+
}
|
|
13
|
+
else if (hederaConfig.accountId && hederaConfig.privateKey) {
|
|
14
|
+
const rawKey = hederaConfig.privateKey.startsWith("0x")
|
|
15
|
+
? hederaConfig.privateKey.slice(2)
|
|
16
|
+
: hederaConfig.privateKey;
|
|
17
|
+
hederaClient.setOperator(AccountId.fromString(hederaConfig.accountId), PrivateKey.fromStringECDSA(rawKey));
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return hederaClient;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create a new HCS topic for CCP events.
|
|
24
|
+
* Call once during setup.
|
|
25
|
+
*/
|
|
26
|
+
export async function createCCPTopic() {
|
|
27
|
+
const client = getClient();
|
|
28
|
+
const tx = new TopicCreateTransaction().setTopicMemo("CCP Protocol Events — Containment Certificate Protocol");
|
|
29
|
+
const response = await tx.execute(client);
|
|
30
|
+
const receipt = await response.getReceipt(client);
|
|
31
|
+
const newTopicId = receipt.topicId.toString();
|
|
32
|
+
console.log(` [HCS] Created CCP topic: ${newTopicId}`);
|
|
33
|
+
topicId = TopicId.fromString(newTopicId);
|
|
34
|
+
return newTopicId;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Set the topic ID (if already created).
|
|
38
|
+
*/
|
|
39
|
+
export function setTopicId(id) {
|
|
40
|
+
topicId = TopicId.fromString(id);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Publish a CCP event to the HCS topic.
|
|
44
|
+
* Events are timestamped by Hedera consensus with guaranteed ordering.
|
|
45
|
+
*/
|
|
46
|
+
export async function publishEvent(event) {
|
|
47
|
+
if (!topicId) {
|
|
48
|
+
if (hederaConfig.hcsTopicId) {
|
|
49
|
+
topicId = TopicId.fromString(hederaConfig.hcsTopicId);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
console.warn(" [HCS] No topic ID set. Skipping event publish.");
|
|
53
|
+
return "";
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const client = getClient();
|
|
57
|
+
const message = JSON.stringify(event);
|
|
58
|
+
const tx = new TopicMessageSubmitTransaction().setTopicId(topicId).setMessage(message);
|
|
59
|
+
const response = await tx.execute(client);
|
|
60
|
+
const receipt = await response.getReceipt(client);
|
|
61
|
+
const seqNum = receipt.topicSequenceNumber?.toString() || "?";
|
|
62
|
+
console.log(` [HCS] Published ${event.type} (seq: ${seqNum})`);
|
|
63
|
+
return seqNum;
|
|
64
|
+
}
|
|
65
|
+
// ─── Convenience publishers ───
|
|
66
|
+
export async function publishCertificatePublished(certHash, agent, operator, certClass, containmentBound) {
|
|
67
|
+
return publishEvent({
|
|
68
|
+
type: "CERTIFICATE_PUBLISHED",
|
|
69
|
+
certHash,
|
|
70
|
+
agent,
|
|
71
|
+
operator,
|
|
72
|
+
class: certClass,
|
|
73
|
+
containmentBound,
|
|
74
|
+
timestamp: Date.now(),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
export async function publishAttestationSigned(certHash, auditor, certClass) {
|
|
78
|
+
return publishEvent({
|
|
79
|
+
type: "ATTESTATION_SIGNED",
|
|
80
|
+
certHash,
|
|
81
|
+
auditor,
|
|
82
|
+
class: certClass,
|
|
83
|
+
timestamp: Date.now(),
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
export async function publishAgentTransaction(agent, to, value, ledgerCosigned, periodSpent, periodLimit) {
|
|
87
|
+
return publishEvent({
|
|
88
|
+
type: "AGENT_TRANSACTION",
|
|
89
|
+
agent,
|
|
90
|
+
to,
|
|
91
|
+
value,
|
|
92
|
+
ledgerCosigned,
|
|
93
|
+
periodSpent,
|
|
94
|
+
periodLimit,
|
|
95
|
+
timestamp: Date.now(),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
export async function publishTransactionBlocked(agent, value, reason, periodSpent, periodLimit) {
|
|
99
|
+
return publishEvent({
|
|
100
|
+
type: "TRANSACTION_BLOCKED",
|
|
101
|
+
agent,
|
|
102
|
+
value,
|
|
103
|
+
reason,
|
|
104
|
+
periodSpent,
|
|
105
|
+
periodLimit,
|
|
106
|
+
timestamp: Date.now(),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
export async function publishChallengeSubmitted(challengeId, certHash, challenger) {
|
|
110
|
+
return publishEvent({
|
|
111
|
+
type: "CHALLENGE_SUBMITTED",
|
|
112
|
+
challengeId,
|
|
113
|
+
certHash,
|
|
114
|
+
agent: challenger,
|
|
115
|
+
timestamp: Date.now(),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
export async function publishChallengeResolved(challengeId, certHash, upheld) {
|
|
119
|
+
return publishEvent({
|
|
120
|
+
type: upheld ? "CHALLENGE_UPHELD" : "CHALLENGE_REJECTED",
|
|
121
|
+
challengeId,
|
|
122
|
+
certHash,
|
|
123
|
+
timestamp: Date.now(),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=publisher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publisher.js","sourceRoot":"","sources":["../../src/hcs/publisher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { hederaConfig } from "../config.js";
|
|
2
|
+
const MIRROR_BASE = hederaConfig.network === "testnet"
|
|
3
|
+
? "https://testnet.mirrornode.hedera.com"
|
|
4
|
+
: "https://mainnet.mirrornode.hedera.com";
|
|
5
|
+
/**
|
|
6
|
+
* Query contract state via Mirror Node REST API.
|
|
7
|
+
*/
|
|
8
|
+
export async function getContractInfo(contractAddress) {
|
|
9
|
+
const res = await fetch(`${MIRROR_BASE}/api/v1/contracts/${contractAddress}`);
|
|
10
|
+
return res.json();
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get token balance for an account.
|
|
14
|
+
*/
|
|
15
|
+
export async function getAccountTokens(accountId) {
|
|
16
|
+
const res = await fetch(`${MIRROR_BASE}/api/v1/accounts/${accountId}/tokens`);
|
|
17
|
+
return res.json();
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get transaction history for a contract.
|
|
21
|
+
*/
|
|
22
|
+
export async function getContractTransactions(contractAddress, limit = 25) {
|
|
23
|
+
const res = await fetch(`${MIRROR_BASE}/api/v1/contracts/${contractAddress}/results?limit=${limit}&order=desc`);
|
|
24
|
+
return res.json();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get all messages from an HCS topic (certificate event history).
|
|
28
|
+
*/
|
|
29
|
+
export async function getTopicMessages(topicId, limit = 100) {
|
|
30
|
+
const res = await fetch(`${MIRROR_BASE}/api/v1/topics/${topicId}/messages?limit=${limit}&order=asc`);
|
|
31
|
+
const data = (await res.json());
|
|
32
|
+
return data.messages.map((msg) => ({
|
|
33
|
+
timestamp: msg.consensus_timestamp,
|
|
34
|
+
sequenceNumber: msg.sequence_number,
|
|
35
|
+
content: JSON.parse(Buffer.from(msg.message, "base64").toString("utf8")),
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Print a formatted event timeline from HCS.
|
|
40
|
+
*/
|
|
41
|
+
export async function printEventTimeline(topicId) {
|
|
42
|
+
console.log("\n═══ CCP Event Timeline (HCS) ═══\n");
|
|
43
|
+
const messages = await getTopicMessages(topicId);
|
|
44
|
+
for (const msg of messages) {
|
|
45
|
+
const event = msg.content;
|
|
46
|
+
const time = new Date(parseFloat(msg.timestamp) * 1000).toISOString();
|
|
47
|
+
switch (event.type) {
|
|
48
|
+
case "CERTIFICATE_PUBLISHED":
|
|
49
|
+
console.log(` ${time} | CERT PUBLISHED | agent=${event.agent?.slice(0, 10)}... class=${event.class}`);
|
|
50
|
+
break;
|
|
51
|
+
case "ATTESTATION_SIGNED":
|
|
52
|
+
console.log(` ${time} | ATTESTED | auditor=${event.auditor?.slice(0, 10)}... class=${event.class}`);
|
|
53
|
+
break;
|
|
54
|
+
case "AGENT_TRANSACTION":
|
|
55
|
+
console.log(` ${time} | TX EXECUTED | to=${event.to?.slice(0, 10)}... value=${event.value} cosigned=${event.ledgerCosigned}`);
|
|
56
|
+
break;
|
|
57
|
+
case "TRANSACTION_BLOCKED":
|
|
58
|
+
console.log(` ${time} | TX BLOCKED | value=${event.value} reason=${event.reason}`);
|
|
59
|
+
break;
|
|
60
|
+
case "CHALLENGE_SUBMITTED":
|
|
61
|
+
console.log(` ${time} | CHALLENGED | id=${event.challengeId}`);
|
|
62
|
+
break;
|
|
63
|
+
case "CHALLENGE_UPHELD":
|
|
64
|
+
console.log(` ${time} | SLASH | challenge=${event.challengeId} UPHELD`);
|
|
65
|
+
break;
|
|
66
|
+
case "CHALLENGE_REJECTED":
|
|
67
|
+
console.log(` ${time} | REJECTED | challenge=${event.challengeId} frivolous`);
|
|
68
|
+
break;
|
|
69
|
+
default:
|
|
70
|
+
console.log(` ${time} | ${event.type}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
console.log("\n═══════════════════════════════\n");
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=mirrorNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mirrorNode.js","sourceRoot":"","sources":["../../src/hedera/mirrorNode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { encodePacked, keccak256 } from "viem";
|
|
2
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
3
|
+
import { publicClient, getWalletClient } from "../client.js";
|
|
4
|
+
import { SpendingLimitABI } from "../contracts/index.js";
|
|
5
|
+
import { keys } from "../config.js";
|
|
6
|
+
/**
|
|
7
|
+
* Generate a Ledger co-signature for a transaction above the cosign threshold.
|
|
8
|
+
* The SpendingLimit contract verifies: keccak256(to, value, chainId, spendingLimit)
|
|
9
|
+
*/
|
|
10
|
+
export async function ledgerCosign(request) {
|
|
11
|
+
const txHash = keccak256(encodePacked(["address", "uint256", "uint256", "address"], [request.to, request.value, BigInt(request.chainId), request.spendingLimitAddress]));
|
|
12
|
+
// In production: send txHash to Ledger device via DMK
|
|
13
|
+
// Ledger displays Clear Signing JSON showing:
|
|
14
|
+
// "Co-sign Agent Transaction (above threshold)"
|
|
15
|
+
// Recipient: <to>
|
|
16
|
+
// Amount: <value> USDC
|
|
17
|
+
// Period Spent: <current> / <limit>
|
|
18
|
+
// Operator physically approves on device.
|
|
19
|
+
// For demo: sign with the ledger private key
|
|
20
|
+
const account = privateKeyToAccount(keys.ledger);
|
|
21
|
+
const signature = await account.signMessage({ message: { raw: txHash } });
|
|
22
|
+
console.log(` [Ledger] Co-signed transaction: ${request.value} to ${request.to}`);
|
|
23
|
+
return signature;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Sign a CCP certificate hash with the operator's Ledger device.
|
|
27
|
+
* This produces a hardware-attested operator signature.
|
|
28
|
+
*/
|
|
29
|
+
export async function ledgerSignCertificate(certHash) {
|
|
30
|
+
// In production: send certHash to Ledger device
|
|
31
|
+
// Clear Signing displays:
|
|
32
|
+
// "Publish CCP Certificate"
|
|
33
|
+
// Agent: <agent ENS name>
|
|
34
|
+
// Class: C2
|
|
35
|
+
// Containment Bound: $50,000 USDC
|
|
36
|
+
// Expires: <date>
|
|
37
|
+
const account = privateKeyToAccount(keys.operator);
|
|
38
|
+
const signature = await account.signMessage({ message: { raw: certHash } });
|
|
39
|
+
console.log(` [Ledger] Operator signed certificate: ${certHash.slice(0, 18)}...`);
|
|
40
|
+
return signature;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Sign a CCP certificate hash as an auditor attestation with Ledger.
|
|
44
|
+
* Hardware-attested audit signature.
|
|
45
|
+
*/
|
|
46
|
+
export async function ledgerSignAttestation(certHash) {
|
|
47
|
+
// Clear Signing displays:
|
|
48
|
+
// "Attest CCP Certificate"
|
|
49
|
+
// Agent: <agent ENS name>
|
|
50
|
+
// Class: C2
|
|
51
|
+
// Containment Bound: $50,000 USDC
|
|
52
|
+
// Your Stake: $1,500 USDC
|
|
53
|
+
const account = privateKeyToAccount(keys.auditor);
|
|
54
|
+
const signature = await account.signMessage({ message: { raw: certHash } });
|
|
55
|
+
console.log(` [Ledger] Auditor signed attestation: ${certHash.slice(0, 18)}...`);
|
|
56
|
+
return signature;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Execute a transaction through SpendingLimit with Ledger co-signature.
|
|
60
|
+
*/
|
|
61
|
+
export async function executeWithLedgerCosign(to, value, spendingLimitAddress) {
|
|
62
|
+
const cosig = await ledgerCosign({
|
|
63
|
+
to,
|
|
64
|
+
value,
|
|
65
|
+
spendingLimitAddress,
|
|
66
|
+
chainId: 296, // Hedera testnet
|
|
67
|
+
});
|
|
68
|
+
const agentWallet = getWalletClient(keys.agent);
|
|
69
|
+
const txHash = await agentWallet.writeContract({
|
|
70
|
+
address: spendingLimitAddress,
|
|
71
|
+
abi: SpendingLimitABI,
|
|
72
|
+
functionName: "executeWithCosign",
|
|
73
|
+
args: [to, value, "0x", cosig],
|
|
74
|
+
});
|
|
75
|
+
await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
76
|
+
console.log(` [Agent] Executed with Ledger co-sign: ${txHash}`);
|
|
77
|
+
return txHash;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=cosigner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cosigner.js","sourceRoot":"","sources":["../../src/ledger/cosigner.ts"],"names":[],"mappings":"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"}
|