agentspend 0.1.5 → 0.1.6
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/dist/commands/card.js +4 -1
- package/dist/commands/pay.js +58 -15
- package/package.json +1 -1
- package/src/commands/card.ts +5 -1
- package/src/commands/pay.ts +60 -14
package/dist/commands/card.js
CHANGED
|
@@ -93,7 +93,10 @@ function registerCardCommands(program) {
|
|
|
93
93
|
if (status.status === "ready") {
|
|
94
94
|
console.log(`Card is ready!`);
|
|
95
95
|
if (status.card_id) {
|
|
96
|
-
await (0, promises_1.writeFile)(CARD_FILE, JSON.stringify({
|
|
96
|
+
await (0, promises_1.writeFile)(CARD_FILE, JSON.stringify({
|
|
97
|
+
card_id: status.card_id,
|
|
98
|
+
card_secret: status.card_secret,
|
|
99
|
+
}, null, 2));
|
|
97
100
|
console.log(`Card ID saved to ${CARD_FILE}`);
|
|
98
101
|
}
|
|
99
102
|
// Clean up setup file
|
package/dist/commands/pay.js
CHANGED
|
@@ -7,10 +7,11 @@ const node_path_1 = require("node:path");
|
|
|
7
7
|
const CONFIG_DIR = (0, node_path_1.join)((0, node_os_1.homedir)(), ".agentspend");
|
|
8
8
|
const CARD_FILE = (0, node_path_1.join)(CONFIG_DIR, "card.json");
|
|
9
9
|
const WALLET_FILE = (0, node_path_1.join)(CONFIG_DIR, "wallet.json");
|
|
10
|
+
const API_BASE = process.env.AGENTSPEND_API_URL ?? "https://api.agentspend.co";
|
|
10
11
|
async function readCardConfig() {
|
|
11
12
|
try {
|
|
12
13
|
const data = JSON.parse(await (0, promises_1.readFile)(CARD_FILE, "utf-8"));
|
|
13
|
-
if (typeof data.card_id === "string" && data.card_id) {
|
|
14
|
+
if (typeof data.card_id === "string" && data.card_id && typeof data.card_secret === "string" && data.card_secret) {
|
|
14
15
|
return data;
|
|
15
16
|
}
|
|
16
17
|
}
|
|
@@ -42,31 +43,73 @@ function parseHeaders(headerArgs) {
|
|
|
42
43
|
}
|
|
43
44
|
return headers;
|
|
44
45
|
}
|
|
45
|
-
async function payWithCard(url,
|
|
46
|
+
async function payWithCard(url, cardConfig, body, extraHeaders) {
|
|
46
47
|
const headers = {
|
|
47
48
|
...extraHeaders,
|
|
48
|
-
"x-card-id":
|
|
49
|
+
"x-card-id": cardConfig.card_id,
|
|
49
50
|
};
|
|
50
51
|
if (body) {
|
|
51
52
|
headers["content-type"] = "application/json";
|
|
52
53
|
}
|
|
54
|
+
// Try with x-card-id
|
|
53
55
|
const res = await fetch(url, {
|
|
54
56
|
method: "POST",
|
|
55
57
|
headers,
|
|
56
58
|
body: body ?? undefined,
|
|
57
59
|
});
|
|
58
|
-
|
|
59
|
-
if (
|
|
60
|
-
console.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
// Success
|
|
61
|
+
if (res.ok) {
|
|
62
|
+
console.log("Payment successful (card)");
|
|
63
|
+
const data = await res.text();
|
|
64
|
+
try {
|
|
65
|
+
console.log(JSON.stringify(JSON.parse(data), null, 2));
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
console.log(data);
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
66
71
|
}
|
|
67
|
-
|
|
68
|
-
|
|
72
|
+
// 402 with agentspend.service_id — need to bind
|
|
73
|
+
if (res.status === 402) {
|
|
74
|
+
const errorBody = await res.json().catch(() => ({}));
|
|
75
|
+
const agentspend = errorBody?.agentspend;
|
|
76
|
+
const serviceId = agentspend?.service_id;
|
|
77
|
+
if (serviceId) {
|
|
78
|
+
console.log(`Binding to service ${serviceId}...`);
|
|
79
|
+
const bindRes = await fetch(`${API_BASE}/v1/card/${encodeURIComponent(cardConfig.card_id)}/bind`, {
|
|
80
|
+
method: "POST",
|
|
81
|
+
headers: { "content-type": "application/json" },
|
|
82
|
+
body: JSON.stringify({
|
|
83
|
+
card_secret: cardConfig.card_secret,
|
|
84
|
+
service_id: serviceId,
|
|
85
|
+
}),
|
|
86
|
+
});
|
|
87
|
+
if (!bindRes.ok) {
|
|
88
|
+
const bindError = await bindRes.text();
|
|
89
|
+
console.error(`Failed to bind (${bindRes.status}): ${bindError}`);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
console.log("Bound. Retrying payment...");
|
|
93
|
+
// Retry with x-card-id
|
|
94
|
+
const retryRes = await fetch(url, { method: "POST", headers, body: body ?? undefined });
|
|
95
|
+
if (!retryRes.ok) {
|
|
96
|
+
console.error(`Retry failed (${retryRes.status}): ${await retryRes.text()}`);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
console.log("Payment successful (card)");
|
|
100
|
+
const data = await retryRes.text();
|
|
101
|
+
try {
|
|
102
|
+
console.log(JSON.stringify(JSON.parse(data), null, 2));
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
console.log(data);
|
|
106
|
+
}
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
69
109
|
}
|
|
110
|
+
// Other error
|
|
111
|
+
console.error(`Request failed (${res.status}): ${await res.text().catch(() => "")}`);
|
|
112
|
+
process.exit(1);
|
|
70
113
|
}
|
|
71
114
|
async function payWithCrypto(url, walletConfig, body, extraHeaders) {
|
|
72
115
|
const headers = { ...extraHeaders };
|
|
@@ -148,7 +191,7 @@ function registerPayCommand(program) {
|
|
|
148
191
|
console.error("No card configured. Run: agentspend card setup");
|
|
149
192
|
process.exit(1);
|
|
150
193
|
}
|
|
151
|
-
await payWithCard(url, card
|
|
194
|
+
await payWithCard(url, card, opts.body, extraHeaders);
|
|
152
195
|
return;
|
|
153
196
|
}
|
|
154
197
|
if (opts.method === "crypto") {
|
|
@@ -163,7 +206,7 @@ function registerPayCommand(program) {
|
|
|
163
206
|
// Auto-detect: try card first, then crypto
|
|
164
207
|
const card = await readCardConfig();
|
|
165
208
|
if (card) {
|
|
166
|
-
await payWithCard(url, card
|
|
209
|
+
await payWithCard(url, card, opts.body, extraHeaders);
|
|
167
210
|
return;
|
|
168
211
|
}
|
|
169
212
|
const wallet = await readWalletConfig();
|
package/package.json
CHANGED
package/src/commands/card.ts
CHANGED
|
@@ -18,6 +18,7 @@ interface CardSetupStatusResponse {
|
|
|
18
18
|
status: CardSetupStatus;
|
|
19
19
|
expires_at: string;
|
|
20
20
|
card_id?: string;
|
|
21
|
+
card_secret?: string;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
const CONFIG_DIR = join(homedir(), ".agentspend");
|
|
@@ -121,7 +122,10 @@ export function registerCardCommands(program: Command): void {
|
|
|
121
122
|
if (status.status === "ready") {
|
|
122
123
|
console.log(`Card is ready!`);
|
|
123
124
|
if (status.card_id) {
|
|
124
|
-
await writeFile(CARD_FILE, JSON.stringify({
|
|
125
|
+
await writeFile(CARD_FILE, JSON.stringify({
|
|
126
|
+
card_id: status.card_id,
|
|
127
|
+
card_secret: status.card_secret,
|
|
128
|
+
}, null, 2));
|
|
125
129
|
console.log(`Card ID saved to ${CARD_FILE}`);
|
|
126
130
|
}
|
|
127
131
|
// Clean up setup file
|
package/src/commands/pay.ts
CHANGED
|
@@ -6,9 +6,11 @@ import { join } from "node:path";
|
|
|
6
6
|
const CONFIG_DIR = join(homedir(), ".agentspend");
|
|
7
7
|
const CARD_FILE = join(CONFIG_DIR, "card.json");
|
|
8
8
|
const WALLET_FILE = join(CONFIG_DIR, "wallet.json");
|
|
9
|
+
const API_BASE = process.env.AGENTSPEND_API_URL ?? "https://api.agentspend.co";
|
|
9
10
|
|
|
10
11
|
interface CardConfig {
|
|
11
12
|
card_id: string;
|
|
13
|
+
card_secret: string;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
interface WalletConfig {
|
|
@@ -20,7 +22,7 @@ interface WalletConfig {
|
|
|
20
22
|
async function readCardConfig(): Promise<CardConfig | null> {
|
|
21
23
|
try {
|
|
22
24
|
const data = JSON.parse(await readFile(CARD_FILE, "utf-8"));
|
|
23
|
-
if (typeof data.card_id === "string" && data.card_id) {
|
|
25
|
+
if (typeof data.card_id === "string" && data.card_id && typeof data.card_secret === "string" && data.card_secret) {
|
|
24
26
|
return data as CardConfig;
|
|
25
27
|
}
|
|
26
28
|
} catch {
|
|
@@ -55,36 +57,80 @@ function parseHeaders(headerArgs: string[]): Record<string, string> {
|
|
|
55
57
|
|
|
56
58
|
async function payWithCard(
|
|
57
59
|
url: string,
|
|
58
|
-
|
|
60
|
+
cardConfig: CardConfig,
|
|
59
61
|
body: string | undefined,
|
|
60
62
|
extraHeaders: Record<string, string>
|
|
61
63
|
): Promise<void> {
|
|
62
64
|
const headers: Record<string, string> = {
|
|
63
65
|
...extraHeaders,
|
|
64
|
-
"x-card-id":
|
|
66
|
+
"x-card-id": cardConfig.card_id,
|
|
65
67
|
};
|
|
66
68
|
if (body) {
|
|
67
69
|
headers["content-type"] = "application/json";
|
|
68
70
|
}
|
|
69
71
|
|
|
72
|
+
// Try with x-card-id
|
|
70
73
|
const res = await fetch(url, {
|
|
71
74
|
method: "POST",
|
|
72
75
|
headers,
|
|
73
76
|
body: body ?? undefined,
|
|
74
77
|
});
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
if (
|
|
78
|
-
console.
|
|
79
|
-
|
|
79
|
+
// Success
|
|
80
|
+
if (res.ok) {
|
|
81
|
+
console.log("Payment successful (card)");
|
|
82
|
+
const data = await res.text();
|
|
83
|
+
try { console.log(JSON.stringify(JSON.parse(data), null, 2)); }
|
|
84
|
+
catch { console.log(data); }
|
|
85
|
+
return;
|
|
80
86
|
}
|
|
81
87
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
88
|
+
// 402 with agentspend.service_id — need to bind
|
|
89
|
+
if (res.status === 402) {
|
|
90
|
+
const errorBody = await res.json().catch(() => ({})) as Record<string, unknown>;
|
|
91
|
+
const agentspend = errorBody?.agentspend as Record<string, unknown> | undefined;
|
|
92
|
+
const serviceId = agentspend?.service_id as string | undefined;
|
|
93
|
+
|
|
94
|
+
if (serviceId) {
|
|
95
|
+
console.log(`Binding to service ${serviceId}...`);
|
|
96
|
+
const bindRes = await fetch(
|
|
97
|
+
`${API_BASE}/v1/card/${encodeURIComponent(cardConfig.card_id)}/bind`,
|
|
98
|
+
{
|
|
99
|
+
method: "POST",
|
|
100
|
+
headers: { "content-type": "application/json" },
|
|
101
|
+
body: JSON.stringify({
|
|
102
|
+
card_secret: cardConfig.card_secret,
|
|
103
|
+
service_id: serviceId,
|
|
104
|
+
}),
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
if (!bindRes.ok) {
|
|
109
|
+
const bindError = await bindRes.text();
|
|
110
|
+
console.error(`Failed to bind (${bindRes.status}): ${bindError}`);
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
console.log("Bound. Retrying payment...");
|
|
115
|
+
|
|
116
|
+
// Retry with x-card-id
|
|
117
|
+
const retryRes = await fetch(url, { method: "POST", headers, body: body ?? undefined });
|
|
118
|
+
if (!retryRes.ok) {
|
|
119
|
+
console.error(`Retry failed (${retryRes.status}): ${await retryRes.text()}`);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
console.log("Payment successful (card)");
|
|
124
|
+
const data = await retryRes.text();
|
|
125
|
+
try { console.log(JSON.stringify(JSON.parse(data), null, 2)); }
|
|
126
|
+
catch { console.log(data); }
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
87
129
|
}
|
|
130
|
+
|
|
131
|
+
// Other error
|
|
132
|
+
console.error(`Request failed (${res.status}): ${await res.text().catch(() => "")}`);
|
|
133
|
+
process.exit(1);
|
|
88
134
|
}
|
|
89
135
|
|
|
90
136
|
async function payWithCrypto(
|
|
@@ -185,7 +231,7 @@ export function registerPayCommand(program: Command): void {
|
|
|
185
231
|
console.error("No card configured. Run: agentspend card setup");
|
|
186
232
|
process.exit(1);
|
|
187
233
|
}
|
|
188
|
-
await payWithCard(url, card
|
|
234
|
+
await payWithCard(url, card, opts.body, extraHeaders);
|
|
189
235
|
return;
|
|
190
236
|
}
|
|
191
237
|
|
|
@@ -202,7 +248,7 @@ export function registerPayCommand(program: Command): void {
|
|
|
202
248
|
// Auto-detect: try card first, then crypto
|
|
203
249
|
const card = await readCardConfig();
|
|
204
250
|
if (card) {
|
|
205
|
-
await payWithCard(url, card
|
|
251
|
+
await payWithCard(url, card, opts.body, extraHeaders);
|
|
206
252
|
return;
|
|
207
253
|
}
|
|
208
254
|
|