@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.
Files changed (2) hide show
  1. package/dist/index.js +117 -88
  2. 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://app.coinfello.com/";
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.signed_subdelegation = signedSubdelegation;
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}/api/conversation`, {
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
- config.session_token = result.token;
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
- "https://app.coinfello.com/api/auth"
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").option("--use-redelegation", "Create a redelegation from a stored parent delegation").action(
3669
- async (prompt, opts) => {
3670
- try {
3671
- const config = await loadConfig();
3672
- if (!config.private_key) {
3673
- console.error("Error: No private key found in config. Run 'create_account' first.");
3674
- process.exit(1);
3675
- }
3676
- if (!config.smart_account_address) {
3677
- console.error("Error: No smart account found. Run 'create_account' first.");
3678
- process.exit(1);
3679
- }
3680
- if (!config.chain) {
3681
- console.error("Error: No chain found in config. Run 'create_account' first.");
3682
- process.exit(1);
3683
- }
3684
- if (opts.useRedelegation && !config.delegation) {
3685
- console.error(
3686
- "Error: --use-redelegation requires a parent delegation. Run 'set_delegation' first."
3687
- );
3688
- process.exit(1);
3689
- }
3690
- if (config.session_token) {
3691
- await loadSessionToken(config.session_token, BASE_URL_V1);
3692
- }
3693
- console.log("Sending prompt...");
3694
- const initialResponse = await sendConversation({
3695
- prompt
3696
- });
3697
- if (!initialResponse.toolCalls?.length && !initialResponse.txn_id) {
3698
- console.log(initialResponse.responseText ?? "");
3699
- return;
3700
- }
3701
- if (initialResponse.txn_id && !initialResponse.toolCalls?.length) {
3702
- console.log("Transaction submitted successfully.");
3703
- console.log(`Transaction ID: ${initialResponse.txn_id}`);
3704
- return;
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.0.2",
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",