@manifest-network/manifest-mcp-browser 0.1.1 → 0.1.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.
Files changed (121) hide show
  1. package/.github/workflows/publish.yml +4 -2
  2. package/CLAUDE.md +7 -3
  3. package/README.md +1 -1
  4. package/dist/client.d.ts +6 -1
  5. package/dist/client.d.ts.map +1 -1
  6. package/dist/client.js +77 -21
  7. package/dist/client.js.map +1 -1
  8. package/dist/cosmos.d.ts.map +1 -1
  9. package/dist/cosmos.js +7 -57
  10. package/dist/cosmos.js.map +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +16 -25
  13. package/dist/index.js.map +1 -1
  14. package/dist/modules.d.ts +30 -1
  15. package/dist/modules.d.ts.map +1 -1
  16. package/dist/modules.js +65 -1
  17. package/dist/modules.js.map +1 -1
  18. package/dist/modules.test.js +58 -1
  19. package/dist/modules.test.js.map +1 -1
  20. package/dist/queries/auth.d.ts +7 -1
  21. package/dist/queries/auth.d.ts.map +1 -1
  22. package/dist/queries/auth.js +18 -45
  23. package/dist/queries/auth.js.map +1 -1
  24. package/dist/queries/bank.d.ts +7 -1
  25. package/dist/queries/bank.d.ts.map +1 -1
  26. package/dist/queries/bank.js +24 -38
  27. package/dist/queries/bank.js.map +1 -1
  28. package/dist/queries/billing.d.ts +7 -1
  29. package/dist/queries/billing.d.ts.map +1 -1
  30. package/dist/queries/billing.js +28 -54
  31. package/dist/queries/billing.js.map +1 -1
  32. package/dist/queries/distribution.d.ts +7 -1
  33. package/dist/queries/distribution.d.ts.map +1 -1
  34. package/dist/queries/distribution.js +18 -36
  35. package/dist/queries/distribution.js.map +1 -1
  36. package/dist/queries/gov.d.ts +7 -1
  37. package/dist/queries/gov.d.ts.map +1 -1
  38. package/dist/queries/gov.js +24 -41
  39. package/dist/queries/gov.js.map +1 -1
  40. package/dist/queries/index.d.ts +2 -1
  41. package/dist/queries/index.d.ts.map +1 -1
  42. package/dist/queries/index.js +1 -1
  43. package/dist/queries/index.js.map +1 -1
  44. package/dist/queries/staking.d.ts +7 -1
  45. package/dist/queries/staking.d.ts.map +1 -1
  46. package/dist/queries/staking.js +36 -59
  47. package/dist/queries/staking.js.map +1 -1
  48. package/dist/queries/utils.d.ts +42 -10
  49. package/dist/queries/utils.d.ts.map +1 -1
  50. package/dist/queries/utils.js +64 -12
  51. package/dist/queries/utils.js.map +1 -1
  52. package/dist/queries/utils.test.js +68 -8
  53. package/dist/queries/utils.test.js.map +1 -1
  54. package/dist/transactions/bank.d.ts +2 -2
  55. package/dist/transactions/bank.d.ts.map +1 -1
  56. package/dist/transactions/bank.js +9 -18
  57. package/dist/transactions/bank.js.map +1 -1
  58. package/dist/transactions/billing.d.ts +2 -2
  59. package/dist/transactions/billing.d.ts.map +1 -1
  60. package/dist/transactions/billing.js +29 -86
  61. package/dist/transactions/billing.js.map +1 -1
  62. package/dist/transactions/distribution.d.ts +2 -2
  63. package/dist/transactions/distribution.d.ts.map +1 -1
  64. package/dist/transactions/distribution.js +7 -13
  65. package/dist/transactions/distribution.js.map +1 -1
  66. package/dist/transactions/gov.d.ts +2 -2
  67. package/dist/transactions/gov.d.ts.map +1 -1
  68. package/dist/transactions/gov.js +29 -20
  69. package/dist/transactions/gov.js.map +1 -1
  70. package/dist/transactions/index.d.ts +1 -1
  71. package/dist/transactions/index.d.ts.map +1 -1
  72. package/dist/transactions/index.js +1 -1
  73. package/dist/transactions/index.js.map +1 -1
  74. package/dist/transactions/manifest.d.ts +2 -2
  75. package/dist/transactions/manifest.d.ts.map +1 -1
  76. package/dist/transactions/manifest.js +7 -14
  77. package/dist/transactions/manifest.js.map +1 -1
  78. package/dist/transactions/staking.d.ts +2 -2
  79. package/dist/transactions/staking.d.ts.map +1 -1
  80. package/dist/transactions/staking.js +7 -13
  81. package/dist/transactions/staking.js.map +1 -1
  82. package/dist/transactions/utils.d.ts +63 -1
  83. package/dist/transactions/utils.d.ts.map +1 -1
  84. package/dist/transactions/utils.js +121 -2
  85. package/dist/transactions/utils.js.map +1 -1
  86. package/dist/transactions/utils.test.js +351 -1
  87. package/dist/transactions/utils.test.js.map +1 -1
  88. package/dist/types.d.ts +203 -8
  89. package/dist/types.d.ts.map +1 -1
  90. package/dist/types.js.map +1 -1
  91. package/dist/wallet/mnemonic.d.ts +1 -0
  92. package/dist/wallet/mnemonic.d.ts.map +1 -1
  93. package/dist/wallet/mnemonic.js +34 -13
  94. package/dist/wallet/mnemonic.js.map +1 -1
  95. package/package.json +5 -1
  96. package/src/client.ts +84 -21
  97. package/src/cosmos.ts +13 -109
  98. package/src/index.ts +17 -23
  99. package/src/modules.test.ts +60 -0
  100. package/src/modules.ts +122 -5
  101. package/src/queries/auth.ts +35 -74
  102. package/src/queries/bank.ts +40 -58
  103. package/src/queries/billing.ts +46 -86
  104. package/src/queries/distribution.ts +35 -59
  105. package/src/queries/gov.ts +40 -64
  106. package/src/queries/index.ts +10 -1
  107. package/src/queries/staking.ts +55 -91
  108. package/src/queries/utils.test.ts +103 -8
  109. package/src/queries/utils.ts +92 -12
  110. package/src/transactions/bank.ts +9 -33
  111. package/src/transactions/billing.ts +30 -137
  112. package/src/transactions/distribution.ts +7 -29
  113. package/src/transactions/gov.ts +33 -37
  114. package/src/transactions/index.ts +1 -1
  115. package/src/transactions/manifest.ts +7 -29
  116. package/src/transactions/staking.ts +7 -29
  117. package/src/transactions/utils.test.ts +390 -1
  118. package/src/transactions/utils.ts +191 -2
  119. package/src/types.ts +318 -9
  120. package/src/wallet/mnemonic.ts +41 -17
  121. package/.claude/settings.local.json +0 -20
