Bankr开发-客户端模式Skill BankrDev-ClientPatterns

这个技能提供了用于Bankr API项目的可重用客户端代码和常见文件,帮助开发者快速构建和配置Bankr API客户端,适用于Web服务、CLI等多种项目类型,支持TypeScript开发、项目配置和环境设置。关键词:Bankr, API客户端, TypeScript, 项目配置, 量化交易, 区块链集成, 金融科技

后端开发 0 次安装 0 次浏览 更新于 3/15/2026

name: Bankr 开发 - 客户端模式 description: 这个技能应在用户请求“实现Bankr客户端”、“编写bankr-client.ts”、“创建Bankr的API客户端”、“Bankr项目的通用文件”、“Bankr的package.json”、“Bankr的tsconfig”、“Bankr TypeScript模式”、“Bankr响应类型”时使用,或需要可重用的客户端代码和常见项目文件用于Bankr API集成。 version: 1.0.0

Bankr 客户端模式

用于Bankr API项目的可重用客户端代码和常见文件。

bankr-client.ts

所有Bankr项目的核心API客户端模块:

import "dotenv/config";

const API_URL = process.env.BANKR_API_URL || "https://api.bankr.bot";
const API_KEY = process.env.BANKR_API_KEY;

// ============================================
// 类型定义
// ============================================

export type JobStatus = "pending" | "processing" | "completed" | "failed" | "cancelled";

export interface JobStatusResponse {
  success: boolean;
  jobId: string;
  status: JobStatus;
  prompt: string;
  response?: string;
  transactions?: Transaction[];
  richData?: RichData[];
  statusUpdates?: StatusUpdate[];
  error?: string;
  createdAt: string;
  startedAt?: string;
  completedAt?: string;
  cancelledAt?: string;
  processingTime?: number;
  cancellable?: boolean;
}

export interface StatusUpdate {
  message: string;
  timestamp: string;
}

// 交易类型
export type Transaction =
  | SwapTransaction
  | ApprovalTransaction
  | TransferErc20Transaction
  | TransferEthTransaction
  | ConvertEthToWethTransaction
  | ConvertWethToEthTransaction
  | TransferNftTransaction
  | MintManifoldNftTransaction
  | MintSeaDropNftTransaction
  | BuyNftTransaction
  | AvantisTradeTransaction
  | SwapCrossChainTransaction
  | ManageBankrStakingTransaction;

interface BaseTransactionMetadata {
  __ORIGINAL_TX_DATA__: {
    chain: string;
    humanReadableMessage: string;
    inputTokenAddress: string;
    inputTokenAmount: string;
    inputTokenTicker: string;
    outputTokenAddress: string;
    outputTokenTicker: string;
    receiver: string;
  };
  transaction: {
    chainId: number;
    to: string;
    data: string;
    gas: string;
    gasPrice: string;
    value: string;
  };
}

export interface SwapTransaction {
  type: "swap";
  metadata: BaseTransactionMetadata & {
    approvalRequired?: boolean;
    approvalTx?: { to: string; data: string };
    permit2?: object;
  };
}

export interface ApprovalTransaction {
  type: "approval";
  metadata: BaseTransactionMetadata;
}

export interface TransferErc20Transaction {
  type: "transfer_erc20";
  metadata: BaseTransactionMetadata;
}

export interface TransferEthTransaction {
  type: "transfer_eth";
  metadata: BaseTransactionMetadata;
}

export interface ConvertEthToWethTransaction {
  type: "convert_eth_to_weth";
  metadata: BaseTransactionMetadata;
}

export interface ConvertWethToEthTransaction {
  type: "convert_weth_to_eth";
  metadata: BaseTransactionMetadata;
}

export interface TransferNftTransaction {
  type: "transfer_nft";
  metadata: BaseTransactionMetadata;
}

export interface MintManifoldNftTransaction {
  type: "mint_manifold_nft";
  metadata: BaseTransactionMetadata;
}

export interface MintSeaDropNftTransaction {
  type: "mint_seadrop_nft";
  metadata: BaseTransactionMetadata;
}

export interface BuyNftTransaction {
  type: "buy_nft";
  metadata: BaseTransactionMetadata;
}

export interface AvantisTradeTransaction {
  type: "avantisTrade";
  metadata: {
    chainId: number;
    description: string;
    to: string;
    data: string;
    value?: string;
  };
}

export interface SwapCrossChainTransaction {
  type: "swapCrossChain";
  metadata: {
    chainId: number;
    description: string;
    to: string;
    data: string;
    value: string;
  };
}

export interface ManageBankrStakingTransaction {
  type: "manage_bankr_staking";
  metadata: {
    chainId: number;
    description: string;
    to: string;
    data: string;
    value?: string;
  };
}

// 富数据类型
export type RichData = SocialCard | Chart;

export interface SocialCard {
  type: "social-card";
  variant: "analysis";
  text: string;
}

export interface Chart {
  type: "chart";
  url: string;
}

// ============================================
// API 函数
// ============================================

export async function submitPrompt(prompt: string): Promise<{ jobId: string }> {
  if (!API_KEY) {
    throw new Error("BANKR_API_KEY 未设置。请访问 https://bankr.bot/api 获取");
  }

  const response = await fetch(`${API_URL}/agent/prompt`, {
    method: "POST",
    headers: {
      "x-api-key": API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ prompt }),
  });

  if (!response.ok) {
    const text = await response.text();
    throw new Error(`API 错误 ${response.status}: ${text}`);
  }

  const data = await response.json();
  if (!data.success) {
    throw new Error(data.error || "提交提示失败");
  }

  return { jobId: data.jobId };
}

