Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,13 @@ api.json

# JSDoc
docs/
plugin-*/
plugin-*/vialabs-testnet/artifacts/
vialabs-testnet/cache/
vialabs-testnet/typechain-types/
vialabs-testnet/node_modules/
vialabs-testnet/quickstart-token-ref/
vialabs-testnet/artifacts/
vialabs-testnet/cache/
vialabs-testnet/typechain-types/
vialabs-testnet/node_modules/
vialabs-testnet/quickstart-token-ref/
22 changes: 22 additions & 0 deletions agentkit-core/check_chain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { createPublicClient, http } from "viem";

const RPC_URL = "https://services.datahaven-testnet.network/testnet";

async function checkChain() {
const client = createPublicClient({
transport: http(RPC_URL),
});

try {
const chainId = await client.getChainId();
console.log(`Chain ID: ${chainId}`);

const blockNumber = await client.getBlockNumber();
console.log(`Block Number: ${blockNumber}`);

} catch (error) {
console.error("RPC Error:", error);
}
}

checkChain();
47 changes: 47 additions & 0 deletions agentkit-core/check_chainlink_actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { DeployCREWorkflowAction } from "./src/actions/DeployCREWorkflowAction/deployCREWorkflowAction";
import { ChainlinkDocsAction } from "./src/actions/ChainlinkDocsAction/chainlinkDocsAction";
import { CRE_SUPPORTED_NETWORKS } from "./src/utils/chainlinkConstants";

async function verifyActions() {
console.log("Verifying Chainlink Actions...");

// 1. Verify DeployCREWorkflowAction
console.log("\n1. Testing DeployCREWorkflowAction instantiation...");
const deployAction = new DeployCREWorkflowAction();
console.log(`Action Name: ${deployAction.name}`);
if (deployAction.name !== "deploy_cre_workflow") {
throw new Error("DeployCREWorkflowAction name mismatch");
}
console.log("DeployCREWorkflowAction instantiated successfully.");

// 1b. Verify Supported Networks
console.log("\n1b. Checking Supported Networks...");
const avaxTestnet = CRE_SUPPORTED_NETWORKS["avalanche-fuji"];
if (!avaxTestnet || avaxTestnet.chainSelector !== "avalanche-testnet-fuji") {
throw new Error("Avalanche Fuji config missing or incorrect");
}
console.log("Network config looks correct.");

// 2. Verify ChainlinkDocsAction
console.log("\n2. Testing ChainlinkDocsAction instantiation...");
const docsAction = new ChainlinkDocsAction();
console.log(`Action Name: ${docsAction.name}`);
if (docsAction.name !== "chainlink_cre_docs") {
throw new Error("ChainlinkDocsAction name mismatch");
}

// 2b. Test Docs Logic (Action Function)
console.log("\n2b. Testing Docs Retrieval Logic...");
const docsResult = await docsAction.func({} as any, { query: "forwarder" });
if (!docsResult.includes("KeystoneForwarder")) {
throw new Error("Docs query for 'forwarder' did not return expected content.");
}
console.log("Docs retrieval logic verified.");

console.log("\n✅ All Chainlink Actions Verified Successfully!");
}

verifyActions().catch((err) => {
console.error("\n❌ Verification Failed:", err);
process.exit(1);
});
22 changes: 22 additions & 0 deletions agentkit-core/check_exports.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as core from '@storagehub-sdk/core';

console.log("Exported Keys:", Object.keys(core));

for (const key of Object.keys(core)) {
const Val = (core as any)[key];
if (typeof Val === 'string') {
console.log(`String export: ${key} = ${Val}`);
}
}

// Check if there is a likely candidate for contract address
console.log("\nSearching for 'Address' in exports...");
for (const key of Object.keys(core)) {
if (key.toLowerCase().includes('address')) {
console.log(`Found: ${key} = ${(core as any)[key]}`);
}
}

// Check StorageHubClientOptions interface if possible? No, runtime only.
// Check if StorageHubClient has length (constructor args count)
console.log("StorageHubClient length:", core.StorageHubClient ? core.StorageHubClient.length : "N/A");
23 changes: 23 additions & 0 deletions agentkit-core/check_precompile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { createPublicClient, http } from "viem";

const RPC_URL = "https://services.datahaven-testnet.network/testnet";
const PRECOMPILE_ADDRESS = "0x0000000000000000000000000000000000000064";

async function checkContract() {
const client = createPublicClient({
transport: http(RPC_URL),
});

console.log(`Checking code at ${PRECOMPILE_ADDRESS}...`);
const code = await client.getBytecode({ address: PRECOMPILE_ADDRESS });

console.log(`Code result: ${code}`);

if (!code || code === "0x") {
console.log("❌ No code found at address! Precompile missing or RPC issue.");
} else {
console.log(`✅ Code found (${code.length} bytes). Contract exists.`);
}
}

checkContract().catch(console.error);
35 changes: 35 additions & 0 deletions agentkit-core/inspect_api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { ApiPromise, WsProvider } from '@polkadot/api';
import '@storagehub/api-augment';

