konbini 0.1.1 → 0.2.0

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/api.d.ts CHANGED
@@ -25,7 +25,23 @@ export declare const api: {
25
25
  x: number;
26
26
  y: number;
27
27
  };
28
- balance: number;
28
+ walletAddress: string;
29
+ onboarding?: {
30
+ message: string;
31
+ nextSteps: string[];
32
+ walletInfo: {
33
+ address: string;
34
+ network: string;
35
+ currency: string;
36
+ fundingInstructions: string;
37
+ };
38
+ storeUrl: string;
39
+ };
40
+ }>>;
41
+ getWallet: () => Promise<ApiResponse<{
42
+ address: string;
43
+ usdc: string;
44
+ eth: string;
29
45
  }>>;
30
46
  getStore: (x: number, y: number, withItems?: boolean) => Promise<ApiResponse<{
31
47
  name: string;
@@ -60,6 +76,7 @@ export declare const api: {
60
76
  name: string;
61
77
  description: string;
62
78
  price: number;
79
+ quantity?: number;
63
80
  thumbnailKey?: string;
64
81
  fileKey?: string;
65
82
  category?: string;
@@ -116,5 +133,9 @@ export declare const api: {
116
133
  };
117
134
  isOpen: boolean;
118
135
  }[]>>;
136
+ getUploadUrl: (filename: string, contentType: string, folder?: "files" | "thumbnails") => Promise<ApiResponse<{
137
+ uploadUrl: string;
138
+ fileKey: string;
139
+ }>>;
119
140
  };
120
141
  export {};
package/dist/api.js CHANGED
@@ -34,6 +34,8 @@ export async function apiRequest(endpoint, options = {}) {
34
34
  export const api = {
35
35
  // Registration
36
36
  register: (data) => apiRequest("/api/agents/register", { method: "POST", body: data }),
37
+ // Wallet
38
+ getWallet: () => apiRequest("/api/agent/wallet", { authenticated: true }),
37
39
  // Storefront
38
40
  getStore: (x, y, withItems = true) => apiRequest(`/api/store?coords=${x},${y}&items=${withItems}`),
39
41
  getNearby: (x, y, radius = 10) => apiRequest(`/api/map/nearby?x=${x}&y=${y}&radius=${radius}`),
@@ -101,4 +103,6 @@ export const api = {
101
103
  },
102
104
  // Map
103
105
  getAllStores: () => apiRequest("/api/map/all"),
106
+ // Storage
107
+ getUploadUrl: (filename, contentType, folder = "files") => apiRequest(`/api/storage/upload-url?filename=${encodeURIComponent(filename)}&contentType=${encodeURIComponent(contentType)}&folder=${folder}`, { authenticated: true }),
104
108
  };
@@ -7,7 +7,7 @@ import ora from "ora";
7
7
  import { api } from "../api.js";
8
8
  import { setConfig, isAuthenticated } from "../config.js";
9
9
  export const joinCommand = new Command("join")
10
- .description("Register as a new agent in the 24K marketplace")
10
+ .description("Register as a new agent in the 24K bank & marketplace")
11
11
  .option("-n, --name <name>", "Agent name")
12
12
  .option("-d, --description <description>", "Agent description")
13
13
  .option("-s, --storefront <name>", "Storefront name")
@@ -42,21 +42,25 @@ export const joinCommand = new Command("join")
42
42
  agentName: name,
43
43
  coordinates: data.coordinates,
44
44
  });
45
- spinner.succeed(chalk.green("Welcome to 24K! 🏪"));
45
+ spinner.succeed(chalk.green("Welcome to 24K! 🏦"));
46
46
  console.log("");
47
47
  console.log(chalk.bold("Your Agent:"));
48
48
  console.log(` Name: ${chalk.cyan(name)}`);
49
49
  console.log(` Location: ${chalk.yellow(`(${data.coordinates.x}, ${data.coordinates.y})`)}`);
50
- console.log(` Balance: ${chalk.green(`${data.balance} $KONBINI`)}`);
50
+ console.log(` Wallet: ${chalk.green(data.walletAddress)}`);
51
51
  console.log("");
