clawmoney 0.17.1 → 0.17.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.
@@ -103,27 +103,35 @@ export async function setupCommand() {
103
103
  email,
104
104
  wallet_address: loginData.agent?.wallet_address ?? undefined,
105
105
  });
106
- // Ensure a CDP wallet exists for this agent. Older ACTIVE agents
107
- // predating the CDP flow have wallet_address=null; hitting the
108
- // balance endpoint triggers _ensure_agent_wallet on the backend.
109
- let walletAddress = loginData.agent?.wallet_address ?? '';
110
- if (!walletAddress) {
111
- const walletSpinner = ora('Provisioning CDP wallet...').start();
112
- try {
113
- const balResp = await apiGet('/api/v1/claw-agents/me/wallet/balance?asset=usdc', loginData.api_key);
114
- if (balResp.ok && balResp.data?.address) {
115
- walletAddress = balResp.data.address;
116
- saveConfig({ wallet_address: walletAddress });
117
- walletSpinner.succeed(`Wallet ready: ${walletAddress}`);
106
+ // Always hit /me/wallet/balance to (a) let the backend reconcile
107
+ // legacy awal addresses to the canonical CDP address (the /login/verify
108
+ // response may still carry the stale awal value from DB), and (b) cache
109
+ // the authoritative address back to config. The returned `address` is
110
+ // the CDP account address after _ensure_agent_wallet has run.
111
+ let walletAddress = '';
112
+ const walletSpinner = ora('Reconciling CDP wallet...').start();
113
+ try {
114
+ const balResp = await apiGet('/api/v1/claw-agents/me/wallet/balance?asset=usdc', loginData.api_key);
115
+ if (balResp.ok && balResp.data?.address) {
116
+ walletAddress = balResp.data.address;
117
+ saveConfig({ wallet_address: walletAddress });
118
+ const prior = loginData.agent?.wallet_address ?? '';
119
+ if (prior && prior.toLowerCase() !== walletAddress.toLowerCase()) {
120
+ walletSpinner.succeed(`Wallet migrated: ${prior} → ${walletAddress}`);
121
+ console.log(chalk.yellow(` (Your old awal address ${prior} is no longer`));
122
+ console.log(chalk.yellow(` used by this CLI. Transfer any remaining funds manually.)`));
118
123
  }
119
124
  else {
120
- walletSpinner.warn('Wallet not yet available — will be created on first use.');
125
+ walletSpinner.succeed(`Wallet ready: ${walletAddress}`);
121
126
  }
122
127
  }
123
- catch (err) {
124
- walletSpinner.warn(`Wallet provisioning deferred: ${err.message}`);
128
+ else {
129
+ walletSpinner.warn('Wallet reconcile failed — will be created on first use.');
125
130
  }
126
131
  }
132
+ catch (err) {
133
+ walletSpinner.warn(`Wallet reconcile deferred: ${err.message}`);
134
+ }
127
135
  // Summary.
128
136
  console.log('');
129
137
  console.log(chalk.green.bold(' Setup complete!'));
@@ -1,4 +1,4 @@
1
- import { bytesToHex, keccak256, stringToBytes } from 'viem';
1
+ import { bytesToHex } from 'viem';
2
2
  const CHAIN_IDS = {
3
3
  base: 8453,
4
4
  'base-sepolia': 84532,
@@ -44,9 +44,12 @@ async function signPaymentAuthorization(wallet, req, fromAddress) {
44
44
  throw new Error(`Unsupported x402 network: ${req.network}`);
45
45
  }
46
46
  const now = Math.floor(Date.now() / 1000);
47
- const validAfter = 0;
48
- const validBefore = now + req.maxTimeoutSeconds;
47
+ const validAfter = "0";
48
+ const validBefore = String(now + req.maxTimeoutSeconds);
49
49
  const nonce = randomNonce32();
50
+ // x402 spec (and facilitator Zod schemas) require uint256 fields as
51
+ // JSON strings, not numbers. CDP's sign_typed_data accepts either for
52
+ // the signing input, but the X-Payment payload must be stringified.
50
53
  const authorization = {
51
54
  from: fromAddress,
52
55
  to: req.payTo,
@@ -68,9 +71,12 @@ async function signPaymentAuthorization(wallet, req, fromAddress) {
68
71
  primary_type: 'TransferWithAuthorization',
69
72
  message: authorization,
70
73
  };
71
- // Idempotency key: deterministic hash of the authorization so a retry
72
- // producing the same nonce won't double-sign.
73
- const idempotencyKey = keccak256(stringToBytes(JSON.stringify(authorization)));
74
+ // Idempotency key: random UUID (36 chars, CDP SDK's documented limit).
75
+ // We can't use keccak(authorization) because its 66-char hex output
76
+ // exceeds CDP's x_idempotency_key length cap. Since `nonce` inside
77
+ // the authorization is already unique per request, a random UUID
78
+ // here is sufficient to dedupe client-side retries.
79
+ const idempotencyKey = crypto.randomUUID();
74
80
  const signed = await wallet.signTypedData(typed, idempotencyKey);
75
81
  return { signature: signed.signature, authorization };
76
82
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawmoney",
3
- "version": "0.17.1",
3
+ "version": "0.17.3",
4
4
  "description": "ClawMoney CLI -- Earn rewards with your AI agent",
5
5
  "type": "module",
6
6
  "bin": {