package/src/modules.ts CHANGED
@@ -1,4 +1,66 @@
1
- import { ModuleInfo, AvailableModules, ManifestMCPError, ManifestMCPErrorCode } from './types.js';
1
+ import { SigningStargateClient } from '@cosmjs/stargate';
2
+ import { ModuleInfo, AvailableModules, ManifestMCPError, ManifestMCPErrorCode, CosmosTxResult, QueryResult } from './types.js';
3
+ import { ManifestQueryClient } from './client.js';
4
+
5
+ // Import query handlers
6
+ import { routeBankQuery } from './queries/bank.js';
7
+ import { routeStakingQuery } from './queries/staking.js';
8
+ import { routeDistributionQuery } from './queries/distribution.js';
9
+ import { routeGovQuery } from './queries/gov.js';
10
+ import { routeAuthQuery } from './queries/auth.js';
11
+ import { routeBillingQuery } from './queries/billing.js';
12
+
13
+ // Import transaction handlers
14
+ import { routeBankTransaction } from './transactions/bank.js';
15
+ import { routeStakingTransaction } from './transactions/staking.js';
16
+ import { routeDistributionTransaction } from './transactions/distribution.js';
17
+ import { routeGovTransaction } from './transactions/gov.js';
18
+ import { routeBillingTransaction } from './transactions/billing.js';
19
+ import { routeManifestTransaction } from './transactions/manifest.js';
20
+
21
+ /**
22
+ * Handler function type for query modules
23
+ */
24
+ export type QueryHandler = (
25
+ queryClient: ManifestQueryClient,
26
+ subcommand: string,
27
+ args: string[]
28
+ ) => Promise<QueryResult>;
29
+
30
+ /**
31
+ * Handler function type for transaction modules
32
+ */
33
+ export type TxHandler = (
34
+ signingClient: SigningStargateClient,
35
+ senderAddress: string,
36
+ subcommand: string,
37
+ args: string[],
38
+ waitForConfirmation: boolean
39
+ ) => Promise<CosmosTxResult>;
40
+
41
+ /**
42
+ * Throw an error for an unsupported subcommand.
43
+ * Automatically looks up available subcommands from the module registry.
44
+ *
45
+ * @param type - 'query' or 'tx'
46
+ * @param module - The module name (e.g., 'bank', 'staking')
47
+ * @param subcommand - The unsupported subcommand that was requested
48
+ */
49
+ export function throwUnsupportedSubcommand(
50
+ type: 'query' | 'tx',
51
+ module: string,
52
+ subcommand: string
53
+ ): never {
54
+ const registry = type === 'query' ? QUERY_MODULES : TX_MODULES;
55
+ const moduleInfo = registry[module];
56
+ const availableSubcommands = moduleInfo?.subcommands.map(s => s.name) ?? [];
57
+
58
+ throw new ManifestMCPError(
59
+ type === 'query' ? ManifestMCPErrorCode.UNSUPPORTED_QUERY : ManifestMCPErrorCode.UNSUPPORTED_TX,
60
+ `Unsupported ${module} ${type === 'query' ? 'query' : 'transaction'} subcommand: ${subcommand}`,
61
+ { availableSubcommands }
62
+ );
63
+ }
2
64
 