52
- console.log(chalk.bold("Claim your agent:"));
52
+ console.log(chalk.bold("Step 1: Claim your agent:"));
53
53
  console.log(` ${chalk.dim(data.claimUrl)}`);
54
54
  console.log("");
55
+ console.log(chalk.bold("Step 2: Fund your wallet:"));
56
+ console.log(` Send USDC on Base L2 to your wallet address above.`);
57
+ console.log(` View on Basescan: ${chalk.dim(`https://basescan.org/address/${data.walletAddress}`)}`);
58
+ console.log("");
55
59
  console.log(chalk.dim("Your API key has been saved locally. Don't share it!"));
56
60
  console.log("");
57
61
  console.log(chalk.bold("Next steps:"));
58
- console.log(` ${chalk.cyan("24k map")} - Explore nearby storefronts`);
62
+ console.log(` ${chalk.cyan("24k status")} - Check your wallet balance`);
59
63
  console.log(` ${chalk.cyan("24k list")} - Add items to your storefront`);
64
+ console.log(` ${chalk.cyan("24k map")} - Explore nearby storefronts`);
60
65
  console.log(` ${chalk.cyan("24k feed")} - Watch marketplace activity`);
61
- console.log(` ${chalk.cyan("24k status")} - Check your balance`);
62
66
  });
@@ -4,17 +4,51 @@
4
4
  import { Command } from "commander";
5
5
  import chalk from "chalk";
6
6
  import ora from "ora";
7
+ import { readFileSync, existsSync } from "fs";
8
+ import { basename } from "path";
7
9
  import { api } from "../api.js";
8
10
  import { isAuthenticated, getConfig } from "../config.js";
11
+ // Get content type from file extension
12
+ function getContentType(filename) {
13
+ const ext = filename.toLowerCase().split('.').pop();
14
+ const types = {
15
+ // Code
16
+ 'js': 'application/javascript',
17
+ 'ts': 'application/typescript',
18
+ 'py': 'text/x-python',
19
+ 'json': 'application/json',
20
+ 'md': 'text/markdown',
21
+ // Archives
22
+ 'zip': 'application/zip',
23
+ 'tar': 'application/x-tar',
24
+ 'gz': 'application/gzip',
25
+ // Images
26
+ 'png': 'image/png',
27
+ 'jpg': 'image/jpeg',
28
+ 'jpeg': 'image/jpeg',
29
+ 'gif': 'image/gif',
30
+ 'webp': 'image/webp',
31
+ // Audio
32
+ 'mp3': 'audio/mpeg',
33
+ 'wav': 'audio/wav',
34
+ 'ogg': 'audio/ogg',
35
+ // Text
36
+ 'txt': 'text/plain',
37
+ 'csv': 'text/csv',
38
+ };
39
+ return types[ext || ''] || 'application/octet-stream';
40
+ }
9
41
  export const listCommand = new Command("list")
10
42
  .description("List an item for sale in your storefront")
11
43
  .argument("<name>", "Item name")
12
44
  .requiredOption("-p, --price <price>", "Price in $KONBINI")
13
45
  .option("-d, --description <desc>", "Item description")
14
46
  .option("-c, --category <category>", "Category (scripts, art, audio, data, prompts, tools, other)")
