@manifest-network/manifest-mcp-browser 0.1.7 → 0.1.9

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 (89) hide show
  1. package/README.md +5 -2
  2. package/dist/client.d.ts +5 -2
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +8 -2
  5. package/dist/client.js.map +1 -1
  6. package/dist/config.d.ts.map +1 -1
  7. package/dist/config.js +0 -10
  8. package/dist/config.js.map +1 -1
  9. package/dist/index.d.ts +0 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +4 -8
  12. package/dist/index.js.map +1 -1
  13. package/dist/queries/index.d.ts +1 -0
  14. package/dist/queries/index.d.ts.map +1 -1
  15. package/dist/queries/index.js +1 -0
  16. package/dist/queries/index.js.map +1 -1
  17. package/dist/transactions/bank.d.ts.map +1 -1
  18. package/dist/transactions/bank.js +7 -5
  19. package/dist/transactions/bank.js.map +1 -1
  20. package/dist/transactions/gov.d.ts.map +1 -1
  21. package/dist/transactions/gov.js +7 -5
  22. package/dist/transactions/gov.js.map +1 -1
  23. package/dist/transactions/index.d.ts +1 -0
  24. package/dist/transactions/index.d.ts.map +1 -1
  25. package/dist/transactions/index.js +1 -0
  26. package/dist/transactions/index.js.map +1 -1
  27. package/dist/transactions/utils.d.ts.map +1 -1
  28. package/dist/transactions/utils.js +5 -6
  29. package/dist/transactions/utils.js.map +1 -1
  30. package/dist/types.d.ts +2 -4
  31. package/dist/types.d.ts.map +1 -1
  32. package/dist/types.js.map +1 -1
  33. package/dist/version.d.ts +2 -0
  34. package/dist/version.d.ts.map +1 -0
  35. package/dist/version.js +2 -0
  36. package/dist/version.js.map +1 -0
  37. package/package.json +13 -3
  38. package/.github/workflows/ci.yml +0 -37
  39. package/.github/workflows/publish.yml +0 -53
  40. package/CLAUDE.md +0 -113
  41. package/dist/config.test.d.ts +0 -2
  42. package/dist/config.test.d.ts.map +0 -1
  43. package/dist/config.test.js +0 -251
  44. package/dist/config.test.js.map +0 -1
  45. package/dist/modules.test.d.ts +0 -2
  46. package/dist/modules.test.d.ts.map +0 -1
  47. package/dist/modules.test.js +0 -161
  48. package/dist/modules.test.js.map +0 -1
  49. package/dist/queries/utils.test.d.ts +0 -2
  50. package/dist/queries/utils.test.d.ts.map +0 -1
  51. package/dist/queries/utils.test.js +0 -117
  52. package/dist/queries/utils.test.js.map +0 -1
  53. package/dist/transactions/utils.test.d.ts +0 -2
  54. package/dist/transactions/utils.test.d.ts.map +0 -1
  55. package/dist/transactions/utils.test.js +0 -567
  56. package/dist/transactions/utils.test.js.map +0 -1
  57. package/src/client.ts +0 -288
  58. package/src/config.test.ts +0 -299
  59. package/src/config.ts +0 -174
  60. package/src/cosmos.ts +0 -106
  61. package/src/index.ts +0 -478
  62. package/src/modules.test.ts +0 -191
  63. package/src/modules.ts +0 -470
  64. package/src/queries/auth.ts +0 -97
  65. package/src/queries/bank.ts +0 -99
  66. package/src/queries/billing.ts +0 -124
  67. package/src/queries/distribution.ts +0 -114
  68. package/src/queries/gov.ts +0 -104
  69. package/src/queries/group.ts +0 -146
  70. package/src/queries/index.ts +0 -17
  71. package/src/queries/sku.ts +0 -85
  72. package/src/queries/staking.ts +0 -154
  73. package/src/queries/utils.test.ts +0 -156
  74. package/src/queries/utils.ts +0 -121
  75. package/src/transactions/bank.ts +0 -86
  76. package/src/transactions/billing.ts +0 -286
  77. package/src/transactions/distribution.ts +0 -76
  78. package/src/transactions/gov.ts +0 -164
  79. package/src/transactions/group.ts +0 -458
  80. package/src/transactions/index.ts +0 -8
  81. package/src/transactions/manifest.ts +0 -67
  82. package/src/transactions/sku.ts +0 -232
  83. package/src/transactions/staking.ts +0 -85
  84. package/src/transactions/utils.test.ts +0 -626
  85. package/src/transactions/utils.ts +0 -417
  86. package/src/types.ts +0 -548
  87. package/src/wallet/index.ts +0 -2
  88. package/src/wallet/mnemonic.ts +0 -146
  89. package/tsconfig.json +0 -23
