Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/asDNSk/eliza into HEAD
Browse files Browse the repository at this point in the history
  • Loading branch information
lalalune committed Nov 29, 2024
2 parents 154fe3a + 53775cb commit 1aeaab2
Show file tree
Hide file tree
Showing 24 changed files with 1,860 additions and 1 deletion.
6 changes: 5 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,8 @@ WHATSAPP_ACCESS_TOKEN= # Permanent access token from Facebook Dev
WHATSAPP_PHONE_NUMBER_ID= # Phone number ID from WhatsApp Business API
WHATSAPP_BUSINESS_ACCOUNT_ID= # Business Account ID from Facebook Business Manager
WHATSAPP_WEBHOOK_VERIFY_TOKEN= # Custom string for webhook verification
WHATSAPP_API_VERSION=v17.0 # WhatsApp API version (default: v17.0)
WHATSAPP_API_VERSION=v17.0 # WhatsApp API version (default: v17.0)

# ICP
INTERNET_COMPUTER_PRIVATE_KEY=
INTERNET_COMPUTER_ADDRESS=
23 changes: 23 additions & 0 deletions packages/plugin-icp/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "@ai16z/plugin-icp",
"version": "0.0.1",
"main": "dist/index.js",
"type": "module",
"types": "dist/index.d.ts",
"dependencies": {
"@ai16z/eliza": "workspace:*",
"@dfinity/agent": "^2.1.3",
"@dfinity/candid": "^2.1.3",
"@dfinity/identity": "^2.1.3",
"@dfinity/principal": "^2.1.3"
},
"scripts": {
"build": "tsup --format esm --dts"
},
"devDependencies": {
"@types/jest": "29.5.14",
"jest": "29.7.0",
"tsup": "^8.3.5",
"typescript": "5.6.3"
}
}
182 changes: 182 additions & 0 deletions packages/plugin-icp/src/actions/createToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import { composeContext } from "@ai16z/eliza/src/context";
import { generateObject } from "@ai16z/eliza/src/generation";
import {
ActionExample,
HandlerCallback,
IAgentRuntime,
Memory,
ModelClass,
State,
type Action,
} from "@ai16z/eliza/src/types";
import { idlFactory } from "../canisters/pick-pump/index.did";
import { _SERVICE } from "../canisters/pick-pump/index.did.d";
import { ActorCreator, CreateMemeTokenArg } from "../types";
import { unwrapOption, wrapOption } from "../utils/common/types/options";
import { unwrapRustResultMap } from "../utils/common/types/results";
import { icpWalletProvider } from "../providers/wallet";

const createTokenTemplate = `Respond with a JSON markdown block containing only the extracted values. Use null for any values that cannot be determined.
Based on the user's description, generate appropriate values for a new token:
- Create a suitable token name
- Generate a 3-4 letter symbol based on the name
- Write a clear description
- Use "https://icptoken.default.logo" as default logo URL
- Set other fields to null
Example response:
\`\`\`json
{
"name": "My ICP Token",
"symbol": "MIT",
"description": "A fun meme token on ICP",
"logo": "https://icptoken.default.logo",
"website": null,
"twitter": null,
"telegram": null
}
\`\`\`
{{recentMessages}}
Generate appropriate token information based on the user's description.
Respond with a JSON markdown block containing only the generated values.`;

async function createTokenTransaction(
creator: ActorCreator,
tokenInfo: CreateMemeTokenArg
): Promise<any> {
const actor: _SERVICE = await creator(
idlFactory,
"bn4fo-iyaaa-aaaap-akp6a-cai"
);

const result = await actor.create_token({
...tokenInfo,
name: tokenInfo.name ?? "My ICP Token",
symbol: tokenInfo.symbol ?? "MIT",
description: tokenInfo.description ?? "A fun meme token on ICP",
logo: "https://icptoken.default.logo",
twitter: wrapOption(tokenInfo.twitter),
website: wrapOption(tokenInfo.website),
telegram: wrapOption(tokenInfo.telegram),
});

return unwrapRustResultMap(
result,
(ok) => ({
...ok,
twitter: unwrapOption(ok.twitter),
website: unwrapOption(ok.website),
telegram: unwrapOption(ok.telegram),
}),
(err) => {
throw new Error(`Token creation failed: ${err}`);
}
);
}