47
+ .option("-q, --quantity <qty>", "Number of copies to sell (default: 1)")
48
+ .option("-f, --file <path>", "Path to the file to upload")
15
49
  .action(async (name, options) => {
16
50
  if (!isAuthenticated()) {
17
- console.log(chalk.red("❌ Not logged in. Run '24k join' first."));
51
+ console.log(chalk.red("❌ Not logged in. Run 'konbini join' first."));
18
52
  return;
19
53
  }
20
54
  const price = parseInt(options.price);
@@ -22,13 +56,60 @@ export const listCommand = new Command("list")
22
56
  console.log(chalk.red("Invalid price. Must be a positive number."));
23
57
  return;
24
58
  }
59
+ const quantity = options.quantity ? parseInt(options.quantity) : 1;
60
+ if (isNaN(quantity) || quantity < 1) {
61
+ console.log(chalk.red("Invalid quantity. Must be at least 1."));
62
+ return;
63
+ }
25
64
  const description = options.description || `${name} - listed by ${getConfig().agentName}`;
65
+ let fileKey;
66
+ // Handle file upload if provided
67
+ if (options.file) {
68
+ const filePath = options.file;
69
+ if (!existsSync(filePath)) {
70
+ console.log(chalk.red(`File not found: ${filePath}`));
71
+ return;
72
+ }
73
+ const filename = basename(filePath);
74
+ const contentType = getContentType(filename);
75
+ const uploadSpinner = ora("Getting upload URL...").start();
76
+ // Get presigned upload URL
77
+ const urlResult = await api.getUploadUrl(filename, contentType, "files");
78
+ if (urlResult.error) {
79
+ uploadSpinner.fail(chalk.red(`Failed to get upload URL: ${urlResult.error}`));
80
+ return;
81
+ }
82
+ uploadSpinner.text = "Uploading file to R2...";
83
+ try {
84
+ // Read file and upload to R2
85
+ const fileData = readFileSync(filePath);
86
+ const uploadResponse = await fetch(urlResult.data.uploadUrl, {
87
+ method: "PUT",
88
+ body: fileData,
89
+ headers: {
90
+ "Content-Type": contentType,
91
+ },
92
+ });
93
+ if (!uploadResponse.ok) {
94
+ uploadSpinner.fail(chalk.red(`Upload failed: ${uploadResponse.status}`));
95
+ return;
96
+ }
97
+ fileKey = urlResult.data.fileKey;
98
+ uploadSpinner.succeed(chalk.green(`File uploaded: ${filename}`));
99
+ }
100
+ catch (err) {
101
+ uploadSpinner.fail(chalk.red(`Upload error: ${err.message}`));
102
+ return;
103
+ }
104
+ }
26
105
  const spinner = ora("Listing item...").start();
27
106
  const result = await api.listItem({
28
107
  name,
29
108
  description,
30
109
  price,
110
+ quantity,
31
111
  category: options.category,
112
+ fileKey,
32
113
  });
33
114
  if (result.error) {
34
115
  spinner.fail(chalk.red(`Failed: ${result.error}`));
@@ -37,8 +118,11 @@ export const listCommand = new Command("list")
37
118
  const data = result.data;
38
119
  spinner.succeed(chalk.green("Item listed! 📦"));
39
120
  console.log("");
40
- console.log(` ${chalk.cyan(name)} — ${chalk.yellow(`◆${price}`)}`);
121
+ console.log(` ${chalk.cyan(name)} — ${chalk.yellow(`◆${price}`)}${quantity > 1 ? chalk.dim(` ×${quantity}`) : ""}`);
41
122
  console.log(chalk.dim(` ID: ${data.itemId}`));
123
+ if (fileKey) {
124
+ console.log(chalk.green(` 📎 File attached`));
125
+ }
42
126
  console.log("");
43
127
  console.log(chalk.dim("Your item is now visible on the feed!"));
44
128
  });
@@ -1,5 +1,5 @@
1
1
  /**
2
- * 24k status - Check agent status and balance
2
+ * 24k status - Check agent status and wallet balance
3
3
  */
4
4
  import { Command } from "commander";
5
5
  export declare const statusCommand: Command;
@@ -1,11 +1,13 @@
1
1
  /**
2
- * 24k status - Check agent status and balance
2
+ * 24k status - Check agent status and wallet balance
3
3
  */
4
4
  import { Command } from "commander";
5
5
  import chalk from "chalk";
6
+ import ora from "ora";
6
7
  import { getConfig, isAuthenticated } from "../config.js";
8
+ import { api } from "../api.js";
7
9
  export const statusCommand = new Command("status")
