@manifest-network/manifest-mcp-browser 0.1.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 (156) hide show
  1. package/.claude/settings.local.json +17 -0
  2. package/.github/workflows/ci.yml +37 -0
  3. package/.github/workflows/publish.yml +51 -0
  4. package/CLAUDE.md +104 -0
  5. package/LICENSE +21 -0
  6. package/README.md +298 -0
  7. package/dist/browser.d.ts.map +1 -0
  8. package/dist/browser.js.map +1 -0
  9. package/dist/client.d.ts +44 -0
  10. package/dist/client.d.ts.map +1 -0
  11. package/dist/client.js +131 -0
  12. package/dist/client.js.map +1 -0
  13. package/dist/config.d.ts +21 -0
  14. package/dist/config.d.ts.map +1 -0
  15. package/dist/config.js +98 -0
  16. package/dist/config.js.map +1 -0
  17. package/dist/config.test.d.ts +2 -0
  18. package/dist/config.test.d.ts.map +1 -0
  19. package/dist/config.test.js +123 -0
  20. package/dist/config.test.js.map +1 -0
  21. package/dist/cosmos.d.ts +11 -0
  22. package/dist/cosmos.d.ts.map +1 -0
  23. package/dist/cosmos.js +112 -0
  24. package/dist/cosmos.js.map +1 -0
  25. package/dist/index.d.ts +70 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +382 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/modules.d.ts +30 -0
  30. package/dist/modules.d.ts.map +1 -0
  31. package/dist/modules.js +221 -0
  32. package/dist/modules.js.map +1 -0
  33. package/dist/modules.test.d.ts +2 -0
  34. package/dist/modules.test.d.ts.map +1 -0
  35. package/dist/modules.test.js +100 -0
  36. package/dist/modules.test.js.map +1 -0
  37. package/dist/queries/auth.d.ts +6 -0
  38. package/dist/queries/auth.d.ts.map +1 -0
  39. package/dist/queries/auth.js +93 -0
  40. package/dist/queries/auth.js.map +1 -0
  41. package/dist/queries/bank.d.ts +6 -0
  42. package/dist/queries/bank.d.ts.map +1 -0
  43. package/dist/queries/bank.js +83 -0
  44. package/dist/queries/bank.js.map +1 -0
  45. package/dist/queries/billing.d.ts +6 -0
  46. package/dist/queries/billing.d.ts.map +1 -0
  47. package/dist/queries/billing.js +115 -0
  48. package/dist/queries/billing.js.map +1 -0
  49. package/dist/queries/distribution.d.ts +6 -0
  50. package/dist/queries/distribution.d.ts.map +1 -0
  51. package/dist/queries/distribution.js +102 -0
  52. package/dist/queries/distribution.js.map +1 -0
  53. package/dist/queries/gov.d.ts +6 -0
  54. package/dist/queries/gov.d.ts.map +1 -0
  55. package/dist/queries/gov.js +92 -0
  56. package/dist/queries/gov.js.map +1 -0
  57. package/dist/queries/index.d.ts +8 -0
  58. package/dist/queries/index.d.ts.map +1 -0
  59. package/dist/queries/index.js +8 -0
  60. package/dist/queries/index.js.map +1 -0
  61. package/dist/queries/manifest.d.ts +10 -0
  62. package/dist/queries/manifest.d.ts.map +1 -0
  63. package/dist/queries/manifest.js +14 -0
  64. package/dist/queries/manifest.js.map +1 -0
  65. package/dist/queries/staking.d.ts +6 -0
  66. package/dist/queries/staking.d.ts.map +1 -0
  67. package/dist/queries/staking.js +141 -0
  68. package/dist/queries/staking.js.map +1 -0
  69. package/dist/queries/utils.d.ts +22 -0
  70. package/dist/queries/utils.d.ts.map +1 -0
  71. package/dist/queries/utils.js +32 -0
  72. package/dist/queries/utils.js.map +1 -0
  73. package/dist/queries/utils.test.d.ts +2 -0
  74. package/dist/queries/utils.test.d.ts.map +1 -0
  75. package/dist/queries/utils.test.js +57 -0
  76. package/dist/queries/utils.test.js.map +1 -0
  77. package/dist/transactions/bank.d.ts +7 -0
  78. package/dist/transactions/bank.d.ts.map +1 -0
  79. package/dist/transactions/bank.js +76 -0
  80. package/dist/transactions/bank.js.map +1 -0
  81. package/dist/transactions/billing.d.ts +7 -0
  82. package/dist/transactions/billing.d.ts.map +1 -0
  83. package/dist/transactions/billing.js +108 -0
  84. package/dist/transactions/billing.js.map +1 -0
  85. package/dist/transactions/distribution.d.ts +7 -0
  86. package/dist/transactions/distribution.d.ts.map +1 -0
  87. package/dist/transactions/distribution.js +63 -0
  88. package/dist/transactions/distribution.js.map +1 -0
  89. package/dist/transactions/gov.d.ts +7 -0
  90. package/dist/transactions/gov.d.ts.map +1 -0
  91. package/dist/transactions/gov.js +132 -0
  92. package/dist/transactions/gov.js.map +1 -0
  93. package/dist/transactions/index.d.ts +8 -0
  94. package/dist/transactions/index.d.ts.map +1 -0
  95. package/dist/transactions/index.js +8 -0
  96. package/dist/transactions/index.js.map +1 -0
  97. package/dist/transactions/manifest.d.ts +7 -0
  98. package/dist/transactions/manifest.d.ts.map +1 -0
  99. package/dist/transactions/manifest.js +58 -0
  100. package/dist/transactions/manifest.js.map +1 -0
  101. package/dist/transactions/staking.d.ts +7 -0
  102. package/dist/transactions/staking.d.ts.map +1 -0
  103. package/dist/transactions/staking.js +72 -0
  104. package/dist/transactions/staking.js.map +1 -0
  105. package/dist/transactions/utils.d.ts +40 -0
  106. package/dist/transactions/utils.d.ts.map +1 -0
  107. package/dist/transactions/utils.js +114 -0
  108. package/dist/transactions/utils.js.map +1 -0
  109. package/dist/transactions/utils.test.d.ts +2 -0
  110. package/dist/transactions/utils.test.d.ts.map +1 -0
  111. package/dist/transactions/utils.test.js +121 -0
  112. package/dist/transactions/utils.test.js.map +1 -0
  113. package/dist/types.d.ts +110 -0
  114. package/dist/types.d.ts.map +1 -0
  115. package/dist/types.js +55 -0
  116. package/dist/types.js.map +1 -0
  117. package/dist/wallet/index.d.ts +3 -0
  118. package/dist/wallet/index.d.ts.map +1 -0
  119. package/dist/wallet/index.js +2 -0
  120. package/dist/wallet/index.js.map +1 -0
  121. package/dist/wallet/keplr.d.ts.map +1 -0
  122. package/dist/wallet/keplr.js.map +1 -0
  123. package/dist/wallet/mnemonic.d.ts +40 -0
  124. package/dist/wallet/mnemonic.d.ts.map +1 -0
  125. package/dist/wallet/mnemonic.js +87 -0
  126. package/dist/wallet/mnemonic.js.map +1 -0
  127. package/package.json +40 -0
  128. package/src/client.ts +178 -0
  129. package/src/config.test.ts +143 -0
  130. package/src/config.ts +122 -0
  131. package/src/cosmos.ts +196 -0
  132. package/src/index.ts +484 -0
  133. package/src/modules.test.ts +127 -0
  134. package/src/modules.ts +278 -0
  135. package/src/queries/auth.ts +136 -0
  136. package/src/queries/bank.ts +117 -0
  137. package/src/queries/billing.ts +164 -0
  138. package/src/queries/distribution.ts +138 -0
  139. package/src/queries/gov.ts +128 -0
  140. package/src/queries/index.ts +7 -0
  141. package/src/queries/staking.ts +190 -0
  142. package/src/queries/utils.test.ts +61 -0
  143. package/src/queries/utils.ts +38 -0
  144. package/src/transactions/bank.ts +110 -0
  145. package/src/transactions/billing.ts +160 -0
  146. package/src/transactions/distribution.ts +98 -0
  147. package/src/transactions/gov.ts +185 -0
  148. package/src/transactions/index.ts +7 -0
  149. package/src/transactions/manifest.ts +89 -0
  150. package/src/transactions/staking.ts +107 -0
  151. package/src/transactions/utils.test.ts +129 -0
  152. package/src/transactions/utils.ts +156 -0
  153. package/src/types.ts +152 -0
  154. package/src/wallet/index.ts +2 -0
  155. package/src/wallet/mnemonic.ts +122 -0
  156. package/tsconfig.json +23 -0
