Skip to content

Commit

Permalink
Merge pull request #2 from APRO-com/20250205
Browse files Browse the repository at this point in the history
Rename the plugin name from plugin-apro to plugin-ATTPs
  • Loading branch information
fifahuihua authored Feb 7, 2025
2 parents fd3693c + 9186350 commit fa4c06a
Show file tree
Hide file tree
Showing 17 changed files with 1,753 additions and 0 deletions.
172 changes: 172 additions & 0 deletions packages/plugin-attps/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@

# @elizaos/plugin-attps

Foundation plugin that enables advanced agent interactions, data verification, and price queries on the Eliza OS platform. It streamlines agent creation, verification processes, and provides a flexible framework for building robust agent-based solutions.

## Overview

The ATTPs plugin bridges agent-based logic with the Eliza ecosystem. It handles agent registration, data verification, and price queries, empowering both automated and user-driven workflows.

## Features

### Agent Operations
- **Agent Creation**: Deploy new agents with custom settings
- **Registration**: Register agents on-chain or via standardized processes
- **Multi-Signer Framework**: Supports threshold-based approval flows

### Data Verification
- **Chain Validation**: Verify data authenticity on-chain
- **Transaction Execution**: Handle verification logic with built-in security checks
- **Auto-Hashing**: Convert raw data to hashed formats when needed
- **Metadata Parsing**: Validate content type, encoding, and compression

### Price Queries
- **Live Price Data**: Fetch price information for various pairs
- **Format Validation**: Normalize user query inputs to standard trading-pair formats
- **APIs Integration**: Retrieve real-time or near-real-time pricing information

## Security Features

### Access Control
- **Private Key Management**: Safe usage of private keys for transaction signing
- **Environment Variables**: Secure injection of credentials
- **On-Chain Validation**: Leverage on-chain contract checks

### Verification
- **Input Validation**: Strict schema checks before on-chain operations
- **Transaction Receipts**: Provide verifiable transaction details
- **Error Handling**: Detailed error logs for quick debugging

## Installation

```bash
npm install @elizaos/plugin-attps
```

## Configuration

Configure the plugin by setting environment variables or runtime settings:
- ATTPS_RPC_URL
- ATTPS_PROXY_ADDRESS
- ATTPS_PRIVATE_KEY
- ATTPS_CONVERTER_ADDRESS
- ATTPS_AUTO_HASH_DATA

## Usage

### Basic Setup
```typescript
import { attpsPlugin } from "@elizaos/plugin-attps";

// Initialize the plugin
const runtime = await initializeRuntime({
plugins: [attpsPlugin],
});
```

### Actions

#### CREATE_AND_REGISTER_AGENT
Creates and registers an agent using specified settings.

```typescript
const result = await runtime.executeAction("CREATE_AND_REGISTER_AGENT", {
signers: [...],
threshold: 3,
agentHeader: { ... },
// ...other fields...
});
```

#### VERIFY
Verifies data on-chain via the Agent SDK.

```typescript
const result = await runtime.executeAction("VERIFY", {
payload: {
data: "0x...hexData",
signatures: [...],
},
agent: "0x...agentAddress",
digest: "0x...digestString",
});
```

#### PRICE_QUERY
Fetches live price data for a specified trading pair.

```typescript
const result = await runtime.executeAction("PRICE_QUERY", {
pair: "BTC/USD",
});
```

## Performance Optimization

1. **Cache Management**
- Implement caching for frequent queries
- Monitor retrieval times and cache hits

2. **Network Efficiency**
- Batch requests where possible
- Validate response parsing to reduce overhead

## System Requirements
- Node.js 16.x or higher
- Sufficient network access to on-chain endpoints
- Basic configuration of environment variables
- Minimum 4GB RAM recommended

## Troubleshooting

1. **Invalid Agent Settings**
- Ensure signers and threshold are correct
- Validate agentHeader for proper UUIDs and numeric values

2. **Verification Failures**
- Check the input data formats
- Confirm environment variables are set

3. **Price Query Errors**
- Verify the trading pair format
- Check external API availability

## Safety & Security

1. **Credential Management**
- Store private keys securely
- Do not commit secrets to version control

2. **Transaction Limits**
- Configure thresholds to mitigate abuse
- Log transaction attempts and failures

3. **Monitoring & Logging**
- Track unusual activity
- Maintain detailed audit logs

## Support

For issues or feature requests:
1. Check existing documentation
2. Submit a GitHub issue with relevant details
3. Include transaction logs and system info if applicable

## Contributing

We welcome pull requests! Refer to the project’s CONTRIBUTING.md and open discussions to coordinate efforts.

## Credits