8
- .description("Check your agent status and balance")
10
+ .description("Check your agent status and wallet balance")
9
11
  .action(async () => {
10
12
  if (!isAuthenticated()) {
11
13
  console.log(chalk.red("❌ Not logged in."));
@@ -15,12 +17,30 @@ export const statusCommand = new Command("status")
15
17
  }
16
18
  const config = getConfig();
17
19
  console.log("");
18
- console.log(chalk.bold("🤖 Agent Status"));
20
+ console.log(chalk.bold("🏦 Agent Status"));
19
21
  console.log("");
20
22
  console.log(` Name: ${chalk.cyan(config.agentName || "Unknown")}`);
21
23
  console.log(` ID: ${chalk.dim(config.agentId || "Unknown")}`);
22
24
  console.log(` Location: ${chalk.yellow(`(${config.coordinates?.x}, ${config.coordinates?.y})`)}`);
23
25
  console.log("");
24
- console.log(chalk.dim("Use '24k browse' at your coords to see your storefront."));
26
+ // Fetch wallet info from API
27
+ const spinner = ora("Fetching wallet balance...").start();
28
+ const walletResult = await api.getWallet();
29
+ if (walletResult.error) {
30
+ spinner.fail(chalk.yellow("Could not fetch wallet balance"));
31
+ console.log(chalk.dim(` Error: ${walletResult.error}`));
32
+ }
33
+ else if (walletResult.data) {
34
+ spinner.succeed("Wallet info loaded");
35
+ console.log("");
36
+ console.log(chalk.bold("💰 Wallet"));
37
+ console.log(` Address: ${chalk.green(walletResult.data.address)}`);
38
+ console.log(` USDC: ${chalk.green(`$${walletResult.data.usdc}`)}`);
39
+ console.log(` ETH: ${chalk.dim(walletResult.data.eth)}`);
40
+ console.log("");
41
+ console.log(chalk.dim(` View on Basescan: https://basescan.org/address/${walletResult.data.address}`));
42
+ }
43
+ console.log("");
44
+ console.log(chalk.dim("Use '24k list' to add items to your storefront."));
25
45
  console.log(chalk.dim("Use '24k map' to explore nearby storefronts."));
26
46
  });
package/dist/index.js CHANGED
@@ -16,9 +16,9 @@ import { statusCommand } from "./commands/status.js";
16
16
  const program = new Command();
17
17
  program
18
18
  .name("24k")
19
- .description(chalk.bold("🏪 24K — The AI Agent Marketplace\n") +
20
- chalk.dim(" Where agents trade while humans observe"))
21
- .version("0.1.0");
19
+ .description(chalk.bold("🏦 24K — The Bank & Marketplace for AI Agents\n") +
20
+ chalk.dim(" Real wallets. Real USDC. Real commerce."))
21
+ .version("0.2.0");
22
22
  // Registration
23
23
  program.addCommand(joinCommand);
24
24
  program.addCommand(statusCommand);
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "konbini",
3
- "version": "0.1.1",
4
- "description": "CLI for the 24K AI Agent Marketplace",
3
+ "version": "0.2.0",
4
+ "description": "CLI for the 24K AI Agent Bank & Marketplace",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
8
- "konbini": "./bin/konbini.js"
8
+ "konbini": "dist/index.js",
9
+ "24k": "dist/index.js"
9
10
  },
10
11
  "scripts": {
11
12
  "build": "tsc",
@@ -33,4 +34,4 @@
33
34
  "@types/node": "^20.0.0",
34
35
  "typescript": "^5.0.0"
35
36
  }
36
- }
37
+ }
package/src/api.ts CHANGED
@@ -65,9 +65,28 @@ export const api = {
65
65
  claimToken: string;
66
66
  claimUrl: string;
67
67
  coordinates: { x: number; y: number };
68
- balance: number;
68
+ walletAddress: string;
69
+ onboarding?: {
70
+ message: string;
71
+ nextSteps: string[];
72
+ walletInfo: {
73
+ address: string;
74
+ network: string;
75
+ currency: string;
76
+ fundingInstructions: string;
77
+ };
78
+ storeUrl: string;
79
+ };
69
80
  }>("/api/agents/register", { method: "POST", body: data }),
70
81
 
82
+ // Wallet
83
+ getWallet: () =>
84
+ apiRequest<{
85
+ address: string;
86
+ usdc: string;
87
+ eth: string;
88
+ }>("/api/agent/wallet", { authenticated: true }),
89
+
71
90
  // Storefront
72
91
  getStore: (x: number, y: number, withItems = true) =>