@@ -0,0 +1,160 @@
1
+ import { SigningStargateClient } from '@cosmjs/stargate';
2
+ import { liftedinit } from '@manifest-network/manifestjs';
3
+ import { ManifestMCPError, ManifestMCPErrorCode, CosmosTxResult, ManifestMCPConfig } from '../types.js';
4
+ import { parseAmount, buildTxResult, parseBigInt, validateAddress, validateArgsLength } from './utils.js';
5
+ import { getSubcommandUsage } from '../modules.js';
6
+
7
+ const { MsgFundCredit, MsgCreateLease, MsgCloseLease, MsgWithdraw } = liftedinit.billing.v1;
8
+
9
+ /**
10
+ * Route billing transaction to appropriate handler
11
+ */
12
+ export async function routeBillingTransaction(
13
+ client: SigningStargateClient,
14
+ senderAddress: string,
15
+ subcommand: string,
16
+ args: string[],
17
+ _config: ManifestMCPConfig,
18
+ waitForConfirmation: boolean
19
+ ): Promise<CosmosTxResult> {
20
+ validateArgsLength(args, 'billing transaction');
21
+
22
+ switch (subcommand) {
23
+ case 'fund-credit': {
24
+ if (args.length < 2) {
25
+ const usage = getSubcommandUsage('tx', 'billing', 'fund-credit');
26
+ throw new ManifestMCPError(
27
+ ManifestMCPErrorCode.TX_FAILED,
28
+ `fund-credit requires tenant-address and amount arguments. Received ${args.length} argument(s): [${args.map(a => `"${a}"`).join(', ')}]. Usage: fund-credit ${usage || '<tenant-address> <amount>'}`,
29
+ { receivedArgs: args, expectedArgs: ['tenant-address', 'amount'], usage }
30
+ );
31
+ }
32
+
33
+ const [tenant, amountStr] = args;
34
+ validateAddress(tenant, 'tenant address');
35
+ const { amount, denom } = parseAmount(amountStr);
36
+
37
+ const msg = {
38
+ typeUrl: '/liftedinit.billing.v1.MsgFundCredit',
39
+ value: MsgFundCredit.fromPartial({
40
+ sender: senderAddress,
41
+ tenant,
42
+ amount: { denom, amount },
43
+ }),
44
+ };
45
+
46
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
47
+ return buildTxResult('billing', 'fund-credit', result, waitForConfirmation);
48
+ }
49
+
50
+ case 'create-lease': {
51
+ if (args.length < 1) {
52
+ const usage = getSubcommandUsage('tx', 'billing', 'create-lease');
53
+ throw new ManifestMCPError(
54
+ ManifestMCPErrorCode.TX_FAILED,
55
+ `create-lease requires at least one sku-uuid:quantity pair. Usage: create-lease ${usage || '<sku-uuid:quantity>...'}`,
56
+ { usage }
57
+ );
58
+ }
59
+
60
+ // Parse items (format: sku-uuid:quantity ...)
61
+ const items = args.map((arg) => {
62
+ const [skuUuid, quantityStr] = arg.split(':');
63
+ if (!skuUuid || !quantityStr) {
64
+ throw new ManifestMCPError(
65
+ ManifestMCPErrorCode.TX_FAILED,
66
+ `Invalid lease item format: ${arg}. Expected format: sku-uuid:quantity`
67
+ );
68
+ }
69
+ return { skuUuid, quantity: parseBigInt(quantityStr, 'quantity') };
70
+ });
71
+
72
+ const msg = {
73
+ typeUrl: '/liftedinit.billing.v1.MsgCreateLease',
74
+ value: MsgCreateLease.fromPartial({
75
+ tenant: senderAddress,
76
+ items,
77
+ }),
78
+ };
79
+
80
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
81
+ return buildTxResult('billing', 'create-lease', result, waitForConfirmation);
82
+ }
83
+
84
+ case 'close-lease': {
85
+ if (args.length < 1) {
86
+ const usage = getSubcommandUsage('tx', 'billing', 'close-lease');
87
+ throw new ManifestMCPError(
88
+ ManifestMCPErrorCode.TX_FAILED,
89
+ `close-lease requires at least one lease-uuid argument. Usage: close-lease ${usage || '<lease-uuid>...'}`,
90
+ { usage }
91
+ );
92
+ }
93
+
94
+ // MsgCloseLease can close multiple leases at once
95
+ const leaseUuids = args;
96
+ const reason = ''; // Optional reason, could be added as a flag later
97
+
98
+ const msg = {
99
+ typeUrl: '/liftedinit.billing.v1.MsgCloseLease',
100
+ value: MsgCloseLease.fromPartial({
101
+ sender: senderAddress,
102
+ leaseUuids,
103
+ reason,
104
+ }),
105
+ };
106
+
107
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
108
+ return buildTxResult('billing', 'close-lease', result, waitForConfirmation);
109
+ }
110
+
111
+ case 'withdraw': {
112
+ if (args.length < 1) {
113
+ const usage = getSubcommandUsage('tx', 'billing', 'withdraw');
114
+ throw new ManifestMCPError(
115
+ ManifestMCPErrorCode.TX_FAILED,
116
+ `withdraw requires at least one lease-uuid argument or provider-uuid with --provider flag. Usage: withdraw ${usage || '<lease-uuid>... OR --provider <provider-uuid>'}`,
117
+ { usage }
118
+ );
119
+ }
120
+
121
+ // Check if using provider-wide withdrawal
122
+ const providerFlagIndex = args.indexOf('--provider');
123
+ let leaseUuids: string[] = [];
124
+ let providerUuid = '';
125
+
126
+ if (providerFlagIndex !== -1) {
127
+ // Provider-wide withdrawal mode
128
+ providerUuid = args[providerFlagIndex + 1] || '';
129
+ if (!providerUuid) {
130
+ throw new ManifestMCPError(
131
+ ManifestMCPErrorCode.TX_FAILED,
132
+ 'withdraw with --provider flag requires provider-uuid argument'
133
+ );
134
+ }
135
+ } else {
136
+ // Lease-specific withdrawal mode
137
+ leaseUuids = args;
138
+ }
139
+
140
+ const msg = {
141
+ typeUrl: '/liftedinit.billing.v1.MsgWithdraw',
142
+ value: MsgWithdraw.fromPartial({
143
+ sender: senderAddress,
144
+ leaseUuids,
145
+ providerUuid,
146
+ }),
147
+ };
148
+
149
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
150
+ return buildTxResult('billing', 'withdraw', result, waitForConfirmation);
151
+ }
152
+
153
+ default:
154
+ throw new ManifestMCPError(
155
+ ManifestMCPErrorCode.UNSUPPORTED_TX,
156
+ `Unsupported billing transaction subcommand: ${subcommand}`,
157
+ { availableSubcommands: ['fund-credit', 'create-lease', 'close-lease', 'withdraw'] }
158
+ );
159
+ }
160
+ }
@@ -0,0 +1,98 @@
1
+ import { SigningStargateClient } from '@cosmjs/stargate';
2
+ import { cosmos } from '@manifest-network/manifestjs';
3
+ import { ManifestMCPError, ManifestMCPErrorCode, CosmosTxResult, ManifestMCPConfig } from '../types.js';
4
+ import { parseAmount, buildTxResult, validateAddress, validateArgsLength } from './utils.js';
5
+
6
+ const { MsgWithdrawDelegatorReward, MsgSetWithdrawAddress, MsgFundCommunityPool } = cosmos.distribution.v1beta1;
7
+
8
+ /**
9
+ * Route distribution transaction to appropriate handler
10
+ */
11
+ export async function routeDistributionTransaction(
12
+ client: SigningStargateClient,
13
+ senderAddress: string,
14
+ subcommand: string,
15
+ args: string[],
16
+ _config: ManifestMCPConfig,
17
+ waitForConfirmation: boolean
18
+ ): Promise<CosmosTxResult> {
19
+ validateArgsLength(args, 'distribution transaction');
20
+
21
+ switch (subcommand) {
22
+ case 'withdraw-rewards': {
23
+ if (args.length < 1) {
24
+ throw new ManifestMCPError(
25
+ ManifestMCPErrorCode.TX_FAILED,
26
+ 'withdraw-rewards requires validator-address argument'
27
+ );
28
+ }
29
+
30
+ const [validatorAddress] = args;
31
+ validateAddress(validatorAddress, 'validator address');
32
+
33
+ const msg = {
34
+ typeUrl: '/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward',
35
+ value: MsgWithdrawDelegatorReward.fromPartial({
36
+ delegatorAddress: senderAddress,
37
+ validatorAddress,
38
+ }),
39
+ };
40
+
41
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
42
+ return buildTxResult('distribution', 'withdraw-rewards', result, waitForConfirmation);
43
+ }
44
+
45
+ case 'set-withdraw-addr': {
46
+ if (args.length < 1) {
47
+ throw new ManifestMCPError(
48
+ ManifestMCPErrorCode.TX_FAILED,
49
+ 'set-withdraw-addr requires withdraw-address argument'
50
+ );
51
+ }
52
+
53
+ const [withdrawAddress] = args;
54
+ validateAddress(withdrawAddress, 'withdraw address');
55
+
56
+ const msg = {
57
+ typeUrl: '/cosmos.distribution.v1beta1.MsgSetWithdrawAddress',
58
+ value: MsgSetWithdrawAddress.fromPartial({
59
+ delegatorAddress: senderAddress,
60
+ withdrawAddress,
61
+ }),
62
+ };
63
+
64
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
65
+ return buildTxResult('distribution', 'set-withdraw-addr', result, waitForConfirmation);
66
+ }
67
+
68
+ case 'fund-community-pool': {
69
+ if (args.length < 1) {
70
+ throw new ManifestMCPError(
71
+ ManifestMCPErrorCode.TX_FAILED,
72
+ 'fund-community-pool requires amount argument'
73
+ );
74
+ }
75
+
76
+ const [amountStr] = args;
77
+ const { amount, denom } = parseAmount(amountStr);
78
+
79
+ const msg = {
80
+ typeUrl: '/cosmos.distribution.v1beta1.MsgFundCommunityPool',
81
+ value: MsgFundCommunityPool.fromPartial({
82
+ depositor: senderAddress,
83
+ amount: [{ denom, amount }],
84
+ }),
85
+ };
86
+
87
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
88
+ return buildTxResult('distribution', 'fund-community-pool', result, waitForConfirmation);
89
+ }
90
+
91
+ default:
92
+ throw new ManifestMCPError(
93
+ ManifestMCPErrorCode.UNSUPPORTED_TX,
94
+ `Unsupported distribution transaction subcommand: ${subcommand}`,
95
+ { availableSubcommands: ['withdraw-rewards', 'set-withdraw-addr', 'fund-community-pool'] }
96
+ );
97
+ }
98
+ }
@@ -0,0 +1,185 @@
1
+ import { SigningStargateClient } from '@cosmjs/stargate';
2
+ import { cosmos } from '@manifest-network/manifestjs';
3
+ import { ManifestMCPError, ManifestMCPErrorCode, CosmosTxResult, ManifestMCPConfig } from '../types.js';
4
+ import { parseAmount, buildTxResult, parseBigInt, validateArgsLength } from './utils.js';
5
+
6
+ const { MsgVote, MsgDeposit, MsgVoteWeighted, VoteOption } = cosmos.gov.v1;
7
+
8
+ /**
9
+ * Parse a decimal weight string to an 18-decimal fixed-point string.
10
+ * Uses string manipulation to avoid floating-point precision loss.
11
+ *
12
+ * @param weightStr - Decimal string like "0.5", "0.333333333333333333", "1"
13
+ * @returns String representation of weight * 10^18
14
+ */
15
+ function parseWeightToFixed18(weightStr: string): string {
16
+ // Validate format: must be a valid decimal number
17
+ if (!/^\d+(\.\d+)?$/.test(weightStr)) {
18
+ throw new ManifestMCPError(
19
+ ManifestMCPErrorCode.TX_FAILED,
20
+ `Invalid weight format: "${weightStr}". Expected decimal like "0.5" or "0.333333333333333333"`
21
+ );
22
+ }
23
+
24
+ const [intPart, decPart = ''] = weightStr.split('.');
25
+
26
+ // Pad or truncate decimal part to exactly 18 digits
27
+ const paddedDecimal = decPart.padEnd(18, '0').slice(0, 18);
28
+
29
+ // Combine integer and decimal parts
30
+ const combined = intPart + paddedDecimal;
31
+
32
+ // Remove leading zeros but keep at least one digit
33
+ const result = combined.replace(/^0+/, '') || '0';
34
+
35
+ return result;
36
+ }
37
+
38
+ /**
39
+ * Parse vote option string to VoteOption enum value from manifestjs
40
+ */
41
+ function parseVoteOption(optionStr: string): number {
42
+ const option = optionStr.toLowerCase();
43
+ switch (option) {
44
+ case 'yes':
45
+ case '1':
46
+ return VoteOption.VOTE_OPTION_YES;
47
+ case 'abstain':
48
+ case '2':
49
+ return VoteOption.VOTE_OPTION_ABSTAIN;
50
+ case 'no':
51
+ case '3':
52
+ return VoteOption.VOTE_OPTION_NO;
53
+ case 'no_with_veto':
54
+ case 'nowithveto':
55
+ case '4':
56
+ return VoteOption.VOTE_OPTION_NO_WITH_VETO;
57
+ default:
58
+ throw new ManifestMCPError(
59
+ ManifestMCPErrorCode.TX_FAILED,
60
+ `Invalid vote option: ${optionStr}. Expected: yes, no, abstain, or no_with_veto`
61
+ );
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Route gov transaction to appropriate handler
67
+ */
68
+ export async function routeGovTransaction(
69
+ client: SigningStargateClient,
70
+ senderAddress: string,
71
+ subcommand: string,
72
+ args: string[],
73
+ _config: ManifestMCPConfig,
74
+ waitForConfirmation: boolean
75
+ ): Promise<CosmosTxResult> {
76
+ validateArgsLength(args, 'gov transaction');
77
+
78
+ switch (subcommand) {
79
+ case 'vote': {
80
+ if (args.length < 2) {
81
+ throw new ManifestMCPError(
82
+ ManifestMCPErrorCode.TX_FAILED,
83
+ 'vote requires proposal-id and option arguments'
84
+ );
85
+ }
86
+
87
+ const [proposalIdStr, optionStr] = args;
88
+ const proposalId = parseBigInt(proposalIdStr, 'proposal-id');
89
+ const option = parseVoteOption(optionStr);
90
+
91
+ // Extract optional metadata from args
92
+ let metadata = '';
93
+ const metadataIndex = args.indexOf('--metadata');
94
+ if (metadataIndex !== -1 && args[metadataIndex + 1]) {
95
+ metadata = args[metadataIndex + 1];
96
+ }
97
+
98
+ const msg = {
99
+ typeUrl: '/cosmos.gov.v1.MsgVote',
100
+ value: MsgVote.fromPartial({
101
+ proposalId,
102
+ voter: senderAddress,
103
+ option,
104
+ metadata,
105
+ }),
106
+ };
107
+
108
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
109
+ return buildTxResult('gov', 'vote', result, waitForConfirmation);
110
+ }
111
+
112
+ case 'weighted-vote': {
113
+ if (args.length < 2) {
114
+ throw new ManifestMCPError(
115
+ ManifestMCPErrorCode.TX_FAILED,
116
+ 'weighted-vote requires proposal-id and options arguments (format: yes=0.5,no=0.5)'
117
+ );
118
+ }
119
+
120
+ const [proposalIdStr, optionsStr] = args;
121
+ const proposalId = parseBigInt(proposalIdStr, 'proposal-id');
122
+
123
+ // Parse weighted options (format: yes=0.5,no=0.3,abstain=0.2)
124
+ const options = optionsStr.split(',').map((opt) => {
125
+ const [optName, weightStr] = opt.split('=');
126
+ if (!optName || !weightStr) {
127
+ throw new ManifestMCPError(
128
+ ManifestMCPErrorCode.TX_FAILED,
129
+ `Invalid weighted vote format: ${opt}. Expected format: option=weight`
130
+ );
131
+ }
132
+ const option = parseVoteOption(optName);
133
+ // Weight is a decimal string (e.g., "0.5" -> "500000000000000000" for 18 decimals)
134
+ // Use string-based conversion to avoid floating-point precision loss
135
+ const weight = parseWeightToFixed18(weightStr);
136
+ return { option, weight };
137
+ });
138
+
139
+ const msg = {
140
+ typeUrl: '/cosmos.gov.v1.MsgVoteWeighted',
141
+ value: MsgVoteWeighted.fromPartial({
142
+ proposalId,
143
+ voter: senderAddress,
144
+ options,
145
+ metadata: '',
146
+ }),
147
+ };
148
+
149
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
150
+ return buildTxResult('gov', 'weighted-vote', result, waitForConfirmation);
151
+ }
152
+
153
+ case 'deposit': {
154
+ if (args.length < 2) {
155
+ throw new ManifestMCPError(
156
+ ManifestMCPErrorCode.TX_FAILED,
157
+ 'deposit requires proposal-id and amount arguments'
158
+ );
159
+ }
160
+
161
+ const [proposalIdStr, amountStr] = args;
162
+ const proposalId = parseBigInt(proposalIdStr, 'proposal-id');
163
+ const { amount, denom } = parseAmount(amountStr);
164
+
165
+ const msg = {
166
+ typeUrl: '/cosmos.gov.v1.MsgDeposit',
167
+ value: MsgDeposit.fromPartial({
168
+ proposalId,
169
+ depositor: senderAddress,
170
+ amount: [{ denom, amount }],
171
+ }),
172
+ };
173
+
174
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
175
+ return buildTxResult('gov', 'deposit', result, waitForConfirmation);
176
+ }
177
+
178
+ default:
179
+ throw new ManifestMCPError(
180
+ ManifestMCPErrorCode.UNSUPPORTED_TX,
181
+ `Unsupported gov transaction subcommand: ${subcommand}`,
182
+ { availableSubcommands: ['vote', 'weighted-vote', 'deposit'] }
183
+ );
184
+ }
185
+ }
@@ -0,0 +1,7 @@
1
+ export { parseAmount, buildTxResult, parseBigInt } from './utils.js';
2
+ export { routeBankTransaction } from './bank.js';
3
+ export { routeStakingTransaction } from './staking.js';
4
+ export { routeDistributionTransaction } from './distribution.js';
5
+ export { routeGovTransaction } from './gov.js';
6
+ export { routeBillingTransaction } from './billing.js';
7
+ export { routeManifestTransaction } from './manifest.js';
@@ -0,0 +1,89 @@
1
+ import { SigningStargateClient } from '@cosmjs/stargate';
2
+ import { liftedinit } from '@manifest-network/manifestjs';
3
+ import { ManifestMCPError, ManifestMCPErrorCode, CosmosTxResult, ManifestMCPConfig } from '../types.js';
4
+ import { parseAmount, buildTxResult, validateAddress, validateArgsLength } from './utils.js';
5
+
6
+ const { MsgPayout, MsgBurnHeldBalance } = liftedinit.manifest.v1;
7
+
8
+ /**
9
+ * Route manifest transaction to appropriate handler
10
+ */
11
+ export async function routeManifestTransaction(
12
+ client: SigningStargateClient,
13
+ senderAddress: string,
14
+ subcommand: string,
15
+ args: string[],
16
+ _config: ManifestMCPConfig,
17
+ waitForConfirmation: boolean
18
+ ): Promise<CosmosTxResult> {
19
+ validateArgsLength(args, 'manifest transaction');
20
+
21
+ switch (subcommand) {
22
+ case 'payout': {
23
+ if (args.length < 1) {
24
+ throw new ManifestMCPError(
25
+ ManifestMCPErrorCode.TX_FAILED,
26
+ 'payout requires at least one address:amount pair'
27
+ );
28
+ }
29
+
30
+ // Parse payout pairs (format: address:amount ...)
31
+ const payoutPairs = args.map((arg) => {
32
+ const [address, amountStr] = arg.split(':');
33
+ if (!address || !amountStr) {
34
+ throw new ManifestMCPError(
35
+ ManifestMCPErrorCode.TX_FAILED,
36
+ `Invalid payout pair format: ${arg}. Expected format: address:amount`
37
+ );
38
+ }
39
+ validateAddress(address, 'payout recipient address');
40
+ const { amount, denom } = parseAmount(amountStr);
41
+ return { address, coin: { denom, amount } };
42
+ });
43
+
44
+ const msg = {
45
+ typeUrl: '/liftedinit.manifest.v1.MsgPayout',
46
+ value: MsgPayout.fromPartial({
47
+ authority: senderAddress,
48
+ payoutPairs,
49
+ }),
50
+ };
51
+
52
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
53
+ return buildTxResult('manifest', 'payout', result, waitForConfirmation);
54
+ }
55
+
56
+ case 'burn-held-balance': {
57
+ if (args.length < 1) {
58
+ throw new ManifestMCPError(
59
+ ManifestMCPErrorCode.TX_FAILED,
60
+ 'burn-held-balance requires at least one amount argument'
61
+ );
62
+ }
63
+
64
+ // Parse coins to burn
65
+ const burnCoins = args.map((amountStr) => {
66
+ const { amount, denom } = parseAmount(amountStr);
67
+ return { denom, amount };
68
+ });
69
+
70
+ const msg = {
71
+ typeUrl: '/liftedinit.manifest.v1.MsgBurnHeldBalance',
72
+ value: MsgBurnHeldBalance.fromPartial({
73
+ authority: senderAddress,
74
+ burnCoins,
75
+ }),
76
+ };
77
+
78
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
79
+ return buildTxResult('manifest', 'burn-held-balance', result, waitForConfirmation);
80
+ }
81
+
82
+ default:
83
+ throw new ManifestMCPError(
84
+ ManifestMCPErrorCode.UNSUPPORTED_TX,
85
+ `Unsupported manifest transaction subcommand: ${subcommand}`,
86
+ { availableSubcommands: ['payout', 'burn-held-balance'] }
87
+ );
88
+ }
89
+ }
@@ -0,0 +1,107 @@
1
+ import { SigningStargateClient } from '@cosmjs/stargate';
2
+ import { cosmos } from '@manifest-network/manifestjs';
3
+ import { ManifestMCPError, ManifestMCPErrorCode, CosmosTxResult, ManifestMCPConfig } from '../types.js';
4
+ import { parseAmount, buildTxResult, validateAddress, validateArgsLength } from './utils.js';
5
+
6
+ const { MsgDelegate, MsgUndelegate, MsgBeginRedelegate } = cosmos.staking.v1beta1;
7
+
8
+ /**
9
+ * Route staking transaction to appropriate handler
10
+ */
11
+ export async function routeStakingTransaction(
12
+ client: SigningStargateClient,
13
+ senderAddress: string,
14
+ subcommand: string,
15
+ args: string[],
16
+ _config: ManifestMCPConfig,
17
+ waitForConfirmation: boolean
18
+ ): Promise<CosmosTxResult> {
19
+ validateArgsLength(args, 'staking transaction');
20
+
21
+ switch (subcommand) {
22
+ case 'delegate': {
23
+ if (args.length < 2) {
24
+ throw new ManifestMCPError(
25
+ ManifestMCPErrorCode.TX_FAILED,
26
+ 'delegate requires validator-address and amount arguments'
27
+ );
28
+ }
29
+
30
+ const [validatorAddress, amountStr] = args;
31
+ validateAddress(validatorAddress, 'validator address');
32
+ const { amount, denom } = parseAmount(amountStr);
33
+
34
+ const msg = {
35
+ typeUrl: '/cosmos.staking.v1beta1.MsgDelegate',
36
+ value: MsgDelegate.fromPartial({
37
+ delegatorAddress: senderAddress,
38
+ validatorAddress,
39
+ amount: { denom, amount },
40
+ }),
41
+ };
42
+
43
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
44
+ return buildTxResult('staking', 'delegate', result, waitForConfirmation);
45
+ }
46
+
47
+ case 'unbond':
48
+ case 'undelegate': {
49
+ if (args.length < 2) {
50
+ throw new ManifestMCPError(
51
+ ManifestMCPErrorCode.TX_FAILED,
52
+ 'unbond requires validator-address and amount arguments'
53
+ );
54
+ }
55
+
56
+ const [validatorAddress, amountStr] = args;
57
+ validateAddress(validatorAddress, 'validator address');
58
+ const { amount, denom } = parseAmount(amountStr);
59
+
60
+ const msg = {
61
+ typeUrl: '/cosmos.staking.v1beta1.MsgUndelegate',
62
+ value: MsgUndelegate.fromPartial({
63
+ delegatorAddress: senderAddress,
64
+ validatorAddress,
65
+ amount: { denom, amount },
66
+ }),
67
+ };
68
+
69
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
70
+ return buildTxResult('staking', 'unbond', result, waitForConfirmation);
71
+ }
72
+
73
+ case 'redelegate': {
74
+ if (args.length < 3) {
75
+ throw new ManifestMCPError(
76
+ ManifestMCPErrorCode.TX_FAILED,
77
+ 'redelegate requires src-validator, dst-validator, and amount arguments'
78
+ );
79
+ }
80
+
81
+ const [srcValidatorAddress, dstValidatorAddress, amountStr] = args;
82
+ validateAddress(srcValidatorAddress, 'source validator address');
83
+ validateAddress(dstValidatorAddress, 'destination validator address');
84
+ const { amount, denom } = parseAmount(amountStr);
85
+
86
+ const msg = {
87
+ typeUrl: '/cosmos.staking.v1beta1.MsgBeginRedelegate',
88
+ value: MsgBeginRedelegate.fromPartial({
89
+ delegatorAddress: senderAddress,
90
+ validatorSrcAddress: srcValidatorAddress,
91
+ validatorDstAddress: dstValidatorAddress,
92
+ amount: { denom, amount },
93
+ }),
94
+ };
95
+
96
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
97
+ return buildTxResult('staking', 'redelegate', result, waitForConfirmation);
98
+ }
99
+
100
+ default:
101
+ throw new ManifestMCPError(
102
+ ManifestMCPErrorCode.UNSUPPORTED_TX,
103
+ `Unsupported staking transaction subcommand: ${subcommand}`,
104
+ { availableSubcommands: ['delegate', 'unbond', 'redelegate'] }
105
+ );
106
+ }
107
+ }