Skip to content

Commit

Permalink
feat: add Arthera plugin from EVM plugin model
Browse files Browse the repository at this point in the history
feat: rename plugin from EVM to Arthera and update README

feat: remove bridge and swap actions from Arthera plugin

feat: update transfer examples and templates to use AA instead of ETH

feat: update viem dependency to version 2.21.58 and adjust pnpm-lock.yaml

feat: remove unused LiFi dependencies and clean up type definitions in Arthera plugin

feat: remove bridge actions and templates from Arthera plugin

feat: remove swap actions and templates from Arthera plugin

feat: update EVM naming to Arthera

feat: update README and types for Arthera mainnet integration

feat: update plugin to use Arthera instead of mainnet

fix: add required devDependencies

fix: remove switchChain

fix: update _options type to Record<string, unknown> in transferAction

fix: correct log message format in transfer action to include wallet client address

test: enhance transfer tests with additional wallet provider and address validation

Plugin arthera merge (#3)

* feat: added arthera to default character and agent

* feat: renamed EVM_PRIVATE_KEY by ARTHERA_PRIVATE_KEY

* fix: roll back core package

* fix: workspace: version

---------

Co-authored-by: Arthera Node <[email protected]>

fix: run transfer test only if private key provided

fix: add missing newline at end of package.json and tsconfig.json files
  • Loading branch information
bertux committed Jan 5, 2025
1 parent 472eca8 commit 401f6fd
Show file tree
Hide file tree
Showing 16 changed files with 1,016 additions and 62 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ EVM_PROVIDER_URL=
AVALANCHE_PRIVATE_KEY=
AVALANCHE_PUBLIC_KEY=

# Arthera
ARTHERA_PRIVATE_KEY=

# Solana
SOLANA_PRIVATE_KEY=
SOLANA_PUBLIC_KEY=
Expand Down
1 change: 1 addition & 0 deletions agent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"@elizaos/plugin-fuel": "workspace:*",
"@elizaos/plugin-avalanche": "workspace:*",
"@elizaos/plugin-web-search": "workspace:*",
"@elizaos/plugin-arthera": "workspace:*",
"readline": "1.3.0",
"ws": "8.18.0",
"yargs": "17.7.2"
Expand Down
4 changes: 4 additions & 0 deletions agent/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import { abstractPlugin } from "@elizaos/plugin-abstract";
import { avalanchePlugin } from "@elizaos/plugin-avalanche";
import { webSearchPlugin } from "@elizaos/plugin-web-search";
import { echoChamberPlugin } from "@elizaos/plugin-echochambers";
import { artheraPlugin } from "@elizaos/plugin-arthera";
import Database from "better-sqlite3";
import fs from "fs";
import path from "path";
Expand Down Expand Up @@ -609,6 +610,9 @@ export async function createAgent(
getSecret(character, "ECHOCHAMBERS_API_KEY")
? echoChamberPlugin
: null,
getSecret(character, "ARTHERA_PRIVATE_KEY")?.startsWith("0x")
? artheraPlugin
: null,
].filter(Boolean),
providers: [],
actions: [],
Expand Down
68 changes: 68 additions & 0 deletions packages/plugin-arthera/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# `@elizaos/plugin-arthera`

This plugin provides actions and providers for interacting with Arthera.

---

## Configuration

### Default Setup

By default, **Arthera** is enabled. To use it, simply add your private key to the `.env` file:

```env
ARTHERA_PRIVATE_KEY=your-private-key-here
```

### Custom RPC URLs

By default, the RPC URL is inferred from the `viem/chains` config. To use a custom RPC URL for a specific chain, add the following to your `.env` file:

```env
ETHEREUM_PROVIDER_<CHAIN_NAME>=https://your-custom-rpc-url
```

**Example usage:**

```env
ETHEREUM_PROVIDER_ARTHERA=https://rpc.arthera.net
```

## Provider

The **Wallet Provider** initializes with Arthera. It:

- Provides the **context** of the currently connected address and its balance.
- Creates **Public** and **Wallet clients** to interact with the supported chain.

---

## Actions

### Transfer

Transfer tokens from one address to another on Arthera. Just specify the:

- **Amount**
- **Chain**
- **Recipient Address**

**Example usage:**

```bash
Transfer 1 AA to 0xRecipient on arthera.
```

---

## Contribution

The plugin contains tests. Whether you're using **TDD** or not, please make sure to run the tests before submitting a PR.

### Running Tests

Navigate to the `plugin-arthera` directory and run:

```bash
pnpm test
```
3 changes: 3 additions & 0 deletions packages/plugin-arthera/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import eslintGlobalConfig from "../../eslint.config.mjs";

export default [...eslintGlobalConfig];
24 changes: 24 additions & 0 deletions packages/plugin-arthera/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "@elizaos/plugin-arthera",
"version": "0.1.7-alpha.2",
"main": "dist/index.js",
"type": "module",
"types": "dist/index.d.ts",
"dependencies": {
"@elizaos/core": "workspace:*",
"tsup": "8.3.5",
"viem": "2.21.58"
},
"scripts": {
"build": "tsup --format esm --dts",
"dev": "tsup --format esm --dts --watch",
"test": "vitest run",
"lint": "eslint --fix --cache ."
},
"devDependencies": {
"whatwg-url": "7.1.0"
},
"peerDependencies": {
"whatwg-url": "7.1.0"
}
}
176 changes: 176 additions & 0 deletions packages/plugin-arthera/src/actions/transfer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import { ByteArray, formatEther, parseEther, type Hex } from "viem";
import {
composeContext,
generateObjectDeprecated,
HandlerCallback,
ModelClass,
type IAgentRuntime,
type Memory,
type State,
} from "@elizaos/core";

