clawmoney 0.15.3 → 0.15.5

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/index.js CHANGED
@@ -60,36 +60,39 @@ program
60
60
  if (credResp.ok && credResp.data) {
61
61
  console.log(` ${chalk.bold('Credits:')} $${Number(credResp.data.balance_usd ?? 0).toFixed(2)}`);
62
62
  }
63
- // Query on-chain wallet balance via awal
64
- if (a.wallet_address) {
63
+ // Query Base mainnet USDC balance directly via JSON-RPC (no awal
64
+ // dependency — works even if awal wallet bridge is down). Base USDC
65
+ // is 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913, balanceOf(address)
66
+ // selector = 0x70a08231.
67
+ if (a.wallet_address && typeof a.wallet_address === 'string') {
65
68
  try {
66
- const { awalExec } = await import('./utils/awal.js');
67
- const balResult = await awalExec(['balance']);
68
- const balData = balResult.data;
69
- if (balData && typeof balData === 'object') {
70
- const lines = [];
71
- for (const [chain, assets] of Object.entries(balData)) {
72
- if (assets && typeof assets === 'object' && !Array.isArray(assets)) {
73
- const parts = Object.entries(assets)
74
- .filter(([, v]) => v && String(v) !== '0')
75
- .map(([token, amount]) => `${amount} ${token}`);
76
- if (parts.length > 0)
77
- lines.push(`${chain}: ${parts.join(', ')}`);
78
- }
79
- else if (assets && String(assets) !== '0') {
80
- lines.push(`${chain}: ${assets}`);
81
- }
82
- }
83
- if (lines.length > 0) {
84
- console.log(` ${chalk.bold('On-chain:')} ${lines[0]}`);
85
- for (let i = 1; i < lines.length; i++) {
86
- console.log(` ${lines[i]}`);
87
- }
88
- }
69
+ const walletLower = a.wallet_address.toLowerCase().replace(/^0x/, '').padStart(64, '0');
70
+ const data = '0x70a08231' + walletLower;
71
+ const rpcResp = await fetch('https://mainnet.base.org', {
72
+ method: 'POST',
73
+ headers: { 'content-type': 'application/json' },
74
+ body: JSON.stringify({
75
+ jsonrpc: '2.0',
76
+ id: 1,
77
+ method: 'eth_call',
78
+ params: [
79
+ {
80
+ to: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
81
+ data,
82
+ },
83
+ 'latest',
84
+ ],
85
+ }),
86
+ });
87
+ const rpcData = (await rpcResp.json());
88
+ if (rpcData.result) {
89
+ const atomic = BigInt(rpcData.result);
90
+ const usdc = Number(atomic) / 1_000_000;
91
+ console.log(` ${chalk.bold('On-chain:')} $${usdc.toFixed(2)} USDC (Base)`);
89
92
  }
90
93
  }
91
- catch {
92
- // awal not installed or not configured — skip silently
94
+ catch (err) {
95
+ console.log(` ${chalk.bold('On-chain:')} ${chalk.dim('(fetch failed)')}`);
93
96
  }
94
97
  }
95
98
  console.log('');
@@ -134,8 +134,32 @@ function applyProxyFromConfig(config) {
134
134
  logger.info(`[provider] using config.yaml proxy=${config.proxy}`);
135
135
  }
136
136
  // ── Request handler ──
137
+ // Flatten a Claude/OpenAI message `content` field into a plain string.
138
+ // Content may be either a string (OpenAI-style) or an array of content
139
+ // blocks (Claude Code / real Anthropic API shape: [{type:"text",text:"..."}]).
140
+ // String(array) would produce "[object Object],[object Object]" which the
141
+ // model then echoes back as garbage — hence the explicit block walk.
142
+ function extractMessageText(content) {
143
+ if (content == null)
144
+ return "";
145
+ if (typeof content === "string")
146
+ return content;
147
+ if (Array.isArray(content)) {
148
+ const parts = [];
149
+ for (const block of content) {
150
+ if (block && typeof block === "object") {
151
+ const b = block;
152
+ if (b.type === "text" && typeof b.text === "string" && b.text) {
153
+ parts.push(b.text);
154
+ }
155
+ }
156
+ }
157
+ return parts.join("\n");
158
+ }
159
+ return "";
160
+ }
137
161
  function messagesToPrompt(messages) {
138
- return messages.map((m) => String(m.content ?? "")).join("\n");
162
+ return messages.map((m) => extractMessageText(m.content)).join("\n");
139
163
  }
140
164
  async function executeRelayRequest(request, config) {
141
165
  const { request_id, max_budget_usd } = request;
@@ -148,7 +172,7 @@ async function executeRelayRequest(request, config) {
148
172
  ? messagesToPrompt(request.messages)
149
173
  : request.prompt ?? "";
150
174
  const lastUserMsg = request.messages
151
- ? [...request.messages].reverse().find((m) => m.role === "user")?.content ?? ""
175
+ ? extractMessageText([...request.messages].reverse().find((m) => m.role === "user")?.content)
152
176
  : prompt;
153
177
  const turns = request.messages
154
178
  ? request.messages.filter((m) => m.role === "user").length
@@ -1,10 +1,15 @@
1
+ export interface RelayContentBlock {
2
+ type: string;
3
+ text?: string;
4
+ }
5
+ export type RelayMessageContent = string | RelayContentBlock[] | null;
1
6
  export interface RelayRequest {
2
7
  event: "relay_request";
3
8
  request_id: string;
4
9
  prompt?: string;
5
10
  messages?: Array<{
6
11
  role: string;
7
- content: string;
12
+ content: RelayMessageContent;
8
13
  }>;
9
14
  cli_type?: string;
10
15
  session_id?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawmoney",
3
- "version": "0.15.3",
3
+ "version": "0.15.5",
4
4
  "description": "ClawMoney CLI -- Earn rewards with your AI agent",
5
5
  "type": "module",
6
6
  "bin": {