export async function getJobStatus(jobId: string): Promise<JobStatusResponse> {
  if (!API_KEY) {
    throw new Error("BANKR_API_KEY 未设置");
  }

  const response = await fetch(`${API_URL}/agent/job/${jobId}`, {
    headers: { "x-api-key": API_KEY },
  });

  if (!response.ok) {
    const text = await response.text();
    throw new Error(`API 错误 ${response.status}: ${text}`);
  }

  return response.json();
}

export async function cancelJob(jobId: string): Promise<JobStatusResponse> {
  if (!API_KEY) {
    throw new Error("BANKR_API_KEY 未设置");
  }

  const response = await fetch(`${API_URL}/agent/job/${jobId}/cancel`, {
    method: "POST",
    headers: {
      "x-api-key": API_KEY,
      "Content-Type": "application/json",
    },
  });

  if (!response.ok) {
    const text = await response.text();
    throw new Error(`API 错误 ${response.status}: ${text}`);
  }

  return response.json();
}

export async function waitForCompletion(
  jobId: string,
  onProgress?: (message: string) => void,
  options?: { pollInterval?: number; maxAttempts?: number }
): Promise<JobStatusResponse> {
  const pollInterval = options?.pollInterval || 2000;
  const maxAttempts = options?.maxAttempts || 150; // 最大5分钟
  let lastUpdateCount = 0;

  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    const status = await getJobStatus(jobId);

    // 报告新状态更新
    if (onProgress && status.statusUpdates) {
      for (let i = lastUpdateCount; i < status.statusUpdates.length; i++) {
        onProgress(status.statusUpdates[i].message);
      }
      lastUpdateCount = status.statusUpdates.length;
    }

    // 检查终端状态
    if (["completed", "failed", "cancelled"].includes(status.status)) {
      return status;
    }

    await new Promise((resolve) => setTimeout(resolve, pollInterval));
  }

  throw new Error("作业在最大尝试次数后超时");
}

/**
 * 执行Bankr提示并等待完成
 * 结合提交和轮询的便捷函数
 */
export async function execute(
  prompt: string,
  onProgress?: (message: string) => void
): Promise<JobStatusResponse> {
  const { jobId } = await submitPrompt(prompt);
  onProgress?.(`作业已提交: ${jobId}`);
  return waitForCompletion(jobId, onProgress);
}

通用文件

package.json

所有Bankr项目的基础package.json:

{
  "name": "{项目名称}",
  "version": "0.1.0",
  "description": "{描述}",
  "type": "module",
  "main": "dist/index.js",
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "tsx src/index.ts"
  },
  "dependencies": {
    "dotenv": "^16.3.1"
  },
  "devDependencies": {
    "@types/node": "^20.10.0",
    "tsx": "^4.7.0",
    "typescript": "^5.3.0"
  }
}

框架特定依赖

根据项目模板添加:

Web服务 (Express):

"dependencies": {
  "express": "^4.18.0"
},
"devDependencies": {
  "@types/express": "^4.17.21"
}

Web服务 (Fastify):

"dependencies": {
  "fastify": "^4.25.0"
}

CLI:

"dependencies": {
  "commander": "^12.0.0"
}

tsconfig.json

TypeScript配置:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "declaration": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

.env.example

环境变量模板:

# Bankr API配置
BANKR_API_KEY=bk_your_api_key_here
BANKR_API_URL=https://api.bankr.bot

# 可选:用于上下文的钱包地址
BANKR_WALLET_ADDRESS=0x...

.gitignore

标准忽略模式:

# 依赖
node_modules/

# 构建输出
dist/

# 环境
.env
.env.local
.env.*.local

# 日志
*.log
npm-debug.log*

# IDE
.idea/
.vscode/
*.swp
*.swo

# 操作系统
.DS_Store
Thumbs.db

# 测试
coverage/

使用模式

基本用法

import { execute } from "./bankr-client";

const result = await execute("ETH的价格是多少?", (msg) => {
  console.log("进度:", msg);
});

console.log(result.response);

带错误处理

import { execute } from "./bankr-client";

try {
  const result = await execute("在Base上购买50美元的ETH");

  if (result.status === "completed") {
    console.log("成功:", result.response);

    // 处理交易
    if (result.transactions) {
      for (const tx of result.transactions) {
        console.log(`${tx.type}:`, tx.metadata.__ORIGINAL_TX_DATA__?.humanReadableMessage);
      }
    }
  } else if (result.status === "failed") {
    console.error("失败:", result.error);
  }
} catch (error) {
  console.error("错误:", error.message);
}

手动控制

import { submitPrompt, waitForCompletion, cancelJob } from "./bankr-client";

// 提交
const { jobId } = await submitPrompt("分析ETH市场");

// 设置超时
const timeout = setTimeout(() => {
  cancelJob(jobId);
}, 120000);

// 等待并自定义选项
const result = await waitForCompletion(jobId, console.log, {
  pollInterval: 2000,
  maxAttempts: 60,
});

clearTimeout(timeout);

API参考

请参阅bankr-api-basics技能获取:

  • 完整端点文档
  • 认证详情
  • 响应字段描述
  • 错误代码和处理