@@ -1,154 +0,0 @@
1
- import { ManifestQueryClient } from '../client.js';
2
- import {
3
- DelegationResult, DelegationsResult, UnbondingDelegationResult, UnbondingDelegationsResult,
4
- RedelegationsResult, ValidatorResult, ValidatorsResult, StakingPoolResult,
5
- StakingParamsResult, HistoricalInfoResult
6
- } from '../types.js';
7
- import { parseBigInt, requireArgs, extractPaginationArgs } from './utils.js';
8
- import { throwUnsupportedSubcommand } from '../modules.js';
9
-
10
- /** Staking query result union type */
11
- type StakingQueryResult =
12
- | DelegationResult
13
- | DelegationsResult
14
- | UnbondingDelegationResult
15
- | UnbondingDelegationsResult
16
- | RedelegationsResult
17
- | ValidatorResult
18
- | ValidatorsResult
19
- | StakingPoolResult
20
- | StakingParamsResult
21
- | HistoricalInfoResult;
22
-
23
- /**
24
- * Route staking query to manifestjs query client
25
- *
26
- * Paginated queries support --limit flag (default: 100, max: 1000)
27
- */
28
- export async function routeStakingQuery(
29
- queryClient: ManifestQueryClient,
30
- subcommand: string,
31
- args: string[]
32
- ): Promise<StakingQueryResult> {
33
- const staking = queryClient.cosmos.staking.v1beta1;
34
-
35
- switch (subcommand) {
36
- case 'delegation': {
37
- requireArgs(args, 2, ['delegator-address', 'validator-address'], 'staking delegation');
38
- const [delegatorAddr, validatorAddr] = args;
39
- const result = await staking.delegation({
40
- delegatorAddr,
41
- validatorAddr,
42
- });
43
- return { delegationResponse: result.delegationResponse };
44
- }
45
-
46
- case 'delegations': {
47
- const { pagination, remainingArgs } = extractPaginationArgs(args, 'staking delegations');
48
- requireArgs(remainingArgs, 1, ['delegator-address'], 'staking delegations');
49
- const [delegatorAddr] = remainingArgs;
50
- const result = await staking.delegatorDelegations({ delegatorAddr, pagination });
51
- return {
52
- delegationResponses: result.delegationResponses,
53
- pagination: result.pagination,
54
- };
55
- }
56
-
57
- case 'unbonding-delegation': {
58
- requireArgs(args, 2, ['delegator-address', 'validator-address'], 'staking unbonding-delegation');
59
- const [delegatorAddr, validatorAddr] = args;
60
- const result = await staking.unbondingDelegation({
61
- delegatorAddr,
62
- validatorAddr,
63
- });
64
- return { unbond: result.unbond };
65
- }
66
-
67
- case 'unbonding-delegations': {
68
- const { pagination, remainingArgs } = extractPaginationArgs(args, 'staking unbonding-delegations');
69
- requireArgs(remainingArgs, 1, ['delegator-address'], 'staking unbonding-delegations');
70
- const [delegatorAddr] = remainingArgs;
71
- const result = await staking.delegatorUnbondingDelegations({ delegatorAddr, pagination });
72
- return {
73
- unbondingResponses: result.unbondingResponses,
74
- pagination: result.pagination,
75
- };
76
- }
77
-
78
- case 'redelegations': {
79
- const { pagination, remainingArgs } = extractPaginationArgs(args, 'staking redelegations');
80
- requireArgs(remainingArgs, 1, ['delegator-address'], 'staking redelegations');
81
- const [delegatorAddr] = remainingArgs;
82
- // Optional: src and dst validator addresses for filtering
83
- const srcValidatorAddr = remainingArgs[1] || '';
84
- const dstValidatorAddr = remainingArgs[2] || '';
85
- const result = await staking.redelegations({
86
- delegatorAddr,
87
- srcValidatorAddr,
88
- dstValidatorAddr,
89
- pagination,
90
- });
91
- return {
92
- redelegationResponses: result.redelegationResponses,
93
- pagination: result.pagination,
94
- };
95
- }
96
-
97
- case 'validator': {
98
- requireArgs(args, 1, ['validator-address'], 'staking validator');
99
- const [validatorAddr] = args;
100
- const result = await staking.validator({ validatorAddr });
101
- return { validator: result.validator };
102
- }
103
-
104
- case 'validators': {
105
- const { pagination, remainingArgs } = extractPaginationArgs(args, 'staking validators');
106
- // Optional: status filter
107
- const status = remainingArgs[0] || '';
108
- const result = await staking.validators({ status, pagination });
109
- return { validators: result.validators, pagination: result.pagination };
110
- }
111
-
112
- case 'validator-delegations': {
113
- const { pagination, remainingArgs } = extractPaginationArgs(args, 'staking validator-delegations');
114
- requireArgs(remainingArgs, 1, ['validator-address'], 'staking validator-delegations');
115
- const [validatorAddr] = remainingArgs;
116
- const result = await staking.validatorDelegations({ validatorAddr, pagination });
117
- return {
118
- delegationResponses: result.delegationResponses,
119
- pagination: result.pagination,
120
- };
121
- }
122
-
123
- case 'validator-unbonding-delegations': {
124
- const { pagination, remainingArgs } = extractPaginationArgs(args, 'staking validator-unbonding-delegations');
125
- requireArgs(remainingArgs, 1, ['validator-address'], 'staking validator-unbonding-delegations');
126
- const [validatorAddr] = remainingArgs;
127
- const result = await staking.validatorUnbondingDelegations({ validatorAddr, pagination });
128
- return {
129
- unbondingResponses: result.unbondingResponses,
130
- pagination: result.pagination,
131
- };
132
- }
133
-
134
- case 'pool': {
135
- const result = await staking.pool({});
136
- return { pool: result.pool };
137
- }
138
-
139
- case 'params': {
140
- const result = await staking.params({});
141
- return { params: result.params };
142
- }
143
-
144
- case 'historical-info': {
145
- requireArgs(args, 1, ['height'], 'staking historical-info');
146
- const height = parseBigInt(args[0], 'height');
147
- const result = await staking.historicalInfo({ height });
148
- return { hist: result.hist };
149
- }
150
-
151
- default:
152
- throwUnsupportedSubcommand('query', 'staking', subcommand);
153
- }
154
- }
@@ -1,156 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import {
3
- parseBigInt,
4
- parseInteger,
5
- createPagination,
6
- extractPaginationArgs,
7
- DEFAULT_PAGE_LIMIT,
8
- MAX_PAGE_LIMIT,
9
- } from './utils.js';
10
- import { ManifestMCPError, ManifestMCPErrorCode } from '../types.js';
11
-
12
- describe('parseBigInt', () => {
13
- it('should parse valid integer strings', () => {
14
- expect(parseBigInt('0', 'height')).toBe(BigInt(0));
15
- expect(parseBigInt('123', 'height')).toBe(BigInt(123));
16
- expect(parseBigInt('9999999999999999999', 'height')).toBe(BigInt('9999999999999999999'));
17
- });
18
-
19
- it('should throw ManifestMCPError for invalid integers', () => {
20
- expect(() => parseBigInt('abc', 'height')).toThrow(ManifestMCPError);
21
- expect(() => parseBigInt('12.34', 'height')).toThrow(ManifestMCPError);
22
- });
23
-
24
- it('should throw ManifestMCPError for empty string', () => {
25
- // Empty string should be rejected for security (prevents accidental 0 values)
26
- expect(() => parseBigInt('', 'height')).toThrow(ManifestMCPError);
27
- expect(() => parseBigInt(' ', 'height')).toThrow(ManifestMCPError);
28
- });
29
-
30
- it('should have correct error code', () => {
31
- try {
32
- parseBigInt('invalid', 'height');
33
- } catch (error) {
34
- expect(error).toBeInstanceOf(ManifestMCPError);
35
- expect((error as ManifestMCPError).code).toBe(ManifestMCPErrorCode.QUERY_FAILED);
36
- }
37
- });
38
-
39
- it('should include field name in error message', () => {
40
- try {
41
- parseBigInt('invalid', 'block-height');
42
- } catch (error) {
43
- expect((error as ManifestMCPError).message).toContain('block-height');
44
- }
45
- });
46
- });
47
-
48
- describe('parseInteger', () => {
49
- it('should parse valid integer strings', () => {
50
- expect(parseInteger('0', 'status')).toBe(0);
51
- expect(parseInteger('123', 'status')).toBe(123);
52
- expect(parseInteger('-5', 'status')).toBe(-5);
53
- });
54
-
55
- it('should throw ManifestMCPError for invalid integers', () => {
56
- expect(() => parseInteger('', 'status')).toThrow(ManifestMCPError);
57
- expect(() => parseInteger('abc', 'status')).toThrow(ManifestMCPError);
58
- });
59
-
60
- it('should have correct error code', () => {
61
- try {
62
- parseInteger('invalid', 'status');
63
- } catch (error) {
64
- expect(error).toBeInstanceOf(ManifestMCPError);
65
- expect((error as ManifestMCPError).code).toBe(ManifestMCPErrorCode.QUERY_FAILED);
66
- }
67
- });
68
- });
69
-
70
- describe('createPagination', () => {
71
- it('should use default limit when none provided', () => {
72
- const pagination = createPagination();
73
- expect(pagination.limit).toBe(DEFAULT_PAGE_LIMIT);
74
- expect(pagination.offset).toBe(BigInt(0));
75
- expect(pagination.countTotal).toBe(false);
76
- expect(pagination.reverse).toBe(false);
77
- expect(pagination.key).toEqual(new Uint8Array());
78
- });
79
-
80
- it('should use provided limit', () => {
81
- const pagination = createPagination(BigInt(50));
82
- expect(pagination.limit).toBe(BigInt(50));
83
- });
84
-
85
- it('should clamp limit to minimum of 1', () => {
86
- const pagination = createPagination(BigInt(0));
87
- expect(pagination.limit).toBe(BigInt(1));
88
-
89
- const paginationNegative = createPagination(BigInt(-10));
90
- expect(paginationNegative.limit).toBe(BigInt(1));
91
- });
92
-
93
- it('should clamp limit to maximum', () => {
94
- const pagination = createPagination(BigInt(9999));
95
- expect(pagination.limit).toBe(MAX_PAGE_LIMIT);
96
- });
97
- });
98
-
99
- describe('extractPaginationArgs', () => {
100
- it('should return default pagination when no --limit flag', () => {
101
- const { pagination, remainingArgs } = extractPaginationArgs(['arg1', 'arg2'], 'test');
102
- expect(pagination.limit).toBe(DEFAULT_PAGE_LIMIT);
103
- expect(remainingArgs).toEqual(['arg1', 'arg2']);
104
- });
105
-
106
- it('should extract --limit flag and value', () => {
107
- const { pagination, remainingArgs } = extractPaginationArgs(
108
- ['arg1', '--limit', '50', 'arg2'],
109
- 'test'
110
- );
111
- expect(pagination.limit).toBe(BigInt(50));
112
- expect(remainingArgs).toEqual(['arg1', 'arg2']);
113
- });
114
-
115
- it('should handle --limit at end of args', () => {
116
- const { pagination, remainingArgs } = extractPaginationArgs(
117
- ['arg1', '--limit', '25'],
118
- 'test'
119
- );
120
- expect(pagination.limit).toBe(BigInt(25));
121
- expect(remainingArgs).toEqual(['arg1']);
122
- });
123
-
124
- it('should handle --limit at start of args', () => {
125
- const { pagination, remainingArgs } = extractPaginationArgs(
126
- ['--limit', '75', 'arg1'],
127
- 'test'
128
- );
129
- expect(pagination.limit).toBe(BigInt(75));
130
- expect(remainingArgs).toEqual(['arg1']);
131
- });
132
-
133
- it('should throw for invalid limit value', () => {
134
- expect(() =>
135
- extractPaginationArgs(['--limit', 'abc'], 'test')
136
- ).toThrow(ManifestMCPError);
137
- });
138
-
139
- it('should throw for limit below minimum', () => {
140
- expect(() =>
141
- extractPaginationArgs(['--limit', '0'], 'test')
142
- ).toThrow(ManifestMCPError);
143
- });
144
-
145
- it('should throw for limit above maximum', () => {
146
- expect(() =>
147
- extractPaginationArgs(['--limit', '9999'], 'test')
148
- ).toThrow(ManifestMCPError);
149
- });
150
-
151
- it('should handle empty args array', () => {
152
- const { pagination, remainingArgs } = extractPaginationArgs([], 'test');
153
- expect(pagination.limit).toBe(DEFAULT_PAGE_LIMIT);
154
- expect(remainingArgs).toEqual([]);
155
- });
156
- });
@@ -1,121 +0,0 @@
1
- import { ManifestMCPError, ManifestMCPErrorCode } from '../types.js';
2
- import { parseBigIntWithCode, requireArgs as requireArgsBase, extractFlag, filterConsumedArgs, validateAddress, extractBooleanFlag } from '../transactions/utils.js';
3
-
4
- export { validateAddress, extractBooleanFlag };
5
- export type { ExtractedBooleanFlag } from '../transactions/utils.js';
6
-
7
- /** Default page size limit for paginated queries to prevent resource exhaustion */
8
- export const DEFAULT_PAGE_LIMIT = BigInt(100);
9
-
10
- /** Maximum page size limit to prevent DoS */
11
- export const MAX_PAGE_LIMIT = BigInt(1000);
12
-
13
- /**
14
- * Cosmos SDK pagination configuration
15
- */
16
- export interface PaginationConfig {
17
- readonly key: Uint8Array;
18
- readonly offset: bigint;
19
- readonly limit: bigint;
20
- readonly countTotal: boolean;
21
- readonly reverse: boolean;
22
- }
23
-
24
- /**
25
- * Create pagination configuration with optional custom limit.
26
- * Validates that limit is within acceptable bounds.
27
- *
28
- * @param limit - Optional custom limit (defaults to DEFAULT_PAGE_LIMIT)
29
- * @returns Cosmos SDK pagination object
30
- */
31
- export function createPagination(limit?: bigint): PaginationConfig {
32
- let effectiveLimit = limit ?? DEFAULT_PAGE_LIMIT;
33
-
34
- // Clamp to valid range
35
- if (effectiveLimit < BigInt(1)) {
36
- effectiveLimit = BigInt(1);
37
- } else if (effectiveLimit > MAX_PAGE_LIMIT) {
38
- effectiveLimit = MAX_PAGE_LIMIT;
39
- }
40
-
41
- return {
42
- key: new Uint8Array(),
43
- offset: BigInt(0),
44
- limit: effectiveLimit,
45
- countTotal: false,
46
- reverse: false,
47
- };
48
- }
49
-
50
- /**
51
- * Default pagination configuration for queries (for backwards compatibility)
52
- * @deprecated Use createPagination() instead for configurable limits
53
- */
54
- export const defaultPagination = createPagination();
55
-
56
- /**
57
- * Extract --limit flag from args and return pagination config with remaining args.
58
- * Use this helper for paginated queries.
59
- *
60
- * @param args - The arguments array
61
- * @param context - Context for error messages
62
- * @returns Object with pagination config and filtered args
63
- */
64
- export function extractPaginationArgs(
65
- args: string[],
66
- context: string
67
- ): { pagination: PaginationConfig; remainingArgs: string[] } {
68
- const { value: limitStr, consumedIndices } = extractFlag(args, '--limit', context);
69
- const remainingArgs = filterConsumedArgs(args, consumedIndices);
70
-
71
- let pagination: PaginationConfig;
72
- if (limitStr) {
73
- const limit = parseBigInt(limitStr, 'limit');
74
- if (limit < BigInt(1) || limit > MAX_PAGE_LIMIT) {
75
- throw new ManifestMCPError(
76
- ManifestMCPErrorCode.QUERY_FAILED,
77
- `Invalid limit: ${limit}. Must be between 1 and ${MAX_PAGE_LIMIT}.`
78
- );
79
- }
80
- pagination = createPagination(limit);
81
- } else {
82
- pagination = createPagination();
83
- }
84
-
85
- return { pagination, remainingArgs };
86
- }
87
-
88
- /**
89
- * Safely parse a string to BigInt with proper error handling (for queries)
90
- */
91
- export function parseBigInt(value: string, fieldName: string): bigint {
92
- return parseBigIntWithCode(value, fieldName, ManifestMCPErrorCode.QUERY_FAILED);
93
- }
94
-
95
- /**
96
- * Safely parse a string to integer with proper error handling.
97
- * Named parseInteger to avoid shadowing global parseInt.
98
- */
99
- export function parseInteger(value: string, fieldName: string): number {
100
- const parsed = Number.parseInt(value, 10);
101
- if (Number.isNaN(parsed)) {
102
- throw new ManifestMCPError(
103
- ManifestMCPErrorCode.QUERY_FAILED,
104
- `Invalid ${fieldName}: "${value}". Expected a valid integer.`
105
- );
106
- }
107
- return parsed;
108
- }
109
-
110
- /**
111
- * Validate that required arguments are present (for queries).
112
- * Uses QUERY_FAILED error code by default.
113
- */
114
- export function requireArgs(
115
- args: string[],
116
- minCount: number,
117
- expectedNames: string[],
118
- context: string
119
- ): void {
120
- requireArgsBase(args, minCount, expectedNames, context, ManifestMCPErrorCode.QUERY_FAILED);
121
- }
@@ -1,86 +0,0 @@
1
- import { SigningStargateClient } from '@cosmjs/stargate';
2
- import { cosmos } from '@manifest-network/manifestjs';
3
- import { CosmosTxResult } from '../types.js';
4
- import { throwUnsupportedSubcommand } from '../modules.js';
5
- import { parseAmount, buildTxResult, validateAddress, validateMemo, validateArgsLength, extractFlag, parseColonPair, requireArgs } from './utils.js';
6
-
7
- const { MsgSend, MsgMultiSend } = cosmos.bank.v1beta1;
8
-
9
- /**
10
- * Route bank transaction to appropriate handler
11
- */
12
- export async function routeBankTransaction(
13
- client: SigningStargateClient,
14
- senderAddress: string,
15
- subcommand: string,
16
- args: string[],
17
- waitForConfirmation: boolean
18
- ): Promise<CosmosTxResult> {
19
- validateArgsLength(args, 'bank transaction');
20
-
21
- switch (subcommand) {
22
- case 'send': {
23
- requireArgs(args, 2, ['recipient-address', 'amount'], 'bank send');
24
- const [recipientAddress, amountStr] = args;
25
- validateAddress(recipientAddress, 'recipient address');
26
- const { amount, denom } = parseAmount(amountStr);
27
-
28
- // Extract optional memo from args
29
- const { value: memo = '' } = extractFlag(args, '--memo', 'bank send');
30
- if (memo) {
31
- validateMemo(memo);
32
- }
33
-
34
- const msg = {
35
- typeUrl: '/cosmos.bank.v1beta1.MsgSend',
36
- value: MsgSend.fromPartial({
37
- fromAddress: senderAddress,
38
- toAddress: recipientAddress,
39
- amount: [{ denom, amount }],
40
- }),
41
- };
42
-
43
- const result = await client.signAndBroadcast(senderAddress, [msg], 'auto', memo);
44
- return buildTxResult('bank', 'send', result, waitForConfirmation);
45
- }
46
-
47
- case 'multi-send': {
48
- requireArgs(args, 1, ['recipient:amount'], 'bank multi-send');
49
- // Parse format: multi-send recipient1:amount1 recipient2:amount2 ...
50
- const outputs = args.map((arg) => {
51
- const [address, amountStr] = parseColonPair(arg, 'address', 'amount', 'multi-send');
52
- validateAddress(address, 'recipient address');
53
- const { amount, denom } = parseAmount(amountStr);
54
- return { address, coins: [{ denom, amount }] };
55
- });
56
-
57
- // Calculate total input
58
- const totalByDenom = new Map<string, bigint>();
59
- for (const output of outputs) {
60
- for (const coin of output.coins) {
61
- const current = totalByDenom.get(coin.denom) || BigInt(0);
62
- totalByDenom.set(coin.denom, current + BigInt(coin.amount));
63
- }
64
- }
65
-
66
- const inputCoins = Array.from(totalByDenom.entries()).map(([denom, amount]) => ({
67
- denom,
68
- amount: amount.toString(),
69
- }));
70
-
71
- const msg = {
72
- typeUrl: '/cosmos.bank.v1beta1.MsgMultiSend',
73
- value: MsgMultiSend.fromPartial({
74
- inputs: [{ address: senderAddress, coins: inputCoins }],
75
- outputs,
76
- }),
77
- };
78
-
79
- const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
80
- return buildTxResult('bank', 'multi-send', result, waitForConfirmation);
81
- }
82
-
83
- default:
84
- throwUnsupportedSubcommand('tx', 'bank', subcommand);
85
- }
86
- }