@manifest-network/manifest-mcp-browser 0.1.5 → 0.1.6

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.
@@ -1,13 +1,14 @@
1
1
  import { SigningStargateClient } from '@cosmjs/stargate';
2
2
  import { liftedinit } from '@manifest-network/manifestjs';
3
3
  import { CosmosTxResult, ManifestMCPError, ManifestMCPErrorCode } from '../types.js';
4
- import { parseAmount, buildTxResult, parseBigInt, validateAddress, validateArgsLength, extractFlag, filterConsumedArgs, parseColonPair, requireArgs, parseHexBytes } from './utils.js';
4
+ import { parseAmount, buildTxResult, parseBigInt, validateAddress, validateArgsLength, extractFlag, filterConsumedArgs, parseColonPair, requireArgs, parseHexBytes, MAX_META_HASH_BYTES } from './utils.js';
5
5
  import { getSubcommandUsage, throwUnsupportedSubcommand } from '../modules.js';
6
6
 
7
- const { MsgFundCredit, MsgCreateLease, MsgCloseLease, MsgWithdraw } = liftedinit.billing.v1;
8
-
9
- /** Maximum meta hash length in bytes (64 bytes for SHA-512) */
10
- const MAX_META_HASH_BYTES = 64;
7
+ const {
8
+ MsgFundCredit, MsgCreateLease, MsgCloseLease, MsgWithdraw,
9
+ MsgCreateLeaseForTenant, MsgAcknowledgeLease, MsgRejectLease, MsgCancelLease,
10
+ MsgUpdateParams,
11
+ } = liftedinit.billing.v1;
11
12
 
