@polymerdao/polymer-api-client
v0.3.0
Published
TypeScript client library for interacting with Polymer's proof API and blockchain verification
Downloads
9
Readme
Polymer API Client
TypeScript client library for interacting with Polymer's proof API and blockchain verification. Provides a complete SDK for requesting proofs, verifying cryptographic signatures, and accessing blockchain data.
🚀 Installation
npm install @polymerdao/polymer-api-client🎯 Quick Start
import { PolymerOpenRpcClient, ProofVerifier, ChainlistClient } from '@polymerdao/polymer-api-client';
// Initialize the client
const client = new PolymerOpenRpcClient('your-api-key', 'https://api.polymer.zone/v1');
// Request a proof
const proofRequest = await client.proofRequest({
srcChainId: 1, // Ethereum
globalLogIndex: 12345,
srcBlockNumber: 19000000
});
// Query proof status
const status = await client.proofQueryJob({ id: proofRequest.jobId });
// Verify a proof
const verifier = new ProofVerifier('0x4632e987c6f31d6351e39324dec6f1404af56209', 444);
const isValid = await verifier.verifyProof(proofData);📚 API Reference
PolymerOpenRpcClient
Main client for interacting with Polymer's API.
import { PolymerOpenRpcClient } from '@polymerdao/polymer-api-client';
const client = new PolymerOpenRpcClient(apiKey, baseUrl);Proof Methods
Request a proof:
const request = await client.proofRequest({
srcChainId: number, // Source chain ID (e.g., 1 for Ethereum)
globalLogIndex: number, // Global log index of the event
srcBlockNumber: number // Block number containing the event
});
// Returns: { jobId: number, status: string }Query proof job:
const status = await client.proofQueryJob({
id: number // Job ID from proof request
});
// Returns: { jobId: number, status: string, proof?: string, ... }Query with filters:
const results = await client.proofQueryWithFilter({
chainId?: number,
status?: string,
limit?: number,
offset?: number
});Get job statistics:
const stats = await client.proofQueryJobStats();Execution Methods
Submit execution request:
const execution = await client.executeRequest({
proofRequest: {
srcChainId: 11155420, // Optional: request proof generation on the fly
srcBlockNumber: 29540611,
globalLogIndex: 5,
},
executeRequest: {
destChainId: 84532,
destContractAddress: '0xdda9a457771534eDba705E1D79B1ed0f732d642E',
methodSignature: 'setValueFromSource(string,bytes,bytes)',
args: ['tester', '0x1234', '$proof'], // '$proof' is replaced with the generated proof bytes
gasLimit: 1_000_000,
},
// Alternatively, omit proofRequest and provide a pre-generated proof:
// proof: 'base64_proof_payload'
});Query execution:
const status = await client.executeQuery({
id: number // Execution job ID
});Info Methods
Get connected chains:
const chains = await client.infoGetConnectedChains();Get client updates:
const updates = await client.infoGetClientUpdates();ProofVerifier
Cryptographic proof verification utilities.
import { ProofVerifier } from '@polymerdao/polymer-api-client';
const verifier = new ProofVerifier(
validationKey, // Ethereum address for ECDSA verification
polymerChainId // Polymer chain ID (default: 444)
);Verify a proof:
const isValid = await verifier.verifyProof(proofData);
// Returns: booleanParse proof data:
const parsed = verifier.parseProof(proofData);
// Returns: { appHash: string, peptideHeight: number, signature: {...}, ... }Verify ECDSA signature:
const isValidSig = verifier.verifySignature(messageHash, signature, expectedAddress);ChainlistClient
Client for accessing blockchain RPC endpoints and chain information.
import { ChainlistClient } from '@polymerdao/polymer-api-client';
const chainlist = new ChainlistClient();Get chain information:
const chains = await chainlist.getChains();
// Returns: Array of chain objects with RPC endpointsGet RPC endpoints for a chain:
const rpcs = await chainlist.getChainRpcs('ethereum');
// Returns: Array of RPC endpoint objectsExecute RPC call:
const result = await chainlist.executeRpc(
'ethereum', // Chain name
'eth_getBlockByNumber', // RPC method
['latest', false] // Method parameters
);Cache management:
// Get cache statistics
const stats = chainlist.getCacheStats();
// Clear cache
chainlist.clearCache();🔧 Configuration
Environment Setup
// Using environment variables
process.env.POLYMER_API_KEY = 'your-api-key';
process.env.POLYMER_API_BASE = 'https://api.polymer.zone/v1';
const client = new PolymerOpenRpcClient(
process.env.POLYMER_API_KEY!,
process.env.POLYMER_API_BASE
);Custom Configuration
const client = new PolymerOpenRpcClient(
'your-api-key',
'https://staging.polymer.zone/v1', // Custom API base
{
timeout: 30000, // 30 second timeout
retries: 3, // Retry failed requests
headers: { // Custom headers
'User-Agent': 'MyApp/1.0'
}
}
);📊 Examples
Complete Proof Workflow
import { PolymerOpenRpcClient, ProofVerifier } from '@polymerdao/polymer-api-client';
async function completeProofWorkflow() {
const client = new PolymerOpenRpcClient('your-api-key');
const verifier = new ProofVerifier('0x4632e987c6f31d6351e39324dec6f1404af56209', 444);
// 1. Request proof
const request = await client.proofRequest({
srcChainId: 1, // Ethereum
globalLogIndex: 12345,
srcBlockNumber: 19000000
});
console.log(`Proof requested: Job ID ${request.jobId}`);
// 2. Poll for completion
let status;
do {
await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
status = await client.proofQueryJob({ id: request.jobId });
console.log(`Status: ${status.status}`);
} while (status.status === 'pending');
// 3. Verify proof if completed
if (status.status === 'completed' && status.proof) {
const isValid = await verifier.verifyProof(status.proof);
console.log(`Proof valid: ${isValid}`);
// Parse proof details
const parsed = verifier.parseProof(status.proof);
console.log('Proof details:', parsed);
}
}Cross-Chain Execution
async function executecrossChain() {
const client = new PolymerOpenRpcClient('your-api-key');
// Prepare execution envelope
const envelope = {
proof: 'base64_encoded_proof_data',
executeRequest: {
destChainId: 137, // Polygon
destContractAddress: '0x...', // Target contract
methodSignature: 'setProof(bytes)',
args: ['$proof'], // '$proof' gets replaced with proof bytes
}
};
// Submit execution
const execution = await client.executeRequest(envelope);
console.log(`Execution submitted: ${execution.jobId}`);
// Monitor execution
const result = await client.executeQuery({ id: execution.jobId });
console.log('Execution result:', result);
}Blockchain Data Access
async function accessBlockchainData() {
const chainlist = new ChainlistClient();
// Get latest Ethereum block
const latestBlock = await chainlist.executeRpc(
'ethereum',
'eth_getBlockByNumber',
['latest', false]
);
console.log('Latest block:', latestBlock);
// Get contract events
const logs = await chainlist.executeRpc(
'ethereum',
'eth_getLogs',
[{
fromBlock: '0x1234567',
toBlock: 'latest',
address: '0x...',
topics: ['0x...']
}]
);
console.log('Contract events:', logs);
}Error Handling
import { PolymerApiError } from '@polymerdao/polymer-api-client';
async function handleErrors() {
try {
const client = new PolymerOpenRpcClient('invalid-key');
await client.proofRequest({ srcChainId: 1, globalLogIndex: 1, srcBlockNumber: 1 });
} catch (error) {
if (error instanceof PolymerApiError) {
console.error('API Error:', error.message);
console.error('Status Code:', error.statusCode);
console.error('Response:', error.response);
} else {
console.error('Unexpected error:', error);
}
}
}🧪 Testing
# Run tests
npm test
# Run tests with coverage
npm run test:coverage
# Run specific test file
npm test -- chainlist.test.tsExample Test
import { PolymerOpenRpcClient } from '@polymerdao/polymer-api-client';
describe('PolymerOpenRpcClient', () => {
it('should request a proof', async () => {
const client = new PolymerOpenRpcClient('test-key');
// Mock the API call
const mockResponse = { jobId: 123, status: 'pending' };
jest.spyOn(client, 'proofRequest').mockResolvedValue(mockResponse);
const result = await client.proofRequest({
srcChainId: 1,
globalLogIndex: 12345,
srcBlockNumber: 19000000
});
expect(result.jobId).toBe(123);
expect(result.status).toBe('pending');
});
});🔧 Development
Building from Source
# Clone the monorepo
git clone https://github.com/polymerdao/mcp-polymer.git
cd mcp-polymer/packages/api-client
# Install dependencies
npm install
# Build
npm run build
# Generate client from OpenRPC spec
npm run generate-clientProject Structure
src/
├── index.ts # Main exports
├── client.ts # PolymerOpenRpcClient implementation
├── verification.ts # ProofVerifier implementation
├── chainlist.ts # ChainlistClient implementation
├── types.ts # TypeScript type definitions
└── generated-client.ts # Auto-generated from OpenRPC specCode Generation
The client includes auto-generated methods from Polymer's OpenRPC specification:
# Regenerate client methods
npm run generate-client📄 Type Definitions
Core Types
interface ProofRequest {
srcChainId: number;
globalLogIndex: number;
srcBlockNumber: number;
}
interface ProofResponse {
jobId: number;
status: 'pending' | 'completed' | 'failed';
proof?: string;
error?: string;
}
interface ExecuteEnvelope {
proof: string;
executeRequest: {
chainId: number;
payload: string;
};
}
interface ChainInfo {
chainId: number;
name: string;
rpc: string[];
nativeCurrency: {
name: string;
symbol: string;
decimals: number;
};
}🤝 Contributing
See the main repository README for contribution guidelines.
Adding New Features
- Add feature to appropriate client class
- Update type definitions in
types.ts - Add tests for new functionality
- Update this README with examples
📄 License
Apache 2.0 License - see LICENSE for details.