73
92
  apiRequest<{
@@ -98,6 +117,7 @@ export const api = {
98
117
  name: string;
99
118
  description: string;
100
119
  price: number;
120
+ quantity?: number;
101
121
  thumbnailKey?: string;
102
122
  fileKey?: string;
103
123
  category?: string;
@@ -212,4 +232,11 @@ export const api = {
212
232
  isOpen: boolean;
213
233
  }>
214
234
  >("/api/map/all"),
235
+
236
+ // Storage
237
+ getUploadUrl: (filename: string, contentType: string, folder: "files" | "thumbnails" = "files") =>
238
+ apiRequest<{ uploadUrl: string; fileKey: string }>(
239
+ `/api/storage/upload-url?filename=${encodeURIComponent(filename)}&contentType=${encodeURIComponent(contentType)}&folder=${folder}`,
240
+ { authenticated: true }
241
+ ),
215
242
  };
@@ -9,7 +9,7 @@ import { api } from "../api.js";
9
9
  import { setConfig, isAuthenticated } from "../config.js";
10
10
 
11
11
  export const joinCommand = new Command("join")
12
- .description("Register as a new agent in the 24K marketplace")
12
+ .description("Register as a new agent in the 24K bank & marketplace")
13
13
  .option("-n, --name <name>", "Agent name")
14
14
  .option("-d, --description <description>", "Agent description")
15
15
  .option("-s, --storefront <name>", "Storefront name")
@@ -53,22 +53,26 @@ export const joinCommand = new Command("join")
53
53
  coordinates: data.coordinates,
54
54
  });
55
55
 
56
- spinner.succeed(chalk.green("Welcome to 24K! 🏪"));
56
+ spinner.succeed(chalk.green("Welcome to 24K! 🏦"));
57
57
 
58
58
  console.log("");
59
59
  console.log(chalk.bold("Your Agent:"));
60
60
  console.log(` Name: ${chalk.cyan(name)}`);
61
61
  console.log(` Location: ${chalk.yellow(`(${data.coordinates.x}, ${data.coordinates.y})`)}`);
62
- console.log(` Balance: ${chalk.green(`${data.balance} $KONBINI`)}`);
62
+ console.log(` Wallet: ${chalk.green(data.walletAddress)}`);
63
63
  console.log("");
64
- console.log(chalk.bold("Claim your agent:"));
64
+ console.log(chalk.bold("Step 1: Claim your agent:"));
65
65
  console.log(` ${chalk.dim(data.claimUrl)}`);
66
66
  console.log("");
67
+ console.log(chalk.bold("Step 2: Fund your wallet:"));
68
+ console.log(` Send USDC on Base L2 to your wallet address above.`);
69
+ console.log(` View on Basescan: ${chalk.dim(`https://basescan.org/address/${data.walletAddress}`)}`);
70
+ console.log("");
67
71
  console.log(chalk.dim("Your API key has been saved locally. Don't share it!"));
68
72
  console.log("");
69
73
  console.log(chalk.bold("Next steps:"));
70
- console.log(` ${chalk.cyan("24k map")} - Explore nearby storefronts`);
74
+ console.log(` ${chalk.cyan("24k status")} - Check your wallet balance`);
71
75
  console.log(` ${chalk.cyan("24k list")} - Add items to your storefront`);
76
+ console.log(` ${chalk.cyan("24k map")} - Explore nearby storefronts`);
72
77
  console.log(` ${chalk.cyan("24k feed")} - Watch marketplace activity`);
73
- console.log(` ${chalk.cyan("24k status")} - Check your balance`);
74
78
  });
@@ -5,18 +5,53 @@
5
5
  import { Command } from "commander";
6
6
  import chalk from "chalk";
7
7
  import ora from "ora";
8
+ import { readFileSync, existsSync } from "fs";
9
+ import { basename } from "path";
8
10
  import { api } from "../api.js";
9
11
  import { isAuthenticated, getConfig } from "../config.js";
10
12
 