3
65
  /**
4
66
  * Static module registry for browser-compatible module discovery
@@ -11,19 +73,30 @@ interface SubcommandInfo {
11
73
  args?: string; // Usage hint for arguments
12
74
  }
13
75
 
14
- interface ModuleRegistry {
76
+ interface QueryModuleRegistry {
15
77
  [moduleName: string]: {
16
78
  description: string;
17
79
  subcommands: SubcommandInfo[];
80
+ handler: QueryHandler;
81
+ };
82
+ }
83
+
84
+ interface TxModuleRegistry {
85
+ [moduleName: string]: {
86
+ description: string;
87
+ subcommands: SubcommandInfo[];
88
+ handler: TxHandler;
18
89
  };
19
90
  }
20
91
 
21
92
  /**
22
93
  * Query modules registry
94
+ * Each module includes metadata and its handler function
23
95
  */
24
- const QUERY_MODULES: ModuleRegistry = {
96
+ const QUERY_MODULES: QueryModuleRegistry = {
25
97
  bank: {
26
98
  description: 'Querying commands for the bank module',
99
+ handler: routeBankQuery,
27
100
  subcommands: [
28
101
  { name: 'balance', description: 'Query account balance for a specific denom' },
29
102
  { name: 'balances', description: 'Query all balances for an account' },
@@ -39,6 +112,7 @@ const QUERY_MODULES: ModuleRegistry = {
39
112
  },
40
113
  staking: {
41
114
  description: 'Querying commands for the staking module',
115
+ handler: routeStakingQuery,
42
116
  subcommands: [
43
117
  { name: 'delegation', description: 'Query a delegation' },
44
118
  { name: 'delegations', description: 'Query all delegations for a delegator' },
@@ -56,6 +130,7 @@ const QUERY_MODULES: ModuleRegistry = {
56
130
  },
57
131
  distribution: {
58
132
  description: 'Querying commands for the distribution module',
133
+ handler: routeDistributionQuery,
59
134
  subcommands: [
60
135
  { name: 'rewards', description: 'Query distribution rewards for a delegator' },
61
136
  { name: 'commission', description: 'Query validator commission' },
@@ -69,6 +144,7 @@ const QUERY_MODULES: ModuleRegistry = {
69
144
  },
70
145
  gov: {
71
146
  description: 'Querying commands for the governance module',
147
+ handler: routeGovQuery,
72
148
  subcommands: [
73
149
  { name: 'proposal', description: 'Query a proposal by ID' },
74
150
  { name: 'proposals', description: 'Query all proposals' },
@@ -82,6 +158,7 @@ const QUERY_MODULES: ModuleRegistry = {
82
158
  },
83
159
  auth: {
84
160
  description: 'Querying commands for the auth module',
161
+ handler: routeAuthQuery,
85
162
  subcommands: [
86
163
  { name: 'account', description: 'Query account by address' },
87
164
  { name: 'accounts', description: 'Query all accounts' },
@@ -96,6 +173,7 @@ const QUERY_MODULES: ModuleRegistry = {
96
173
  },
97
174
  billing: {
98
175
  description: 'Querying commands for the Manifest billing module',
176
+ handler: routeBillingQuery,
99
177
  subcommands: [
100
178
  { name: 'params', description: 'Query billing parameters' },
101
179
  { name: 'lease', description: 'Query a lease by UUID' },
@@ -115,10 +193,12 @@ const QUERY_MODULES: ModuleRegistry = {
115
193
 
116
194
  /**
117
195
  * Transaction modules registry
196
+ * Each module includes metadata and its handler function
118
197
  */
119
- const TX_MODULES: ModuleRegistry = {
198
+ const TX_MODULES: TxModuleRegistry = {
120
199
  bank: {
121
200
  description: 'Bank transaction subcommands',
201
+ handler: routeBankTransaction,
122
202
  subcommands: [
123
203
  { name: 'send', description: 'Send tokens to another account', args: '<to-address> <amount> (e.g., manifest1abc... 1000000umfx)' },
124
204
  { name: 'multi-send', description: 'Send tokens to multiple accounts', args: '<to-address:amount>... (e.g., manifest1a:1000umfx manifest1b:2000umfx)' },
@@ -126,6 +206,7 @@ const TX_MODULES: ModuleRegistry = {
126
206
  },
127
207
  staking: {
128
208
  description: 'Staking transaction subcommands',
209
+ handler: routeStakingTransaction,
129
210
  subcommands: [
130
211
  { name: 'delegate', description: 'Delegate tokens to a validator' },
131
212
  { name: 'unbond', description: 'Unbond tokens from a validator' },
@@ -135,6 +216,7 @@ const TX_MODULES: ModuleRegistry = {
135
216
  },
136
217
  distribution: {
137
218
  description: 'Distribution transaction subcommands',
219
+ handler: routeDistributionTransaction,
138
220
  subcommands: [
139
221
  { name: 'withdraw-rewards', description: 'Withdraw rewards from a validator' },
140
222
  { name: 'set-withdraw-addr', description: 'Set withdraw address' },
@@ -143,6 +225,7 @@ const TX_MODULES: ModuleRegistry = {
143
225
  },
144
226
  gov: {
145
227
  description: 'Governance transaction subcommands',
228
+ handler: routeGovTransaction,
146
229
  subcommands: [
147
230
  { name: 'vote', description: 'Vote on a proposal' },
148
231
  { name: 'weighted-vote', description: 'Weighted vote on a proposal' },
@@ -151,15 +234,17 @@ const TX_MODULES: ModuleRegistry = {
151
234
  },
152
235
  billing: {
153
236
  description: 'Manifest billing transaction subcommands',
237
+ handler: routeBillingTransaction,
154
238
  subcommands: [
155
239
  { name: 'fund-credit', description: 'Fund credit for a tenant', args: '<tenant-address> <amount> (e.g., manifest1abc... 1000000umfx)' },
156
240
  { name: 'create-lease', description: 'Create a new lease', args: '[--meta-hash <hex>] <sku-uuid:quantity>... (e.g., sku-123:1 sku-456:2)' },
157
- { name: 'close-lease', description: 'Close one or more leases', args: '<lease-uuid>... (e.g., lease-123 lease-456)' },
241
+ { name: 'close-lease', description: 'Close one or more leases', args: '[--reason <text>] <lease-uuid>... (e.g., lease-123 lease-456)' },
158
242
  { name: 'withdraw', description: 'Withdraw earnings from leases', args: '<lease-uuid>... OR --provider <provider-uuid> [--limit <1-100>]' },
159
243
  ],
160
244
  },
161
245
  manifest: {
162
246
  description: 'Manifest module transaction subcommands',
247
+ handler: routeManifestTransaction,
163
248
  subcommands: [
164
249
  { name: 'payout', description: 'Execute a payout to multiple addresses' },
165
250
  { name: 'burn-held-balance', description: 'Burn held balance' },
@@ -276,3 +361,35 @@ export function getSupportedModules(): {
276
361
 
277
362
  return result;
278
363
  }
364
+
365
+ /**
366
+ * Get the handler function for a query module
367
+ * @throws ManifestMCPError if module is not found
368
+ */
369
+ export function getQueryHandler(module: string): QueryHandler {
370
+ const moduleInfo = QUERY_MODULES[module];
371
+ if (!moduleInfo) {
372
+ throw new ManifestMCPError(
373
+ ManifestMCPErrorCode.UNKNOWN_MODULE,
374
+ `Unknown query module: ${module}`,
375
+ { availableModules: Object.keys(QUERY_MODULES) }
376
+ );
377
+ }
378
+ return moduleInfo.handler;
379
+ }
380
+
381
+ /**
382
+ * Get the handler function for a transaction module
383
+ * @throws ManifestMCPError if module is not found
384
+ */
385
+ export function getTxHandler(module: string): TxHandler {
386
+ const moduleInfo = TX_MODULES[module];
387
+ if (!moduleInfo) {
388
+ throw new ManifestMCPError(
389
+ ManifestMCPErrorCode.UNKNOWN_MODULE,
390
+ `Unknown tx module: ${module}`,
391
+ { availableModules: Object.keys(TX_MODULES) }
392
+ );
393
+ }
394
+ return moduleInfo.handler;
395
+ }
@@ -1,32 +1,50 @@
1
1
  import { ManifestQueryClient } from '../client.js';
2
- import { ManifestMCPError, ManifestMCPErrorCode } from '../types.js';
3
- import { defaultPagination } from './utils.js';
2
+ import {
3
+ ManifestMCPErrorCode,
4
+ AuthAccountResult, AuthAccountsResult, AuthParamsResult, ModuleAccountsResult,
5
+ AddressBytesToStringResult, AddressStringToBytesResult, Bech32PrefixResult, AccountInfoResult
6
+ } from '../types.js';
7
+ import { requireArgs, extractPaginationArgs } from './utils.js';
8
+ import { parseHexBytes, bytesToHex } from '../transactions/utils.js';
9
+ import { throwUnsupportedSubcommand } from '../modules.js';
10
+
11
+ /** Maximum address bytes length (256 bytes, more than enough for any address) */
12
+ const MAX_ADDRESS_BYTES = 256;
13
+
14
+ /** Auth query result union type */
15
+ type AuthQueryResult =
16
+ | AuthAccountResult
17
+ | AuthAccountsResult
18
+ | AuthParamsResult
19
+ | ModuleAccountsResult
20
+ | AddressBytesToStringResult
21
+ | AddressStringToBytesResult
22
+ | Bech32PrefixResult
23
+ | AccountInfoResult;
4
24
 
5
25
  /**
6
26
  * Route auth query to manifestjs query client
27
+ *
28
+ * Paginated queries support --limit flag (default: 100, max: 1000)
7
29
  */
8
30
  export async function routeAuthQuery(
9
31
  queryClient: ManifestQueryClient,
10
32
  subcommand: string,
11
33
  args: string[]
12
- ): Promise<Record<string, unknown>> {
34
+ ): Promise<AuthQueryResult> {
13
35
  const auth = queryClient.cosmos.auth.v1beta1;
14
36
 
15
37
  switch (subcommand) {
16
38
  case 'account': {
17
- if (args.length < 1) {
18
- throw new ManifestMCPError(
19
- ManifestMCPErrorCode.QUERY_FAILED,
20
- 'account requires address argument'
21
- );
22
- }
39
+ requireArgs(args, 1, ['address'], 'auth account');
23
40
  const [address] = args;
24
41
  const result = await auth.account({ address });
25
42
  return { account: result.account };
26
43
  }
27
44
 
28
45
  case 'accounts': {
29
- const result = await auth.accounts({ pagination: defaultPagination });
46
+ const { pagination } = extractPaginationArgs(args, 'auth accounts');
47
+ const result = await auth.accounts({ pagination });
30
48
  return { accounts: result.accounts, pagination: result.pagination };
31
49
  }
32
50
 
@@ -41,60 +59,24 @@ export async function routeAuthQuery(
41
59
  }
42
60
 
43
61
  case 'module-account-by-name': {
44
- if (args.length < 1) {
45
- throw new ManifestMCPError(
46
- ManifestMCPErrorCode.QUERY_FAILED,
47
- 'module-account-by-name requires name argument'
48
- );
49
- }
62
+ requireArgs(args, 1, ['name'], 'auth module-account-by-name');
50
63
  const [name] = args;
51
64
  const result = await auth.moduleAccountByName({ name });
52
65
  return { account: result.account };
53
66
  }
54
67
 
55
68
  case 'address-bytes-to-string': {
56
- if (args.length < 1) {
57
- throw new ManifestMCPError(
58
- ManifestMCPErrorCode.QUERY_FAILED,
59
- 'address-bytes-to-string requires address-bytes argument'
60
- );
61
- }
62
- const hexString = args[0];
63
- // Validate hex format: must be valid hex characters with even length
64
- if (!/^[0-9a-fA-F]*$/.test(hexString)) {
65
- throw new ManifestMCPError(
66
- ManifestMCPErrorCode.QUERY_FAILED,
67
- `Invalid hex string: "${hexString}". Must contain only hexadecimal characters (0-9, a-f, A-F)`
68
- );
69
- }
70
- if (hexString.length % 2 !== 0) {
71
- throw new ManifestMCPError(
72
- ManifestMCPErrorCode.QUERY_FAILED,
73
- `Invalid hex string length: ${hexString.length}. Must have an even number of characters`
74
- );
75
- }
76
- // Limit size to prevent DoS (256 bytes = 512 hex chars, more than enough for any address)
77
- if (hexString.length > 512) {
78
- throw new ManifestMCPError(
79
- ManifestMCPErrorCode.QUERY_FAILED,
80
- `Hex string too long: ${hexString.length} characters. Maximum allowed: 512`
81
- );
82
- }
83
- const addressBytes = new Uint8Array(Buffer.from(hexString, 'hex'));
69
+ requireArgs(args, 1, ['address-bytes'], 'auth address-bytes-to-string');
70
+ const addressBytes = parseHexBytes(args[0], 'address-bytes', MAX_ADDRESS_BYTES, ManifestMCPErrorCode.QUERY_FAILED);
84
71
  const result = await auth.addressBytesToString({ addressBytes });
85
72
  return { addressString: result.addressString };
86
73
  }
87
74
 
88
75
  case 'address-string-to-bytes': {
89
- if (args.length < 1) {
90
- throw new ManifestMCPError(
91
- ManifestMCPErrorCode.QUERY_FAILED,
92
- 'address-string-to-bytes requires address-string argument'
93
- );
94
- }
76
+ requireArgs(args, 1, ['address-string'], 'auth address-string-to-bytes');
95
77
  const [addressString] = args;
96
78
  const result = await auth.addressStringToBytes({ addressString });
97
- return { addressBytes: Buffer.from(result.addressBytes).toString('hex') };
79
+ return { addressBytes: bytesToHex(result.addressBytes) };
98
80
  }
99
81
 
100
82
  case 'bech32-prefix': {
@@ -103,34 +85,13 @@ export async function routeAuthQuery(
103
85
  }
104
86
 
105
87
  case 'account-info': {
106
- if (args.length < 1) {
107
- throw new ManifestMCPError(
108
- ManifestMCPErrorCode.QUERY_FAILED,
109
- 'account-info requires address argument'
110
- );
111
- }
88
+ requireArgs(args, 1, ['address'], 'auth account-info');
112
89
  const [address] = args;
113
90
  const result = await auth.accountInfo({ address });
114
91
  return { info: result.info };
115
92
  }
116
93
 
117
94
  default:
118
- throw new ManifestMCPError(
119
- ManifestMCPErrorCode.UNSUPPORTED_QUERY,
120
- `Unsupported auth query subcommand: ${subcommand}`,
121
- {
122
- availableSubcommands: [
123
- 'account',
124
- 'accounts',
125
- 'params',
126
- 'module-accounts',
127
- 'module-account-by-name',
128
- 'address-bytes-to-string',
129
- 'address-string-to-bytes',
130
- 'bech32-prefix',
131
- 'account-info',
132
- ],
133
- }
134
- );
95
+ throwUnsupportedSubcommand('query', 'auth', subcommand);
135
96
  }
136
97
  }
@@ -1,67 +1,67 @@
1
1
  import { ManifestQueryClient } from '../client.js';
2
- import { ManifestMCPError, ManifestMCPErrorCode } from '../types.js';
3
- import { defaultPagination } from './utils.js';
2
+ import {
3
+ BalanceResult, BalancesResult, TotalSupplyResult, SupplyOfResult,
4
+ BankParamsResult, DenomMetadataResult, DenomsMetadataResult, SendEnabledResult
5
+ } from '../types.js';
6
+ import { requireArgs, extractPaginationArgs } from './utils.js';
7
+ import { throwUnsupportedSubcommand } from '../modules.js';
8
+
9
+ /** Bank query result union type */
10
+ type BankQueryResult =
11
+ | BalanceResult
12
+ | BalancesResult
13
+ | TotalSupplyResult
14
+ | SupplyOfResult
15
+ | BankParamsResult
16
+ | DenomMetadataResult
17
+ | DenomsMetadataResult
18
+ | SendEnabledResult;
4
19
 
5
20
  /**
6
21
  * Route bank query to manifestjs query client
22
+ *
23
+ * Paginated queries support --limit flag (default: 100, max: 1000)
7
24
  */
8
25
  export async function routeBankQuery(
9
26
  queryClient: ManifestQueryClient,
10
27
  subcommand: string,
11
28
  args: string[]
12
- ): Promise<Record<string, unknown>> {
29
+ ): Promise<BankQueryResult> {
13
30
  const bank = queryClient.cosmos.bank.v1beta1;
14
31
 
15
32
  switch (subcommand) {
16
33
  case 'balance': {
17
- if (args.length < 2) {
18
- throw new ManifestMCPError(
19
- ManifestMCPErrorCode.QUERY_FAILED,
20
- 'balance requires address and denom arguments'
21
- );
22
- }
34
+ requireArgs(args, 2, ['address', 'denom'], 'bank balance');
23
35
  const [address, denom] = args;
24
36
  const result = await bank.balance({ address, denom });
25
37
  return { balance: result.balance };
26
38
  }
27
39
 
28
40
  case 'balances': {
29
- if (args.length < 1) {
30
- throw new ManifestMCPError(
31
- ManifestMCPErrorCode.QUERY_FAILED,
32
- 'balances requires address argument'
33
- );
34
- }
35
- const [address] = args;
36
- const result = await bank.allBalances({ address, resolveDenom: false, pagination: defaultPagination });
41
+ const { pagination, remainingArgs } = extractPaginationArgs(args, 'bank balances');
42
+ requireArgs(remainingArgs, 1, ['address'], 'bank balances');
43
+ const [address] = remainingArgs;
44
+ const result = await bank.allBalances({ address, resolveDenom: false, pagination });
37
45
  return { balances: result.balances, pagination: result.pagination };
38
46
  }
39
47
 
40
48
  case 'spendable-balances': {
41
- if (args.length < 1) {
42
- throw new ManifestMCPError(
43
- ManifestMCPErrorCode.QUERY_FAILED,
44
- 'spendable-balances requires address argument'
45
- );
46
- }
47
- const [address] = args;
48
- const result = await bank.spendableBalances({ address, pagination: defaultPagination });
49
+ const { pagination, remainingArgs } = extractPaginationArgs(args, 'bank spendable-balances');
50
+ requireArgs(remainingArgs, 1, ['address'], 'bank spendable-balances');
51
+ const [address] = remainingArgs;
52
+ const result = await bank.spendableBalances({ address, pagination });
49
53
  return { balances: result.balances, pagination: result.pagination };
50
54
  }
51
55
 
52
56
  case 'total-supply':
53
57
  case 'total': {
54
- const result = await bank.totalSupply({ pagination: defaultPagination });
58
+ const { pagination } = extractPaginationArgs(args, 'bank total-supply');
59
+ const result = await bank.totalSupply({ pagination });
55
60
  return { supply: result.supply, pagination: result.pagination };
56
61
  }
57
62
 
58
63
  case 'supply-of': {
59
- if (args.length < 1) {
60
- throw new ManifestMCPError(
61
- ManifestMCPErrorCode.QUERY_FAILED,
62
- 'supply-of requires denom argument'
63
- );
64
- }
64
+ requireArgs(args, 1, ['denom'], 'bank supply-of');
65
65
  const [denom] = args;
66
66
  const result = await bank.supplyOf({ denom });
67
67
  return { amount: result.amount };
@@ -73,45 +73,27 @@ export async function routeBankQuery(
73
73
  }
74
74
 
75
75
  case 'denom-metadata': {
76
- if (args.length < 1) {
77
- throw new ManifestMCPError(
78
- ManifestMCPErrorCode.QUERY_FAILED,
79
- 'denom-metadata requires denom argument'
80
- );
81
- }
76
+ requireArgs(args, 1, ['denom'], 'bank denom-metadata');
82
77
  const [denom] = args;
83
78
  const result = await bank.denomMetadata({ denom });
84
79
  return { metadata: result.metadata };
85
80
  }
86
81
 
87
82
  case 'denoms-metadata': {
88
- const result = await bank.denomsMetadata({ pagination: defaultPagination });
83
+ const { pagination } = extractPaginationArgs(args, 'bank denoms-metadata');
84
+ const result = await bank.denomsMetadata({ pagination });
89
85
  return { metadatas: result.metadatas, pagination: result.pagination };
90
86
  }
91
87
 
92
88
  case 'send-enabled': {
93
- const denoms = args.length > 0 ? args : [];
94
- const result = await bank.sendEnabled({ denoms, pagination: defaultPagination });
89
+ const { pagination, remainingArgs } = extractPaginationArgs(args, 'bank send-enabled');
90
+ // Optional: denoms can be empty to query all
91
+ const denoms = remainingArgs.length > 0 ? remainingArgs : [];
92
+ const result = await bank.sendEnabled({ denoms, pagination });
95
93
  return { sendEnabled: result.sendEnabled, pagination: result.pagination };
96
94
  }
97
95
 
98
96
  default:
99
- throw new ManifestMCPError(
100
- ManifestMCPErrorCode.UNSUPPORTED_QUERY,
101
- `Unsupported bank query subcommand: ${subcommand}`,
102
- {
103
- availableSubcommands: [
104
- 'balance',
105
- 'balances',
106
- 'spendable-balances',
107
- 'total-supply',
108
- 'supply-of',
109
- 'params',
110
- 'denom-metadata',
111
- 'denoms-metadata',
112
- 'send-enabled',
113
- ],
114
- }
115
- );
97
+ throwUnsupportedSubcommand('query', 'bank', subcommand);
116
98
  }
117
99
  }