@naturalpay/sdk 0.1.1 → 0.1.3
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/README.md +23 -231
- package/dist/index.cjs +40 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -4
- package/dist/index.d.ts +21 -4
- package/dist/index.js +39 -5
- package/dist/index.js.map +1 -1
- package/dist/mcp/cli.cjs +1 -1
- package/dist/mcp/cli.cjs.map +1 -1
- package/dist/mcp/cli.js +1 -1
- package/dist/mcp/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,260 +1,52 @@
|
|
|
1
|
-
# Natural Payments
|
|
1
|
+
# Natural Payments SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://npmjs.org/package/@naturalpay/sdk)
|
|
4
|
+
|
|
5
|
+
The Natural Payments SDK provides access to the [Natural API](https://docs.natural.co) from server-side TypeScript and JavaScript applications, for building AI agents that send, receive, and manage money.
|
|
6
|
+
|
|
7
|
+
## Documentation
|
|
8
|
+
|
|
9
|
+
Full documentation, guides, and API reference are available at **[docs.natural.co/guides/platform/sdks](https://docs.natural.co/guides/platform/sdks)**.
|
|
4
10
|
|
|
5
11
|
## Installation
|
|
6
12
|
|
|
7
|
-
```
|
|
13
|
+
```sh
|
|
8
14
|
npm install @naturalpay/sdk
|
|
9
|
-
# or
|
|
10
|
-
pnpm add @naturalpay/sdk
|
|
11
|
-
# or
|
|
12
|
-
yarn add @naturalpay/sdk
|
|
13
15
|
```
|
|
14
16
|
|
|
15
|
-
##
|
|
17
|
+
## Getting started
|
|
16
18
|
|
|
17
19
|
```typescript
|
|
18
20
|
import { NaturalClient } from '@naturalpay/sdk';
|
|
19
21
|
|
|
20
|
-
const client = new NaturalClient({
|
|
21
|
-
apiKey: process.env.NATURAL_API_KEY, // or pass directly
|
|
22
|
-
});
|
|
22
|
+
const client = new NaturalClient({ apiKey: process.env['NATURAL_API_KEY'] });
|
|
23
23
|
|
|
24
|
-
// Create a payment
|
|
25
24
|
const payment = await client.payments.create({
|
|
26
|
-
agentId: 'agent_123',
|
|
27
|
-
instanceId: 'instance_456',
|
|
28
|
-
amount: 5000,
|
|
29
|
-
customerPartyId: 'party_456',
|
|
30
25
|
recipient: 'alice@example.com',
|
|
26
|
+
amount: 5000,
|
|
31
27
|
memo: 'Payment for consulting',
|
|
32
|
-
|
|
28
|
+
agentId: 'agt_019cd1798d637a4da75dce386343931d',
|
|
29
|
+
instanceId: 'session-abc123',
|
|
30
|
+
customerPartyId: 'pty_019cd34e27c179bfbbe6870486b11b67',
|
|
31
|
+
idempotencyKey: 'pay_unique_key',
|
|
33
32
|
});
|
|
34
33
|
|
|
35
|
-
console.log(
|
|
36
|
-
|
|
37
|
-
// Check balance
|
|
38
|
-
const balance = await client.wallet.balance();
|
|
39
|
-
console.log(`Available: ${balance.available.amountMinor} minor units`);
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Configuration
|
|
43
|
-
|
|
44
|
-
### Environment Variables
|
|
45
|
-
|
|
46
|
-
- `NATURAL_API_KEY` - Your API key (starts with `sk_ntl_sandbox_` or `sk_ntl_live_`)
|
|
47
|
-
- `NATURAL_SERVER_URL` - API base URL (default: `https://api.natural.co`)
|
|
48
|
-
|
|
49
|
-
### Client Options
|
|
50
|
-
|
|
51
|
-
```typescript
|
|
52
|
-
const client = new NaturalClient({
|
|
53
|
-
apiKey: 'sk_ntl_sandbox_xxx', // API key
|
|
54
|
-
baseUrl: 'https://api.natural.co', // Custom base URL
|
|
55
|
-
timeout: 30000, // Request timeout in ms
|
|
56
|
-
});
|
|
34
|
+
console.log(payment.transactionId);
|
|
57
35
|
```
|
|
58
36
|
|
|
59
|
-
##
|
|
37
|
+
## MCP server
|
|
60
38
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
// Create a payment
|
|
65
|
-
const payment = await client.payments.create({
|
|
66
|
-
agentId: 'agent_123',
|
|
67
|
-
instanceId: 'instance_789', // required when agentId is provided
|
|
68
|
-
amount: 10000,
|
|
69
|
-
customerPartyId: 'party_456',
|
|
70
|
-
recipient: 'alice@example.com', // email, phone, or party ID (pty_xxx)
|
|
71
|
-
memo: 'Payment description',
|
|
72
|
-
idempotencyKey: 'unique-key-for-this-payment',
|
|
73
|
-
});
|
|
74
|
-
```
|
|
39
|
+
The SDK ships with an MCP server for AI agent integration with Claude Desktop, Cursor, and other MCP clients:
|
|
75
40
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
```typescript
|
|
79
|
-
// Get account balance
|
|
80
|
-
const balance = await client.wallet.balance();
|
|
81
|
-
|
|
82
|
-
// Withdraw funds
|
|
83
|
-
const withdrawal = await client.wallet.withdraw({
|
|
84
|
-
amount: 50000,
|
|
85
|
-
externalFundingSourceId: 'efs_xxx',
|
|
86
|
-
idempotencyKey: 'wd_unique_key',
|
|
87
|
-
});
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Transactions
|
|
91
|
-
|
|
92
|
-
```typescript
|
|
93
|
-
import { TransactionTypeFilter } from '@naturalpay/sdk';
|
|
94
|
-
|
|
95
|
-
// List all transactions
|
|
96
|
-
const transactions = await client.transactions.list({
|
|
97
|
-
limit: 100,
|
|
98
|
-
agentId: 'agent_123',
|
|
99
|
-
instanceId: 'instance_789', // required when agentId is provided
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
// List only transfers
|
|
103
|
-
const transfers = await client.transactions.list({
|
|
104
|
-
type: TransactionTypeFilter.TRANSFER,
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
// List only payments
|
|
108
|
-
const payments = await client.transactions.list({
|
|
109
|
-
type: TransactionTypeFilter.PAYMENT,
|
|
110
|
-
});
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
### Agents
|
|
114
|
-
|
|
115
|
-
```typescript
|
|
116
|
-
// List agents
|
|
117
|
-
const agents = await client.agents.list({
|
|
118
|
-
status: 'ACTIVE',
|
|
119
|
-
limit: 50,
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
// Create an agent
|
|
123
|
-
const agent = await client.agents.create({
|
|
124
|
-
name: 'Shopping Assistant',
|
|
125
|
-
partyId: 'party_123',
|
|
126
|
-
description: 'Handles shopping tasks',
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
// Update an agent
|
|
130
|
-
const updated = await client.agents.update('agent_id', {
|
|
131
|
-
name: 'Updated Name',
|
|
132
|
-
status: 'REVOKED',
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
// Delete an agent
|
|
136
|
-
await client.agents.delete('agent_id');
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### Delegations
|
|
140
|
-
|
|
141
|
-
```typescript
|
|
142
|
-
// List agent delegations
|
|
143
|
-
const delegations = await client.delegations.list({
|
|
144
|
-
limit: 50,
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
// Get delegation details
|
|
148
|
-
const delegation = await client.delegations.get('adl_xxx');
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
### Customers
|
|
152
|
-
|
|
153
|
-
```typescript
|
|
154
|
-
// List customers who have delegated to you
|
|
155
|
-
const customers = await client.customers.list({
|
|
156
|
-
limit: 50,
|
|
157
|
-
});
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
## MCP Server
|
|
161
|
-
|
|
162
|
-
The SDK includes an MCP (Model Context Protocol) server for AI agent integration.
|
|
163
|
-
|
|
164
|
-
### CLI Usage
|
|
165
|
-
|
|
166
|
-
Use `npx` to run the CLI without global installation:
|
|
167
|
-
|
|
168
|
-
```bash
|
|
169
|
-
# Show help
|
|
170
|
-
npx @naturalpay/sdk --help
|
|
171
|
-
|
|
172
|
-
# Start MCP server with stdio transport
|
|
41
|
+
```sh
|
|
173
42
|
npx @naturalpay/sdk mcp serve
|
|
174
|
-
|
|
175
|
-
# With explicit options
|
|
176
|
-
npx @naturalpay/sdk mcp serve --api-key sk_ntl_sandbox_xxx --mcp-url https://mcp.natural.co
|
|
177
43
|
```
|
|
178
44
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
### Claude Desktop / Cursor Config
|
|
182
|
-
|
|
183
|
-
```json
|
|
184
|
-
{
|
|
185
|
-
"mcpServers": {
|
|
186
|
-
"natural": {
|
|
187
|
-
"command": "npx",
|
|
188
|
-
"args": ["@naturalpay/sdk", "mcp", "serve"],
|
|
189
|
-
"env": { "NATURAL_API_KEY": "sk_ntl_..." }
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### Available MCP Tools
|
|
196
|
-
|
|
197
|
-
| Tool | Description |
|
|
198
|
-
|------|-------------|
|
|
199
|
-
| `create_payment` | Create a payment to a recipient |
|
|
200
|
-
| `get_payment_status` | Check payment status by transfer ID |
|
|
201
|
-
| `get_account_balance` | Get current wallet balance |
|
|
202
|
-
| `list_transactions` | List recent transactions |
|
|
203
|
-
| `list_agents` | List agents for the partner |
|
|
204
|
-
| `list_customers` | List customers who delegated to you |
|
|
45
|
+
See [docs.natural.co/guides/platform/sdks#mcp-server](https://docs.natural.co/guides/platform/sdks#mcp-server) for client configuration.
|
|
205
46
|
|
|
206
|
-
##
|
|
47
|
+
## Requirements
|
|
207
48
|
|
|
208
|
-
|
|
209
|
-
import {
|
|
210
|
-
NaturalError,
|
|
211
|
-
AuthenticationError,
|
|
212
|
-
InvalidRequestError,
|
|
213
|
-
PaymentError,
|
|
214
|
-
InsufficientFundsError,
|
|
215
|
-
RecipientNotFoundError,
|
|
216
|
-
RateLimitError,
|
|
217
|
-
ServerError,
|
|
218
|
-
} from '@naturalpay/sdk';
|
|
219
|
-
|
|
220
|
-
try {
|
|
221
|
-
await client.payments.create({ ... });
|
|
222
|
-
} catch (error) {
|
|
223
|
-
if (error instanceof AuthenticationError) {
|
|
224
|
-
// Handle authentication issues (401)
|
|
225
|
-
} else if (error instanceof InsufficientFundsError) {
|
|
226
|
-
// Handle insufficient balance
|
|
227
|
-
} else if (error instanceof RecipientNotFoundError) {
|
|
228
|
-
// Handle invalid recipient
|
|
229
|
-
} else if (error instanceof RateLimitError) {
|
|
230
|
-
// Handle rate limiting (429)
|
|
231
|
-
console.log(`Retry after: ${error.retryAfter}s`);
|
|
232
|
-
} else if (error instanceof ServerError) {
|
|
233
|
-
// Handle server errors (5xx)
|
|
234
|
-
} else if (error instanceof NaturalError) {
|
|
235
|
-
// Handle other API errors
|
|
236
|
-
console.log(`Error: ${error.message}, Code: ${error.code}`);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
## TypeScript Support
|
|
242
|
-
|
|
243
|
-
This SDK is written in TypeScript and provides full type definitions:
|
|
244
|
-
|
|
245
|
-
```typescript
|
|
246
|
-
import type {
|
|
247
|
-
PaymentCreateParams,
|
|
248
|
-
AccountBalance,
|
|
249
|
-
Transaction,
|
|
250
|
-
TransactionListResponse,
|
|
251
|
-
Agent,
|
|
252
|
-
AgentDelegation,
|
|
253
|
-
WithdrawResponse,
|
|
254
|
-
} from '@naturalpay/sdk';
|
|
255
|
-
|
|
256
|
-
import { TransactionTypeFilter } from '@naturalpay/sdk';
|
|
257
|
-
```
|
|
49
|
+
Node.js 18+
|
|
258
50
|
|
|
259
51
|
## License
|
|
260
52
|
|
package/dist/index.cjs
CHANGED
|
@@ -62,7 +62,7 @@ var ServerError = class extends NaturalError {
|
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
// src/version.ts
|
|
65
|
-
var VERSION = "0.1.
|
|
65
|
+
var VERSION = "0.1.3";
|
|
66
66
|
|
|
67
67
|
// src/logging.ts
|
|
68
68
|
var LOG_LEVEL_VALUES = {
|
|
@@ -312,6 +312,39 @@ function getToolCallHeader() {
|
|
|
312
312
|
var logger = getLogger("http");
|
|
313
313
|
var DEFAULT_BASE_URL = "https://api.natural.co";
|
|
314
314
|
var DEFAULT_TIMEOUT = 3e4;
|
|
315
|
+
var API_KEY_PREFIX_REGEX = /^sk_ntl_(dev|sandbox|prod)_/;
|
|
316
|
+
function parseApiKeyEnv(key) {
|
|
317
|
+
const match = API_KEY_PREFIX_REGEX.exec(key);
|
|
318
|
+
if (match) {
|
|
319
|
+
return match[1];
|
|
320
|
+
}
|
|
321
|
+
const preview = key.length > 16 ? `${key.slice(0, 16)}...` : key;
|
|
322
|
+
throw new InvalidRequestError(
|
|
323
|
+
`Invalid API key prefix. Expected a key starting with 'sk_ntl_dev_', 'sk_ntl_sandbox_', or 'sk_ntl_prod_'. Got: '${preview}'`
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
function validateBaseUrl(baseUrl) {
|
|
327
|
+
let url;
|
|
328
|
+
try {
|
|
329
|
+
url = new URL(baseUrl);
|
|
330
|
+
} catch {
|
|
331
|
+
throw new InvalidRequestError(`Invalid baseUrl: '${baseUrl}'. Must be a valid absolute URL.`);
|
|
332
|
+
}
|
|
333
|
+
if (url.protocol === "https:") {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
const host = url.hostname;
|
|
337
|
+
if (host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]") {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
const allowHttp = process.env["NATURAL_ALLOW_HTTP"];
|
|
341
|
+
if (allowHttp && allowHttp !== "0" && allowHttp.toLowerCase() !== "false") {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
throw new InvalidRequestError(
|
|
345
|
+
`baseUrl must use HTTPS (got '${baseUrl}'). To allow plaintext HTTP for development, set NATURAL_ALLOW_HTTP=1 or use a localhost host.`
|
|
346
|
+
);
|
|
347
|
+
}
|
|
315
348
|
function hashString(str) {
|
|
316
349
|
let hash = 0;
|
|
317
350
|
for (let i = 0; i < str.length; i++) {
|
|
@@ -329,6 +362,10 @@ var HTTPClient = class {
|
|
|
329
362
|
constructor(options = {}) {
|
|
330
363
|
this.apiKey = options.apiKey ?? process.env["NATURAL_API_KEY"] ?? "";
|
|
331
364
|
this.baseUrl = (options.baseUrl ?? process.env["NATURAL_SERVER_URL"] ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
365
|
+
validateBaseUrl(this.baseUrl);
|
|
366
|
+
if (this.apiKey) {
|
|
367
|
+
parseApiKeyEnv(this.apiKey);
|
|
368
|
+
}
|
|
332
369
|
this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
333
370
|
}
|
|
334
371
|
/**
|
|
@@ -338,9 +375,6 @@ var HTTPClient = class {
|
|
|
338
375
|
if (!this.apiKey) {
|
|
339
376
|
throw new AuthenticationError();
|
|
340
377
|
}
|
|
341
|
-
if (!this.apiKey.startsWith("sk_ntl_")) {
|
|
342
|
-
return this.apiKey;
|
|
343
|
-
}
|
|
344
378
|
const cacheKey = hashString(this.apiKey);
|
|
345
379
|
const cached = this.jwtCache.get(cacheKey);
|
|
346
380
|
if (cached && Date.now() < cached.expiresAt) {
|
|
@@ -1224,6 +1258,8 @@ exports.getLogger = getLogger;
|
|
|
1224
1258
|
exports.logApiCall = logApiCall;
|
|
1225
1259
|
exports.logError = logError;
|
|
1226
1260
|
exports.logToolCall = logToolCall;
|
|
1261
|
+
exports.parseApiKeyEnv = parseApiKeyEnv;
|
|
1227
1262
|
exports.runWithContext = runWithContext;
|
|
1263
|
+
exports.validateBaseUrl = validateBaseUrl;
|
|
1228
1264
|
//# sourceMappingURL=index.cjs.map
|
|
1229
1265
|
//# sourceMappingURL=index.cjs.map
|