import { initWalletProvider, WalletProvider } from "../providers/wallet";
import type { Transaction, TransferParams } from "../types";
import { transferTemplate } from "../templates";

export { transferTemplate };

// Exported for tests
export class TransferAction {
constructor(private walletProvider: WalletProvider) {}

async transfer(params: TransferParams): Promise<Transaction> {
const walletClient = this.walletProvider.getWalletClient(
params.fromChain
);

console.log(
`Transferring: ${params.amount} tokens from (${walletClient.account.address} to (${params.toAddress} on ${params.fromChain})`
);

if (!params.data) {
params.data = "0x";
}

try {
const hash = await walletClient.sendTransaction({
account: walletClient.account,
to: params.toAddress,
value: parseEther(params.amount),
data: params.data as Hex,
kzg: {
blobToKzgCommitment: function (_: ByteArray): ByteArray {
throw new Error("Function not implemented.");
},
computeBlobKzgProof: function (
_blob: ByteArray,
_commitment: ByteArray
): ByteArray {
throw new Error("Function not implemented.");
},
},
chain: undefined,
});

return {
hash,
from: walletClient.account.address,
to: params.toAddress,
value: parseEther(params.amount),
data: params.data as Hex,
};
} catch (error) {
throw new Error(`Transfer failed: ${error.message}`);
}
}
}

const buildTransferDetails = async (
state: State,
runtime: IAgentRuntime,
wp: WalletProvider
): Promise<TransferParams> => {
const context = composeContext({
state,
template: transferTemplate,
});

const chains = Object.keys(wp.chains);

const contextWithChains = context.replace(
"SUPPORTED_CHAINS",
chains.map((item) => `"${item}"`).join("|")
);

const transferDetails = (await generateObjectDeprecated({
runtime,
context: contextWithChains,
modelClass: ModelClass.SMALL,
})) as TransferParams;

const existingChain = wp.chains[transferDetails.fromChain];

if (!existingChain) {
throw new Error(
"The chain " +
transferDetails.fromChain +
" not configured yet. Add the chain or choose one from configured: " +
chains.toString()
);
}

return transferDetails;
};

export const transferAction = {
name: "transfer",
description: "Transfer tokens between addresses on the same chain",
handler: async (
runtime: IAgentRuntime,
_message: Memory,
state: State,
_options: Record<string, unknown>,
callback?: HandlerCallback
) => {
console.log("Transfer action handler called");
const walletProvider = initWalletProvider(runtime);
const action = new TransferAction(walletProvider);

// Compose transfer context
const paramOptions = await buildTransferDetails(
state,
runtime,
walletProvider
);

try {
const transferResp = await action.transfer(paramOptions);
if (callback) {
callback({
text: `Successfully transferred ${paramOptions.amount} tokens to ${paramOptions.toAddress}\nTransaction Hash: ${transferResp.hash}`,
content: {
success: true,
hash: transferResp.hash,
amount: formatEther(transferResp.value),
recipient: transferResp.to,
chain: paramOptions.fromChain,
},
});
}
return true;
} catch (error) {
console.error("Error during token transfer:", error);
if (callback) {
callback({
text: `Error transferring tokens: ${error.message}`,
content: { error: error.message },
});
}
return false;
}
},
template: transferTemplate,
validate: async (runtime: IAgentRuntime) => {
const privateKey = runtime.getSetting("ARTHERA_PRIVATE_KEY");
return typeof privateKey === "string" && privateKey.startsWith("0x");
},
examples: [
[
{
user: "assistant",
content: {
text: "I'll help you transfer 1 AA to 0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
action: "SEND_TOKENS",
},
},
{
user: "user",
content: {
text: "Transfer 1 AA to 0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
action: "SEND_TOKENS",
},
},
],
],
similes: ["SEND_TOKENS", "TOKEN_TRANSFER", "MOVE_TOKENS"],
};
18 changes: 18 additions & 0 deletions packages/plugin-arthera/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export * from "./actions/transfer";
export * from "./providers/wallet";
export * from "./types";

import type { Plugin } from "@elizaos/core";
import { transferAction } from "./actions/transfer";
import { artheraWalletProvider } from "./providers/wallet";

export const artheraPlugin: Plugin = {
name: "arthera",
description: "Arthera blockchain integration plugin",
providers: [artheraWalletProvider],
evaluators: [],
services: [],
actions: [transferAction],
};

export default artheraPlugin;
Loading

0 comments on commit 401f6fd

Please sign in to comment.