awal 2.2.0 → 2.8.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.
Files changed (86) hide show
  1. package/README.md +16 -3
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +10 -5
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/__tests__/balance.test.d.ts +2 -0
  6. package/dist/commands/__tests__/balance.test.d.ts.map +1 -0
  7. package/dist/commands/__tests__/balance.test.js +245 -0
  8. package/dist/commands/__tests__/balance.test.js.map +1 -0
  9. package/dist/commands/__tests__/telemetry.test.d.ts +2 -0
  10. package/dist/commands/__tests__/telemetry.test.d.ts.map +1 -0
  11. package/dist/commands/__tests__/telemetry.test.js +79 -0
  12. package/dist/commands/__tests__/telemetry.test.js.map +1 -0
  13. package/dist/commands/__tests__/trade.test.d.ts +2 -0
  14. package/dist/commands/__tests__/trade.test.d.ts.map +1 -0
  15. package/dist/commands/__tests__/trade.test.js +147 -0
  16. package/dist/commands/__tests__/trade.test.js.map +1 -0
  17. package/dist/commands/auth.d.ts.map +1 -1
  18. package/dist/commands/auth.js +48 -5
  19. package/dist/commands/auth.js.map +1 -1
  20. package/dist/commands/balance.d.ts +16 -0
  21. package/dist/commands/balance.d.ts.map +1 -1
  22. package/dist/commands/balance.js +53 -22
  23. package/dist/commands/balance.js.map +1 -1
  24. package/dist/commands/bazaar.d.ts.map +1 -1
  25. package/dist/commands/bazaar.js +51 -22
  26. package/dist/commands/bazaar.js.map +1 -1
  27. package/dist/commands/persistence.d.ts +3 -0
  28. package/dist/commands/persistence.d.ts.map +1 -0
  29. package/dist/commands/persistence.js +75 -0
  30. package/dist/commands/persistence.js.map +1 -0
  31. package/dist/commands/quit.d.ts +3 -0
  32. package/dist/commands/quit.d.ts.map +1 -0
  33. package/dist/commands/quit.js +91 -0
  34. package/dist/commands/quit.js.map +1 -0
  35. package/dist/commands/send.d.ts.map +1 -1
  36. package/dist/commands/send.js +23 -14
  37. package/dist/commands/send.js.map +1 -1
  38. package/dist/commands/telemetry.d.ts +3 -0
  39. package/dist/commands/telemetry.d.ts.map +1 -0
  40. package/dist/commands/telemetry.js +41 -0
  41. package/dist/commands/telemetry.js.map +1 -0
  42. package/dist/commands/trade.d.ts +13 -0
  43. package/dist/commands/trade.d.ts.map +1 -1
  44. package/dist/commands/trade.js +22 -20
  45. package/dist/commands/trade.js.map +1 -1
  46. package/dist/constants.d.ts +11 -0
  47. package/dist/constants.d.ts.map +1 -0
  48. package/dist/constants.js +22 -0
  49. package/dist/constants.js.map +1 -0
  50. package/dist/formatters/output.d.ts +3 -2
  51. package/dist/formatters/output.d.ts.map +1 -1
  52. package/dist/formatters/output.js +13 -6
  53. package/dist/formatters/output.js.map +1 -1
  54. package/dist/index.js +0 -0
  55. package/dist/ipcClient.d.ts.map +1 -1
  56. package/dist/ipcClient.js +4 -3
  57. package/dist/ipcClient.js.map +1 -1
  58. package/dist/utils/chainValidation.d.ts +11 -0
  59. package/dist/utils/chainValidation.d.ts.map +1 -0
  60. package/dist/utils/chainValidation.js +29 -0
  61. package/dist/utils/chainValidation.js.map +1 -0
  62. package/dist/utils/configManager.d.ts +9 -0
  63. package/dist/utils/configManager.d.ts.map +1 -0
  64. package/dist/utils/configManager.js +46 -0
  65. package/dist/utils/configManager.js.map +1 -0
  66. package/dist/utils/errors.d.ts +4 -0
  67. package/dist/utils/errors.d.ts.map +1 -1
  68. package/dist/utils/errors.js +14 -10
  69. package/dist/utils/errors.js.map +1 -1
  70. package/dist/utils/parseAmount.d.ts +11 -1
  71. package/dist/utils/parseAmount.d.ts.map +1 -1
  72. package/dist/utils/parseAmount.js +36 -1
  73. package/dist/utils/parseAmount.js.map +1 -1
  74. package/dist/utils/serverManager.js +1 -1
  75. package/package.json +15 -6
  76. package/server-bundle/bundle-electron.js +43 -42
  77. package/server-bundle/package.json +1 -1
  78. package/server-bundle/preload.js +1 -1
  79. package/dist/commands/discover.d.ts +0 -3
  80. package/dist/commands/discover.d.ts.map +0 -1
  81. package/dist/commands/discover.js +0 -76
  82. package/dist/commands/discover.js.map +0 -1
  83. package/dist/utils/bazaarCache.d.ts +0 -36
  84. package/dist/utils/bazaarCache.d.ts.map +0 -1
  85. package/dist/utils/bazaarCache.js +0 -246
  86. package/dist/utils/bazaarCache.js.map +0 -1
