Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add evm provider #6

Closed
wants to merge 2 commits into from
Closed
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
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"ajv": "^8.17.1",
"chromadb": "^1.9.4",
"chromadb-default-embed": "^2.13.2",
"ethers": "^6.13.5",
"openai": "^4.76.0",
"starknet": "^6.11.0",
"uuid": "^11.0.3",
Expand Down
54 changes: 53 additions & 1 deletion packages/core/src/core/providers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Account, type Call, CallData, RpcProvider } from "starknet";
import { env } from "./env";

import type { CoTTransaction } from "../types";
import { ethers } from "ethers";
interface GraphQLResponse<T> {
data?: T;
errors?: Array<{
Expand Down Expand Up @@ -82,3 +83,54 @@ export const executeStarknetTransaction = async (call: Call): Promise<any> => {
return error instanceof Error ? error : new Error("Unknown error occurred");
}
};

export interface EvmTransaction extends CoTTransaction {
network: "evm";
method: string;
value?: string;
gasLimit?: string;
}

export async function executeEvmTransaction(
transaction: EvmTransaction
): Promise<any> {
try {
// Initialize provider (customize based on your needs)
const provider = new ethers.JsonRpcProvider(process.env.EVM_RPC_URL);

// Initialize wallet/signer
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
Comment on lines +98 to +102
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add environment variable validation.

The code assumes environment variables will be present without validation.

Add validation before using environment variables:

-    const provider = new ethers.JsonRpcProvider(process.env.EVM_RPC_URL);
-    const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
+    const rpcUrl = process.env.EVM_RPC_URL;
+    const privateKey = process.env.PRIVATE_KEY;
+    
+    if (!rpcUrl || !privateKey) {
+      throw new Error('Missing required environment variables: EVM_RPC_URL or PRIVATE_KEY');
+    }
+    
+    const provider = new ethers.JsonRpcProvider(rpcUrl);
+    const wallet = new ethers.Wallet(privateKey, provider);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Initialize provider (customize based on your needs)
const provider = new ethers.JsonRpcProvider(process.env.EVM_RPC_URL);
// Initialize wallet/signer
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
// Initialize provider (customize based on your needs)
const rpcUrl = process.env.EVM_RPC_URL;
const privateKey = process.env.PRIVATE_KEY;
if (!rpcUrl || !privateKey) {
throw new Error('Missing required environment variables: EVM_RPC_URL or PRIVATE_KEY');
}
const provider = new ethers.JsonRpcProvider(rpcUrl);
const wallet = new ethers.Wallet(privateKey, provider);


// Create contract instance
if (!transaction.abi) {
throw new Error('Contract ABI is required');
}

const contract = new ethers.Contract(
transaction.contractAddress,
transaction.abi,
wallet
);

if (!contract[transaction.method]) {
throw new Error(`Method ${transaction.method} not found in contract ABI`);
}

// Prepare transaction options
const txOptions = {
value: BigInt(transaction.value || "0"),
gasLimit: BigInt(transaction.gasLimit || "0"),
};
Comment on lines +120 to +123
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Improve gas limit handling.

The current implementation might lead to transaction failures if gas limit is not properly set.

Consider these improvements:

  1. Add gas estimation
  2. Validate gas limit values
  3. Handle potential out-of-gas scenarios
-    const txOptions = {
-      value: BigInt(transaction.value || "0"),
-      gasLimit: BigInt(transaction.gasLimit || "0"),
-    };
+    const txOptions: ethers.ContractTransactionRequest = {
+      value: BigInt(transaction.value || "0"),
+    };
+
+    if (transaction.gasLimit) {
+      txOptions.gasLimit = BigInt(transaction.gasLimit);
+    } else {
+      // Estimate gas if not provided
+      try {
+        txOptions.gasLimit = await contract[transaction.method].estimateGas(
+          ...transaction.calldata,
+          { value: txOptions.value }
+        );
+      } catch (error) {
+        throw new Error(`Gas estimation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
+      }
+    }

Committable suggestion skipped: line range outside the PR's diff.


// Execute transaction
const tx = await contract[transaction.method](
...transaction.calldata,
txOptions
);
const receipt = await tx.wait();

return receipt;
Comment on lines +126 to +132
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance transaction execution and receipt handling.

The current implementation lacks proper transaction monitoring and receipt validation.

Consider these improvements:

  1. Add transaction confirmation blocks
  2. Validate transaction receipt
  3. Handle revert reasons
-    const tx = await contract[transaction.method](
-      ...transaction.calldata,
-      txOptions
-    );
-    const receipt = await tx.wait();
-
-    return receipt;
+    try {
+      const tx = await contract[transaction.method](
+        ...transaction.calldata,
+        txOptions
+      );
+      
+      // Wait for 2 confirmations
+      const receipt = await tx.wait(2);
+      
+      if (!receipt.status) {
+        throw new Error('Transaction failed');
+      }
+      
+      return receipt;
+    } catch (error: any) {
+      // Handle revert reasons
+      if (error.data) {
+        throw new Error(`Transaction reverted: ${error.data}`);
+      }
+      throw error;
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const tx = await contract[transaction.method](
...transaction.calldata,
txOptions
);
const receipt = await tx.wait();
return receipt;
try {
const tx = await contract[transaction.method](
...transaction.calldata,
txOptions
);
// Wait for 2 confirmations
const receipt = await tx.wait(2);
if (!receipt.status) {
throw new Error('Transaction failed');
}
return receipt;
} catch (error: any) {
// Handle revert reasons
if (error.data) {
throw new Error(`Transaction reverted: ${error.data}`);
}
throw error;
}

} catch (error) {
return error instanceof Error ? error : new Error("Unknown error occurred");
}
Comment on lines +133 to +135
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error handling specificity.

The current error handling loses valuable information by converting all errors to a generic message. Consider handling specific error types differently.

   } catch (error) {
-    return error instanceof Error ? error : new Error("Unknown error occurred");
+    if (error instanceof ethers.ContractTransactionExecutionError) {
+      return new Error(`Transaction execution failed: ${error.message}`);
+    } else if (error instanceof ethers.ContractTransactionRevertedError) {
+      return new Error(`Transaction reverted: ${error.message}`);
+    } else if (error instanceof ethers.ProviderError) {
+      return new Error(`Provider error: ${error.message}`);
+    } else {
+      return error instanceof Error ? error : new Error("Unknown error occurred");
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (error) {
return error instanceof Error ? error : new Error("Unknown error occurred");
}
} catch (error) {
if (error instanceof ethers.ContractTransactionExecutionError) {
return new Error(`Transaction execution failed: ${error.message}`);
} else if (error instanceof ethers.ContractTransactionRevertedError) {
return new Error(`Transaction reverted: ${error.message}`);
} else if (error instanceof ethers.ProviderError) {
return new Error(`Provider error: ${error.message}`);
} else {
return error instanceof Error ? error : new Error("Unknown error occurred");
}
}

}
74 changes: 74 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Daydreams

Daydreams is a generative agent library for playing anything onchain. It is chain agnostic and can be used to play any onchain game by simply injecting context. Base, Solana, Ethereum, Starknet, etc.
Daydreams is a generative agent library for playing anything onchain. It is chain agnostic and can be used to play anything onchain by simply injecting context. Base, Solana, Ethereum, Starknet, etc.

You can drop daydreams into Eliza or any typescript agent framework via their plugin system.

Expand Down
Loading