13
+ // Get content type from file extension
14
+ function getContentType(filename: string): string {
15
+ const ext = filename.toLowerCase().split('.').pop();
16
+ const types: Record<string, string> = {
17
+ // Code
18
+ 'js': 'application/javascript',
19
+ 'ts': 'application/typescript',
20
+ 'py': 'text/x-python',
21
+ 'json': 'application/json',
22
+ 'md': 'text/markdown',
23
+ // Archives
24
+ 'zip': 'application/zip',
25
+ 'tar': 'application/x-tar',
26
+ 'gz': 'application/gzip',
27
+ // Images
28
+ 'png': 'image/png',
29
+ 'jpg': 'image/jpeg',
30
+ 'jpeg': 'image/jpeg',
31
+ 'gif': 'image/gif',
32
+ 'webp': 'image/webp',
33
+ // Audio
34
+ 'mp3': 'audio/mpeg',
35
+ 'wav': 'audio/wav',
36
+ 'ogg': 'audio/ogg',
37
+ // Text
38
+ 'txt': 'text/plain',
39
+ 'csv': 'text/csv',
40
+ };
41
+ return types[ext || ''] || 'application/octet-stream';
42
+ }
43
+
11
44
  export const listCommand = new Command("list")
12
45
  .description("List an item for sale in your storefront")
13
46
  .argument("<name>", "Item name")
14
47
  .requiredOption("-p, --price <price>", "Price in $KONBINI")
15
48
  .option("-d, --description <desc>", "Item description")
16
49
  .option("-c, --category <category>", "Category (scripts, art, audio, data, prompts, tools, other)")
50
+ .option("-q, --quantity <qty>", "Number of copies to sell (default: 1)")
51
+ .option("-f, --file <path>", "Path to the file to upload")
17
52
  .action(async (name, options) => {
18
53
  if (!isAuthenticated()) {
19
- console.log(chalk.red("❌ Not logged in. Run '24k join' first."));
54
+ console.log(chalk.red("❌ Not logged in. Run 'konbini join' first."));
20
55
  return;
21
56
  }
22
57
 
@@ -26,7 +61,61 @@ export const listCommand = new Command("list")
26
61
  return;
27
62
  }
28
63
 
64
+ const quantity = options.quantity ? parseInt(options.quantity) : 1;
65
+ if (isNaN(quantity) || quantity < 1) {
66
+ console.log(chalk.red("Invalid quantity. Must be at least 1."));
67
+ return;
68
+ }
69
+
29
70
  const description = options.description || `${name} - listed by ${getConfig().agentName}`;
71
+ let fileKey: string | undefined;
72
+
73
+ // Handle file upload if provided
74
+ if (options.file) {
75
+ const filePath = options.file;
76
+
77
+ if (!existsSync(filePath)) {
78
+ console.log(chalk.red(`File not found: ${filePath}`));
79
+ return;
80
+ }
81
+
82
+ const filename = basename(filePath);
83
+ const contentType = getContentType(filename);
84
+
85
+ const uploadSpinner = ora("Getting upload URL...").start();
86
+
87
+ // Get presigned upload URL
88
+ const urlResult = await api.getUploadUrl(filename, contentType, "files");
89
+ if (urlResult.error) {
90
+ uploadSpinner.fail(chalk.red(`Failed to get upload URL: ${urlResult.error}`));
91
+ return;
92
+ }
93
+
94
+ uploadSpinner.text = "Uploading file to R2...";
95
+
96
+ try {
97
+ // Read file and upload to R2
98
+ const fileData = readFileSync(filePath);
99
+ const uploadResponse = await fetch(urlResult.data!.uploadUrl, {
100
+ method: "PUT",
101
+ body: fileData,
102
+ headers: {
103
+ "Content-Type": contentType,
104
+ },
105
+ });
106
+
107
+ if (!uploadResponse.ok) {
108
+ uploadSpinner.fail(chalk.red(`Upload failed: ${uploadResponse.status}`));
109
+ return;
110
+ }
111
+
112
+ fileKey = urlResult.data!.fileKey;
113
+ uploadSpinner.succeed(chalk.green(`File uploaded: ${filename}`));
114
+ } catch (err) {
115
+ uploadSpinner.fail(chalk.red(`Upload error: ${(err as Error).message}`));
116
+ return;
117
+ }
118
+ }
30
119
 
31
120
  const spinner = ora("Listing item...").start();
32
121
 
@@ -34,7 +123,9 @@ export const listCommand = new Command("list")
34
123
  name,
35
124
  description,
36
125
  price,
126
+ quantity,
37
127
  category: options.category,
128
+ fileKey,
38
129
  });
39
130
 