package/README.md CHANGED
@@ -25,17 +25,22 @@ awal status
25
25
  awal auth login your@email.com
26
26
  awal auth verify <flow-id> <6-digit-code>
27
27
 
28
- # Check your balance
28
+ # Check your balance (all chains)
29
29
  awal balance
30
30
 
31
+ # Check balance on a specific chain
32
+ awal balance --chain polygon
33
+
31
34
  # Get your wallet address
32
35
  awal address
33
36
 
34
37
  # Send USDC
35
38
  awal send $1.00 0x...recipient...
39
+ awal send $1.00 0x...recipient... --chain polygon
36
40
 
37
41
  # Swap tokens
38
42
  awal trade $1 usdc eth
43
+ awal trade $1 usdc pol --chain polygon
39
44
  ```
40
45
 
41
46
  ## Commands
@@ -43,7 +48,7 @@ awal trade $1 usdc eth
43
48
  ### Wallet
44
49
 
45
50
  - `awal status` - Check server and auth status
46
- - `awal balance` - Get wallet balances (USDC, ETH, WETH)
51
+ - `awal balance` - Get wallet balances across all chains (Base: USDC/ETH, Polygon: USDC/POL, Solana: USDC/SOL)
47
52
  - `awal address` - Get wallet address
48
53
  - `awal show` - Open wallet UI
49
54
 
@@ -60,6 +65,14 @@ awal trade $1 usdc eth
60
65
  ### X402 Payments
61
66
 
62
67
  - `awal bazaar list` - List X402 payment services
68
+ - `awal bazaar search <query>` - Search bazaar resources by keyword
69
+ - `--network <network>` - Filter by chain (base, base-sepolia, polygon, solana, solana-devnet)
70
+ - `--scheme <scheme>` - Filter by payment scheme: `exact` or `upto`
71
+ - `--max-price <usd>` - Maximum price in USD (e.g. `0.01`)
72
+ - `--asset <address>` - Filter by payment asset address
73
+ - `--pay-to <address>` - Filter by recipient wallet address
74
+ - `--extensions <type>` - Filter by extension type (e.g. `outputSchema`, `bazaar`)
75
+ - `-k, --top <n>` - Max results, 1–20 (default: 20)
63
76
  - `awal bazaar details <url>` - Get service details
64
77
  - `awal pay <baseURL> <path>` - Make X402 payment request
65
78
  - `awal discover <baseURL> <path>` - Discover payment requirements
@@ -68,7 +81,7 @@ awal trade $1 usdc eth
68
81
 
69
82
  Most commands support:
70
83
  - `--json` - Output as JSON
71
- - `--chain <chain>` - Specify blockchain (default: base)
84
+ - `--chain <chain>` - Specify blockchain: base, base-sepolia, polygon, solana, solana-devnet (default: base)
72
85
 
73
86
  ## Architecture
74
87
 
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,wBAAgB,aAAa,IAAI,OAAO,CAmBvC"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBpC,wBAAgB,aAAa,IAAI,OAAO,CAmBvC"}
package/dist/cli.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Command } from 'commander';
2
+ import { createRequire } from 'module';
2
3
  import { createStatusCommand } from './commands/status.js';
3
4
  import { createBalanceCommand } from './commands/balance.js';
4
5
  import { createAddressCommand } from './commands/address.js';
@@ -7,13 +8,14 @@ import { createX402Command } from './commands/x402.js';
7
8
  import { createAuthCommand } from './commands/auth.js';
8
9
  import { createSendCommand } from './commands/send.js';
9
10
  import { createTradeCommand } from './commands/trade.js';
10
- const VERSION = '1.0.0';
11
+ import { createQuitCommand } from './commands/quit.js';
12
+ import { createTelemetryCommand } from './commands/telemetry.js';
13
+ import { createPersistenceCommand } from './commands/persistence.js';
14
+ const require = createRequire(import.meta.url);
15
+ const { version: VERSION } = require('../package.json');
11
16
  export function createProgram() {
12
17
  const program = new Command();
13
- program
14
- .name('awal')
15
- .description('Coinbase Wallet CLI for payments and crypto')
16
- .version(VERSION);
18
+ program.name('awal').description('Coinbase Wallet CLI for payments and crypto').version(VERSION);
17
19
  // Add commands
18
20
  program.addCommand(createStatusCommand());
19
21
  program.addCommand(createBalanceCommand());
@@ -23,6 +25,9 @@ export function createProgram() {
23
25
  program.addCommand(createAuthCommand());
24
26
  program.addCommand(createSendCommand());
25
27
  program.addCommand(createTradeCommand());
28
+ program.addCommand(createQuitCommand());
29
+ program.addCommand(createTelemetryCommand());
30
+ program.addCommand(createPersistenceCommand());
26
31
  return program;
27
32
  }
28
33
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,OAAO,GAAG,OAAO,CAAC;AAExB,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,MAAM,CAAC;SACZ,WAAW,CAAC,6CAA6C,CAAC;SAC1D,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,eAAe;IACf,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAEzC,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAErE,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAE/E,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,6CAA6C,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjG,eAAe;IACf,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACzC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,UAAU,CAAC,sBAAsB,EAAE,CAAC,CAAC;IAC7C,OAAO,CAAC,UAAU,CAAC,wBAAwB,EAAE,CAAC,CAAC;IAE/C,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=balance.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/balance.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,245 @@
1
+ jest.mock('ora', () => {
2
+ const spinner = { start: jest.fn(), stop: jest.fn(), fail: jest.fn() };
3
+ spinner.start.mockReturnValue(spinner);
4
+ return { __esModule: true, default: jest.fn(() => spinner) };
5
+ });
6
+ jest.mock('../../ipcClient.js', () => ({
7
+ sendIpcRequest: jest.fn(),
8
+ }));
9
+ jest.mock('../../utils/authCheck.js', () => ({
10
+ requireAuth: jest.fn(),
11
+ }));
12
+ import { sendIpcRequest } from '../../ipcClient.js';
13
+ import { requireAuth } from '../../utils/authCheck.js';
14
+ import { isSolanaChain, isPolygonChain } from '../../utils/chainValidation.js';
15
+ import { getDefaultAssetsForChain, getDefaultDecimals, filterDisplayAssets, createBalanceCommand, } from '../balance.js';
16
+ const mockSendIpcRequest = sendIpcRequest;
17
+ const mockRequireAuth = requireAuth;
18
+ function makeBalanceResponse(chain, balances) {
19
+ return {
20
+ address: '0xtest',
21
+ chain,
22
+ balances,
23
+ timestamp: new Date().toISOString(),
24
+ };
25
+ }
26
+ describe('balance command', () => {
27
+ describe('isSolanaChain', () => {
28
+ it('returns true for solana', () => {
29
+ expect(isSolanaChain('solana')).toBe(true);
30
+ });
31
+ it('returns true for solana-devnet', () => {
32
+ expect(isSolanaChain('solana-devnet')).toBe(true);
33
+ });
34
+ it('returns true for CAIP-2 solana chains', () => {
35
+ expect(isSolanaChain('solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp')).toBe(true);
36
+ });
37
+ it('returns false for base', () => {
38
+ expect(isSolanaChain('base')).toBe(false);
39
+ });
40
+ it('returns false for polygon', () => {
41
+ expect(isSolanaChain('polygon')).toBe(false);
42
+ });
43
+ it('returns false for undefined', () => {
44
+ expect(isSolanaChain(undefined)).toBe(false);
45
+ });
46
+ });
47
+ describe('isPolygonChain', () => {
48
+ it('returns true for polygon', () => {
49
+ expect(isPolygonChain('polygon')).toBe(true);
50
+ });
51
+ it('returns false for base', () => {
52
+ expect(isPolygonChain('base')).toBe(false);
53
+ });
54
+ it('returns false for solana', () => {
55
+ expect(isPolygonChain('solana')).toBe(false);
56
+ });
57
+ it('returns false for undefined', () => {
58
+ expect(isPolygonChain(undefined)).toBe(false);
59
+ });
60
+ });
61
+ describe('getDefaultAssetsForChain', () => {
62
+ it('returns Solana assets for solana chain', () => {
63
+ expect(getDefaultAssetsForChain('solana')).toEqual(['USDC', 'SOL']);
64
+ });
65
+ it('returns Polygon assets for polygon chain', () => {
66
+ expect(getDefaultAssetsForChain('polygon')).toEqual(['USDC', 'POL']);
67
+ });
68
+ it('returns Base assets for base chain', () => {
69
+ expect(getDefaultAssetsForChain('base')).toEqual(['USDC', 'ETH']);
70
+ });
71
+ it('returns Base assets for undefined (default)', () => {
72
+ expect(getDefaultAssetsForChain(undefined)).toEqual(['USDC', 'ETH']);
73
+ });
74
+ it('returns Base assets for unknown chains', () => {
75
+ expect(getDefaultAssetsForChain('arbitrum')).toEqual(['USDC', 'ETH']);
76
+ });
77
+ });
78
+ describe('getDefaultDecimals', () => {
79
+ it('returns 6 for USDC', () => {
80
+ expect(getDefaultDecimals('USDC')).toBe(6);
81
+ });
82
+ it('returns 6 for usdc (case-insensitive)', () => {
83
+ expect(getDefaultDecimals('usdc')).toBe(6);
84
+ });
85
+ it('returns 9 for SOL', () => {
86
+ expect(getDefaultDecimals('SOL')).toBe(9);
87
+ });
88
+ it('returns 18 for ETH', () => {
89
+ expect(getDefaultDecimals('ETH')).toBe(18);
90
+ });
91
+ it('returns 18 for POL', () => {
92
+ expect(getDefaultDecimals('POL')).toBe(18);
93
+ });
94
+ it('returns 18 for unknown assets', () => {
95
+ expect(getDefaultDecimals('UNKNOWN')).toBe(18);
96
+ });
97
+ });
98
+ describe('filterDisplayAssets', () => {
99
+ it('always shows USDC and native token even with zero balance', () => {
100
+ const result = filterDisplayAssets('base', ['USDC', 'ETH'], {
101
+ USDC: { raw: '0', formatted: '0', decimals: 6 },
102
+ ETH: { raw: '0', formatted: '0', decimals: 18 },
103
+ });
104
+ expect(result).toEqual(['USDC', 'ETH']);
105
+ });
106
+ it('always shows USDC and SOL on solana', () => {
107
+ const result = filterDisplayAssets('solana', ['USDC', 'SOL'], {
108
+ USDC: { raw: '0', formatted: '0', decimals: 6 },
109
+ SOL: { raw: '0', formatted: '0', decimals: 9 },
110
+ });
111
+ expect(result).toEqual(['USDC', 'SOL']);
112
+ });
113
+ it('returns all assets for unknown chains', () => {
114
+ const result = filterDisplayAssets('arbitrum', ['USDC', 'ETH'], {
115
+ USDC: { raw: '0', formatted: '0', decimals: 6 },
116
+ ETH: { raw: '0', formatted: '0', decimals: 18 },
117
+ });
118
+ expect(result).toEqual(['USDC', 'ETH']);
119
+ });
120
+ it('treats missing balance data as zero', () => {
121
+ const result = filterDisplayAssets('base', ['USDC', 'ETH'], {
122
+ USDC: { raw: '1000000', formatted: '1.0', decimals: 6 },
123
+ });
124
+ expect(result).toEqual(['USDC', 'ETH']);
125
+ });
126
+ });
127
+ describe('createBalanceCommand', () => {
128
+ let consoleSpy;
129
+ beforeEach(() => {
130
+ consoleSpy = jest.spyOn(console, 'log').mockImplementation();
131
+ jest.spyOn(console, 'error').mockImplementation();
132
+ mockRequireAuth.mockResolvedValue(undefined);
133
+ });
134
+ afterEach(() => {
135
+ consoleSpy.mockRestore();
136
+ });
137
+ describe('single-chain mode', () => {
138
+ it('uses Polygon default assets for --chain polygon', async () => {
139
+ mockSendIpcRequest.mockResolvedValue(makeBalanceResponse('Polygon', {
140
+ USDC: { raw: '1000000', formatted: '1.0', decimals: 6 },
141
+ POL: { raw: '1000000000000000000', formatted: '1.0', decimals: 18 },
142
+ }));
143
+ const cmd = createBalanceCommand();
144
+ await cmd.parseAsync(['--chain', 'polygon'], { from: 'user' });
145
+ expect(mockSendIpcRequest).toHaveBeenCalledWith('get-wallet-balance', {
146
+ assets: ['USDC', 'POL'],
147
+ chain: 'polygon',
148
+ });
149
+ });
150
+ it('uses Base default assets for --chain base', async () => {
151
+ mockSendIpcRequest.mockResolvedValue(makeBalanceResponse('Base', {
152
+ USDC: { raw: '1000000', formatted: '1.0', decimals: 6 },
153
+ ETH: { raw: '0', formatted: '0', decimals: 18 },
154
+ }));
155
+ const cmd = createBalanceCommand();
156
+ await cmd.parseAsync(['--chain', 'base'], { from: 'user' });
157
+ expect(mockSendIpcRequest).toHaveBeenCalledWith('get-wallet-balance', {
158
+ assets: ['USDC', 'ETH'],
159
+ chain: 'base',
160
+ });
161
+ });
162
+ it('uses Solana default assets for --chain solana', async () => {
163
+ mockSendIpcRequest.mockResolvedValue(makeBalanceResponse('Solana', {
164
+ USDC: { raw: '1000000', formatted: '1.0', decimals: 6 },
165
+ SOL: { raw: '1000000000', formatted: '1.0', decimals: 9 },
166
+ }));
167
+ const cmd = createBalanceCommand();
168
+ await cmd.parseAsync(['--chain', 'solana'], { from: 'user' });
169
+ expect(mockSendIpcRequest).toHaveBeenCalledWith('get-wallet-balance', {
170
+ assets: ['USDC', 'SOL'],
171
+ chain: 'solana',
172
+ });
173
+ });
174
+ it('uses explicit asset when --asset is provided', async () => {
175
+ mockSendIpcRequest.mockResolvedValue(makeBalanceResponse('Polygon', {
176
+ POL: { raw: '1000000000000000000', formatted: '1.0', decimals: 18 },
177
+ }));
178
+ const cmd = createBalanceCommand();
179
+ await cmd.parseAsync(['--chain', 'polygon', '--asset', 'pol'], { from: 'user' });
180
+ expect(mockSendIpcRequest).toHaveBeenCalledWith('get-wallet-balance', {
181
+ assets: ['POL'],
182
+ chain: 'polygon',
183
+ });
184
+ });
185
+ });
186
+ describe('all-chains mode', () => {
187
+ it('queries Base, Polygon, and Solana in parallel', async () => {
188
+ mockSendIpcRequest
189
+ .mockResolvedValueOnce(makeBalanceResponse('Base', {
190
+ USDC: { raw: '1000000', formatted: '1.0', decimals: 6 },
191
+ ETH: { raw: '0', formatted: '0', decimals: 18 },
192
+ }))
193
+ .mockResolvedValueOnce(makeBalanceResponse('Polygon', {
194
+ USDC: { raw: '0', formatted: '0', decimals: 6 },
195
+ POL: { raw: '0', formatted: '0', decimals: 18 },
196
+ }))
197
+ .mockResolvedValueOnce(makeBalanceResponse('Solana', {
198
+ USDC: { raw: '0', formatted: '0', decimals: 6 },
199
+ SOL: { raw: '0', formatted: '0', decimals: 9 },
200
+ }));
201
+ const cmd = createBalanceCommand();
202
+ await cmd.parseAsync([], { from: 'user' });
203
+ expect(mockSendIpcRequest).toHaveBeenCalledTimes(3);
204
+ expect(mockSendIpcRequest).toHaveBeenCalledWith('get-wallet-balance', {
205
+ assets: ['USDC', 'ETH'],
206
+ chain: 'base',
207
+ });
208
+ expect(mockSendIpcRequest).toHaveBeenCalledWith('get-wallet-balance', {
209
+ assets: ['USDC', 'POL'],
210
+ chain: 'polygon',
211
+ });
212
+ expect(mockSendIpcRequest).toHaveBeenCalledWith('get-wallet-balance', {
213
+ assets: ['USDC', 'SOL'],
214
+ chain: 'solana',
215
+ });
216
+ });
217
+ it('outputs JSON with base, polygon, and solana keys', async () => {
218
+ const baseResp = makeBalanceResponse('Base', {
219
+ USDC: { raw: '1000000', formatted: '1.0', decimals: 6 },
220
+ ETH: { raw: '0', formatted: '0', decimals: 18 },
221
+ });
222
+ const polygonResp = makeBalanceResponse('Polygon', {
223
+ USDC: { raw: '0', formatted: '0', decimals: 6 },
224
+ POL: { raw: '0', formatted: '0', decimals: 18 },
225
+ });
226
+ const solanaResp = makeBalanceResponse('Solana', {
227
+ USDC: { raw: '0', formatted: '0', decimals: 6 },
228
+ SOL: { raw: '0', formatted: '0', decimals: 9 },
229
+ });
230
+ mockSendIpcRequest
231
+ .mockResolvedValueOnce(baseResp)
232
+ .mockResolvedValueOnce(polygonResp)
233
+ .mockResolvedValueOnce(solanaResp);
234
+ const cmd = createBalanceCommand();
235
+ await cmd.parseAsync(['--json'], { from: 'user' });
236
+ const output = consoleSpy.mock.calls[0][0];
237
+ const parsed = JSON.parse(output);
238
+ expect(parsed).toHaveProperty('base');
239
+ expect(parsed).toHaveProperty('polygon');
240
+ expect(parsed).toHaveProperty('solana');
241
+ });
242
+ });
243
+ });
244
+ });
245
+ //# sourceMappingURL=balance.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/balance.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=telemetry.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/telemetry.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,79 @@
1
+ import { writeFileSync } from 'fs';
2
+ jest.mock('fs');
3
+ jest.mock('env-paths', () => {
4
+ return jest.fn(() => ({
5
+ data: '/mock/awal-data',
6
+ config: '/mock/awal-config',
7
+ cache: '/mock/awal-cache',
8
+ log: '/mock/awal-log',
9
+ temp: '/mock/awal-temp',
10
+ }));
11
+ });
12
+ import { createTelemetryCommand } from '../telemetry.js';
13
+ const mockWriteFileSync = writeFileSync;
14
+ describe('telemetry command', () => {
15
+ describe('CLI commands', () => {
16
+ let consoleSpy;
17
+ beforeEach(() => {
18
+ consoleSpy = jest.spyOn(console, 'log').mockImplementation();
19
+ jest.clearAllMocks();
20
+ });
21
+ afterEach(() => {
22
+ consoleSpy.mockRestore();
23
+ });
24
+ it('disable writes telemetryDisabled: true to config.json', async () => {
25
+ const { existsSync, readFileSync } = await import('fs');
26
+ existsSync.mockReturnValue(false);
27
+ const cmd = createTelemetryCommand();
28
+ await cmd.parseAsync(['disable'], { from: 'user' });
29
+ expect(mockWriteFileSync).toHaveBeenCalledWith('/mock/awal-data/config.json', expect.any(String), expect.objectContaining({ mode: 0o600 }));
30
+ const written = mockWriteFileSync.mock.calls[0][1];
31
+ const parsed = JSON.parse(written);
32
+ expect(parsed.telemetryDisabled).toBe(true);
33
+ });
34
+ it('enable writes telemetryDisabled: false to config.json', async () => {
35
+ const { existsSync } = await import('fs');
36
+ existsSync.mockReturnValue(false);
37
+ const cmd = createTelemetryCommand();
38
+ await cmd.parseAsync(['enable'], { from: 'user' });
39
+ const written = mockWriteFileSync.mock.calls[0][1];
40
+ const parsed = JSON.parse(written);
41
+ expect(parsed.telemetryDisabled).toBe(false);
42
+ });
43
+ it('status reports disabled when telemetryDisabled is true', async () => {
44
+ const { existsSync, readFileSync } = await import('fs');
45
+ existsSync.mockReturnValue(true);
46
+ readFileSync.mockReturnValue(JSON.stringify({ telemetryDisabled: true }));
47
+ const cmd = createTelemetryCommand();
48
+ await cmd.parseAsync(['status'], { from: 'user' });
49
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('disabled'));
50
+ });
51
+ it('status reports enabled when telemetryDisabled is false', async () => {
52
+ const { existsSync, readFileSync } = await import('fs');
53
+ existsSync.mockReturnValue(true);
54
+ readFileSync.mockReturnValue(JSON.stringify({ telemetryDisabled: false }));
55
+ const cmd = createTelemetryCommand();
56
+ await cmd.parseAsync(['status'], { from: 'user' });
57
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('enabled'));
58
+ });
59
+ it('status reports enabled when config file does not exist', async () => {
60
+ const { existsSync } = await import('fs');
61
+ existsSync.mockReturnValue(false);
62
+ const cmd = createTelemetryCommand();
63
+ await cmd.parseAsync(['status'], { from: 'user' });
64
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('enabled'));
65
+ });
66
+ it('preserves existing config keys when writing', async () => {
67
+ const { existsSync, readFileSync } = await import('fs');
68
+ existsSync.mockReturnValue(true);
69
+ readFileSync.mockReturnValue(JSON.stringify({ persistence: false }));
70
+ const cmd = createTelemetryCommand();
71
+ await cmd.parseAsync(['disable'], { from: 'user' });
72
+ const written = mockWriteFileSync.mock.calls[0][1];
73
+ const parsed = JSON.parse(written);
74
+ expect(parsed.persistence).toBe(false);
75
+ expect(parsed.telemetryDisabled).toBe(true);
76
+ });
77
+ });
78
+ });
79
+ //# sourceMappingURL=telemetry.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/telemetry.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=trade.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trade.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/trade.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,147 @@
1
+ jest.mock('ora', () => {
2
+ const spinner = { start: jest.fn(), stop: jest.fn(), fail: jest.fn(), text: '' };
3
+ spinner.start.mockReturnValue(spinner);
4
+ return { __esModule: true, default: jest.fn(() => spinner) };
5
+ });
6
+ jest.mock('../../ipcClient.js', () => ({
7
+ sendIpcRequest: jest.fn(),
8
+ }));
9
+ jest.mock('../../utils/authCheck.js', () => ({
10
+ requireAuth: jest.fn(),
11
+ }));
12
+ import { sendIpcRequest } from '../../ipcClient.js';
13
+ import { requireAuth } from '../../utils/authCheck.js';
14
+ import { TOKEN_ALIASES, resolveTokenDisplay, createTradeCommand } from '../trade.js';
15
+ const mockSendIpcRequest = sendIpcRequest;
16
+ const mockRequireAuth = requireAuth;
17
+ describe('trade command', () => {
18
+ describe('TOKEN_ALIASES', () => {
19
+ it('includes Base tokens', () => {
20
+ expect(TOKEN_ALIASES).toHaveProperty('usdc');
21
+ expect(TOKEN_ALIASES).toHaveProperty('eth');
22
+ });
23
+ it('includes Polygon tokens', () => {
24
+ expect(TOKEN_ALIASES).toHaveProperty('pol');
25
+ });
26
+ it('has correct decimals for POL', () => {
27
+ expect(TOKEN_ALIASES.pol.decimals).toBe(18);
28
+ expect(TOKEN_ALIASES.pol.display).toBe('POL');
29
+ });
30
+ it('has correct decimals for USDC', () => {
31
+ expect(TOKEN_ALIASES.usdc.decimals).toBe(6);
32
+ });
33
+ });
34
+ describe('resolveTokenDisplay', () => {
35
+ it('resolves pol alias', () => {
36
+ const result = resolveTokenDisplay('pol');
37
+ expect(result).toEqual({ token: 'pol', decimals: 18, display: 'POL' });
38
+ });
39
+ it('resolves usdc alias', () => {
40
+ const result = resolveTokenDisplay('usdc');
41
+ expect(result).toEqual({ token: 'usdc', decimals: 6, display: 'USDC' });
42
+ });
43
+ it('resolves eth alias', () => {
44
+ const result = resolveTokenDisplay('eth');
45
+ expect(result).toEqual({ token: 'eth', decimals: 18, display: 'ETH' });
46
+ });
47
+ it('resolves 0x address', () => {
48
+ const result = resolveTokenDisplay('0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359');
49
+ expect(result).not.toBeNull();
50
+ expect(result.token).toBe('0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359');
51
+ });
52
+ it('returns null for unknown non-address token', () => {
53
+ const result = resolveTokenDisplay('foobar');
54
+ expect(result).toBeNull();
55
+ });
56
+ it('is case-insensitive for aliases', () => {
57
+ const result = resolveTokenDisplay('POL');
58
+ expect(result).toEqual({ token: 'pol', decimals: 18, display: 'POL' });
59
+ });
60
+ });
61
+ describe('createTradeCommand', () => {
62
+ let consoleSpy;
63
+ beforeEach(() => {
64
+ consoleSpy = jest.spyOn(console, 'log').mockImplementation();
65
+ jest.spyOn(console, 'error').mockImplementation();
66
+ mockRequireAuth.mockResolvedValue(undefined);
67
+ });
68
+ afterEach(() => {
69
+ consoleSpy.mockRestore();
70
+ });
71
+ it('passes polygon chain to IPC request', async () => {
72
+ mockSendIpcRequest.mockResolvedValue({
73
+ success: true,
74
+ transactionHash: '0xabc',
75
+ blockExplorerUrl: 'https://polygonscan.com/tx/0xabc',
76
+ fromToken: 'usdc',
77
+ toToken: 'pol',
78
+ fromAmount: '1000000',
79
+ toAmount: '2000000000000000000',
80
+ chain: 'Polygon',
81
+ });
82
+ const cmd = createTradeCommand();
83
+ await cmd.parseAsync(['$1', 'usdc', 'pol', '--chain', 'polygon'], { from: 'user' });
84
+ expect(mockSendIpcRequest).toHaveBeenCalledWith('execute-swap', {
85
+ fromToken: 'usdc',
86
+ toToken: 'pol',
87
+ fromAmount: '$1',
88
+ chain: 'polygon',
89
+ slippageBps: 100,
90
+ });
91
+ });
92
+ it('shows Polygonscan label for polygon chain', async () => {
93
+ mockSendIpcRequest.mockResolvedValue({
94
+ success: true,
95
+ transactionHash: '0xabc',
96
+ blockExplorerUrl: 'https://polygonscan.com/tx/0xabc',
97
+ fromToken: 'usdc',
98
+ toToken: 'pol',
99
+ fromAmount: '1000000',
100
+ toAmount: '2000000000000000000',
101
+ chain: 'Polygon',
102
+ });
103
+ const cmd = createTradeCommand();
104
+ await cmd.parseAsync(['$1', 'usdc', 'pol', '--chain', 'polygon'], { from: 'user' });
105
+ const output = consoleSpy.mock.calls.map((c) => c[0]).join('\n');
106
+ expect(output).toContain('Polygonscan');
107
+ expect(output).not.toContain('Basescan');
108
+ });
109
+ it('shows Basescan label for base chain', async () => {
110
+ mockSendIpcRequest.mockResolvedValue({
111
+ success: true,
112
+ transactionHash: '0xabc',
113
+ blockExplorerUrl: 'https://basescan.org/tx/0xabc',
114
+ fromToken: 'usdc',
115
+ toToken: 'eth',
116
+ fromAmount: '1000000',
117
+ toAmount: '500000000000000',
118
+ chain: 'Base',
119
+ });
120
+ const cmd = createTradeCommand();
121
+ await cmd.parseAsync(['$1', 'usdc', 'eth', '--chain', 'base'], { from: 'user' });
122
+ const output = consoleSpy.mock.calls.map((c) => c[0]).join('\n');
123
+ expect(output).toContain('Basescan');
124
+ });
125
+ it('outputs JSON with polygon chain info', async () => {
126
+ const response = {
127
+ success: true,
128
+ transactionHash: '0xabc',
129
+ fromToken: 'usdc',
130
+ toToken: 'pol',
131
+ fromAmount: '1000000',
132
+ toAmount: '2000000000000000000',
133
+ chain: 'Polygon',
134
+ };
135
+ mockSendIpcRequest.mockResolvedValue(response);
136
+ const cmd = createTradeCommand();
137
+ await cmd.parseAsync(['$1', 'usdc', 'pol', '--chain', 'polygon', '--json'], {
138
+ from: 'user',
139
+ });
140
+ const output = consoleSpy.mock.calls[0][0];
141
+ const parsed = JSON.parse(output);
142
+ expect(parsed.chain).toBe('Polygon');
143
+ expect(parsed.toToken).toBe('pol');
144
+ });
145
+ });
146
+ });
147
+ //# sourceMappingURL=trade.test.js.map