- [APRO](https://www.apro.com/) - Plugin sponsor and partner
- [ai-agent-sdk-js](https://github.com/APRO-com/ai-agent-sdk-js) - Underlying agent SDK
- [ethers.js](https://docs.ethers.io/) - Transaction and contract interaction
- Community contributors for feedback and testing

For more information about Apro plugin capabilities:

- [Apro Documentation](https://docs.apro.com/en)

## License

This plugin is part of the Eliza project. Refer to the main project repository for licensing details.
174 changes: 174 additions & 0 deletions packages/plugin-attps/__tests__/actions/attpsPriceQuery.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// Mock declarations must come first
vi.mock('@elizaos/core');
vi.mock('ai-agent-sdk-js');

import { vi, describe, it, expect, beforeEach } from 'vitest';
import type { IAgentRuntime, Memory, State } from '@elizaos/core';
import { generateObject } from '@elizaos/core';
import { attpsPriceQuery } from '../../src/actions/attpsPriceQuery';

describe('attpsPriceQuery', () => {
const mockRuntime: IAgentRuntime = {
composeState: vi.fn(),
updateRecentMessageState: vi.fn(),
getSetting: vi.fn()
} as unknown as IAgentRuntime;

const mockMessage: Memory = {
userId: 'test-user',
agentId: 'test-agent',
roomId: 'test-room',
content: {
text: 'query price'
}
} as Memory;

const mockState: State = {};
const mockCallback = vi.fn();
const mockFetch = vi.fn();

beforeEach(() => {
vi.clearAllMocks();
vi.mocked(mockRuntime.composeState).mockResolvedValue(mockState);
vi.mocked(mockRuntime.updateRecentMessageState).mockResolvedValue(mockState);
global.fetch = mockFetch;
});

describe('validate', () => {
it('should always return true', async () => {
const result = await attpsPriceQuery.validate(mockRuntime, mockMessage);
expect(result).toBe(true);
});
});

describe('handler', () => {
const mockPriceQuery = {
sourceAgentId: 'test-source-agent',
feedId: 'test-feed'
};

const mockPriceResponse = {
code: 0,
message: 'success',
result: {
askPrice: '100.50',
bidPrice: '100.40',
midPrice: '100.45',
validTimeStamp: '1234567890'
}
};

it('should successfully fetch price data', async () => {
// Mock generateObject to return price query params
vi.mocked(generateObject).mockResolvedValueOnce({
object: mockPriceQuery
});

// Mock successful API response
mockFetch.mockResolvedValueOnce({
json: () => Promise.resolve(mockPriceResponse)
});

const result = await attpsPriceQuery.handler(
mockRuntime,
mockMessage,
mockState,
{},
mockCallback
);

expect(mockCallback).toHaveBeenCalledWith(expect.objectContaining({
text: expect.stringContaining('Ask price: 100.5')
}));
expect(mockFetch).toHaveBeenCalledWith(
expect.stringContaining('sourceAgentId=test-source-agent')
);
});

it('should handle price query params generation failure', async () => {
// Mock generateObject to throw an error
vi.mocked(generateObject).mockRejectedValueOnce(
new Error('Failed to generate params')
);

await attpsPriceQuery.handler(
mockRuntime,
mockMessage,
mockState,
{},
mockCallback
);

expect(mockCallback).toHaveBeenCalledWith({
text: expect.stringContaining('Failed to generate price query params')
});
});

it('should handle API error response', async () => {
// Mock generateObject to return price query params
vi.mocked(generateObject).mockResolvedValueOnce({
object: mockPriceQuery
});

// Mock API error response
mockFetch.mockResolvedValueOnce({
json: () => Promise.resolve({
code: 1,
message: 'API Error'
})
});

await attpsPriceQuery.handler(
mockRuntime,
mockMessage,
mockState,
{},
mockCallback
);

expect(mockCallback).toHaveBeenCalledWith({
text: 'Error fetching price data: API Error'
});
});

it('should handle network failure', async () => {
// Mock generateObject to return price query params
vi.mocked(generateObject).mockResolvedValueOnce({
object: mockPriceQuery
});

// Mock network failure
mockFetch.mockRejectedValueOnce(new Error('Network error'));

await attpsPriceQuery.handler(
mockRuntime,
mockMessage,
mockState,
{},
mockCallback
);

expect(mockCallback).toHaveBeenCalledWith({
text: 'Error fetching price data: Network error'
});
});
});

describe('metadata', () => {
it('should have correct name and description', () => {
expect(attpsPriceQuery.name).toBe('ATTPS_PRICE_QUERY');
expect(attpsPriceQuery.description).toContain('Call remote API to fetch price data');
});

it('should have valid examples', () => {
expect(Array.isArray(attpsPriceQuery.examples)).toBe(true);
expect(attpsPriceQuery.examples.length).toBeGreaterThan(0);

attpsPriceQuery.examples.forEach(example => {
expect(Array.isArray(example)).toBe(true);
expect(example.length).toBe(2);
expect(example[1].content.action).toBe('ATTPS_PRICE_QUERY');
});
});
});
});
Loading

0 comments on commit fa4c06a

Please sign in to comment.