12
13
  /**
13
14
  * Route billing transaction to appropriate handler
@@ -159,6 +160,126 @@ export async function routeBillingTransaction(
159
160
  return buildTxResult('billing', 'withdraw', result, waitForConfirmation);
160
161
  }
161
162
 
163
+ case 'create-lease-for-tenant': {
164
+ // Parse optional --meta-hash flag
165
+ const { value: metaHashHex, consumedIndices } = extractFlag(args, '--meta-hash', 'billing create-lease-for-tenant');
166
+ const metaHash = metaHashHex ? parseHexBytes(metaHashHex, 'meta-hash', MAX_META_HASH_BYTES) : undefined;
167
+
168
+ // Filter out --meta-hash and its value to get remaining args
169
+ const remainingArgs = filterConsumedArgs(args, consumedIndices);
170
+ requireArgs(remainingArgs, 2, ['tenant-address', 'sku-uuid:quantity'], 'billing create-lease-for-tenant');
171
+
172
+ const [tenant, ...itemArgs] = remainingArgs;
173
+ validateAddress(tenant, 'tenant address');
174
+
175
+ // Parse items (format: sku-uuid:quantity ...)
176
+ const items = itemArgs.map((arg) => {
177
+ const [skuUuid, quantityStr] = parseColonPair(arg, 'sku-uuid', 'quantity', 'lease item');
178
+ return { skuUuid, quantity: parseBigInt(quantityStr, 'quantity') };
179
+ });
180
+
181
+ const msg = {
182
+ typeUrl: '/liftedinit.billing.v1.MsgCreateLeaseForTenant',
183
+ value: MsgCreateLeaseForTenant.fromPartial({
184
+ authority: senderAddress,
185
+ tenant,
186
+ items,
187
+ metaHash: metaHash ?? new Uint8Array(),
188
+ }),
189
+ };
190
+
191
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
192
+ return buildTxResult('billing', 'create-lease-for-tenant', result, waitForConfirmation);
193
+ }
194
+
195
+ case 'acknowledge-lease': {
196
+ requireArgs(args, 1, ['lease-uuid'], 'billing acknowledge-lease');
197
+ const leaseUuids = args;
198
+
199
+ const msg = {
200
+ typeUrl: '/liftedinit.billing.v1.MsgAcknowledgeLease',
201
+ value: MsgAcknowledgeLease.fromPartial({
202
+ sender: senderAddress,
203
+ leaseUuids,
204
+ }),
205
+ };
206
+
207
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
208
+ return buildTxResult('billing', 'acknowledge-lease', result, waitForConfirmation);
209
+ }
210
+
211
+ case 'reject-lease': {
212
+ // Parse optional --reason flag
213
+ const { value: reason, consumedIndices } = extractFlag(args, '--reason', 'billing reject-lease');
214
+ const leaseArgs = filterConsumedArgs(args, consumedIndices);
215
+ requireArgs(leaseArgs, 1, ['lease-uuid'], 'billing reject-lease');
216
+
217
+ const leaseUuids = leaseArgs;
218
+
219
+ const msg = {
220
+ typeUrl: '/liftedinit.billing.v1.MsgRejectLease',
221
+ value: MsgRejectLease.fromPartial({
222
+ sender: senderAddress,
223
+ leaseUuids,
224
+ reason: reason ?? '',
225
+ }),
226
+ };
227
+
228
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
229
+ return buildTxResult('billing', 'reject-lease', result, waitForConfirmation);
230
+ }
231
+
232
+ case 'cancel-lease': {
233
+ requireArgs(args, 1, ['lease-uuid'], 'billing cancel-lease');
234
+ const leaseUuids = args;
235
+
236
+ const msg = {
237
+ typeUrl: '/liftedinit.billing.v1.MsgCancelLease',
238
+ value: MsgCancelLease.fromPartial({
239
+ tenant: senderAddress,
240
+ leaseUuids,
241
+ }),
242
+ };
243
+
244
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
245
+ return buildTxResult('billing', 'cancel-lease', result, waitForConfirmation);
246
+ }
247
+
248
+ case 'update-params': {
249
+ requireArgs(args, 5, [
250
+ 'max-leases-per-tenant', 'max-items-per-lease', 'min-lease-duration',
251
+ 'max-pending-leases-per-tenant', 'pending-timeout',
252
+ ], 'billing update-params');
253
+
254
+ const [
255
+ maxLeasesPerTenantStr, maxItemsPerLeaseStr, minLeaseDurationStr,
256
+ maxPendingLeasesPerTenantStr, pendingTimeoutStr,
257
+ ...allowedAddresses
258
+ ] = args;
259
+
260
+ for (const addr of allowedAddresses) {
261
+ validateAddress(addr, 'allowed address');
262
+ }
263
+
264
+ const msg = {
265
+ typeUrl: '/liftedinit.billing.v1.MsgUpdateParams',
266
+ value: MsgUpdateParams.fromPartial({
267
+ authority: senderAddress,
268
+ params: {
269
+ maxLeasesPerTenant: parseBigInt(maxLeasesPerTenantStr, 'max-leases-per-tenant'),
270
+ maxItemsPerLease: parseBigInt(maxItemsPerLeaseStr, 'max-items-per-lease'),
271
+ minLeaseDuration: parseBigInt(minLeaseDurationStr, 'min-lease-duration'),
272
+ maxPendingLeasesPerTenant: parseBigInt(maxPendingLeasesPerTenantStr, 'max-pending-leases-per-tenant'),
273
+ pendingTimeout: parseBigInt(pendingTimeoutStr, 'pending-timeout'),
274
+ allowedList: allowedAddresses,
275
+ },
276
+ }),
277
+ };
278
+
279
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
280
+ return buildTxResult('billing', 'update-params', result, waitForConfirmation);
281
+ }
282
+
162
283
  default:
163
284
  throwUnsupportedSubcommand('tx', 'billing', subcommand);
164
285
  }
@@ -0,0 +1,232 @@
1
+ import { SigningStargateClient } from '@cosmjs/stargate';
2
+ import { liftedinit } from '@manifest-network/manifestjs';
3
+ import { CosmosTxResult, ManifestMCPError, ManifestMCPErrorCode } from '../types.js';
4
+ import { parseAmount, buildTxResult, validateAddress, validateArgsLength, extractFlag, filterConsumedArgs, requireArgs, parseHexBytes, MAX_META_HASH_BYTES } from './utils.js';
5
+ import { throwUnsupportedSubcommand } from '../modules.js';
6
+
7
+ const {
8
+ MsgCreateProvider, MsgUpdateProvider, MsgDeactivateProvider,
9
+ MsgCreateSKU, MsgUpdateSKU, MsgDeactivateSKU,
10
+ MsgUpdateParams,
11
+ Unit,
12
+ } = liftedinit.sku.v1;
13
+
14
+ /**
15
+ * Parse a unit string to the Unit enum value.
16
+ * Accepts 'per-hour' or 'per-day'.
17
+ */
18
+ function parseUnit(value: string): number {
19
+ switch (value.toLowerCase()) {
20
+ case 'per-hour':
21
+ return Unit.UNIT_PER_HOUR;
22
+ case 'per-day':
23
+ return Unit.UNIT_PER_DAY;
24
+ default:
25
+ throw new ManifestMCPError(
26
+ ManifestMCPErrorCode.TX_FAILED,
27
+ `Invalid unit: "${value}". Expected "per-hour" or "per-day".`
28
+ );
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Parse a boolean string ('true' or 'false').
34
+ */
35
+ function parseBooleanString(value: string, fieldName: string): boolean {
36
+ const lower = value.toLowerCase();
37
+ if (lower === 'true') return true;
38
+ if (lower === 'false') return false;
39
+ throw new ManifestMCPError(
40
+ ManifestMCPErrorCode.TX_FAILED,
41
+ `Invalid ${fieldName}: "${value}". Expected "true" or "false".`
42
+ );
43
+ }
44
+
45
+ /**
46
+ * Route SKU transaction to appropriate handler
47
+ */
48
+ export async function routeSkuTransaction(
49
+ client: SigningStargateClient,
50
+ senderAddress: string,
51
+ subcommand: string,
52
+ args: string[],
53
+ waitForConfirmation: boolean
54
+ ): Promise<CosmosTxResult> {
55
+ validateArgsLength(args, 'sku transaction');
56
+
57
+ switch (subcommand) {
58
+ case 'create-provider': {
59
+ // Parse optional --meta-hash flag
60
+ const { value: metaHashHex, consumedIndices } = extractFlag(args, '--meta-hash', 'sku create-provider');
61
+ const metaHash = metaHashHex ? parseHexBytes(metaHashHex, 'meta-hash', MAX_META_HASH_BYTES) : new Uint8Array();
62
+ const positionalArgs = filterConsumedArgs(args, consumedIndices);
63
+
64
+ requireArgs(positionalArgs, 3, ['address', 'payout-address', 'api-url'], 'sku create-provider');
65
+ const [address, payoutAddress, apiUrl] = positionalArgs;
66
+ validateAddress(address, 'address');
67
+ validateAddress(payoutAddress, 'payout address');
68
+
69
+ const msg = {
70
+ typeUrl: '/liftedinit.sku.v1.MsgCreateProvider',
71
+ value: MsgCreateProvider.fromPartial({
72
+ authority: senderAddress,
73
+ address,
74
+ payoutAddress,
75
+ metaHash,
76
+ apiUrl,
77
+ }),
78
+ };
79
+
80
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
81
+ return buildTxResult('sku', 'create-provider', result, waitForConfirmation);
82
+ }
83
+
84
+ case 'update-provider': {
85
+ // Parse optional flags
86
+ const metaHashFlag = extractFlag(args, '--meta-hash', 'sku update-provider');
87
+ const activeFlag = extractFlag(args, '--active', 'sku update-provider');
88
+ const allConsumed = [...metaHashFlag.consumedIndices, ...activeFlag.consumedIndices];
89
+ const positionalArgs = filterConsumedArgs(args, allConsumed);
90
+
91
+ requireArgs(positionalArgs, 4, ['provider-uuid', 'address', 'payout-address', 'api-url'], 'sku update-provider');
92
+ const [uuid, address, payoutAddress, apiUrl] = positionalArgs;
93
+ validateAddress(address, 'address');
94
+ validateAddress(payoutAddress, 'payout address');
95
+
96
+ const metaHash = metaHashFlag.value ? parseHexBytes(metaHashFlag.value, 'meta-hash', MAX_META_HASH_BYTES) : new Uint8Array();
97
+ const active = activeFlag.value ? parseBooleanString(activeFlag.value, 'active') : true;
98
+
99
+ const msg = {
100
+ typeUrl: '/liftedinit.sku.v1.MsgUpdateProvider',
101
+ value: MsgUpdateProvider.fromPartial({
102
+ authority: senderAddress,
103
+ uuid,
104
+ address,
105
+ payoutAddress,
106
+ metaHash,
107
+ active,
108
+ apiUrl,
109
+ }),
110
+ };
111
+
112
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
113
+ return buildTxResult('sku', 'update-provider', result, waitForConfirmation);
114
+ }
115
+
116
+ case 'deactivate-provider': {
117
+ requireArgs(args, 1, ['provider-uuid'], 'sku deactivate-provider');
118
+ const [uuid] = args;
119
+
120
+ const msg = {
121
+ typeUrl: '/liftedinit.sku.v1.MsgDeactivateProvider',
122
+ value: MsgDeactivateProvider.fromPartial({
123
+ authority: senderAddress,
124
+ uuid,
125
+ }),
126
+ };
127
+
128
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
129
+ return buildTxResult('sku', 'deactivate-provider', result, waitForConfirmation);
130
+ }
131
+
132
+ case 'create-sku': {
133
+ // Parse optional --meta-hash flag
134
+ const { value: metaHashHex, consumedIndices } = extractFlag(args, '--meta-hash', 'sku create-sku');
135
+ const metaHash = metaHashHex ? parseHexBytes(metaHashHex, 'meta-hash', MAX_META_HASH_BYTES) : new Uint8Array();
136
+ const positionalArgs = filterConsumedArgs(args, consumedIndices);
137
+
138
+ requireArgs(positionalArgs, 4, ['provider-uuid', 'name', 'unit', 'base-price'], 'sku create-sku');
139
+ const [providerUuid, name, unitStr, basePriceStr] = positionalArgs;
140
+
141
+ const unit = parseUnit(unitStr);
142
+ const { amount, denom } = parseAmount(basePriceStr);
143
+
144
+ const msg = {
145
+ typeUrl: '/liftedinit.sku.v1.MsgCreateSKU',
146
+ value: MsgCreateSKU.fromPartial({
147
+ authority: senderAddress,
148
+ providerUuid,
149
+ name,
150
+ unit,
151
+ basePrice: { denom, amount },
152
+ metaHash,
153
+ }),
154
+ };
155
+
156
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
157
+ return buildTxResult('sku', 'create-sku', result, waitForConfirmation);
158
+ }
159
+
160
+ case 'update-sku': {
161
+ // Parse optional flags
162
+ const metaHashFlag = extractFlag(args, '--meta-hash', 'sku update-sku');
163
+ const activeFlag = extractFlag(args, '--active', 'sku update-sku');
164
+ const allConsumed = [...metaHashFlag.consumedIndices, ...activeFlag.consumedIndices];
165
+ const positionalArgs = filterConsumedArgs(args, allConsumed);
166
+
167
+ requireArgs(positionalArgs, 5, ['sku-uuid', 'provider-uuid', 'name', 'unit', 'base-price'], 'sku update-sku');
168
+ const [uuid, providerUuid, name, unitStr, basePriceStr] = positionalArgs;
169
+
170
+ const unit = parseUnit(unitStr);
171
+ const { amount, denom } = parseAmount(basePriceStr);
172
+ const metaHash = metaHashFlag.value ? parseHexBytes(metaHashFlag.value, 'meta-hash', MAX_META_HASH_BYTES) : new Uint8Array();
173
+ const active = activeFlag.value ? parseBooleanString(activeFlag.value, 'active') : true;
174
+
175
+ const msg = {
176
+ typeUrl: '/liftedinit.sku.v1.MsgUpdateSKU',
177
+ value: MsgUpdateSKU.fromPartial({
178
+ authority: senderAddress,
179
+ uuid,
180
+ providerUuid,
181
+ name,
182
+ unit,
183
+ basePrice: { denom, amount },
184
+ metaHash,
185
+ active,
186
+ }),
187
+ };
188
+
189
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
190
+ return buildTxResult('sku', 'update-sku', result, waitForConfirmation);
191
+ }
192
+
193
+ case 'deactivate-sku': {
194
+ requireArgs(args, 1, ['sku-uuid'], 'sku deactivate-sku');
195
+ const [uuid] = args;
196
+
197
+ const msg = {
198
+ typeUrl: '/liftedinit.sku.v1.MsgDeactivateSKU',
199
+ value: MsgDeactivateSKU.fromPartial({
200
+ authority: senderAddress,
201
+ uuid,
202
+ }),
203
+ };
204
+
205
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
206
+ return buildTxResult('sku', 'deactivate-sku', result, waitForConfirmation);
207
+ }
208
+
209
+ case 'update-params': {
210
+ requireArgs(args, 1, ['allowed-address'], 'sku update-params');
211
+ for (const addr of args) {
212
+ validateAddress(addr, 'allowed address');
213
+ }
214
+
215
+ const msg = {
216
+ typeUrl: '/liftedinit.sku.v1.MsgUpdateParams',
217
+ value: MsgUpdateParams.fromPartial({
218
+ authority: senderAddress,
219
+ params: {
220
+ allowedList: args,
221
+ },
222
+ }),
223
+ };
224
+
225
+ const result = await client.signAndBroadcast(senderAddress, [msg], 'auto');
226
+ return buildTxResult('sku', 'update-params', result, waitForConfirmation);
227
+ }
228
+
229
+ default:
230
+ throwUnsupportedSubcommand('tx', 'sku', subcommand);
231
+ }
232
+ }
@@ -5,6 +5,9 @@ import { ManifestMCPError, ManifestMCPErrorCode, CosmosTxResult } from '../types
5
5
  /** Maximum number of arguments allowed */
6
6
  export const MAX_ARGS = 100;
7
7
 
8
+ /** Maximum meta hash length in bytes (64 bytes for SHA-512) */
9
+ export const MAX_META_HASH_BYTES = 64;
10
+
8
11
  /**
9
12
  * Result from extracting a flag from args
10
13
  */
package/src/types.ts CHANGED
@@ -405,6 +405,27 @@ export interface CreditEstimateResult {
405
405
  readonly estimate: unknown;
406
406
  }
407
407
 
408
+ // SKU query results
409
+ export interface SkuParamsResult {
410
+ readonly params?: unknown;
411
+ }
412
+
413
+ export interface ProviderResult {
414
+ readonly provider?: unknown;
415
+ }
416
+
417
+ export interface ProvidersResult extends PaginatedResult {
418
+ readonly providers: readonly unknown[];
419
+ }
420
+
421
+ export interface SkuResult {
422
+ readonly sku?: unknown;
423
+ }
424
+
425
+ export interface SkusResult extends PaginatedResult {
426
+ readonly skus: readonly unknown[];
427
+ }
428
+
408
429
  /**
409
430
  * Union type of all query results for type-safe handling
410
431
  */
@@ -459,7 +480,12 @@ export type QueryResult =
459
480
  | CreditAddressResult
460
481
  | WithdrawableAmountResult
461
482
  | ProviderWithdrawableResult
462
- | CreditEstimateResult;
483
+ | CreditEstimateResult
484
+ | SkuParamsResult
485
+ | ProviderResult
486
+ | ProvidersResult
487
+ | SkuResult
488
+ | SkusResult;
463
489
 
464
490
  /**
465
491
  * Result from a Cosmos query