Skip to content

Commit

Permalink
feat: Response friendly
Browse files Browse the repository at this point in the history
  • Loading branch information
ybgbob committed Jan 23, 2025
1 parent 8546c97 commit 9575341
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 69 deletions.
152 changes: 89 additions & 63 deletions packages/plugin-bnb/src/actions/gnfd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ import {
import { readFileSync, statSync } from "fs";
import { lookup } from "mime-types";
import { extname } from "node:path";
import { CONFIG, InitGnfdClient } from "../providers/gnfd";
import { CONFIG, getGnfdConfig, InitGnfdClient } from "../providers/gnfd";
import { initWalletProvider, WalletProvider } from "../providers/wallet";
import { greenfieldTemplate } from "../templates";
import { DelegatedPubObjectRequest } from "@bnb-chain/greenfield-js-sdk";
import { SupportedChain } from "../types";
import { CROSS_CHAIN_ABI } from "../abi/CrossChainAbi";
import { TOKENHUB_ABI } from "../abi/TokenHubAbi";
import { stringToHex } from "viem";

export { greenfieldTemplate };

Expand Down Expand Up @@ -66,13 +67,14 @@ export class GreenfieldAction {
return selectSpInfo;
}

async bnbTransferToGnfd(amount: bigint, chain: SupportedChain) {
async bnbTransferToGnfd(amount: bigint, runtime: IAgentRuntime) {
const config = await getGnfdConfig(runtime)

const chain: SupportedChain = config.NETWORK === 'TESTNET' ? 'bscTestnet' : 'bsc'
this.walletProvider.switchChain(chain);
const publicClient = this.walletProvider.getPublicClient(chain);
const walletClient = this.walletProvider.getWalletClient(chain);

const config = chain === "bsc" ? CONFIG["MAINNET"] : CONFIG["TESTNET"];

const [relayFee, ackRelayFee] = await publicClient.readContract({
address: config.CROSSCHAIN_ADDRESS as `0x${string}`,
abi: CROSS_CHAIN_ABI,
Expand Down Expand Up @@ -123,6 +125,11 @@ export class GreenfieldAction {
return createBucketTxRes.transactionHash;
}

async headBucket(bucketName: string) {
const {bucketInfo} = await this.gnfdClient.bucket.headBucket(bucketName)
return bucketInfo.id;
}

async uploadObject(msg: DelegatedPubObjectRequest) {
const uploadRes = await this.gnfdClient.object.delegateUploadObject(
msg,
Expand All @@ -137,6 +144,11 @@ export class GreenfieldAction {
return uploadRes.message;
}

async headObject(bucketName: string, objectName: string) {
const {objectInfo} = await this.gnfdClient.object.headObject(bucketName, objectName);
return objectInfo.id;
}

async deleteObject(msg: MsgDeleteObject) {
const deleteObjectTx = await this.gnfdClient.object.deleteObject(msg);

Expand Down Expand Up @@ -194,11 +206,11 @@ export const greenfieldAction = {

elizaLogger.log("content", content);

const config = await getGnfdConfig(runtime)
const gnfdClient = await InitGnfdClient(runtime);
const walletProvider = initWalletProvider(runtime);
const action = new GreenfieldAction(walletProvider, gnfdClient);

let result;
const actionType = content.actionType;
const spInfo = await action.selectSp();

Expand All @@ -207,71 +219,81 @@ export const greenfieldAction = {
const { bucketName, objectName } = content;
const attachments = message.content.attachments;

switch (actionType) {
case "createBucket": {
const hash = await action.createBucket({
bucketName: bucketName,
creator: walletProvider.account.address,
visibility: VisibilityType.VISIBILITY_TYPE_PUBLIC_READ,
chargedReadQuota: Long.fromString("0"),
paymentAddress: walletProvider.account.address,
primarySpAddress: spInfo.primarySpAddress,
});
result = `create bucket successfully, hash: ${hash}`;
break;
}

case "uploadObject": {
if (!attachments) {
throw new Error("no file to upload");
try {
let result = '';
switch (actionType) {
case "createBucket": {
const msg = {
bucketName: bucketName,
creator: walletProvider.account.address,
visibility: VisibilityType.VISIBILITY_TYPE_PUBLIC_READ,
chargedReadQuota: Long.fromString("0"),
paymentAddress: walletProvider.account.address,
primarySpAddress: spInfo.primarySpAddress,
}
const hash = await action.createBucket(msg);
const bucketId = await action.headBucket(msg.bucketName)
result = `create bucket successfully, details: ${config.GREENFIELD_SCAN}/bucket/${toHex(bucketId)}`;
break;
}

const uploadObjName = objectName;
case "uploadObject": {
if (!attachments) {
throw new Error("no file to upload");
}

const uploadObjName = objectName;

await action.uploadObject({
bucketName,
objectName: uploadObjName,
body: generateFile(attachments[0]),
delegatedOpts: {
visibility: VisibilityType.VISIBILITY_TYPE_PUBLIC_READ,
},
});

const objectId = await action.headObject(bucketName, objectName)

if (attachments.length > 1) {
result += `Only one object can be uploaded. \n`;
}
result += `Upload object (${uploadObjName}) successfully, details: ${config.GREENFIELD_SCAN}/object/${toHex(objectId)}`;
break;
}

await action.uploadObject({
bucketName,
objectName: uploadObjName,
body: generateFile(attachments[0]),
delegatedOpts: {
visibility: VisibilityType.VISIBILITY_TYPE_PUBLIC_READ,
},
});
case "deleteObject": {
const hash = await action.deleteObject({
bucketName,
objectName,
operator: walletProvider.account.address,
});
result = `delete object successfully, hash: 0x${hash}`;
break;
}

if (attachments.length > 1) {
result += `Only one object can be uploaded. \n`;
case "transfer": {
const hash = await action.bnbTransferToGnfd(content.content, runtime)
result = `transfer bnb to greenfield successfully, hash: ${hash}`;
break;
}
result += `Upload object successfully, name: ${uploadObjName}`;
break;
}

case "deleteObject": {
const hash = await action.deleteObject({
bucketName,
objectName,
operator: walletProvider.account.address,
if (result) {
callback?.({
text: result,
});
} else {
callback?.({
text: `Unsuccessfully ${actionType || ''}`,
content: result,
});
result = `delete object successfully, hash: ${hash}`;
break;
}
}

if (result) {
callback?.({
text: result,
});
} else {
callback?.({
text: `Unsuccessfully ${actionType}`,
content: { ...result },
});
}

try {
return true;
} catch (error) {
elizaLogger.error("Error in get balance:", error.message);
} catch (error) {
elizaLogger.error("Error execute greenfield action:", error.message);
callback?.({
text: `Getting balance failed`,
text: `Bridge failed: ${error.message}`,
content: { error: error.message },
});
return false;
Expand All @@ -286,28 +308,28 @@ export const greenfieldAction = {
{
user: "user",
content: {
text: "Create a bucket on greenfield",
text: "Create a bucket(${bucketName}) on greenfield",
action: "GREENFIELD_ACTION",
},
},
{
user: "user",
content: {
text: "Upload a object on greenfield",
text: "Upload a object(${objectName}) in bucket(${bucketName}) on greenfield",
action: "GREENFIELD_ACTION",
},
},
{
user: "user",
content: {
text: "Delete object on greenfield",
text: "Delete object(${objectName}) in bucket(${bucketName}) on greenfield",
action: "GREENFIELD_ACTION",
},
},
{
user: "user",
content: {
text: "Transfer bnb to greenfield",
text: "for create account on greenfield, transfer ${amount} BNB to myself",
action: "GREENFIELD_ACTION",
},
},
Expand Down Expand Up @@ -345,3 +367,7 @@ function generateFile(attachment: Media) {
function fixPath(url: string) {
return url.replace("/agent/agent/", "/agent/");
}

function toHex(n: string) {
return "0x" + Number(n).toString(16).padStart(64, '0');
}
14 changes: 11 additions & 3 deletions packages/plugin-bnb/src/providers/gnfd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ import { IAgentRuntime } from "@elizaos/core";
const require = createRequire(import.meta.url);
const { Client } = require("@bnb-chain/greenfield-js-sdk");

export const InitGnfdClient = async (runtime: IAgentRuntime) => {
export const getGnfdConfig = async (runtime: IAgentRuntime) => {
const network = runtime.getSetting("GREENFIELD_NETWORK");

const config =
network === "TESTNET" ? CONFIG["TESTNET"] : CONFIG["MAINNET"];
network === "TESTNET" ? CONFIG["TESTNET"] : CONFIG["MAINNET"];

return config
}

export const InitGnfdClient = async (runtime: IAgentRuntime) => {
const config = await getGnfdConfig(runtime)
if (!config.GREENFIELD_CHAIN_ID || !config.GREENFIELD_CHAIN_ID) {
throw new Error("Creating greenfield client params is error");
}
Expand All @@ -24,16 +28,20 @@ export const InitGnfdClient = async (runtime: IAgentRuntime) => {

export const CONFIG = {
MAINNET: {
NETWORK: "MAINNET",
TOKENHUB_ADDRESS: "0xeA97dF87E6c7F68C9f95A69dA79E19B834823F25",
CROSSCHAIN_ADDRESS: "0x77e719b714be09F70D484AB81F70D02B0E182f7d",
GREENFIELD_RPC_URL: "https://greenfield-chain.bnbchain.org",
GREENFIELD_CHAIN_ID: "1017",
GREENFIELD_SCAN: 'https://greenfieldscan.com'
},
TESTNET: {
NETWORK: "TESTNET",
TOKENHUB_ADDRESS: "0xED8e5C546F84442219A5a987EE1D820698528E04",
CROSSCHAIN_ADDRESS: "0xa5B2c9194131A4E0BFaCbF9E5D6722c873159cb7",
GREENFIELD_RPC_URL:
"https://gnfd-testnet-fullnode-tendermint-us.bnbchain.org",
GREENFIELD_CHAIN_ID: "5600",
GREENFIELD_SCAN: 'https://testnet.greenfieldscan.com'
},
};
7 changes: 4 additions & 3 deletions packages/plugin-bnb/src/templates/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,16 @@ Extract the following details for Greenfield operations:
- **bucketName** (string, optional): The name of the bucket to operate
- **objectName** (string, optional): The name of the object for upload operations
- **visibility** (string, optional): Bucket visibility setting ("private" or "public")
- **amount** (string, optianal): BNB transfer to greenfield token amount.
- **amount** (string, optional): BNB transfer to greenfield token amount.
Required response format:
\`\`\`json
{
"actionType": "createBucket" | "uploadObject" | "deleteBucket" | "downloadObject",
"actionType": "createBucket" | "uploadObject" | "deleteObject" | "transfer",
"bucketName": string,
"objectName": string,
"visibility": "private" | "public"
"visibility": "private" | "public",
"amount": number
}
\`\`\`
`;

0 comments on commit 9575341

Please sign in to comment.