@coinfello/agent-cli 0.0.2 → 0.1.1
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/dist/index.js +117 -88
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import { toMetaMaskSmartAccount, Implementation, createDelegation } from "@metamask/smart-accounts-kit";
|
|
4
4
|
import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
|
|
5
|
-
import { createPublicClient, http } from "viem";
|
|
5
|
+
import { createPublicClient, http, serializeErc6492Signature } from "viem";
|
|
6
6
|
import * as chains from "viem/chains";
|
|
7
|
+
import { randomBytes } from "node:crypto";
|
|
7
8
|
import { readFile, mkdir, writeFile } from "node:fs/promises";
|
|
8
9
|
import { homedir } from "node:os";
|
|
9
10
|
import { join } from "node:path";
|
|
@@ -63,7 +64,8 @@ function createSubdelegation({
|
|
|
63
64
|
to: delegateAddress,
|
|
64
65
|
from: smartAccount.address,
|
|
65
66
|
parentDelegation,
|
|
66
|
-
environment: smartAccount.environment
|
|
67
|
+
environment: smartAccount.environment,
|
|
68
|
+
salt: `0x${randomBytes(32).toString("hex")}`
|
|
67
69
|
});
|
|
68
70
|
}
|
|
69
71
|
const CONFIG_DIR = join(homedir(), ".clawdbot", "skills", "coinfello");
|
|
@@ -2646,7 +2648,7 @@ async function loadSessionToken(token, url) {
|
|
|
2646
2648
|
await cookieJar.setCookie(`better-auth.session_token=${token}`, url);
|
|
2647
2649
|
await cookieJar.setCookie(`logged_in=true`, url);
|
|
2648
2650
|
}
|
|
2649
|
-
const BASE_URL = "https://
|
|
2651
|
+
const BASE_URL = process.env.COINFELLO_BASE_URL || "https://hyp3r-58q8qto10-hyperplay.vercel.app/";
|
|
2650
2652
|
const BASE_URL_V1 = BASE_URL + "api/v1";
|
|
2651
2653
|
async function getCoinFelloAddress() {
|
|
2652
2654
|
const response = await fetchWithCookies(`${BASE_URL_V1}/automation/coinfello-address`);
|
|
@@ -2669,7 +2671,10 @@ async function getCoinFelloAgents() {
|
|
|
2669
2671
|
}
|
|
2670
2672
|
async function sendConversation({
|
|
2671
2673
|
prompt,
|
|
2672
|
-
signedSubdelegation
|
|
2674
|
+
signedSubdelegation,
|
|
2675
|
+
chatId,
|
|
2676
|
+
delegationArguments,
|
|
2677
|
+
callId
|
|
2673
2678
|
}) {
|
|
2674
2679
|
const agents = await getCoinFelloAgents();
|
|
2675
2680
|
const body = {
|
|
@@ -2680,11 +2685,23 @@ async function sendConversation({
|
|
|
2680
2685
|
body.agentId = agents[0].id;
|
|
2681
2686
|
}
|
|
2682
2687
|
if (signedSubdelegation !== void 0) {
|
|
2683
|
-
body.
|
|
2688
|
+
body.clientToolCallResponse = {
|
|
2689
|
+
output: JSON.stringify({
|
|
2690
|
+
success: true,
|
|
2691
|
+
delegation: signedSubdelegation,
|
|
2692
|
+
chainId: delegationArguments ? JSON.parse(delegationArguments).chainId : void 0
|
|
2693
|
+
}),
|
|
2694
|
+
type: "function_call_output",
|
|
2695
|
+
callId,
|
|
2696
|
+
name: "ask_for_delegation",
|
|
2697
|
+
arguments: delegationArguments
|
|
2698
|
+
};
|
|
2699
|
+
}
|
|
2700
|
+
if (chatId) {
|
|
2701
|
+
body.chatId = chatId;
|
|
2684
2702
|
}
|
|
2685
|
-
const response = await fetchWithCookies(`${BASE_URL}
|
|
2703
|
+
const response = await fetchWithCookies(`${BASE_URL}api/conversation`, {
|
|
2686
2704
|
method: "POST",
|
|
2687
|
-
headers: { "Content-Type": "application/json" },
|
|
2688
2705
|
body: JSON.stringify(body)
|
|
2689
2706
|
});
|
|
2690
2707
|
if (!response.ok) {
|
|
@@ -3537,7 +3554,9 @@ async function signInWithAgent(baseUrl, config) {
|
|
|
3537
3554
|
throw new Error("SIWE verification returned success: false");
|
|
3538
3555
|
}
|
|
3539
3556
|
console.log("saving token...");
|
|
3540
|
-
|
|
3557
|
+
const cookies = await cookieJar.getCookies(baseUrl);
|
|
3558
|
+
const sessionCookie = cookies.find((c) => c.key === "better-auth.session_token");
|
|
3559
|
+
config.session_token = sessionCookie?.value ?? result.token;
|
|
3541
3560
|
await saveConfig(config);
|
|
3542
3561
|
return result;
|
|
3543
3562
|
}
|
|
@@ -3638,7 +3657,7 @@ program.command("get_account").description("Display the current smart account ad
|
|
|
3638
3657
|
program.command("sign_in").description("Sign in to a server using SIWE with your smart account").option(
|
|
3639
3658
|
"--base-url <baseUrl>",
|
|
3640
3659
|
"The server base URL override (e.g. https://api.example.com)",
|
|
3641
|
-
|
|
3660
|
+
`${BASE_URL}api/auth`
|
|
3642
3661
|
).action(async (opts) => {
|
|
3643
3662
|
try {
|
|
3644
3663
|
console.log("Signing in with smart account...");
|
|
@@ -3665,88 +3684,98 @@ program.command("set_delegation").description("Store a signed delegation (JSON)
|
|
|
3665
3684
|
process.exit(1);
|
|
3666
3685
|
}
|
|
3667
3686
|
});
|
|
3668
|
-
program.command("send_prompt").description("Send a prompt to CoinFello, creating a delegation if requested by the server").argument("<prompt>", "The prompt to send").
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
});
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
}
|
|
3706
|
-
const delegationToolCall = initialResponse.toolCalls?.find(
|
|
3707
|
-
(tc) => tc.name === "ask_for_delegation"
|
|
3708
|
-
);
|
|
3709
|
-
if (!delegationToolCall) {
|
|
3710
|
-
console.error("Error: No delegation request received from the server.");
|
|
3711
|
-
console.log("Response:", JSON.stringify(initialResponse, null, 2));
|
|
3712
|
-
process.exit(1);
|
|
3713
|
-
}
|
|
3714
|
-
const args = JSON.parse(delegationToolCall.arguments);
|
|
3715
|
-
console.log(`Delegation requested: scope=${args.scope.type}, chainId=${args.chainId}`);
|
|
3716
|
-
console.log("Fetching CoinFello delegate address...");
|
|
3717
|
-
const delegateAddress = await getCoinFelloAddress();
|
|
3718
|
-
console.log("Loading smart account...");
|
|
3719
|
-
const smartAccount = await getSmartAccount(config.private_key, args.chainId);
|
|
3720
|
-
const scope = parseScope(args.scope);
|
|
3721
|
-
console.log("Creating subdelegation...");
|
|
3722
|
-
const subdelegation = createSubdelegation({
|
|
3723
|
-
smartAccount,
|
|
3724
|
-
delegateAddress,
|
|
3725
|
-
parentDelegation: opts.useRedelegation ? config.delegation : void 0,
|
|
3726
|
-
scope
|
|
3727
|
-
});
|
|
3728
|
-
console.log("Signing subdelegation...");
|
|
3729
|
-
const signature = await smartAccount.signDelegation({
|
|
3730
|
-
delegation: subdelegation
|
|
3731
|
-
});
|
|
3732
|
-
const signedSubdelegation = { ...subdelegation, signature };
|
|
3733
|
-
console.log("Sending signed delegation...");
|
|
3734
|
-
const finalResponse = await sendConversation({
|
|
3735
|
-
prompt,
|
|
3736
|
-
signedSubdelegation
|
|
3737
|
-
});
|
|
3738
|
-
if (finalResponse.txn_id) {
|
|
3739
|
-
console.log("Transaction submitted successfully.");
|
|
3740
|
-
console.log(`Transaction ID: ${finalResponse.txn_id}`);
|
|
3741
|
-
} else {
|
|
3742
|
-
console.log("Response:", JSON.stringify(finalResponse, null, 2));
|
|
3743
|
-
}
|
|
3744
|
-
} catch (err) {
|
|
3745
|
-
console.error(`Failed to send prompt: ${err.message}`);
|
|
3687
|
+
program.command("send_prompt").description("Send a prompt to CoinFello, creating a delegation if requested by the server").argument("<prompt>", "The prompt to send").action(async (prompt) => {
|
|
3688
|
+
try {
|
|
3689
|
+
const config = await loadConfig();
|
|
3690
|
+
if (!config.private_key) {
|
|
3691
|
+
console.error("Error: No private key found in config. Run 'create_account' first.");
|
|
3692
|
+
process.exit(1);
|
|
3693
|
+
}
|
|
3694
|
+
if (!config.smart_account_address) {
|
|
3695
|
+
console.error("Error: No smart account found. Run 'create_account' first.");
|
|
3696
|
+
process.exit(1);
|
|
3697
|
+
}
|
|
3698
|
+
if (!config.chain) {
|
|
3699
|
+
console.error("Error: No chain found in config. Run 'create_account' first.");
|
|
3700
|
+
process.exit(1);
|
|
3701
|
+
}
|
|
3702
|
+
if (config.session_token) {
|
|
3703
|
+
await loadSessionToken(config.session_token, BASE_URL_V1);
|
|
3704
|
+
}
|
|
3705
|
+
console.log("Sending prompt...");
|
|
3706
|
+
const initialResponse = await sendConversation({
|
|
3707
|
+
prompt
|
|
3708
|
+
});
|
|
3709
|
+
if (!initialResponse.clientToolCalls?.length && !initialResponse.txn_id) {
|
|
3710
|
+
console.log(initialResponse.responseText ?? "");
|
|
3711
|
+
return;
|
|
3712
|
+
}
|
|
3713
|
+
if (initialResponse.txn_id && !initialResponse.clientToolCalls?.length) {
|
|
3714
|
+
console.log("Transaction submitted successfully.");
|
|
3715
|
+
console.log(`Transaction ID: ${initialResponse.txn_id}`);
|
|
3716
|
+
return;
|
|
3717
|
+
}
|
|
3718
|
+
const delegationToolCall = initialResponse.clientToolCalls?.find(
|
|
3719
|
+
(tc) => tc.name === "ask_for_delegation"
|
|
3720
|
+
);
|
|
3721
|
+
if (!delegationToolCall) {
|
|
3722
|
+
console.error("Error: No delegation request received from the server.");
|
|
3723
|
+
console.log("Response:", JSON.stringify(initialResponse, null, 2));
|
|
3746
3724
|
process.exit(1);
|
|
3747
3725
|
}
|
|
3726
|
+
const args = JSON.parse(delegationToolCall.arguments);
|
|
3727
|
+
console.log(`Delegation requested: scope=${args.scope.type}, chainId=${args.chainId}`);
|
|
3728
|
+
console.log("Fetching CoinFello delegate address...");
|
|
3729
|
+
const delegateAddress = await getCoinFelloAddress();
|
|
3730
|
+
console.log("Loading smart account...");
|
|
3731
|
+
const smartAccount = await getSmartAccount(config.private_key, args.chainId);
|
|
3732
|
+
const scope = parseScope(args.scope);
|
|
3733
|
+
console.log("Creating subdelegation...");
|
|
3734
|
+
const subdelegation = createSubdelegation({
|
|
3735
|
+
smartAccount,
|
|
3736
|
+
delegateAddress,
|
|
3737
|
+
scope
|
|
3738
|
+
});
|
|
3739
|
+
console.log("Signing subdelegation...");
|
|
3740
|
+
const signature = await smartAccount.signDelegation({
|
|
3741
|
+
delegation: subdelegation
|
|
3742
|
+
});
|
|
3743
|
+
let sig = signature;
|
|
3744
|
+
const chain = resolveChainInput(config.chain);
|
|
3745
|
+
const publicClient = createPublicClient({
|
|
3746
|
+
chain,
|
|
3747
|
+
transport: http()
|
|
3748
|
+
});
|
|
3749
|
+
const code = await publicClient.getCode({ address: smartAccount.address });
|
|
3750
|
+
const isDeployed = !!(code && code !== "0x");
|
|
3751
|
+
if (!isDeployed) {
|
|
3752
|
+
const factoryArgs = await smartAccount.getFactoryArgs();
|
|
3753
|
+
sig = serializeErc6492Signature({
|
|
3754
|
+
signature,
|
|
3755
|
+
address: factoryArgs.factory,
|
|
3756
|
+
data: factoryArgs.factoryData
|
|
3757
|
+
});
|
|
3758
|
+
}
|
|
3759
|
+
const signedSubdelegation = { ...subdelegation, signature: sig };
|
|
3760
|
+
console.log("Sending signed delegation...");
|
|
3761
|
+
const finalResponse = await sendConversation({
|
|
3762
|
+
prompt: "Please refer to the previous conversation messages and redeem this delegation.",
|
|
3763
|
+
signedSubdelegation,
|
|
3764
|
+
chatId: initialResponse.chatId,
|
|
3765
|
+
delegationArguments: JSON.stringify(args),
|
|
3766
|
+
callId: delegationToolCall.callId
|
|
3767
|
+
});
|
|
3768
|
+
if (finalResponse.txn_id) {
|
|
3769
|
+
console.log("Transaction submitted successfully.");
|
|
3770
|
+
console.log(`Transaction ID: ${finalResponse.txn_id}`);
|
|
3771
|
+
} else {
|
|
3772
|
+
console.log("Final Response:", JSON.stringify(finalResponse, null, 2));
|
|
3773
|
+
}
|
|
3774
|
+
} catch (err) {
|
|
3775
|
+
console.error(`Failed to send prompt: ${err.message}`);
|
|
3776
|
+
process.exit(1);
|
|
3748
3777
|
}
|
|
3749
|
-
);
|
|
3778
|
+
});
|
|
3750
3779
|
program.command("get_transaction_status").description("Check the status of a submitted transaction").argument("<txn_id>", "The transaction ID to check").action(async (txnId) => {
|
|
3751
3780
|
try {
|
|
3752
3781
|
const result = await getTransactionStatus(txnId);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coinfello/agent-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/node": "^25.2.1",
|
|
27
|
+
"dotenv": "^17.3.1",
|
|
27
28
|
"eslint": "^10.0.0",
|
|
28
29
|
"eslint-config-prettier": "^10.1.8",
|
|
29
30
|
"prettier": "^3.8.1",
|