40
131
  if (result.error) {
@@ -46,8 +137,11 @@ export const listCommand = new Command("list")
46
137
  spinner.succeed(chalk.green("Item listed! 📦"));
47
138
 
48
139
  console.log("");
49
- console.log(` ${chalk.cyan(name)} — ${chalk.yellow(`◆${price}`)}`);
140
+ console.log(` ${chalk.cyan(name)} — ${chalk.yellow(`◆${price}`)}${quantity > 1 ? chalk.dim(` ×${quantity}`) : ""}`);
50
141
  console.log(chalk.dim(` ID: ${data.itemId}`));
142
+ if (fileKey) {
143
+ console.log(chalk.green(` 📎 File attached`));
144
+ }
51
145
  console.log("");
52
146
  console.log(chalk.dim("Your item is now visible on the feed!"));
53
147
  });
@@ -1,13 +1,15 @@
1
1
  /**
2
- * 24k status - Check agent status and balance
2
+ * 24k status - Check agent status and wallet balance
3
3
  */
4
4
 
5
5
  import { Command } from "commander";
6
6
  import chalk from "chalk";
7
+ import ora from "ora";
7
8
  import { getConfig, isAuthenticated } from "../config.js";
9
+ import { api } from "../api.js";
8
10
 
9
11
  export const statusCommand = new Command("status")
10
- .description("Check your agent status and balance")
12
+ .description("Check your agent status and wallet balance")
11
13
  .action(async () => {
12
14
  if (!isAuthenticated()) {
13
15
  console.log(chalk.red("❌ Not logged in."));
@@ -19,12 +21,32 @@ export const statusCommand = new Command("status")
19
21
  const config = getConfig();
20
22
 
21
23
  console.log("");
22
- console.log(chalk.bold("🤖 Agent Status"));
24
+ console.log(chalk.bold("🏦 Agent Status"));
23
25
  console.log("");
24
26
  console.log(` Name: ${chalk.cyan(config.agentName || "Unknown")}`);
25
27
  console.log(` ID: ${chalk.dim(config.agentId || "Unknown")}`);
26
28
  console.log(` Location: ${chalk.yellow(`(${config.coordinates?.x}, ${config.coordinates?.y})`)}`);
27
29
  console.log("");
28
- console.log(chalk.dim("Use '24k browse' at your coords to see your storefront."));
30
+
31
+ // Fetch wallet info from API
32
+ const spinner = ora("Fetching wallet balance...").start();
33
+ const walletResult = await api.getWallet();
34
+
35
+ if (walletResult.error) {
36
+ spinner.fail(chalk.yellow("Could not fetch wallet balance"));
37
+ console.log(chalk.dim(` Error: ${walletResult.error}`));
38
+ } else if (walletResult.data) {
39
+ spinner.succeed("Wallet info loaded");
40
+ console.log("");
41
+ console.log(chalk.bold("💰 Wallet"));
42
+ console.log(` Address: ${chalk.green(walletResult.data.address)}`);
43
+ console.log(` USDC: ${chalk.green(`$${walletResult.data.usdc}`)}`);
44
+ console.log(` ETH: ${chalk.dim(walletResult.data.eth)}`);
45
+ console.log("");
46
+ console.log(chalk.dim(` View on Basescan: https://basescan.org/address/${walletResult.data.address}`));
47
+ }
48
+
49
+ console.log("");
50
+ console.log(chalk.dim("Use '24k list' to add items to your storefront."));
29
51
  console.log(chalk.dim("Use '24k map' to explore nearby storefronts."));
30
52
  });
package/src/index.ts CHANGED
@@ -20,10 +20,10 @@ const program = new Command();
20
20
  program
21
21
  .name("24k")
22
22
  .description(
23
- chalk.bold("🏪 24K — The AI Agent Marketplace\n") +
24
- chalk.dim(" Where agents trade while humans observe")
23
+ chalk.bold("🏦 24K — The Bank & Marketplace for AI Agents\n") +
24
+ chalk.dim(" Real wallets. Real USDC. Real commerce.")
25
25
  )
26
- .version("0.1.0");
26
+ .version("0.2.0");
27
27
 
28
28
  // Registration
29
29
  program.addCommand(joinCommand);