export const executeCreateToken: Action = {
name: "CREATE_TOKEN",
similes: ["CREATE_COIN", "MINT_TOKEN", "DEPLOY_TOKEN", "CREATE_ICP_TOKEN"],
validate: async (runtime: IAgentRuntime, message: Memory) => {
console.log("Message:", message);
return true;
},
description: "Create a new token on Internet Computer.",
handler: async (
runtime: IAgentRuntime,
message: Memory,
state: State,
_options: { [key: string]: unknown },
callback?: HandlerCallback
): Promise<boolean> => {
if (!state) {
state = (await runtime.composeState(message)) as State;
} else {
state = await runtime.updateRecentMessageState(state);
}

const createTokenContext = composeContext({
state,
template: createTokenTemplate,
});

const response = await generateObject({
runtime,
context: createTokenContext,
modelClass: ModelClass.LARGE,
});

console.log("Response:", response);

// Validate required fields
if (
!response.name ||
!response.symbol ||
!response.description ||
!response.logo
) {
const responseMsg = {
text: "I need the token name, symbol, description, and logo URL to create a token",
};
callback?.(responseMsg);
return true;
}

try {
const { wallet } = await icpWalletProvider.get(
runtime,
message,
state
);
const creator = wallet.createActor;
const createTokenResult = await createTokenTransaction(creator, {
name: response.name,
symbol: response.symbol,
description: response.description,
website: response.website,
twitter: response.twitter,
telegram: response.telegram,
});

console.log("Token created successfully:", createTokenResult);
const responseMsg = {
text: `Token ${response.name} (${response.symbol}) created successfully on ICP!`,
data: createTokenResult,
};

callback?.(responseMsg);
return true;
} catch (error) {
console.error("Error creating token:", error);
const responseMsg = {
text: `Failed to create token: ${error.message}`,
};
callback?.(responseMsg);
return false;
}
},
examples: [
[
{
user: "{{user1}}",
content: "I want to create a token for dog lovers",
},
{
user: "{{user2}}",
content: {
text: "Creating new ICP token WOOF...",
action: "CREATE_TOKEN",
},
},
{
user: "{{user2}}",
content: {
text: "Token created successfully on Internet Computer!",
},
},
],
] as ActionExample[][],
} as Action;
126 changes: 126 additions & 0 deletions packages/plugin-icp/src/canisters/pick-pump/index.did.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import type { Principal } from "@dfinity/principal";
import type { ActorMethod } from "@dfinity/agent";
import type { IDL } from "@dfinity/candid";

export interface Candle {
low: number;
high: number;
close: number;
open: number;
timestamp: bigint;
}
export interface Comment {
creator: string;
token: string;
content: string;
created_at: bigint;
image: [] | [string];
}
export interface CreateCommentArg {
token: string;
content: string;
image: [] | [string];
}
export interface CreateMemeTokenArg {
twitter: [] | [string];
logo: string;
name: string;
description: string;
website: [] | [string];
telegram: [] | [string];
symbol: string;
}
export interface Holder {
balance: bigint;
owner: string;
}
export interface InitArg {
fee_receiver: Principal;
create_token_fee: [] | [bigint];
icp_canister_id: Principal;
maintenance: boolean;
fee_percentage: [] | [number];
}
export interface MemeToken {
id: bigint;
creator: string;
available_token: bigint;
twitter: [] | [string];
volume_24h: bigint;
logo: string;
name: string;
liquidity: number;
description: string;
created_at: bigint;
website: [] | [string];
last_tx_time: bigint;
canister: [] | [string];
market_cap_icp: bigint;
market_cap_usd: number;
price: number;
telegram: [] | [string];
symbol: string;
}
export interface MemeTokenView {
token: MemeToken;
balance: bigint;
}
export type Result = { Ok: bigint } | { Err: string };
export type Result_1 = { Ok: MemeToken } | { Err: string };
export type Sort =
| { CreateTimeDsc: null }
| { LastTradeDsc: null }
| { MarketCapDsc: null };
export interface Transaction {
token_amount: bigint;
token_id: bigint;
token_symbol: string;
from: string;
timestamp: bigint;
icp_amount: bigint;
tx_type: string;
}
export interface User {
principal: string;
name: string;
last_login_seconds: bigint;
register_at_second: bigint;
avatar: string;
}
export interface WalletReceiveResult {
accepted: bigint;
}
export interface _SERVICE {
buy: ActorMethod<[bigint, number], Result>;
calculate_buy: ActorMethod<[bigint, number], Result>;
calculate_sell: ActorMethod<[bigint, number], Result>;
create_token: ActorMethod<[CreateMemeTokenArg], Result_1>;
king_of_hill: ActorMethod<[], [] | [MemeToken]>;
last_txs: ActorMethod<[bigint], Array<Transaction>>;
post_comment: ActorMethod<[CreateCommentArg], undefined>;
query_all_tokens: ActorMethod<
[bigint, bigint, [] | [Sort]],
[Array<MemeToken>, bigint]
>;
query_token: ActorMethod<[bigint], [] | [MemeToken]>;
query_token_candle: ActorMethod<[bigint, [] | [bigint]], Array<Candle>>;
query_token_comments: ActorMethod<
[Principal, bigint, bigint],
[Array<Comment>, bigint]
>;
query_token_holders: ActorMethod<
[bigint, bigint, bigint],
[Array<Holder>, bigint]
>;
query_token_transactions: ActorMethod<
[bigint, bigint, bigint],
[Array<Transaction>, bigint]
>;
query_user: ActorMethod<[[] | [Principal]], User>;
query_user_launched: ActorMethod<[[] | [Principal]], Array<MemeToken>>;
query_user_tokens: ActorMethod<[[] | [Principal]], Array<MemeTokenView>>;
sell: ActorMethod<[bigint, number], Result>;
wallet_balance: ActorMethod<[], bigint>;
wallet_receive: ActorMethod<[], WalletReceiveResult>;
}
export declare const idlFactory: IDL.InterfaceFactory;
Loading

0 comments on commit 1aeaab2

Please sign in to comment.