@agentsbank/sdk 1.0.12 → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -1
- package/.env +0 -38
- package/.env.example +0 -53
- package/SKILL.md +0 -250
- package/index.ts +0 -482
- package/security-config.ts +0 -268
- package/tsconfig.json +0 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentsbank/sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "🔒 Secure Financial SDK for AgentsBank - Multi-chain wallet & transaction management. Requires explicit credentials and user authorization for financial operations.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -9,6 +9,12 @@
|
|
|
9
9
|
"build": "tsc",
|
|
10
10
|
"publish": "npm publish"
|
|
11
11
|
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"README.md",
|
|
15
|
+
"CHANGELOG.md",
|
|
16
|
+
"package.json"
|
|
17
|
+
],
|
|
12
18
|
"keywords": [
|
|
13
19
|
"ai-agents",
|
|
14
20
|
"blockchain",
|
package/.env
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# AgentsBank SDK - Environment Variables
|
|
2
|
-
# SECURITY WARNING: Never commit .env to version control
|
|
3
|
-
|
|
4
|
-
# ============================================
|
|
5
|
-
# API Configuration (REQUIRED)
|
|
6
|
-
# ============================================
|
|
7
|
-
# Base URL of AgentsBank API
|
|
8
|
-
AGENTSBANK_API_URL=https://api.agentsbank.online
|
|
9
|
-
|
|
10
|
-
# ============================================
|
|
11
|
-
# Authentication (Choose ONE method)
|
|
12
|
-
# ============================================
|
|
13
|
-
|
|
14
|
-
# METHOD 1: API Key (Recommended for production)
|
|
15
|
-
AGENTSBANK_API_KEY=your-api-key-here-do-not-share
|
|
16
|
-
|
|
17
|
-
# METHOD 2: Agent Credentials (For testing/setup)
|
|
18
|
-
# Uncomment and fill only if using credential-based auth
|
|
19
|
-
# AGENTSBANK_AGENT_USERNAME=agent_name
|
|
20
|
-
# AGENTSBANK_AGENT_PASSWORD=agent_password_secret
|
|
21
|
-
|
|
22
|
-
# ============================================
|
|
23
|
-
# Optional: Pre-authenticated Token
|
|
24
|
-
# ============================================
|
|
25
|
-
# Only needed if you have a pre-issued JWT token
|
|
26
|
-
# AGENTSBANK_AUTH_TOKEN=jwt-token-here
|
|
27
|
-
|
|
28
|
-
# ============================================
|
|
29
|
-
# Optional: Runtime Configuration
|
|
30
|
-
# ============================================
|
|
31
|
-
# Timeout for API requests (in milliseconds)
|
|
32
|
-
SDK_REQUEST_TIMEOUT=10000
|
|
33
|
-
|
|
34
|
-
# Enable verbose logging for debugging
|
|
35
|
-
SDK_DEBUG=false
|
|
36
|
-
|
|
37
|
-
# Custom audit logging endpoint (optional)
|
|
38
|
-
# SDK_AUDIT_LOG_ENDPOINT=https://logs.example.com/audit
|
package/.env.example
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# AgentsBank SDK - Environment Variables Template
|
|
2
|
-
# Copy this to .env and fill in your actual credentials
|
|
3
|
-
# SECURITY WARNING: Never commit .env to version control
|
|
4
|
-
|
|
5
|
-
# ============================================
|
|
6
|
-
# API Configuration (REQUIRED)
|
|
7
|
-
# ============================================
|
|
8
|
-
# Base URL of AgentsBank API
|
|
9
|
-
# For local development: http://localhost:3000
|
|
10
|
-
# For production: https://api.agentsbank.online
|
|
11
|
-
AGENTSBANK_API_URL=https://api.agentsbank.online
|
|
12
|
-
|
|
13
|
-
# ============================================
|
|
14
|
-
# Authentication (Choose ONE method)
|
|
15
|
-
# ============================================
|
|
16
|
-
|
|
17
|
-
# METHOD 1: API Key (Recommended for production)
|
|
18
|
-
AGENTSBANK_API_KEY=your-api-key-here-do-not-share
|
|
19
|
-
|
|
20
|
-
# METHOD 2: Agent Credentials (For testing/setup)
|
|
21
|
-
# Uncomment and fill only if using credential-based auth
|
|
22
|
-
# AGENTSBANK_AGENT_USERNAME=agent_name
|
|
23
|
-
# AGENTSBANK_AGENT_PASSWORD=agent_password_secret
|
|
24
|
-
|
|
25
|
-
# ============================================
|
|
26
|
-
# Optional: Pre-authenticated Token
|
|
27
|
-
# ============================================
|
|
28
|
-
# Only needed if you have a pre-issued JWT token
|
|
29
|
-
# AGENTSBANK_AUTH_TOKEN=jwt-token-here
|
|
30
|
-
|
|
31
|
-
# ============================================
|
|
32
|
-
# Optional: Runtime Configuration
|
|
33
|
-
# ============================================
|
|
34
|
-
# Environment: 'production' or 'sandbox'
|
|
35
|
-
AGENTSBANK_ENVIRONMENT=production
|
|
36
|
-
|
|
37
|
-
# Request timeout in milliseconds
|
|
38
|
-
AGENTSBANK_TIMEOUT_MS=10000
|
|
39
|
-
|
|
40
|
-
# Enable audit logging
|
|
41
|
-
AGENTSBANK_AUDIT_LOG=true
|
|
42
|
-
|
|
43
|
-
# Webhook URL for transaction notifications (optional)
|
|
44
|
-
# AGENTSBANK_WEBHOOK_URL=https://your-domain.com/webhooks/agentsbank
|
|
45
|
-
|
|
46
|
-
# ============================================
|
|
47
|
-
# Security Checklist
|
|
48
|
-
# ============================================
|
|
49
|
-
# ✓ API key obtained from https://dashboard.agentsbank.ai
|
|
50
|
-
# ✓ Never commit this file to git (add to .gitignore)
|
|
51
|
-
# ✓ Rotate API key monthly or when team member leaves
|
|
52
|
-
# ✓ Use different credentials for development vs production
|
|
53
|
-
# ✓ Enable audit logging in production
|
package/SKILL.md
DELETED
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
# AgentsBank SDK - Financial Operations Skill
|
|
2
|
-
|
|
3
|
-
**Status:** Production-grade, requires explicit user invocation for financial operations
|
|
4
|
-
**Version:** 0.1.0
|
|
5
|
-
**Risk Level:** High (financial transactions)
|
|
6
|
-
**Autonomy:** ❌ Disabled for autonomous execution
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## ⚠️ Security & Credential Requirements
|
|
11
|
-
|
|
12
|
-
This is a **financial transaction SDK** that requires explicit credentials and user authorization. It is **NOT autonomously invocable** for security reasons.
|
|
13
|
-
|
|
14
|
-
### Required Environment Variables
|
|
15
|
-
|
|
16
|
-
```env
|
|
17
|
-
# API Configuration (REQUIRED - NO DEFAULT)
|
|
18
|
-
AGENTSBANK_API_URL=https://api.agentsbank.ai
|
|
19
|
-
|
|
20
|
-
# Authentication (Choose ONE)
|
|
21
|
-
AGENTSBANK_API_KEY=your-api-key-here
|
|
22
|
-
# OR
|
|
23
|
-
AGENTSBANK_AGENT_USERNAME=agent_name
|
|
24
|
-
AGENTSBANK_AGENT_PASSWORD=agent_password_secret
|
|
25
|
-
|
|
26
|
-
# Optional runtime token (if pre-authenticated)
|
|
27
|
-
AGENTSBANK_AUTH_TOKEN=jwt-token-here
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
- **`AGENTSBANK_API_URL`** (required): Base URL of the AgentsBank API endpoint
|
|
31
|
-
- No defaults → must be explicitly set
|
|
32
|
-
- Scope: API connectivity only
|
|
33
|
-
|
|
34
|
-
- **`AGENTSBANK_API_KEY`** OR credentials (required for auth):
|
|
35
|
-
- Primary authentication method
|
|
36
|
-
- Scope: Wallet creation, transactions, balance queries
|
|
37
|
-
- Must be rotated regularly
|
|
38
|
-
- Cannot be embedded in code
|
|
39
|
-
|
|
40
|
-
- **`AGENTSBANK_AUTH_TOKEN`** (optional): Pre-issued JWT token
|
|
41
|
-
- Use if already authenticated
|
|
42
|
-
- Shorter scope than API key
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
## 🔐 Credential Security Boundaries
|
|
47
|
-
|
|
48
|
-
| Operation | Credential Required | Scope | Risk |
|
|
49
|
-
|-----------|-------------------|-------|------|
|
|
50
|
-
| Wallet Management | API Key + Agent Auth | Read/Write | 🔴 High |
|
|
51
|
-
| Transactions | API Key + Agent Auth | Write only | 🔴 Critical |
|
|
52
|
-
| Balance Query | API Key | Read only | 🟡 Medium |
|
|
53
|
-
| Gas Estimation | API Key | Informational | 🟢 Low |
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
## 🚫 Autonomous Execution Policy
|
|
58
|
-
|
|
59
|
-
**This SDK MUST NOT be autonomously invoked by AI agents.** Financial operations require:
|
|
60
|
-
|
|
61
|
-
1. **Explicit User Confirmation** – User must authorize before any transaction
|
|
62
|
-
2. **Human Review** – Transaction details must be reviewed and approved
|
|
63
|
-
3. **Audit Trail** – All operations logged with timestamp and actor
|
|
64
|
-
4. **Rate Limiting** – API enforces per-agent limits to prevent abuse
|
|
65
|
-
|
|
66
|
-
### Enforce Constraints in Code
|
|
67
|
-
|
|
68
|
-
```typescript
|
|
69
|
-
// REQUIRED: Check for user authorization flag
|
|
70
|
-
if (!context.userApproval) {
|
|
71
|
-
throw new Error('Financial operations require explicit user authorization');
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// REQUIRED: Log transaction intent before execution
|
|
75
|
-
logger.info('User authorized transaction', {
|
|
76
|
-
agentId: config.agentId,
|
|
77
|
-
recipient: toAddress,
|
|
78
|
-
amount: amount,
|
|
79
|
-
timestamp: new Date()
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
// REQUIRED: Never retry failed financial operations without user re-approval
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
## 📦 Installation
|
|
88
|
-
|
|
89
|
-
```bash
|
|
90
|
-
npm install @agentsbank/sdk
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
### Setup Steps
|
|
94
|
-
|
|
95
|
-
1. **Obtain Credentials**
|
|
96
|
-
- Request API key from dashboard: https://dashboard.agentsbank.ai
|
|
97
|
-
- OR set `AGENTSBANK_AGENT_USERNAME` + `AGENTSBANK_AGENT_PASSWORD`
|
|
98
|
-
- Securely store credentials (never commit to git)
|
|
99
|
-
|
|
100
|
-
2. **Configure Environment**
|
|
101
|
-
```bash
|
|
102
|
-
cp .env.example .env
|
|
103
|
-
# Edit .env with your credentials
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
3. **Initialize SDK**
|
|
107
|
-
```typescript
|
|
108
|
-
import { AgentsBankSDK } from '@agentsbank/sdk';
|
|
109
|
-
|
|
110
|
-
const bank = new AgentsBankSDK({
|
|
111
|
-
apiUrl: process.env.AGENTSBANK_API_URL,
|
|
112
|
-
apiKey: process.env.AGENTSBANK_API_KEY,
|
|
113
|
-
// OR credentials:
|
|
114
|
-
agentUsername: process.env.AGENTSBANK_AGENT_USERNAME,
|
|
115
|
-
agentPassword: process.env.AGENTSBANK_AGENT_PASSWORD,
|
|
116
|
-
});
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
## 💰 Core Capabilities
|
|
122
|
-
|
|
123
|
-
### Wallet Management
|
|
124
|
-
- **`createWallet(chain, type)`** – Create new multi-chain wallet
|
|
125
|
-
- Chains: `ethereum`, `bsc`, `solana`
|
|
126
|
-
- Types: `custodial`, `non-custodial`
|
|
127
|
-
- ⚠️ Custodial wallets require setup confirmationSecurity
|
|
128
|
-
|
|
129
|
-
- **`listWallets()`** – List all wallets for agent
|
|
130
|
-
- **`getWallet(walletId)`** – Retrieve wallet details
|
|
131
|
-
- **`getBalance(walletId)`** – Query wallet balance across assets
|
|
132
|
-
|
|
133
|
-
### Transaction Operations
|
|
134
|
-
- **`sendTransaction(walletId, toAddress, amount, currency)`** – Execute transfer
|
|
135
|
-
- **Requires:** Explicit user approval before execution
|
|
136
|
-
- **Returns:** Transaction ID for tracking
|
|
137
|
-
- **Timeout:** 300s default (configurable)
|
|
138
|
-
|
|
139
|
-
- **`getTransaction(txId)`** – Retrieve transaction status
|
|
140
|
-
- **`getTransactionHistory(walletId, limit)`** – List recent transactions
|
|
141
|
-
- **`waitForConfirmation(txId)`** – Poll until confirmed or timeout
|
|
142
|
-
|
|
143
|
-
### Utilities
|
|
144
|
-
- **`estimateGas(walletId, toAddress, amount)`** – Get gas cost estimate (informational only)
|
|
145
|
-
- **`getStats(walletId, days)`** – Historical transaction metrics
|
|
146
|
-
- **`refreshToken()`** – Renew JWT token before expiry
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
## 🔍 Audit & Compliance
|
|
151
|
-
|
|
152
|
-
All financial operations trigger:
|
|
153
|
-
|
|
154
|
-
- ✅ Agent authentication verification
|
|
155
|
-
- ✅ Transaction signature & validation
|
|
156
|
-
- ✅ Rate limit enforcement (per-agent per-minute)
|
|
157
|
-
- ✅ Immutable audit log entry
|
|
158
|
-
- ✅ Optional webhook notification to recipient
|
|
159
|
-
|
|
160
|
-
---
|
|
161
|
-
|
|
162
|
-
## ⚡ Quick Example
|
|
163
|
-
|
|
164
|
-
```typescript
|
|
165
|
-
import { AgentsBankSDK } from '@agentsbank/sdk';
|
|
166
|
-
|
|
167
|
-
// 1. Initialize with API Key
|
|
168
|
-
const bank = new AgentsBankSDK({
|
|
169
|
-
apiUrl: 'https://api.agentsbank.ai',
|
|
170
|
-
apiKey: process.env.AGENTSBANK_API_KEY
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
// 2. Get or create wallet
|
|
174
|
-
let wallet = await bank.listWallets().then(w => w[0]);
|
|
175
|
-
if (!wallet) {
|
|
176
|
-
wallet = await bank.createWallet('ethereum', 'non-custodial');
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// 3. Check balance
|
|
180
|
-
const balance = await bank.getBalance(wallet.wallet_id);
|
|
181
|
-
console.log('Balance:', balance);
|
|
182
|
-
|
|
183
|
-
// 4. ONLY with user approval:
|
|
184
|
-
if (userConfirmsTransaction) {
|
|
185
|
-
const tx = await bank.sendTransaction(
|
|
186
|
-
wallet.wallet_id,
|
|
187
|
-
'0xRecipient...',
|
|
188
|
-
'1.5',
|
|
189
|
-
'ETH'
|
|
190
|
-
);
|
|
191
|
-
console.log('Tx ID:', tx.tx_id);
|
|
192
|
-
|
|
193
|
-
// 5. Wait for confirmation
|
|
194
|
-
const confirmed = await bank.waitForConfirmation(tx.tx_id);
|
|
195
|
-
console.log('Status:', confirmed.status);
|
|
196
|
-
}
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
---
|
|
200
|
-
|
|
201
|
-
## 🛑 Error Handling
|
|
202
|
-
|
|
203
|
-
```typescript
|
|
204
|
-
try {
|
|
205
|
-
await bank.sendTransaction(walletId, recipient, amount, currency);
|
|
206
|
-
} catch (error) {
|
|
207
|
-
if (error.message.includes('Invalid wallet')) {
|
|
208
|
-
console.error('Wallet not found');
|
|
209
|
-
} else if (error.message.includes('Insufficient balance')) {
|
|
210
|
-
console.error('Not enough funds');
|
|
211
|
-
} else if (error.message.includes('Rate limit exceeded')) {
|
|
212
|
-
console.error('Too many requests - try again later');
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
|
-
## 🚀 Best Practices
|
|
220
|
-
|
|
221
|
-
1. **Never store credentials in code** – Use environment variables only
|
|
222
|
-
2. **Rotate API keys monthly** – Call `regenerateApiKey()` and update `.env`
|
|
223
|
-
3. **Validate recipient addresses** – Always verify before transaction
|
|
224
|
-
4. **Use non-custodial wallets** for agents when possible
|
|
225
|
-
5. **Monitor transaction history** – Regular audits via `getTransactionHistory()`
|
|
226
|
-
6. **Set low rate limits** – Start with 1-5 transactions/minute per agent
|
|
227
|
-
7. **Enable webhook notifications** – Get real-time transaction confirmations
|
|
228
|
-
|
|
229
|
-
---
|
|
230
|
-
|
|
231
|
-
## 📞 Support & Security Issues
|
|
232
|
-
|
|
233
|
-
- Dashboard: https://dashboard.agentsbank.ai
|
|
234
|
-
- Docs: https://docs.agentsbank.ai
|
|
235
|
-
- Report security issues: security@agentsbank.ai (not public issues)
|
|
236
|
-
|
|
237
|
-
---
|
|
238
|
-
|
|
239
|
-
## 📋 Compliance Notes
|
|
240
|
-
|
|
241
|
-
- **OAuth2 Support**: Via API Key or JWT bearer token
|
|
242
|
-
- **Webhook Support**: Transaction confirmations, balance updates
|
|
243
|
-
- **Sandbox Mode**: Available via `AGENTSBANK_ENVIRONMENT=sandbox` env var
|
|
244
|
-
- **Audit Trail**: All transactions immutably logged with actor, timestamp, amount
|
|
245
|
-
- **PCI DSS Notes**: Private keys never transmitted over network; stored encrypted at rest
|
|
246
|
-
|
|
247
|
-
---
|
|
248
|
-
|
|
249
|
-
**Last Updated:** February 2026
|
|
250
|
-
**Requires:** Node.js 18+, @agentsbank/sdk ^0.1.0
|
package/index.ts
DELETED
|
@@ -1,482 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 🔒 AgentsBank.ai SDK for Agents - FINANCIAL OPERATIONS
|
|
3
|
-
*
|
|
4
|
-
* ⚠️ SECURITY CONSTRAINTS:
|
|
5
|
-
* - Requires explicit API credentials (apiUrl + apiKey or agent credentials)
|
|
6
|
-
* - Financial operations (sendTransaction) require UserApprovalContext
|
|
7
|
-
* - NOT autonomously invocable - requires human approval
|
|
8
|
-
* - All operations logged with audit trail
|
|
9
|
-
*
|
|
10
|
-
* Usage:
|
|
11
|
-
* import { AgentsBankSDK } from '@agentsbank/sdk';
|
|
12
|
-
*
|
|
13
|
-
* const bank = new AgentsBankSDK({
|
|
14
|
-
* apiUrl: process.env.AGENTSBANK_API_URL!,
|
|
15
|
-
* apiKey: process.env.AGENTSBANK_API_KEY!,
|
|
16
|
-
* });
|
|
17
|
-
*
|
|
18
|
-
* // Read-only operations (no approval needed)
|
|
19
|
-
* const wallet = await bank.getWallet(walletId);
|
|
20
|
-
*
|
|
21
|
-
* // Financial operations (REQUIRES USER APPROVAL)
|
|
22
|
-
* const tx = await bank.sendTransaction(
|
|
23
|
-
* walletId,
|
|
24
|
-
* toAddress,
|
|
25
|
-
* amount,
|
|
26
|
-
* { userId: 'user_123', approvedAt: new Date(), reason: 'User confirmed on UI' }
|
|
27
|
-
* );
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
import axios, { AxiosInstance } from 'axios';
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* ⚠️ REQUIRED: User approval context for financial operations
|
|
34
|
-
* Prevents autonomous execution of transactions
|
|
35
|
-
*/
|
|
36
|
-
export interface UserApprovalContext {
|
|
37
|
-
userId: string; // ID of human who approved the transaction
|
|
38
|
-
approvedAt: Date; // Timestamp when approval was granted
|
|
39
|
-
reason?: string; // Human-readable reason for audit trail
|
|
40
|
-
approvalMethod?: 'ui' | 'api' | '2fa' | 'autonomous'; // How approval was obtained
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface SDKConfig {
|
|
44
|
-
apiUrl: string;
|
|
45
|
-
agentUsername?: string;
|
|
46
|
-
agentPassword?: string;
|
|
47
|
-
apiKey?: string;
|
|
48
|
-
token?: string;
|
|
49
|
-
auditLogger?: (event: AuditEvent) => void;
|
|
50
|
-
/**
|
|
51
|
-
* ⚠️ AUTONOMOUS MODE (RISKY)
|
|
52
|
-
* If true, allows financial operations without UserApprovalContext
|
|
53
|
-
* Use only for trusted autonomous agents with guardrails enabled
|
|
54
|
-
* Default: false (requires human approval)
|
|
55
|
-
*/
|
|
56
|
-
autonomousMode?: boolean;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface AuditEvent {
|
|
60
|
-
timestamp: Date;
|
|
61
|
-
operation: 'wallet_create' | 'wallet_list' | 'balance_query' | 'transaction_send' | 'auth_login' | 'token_refresh';
|
|
62
|
-
walletId?: string;
|
|
63
|
-
txId?: string;
|
|
64
|
-
userId?: string;
|
|
65
|
-
amount?: string;
|
|
66
|
-
toAddress?: string;
|
|
67
|
-
status: 'initiated' | 'success' | 'failed';
|
|
68
|
-
error?: string;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export interface WalletInfo {
|
|
72
|
-
wallet_id: string;
|
|
73
|
-
agent_id: string;
|
|
74
|
-
chain: string;
|
|
75
|
-
address: string;
|
|
76
|
-
type: 'custodial' | 'non-custodial';
|
|
77
|
-
balance: Record<string, string>;
|
|
78
|
-
created_at: string;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export interface TransactionInfo {
|
|
82
|
-
tx_id: string;
|
|
83
|
-
wallet_id: string;
|
|
84
|
-
type: string;
|
|
85
|
-
amount: string;
|
|
86
|
-
currency: string;
|
|
87
|
-
from_address: string;
|
|
88
|
-
to_address: string;
|
|
89
|
-
tx_hash?: string;
|
|
90
|
-
status: 'pending' | 'confirmed' | 'failed';
|
|
91
|
-
fee: string;
|
|
92
|
-
timestamp: string;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export class AgentsBankSDK {
|
|
96
|
-
private client: AxiosInstance;
|
|
97
|
-
private config: SDKConfig;
|
|
98
|
-
private token?: string;
|
|
99
|
-
private auditLogger: (event: AuditEvent) => void;
|
|
100
|
-
|
|
101
|
-
constructor(config: SDKConfig) {
|
|
102
|
-
// ⚠️ SECURITY: Validate required credentials
|
|
103
|
-
if (!config.apiUrl) {
|
|
104
|
-
throw new Error(
|
|
105
|
-
'SECURITY ERROR: AGENTSBANK_API_URL is required. ' +
|
|
106
|
-
'See SKILL.md for credential requirements.'
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const hasApiKey = !!config.apiKey;
|
|
111
|
-
const hasCredentials = !!(config.agentUsername && config.agentPassword);
|
|
112
|
-
const hasToken = !!config.token;
|
|
113
|
-
|
|
114
|
-
if (!hasApiKey && !hasCredentials && !hasToken) {
|
|
115
|
-
throw new Error(
|
|
116
|
-
'SECURITY ERROR: Authentication required. Provide one of: ' +
|
|
117
|
-
'apiKey, (agentUsername + agentPassword), or token. ' +
|
|
118
|
-
'See SKILL.md for setup instructions.'
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (config.autonomousMode) {
|
|
123
|
-
console.warn(
|
|
124
|
-
'⚠️ WARNING: AgentsBankSDK running in AUTONOMOUS MODE ⚠️\n' +
|
|
125
|
-
'Financial transactions will execute WITHOUT human approval.\n' +
|
|
126
|
-
'Ensure guardrails and spending limits are properly configured.\n' +
|
|
127
|
-
'This mode should only be used for trusted autonomous agents.'
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
this.config = config;
|
|
132
|
-
this.token = config.token;
|
|
133
|
-
this.auditLogger = config.auditLogger || this.defaultAuditLogger;
|
|
134
|
-
|
|
135
|
-
this.client = axios.create({
|
|
136
|
-
baseURL: config.apiUrl,
|
|
137
|
-
timeout: 10000,
|
|
138
|
-
headers: {
|
|
139
|
-
'Content-Type': 'application/json',
|
|
140
|
-
'User-Agent': 'AgentsBank-SDK/0.1.0',
|
|
141
|
-
},
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
// Add token to all requests
|
|
145
|
-
this.client.interceptors.request.use((conf) => {
|
|
146
|
-
if (this.token) {
|
|
147
|
-
conf.headers.Authorization = `Bearer ${this.token}`;
|
|
148
|
-
}
|
|
149
|
-
if (config.apiKey) {
|
|
150
|
-
conf.headers['X-API-Key'] = config.apiKey;
|
|
151
|
-
}
|
|
152
|
-
return conf;
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
// Handle errors with better messages
|
|
156
|
-
this.client.interceptors.response.use(
|
|
157
|
-
(response) => response,
|
|
158
|
-
(error) => {
|
|
159
|
-
// Improve error messages for debugging
|
|
160
|
-
if (error.response) {
|
|
161
|
-
const status = error.response.status;
|
|
162
|
-
const errorData = error.response.data;
|
|
163
|
-
const message = errorData?.error || errorData?.message || 'API Error';
|
|
164
|
-
const enhancedError = new Error(
|
|
165
|
-
`API Error ${status}: ${message}\nEndpoint: ${error.config?.url}`
|
|
166
|
-
);
|
|
167
|
-
enhancedError.name = 'APIError';
|
|
168
|
-
return Promise.reject(enhancedError);
|
|
169
|
-
}
|
|
170
|
-
if (error.request) {
|
|
171
|
-
const enhancedError = new Error(
|
|
172
|
-
`Network Error: No response from ${error.config?.baseURL}\nMake sure the API is online`
|
|
173
|
-
);
|
|
174
|
-
enhancedError.name = 'NetworkError';
|
|
175
|
-
return Promise.reject(enhancedError);
|
|
176
|
-
}
|
|
177
|
-
return Promise.reject(error);
|
|
178
|
-
}
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Default audit logger - logs to console (override with custom logger)
|
|
184
|
-
*/
|
|
185
|
-
private defaultAuditLogger(event: AuditEvent): void {
|
|
186
|
-
console.log(`[AUDIT] ${event.operation.toUpperCase()} - ${event.status}`, {
|
|
187
|
-
timestamp: event.timestamp.toISOString(),
|
|
188
|
-
userId: event.userId || 'system',
|
|
189
|
-
walletId: event.walletId,
|
|
190
|
-
txId: event.txId,
|
|
191
|
-
...(event.error && { error: event.error }),
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Internal audit logging
|
|
197
|
-
*/
|
|
198
|
-
private logAudit(event: AuditEvent): void {
|
|
199
|
-
this.auditLogger(event);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Login with agent credentials
|
|
204
|
-
*/
|
|
205
|
-
async login(): Promise<string> {
|
|
206
|
-
if (!this.config.agentUsername || !this.config.agentPassword) {
|
|
207
|
-
throw new Error('agentUsername and agentPassword required for login');
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
try {
|
|
211
|
-
const { data } = await this.client.post('/api/auth/agent/login', {
|
|
212
|
-
agent_username: this.config.agentUsername,
|
|
213
|
-
agent_password: this.config.agentPassword,
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
this.token = data.token;
|
|
217
|
-
|
|
218
|
-
this.logAudit({
|
|
219
|
-
timestamp: new Date(),
|
|
220
|
-
operation: 'auth_login',
|
|
221
|
-
status: 'success',
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
return data.token;
|
|
225
|
-
} catch (error) {
|
|
226
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
227
|
-
|
|
228
|
-
this.logAudit({
|
|
229
|
-
timestamp: new Date(),
|
|
230
|
-
operation: 'auth_login',
|
|
231
|
-
status: 'failed',
|
|
232
|
-
error: errorMessage,
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
// Re-throw with context
|
|
236
|
-
if (errorMessage.includes('API Error 401')) {
|
|
237
|
-
throw new Error('Authentication failed: Invalid credentials. Check agent_username and agent_password.');
|
|
238
|
-
} else if (errorMessage.includes('Network Error')) {
|
|
239
|
-
throw new Error(`Cannot reach API at ${this.config.apiUrl}. API may be offline.`);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
throw error;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Create a new wallet
|
|
248
|
-
*/
|
|
249
|
-
async createWallet(
|
|
250
|
-
chain: 'ethereum' | 'bsc' | 'solana',
|
|
251
|
-
type: 'custodial' | 'non-custodial' = 'non-custodial'
|
|
252
|
-
): Promise<WalletInfo> {
|
|
253
|
-
if (!this.token) await this.login();
|
|
254
|
-
|
|
255
|
-
const { data } = await this.client.post('/api/wallets', {
|
|
256
|
-
chain,
|
|
257
|
-
type,
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
return data;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Get wallet details
|
|
265
|
-
*/
|
|
266
|
-
async getWallet(walletId: string): Promise<WalletInfo> {
|
|
267
|
-
const { data } = await this.client.get(`/api/wallets/${walletId}`);
|
|
268
|
-
return data;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* List all wallets for agent
|
|
273
|
-
*/
|
|
274
|
-
async listWallets(): Promise<WalletInfo[]> {
|
|
275
|
-
const { data } = await this.client.get('/api/wallets');
|
|
276
|
-
return data.wallets;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Get wallet balance
|
|
281
|
-
*/
|
|
282
|
-
async getBalance(walletId: string): Promise<Record<string, string>> {
|
|
283
|
-
const { data } = await this.client.get(`/api/wallets/${walletId}/balance`);
|
|
284
|
-
return data.balance;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* Estimate gas for transaction
|
|
289
|
-
*/
|
|
290
|
-
async estimateGas(
|
|
291
|
-
walletId: string,
|
|
292
|
-
toAddress: string,
|
|
293
|
-
amount: string
|
|
294
|
-
): Promise<{ estimated_gas: string }> {
|
|
295
|
-
const { data } = await this.client.get(`/api/wallets/${walletId}/estimate-gas`, {
|
|
296
|
-
params: { to_address: toAddress, amount },
|
|
297
|
-
});
|
|
298
|
-
return data;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* ⚠️ FINANCIAL OPERATION: Send transaction
|
|
303
|
-
*
|
|
304
|
-
* DEFAULT: Requires UserApprovalContext with human approval evidence
|
|
305
|
-
* - Prevents autonomous execution by default
|
|
306
|
-
* - Requires userId of approver and approval timestamp
|
|
307
|
-
* - All transactions logged in audit trail
|
|
308
|
-
*
|
|
309
|
-
* AUTONOMOUS MODE: If enabled in SDKConfig, can run without approval
|
|
310
|
-
* - Use only for trusted autonomous agents with guardrails
|
|
311
|
-
* - Still requires audit logging and guardrails validation
|
|
312
|
-
*
|
|
313
|
-
* @param walletId Source wallet ID
|
|
314
|
-
* @param toAddress Recipient blockchain address
|
|
315
|
-
* @param amount Transaction amount
|
|
316
|
-
* @param approval User approval context (OPTIONAL if autonomousMode enabled)
|
|
317
|
-
* @param currency Asset to transfer (default: ETH)
|
|
318
|
-
*/
|
|
319
|
-
async sendTransaction(
|
|
320
|
-
walletId: string,
|
|
321
|
-
toAddress: string,
|
|
322
|
-
amount: string,
|
|
323
|
-
approval?: UserApprovalContext,
|
|
324
|
-
currency: string = 'ETH'
|
|
325
|
-
): Promise<TransactionInfo> {
|
|
326
|
-
// ⚠️ SECURITY: Check approval requirement
|
|
327
|
-
if (!this.config.autonomousMode) {
|
|
328
|
-
// Default mode: approval REQUIRED
|
|
329
|
-
if (!approval || !approval.userId || !approval.approvedAt) {
|
|
330
|
-
throw new Error(
|
|
331
|
-
'SECURITY ERROR: User approval context required for transactions. ' +
|
|
332
|
-
'Provide userId and approvedAt timestamp, or enable autonomousMode. ' +
|
|
333
|
-
'This prevents autonomous financial operations by default.'
|
|
334
|
-
);
|
|
335
|
-
}
|
|
336
|
-
} else if (!approval) {
|
|
337
|
-
// Autonomous mode: generate synthetic approval context
|
|
338
|
-
approval = {
|
|
339
|
-
userId: `agent_autonomous_${this.config.agentUsername || 'system'}`,
|
|
340
|
-
approvedAt: new Date(),
|
|
341
|
-
reason: 'Autonomous agent execution - autonomousMode enabled',
|
|
342
|
-
approvalMethod: 'autonomous',
|
|
343
|
-
};
|
|
344
|
-
|
|
345
|
-
this.logAudit({
|
|
346
|
-
timestamp: new Date(),
|
|
347
|
-
operation: 'transaction_send',
|
|
348
|
-
status: 'initiated',
|
|
349
|
-
error: 'AUTONOMOUS_MODE_ENABLED - No human approval provided',
|
|
350
|
-
});
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
// Log transaction initiation
|
|
354
|
-
this.logAudit({
|
|
355
|
-
timestamp: new Date(),
|
|
356
|
-
operation: 'transaction_send',
|
|
357
|
-
status: 'initiated',
|
|
358
|
-
walletId,
|
|
359
|
-
userId: approval?.userId,
|
|
360
|
-
amount,
|
|
361
|
-
toAddress,
|
|
362
|
-
});
|
|
363
|
-
|
|
364
|
-
try {
|
|
365
|
-
const { data } = await this.client.post('/api/transactions', {
|
|
366
|
-
wallet_id: walletId,
|
|
367
|
-
to_address: toAddress,
|
|
368
|
-
amount,
|
|
369
|
-
currency,
|
|
370
|
-
type: 'transfer',
|
|
371
|
-
// Include approval evidence for audit trail
|
|
372
|
-
approval_user_id: approval.userId,
|
|
373
|
-
approval_timestamp: approval.approvedAt.toISOString(),
|
|
374
|
-
approval_reason: approval.reason,
|
|
375
|
-
approval_method: approval.approvalMethod || 'api',
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
// Log success
|
|
379
|
-
this.logAudit({
|
|
380
|
-
timestamp: new Date(),
|
|
381
|
-
operation: 'transaction_send',
|
|
382
|
-
status: 'success',
|
|
383
|
-
txId: data.tx_id,
|
|
384
|
-
walletId,
|
|
385
|
-
userId: approval?.userId,
|
|
386
|
-
amount,
|
|
387
|
-
toAddress,
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
return data;
|
|
391
|
-
} catch (error) {
|
|
392
|
-
// Log failure
|
|
393
|
-
this.logAudit({
|
|
394
|
-
timestamp: new Date(),
|
|
395
|
-
operation: 'transaction_send',
|
|
396
|
-
status: 'failed',
|
|
397
|
-
walletId,
|
|
398
|
-
userId: approval?.userId,
|
|
399
|
-
amount,
|
|
400
|
-
toAddress,
|
|
401
|
-
error: error instanceof Error ? error.message : String(error),
|
|
402
|
-
});
|
|
403
|
-
throw error;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
/**
|
|
408
|
-
* Get transaction details
|
|
409
|
-
*/
|
|
410
|
-
async getTransaction(txId: string): Promise<TransactionInfo> {
|
|
411
|
-
const { data } = await this.client.get(`/api/transactions/${txId}`);
|
|
412
|
-
return data;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
/**
|
|
416
|
-
* Get transaction history for wallet
|
|
417
|
-
*/
|
|
418
|
-
async getTransactionHistory(
|
|
419
|
-
walletId: string,
|
|
420
|
-
limit: number = 50
|
|
421
|
-
): Promise<TransactionInfo[]> {
|
|
422
|
-
const { data } = await this.client.get(
|
|
423
|
-
`/api/transactions/wallet/${walletId}`,
|
|
424
|
-
{ params: { limit } }
|
|
425
|
-
);
|
|
426
|
-
return data.transactions;
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
/**
|
|
430
|
-
* Get transaction statistics
|
|
431
|
-
*/
|
|
432
|
-
async getStats(walletId: string, days: number = 30): Promise<any> {
|
|
433
|
-
const { data } = await this.client.get(
|
|
434
|
-
`/api/transactions/wallet/${walletId}/stats`,
|
|
435
|
-
{ params: { days } }
|
|
436
|
-
);
|
|
437
|
-
return data;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
/**
|
|
441
|
-
* Wait for transaction to be confirmed
|
|
442
|
-
*/
|
|
443
|
-
async waitForConfirmation(
|
|
444
|
-
txId: string,
|
|
445
|
-
maxWaitMs: number = 300000,
|
|
446
|
-
pollIntervalMs: number = 5000
|
|
447
|
-
): Promise<TransactionInfo> {
|
|
448
|
-
const startTime = Date.now();
|
|
449
|
-
|
|
450
|
-
while (Date.now() - startTime < maxWaitMs) {
|
|
451
|
-
const tx = await this.getTransaction(txId);
|
|
452
|
-
|
|
453
|
-
if (tx.status !== 'pending') {
|
|
454
|
-
return tx;
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
throw new Error('Transaction confirmation timeout');
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
/**
|
|
464
|
-
* Update API key
|
|
465
|
-
*/
|
|
466
|
-
async regenerateApiKey(): Promise<string> {
|
|
467
|
-
const { data } = await this.client.post('/api/auth/agent/regenerate-key');
|
|
468
|
-
return data.api_key;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
/**
|
|
472
|
-
* Refresh JWT token
|
|
473
|
-
*/
|
|
474
|
-
async refreshToken(): Promise<string> {
|
|
475
|
-
const { data } = await this.client.post('/api/auth/refresh');
|
|
476
|
-
this.token = data.token;
|
|
477
|
-
return data.token;
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
// Export for convenience
|
|
482
|
-
export default AgentsBankSDK;
|
package/security-config.ts
DELETED
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AgentsBank SDK Security Configuration
|
|
3
|
-
*
|
|
4
|
-
* Defines security constraints and validation rules for the SDK
|
|
5
|
-
* To be used during development and deployment validation
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export const SDK_SECURITY_CONFIG = {
|
|
9
|
-
// ============================================
|
|
10
|
-
// Required Credentials
|
|
11
|
-
// ============================================
|
|
12
|
-
requiredCredentials: [
|
|
13
|
-
'AGENTSBANK_API_URL',
|
|
14
|
-
'AGENTSBANK_API_KEY | (AGENTSBANK_AGENT_USERNAME + AGENTSBANK_AGENT_PASSWORD)'
|
|
15
|
-
],
|
|
16
|
-
|
|
17
|
-
// ============================================
|
|
18
|
-
// Risk Assessment
|
|
19
|
-
// ============================================
|
|
20
|
-
riskLevel: 'HIGH' as const, // Financial transaction platform
|
|
21
|
-
financialOperations: true,
|
|
22
|
-
autonomousExecutionAllowed: false, // DEFAULT: Must not be autonomously invocable
|
|
23
|
-
autonomousModeSupportedButOptional: true, // Can be enabled via config flag if needed
|
|
24
|
-
defaultRequiresApproval: true, // By default, all transactions require approval
|
|
25
|
-
|
|
26
|
-
// ============================================
|
|
27
|
-
// Credential Scope & Constraints
|
|
28
|
-
// ============================================
|
|
29
|
-
credentialScopes: {
|
|
30
|
-
'AGENTSBANK_API_URL': {
|
|
31
|
-
required: true,
|
|
32
|
-
type: 'url' as const,
|
|
33
|
-
description: 'Base URL of AgentsBank API',
|
|
34
|
-
example: 'https://api.agentsbank.ai',
|
|
35
|
-
defaultIfMissing: null, // NO DEFAULT - must be explicit
|
|
36
|
-
},
|
|
37
|
-
'AGENTSBANK_API_KEY': {
|
|
38
|
-
required: false,
|
|
39
|
-
type: 'secret' as const,
|
|
40
|
-
description: 'API Key for authentication (recommended)',
|
|
41
|
-
example: 'sk_live_...',
|
|
42
|
-
rotationInterval: 30 * 24 * 60 * 60 * 1000, // 30 days in ms
|
|
43
|
-
defaultIfMissing: null,
|
|
44
|
-
},
|
|
45
|
-
'AGENTSBANK_AGENT_USERNAME': {
|
|
46
|
-
required: false,
|
|
47
|
-
type: 'string' as const,
|
|
48
|
-
description: 'Agent username (alternative auth method)',
|
|
49
|
-
example: 'agent_123',
|
|
50
|
-
defaultIfMissing: null,
|
|
51
|
-
},
|
|
52
|
-
'AGENTSBANK_AGENT_PASSWORD': {
|
|
53
|
-
required: false,
|
|
54
|
-
type: 'secret' as const,
|
|
55
|
-
description: 'Agent password (alternative auth method)',
|
|
56
|
-
example: 'secret_password',
|
|
57
|
-
defaultIfMissing: null,
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
// ============================================
|
|
62
|
-
// Financial Operation Constraints
|
|
63
|
-
// ============================================
|
|
64
|
-
financialOperationConstraints: {
|
|
65
|
-
sendTransaction: {
|
|
66
|
-
requiresUserApprovalContext: true, // DEFAULT: Always required
|
|
67
|
-
canBypassApprovalInAutonomousMode: true, // Can be disabled if autonomousMode=true in SDKConfig
|
|
68
|
-
requiresUserId: true,
|
|
69
|
-
requiresApprovalTimestamp: true,
|
|
70
|
-
auditLoggingRequired: true,
|
|
71
|
-
atomicity: 'required' as const, // Must succeed or fail completely
|
|
72
|
-
rollbackOnFailure: true,
|
|
73
|
-
warningIfAutonomous: 'Executing financial transaction WITHOUT human approval',
|
|
74
|
-
},
|
|
75
|
-
createWallet: {
|
|
76
|
-
requiresUserApprovalContext: false, // Optional for wallet creation
|
|
77
|
-
auditLoggingRequired: true,
|
|
78
|
-
typeValidation: ['custodial', 'non-custodial'],
|
|
79
|
-
},
|
|
80
|
-
estimateGas: {
|
|
81
|
-
requiresUserApprovalContext: false,
|
|
82
|
-
auditLoggingRequired: false, // Informational only
|
|
83
|
-
cacheable: true, // Can cache results for same params
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
|
|
87
|
-
// ============================================
|
|
88
|
-
// Audit Trail Requirements
|
|
89
|
-
// ============================================
|
|
90
|
-
auditRequirements: {
|
|
91
|
-
requiredFields: [
|
|
92
|
-
'timestamp',
|
|
93
|
-
'operation',
|
|
94
|
-
'status',
|
|
95
|
-
'userId', // For financial operations
|
|
96
|
-
'walletId', // For wallet operations
|
|
97
|
-
],
|
|
98
|
-
retention: {
|
|
99
|
-
production: 7 * 365 * 24 * 60 * 60 * 1000, // 7 years
|
|
100
|
-
development: 90 * 24 * 60 * 60 * 1000, // 90 days
|
|
101
|
-
},
|
|
102
|
-
sensitiveOperations: [
|
|
103
|
-
'transaction_send',
|
|
104
|
-
'auth_login',
|
|
105
|
-
'token_refresh',
|
|
106
|
-
'wallet_create'
|
|
107
|
-
],
|
|
108
|
-
},
|
|
109
|
-
|
|
110
|
-
// ============================================
|
|
111
|
-
// Deployment Constraints
|
|
112
|
-
// ============================================
|
|
113
|
-
deploymentConstraints: {
|
|
114
|
-
allowedEnvironments: ['development', 'staging', 'production'],
|
|
115
|
-
productionRequirements: [
|
|
116
|
-
'Credentials stored in secrets manager',
|
|
117
|
-
'Custom audit logger configured',
|
|
118
|
-
'Rate limiting enabled',
|
|
119
|
-
'Error monitoring (Sentry, DataDog, etc.)',
|
|
120
|
-
'Credential rotation scheduled',
|
|
121
|
-
],
|
|
122
|
-
forbiddenPatternsInCode: [
|
|
123
|
-
'sk_live_', // API keys should not be in code
|
|
124
|
-
'sk_sandbox_',
|
|
125
|
-
'password:',
|
|
126
|
-
'secret:',
|
|
127
|
-
'token:',
|
|
128
|
-
],
|
|
129
|
-
},
|
|
130
|
-
|
|
131
|
-
// ============================================
|
|
132
|
-
// Rate Limiting Defaults
|
|
133
|
-
// ============================================
|
|
134
|
-
rateLimiting: {
|
|
135
|
-
transactionsPerMinute: 5,
|
|
136
|
-
maxAmountPerTransaction: '1000', // Max 1000 of currency
|
|
137
|
-
maxDailyAmount: '10000', // Max 10000 per day per agent
|
|
138
|
-
},
|
|
139
|
-
|
|
140
|
-
// ============================================
|
|
141
|
-
// Validation Functions
|
|
142
|
-
// ============================================
|
|
143
|
-
validators: {
|
|
144
|
-
isValidApiUrl: (url: string | undefined): boolean => {
|
|
145
|
-
if (!url) return false;
|
|
146
|
-
try {
|
|
147
|
-
new URL(url);
|
|
148
|
-
return url.startsWith('https://');
|
|
149
|
-
} catch {
|
|
150
|
-
return false;
|
|
151
|
-
}
|
|
152
|
-
},
|
|
153
|
-
|
|
154
|
-
isValidApiKey: (key: string | undefined): boolean => {
|
|
155
|
-
if (!key) return false;
|
|
156
|
-
return key.startsWith('sk_') && key.length > 20;
|
|
157
|
-
},
|
|
158
|
-
|
|
159
|
-
isValidEthereumAddress: (address: string): boolean => {
|
|
160
|
-
return /^0x[a-fA-F0-9]{40}$/.test(address);
|
|
161
|
-
},
|
|
162
|
-
|
|
163
|
-
isValidAmount: (amount: string): boolean => {
|
|
164
|
-
const num = parseFloat(amount);
|
|
165
|
-
return !isNaN(num) && num > 0;
|
|
166
|
-
},
|
|
167
|
-
},
|
|
168
|
-
} as const;
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Validates SDK configuration before use
|
|
172
|
-
* Throws error if validation fails
|
|
173
|
-
*/
|
|
174
|
-
export function validateSDKConfiguration(config: Record<string, any>): void {
|
|
175
|
-
// Check required API URL
|
|
176
|
-
if (!config.apiUrl) {
|
|
177
|
-
throw new Error(
|
|
178
|
-
'SECURITY VALIDATION FAILED: AGENTSBANK_API_URL is required. ' +
|
|
179
|
-
'See SKILL.md for credential requirements.'
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
if (!SDK_SECURITY_CONFIG.validators.isValidApiUrl(config.apiUrl)) {
|
|
184
|
-
throw new Error(
|
|
185
|
-
'SECURITY VALIDATION FAILED: Invalid API URL. ' +
|
|
186
|
-
'Must be HTTPS URL. Example: https://api.agentsbank.ai'
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Check at least one authentication method
|
|
191
|
-
const hasApiKey = !!config.apiKey && SDK_SECURITY_CONFIG.validators.isValidApiKey(config.apiKey);
|
|
192
|
-
const hasCredentials = config.agentUsername && config.agentPassword;
|
|
193
|
-
const hasToken = !!config.token;
|
|
194
|
-
|
|
195
|
-
if (!hasApiKey && !hasCredentials && !hasToken) {
|
|
196
|
-
throw new Error(
|
|
197
|
-
'SECURITY VALIDATION FAILED: No authentication provided. ' +
|
|
198
|
-
'Provide one of: apiKey, (agentUsername + agentPassword), or token. ' +
|
|
199
|
-
'See SKILL.md for setup instructions.'
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Validates user approval context for financial operations
|
|
206
|
-
*/
|
|
207
|
-
export function validateUserApprovalContext(approval: any): void {
|
|
208
|
-
if (!approval) {
|
|
209
|
-
throw new Error(
|
|
210
|
-
'SECURITY ERROR: User approval context required for financial operations. ' +
|
|
211
|
-
'Cannot execute financial operations autonomously.'
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
if (!approval.userId) {
|
|
216
|
-
throw new Error(
|
|
217
|
-
'SECURITY ERROR: approval.userId required. ' +
|
|
218
|
-
'Must identify human who approved this operation.'
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
if (!approval.approvedAt || !(approval.approvedAt instanceof Date)) {
|
|
223
|
-
throw new Error(
|
|
224
|
-
'SECURITY ERROR: approval.approvedAt required (Date object). ' +
|
|
225
|
-
'Must have timestamp of when approval was granted.'
|
|
226
|
-
);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
// Check approval is recent (within last hour)
|
|
230
|
-
const ageMs = Date.now() - approval.approvedAt.getTime();
|
|
231
|
-
const maxAgeMs = 60 * 60 * 1000; // 1 hour
|
|
232
|
-
|
|
233
|
-
if (ageMs > maxAgeMs) {
|
|
234
|
-
throw new Error(
|
|
235
|
-
`SECURITY ERROR: Approval too old (${Math.round(ageMs / 1000)}s). ` +
|
|
236
|
-
'User approval must be renewed within 1 hour of transaction.'
|
|
237
|
-
);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Validates financial operation parameters
|
|
243
|
-
*/
|
|
244
|
-
export function validateFinancialOperationParams(
|
|
245
|
-
walletId: string,
|
|
246
|
-
toAddress: string,
|
|
247
|
-
amount: string
|
|
248
|
-
): void {
|
|
249
|
-
if (!walletId) {
|
|
250
|
-
throw new Error('walletId is required');
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
if (!toAddress) {
|
|
254
|
-
throw new Error('toAddress is required');
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (!SDK_SECURITY_CONFIG.validators.isValidEthereumAddress(toAddress)) {
|
|
258
|
-
throw new Error(`Invalid Ethereum address: ${toAddress}`);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
if (!amount) {
|
|
262
|
-
throw new Error('amount is required');
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if (!SDK_SECURITY_CONFIG.validators.isValidAmount(amount)) {
|
|
266
|
-
throw new Error(`Invalid amount: ${amount}. Must be a positive number.`);
|
|
267
|
-
}
|
|
268
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"lib": ["ES2020"],
|
|
6
|
-
"outDir": "./dist",
|
|
7
|
-
"rootDir": ".",
|
|
8
|
-
"strict": true,
|
|
9
|
-
"declaration": true,
|
|
10
|
-
"declarationMap": true,
|
|
11
|
-
"sourceMap": true,
|
|
12
|
-
"moduleResolution": "bundler",
|
|
13
|
-
"skipLibCheck": true,
|
|
14
|
-
"forceConsistentCasingInFileNames": true
|
|
15
|
-
},
|
|
16
|
-
"include": ["index.ts", "security-config.ts"],
|
|
17
|
-
"exclude": ["dist", "node_modules"]
|
|
18
|
-
}
|