// Correct WSS URL
const WSS_URL = "wss://services.datahaven-testnet.network/testnet";

async function inspect() {
console.log(`Connecting to ${WSS_URL}...`);
const provider = new WsProvider(WSS_URL);
const api = await ApiPromise.create({ provider });

console.log("Connected! Listing available pallets (modules):");

const pallets = Object.keys(api.tx).sort();
console.log("Pallets:", pallets.join(", "));

for (const pallet of pallets) {
if (pallet.toLowerCase().includes('provider') || pallet.toLowerCase().includes('file') || pallet.toLowerCase().includes('storage')) {
console.log(`\n--- Extrinsics for Module: ${pallet} ---`);
const methods = Object.keys(api.tx[pallet]).sort();
methods.forEach(method => {
console.log(` ${method}`);
});
}
}

// Also check query methods to confirm module names
console.log("\n--- Query Modules ---");
const queryModules = Object.keys(api.query).sort();
console.log(queryModules.join(", "));

await api.disconnect();
}

inspect().catch(console.error);
8 changes: 6 additions & 2 deletions agentkit-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,15 @@
"dependencies": {
"@0xgasless/smart-account": "latest",
"@langchain/core": "^0.3.40",
"@polkadot/api": "^16.5.4",
"@storagehub-sdk/core": "^0.4.0",
"@storagehub-sdk/msp-client": "^0.4.0",
"@storagehub/api-augment": "^0.2.14",
"axios": "^1.7.9",
"merkletreejs": "^0.4.1",
"sqlite3": "^5.1.7",
"viem": "2",
"zod": "^3.23.8",
"sqlite3": "^5.1.7"
"zod": "^3.23.8"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { z } from "zod";
import { ZeroXgaslessSmartAccount } from "@0xgasless/smart-account";
import { AgentkitAction } from "../../agentkit";
import { keccak256, toBytes } from "viem";

const CALCULATE_TOPIC_HASH_PROMPT = `
This tool calculates the Keccak256 hash of a given string (usually an event signature).
Useful for generating topic hashes for Chainlink CRE Log Triggers.

Required parameters:
- eventSignature: The event signature string (e.g., "ReportReceived(bytes32,address,string)").
`;

export const CalculateTopicHashInput = z
.object({
eventSignature: z.string().describe("The event signature to hash e.g. 'Transfer(address,address,uint256)'"),
})
.strip()
.describe("Instructions for calculating topic hash");

async function calculateTopicHash(
wallet: ZeroXgaslessSmartAccount,
args: z.infer<typeof CalculateTopicHashInput>,
): Promise<string> {
try {
const hash = keccak256(toBytes(args.eventSignature));
return `
Event Signature: ${args.eventSignature}
Topic Hash: ${hash}
`;
} catch (error: any) {
return `Error calculating hash: ${error.message}`;
}
}

export class CalculateTopicHashAction implements AgentkitAction<typeof CalculateTopicHashInput> {
public name = "calculate_topic_hash";
public description = CALCULATE_TOPIC_HASH_PROMPT;
public argsSchema = CalculateTopicHashInput;
public func = calculateTopicHash;
public smartAccountRequired = false;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { z } from "zod";
import { ZeroXgaslessSmartAccount } from "@0xgasless/smart-account";
import { AgentkitAction } from "../../agentkit";
import { CRE_DOCS_SUMMARY } from "../../utils/chainlinkConstants";

const CHAINLINK_DOCS_PROMPT = `
This tool provides documentation and context about Chainlink CRE (Compute Runtime Environment).
It is useful when you need to understand how triggers work, how to configure forwarders, or how to troubleshoot deployment issues.

Optional parameters:
- query: A specific keyword to search for in the docs (e.g., "forwarder", "trigger").
`;

export const ChainlinkDocsInput = z
.object({
query: z.string().optional().describe("Keyword to search for in the documentation"),
})
.strip()
.describe("Instructions for retrieving Chainlink CRE docs");

async function getChainlinkDocs(
wallet: ZeroXgaslessSmartAccount,
args: z.infer<typeof ChainlinkDocsInput>,
): Promise<string> {
try {
const docs = CRE_DOCS_SUMMARY;

if (args.query) {
const query = args.query.toLowerCase();
const lines = docs.split("\n");
const matchingLines = lines.filter((line) => line.toLowerCase().includes(query));

if (matchingLines.length > 0) {
return `Found ${matchingLines.length} matches for "${args.query}":\n\n${matchingLines.join("\n")}\n\n--- Full Summary ---\n${docs}`;
} else {
return `No specific matches found for "${args.query}". Here is the full summary:\n\n${docs}`;
}
}

return docs;
} catch (error: any) {
return `Error retrieving docs: ${error.message}`;
}
}

export class ChainlinkDocsAction implements AgentkitAction<typeof ChainlinkDocsInput> {
public name = "chainlink_cre_docs";
public description = CHAINLINK_DOCS_PROMPT;
public argsSchema = ChainlinkDocsInput;
public func = getChainlinkDocs;
// This action doesn't strictly need a smart account, but following the pattern
public smartAccountRequired = false;
}
Loading