@manifest-network/manifest-mcp-core 0.14.0 → 0.15.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.
- package/dist/__test-utils__/mocks.d.ts +47 -2
- package/dist/__test-utils__/mocks.d.ts.map +1 -1
- package/dist/__test-utils__/mocks.js +53 -4
- package/dist/__test-utils__/mocks.js.map +1 -1
- package/dist/brands.d.ts +49 -0
- package/dist/brands.d.ts.map +1 -0
- package/dist/brands.js +55 -0
- package/dist/brands.js.map +1 -0
- package/dist/brands.test-d.d.ts +1 -0
- package/dist/brands.test-d.js +30 -0
- package/dist/brands.test-d.js.map +1 -0
- package/dist/client-factory.d.ts +83 -0
- package/dist/client-factory.d.ts.map +1 -0
- package/dist/client-factory.js +92 -0
- package/dist/client-factory.js.map +1 -0
- package/dist/client-factory.test-d.d.ts +1 -0
- package/dist/client-factory.test-d.js +52 -0
- package/dist/client-factory.test-d.js.map +1 -0
- package/dist/client-full.d.ts +42 -0
- package/dist/client-full.d.ts.map +1 -0
- package/dist/client-full.js +30 -0
- package/dist/client-full.js.map +1 -0
- package/dist/client.d.ts +23 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +35 -3
- package/dist/client.js.map +1 -1
- package/dist/cosmos.d.ts +5 -1
- package/dist/cosmos.d.ts.map +1 -1
- package/dist/cosmos.js +35 -18
- package/dist/cosmos.js.map +1 -1
- package/dist/ctx.d.ts +50 -0
- package/dist/ctx.d.ts.map +1 -0
- package/dist/ctx.js +0 -0
- package/dist/ctx.test-d.d.ts +1 -0
- package/dist/ctx.test-d.js +40 -0
- package/dist/ctx.test-d.js.map +1 -0
- package/dist/index.d.ts +18 -10
- package/dist/index.js +15 -10
- package/dist/internals/read-signal.d.ts +17 -0
- package/dist/internals/read-signal.d.ts.map +1 -0
- package/dist/internals/read-signal.js +32 -0
- package/dist/internals/read-signal.js.map +1 -0
- package/dist/internals/tx-confirmation.d.ts +21 -0
- package/dist/internals/tx-confirmation.d.ts.map +1 -0
- package/dist/internals/tx-confirmation.js +50 -0
- package/dist/internals/tx-confirmation.js.map +1 -0
- package/dist/internals/tx-opts.d.ts +13 -0
- package/dist/internals/tx-opts.d.ts.map +1 -0
- package/dist/internals/tx-opts.js +14 -0
- package/dist/internals/tx-opts.js.map +1 -0
- package/dist/lcd-adapter.d.ts +3 -2
- package/dist/lcd-adapter.d.ts.map +1 -1
- package/dist/lcd-adapter.js +5 -5
- package/dist/lcd-adapter.js.map +1 -1
- package/dist/logger.d.ts +17 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +8 -1
- package/dist/logger.js.map +1 -1
- package/dist/manifest-types.d.ts +237 -0
- package/dist/manifest-types.d.ts.map +1 -0
- package/dist/manifest-types.js +0 -0
- package/dist/manifest-types.test-d.d.ts +1 -0
- package/dist/manifest-types.test-d.js +61 -0
- package/dist/manifest-types.test-d.js.map +1 -0
- package/dist/modules.d.ts +10 -2
- package/dist/modules.d.ts.map +1 -1
- package/dist/modules.js.map +1 -1
- package/dist/options.d.ts +32 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +19 -0
- package/dist/options.js.map +1 -0
- package/dist/queries/group.js +1 -1
- package/dist/queries/utils.d.ts +2 -1
- package/dist/queries/utils.d.ts.map +1 -1
- package/dist/queries/utils.js +2 -1
- package/dist/queries/utils.js.map +1 -1
- package/dist/reads.test-d.d.ts +1 -0
- package/dist/reads.test-d.js +14 -0
- package/dist/reads.test-d.js.map +1 -0
- package/dist/retry.d.ts.map +1 -1
- package/dist/retry.js +1 -0
- package/dist/retry.js.map +1 -1
- package/dist/server-utils.js +0 -1
- package/dist/server-utils.js.map +1 -1
- package/dist/signer.d.ts +36 -0
- package/dist/signer.d.ts.map +1 -0
- package/dist/signer.js +40 -0
- package/dist/signer.js.map +1 -0
- package/dist/sku-resolution.d.ts +10 -5
- package/dist/sku-resolution.d.ts.map +1 -1
- package/dist/sku-resolution.js +13 -11
- package/dist/sku-resolution.js.map +1 -1
- package/dist/tools/executeTx.d.ts +19 -0
- package/dist/tools/executeTx.d.ts.map +1 -0
- package/dist/tools/executeTx.js +50 -0
- package/dist/tools/executeTx.js.map +1 -0
- package/dist/tools/fundCredits.d.ts +10 -5
- package/dist/tools/fundCredits.d.ts.map +1 -1
- package/dist/tools/fundCredits.js +8 -5
- package/dist/tools/fundCredits.js.map +1 -1
- package/dist/tools/getBalance.d.ts +3 -2
- package/dist/tools/getBalance.d.ts.map +1 -1
- package/dist/tools/getBalance.js +6 -5
- package/dist/tools/getBalance.js.map +1 -1
- package/dist/tools/reads.d.ts +32 -0
- package/dist/tools/reads.d.ts.map +1 -0
- package/dist/tools/reads.js +76 -0
- package/dist/tools/reads.js.map +1 -0
- package/dist/tools/setItemCustomDomain.d.ts +39 -32
- package/dist/tools/setItemCustomDomain.d.ts.map +1 -1
- package/dist/tools/setItemCustomDomain.js +26 -26
- package/dist/tools/setItemCustomDomain.js.map +1 -1
- package/dist/tools/stopApp.d.ts +7 -4
- package/dist/tools/stopApp.d.ts.map +1 -1
- package/dist/tools/stopApp.js +5 -3
- package/dist/tools/stopApp.js.map +1 -1
- package/dist/transactions/authz.js +2 -1
- package/dist/transactions/authz.js.map +1 -1
- package/dist/transactions/bank.js +2 -1
- package/dist/transactions/bank.js.map +1 -1
- package/dist/transactions/billing.d.ts +5 -2
- package/dist/transactions/billing.d.ts.map +1 -1
- package/dist/transactions/billing.js +7 -5
- package/dist/transactions/billing.js.map +1 -1
- package/dist/transactions/distribution.js +2 -1
- package/dist/transactions/distribution.js.map +1 -1
- package/dist/transactions/feegrant.js +2 -1
- package/dist/transactions/feegrant.js.map +1 -1
- package/dist/transactions/group.js +3 -2
- package/dist/transactions/group.js.map +1 -1
- package/dist/transactions/ibc-transfer.js +2 -1
- package/dist/transactions/ibc-transfer.js.map +1 -1
- package/dist/transactions/manifest.js +2 -1
- package/dist/transactions/manifest.js.map +1 -1
- package/dist/transactions/poa.js +3 -2
- package/dist/transactions/poa.js.map +1 -1
- package/dist/transactions/sku.js +2 -1
- package/dist/transactions/sku.js.map +1 -1
- package/dist/transactions/staking.js +2 -1
- package/dist/transactions/staking.js.map +1 -1
- package/dist/transactions/tokenfactory.js +2 -1
- package/dist/transactions/tokenfactory.js.map +1 -1
- package/dist/transactions/utils.d.ts +9 -6
- package/dist/transactions/utils.d.ts.map +1 -1
- package/dist/transactions/utils.js +29 -16
- package/dist/transactions/utils.js.map +1 -1
- package/dist/transactions/wasm.js +3 -2
- package/dist/transactions/wasm.js.map +1 -1
- package/dist/txs.test-d.d.ts +1 -0
- package/dist/txs.test-d.js +23 -0
- package/dist/txs.test-d.js.map +1 -0
- package/dist/types.d.ts +12 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -1
- package/dist/validation.d.ts +17 -1
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +30 -3
- package/dist/validation.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +10 -9
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { noopLogger } from "../logger.js";
|
|
1
2
|
import { ManifestMCPConfig, WalletProvider } from "../types.js";
|
|
2
|
-
import { ManifestQueryClient } from "../client.js";
|
|
3
|
+
import { CosmosClientManager, ManifestQueryClient } from "../client.js";
|
|
4
|
+
import { Signer } from "../signer.js";
|
|
5
|
+
import { ReadCtx, TxCtx } from "../ctx.js";
|
|
3
6
|
import { LeaseState } from "@manifest-network/manifestjs/dist/codegen/liftedinit/billing/v1/types.js";
|
|
4
7
|
|
|
5
8
|
//#region src/__test-utils__/mocks.d.ts
|
|
@@ -57,6 +60,30 @@ interface BillingOverrides {
|
|
|
57
60
|
createdAt?: Date;
|
|
58
61
|
closedAt?: Date;
|
|
59
62
|
} | null;
|
|
63
|
+
billingParams?: {
|
|
64
|
+
maxLeasesPerTenant: bigint;
|
|
65
|
+
allowedList: string[];
|
|
66
|
+
maxItemsPerLease: bigint;
|
|
67
|
+
minLeaseDuration: bigint;
|
|
68
|
+
maxPendingLeasesPerTenant: bigint;
|
|
69
|
+
pendingTimeout: bigint;
|
|
70
|
+
reservedDomainSuffixes: string[];
|
|
71
|
+
};
|
|
72
|
+
withdrawableAmount?: {
|
|
73
|
+
denom: string;
|
|
74
|
+
amount: string;
|
|
75
|
+
}[];
|
|
76
|
+
leaseByCustomDomain?: {
|
|
77
|
+
lease: {
|
|
78
|
+
uuid: string;
|
|
79
|
+
tenant: string;
|
|
80
|
+
providerUuid: string;
|
|
81
|
+
items: unknown[];
|
|
82
|
+
state: LeaseState;
|
|
83
|
+
createdAt: Date;
|
|
84
|
+
};
|
|
85
|
+
serviceName: string;
|
|
86
|
+
};
|
|
60
87
|
activeLeases?: {
|
|
61
88
|
uuid: string;
|
|
62
89
|
providerUuid: string;
|
|
@@ -87,6 +114,7 @@ interface SkuOverrides {
|
|
|
87
114
|
providers?: {
|
|
88
115
|
uuid: string;
|
|
89
116
|
address: string;
|
|
117
|
+
payoutAddress?: string;
|
|
90
118
|
apiUrl: string;
|
|
91
119
|
active: boolean;
|
|
92
120
|
}[];
|
|
@@ -126,8 +154,25 @@ declare function makeMockClientManager(overrides?: {
|
|
|
126
154
|
getAddress: import("vitest").Mock<import("@vitest/spy").Procedure>;
|
|
127
155
|
getConfig: import("vitest").Mock<import("@vitest/spy").Procedure>;
|
|
128
156
|
acquireRateLimit: import("vitest").Mock<import("@vitest/spy").Procedure>;
|
|
157
|
+
withBroadcastLock: <T>(_address: string, fn: () => Promise<T>) => Promise<T>;
|
|
129
158
|
disconnect: import("vitest").Mock<import("@vitest/spy").Procedure>;
|
|
130
159
|
};
|
|
160
|
+
/** A ReadCtx for unit tests: a mock query client, a chain stub whose acquireRateLimit resolves, noopLogger. */
|
|
161
|
+
declare function makeReadCtx(overrides?: {
|
|
162
|
+
query?: ReturnType<typeof makeMockQueryClient>;
|
|
163
|
+
chain?: Partial<CosmosClientManager>;
|
|
164
|
+
logger?: typeof noopLogger;
|
|
165
|
+
}): ReadCtx;
|
|
166
|
+
/**
|
|
167
|
+
* A TxCtx for unit tests: a mock client manager whose getAddress/getSigningClient/acquireRateLimit
|
|
168
|
+
* back the tx path, noopLogger. `signer` defaults to undefined — 4c sender comes from `ctx.chain` and
|
|
169
|
+
* never reads `ctx.signer` (the field is plumbed so 4d's per-signer-mutex tests can populate it).
|
|
170
|
+
*/
|
|
171
|
+
declare function makeTxCtx(overrides?: {
|
|
172
|
+
chain?: Partial<CosmosClientManager>;
|
|
173
|
+
signer?: Signer;
|
|
174
|
+
logger?: typeof noopLogger;
|
|
175
|
+
}): TxCtx;
|
|
131
176
|
//#endregion
|
|
132
|
-
export { makeMockClientManager, makeMockConfig, makeMockQueryClient, makeMockWallet };
|
|
177
|
+
export { makeMockClientManager, makeMockConfig, makeMockQueryClient, makeMockWallet, makeReadCtx, makeTxCtx };
|
|
133
178
|
//# sourceMappingURL=mocks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mocks.d.ts","names":[],"sources":["../../src/__test-utils__/mocks.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"mocks.d.ts","names":[],"sources":["../../src/__test-utils__/mocks.ts"],"mappings":";;;;;;;;;;AAeA;iBAAgB,cAAA,CACd,SAAA,GAAY,OAAA,CAAQ,iBAAA,IACnB,iBAAA;;;;;iBAca,cAAA,CAAe,IAAA;EAC7B,aAAA;AAAA,IACE,cAAc;;;;UAiBR,gBAAA;EACR,QAAA;IAAa,KAAA;IAAe,MAAA;EAAA;EAC5B,aAAA;IACE,gBAAA;IACA,iBAAA;IACA,eAAA;MAAmB,KAAA;MAAe,MAAA;IAAA;EAAA;EAEpC,qBAAA;IAA0B,KAAA;IAAe,MAAA;EAAA;EACzC,8BAAA;IAAmC,KAAA;IAAe,MAAA;EAAA;EAClD,cAAA;IACE,cAAA;MAAkB,KAAA;MAAe,MAAA;IAAA;IACjC,kBAAA;MAAsB,KAAA;MAAe,MAAA;IAAA;IACrC,wBAAA;IACA,gBAAA;EAAA;EAEF,KAAA;IACE,IAAA;IACA,KAAA,EAAO,UAAA;IACP,YAAA;IACA,SAAA,GAAY,IAAA;IACZ,QAAA,GAAW,IAAA;EAAA;EAEb,aAAA;IACE,kBAAA;IACA,WAAA;IACA,gBAAA;IACA,gBAAA;IACA,yBAAA;IACA,cAAA;IACA,sBAAA;EAAA;EAEF,kBAAA;IAAuB,KAAA;IAAe,MAAA;EAAA;EACtC,mBAAA;IACE,KAAA;MACE,IAAA;MACA,MAAA;MACA,YAAA;MACA,KAAA;MACA,KAAA,EAAO,UAAA;MACP,SAAA,EAAW,IAAA;IAAA;IAEb,WAAA;EAAA;EAEF,YAAA;IAAiB,IAAA;IAAc,YAAA;IAAsB,SAAA,GAAY,IAAA;EAAA;EACjE,aAAA;IAAkB,IAAA;IAAc,YAAA;IAAsB,SAAA,GAAY,IAAA;EAAA;EAClE,YAAA;IAAiB,IAAA;IAAc,YAAA;IAAsB,SAAA,GAAY,IAAA;EAAA;EACjE,cAAA;IAAmB,IAAA;IAAc,YAAA;IAAsB,SAAA,GAAY,IAAA;EAAA;EACnE,aAAA;IAAkB,IAAA;IAAc,YAAA;IAAsB,SAAA,GAAY,IAAA;EAAA;AAAA;AAAA,UAG1D,YAAA;EACR,SAAA;IACE,IAAA;IACA,OAAA;IACA,aAAA;IACA,MAAA;IACA,MAAA;EAAA;EAEF,IAAA;IACE,IAAA;IACA,IAAA;IACA,YAAA;IACA,SAAA;MAAc,MAAA;MAAgB,KAAA;IAAA;IAC9B,MAAA;EAAA;EAEF,cAAA,GAAiB,MAAM;IAAW,QAAA;MAAY,MAAA;IAAA;EAAA;AAAA;;;;iBAMhC,mBAAA,CAAoB,SAAA;EAClC,OAAA,GAAU,gBAAA;EACV,GAAA,GAAM,YAAA;AAAA,IA6MU,mBAAA;;;;iBAMF,qBAAA,CAAsB,SAAA;EACpC,WAAA,GAAc,mBAAA;EACd,OAAA;EACA,MAAA,GAAS,iBAAA;AAAA;;;;;;yBAcc,QAAA,UACH,EAAA,QACN,OAAA,CAAQ,CAAA,MACjB,OAAA,CAAQ,CAAA;;;;iBAMC,WAAA,CAAY,SAAA;EAC1B,KAAA,GAAQ,UAAA,QAAkB,mBAAA;EAC1B,KAAA,GAAQ,OAAA,CAAQ,mBAAA;EAChB,MAAA,UAAgB,UAAA;AAAA,IACd,OAAA;;;;;AApCiC;iBAoDrB,SAAA,CAAU,SAAA;EACxB,KAAA,GAAQ,OAAA,CAAQ,mBAAA;EAChB,MAAA,GAAS,MAAA;EACT,MAAA,UAAgB,UAAA;AAAA,IACd,KAAA"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { noopLogger } from "../logger.js";
|
|
2
2
|
import { vi } from "vitest";
|
|
3
|
+
import { LeaseState } from "@manifest-network/manifestjs/dist/codegen/liftedinit/billing/v1/types.js";
|
|
3
4
|
//#region src/__test-utils__/mocks.ts
|
|
4
5
|
/**
|
|
5
6
|
* Create a mock ManifestMCPConfig with sensible defaults.
|
|
@@ -46,6 +47,27 @@ function makeMockQueryClient(overrides) {
|
|
|
46
47
|
const creditAccountAvailableBalances = billing.creditAccountAvailableBalances ?? [];
|
|
47
48
|
const creditEstimate = billing.creditEstimate ?? null;
|
|
48
49
|
const lease = billing.lease ?? null;
|
|
50
|
+
const billingParams = billing.billingParams ?? {
|
|
51
|
+
maxLeasesPerTenant: 10n,
|
|
52
|
+
allowedList: [],
|
|
53
|
+
maxItemsPerLease: 5n,
|
|
54
|
+
minLeaseDuration: 3600n,
|
|
55
|
+
maxPendingLeasesPerTenant: 10n,
|
|
56
|
+
pendingTimeout: 1800n,
|
|
57
|
+
reservedDomainSuffixes: []
|
|
58
|
+
};
|
|
59
|
+
const withdrawableAmount = billing.withdrawableAmount ?? [];
|
|
60
|
+
const leaseByCustomDomain = billing.leaseByCustomDomain ?? {
|
|
61
|
+
lease: {
|
|
62
|
+
uuid: "lease-uuid-1",
|
|
63
|
+
tenant: "manifest1tenant",
|
|
64
|
+
providerUuid: "provider-uuid-1",
|
|
65
|
+
items: [],
|
|
66
|
+
state: LeaseState.LEASE_STATE_ACTIVE,
|
|
67
|
+
createdAt: /* @__PURE__ */ new Date(0)
|
|
68
|
+
},
|
|
69
|
+
serviceName: "web"
|
|
70
|
+
};
|
|
49
71
|
const activeLeases = billing.activeLeases ?? [];
|
|
50
72
|
const pendingLeases = billing.pendingLeases ?? [];
|
|
51
73
|
const closedLeases = billing.closedLeases ?? [];
|
|
@@ -162,10 +184,16 @@ function makeMockQueryClient(overrides) {
|
|
|
162
184
|
...l
|
|
163
185
|
})) };
|
|
164
186
|
return { leases: [] };
|
|
165
|
-
})
|
|
187
|
+
}),
|
|
188
|
+
params: vi.fn().mockResolvedValue({ params: billingParams }),
|
|
189
|
+
withdrawableAmount: vi.fn().mockResolvedValue({ amounts: withdrawableAmount }),
|
|
190
|
+
leaseByCustomDomain: vi.fn().mockResolvedValue(leaseByCustomDomain)
|
|
166
191
|
} },
|
|
167
192
|
sku: { v1: {
|
|
168
|
-
providers: vi.fn().mockResolvedValue({ providers
|
|
193
|
+
providers: vi.fn().mockResolvedValue({ providers: providers.map((p) => ({
|
|
194
|
+
payoutAddress: "manifest1payout",
|
|
195
|
+
...p
|
|
196
|
+
})) }),
|
|
169
197
|
sKUs: vi.fn().mockResolvedValue({ skus: skus.map((s) => ({
|
|
170
198
|
active: true,
|
|
171
199
|
...s
|
|
@@ -191,10 +219,31 @@ function makeMockClientManager(overrides) {
|
|
|
191
219
|
getAddress: vi.fn().mockResolvedValue(address),
|
|
192
220
|
getConfig: vi.fn().mockReturnValue(config),
|
|
193
221
|
acquireRateLimit: vi.fn().mockResolvedValue(void 0),
|
|
222
|
+
withBroadcastLock: (_address, fn) => fn(),
|
|
194
223
|
disconnect: vi.fn()
|
|
195
224
|
};
|
|
196
225
|
}
|
|
226
|
+
/** A ReadCtx for unit tests: a mock query client, a chain stub whose acquireRateLimit resolves, noopLogger. */
|
|
227
|
+
function makeReadCtx(overrides) {
|
|
228
|
+
return {
|
|
229
|
+
query: overrides?.query ?? makeMockQueryClient(),
|
|
230
|
+
chain: overrides?.chain ?? { acquireRateLimit: async () => {} },
|
|
231
|
+
logger: overrides?.logger ?? noopLogger
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* A TxCtx for unit tests: a mock client manager whose getAddress/getSigningClient/acquireRateLimit
|
|
236
|
+
* back the tx path, noopLogger. `signer` defaults to undefined — 4c sender comes from `ctx.chain` and
|
|
237
|
+
* never reads `ctx.signer` (the field is plumbed so 4d's per-signer-mutex tests can populate it).
|
|
238
|
+
*/
|
|
239
|
+
function makeTxCtx(overrides) {
|
|
240
|
+
return {
|
|
241
|
+
chain: overrides?.chain ?? makeMockClientManager(),
|
|
242
|
+
signer: overrides?.signer,
|
|
243
|
+
logger: overrides?.logger ?? noopLogger
|
|
244
|
+
};
|
|
245
|
+
}
|
|
197
246
|
//#endregion
|
|
198
|
-
export { makeMockClientManager, makeMockConfig, makeMockQueryClient, makeMockWallet };
|
|
247
|
+
export { makeMockClientManager, makeMockConfig, makeMockQueryClient, makeMockWallet, makeReadCtx, makeTxCtx };
|
|
199
248
|
|
|
200
249
|
//# sourceMappingURL=mocks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mocks.js","names":[],"sources":["../../src/__test-utils__/mocks.ts"],"sourcesContent":["import { LeaseState } from '@manifest-network/manifestjs/dist/codegen/liftedinit/billing/v1/types.js';\nimport { vi } from 'vitest';\nimport type { ManifestQueryClient } from '../client.js';\nimport type {\n ManifestMCPConfig,\n SignArbitraryResult,\n WalletProvider,\n} from '../types.js';\n\n/**\n * Create a mock ManifestMCPConfig with sensible defaults.\n */\nexport function makeMockConfig(\n overrides?: Partial<ManifestMCPConfig>,\n): ManifestMCPConfig {\n return {\n chainId: 'test-chain',\n rpcUrl: 'https://rpc.example.com',\n gasPrice: '1.0umfx',\n addressPrefix: 'manifest',\n ...overrides,\n };\n}\n\n/**\n * Create a mock WalletProvider.\n * Pass `signArbitrary: true` to include a signArbitrary stub.\n */\nexport function makeMockWallet(opts?: {\n signArbitrary?: boolean;\n}): WalletProvider {\n const wallet: WalletProvider = {\n getAddress: vi.fn().mockResolvedValue('manifest1abc'),\n getSigner: vi.fn().mockResolvedValue({}),\n };\n if (opts?.signArbitrary) {\n wallet.signArbitrary = vi.fn().mockResolvedValue({\n pub_key: { type: 'tendermint/PubKeySecp256k1', value: 'mockPubKey' },\n signature: 'mockSignature',\n } satisfies SignArbitraryResult);\n }\n return wallet;\n}\n\n/**\n * Billing mock data defaults\n */\ninterface BillingOverrides {\n balances?: { denom: string; amount: string }[];\n creditAccount?: {\n activeLeaseCount: bigint;\n pendingLeaseCount: bigint;\n reservedAmounts: { denom: string; amount: string }[];\n } | null;\n creditAccountBalances?: { denom: string; amount: string }[];\n creditAccountAvailableBalances?: { denom: string; amount: string }[];\n creditEstimate?: {\n currentBalance: { denom: string; amount: string }[];\n totalRatePerSecond: { denom: string; amount: string }[];\n estimatedDurationSeconds: bigint;\n activeLeaseCount: bigint;\n } | null;\n lease?: {\n uuid: string;\n state: LeaseState;\n providerUuid: string;\n createdAt?: Date;\n closedAt?: Date;\n } | null;\n activeLeases?: { uuid: string; providerUuid: string; createdAt?: Date }[];\n pendingLeases?: { uuid: string; providerUuid: string; createdAt?: Date }[];\n closedLeases?: { uuid: string; providerUuid: string; createdAt?: Date }[];\n rejectedLeases?: { uuid: string; providerUuid: string; createdAt?: Date }[];\n expiredLeases?: { uuid: string; providerUuid: string; createdAt?: Date }[];\n}\n\ninterface SkuOverrides {\n providers?: {\n uuid: string;\n address: string;\n apiUrl: string;\n active: boolean;\n }[];\n skus?: {\n uuid?: string;\n name: string;\n providerUuid: string;\n basePrice?: { amount: string; denom: string };\n active?: boolean;\n }[];\n providerLookup?: Record<string, { provider: { apiUrl: string } }>;\n}\n\n/**\n * Create a mock ManifestQueryClient with configurable billing, bank, and SKU data.\n */\nexport function makeMockQueryClient(overrides?: {\n billing?: BillingOverrides;\n sku?: SkuOverrides;\n}) {\n const billing = overrides?.billing ?? {};\n const sku = overrides?.sku ?? {};\n\n const balances = billing.balances ?? [{ denom: 'umfx', amount: '1000000' }];\n const creditAccount = billing.creditAccount ?? null;\n const creditAccountBalances = billing.creditAccountBalances ?? [];\n const creditAccountAvailableBalances =\n billing.creditAccountAvailableBalances ?? [];\n const creditEstimate = billing.creditEstimate ?? null;\n const lease = billing.lease ?? null;\n const activeLeases = billing.activeLeases ?? [];\n const pendingLeases = billing.pendingLeases ?? [];\n const closedLeases = billing.closedLeases ?? [];\n const rejectedLeases = billing.rejectedLeases ?? [];\n const expiredLeases = billing.expiredLeases ?? [];\n\n const providers = sku.providers ?? [];\n const skus = sku.skus ?? [];\n const providerLookup = sku.providerLookup ?? {};\n\n return {\n cosmos: {\n bank: {\n v1beta1: {\n allBalances: vi.fn().mockResolvedValue({ balances }),\n },\n },\n },\n cosmwasm: {\n wasm: {\n v1: {\n contractInfo: vi.fn().mockResolvedValue({}),\n contractHistory: vi\n .fn()\n .mockResolvedValue({ entries: [], pagination: null }),\n contractsByCode: vi\n .fn()\n .mockResolvedValue({ contracts: [], pagination: null }),\n allContractState: vi\n .fn()\n .mockResolvedValue({ models: [], pagination: null }),\n rawContractState: vi\n .fn()\n .mockResolvedValue({ data: new Uint8Array() }),\n smartContractState: vi\n .fn()\n .mockResolvedValue({ data: new Uint8Array() }),\n code: vi\n .fn()\n .mockResolvedValue({ codeInfo: null, data: new Uint8Array() }),\n codes: vi.fn().mockResolvedValue({ codeInfos: [], pagination: null }),\n codeInfo: vi.fn().mockResolvedValue({\n codeId: BigInt(0),\n creator: '',\n checksum: new Uint8Array(),\n instantiatePermission: { permission: 0, addresses: [] },\n }),\n pinnedCodes: vi\n .fn()\n .mockResolvedValue({ codeIds: [], pagination: null }),\n params: vi.fn().mockResolvedValue({ params: null }),\n contractsByCreator: vi\n .fn()\n .mockResolvedValue({ contractAddresses: [], pagination: null }),\n wasmLimitsConfig: vi.fn().mockResolvedValue({ config: '{}' }),\n buildAddress: vi.fn().mockResolvedValue({ address: '' }),\n },\n },\n },\n liftedinit: {\n billing: {\n v1: {\n creditAccount: vi.fn().mockImplementation(async () => {\n if (creditAccount === null) throw new Error('key not found');\n return {\n creditAccount,\n balances: creditAccountBalances,\n availableBalances: creditAccountAvailableBalances,\n };\n }),\n creditEstimate: vi.fn().mockImplementation(async () => {\n if (creditEstimate === null) throw new Error('credit not found');\n return creditEstimate;\n }),\n lease: vi.fn().mockImplementation(async () => {\n return { lease };\n }),\n leasesByTenant: vi\n .fn()\n .mockImplementation(\n async ({ stateFilter }: { stateFilter: LeaseState }) => {\n if (stateFilter === LeaseState.LEASE_STATE_UNSPECIFIED) {\n return {\n leases: [\n ...activeLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_ACTIVE,\n ...l,\n })),\n ...pendingLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_PENDING,\n ...l,\n })),\n ...closedLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_CLOSED,\n ...l,\n })),\n ...rejectedLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_REJECTED,\n ...l,\n })),\n ...expiredLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_EXPIRED,\n ...l,\n })),\n ],\n };\n }\n if (stateFilter === LeaseState.LEASE_STATE_ACTIVE)\n return {\n leases: activeLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_ACTIVE,\n ...l,\n })),\n };\n if (stateFilter === LeaseState.LEASE_STATE_PENDING)\n return {\n leases: pendingLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_PENDING,\n ...l,\n })),\n };\n if (stateFilter === LeaseState.LEASE_STATE_CLOSED)\n return {\n leases: closedLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_CLOSED,\n ...l,\n })),\n };\n if (stateFilter === LeaseState.LEASE_STATE_REJECTED)\n return {\n leases: rejectedLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_REJECTED,\n ...l,\n })),\n };\n if (stateFilter === LeaseState.LEASE_STATE_EXPIRED)\n return {\n leases: expiredLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_EXPIRED,\n ...l,\n })),\n };\n return { leases: [] };\n },\n ),\n },\n },\n sku: {\n v1: {\n providers: vi.fn().mockResolvedValue({ providers }),\n sKUs: vi.fn().mockResolvedValue({\n skus: skus.map((s) => ({ active: true, ...s })),\n }),\n provider: vi\n .fn()\n .mockImplementation(async ({ uuid }: { uuid: string }) => {\n if (providerLookup[uuid]) return providerLookup[uuid];\n throw new Error(`provider ${uuid} not found`);\n }),\n },\n },\n },\n } as unknown as ManifestQueryClient;\n}\n\n/**\n * Create a mock CosmosClientManager.\n */\nexport function makeMockClientManager(overrides?: {\n queryClient?: ManifestQueryClient;\n address?: string;\n config?: ManifestMCPConfig;\n}) {\n const queryClient = overrides?.queryClient ?? makeMockQueryClient();\n const address = overrides?.address ?? 'manifest1abc';\n const config = overrides?.config ?? makeMockConfig();\n\n return {\n getQueryClient: vi.fn().mockResolvedValue(queryClient),\n getSigningClient: vi.fn().mockResolvedValue({}),\n getAddress: vi.fn().mockResolvedValue(address),\n getConfig: vi.fn().mockReturnValue(config),\n acquireRateLimit: vi.fn().mockResolvedValue(undefined),\n disconnect: vi.fn(),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mocks.js","names":[],"sources":["../../src/__test-utils__/mocks.ts"],"sourcesContent":["import { LeaseState } from '@manifest-network/manifestjs/dist/codegen/liftedinit/billing/v1/types.js';\nimport { vi } from 'vitest';\nimport type { CosmosClientManager, ManifestQueryClient } from '../client.js';\nimport type { ReadCtx, TxCtx } from '../ctx.js';\nimport { noopLogger } from '../logger.js';\nimport type { Signer } from '../signer.js';\nimport type {\n ManifestMCPConfig,\n SignArbitraryResult,\n WalletProvider,\n} from '../types.js';\n\n/**\n * Create a mock ManifestMCPConfig with sensible defaults.\n */\nexport function makeMockConfig(\n overrides?: Partial<ManifestMCPConfig>,\n): ManifestMCPConfig {\n return {\n chainId: 'test-chain',\n rpcUrl: 'https://rpc.example.com',\n gasPrice: '1.0umfx',\n addressPrefix: 'manifest',\n ...overrides,\n };\n}\n\n/**\n * Create a mock WalletProvider.\n * Pass `signArbitrary: true` to include a signArbitrary stub.\n */\nexport function makeMockWallet(opts?: {\n signArbitrary?: boolean;\n}): WalletProvider {\n const wallet: WalletProvider = {\n getAddress: vi.fn().mockResolvedValue('manifest1abc'),\n getSigner: vi.fn().mockResolvedValue({}),\n };\n if (opts?.signArbitrary) {\n wallet.signArbitrary = vi.fn().mockResolvedValue({\n pub_key: { type: 'tendermint/PubKeySecp256k1', value: 'mockPubKey' },\n signature: 'mockSignature',\n } satisfies SignArbitraryResult);\n }\n return wallet;\n}\n\n/**\n * Billing mock data defaults\n */\ninterface BillingOverrides {\n balances?: { denom: string; amount: string }[];\n creditAccount?: {\n activeLeaseCount: bigint;\n pendingLeaseCount: bigint;\n reservedAmounts: { denom: string; amount: string }[];\n } | null;\n creditAccountBalances?: { denom: string; amount: string }[];\n creditAccountAvailableBalances?: { denom: string; amount: string }[];\n creditEstimate?: {\n currentBalance: { denom: string; amount: string }[];\n totalRatePerSecond: { denom: string; amount: string }[];\n estimatedDurationSeconds: bigint;\n activeLeaseCount: bigint;\n } | null;\n lease?: {\n uuid: string;\n state: LeaseState;\n providerUuid: string;\n createdAt?: Date;\n closedAt?: Date;\n } | null;\n billingParams?: {\n maxLeasesPerTenant: bigint;\n allowedList: string[];\n maxItemsPerLease: bigint;\n minLeaseDuration: bigint;\n maxPendingLeasesPerTenant: bigint;\n pendingTimeout: bigint;\n reservedDomainSuffixes: string[];\n };\n withdrawableAmount?: { denom: string; amount: string }[];\n leaseByCustomDomain?: {\n lease: {\n uuid: string;\n tenant: string;\n providerUuid: string;\n items: unknown[];\n state: LeaseState;\n createdAt: Date;\n };\n serviceName: string;\n };\n activeLeases?: { uuid: string; providerUuid: string; createdAt?: Date }[];\n pendingLeases?: { uuid: string; providerUuid: string; createdAt?: Date }[];\n closedLeases?: { uuid: string; providerUuid: string; createdAt?: Date }[];\n rejectedLeases?: { uuid: string; providerUuid: string; createdAt?: Date }[];\n expiredLeases?: { uuid: string; providerUuid: string; createdAt?: Date }[];\n}\n\ninterface SkuOverrides {\n providers?: {\n uuid: string;\n address: string;\n payoutAddress?: string;\n apiUrl: string;\n active: boolean;\n }[];\n skus?: {\n uuid?: string;\n name: string;\n providerUuid: string;\n basePrice?: { amount: string; denom: string };\n active?: boolean;\n }[];\n providerLookup?: Record<string, { provider: { apiUrl: string } }>;\n}\n\n/**\n * Create a mock ManifestQueryClient with configurable billing, bank, and SKU data.\n */\nexport function makeMockQueryClient(overrides?: {\n billing?: BillingOverrides;\n sku?: SkuOverrides;\n}) {\n const billing = overrides?.billing ?? {};\n const sku = overrides?.sku ?? {};\n\n const balances = billing.balances ?? [{ denom: 'umfx', amount: '1000000' }];\n const creditAccount = billing.creditAccount ?? null;\n const creditAccountBalances = billing.creditAccountBalances ?? [];\n const creditAccountAvailableBalances =\n billing.creditAccountAvailableBalances ?? [];\n const creditEstimate = billing.creditEstimate ?? null;\n const lease = billing.lease ?? null;\n const billingParams = billing.billingParams ?? {\n maxLeasesPerTenant: 10n,\n allowedList: [],\n maxItemsPerLease: 5n,\n minLeaseDuration: 3600n,\n maxPendingLeasesPerTenant: 10n,\n pendingTimeout: 1800n,\n reservedDomainSuffixes: [],\n };\n const withdrawableAmount = billing.withdrawableAmount ?? [];\n const leaseByCustomDomain = billing.leaseByCustomDomain ?? {\n lease: {\n uuid: 'lease-uuid-1',\n tenant: 'manifest1tenant',\n providerUuid: 'provider-uuid-1',\n items: [],\n state: LeaseState.LEASE_STATE_ACTIVE,\n createdAt: new Date(0),\n },\n serviceName: 'web',\n };\n const activeLeases = billing.activeLeases ?? [];\n const pendingLeases = billing.pendingLeases ?? [];\n const closedLeases = billing.closedLeases ?? [];\n const rejectedLeases = billing.rejectedLeases ?? [];\n const expiredLeases = billing.expiredLeases ?? [];\n\n const providers = sku.providers ?? [];\n const skus = sku.skus ?? [];\n const providerLookup = sku.providerLookup ?? {};\n\n return {\n cosmos: {\n bank: {\n v1beta1: {\n allBalances: vi.fn().mockResolvedValue({ balances }),\n },\n },\n },\n cosmwasm: {\n wasm: {\n v1: {\n contractInfo: vi.fn().mockResolvedValue({}),\n contractHistory: vi\n .fn()\n .mockResolvedValue({ entries: [], pagination: null }),\n contractsByCode: vi\n .fn()\n .mockResolvedValue({ contracts: [], pagination: null }),\n allContractState: vi\n .fn()\n .mockResolvedValue({ models: [], pagination: null }),\n rawContractState: vi\n .fn()\n .mockResolvedValue({ data: new Uint8Array() }),\n smartContractState: vi\n .fn()\n .mockResolvedValue({ data: new Uint8Array() }),\n code: vi\n .fn()\n .mockResolvedValue({ codeInfo: null, data: new Uint8Array() }),\n codes: vi.fn().mockResolvedValue({ codeInfos: [], pagination: null }),\n codeInfo: vi.fn().mockResolvedValue({\n codeId: BigInt(0),\n creator: '',\n checksum: new Uint8Array(),\n instantiatePermission: { permission: 0, addresses: [] },\n }),\n pinnedCodes: vi\n .fn()\n .mockResolvedValue({ codeIds: [], pagination: null }),\n params: vi.fn().mockResolvedValue({ params: null }),\n contractsByCreator: vi\n .fn()\n .mockResolvedValue({ contractAddresses: [], pagination: null }),\n wasmLimitsConfig: vi.fn().mockResolvedValue({ config: '{}' }),\n buildAddress: vi.fn().mockResolvedValue({ address: '' }),\n },\n },\n },\n liftedinit: {\n billing: {\n v1: {\n creditAccount: vi.fn().mockImplementation(async () => {\n if (creditAccount === null) throw new Error('key not found');\n return {\n creditAccount,\n balances: creditAccountBalances,\n availableBalances: creditAccountAvailableBalances,\n };\n }),\n creditEstimate: vi.fn().mockImplementation(async () => {\n if (creditEstimate === null) throw new Error('credit not found');\n return creditEstimate;\n }),\n lease: vi.fn().mockImplementation(async () => {\n return { lease };\n }),\n leasesByTenant: vi\n .fn()\n .mockImplementation(\n async ({ stateFilter }: { stateFilter: LeaseState }) => {\n if (stateFilter === LeaseState.LEASE_STATE_UNSPECIFIED) {\n return {\n leases: [\n ...activeLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_ACTIVE,\n ...l,\n })),\n ...pendingLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_PENDING,\n ...l,\n })),\n ...closedLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_CLOSED,\n ...l,\n })),\n ...rejectedLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_REJECTED,\n ...l,\n })),\n ...expiredLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_EXPIRED,\n ...l,\n })),\n ],\n };\n }\n if (stateFilter === LeaseState.LEASE_STATE_ACTIVE)\n return {\n leases: activeLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_ACTIVE,\n ...l,\n })),\n };\n if (stateFilter === LeaseState.LEASE_STATE_PENDING)\n return {\n leases: pendingLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_PENDING,\n ...l,\n })),\n };\n if (stateFilter === LeaseState.LEASE_STATE_CLOSED)\n return {\n leases: closedLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_CLOSED,\n ...l,\n })),\n };\n if (stateFilter === LeaseState.LEASE_STATE_REJECTED)\n return {\n leases: rejectedLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_REJECTED,\n ...l,\n })),\n };\n if (stateFilter === LeaseState.LEASE_STATE_EXPIRED)\n return {\n leases: expiredLeases.map((l) => ({\n state: LeaseState.LEASE_STATE_EXPIRED,\n ...l,\n })),\n };\n return { leases: [] };\n },\n ),\n params: vi.fn().mockResolvedValue({ params: billingParams }),\n withdrawableAmount: vi\n .fn()\n .mockResolvedValue({ amounts: withdrawableAmount }),\n leaseByCustomDomain: vi.fn().mockResolvedValue(leaseByCustomDomain),\n },\n },\n sku: {\n v1: {\n providers: vi.fn().mockResolvedValue({\n providers: providers.map((p) => ({\n payoutAddress: 'manifest1payout',\n ...p,\n })),\n }),\n sKUs: vi.fn().mockResolvedValue({\n skus: skus.map((s) => ({ active: true, ...s })),\n }),\n provider: vi\n .fn()\n .mockImplementation(async ({ uuid }: { uuid: string }) => {\n if (providerLookup[uuid]) return providerLookup[uuid];\n throw new Error(`provider ${uuid} not found`);\n }),\n },\n },\n },\n } as unknown as ManifestQueryClient;\n}\n\n/**\n * Create a mock CosmosClientManager.\n */\nexport function makeMockClientManager(overrides?: {\n queryClient?: ManifestQueryClient;\n address?: string;\n config?: ManifestMCPConfig;\n}) {\n const queryClient = overrides?.queryClient ?? makeMockQueryClient();\n const address = overrides?.address ?? 'manifest1abc';\n const config = overrides?.config ?? makeMockConfig();\n\n return {\n getQueryClient: vi.fn().mockResolvedValue(queryClient),\n getSigningClient: vi.fn().mockResolvedValue({}),\n getAddress: vi.fn().mockResolvedValue(address),\n getConfig: vi.fn().mockReturnValue(config),\n acquireRateLimit: vi.fn().mockResolvedValue(undefined),\n // Passthrough is enough for the non-concurrency tests; the serialization test overrides this with\n // the REAL promise-chain (or uses a real CosmosClientManager) to genuinely prove serialization.\n withBroadcastLock: <T>(\n _address: string,\n fn: () => Promise<T>,\n ): Promise<T> => fn(),\n disconnect: vi.fn(),\n };\n}\n\n/** A ReadCtx for unit tests: a mock query client, a chain stub whose acquireRateLimit resolves, noopLogger. */\nexport function makeReadCtx(overrides?: {\n query?: ReturnType<typeof makeMockQueryClient>;\n chain?: Partial<CosmosClientManager>;\n logger?: typeof noopLogger;\n}): ReadCtx {\n return {\n query: overrides?.query ?? makeMockQueryClient(),\n chain: (overrides?.chain ??\n ({\n acquireRateLimit: async () => {},\n } as unknown as CosmosClientManager)) as CosmosClientManager,\n logger: overrides?.logger ?? noopLogger,\n } as ReadCtx;\n}\n\n/**\n * A TxCtx for unit tests: a mock client manager whose getAddress/getSigningClient/acquireRateLimit\n * back the tx path, noopLogger. `signer` defaults to undefined — 4c sender comes from `ctx.chain` and\n * never reads `ctx.signer` (the field is plumbed so 4d's per-signer-mutex tests can populate it).\n */\nexport function makeTxCtx(overrides?: {\n chain?: Partial<CosmosClientManager>;\n signer?: Signer;\n logger?: typeof noopLogger;\n}): TxCtx {\n return {\n chain: (overrides?.chain ?? makeMockClientManager()) as CosmosClientManager,\n signer: overrides?.signer,\n logger: overrides?.logger ?? noopLogger,\n } as TxCtx;\n}\n"],"mappings":"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"}
|
package/dist/brands.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//#region src/brands.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Nominal brand. STRING tag key (not a `unique symbol`) ON PURPOSE: a unique-symbol brand is
|
|
4
|
+
* non-assignable across DUPLICATED package copies (each copy mints a distinct symbol), breaking
|
|
5
|
+
* the incremental cross-copy adoption this monorepo needs (the worktree/dep-drift hazard in
|
|
6
|
+
* CLAUDE.md). Never exported. A brand is structurally `string`: assignable TO string, not FROM it.
|
|
7
|
+
*
|
|
8
|
+
* TWO sanctioned producer families, one per boundary trust-model (spec §5.0):
|
|
9
|
+
* - parse* — VALIDATE + brand at the UNTRUSTED boundary (stringly/MCP input, provider HTTP,
|
|
10
|
+
* wallet-in). Throwing, type-narrowing. Each `as Brand` cast here is preceded by a
|
|
11
|
+
* throwing validator on all paths.
|
|
12
|
+
* - as* — TRUST-CAST at the TRUSTED boundary (chain/codegen reads, already-resolved ids).
|
|
13
|
+
* Brands WITHOUT validation and NEVER throws — the chain is the source of truth, and
|
|
14
|
+
* re-validating would both waste work and throw on non-canonical ids (ENG-258 parse-once).
|
|
15
|
+
* BOTH families confine the lone `as Brand` cast to this file (§8).
|
|
16
|
+
*/
|
|
17
|
+
type Brand<T, B extends string> = T & {
|
|
18
|
+
readonly __brand: B;
|
|
19
|
+
};
|
|
20
|
+
type Address = Brand<string, 'Address'>;
|
|
21
|
+
/** A tenant IS an address — intentional transparent alias (branding does not distinguish them). */
|
|
22
|
+
type Tenant = Address;
|
|
23
|
+
type LeaseUuid = Brand<string, 'LeaseUuid'>;
|
|
24
|
+
type ProviderUuid = Brand<string, 'ProviderUuid'>;
|
|
25
|
+
type SkuUuid = Brand<string, 'SkuUuid'>;
|
|
26
|
+
type Fqdn = Brand<string, 'Fqdn'>;
|
|
27
|
+
/**
|
|
28
|
+
* Validate a bech32 address and brand it. With no `expectedPrefix` this validates bech32
|
|
29
|
+
* STRUCTURE only and does NOT pin the chain prefix — callers needing chain affinity (e.g. the
|
|
30
|
+
* Signer adapter) pass the configured `addressPrefix`.
|
|
31
|
+
*/
|
|
32
|
+
declare function parseAddress(value: string, expectedPrefix?: string): Address;
|
|
33
|
+
declare function parseLeaseUuid(value: string): LeaseUuid;
|
|
34
|
+
declare function parseProviderUuid(value: string): ProviderUuid;
|
|
35
|
+
declare function parseSkuUuid(value: string): SkuUuid;
|
|
36
|
+
declare function asLeaseUuid(value: string): LeaseUuid;
|
|
37
|
+
declare function asProviderUuid(value: string): ProviderUuid;
|
|
38
|
+
declare function asSkuUuid(value: string): SkuUuid;
|
|
39
|
+
declare function asAddress(value: string): Address;
|
|
40
|
+
declare function asFqdn(value: string): Fqdn;
|
|
41
|
+
/**
|
|
42
|
+
* Normalize (RFC 4343: DNS is case-insensitive) and validate a custom domain. Rejects scheme
|
|
43
|
+
* prefixes and IPv4 literals (FQDN_RE has a letter-led top-level label). The chain remains the
|
|
44
|
+
* authoritative validator (reserved suffixes, etc.).
|
|
45
|
+
*/
|
|
46
|
+
declare function parseFqdn(value: string): Fqdn;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { Address, Fqdn, LeaseUuid, ProviderUuid, SkuUuid, Tenant, asAddress, asFqdn, asLeaseUuid, asProviderUuid, asSkuUuid, parseAddress, parseFqdn, parseLeaseUuid, parseProviderUuid, parseSkuUuid };
|
|
49
|
+
//# sourceMappingURL=brands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brands.d.ts","names":[],"sources":["../src/brands.ts"],"mappings":";;;;;;;;;;;;AAuB2D;AAE3D;;;KAFK,KAAA,wBAA6B,CAAA;EAAA,SAAe,OAAA,EAAS,CAAC;AAAA;AAAA,KAE/C,OAAA,GAAU,KAAK;;KAEf,MAAA,GAAS,OAAO;AAAA,KAChB,SAAA,GAAY,KAAK;AAAA,KACjB,YAAA,GAAe,KAAK;AAAA,KACpB,OAAA,GAAU,KAAK;AAAA,KACf,IAAA,GAAO,KAAK;;AAHK;AAC7B;;;iBAiBgB,YAAA,CAAa,KAAA,UAAe,cAAA,YAA0B,OAAO;AAAA,iBAK7D,cAAA,CAAe,KAAA,WAAgB,SAAS;AAAA,iBAIxC,iBAAA,CAAkB,KAAA,WAAgB,YAAY;AAAA,iBAI9C,YAAA,CAAa,KAAA,WAAgB,OAAO;AAAA,iBAMpC,WAAA,CAAY,KAAA,WAAgB,SAAS;AAAA,iBAGrC,cAAA,CAAe,KAAA,WAAgB,YAAY;AAAA,iBAG3C,SAAA,CAAU,KAAA,WAAgB,OAAO;AAAA,iBAGjC,SAAA,CAAU,KAAA,WAAgB,OAAO;AAAA,iBAKjC,MAAA,CAAO,KAAA,WAAgB,IAAI;;;AAhDnB;AAexB;;iBA0CgB,SAAA,CAAU,KAAA,WAAgB,IAAI"}
|
package/dist/brands.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ManifestMCPError } from "./types.js";
|
|
2
|
+
import { FQDN_RE, SCHEME_PREFIX_RE, assertUuid, validateAddress } from "./validation.js";
|
|
3
|
+
//#region src/brands.ts
|
|
4
|
+
const ARG = "INVALID_ARGUMENT";
|
|
5
|
+
/**
|
|
6
|
+
* Validate a bech32 address and brand it. With no `expectedPrefix` this validates bech32
|
|
7
|
+
* STRUCTURE only and does NOT pin the chain prefix — callers needing chain affinity (e.g. the
|
|
8
|
+
* Signer adapter) pass the configured `addressPrefix`.
|
|
9
|
+
*/
|
|
10
|
+
function parseAddress(value, expectedPrefix) {
|
|
11
|
+
validateAddress(value, "address", expectedPrefix);
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
function parseLeaseUuid(value) {
|
|
15
|
+
assertUuid(value, "leaseUuid", ARG);
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
function parseProviderUuid(value) {
|
|
19
|
+
assertUuid(value, "providerUuid", ARG);
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
function parseSkuUuid(value) {
|
|
23
|
+
assertUuid(value, "skuUuid", ARG);
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
function asLeaseUuid(value) {
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
function asProviderUuid(value) {
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
function asSkuUuid(value) {
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
function asAddress(value) {
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
function asFqdn(value) {
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Normalize (RFC 4343: DNS is case-insensitive) and validate a custom domain. Rejects scheme
|
|
43
|
+
* prefixes and IPv4 literals (FQDN_RE has a letter-led top-level label). The chain remains the
|
|
44
|
+
* authoritative validator (reserved suffixes, etc.).
|
|
45
|
+
*/
|
|
46
|
+
function parseFqdn(value) {
|
|
47
|
+
if (SCHEME_PREFIX_RE.test(value)) throw new ManifestMCPError(ARG, `customDomain "${value}" must not include a scheme — pass a bare FQDN`);
|
|
48
|
+
const normalized = value.toLowerCase();
|
|
49
|
+
if (!FQDN_RE.test(normalized)) throw new ManifestMCPError(ARG, `customDomain "${value}" is not a valid FQDN`);
|
|
50
|
+
return normalized;
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
export { asAddress, asFqdn, asLeaseUuid, asProviderUuid, asSkuUuid, parseAddress, parseFqdn, parseLeaseUuid, parseProviderUuid, parseSkuUuid };
|
|
54
|
+
|
|
55
|
+
//# sourceMappingURL=brands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brands.js","names":[],"sources":["../src/brands.ts"],"sourcesContent":["import { ManifestMCPError, ManifestMCPErrorCode } from './types.js';\nimport {\n assertUuid,\n FQDN_RE,\n SCHEME_PREFIX_RE,\n validateAddress,\n} from './validation.js';\n\n/**\n * Nominal brand. STRING tag key (not a `unique symbol`) ON PURPOSE: a unique-symbol brand is\n * non-assignable across DUPLICATED package copies (each copy mints a distinct symbol), breaking\n * the incremental cross-copy adoption this monorepo needs (the worktree/dep-drift hazard in\n * CLAUDE.md). Never exported. A brand is structurally `string`: assignable TO string, not FROM it.\n *\n * TWO sanctioned producer families, one per boundary trust-model (spec §5.0):\n * - parse* — VALIDATE + brand at the UNTRUSTED boundary (stringly/MCP input, provider HTTP,\n * wallet-in). Throwing, type-narrowing. Each `as Brand` cast here is preceded by a\n * throwing validator on all paths.\n * - as* — TRUST-CAST at the TRUSTED boundary (chain/codegen reads, already-resolved ids).\n * Brands WITHOUT validation and NEVER throws — the chain is the source of truth, and\n * re-validating would both waste work and throw on non-canonical ids (ENG-258 parse-once).\n * BOTH families confine the lone `as Brand` cast to this file (§8).\n */\ntype Brand<T, B extends string> = T & { readonly __brand: B };\n\nexport type Address = Brand<string, 'Address'>;\n/** A tenant IS an address — intentional transparent alias (branding does not distinguish them). */\nexport type Tenant = Address;\nexport type LeaseUuid = Brand<string, 'LeaseUuid'>;\nexport type ProviderUuid = Brand<string, 'ProviderUuid'>;\nexport type SkuUuid = Brand<string, 'SkuUuid'>;\nexport type Fqdn = Brand<string, 'Fqdn'>;\n\n// NOTE (v7 scope-down): `tierName`/`denom`/`chainId` are intentionally PLAIN `string`, not branded.\n// They are single-role-per-call-site with low confusion risk, and the whole Cosmos stack\n// (cosmjs/Telescope/InterchainJS) uses bare `string` for them — branding them would tax every\n// interop boundary for little safety. Brands are kept only where a mix-up is plausible AND costly:\n// the same-shaped Lease/Provider/Sku UUID trio, Address, and Fqdn (which also normalizes).\n\nconst ARG = ManifestMCPErrorCode.INVALID_ARGUMENT;\n\n/**\n * Validate a bech32 address and brand it. With no `expectedPrefix` this validates bech32\n * STRUCTURE only and does NOT pin the chain prefix — callers needing chain affinity (e.g. the\n * Signer adapter) pass the configured `addressPrefix`.\n */\nexport function parseAddress(value: string, expectedPrefix?: string): Address {\n validateAddress(value, 'address', expectedPrefix);\n return value as Address;\n}\n\nexport function parseLeaseUuid(value: string): LeaseUuid {\n assertUuid(value, 'leaseUuid', ARG);\n return value as LeaseUuid;\n}\nexport function parseProviderUuid(value: string): ProviderUuid {\n assertUuid(value, 'providerUuid', ARG);\n return value as ProviderUuid;\n}\nexport function parseSkuUuid(value: string): SkuUuid {\n assertUuid(value, 'skuUuid', ARG);\n return value as SkuUuid;\n}\n\n// ===== as* — trust-cast family (no validation, never throws); see the two-family note above. =====\nexport function asLeaseUuid(value: string): LeaseUuid {\n return value as LeaseUuid;\n}\nexport function asProviderUuid(value: string): ProviderUuid {\n return value as ProviderUuid;\n}\nexport function asSkuUuid(value: string): SkuUuid {\n return value as SkuUuid;\n}\nexport function asAddress(value: string): Address {\n return value as Address;\n}\n// NOTE: unlike parseFqdn, asFqdn does NOT lowercase — chain reads are already canonical\n// (re-normalizing would break parse-once, ENG-258) — and does NOT reject '' (trust-cast).\nexport function asFqdn(value: string): Fqdn {\n return value as Fqdn;\n}\n\n/**\n * Normalize (RFC 4343: DNS is case-insensitive) and validate a custom domain. Rejects scheme\n * prefixes and IPv4 literals (FQDN_RE has a letter-led top-level label). The chain remains the\n * authoritative validator (reserved suffixes, etc.).\n */\nexport function parseFqdn(value: string): Fqdn {\n if (SCHEME_PREFIX_RE.test(value)) {\n throw new ManifestMCPError(\n ARG,\n `customDomain \"${value}\" must not include a scheme — pass a bare FQDN`,\n );\n }\n const normalized = value.toLowerCase();\n if (!FQDN_RE.test(normalized)) {\n throw new ManifestMCPError(\n ARG,\n `customDomain \"${value}\" is not a valid FQDN`,\n );\n }\n return normalized as Fqdn;\n}\n"],"mappings":";;;AAuCA,MAAM,MAAA;;;;;;AAON,SAAgB,aAAa,OAAe,gBAAkC;CAC5E,gBAAgB,OAAO,WAAW,cAAc;CAChD,OAAO;AACT;AAEA,SAAgB,eAAe,OAA0B;CACvD,WAAW,OAAO,aAAa,GAAG;CAClC,OAAO;AACT;AACA,SAAgB,kBAAkB,OAA6B;CAC7D,WAAW,OAAO,gBAAgB,GAAG;CACrC,OAAO;AACT;AACA,SAAgB,aAAa,OAAwB;CACnD,WAAW,OAAO,WAAW,GAAG;CAChC,OAAO;AACT;AAGA,SAAgB,YAAY,OAA0B;CACpD,OAAO;AACT;AACA,SAAgB,eAAe,OAA6B;CAC1D,OAAO;AACT;AACA,SAAgB,UAAU,OAAwB;CAChD,OAAO;AACT;AACA,SAAgB,UAAU,OAAwB;CAChD,OAAO;AACT;AAGA,SAAgB,OAAO,OAAqB;CAC1C,OAAO;AACT;;;;;;AAOA,SAAgB,UAAU,OAAqB;CAC7C,IAAI,iBAAiB,KAAK,KAAK,GAC7B,MAAM,IAAI,iBACR,KACA,iBAAiB,MAAM,+CACzB;CAEF,MAAM,aAAa,MAAM,YAAY;CACrC,IAAI,CAAC,QAAQ,KAAK,UAAU,GAC1B,MAAM,IAAI,iBACR,KACA,iBAAiB,MAAM,sBACzB;CAEF,OAAO;AACT"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { asAddress, asFqdn, asLeaseUuid, asProviderUuid, asSkuUuid } from "./brands.js";
|
|
2
|
+
import { describe, expectTypeOf, it } from "vitest";
|
|
3
|
+
//#region src/brands.test-d.ts
|
|
4
|
+
describe("brand distinctness (type-level)", () => {
|
|
5
|
+
it("UUID-backed brands are mutually non-assignable", () => {
|
|
6
|
+
expectTypeOf().not.toEqualTypeOf();
|
|
7
|
+
expectTypeOf().not.toEqualTypeOf();
|
|
8
|
+
expectTypeOf().not.toEqualTypeOf();
|
|
9
|
+
});
|
|
10
|
+
it("a non-UUID pair is also distinct", () => {
|
|
11
|
+
expectTypeOf().not.toEqualTypeOf();
|
|
12
|
+
});
|
|
13
|
+
it("brands are one-way assignable: TO string, not FROM string", () => {
|
|
14
|
+
expectTypeOf().toExtend();
|
|
15
|
+
expectTypeOf().not.toExtend();
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
describe("as* return the correct branded type (type-level)", () => {
|
|
19
|
+
it("each as* returns its own branded type, mutually distinct", () => {
|
|
20
|
+
expectTypeOf(asProviderUuid("x")).toEqualTypeOf();
|
|
21
|
+
expectTypeOf(asLeaseUuid("x")).toEqualTypeOf();
|
|
22
|
+
expectTypeOf(asSkuUuid("x")).toEqualTypeOf();
|
|
23
|
+
expectTypeOf(asProviderUuid("x")).not.toEqualTypeOf();
|
|
24
|
+
expectTypeOf(asAddress("x")).toEqualTypeOf();
|
|
25
|
+
expectTypeOf(asFqdn("x")).toEqualTypeOf();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
//#endregion
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=brands.test-d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brands.test-d.js","names":[],"sources":["../src/brands.test-d.ts"],"sourcesContent":["import { describe, expectTypeOf, it } from 'vitest';\nimport type {\n Address,\n Fqdn,\n LeaseUuid,\n ProviderUuid,\n SkuUuid,\n} from './brands.js';\nimport {\n asAddress,\n asFqdn,\n asLeaseUuid,\n asProviderUuid,\n asSkuUuid,\n} from './brands.js';\n\n// NOTE: never use expectTypeOf(...).branded here — `.branded` normalizes away the\n// `& { __brand }` intersection that DEFINES a brand and would defeat these checks.\ndescribe('brand distinctness (type-level)', () => {\n it('UUID-backed brands are mutually non-assignable', () => {\n expectTypeOf<LeaseUuid>().not.toEqualTypeOf<ProviderUuid>();\n expectTypeOf<ProviderUuid>().not.toEqualTypeOf<SkuUuid>();\n expectTypeOf<LeaseUuid>().not.toEqualTypeOf<SkuUuid>();\n });\n it('a non-UUID pair is also distinct', () => {\n expectTypeOf<Address>().not.toEqualTypeOf<Fqdn>();\n });\n it('brands are one-way assignable: TO string, not FROM string', () => {\n expectTypeOf<LeaseUuid>().toExtend<string>();\n expectTypeOf<string>().not.toExtend<LeaseUuid>();\n });\n});\n\ndescribe('as* return the correct branded type (type-level)', () => {\n it('each as* returns its own branded type, mutually distinct', () => {\n expectTypeOf(asProviderUuid('x')).toEqualTypeOf<ProviderUuid>();\n expectTypeOf(asLeaseUuid('x')).toEqualTypeOf<LeaseUuid>();\n expectTypeOf(asSkuUuid('x')).toEqualTypeOf<SkuUuid>();\n expectTypeOf(asProviderUuid('x')).not.toEqualTypeOf<LeaseUuid>();\n expectTypeOf(asAddress('x')).toEqualTypeOf<Address>();\n expectTypeOf(asFqdn('x')).toEqualTypeOf<Fqdn>();\n });\n});\n"],"mappings":";;;AAkBA,SAAS,yCAAyC;CAChD,GAAG,wDAAwD;EACzD,aAAwB,EAAE,IAAI,cAA4B;EAC1D,aAA2B,EAAE,IAAI,cAAuB;EACxD,aAAwB,EAAE,IAAI,cAAuB;CACvD,CAAC;CACD,GAAG,0CAA0C;EAC3C,aAAsB,EAAE,IAAI,cAAoB;CAClD,CAAC;CACD,GAAG,mEAAmE;EACpE,aAAwB,EAAE,SAAiB;EAC3C,aAAqB,EAAE,IAAI,SAAoB;CACjD,CAAC;AACH,CAAC;AAED,SAAS,0DAA0D;CACjE,GAAG,kEAAkE;EACnE,aAAa,eAAe,GAAG,CAAC,EAAE,cAA4B;EAC9D,aAAa,YAAY,GAAG,CAAC,EAAE,cAAyB;EACxD,aAAa,UAAU,GAAG,CAAC,EAAE,cAAuB;EACpD,aAAa,eAAe,GAAG,CAAC,EAAE,IAAI,cAAyB;EAC/D,aAAa,UAAU,GAAG,CAAC,EAAE,cAAuB;EACpD,aAAa,OAAO,GAAG,CAAC,EAAE,cAAoB;CAChD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { LogLevel, Logger } from "./logger.js";
|
|
2
|
+
import { ManifestMCPConfig, WalletProvider } from "./types.js";
|
|
3
|
+
import { EventTransport, QueryCtx } from "./ctx.js";
|
|
4
|
+
import { listSkuCandidates, resolveSku } from "./sku-resolution.js";
|
|
5
|
+
import { getBalance } from "./tools/getBalance.js";
|
|
6
|
+
import { getBillingParams, getLease, getLeaseByCustomDomain, getLeasesByTenant, getProviders, getSKUs, getWithdrawableAmount } from "./tools/reads.js";
|
|
7
|
+
|
|
8
|
+
//#region src/client-factory.d.ts
|
|
9
|
+
/**
|
|
10
|
+
* Strip the leading ctx parameter: a free fn `(ctx, ...rest) => R` becomes the bound method
|
|
11
|
+
* `(...rest) => R`. Keeps the bound-method interface signatures DERIVED from (never drifting from)
|
|
12
|
+
* the free fns — including getBalance's inferred return.
|
|
13
|
+
*/
|
|
14
|
+
type BoundFn<F> = F extends ((ctx: infer _C, ...rest: infer R) => infer Ret) ? (...rest: R) => Ret : never;
|
|
15
|
+
/** The trailing (post-ctx) parameter tuple of a free fn — the value-level companion of BoundFn,
|
|
16
|
+
* used to type the bound-method closures. Exported so client-full.ts single-sources it (N7). */
|
|
17
|
+
type TailOf<F> = F extends ((ctx: infer _C, ...rest: infer R) => unknown) ? R : never;
|
|
18
|
+
/** Shared factory inputs. `skuSpecs`/`events`/`logLevel` are accepted but NOT threaded in 4b (see plan OI-BETA). */
|
|
19
|
+
interface BaseClientOptions {
|
|
20
|
+
config: ManifestMCPConfig;
|
|
21
|
+
/** Injected at the edge (node: guarded-undici; browser: providerFetch). Defaults to `globalThis.fetch`. */
|
|
22
|
+
fetch?: typeof globalThis.fetch;
|
|
23
|
+
/** Per-instance logging sink; defaults to the silent `noopLogger`. */
|
|
24
|
+
logger?: Logger;
|
|
25
|
+
/** @beta — carried for the later SDK-side level gate; the gate is NOT built in 4b. */
|
|
26
|
+
logLevel?: LogLevel;
|
|
27
|
+
/** @beta — §5.5 placeholder; not a real core type yet, not threaded in 4b. */
|
|
28
|
+
skuSpecs?: unknown;
|
|
29
|
+
/** @beta — §5.9 forward-declared transport stub; not threaded in 4b. */
|
|
30
|
+
events?: EventTransport;
|
|
31
|
+
}
|
|
32
|
+
/** @public — inputs to {@link createManifestClient} (full/signing). A `walletProvider` is REQUIRED. */
|
|
33
|
+
interface FullClientOptions extends BaseClientOptions {
|
|
34
|
+
walletProvider: WalletProvider;
|
|
35
|
+
}
|
|
36
|
+
/** @public — inputs to {@link createManifestReadClient} (query-only). No `walletProvider`. */
|
|
37
|
+
type ReadClientOptions = BaseClientOptions;
|
|
38
|
+
/**
|
|
39
|
+
* Shared ctx builder. Returns the base `ManifestReadClient` (ctx fields + `dispose`); the full factory
|
|
40
|
+
* up-casts to `ManifestClient` (sound — `withSigner=true` ⇒ a defined signer). NOTE (cross-ctx hazard,
|
|
41
|
+
* OI-DISPOSE): `getInstance` mutates the shared instance for a given config key, so do not construct a
|
|
42
|
+
* read client (wallet stub) against a key a full client already holds — the common case is safe because
|
|
43
|
+
* read configs omit `rpcUrl` → a different key.
|
|
44
|
+
*/
|
|
45
|
+
declare function buildClient(opts: BaseClientOptions, walletProvider: WalletProvider, withSigner: boolean): Promise<ManifestReadClient>;
|
|
46
|
+
/**
|
|
47
|
+
* @public — construct a query-only {@link ManifestReadClient} (no signer; reads/queries only).
|
|
48
|
+
*
|
|
49
|
+
* @remarks
|
|
50
|
+
* Each client acquires one reference on a `CosmosClientManager` instance keyed by config
|
|
51
|
+
* (`chainId:rpcUrl[:restUrl]`). Clients sharing a config key share that one underlying instance, and
|
|
52
|
+
* `getInstance` mutates it — so do NOT construct a read client against a config key a full (signing)
|
|
53
|
+
* client already holds (the common case is safe: a query-only config omits `rpcUrl` → a different key).
|
|
54
|
+
* Always `dispose()` each client; the shared clients tear down only once the last holder disposes.
|
|
55
|
+
*/
|
|
56
|
+
declare function createManifestReadClient(opts: ReadClientOptions): Promise<ManifestReadClient>;
|
|
57
|
+
/**
|
|
58
|
+
* @public — query-only bound client. EXTENDS `QueryCtx`, so NO `signer`/tx/subscribe at the TYPE level
|
|
59
|
+
* (the viem Public Client invariant; cosmjs `StargateClient`). The bound READ action methods are added
|
|
60
|
+
* in Plan 4c/4d; 4b declares only the ctx extension + lifecycle. `client.query`/`client.chain` are honest
|
|
61
|
+
* Telescope/cosmjs drop-downs.
|
|
62
|
+
*/
|
|
63
|
+
interface ManifestReadClient extends QueryCtx {
|
|
64
|
+
/**
|
|
65
|
+
* Release this client's share of the underlying keyed `CosmosClientManager` (balances the single
|
|
66
|
+
* `getInstance` refCount the factory acquired). Idempotent. Implemented in 4b; the manager tears the
|
|
67
|
+
* shared clients down only once the last holder disposes.
|
|
68
|
+
*/
|
|
69
|
+
dispose(): void;
|
|
70
|
+
getBalance: BoundFn<typeof getBalance>;
|
|
71
|
+
resolveSku: BoundFn<typeof resolveSku>;
|
|
72
|
+
listSkuCandidates: BoundFn<typeof listSkuCandidates>;
|
|
73
|
+
getLeasesByTenant: BoundFn<typeof getLeasesByTenant>;
|
|
74
|
+
getLease: BoundFn<typeof getLease>;
|
|
75
|
+
getLeaseByCustomDomain: BoundFn<typeof getLeaseByCustomDomain>;
|
|
76
|
+
getSKUs: BoundFn<typeof getSKUs>;
|
|
77
|
+
getProviders: BoundFn<typeof getProviders>;
|
|
78
|
+
getBillingParams: BoundFn<typeof getBillingParams>;
|
|
79
|
+
getWithdrawableAmount: BoundFn<typeof getWithdrawableAmount>;
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { BoundFn, FullClientOptions, ManifestReadClient, ReadClientOptions, TailOf, buildClient, createManifestReadClient };
|
|
83
|
+
//# sourceMappingURL=client-factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-factory.d.ts","names":[],"sources":["../src/client-factory.ts"],"mappings":";;;;;;;;;;AA4BA;;;KAAY,OAAA,MAAa,CAAA,WACvB,GAAA,eACG,IAAA,+BAEG,IAAA,EAAM,CAAA,KAAM,GAAA;;;KAKR,MAAA,MAAY,CAAC,WAAU,GAAA,eAAkB,IAAA,yBACjD,CAAA;;UAIM,iBAAA;EACR,MAAA,EAAQ,iBAAA;EAdG;EAgBX,KAAA,UAAe,UAAA,CAAW,KAAA;EAfvB;EAiBH,MAAA,GAAS,MAAA;EAhBA;EAkBT,QAAA,GAAW,QAAA;EAjBC;EAmBZ,QAAA;EAnBqB;EAqBrB,MAAA,GAAS,cAAA;AAAA;;UAIM,iBAAA,SAA0B,iBAAiB;EAC1D,cAAA,EAAgB,cAAA;AAAA;;KAIN,iBAAA,GAAoB,iBAAiB;;;;;;AAxB5C;AACK;iBAkDY,WAAA,CACpB,IAAA,EAAM,iBAAA,EACN,cAAA,EAAgB,cAAA,EAChB,UAAA,YACC,OAAA,CAAQ,kBAAA;;;;;;;;;;;iBAwEW,wBAAA,CACpB,IAAA,EAAM,iBAAA,GACL,OAAA,CAAQ,kBAAA;;;;;;;UAUM,kBAAA,SAA2B,QAAA;EA5H1C;;;AAAuB;AAIzB;EA8HE,OAAA;EACA,UAAA,EAAY,OAAA,QAAe,UAAA;EAC3B,UAAA,EAAY,OAAA,QAAe,UAAA;EAC3B,iBAAA,EAAmB,OAAA,QAAe,iBAAA;EAClC,iBAAA,EAAmB,OAAA,QAAe,iBAAA;EAClC,QAAA,EAAU,OAAA,QAAe,QAAA;EACzB,sBAAA,EAAwB,OAAA,QAAe,sBAAA;EACvC,OAAA,EAAS,OAAA,QAAe,OAAA;EACxB,YAAA,EAAc,OAAA,QAAe,YAAA;EAC7B,gBAAA,EAAkB,OAAA,QAAe,gBAAA;EACjC,qBAAA,EAAuB,OAAA,QAAe,qBAAA;AAAA"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { ManifestMCPError } from "./types.js";
|
|
2
|
+
import { createValidatedConfig } from "./config.js";
|
|
3
|
+
import { noopLogger } from "./logger.js";
|
|
4
|
+
import { CosmosClientManager } from "./client.js";
|
|
5
|
+
import { createSignerAdapter } from "./signer.js";
|
|
6
|
+
import { listSkuCandidates, resolveSku } from "./sku-resolution.js";
|
|
7
|
+
import { getBalance } from "./tools/getBalance.js";
|
|
8
|
+
import { getBillingParams, getLease, getLeaseByCustomDomain, getLeasesByTenant, getProviders, getSKUs, getWithdrawableAmount } from "./tools/reads.js";
|
|
9
|
+
//#region src/client-factory.ts
|
|
10
|
+
/**
|
|
11
|
+
* A `WalletProvider` for query-only clients. `getInstance` requires a wallet even in query-only mode, but
|
|
12
|
+
* queries never sign — so this stub is stored and never invoked. Every signing accessor REJECTS with
|
|
13
|
+
* `INVALID_CONFIG` (a rejected promise, NOT a sync throw — the methods are `Promise`-returning, so a
|
|
14
|
+
* consumer's `await wallet.getSigner()` must see a rejection) as a hard backstop. `signArbitrary` is
|
|
15
|
+
* included (optional on `WalletProvider`) so the stub fails closed there too.
|
|
16
|
+
*/
|
|
17
|
+
function queryOnlyWalletStub() {
|
|
18
|
+
const fail = () => Promise.reject(new ManifestMCPError("INVALID_CONFIG", "This client was created in query-only mode (createManifestReadClient) and cannot sign or broadcast. Use createManifestClient with a walletProvider for transactions."));
|
|
19
|
+
return {
|
|
20
|
+
getAddress: fail,
|
|
21
|
+
getSigner: fail,
|
|
22
|
+
signArbitrary: fail
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Shared ctx builder. Returns the base `ManifestReadClient` (ctx fields + `dispose`); the full factory
|
|
27
|
+
* up-casts to `ManifestClient` (sound — `withSigner=true` ⇒ a defined signer). NOTE (cross-ctx hazard,
|
|
28
|
+
* OI-DISPOSE): `getInstance` mutates the shared instance for a given config key, so do not construct a
|
|
29
|
+
* read client (wallet stub) against a key a full client already holds — the common case is safe because
|
|
30
|
+
* read configs omit `rpcUrl` → a different key.
|
|
31
|
+
*/
|
|
32
|
+
async function buildClient(opts, walletProvider, withSigner) {
|
|
33
|
+
const config = createValidatedConfig(opts.config);
|
|
34
|
+
const chain = CosmosClientManager.getInstance(config, walletProvider);
|
|
35
|
+
try {
|
|
36
|
+
const signer = withSigner ? createSignerAdapter(walletProvider, config.addressPrefix) : void 0;
|
|
37
|
+
const fetch = opts.fetch ?? globalThis.fetch;
|
|
38
|
+
const logger = opts.logger ?? noopLogger;
|
|
39
|
+
chain.setLogger(logger);
|
|
40
|
+
const query = await chain.getQueryClient();
|
|
41
|
+
let disposed = false;
|
|
42
|
+
const dispose = () => {
|
|
43
|
+
if (disposed) return;
|
|
44
|
+
disposed = true;
|
|
45
|
+
chain.disconnect();
|
|
46
|
+
};
|
|
47
|
+
const base = {
|
|
48
|
+
chain,
|
|
49
|
+
query,
|
|
50
|
+
fetch,
|
|
51
|
+
logger,
|
|
52
|
+
dispose
|
|
53
|
+
};
|
|
54
|
+
const client = signer ? {
|
|
55
|
+
...base,
|
|
56
|
+
signer
|
|
57
|
+
} : base;
|
|
58
|
+
Object.assign(client, {
|
|
59
|
+
getBalance: (address, opts) => getBalance(client, address, opts),
|
|
60
|
+
resolveSku: (...a) => resolveSku(client, ...a),
|
|
61
|
+
listSkuCandidates: (...a) => listSkuCandidates(client, ...a),
|
|
62
|
+
getLeasesByTenant: (...a) => getLeasesByTenant(client, ...a),
|
|
63
|
+
getLease: (...a) => getLease(client, ...a),
|
|
64
|
+
getLeaseByCustomDomain: (...a) => getLeaseByCustomDomain(client, ...a),
|
|
65
|
+
getSKUs: (...a) => getSKUs(client, ...a),
|
|
66
|
+
getProviders: (...a) => getProviders(client, ...a),
|
|
67
|
+
getBillingParams: (...a) => getBillingParams(client, ...a),
|
|
68
|
+
getWithdrawableAmount: (...a) => getWithdrawableAmount(client, ...a)
|
|
69
|
+
});
|
|
70
|
+
return client;
|
|
71
|
+
} catch (err) {
|
|
72
|
+
chain.disconnect();
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* @public — construct a query-only {@link ManifestReadClient} (no signer; reads/queries only).
|
|
78
|
+
*
|
|
79
|
+
* @remarks
|
|
80
|
+
* Each client acquires one reference on a `CosmosClientManager` instance keyed by config
|
|
81
|
+
* (`chainId:rpcUrl[:restUrl]`). Clients sharing a config key share that one underlying instance, and
|
|
82
|
+
* `getInstance` mutates it — so do NOT construct a read client against a config key a full (signing)
|
|
83
|
+
* client already holds (the common case is safe: a query-only config omits `rpcUrl` → a different key).
|
|
84
|
+
* Always `dispose()` each client; the shared clients tear down only once the last holder disposes.
|
|
85
|
+
*/
|
|
86
|
+
async function createManifestReadClient(opts) {
|
|
87
|
+
return buildClient(opts, queryOnlyWalletStub(), false);
|
|
88
|
+
}
|
|
89
|
+
//#endregion
|
|
90
|
+
export { buildClient, createManifestReadClient };
|
|
91
|
+
|
|
92
|
+
//# sourceMappingURL=client-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-factory.js","names":[],"sources":["../src/client-factory.ts"],"sourcesContent":["import { CosmosClientManager } from './client.js';\nimport { createValidatedConfig } from './config.js';\nimport type { EventTransport, QueryCtx } from './ctx.js';\nimport type { Logger, LogLevel } from './logger.js';\nimport { noopLogger } from './logger.js';\nimport type { CallOptions } from './options.js';\nimport { createSignerAdapter } from './signer.js';\nimport { listSkuCandidates, resolveSku } from './sku-resolution.js';\n// VALUE imports (used both for typeof in the interface and for runtime binding). READS ONLY — never\n// import a tx fn here, so a reads-only browser bundle importing createManifestReadClient stays tx-free.\nimport { getBalance } from './tools/getBalance.js';\nimport {\n getBillingParams,\n getLease,\n getLeaseByCustomDomain,\n getLeasesByTenant,\n getProviders,\n getSKUs,\n getWithdrawableAmount,\n} from './tools/reads.js';\nimport type { ManifestMCPConfig, WalletProvider } from './types.js';\nimport { ManifestMCPError, ManifestMCPErrorCode } from './types.js';\n\n/**\n * Strip the leading ctx parameter: a free fn `(ctx, ...rest) => R` becomes the bound method\n * `(...rest) => R`. Keeps the bound-method interface signatures DERIVED from (never drifting from)\n * the free fns — including getBalance's inferred return.\n */\nexport type BoundFn<F> = F extends (\n ctx: infer _C,\n ...rest: infer R\n) => infer Ret\n ? (...rest: R) => Ret\n : never;\n\n/** The trailing (post-ctx) parameter tuple of a free fn — the value-level companion of BoundFn,\n * used to type the bound-method closures. Exported so client-full.ts single-sources it (N7). */\nexport type TailOf<F> = F extends (ctx: infer _C, ...rest: infer R) => unknown\n ? R\n : never;\n\n/** Shared factory inputs. `skuSpecs`/`events`/`logLevel` are accepted but NOT threaded in 4b (see plan OI-BETA). */\ninterface BaseClientOptions {\n config: ManifestMCPConfig;\n /** Injected at the edge (node: guarded-undici; browser: providerFetch). Defaults to `globalThis.fetch`. */\n fetch?: typeof globalThis.fetch;\n /** Per-instance logging sink; defaults to the silent `noopLogger`. */\n logger?: Logger;\n /** @beta — carried for the later SDK-side level gate; the gate is NOT built in 4b. */\n logLevel?: LogLevel;\n /** @beta — §5.5 placeholder; not a real core type yet, not threaded in 4b. */\n skuSpecs?: unknown;\n /** @beta — §5.9 forward-declared transport stub; not threaded in 4b. */\n events?: EventTransport;\n}\n\n/** @public — inputs to {@link createManifestClient} (full/signing). A `walletProvider` is REQUIRED. */\nexport interface FullClientOptions extends BaseClientOptions {\n walletProvider: WalletProvider;\n}\n\n/** @public — inputs to {@link createManifestReadClient} (query-only). No `walletProvider`. */\nexport type ReadClientOptions = BaseClientOptions;\n\n/**\n * A `WalletProvider` for query-only clients. `getInstance` requires a wallet even in query-only mode, but\n * queries never sign — so this stub is stored and never invoked. Every signing accessor REJECTS with\n * `INVALID_CONFIG` (a rejected promise, NOT a sync throw — the methods are `Promise`-returning, so a\n * consumer's `await wallet.getSigner()` must see a rejection) as a hard backstop. `signArbitrary` is\n * included (optional on `WalletProvider`) so the stub fails closed there too.\n */\nfunction queryOnlyWalletStub(): WalletProvider {\n const fail = (): Promise<never> =>\n Promise.reject(\n new ManifestMCPError(\n ManifestMCPErrorCode.INVALID_CONFIG,\n 'This client was created in query-only mode (createManifestReadClient) and cannot sign or broadcast. Use createManifestClient with a walletProvider for transactions.',\n ),\n );\n return { getAddress: fail, getSigner: fail, signArbitrary: fail };\n}\n\n/**\n * Shared ctx builder. Returns the base `ManifestReadClient` (ctx fields + `dispose`); the full factory\n * up-casts to `ManifestClient` (sound — `withSigner=true` ⇒ a defined signer). NOTE (cross-ctx hazard,\n * OI-DISPOSE): `getInstance` mutates the shared instance for a given config key, so do not construct a\n * read client (wallet stub) against a key a full client already holds — the common case is safe because\n * read configs omit `rpcUrl` → a different key.\n */\nexport async function buildClient(\n opts: BaseClientOptions,\n walletProvider: WalletProvider,\n withSigner: boolean,\n): Promise<ManifestReadClient> {\n const config = createValidatedConfig(opts.config); // throws INVALID_CONFIG before any instance is keyed\n const chain = CosmosClientManager.getInstance(config, walletProvider); // ONCE; acquires one refCount\n try {\n const signer = withSigner\n ? createSignerAdapter(walletProvider, config.addressPrefix) // config.addressPrefix defaulted in createConfig\n : undefined;\n // NEUTRAL fetch resolution — never import the node-only guarded fetch (ENG-281 browser-bundle hazard).\n // The node/fred edge injects the guarded fetch via opts.fetch; default to the platform global.\n const fetch = opts.fetch ?? globalThis.fetch;\n const logger = opts.logger ?? noopLogger;\n chain.setLogger(logger); // route the manager's 2 init diagnostics to the per-ctx logger (OI-LOG)\n // Await the query client ONCE so ctx.query is concrete (the await-once-then-read Cosmos idiom).\n const query = await chain.getQueryClient();\n\n // dispose: balance the single getInstance refCount; idempotent so a double-dispose is safe.\n let disposed = false;\n const dispose = (): void => {\n if (disposed) return;\n disposed = true;\n chain.disconnect();\n };\n\n // In query-only mode OMIT the signer key entirely (so `'signer' in client` is false — the runtime\n // matches the read type) rather than carrying `signer: undefined`. 4d binds the read/tx action\n // methods over this ctx; 4b returns the ctx + dispose shell. Structurally a ManifestReadClient; the\n // full factory up-casts to ManifestClient.\n const base = { chain, query, fetch, logger, dispose };\n const ctxShell = signer ? { ...base, signer } : base;\n // Bind the read methods as per-instance arrow-closures over the FINAL object (it IS the ctx).\n // The bound methods close over `client`; `dispose` closes over the buildClient-local `disposed`\n // flag — both end up on the single returned object (no soundness issue, N9).\n const client = ctxShell as ManifestReadClient;\n Object.assign(client, {\n getBalance: (address: string, opts?: CallOptions) =>\n getBalance(client, address, opts),\n resolveSku: (...a: TailOf<typeof resolveSku>) => resolveSku(client, ...a),\n listSkuCandidates: (...a: TailOf<typeof listSkuCandidates>) =>\n listSkuCandidates(client, ...a),\n getLeasesByTenant: (...a: TailOf<typeof getLeasesByTenant>) =>\n getLeasesByTenant(client, ...a),\n getLease: (...a: TailOf<typeof getLease>) => getLease(client, ...a),\n getLeaseByCustomDomain: (...a: TailOf<typeof getLeaseByCustomDomain>) =>\n getLeaseByCustomDomain(client, ...a),\n getSKUs: (...a: TailOf<typeof getSKUs>) => getSKUs(client, ...a),\n getProviders: (...a: TailOf<typeof getProviders>) =>\n getProviders(client, ...a),\n getBillingParams: (...a: TailOf<typeof getBillingParams>) =>\n getBillingParams(client, ...a),\n getWithdrawableAmount: (...a: TailOf<typeof getWithdrawableAmount>) =>\n getWithdrawableAmount(client, ...a),\n });\n return client;\n } catch (err) {\n // getQueryClient (or signer construction) failed AFTER getInstance acquired the refCount, and the\n // caller never received a `dispose()` handle. Release the acquire once so a construction failure does\n // not leak a phantom holder (OI-DISPOSE failure path), then re-throw.\n chain.disconnect();\n throw err;\n }\n}\n\n/**\n * @public — construct a query-only {@link ManifestReadClient} (no signer; reads/queries only).\n *\n * @remarks\n * Each client acquires one reference on a `CosmosClientManager` instance keyed by config\n * (`chainId:rpcUrl[:restUrl]`). Clients sharing a config key share that one underlying instance, and\n * `getInstance` mutates it — so do NOT construct a read client against a config key a full (signing)\n * client already holds (the common case is safe: a query-only config omits `rpcUrl` → a different key).\n * Always `dispose()` each client; the shared clients tear down only once the last holder disposes.\n */\nexport async function createManifestReadClient(\n opts: ReadClientOptions,\n): Promise<ManifestReadClient> {\n return buildClient(opts, queryOnlyWalletStub(), false);\n}\n\n/**\n * @public — query-only bound client. EXTENDS `QueryCtx`, so NO `signer`/tx/subscribe at the TYPE level\n * (the viem Public Client invariant; cosmjs `StargateClient`). The bound READ action methods are added\n * in Plan 4c/4d; 4b declares only the ctx extension + lifecycle. `client.query`/`client.chain` are honest\n * Telescope/cosmjs drop-downs.\n */\nexport interface ManifestReadClient extends QueryCtx {\n /**\n * Release this client's share of the underlying keyed `CosmosClientManager` (balances the single\n * `getInstance` refCount the factory acquired). Idempotent. Implemented in 4b; the manager tears the\n * shared clients down only once the last holder disposes.\n */\n dispose(): void;\n getBalance: BoundFn<typeof getBalance>;\n resolveSku: BoundFn<typeof resolveSku>;\n listSkuCandidates: BoundFn<typeof listSkuCandidates>;\n getLeasesByTenant: BoundFn<typeof getLeasesByTenant>;\n getLease: BoundFn<typeof getLease>;\n getLeaseByCustomDomain: BoundFn<typeof getLeaseByCustomDomain>;\n getSKUs: BoundFn<typeof getSKUs>;\n getProviders: BoundFn<typeof getProviders>;\n getBillingParams: BoundFn<typeof getBillingParams>;\n getWithdrawableAmount: BoundFn<typeof getWithdrawableAmount>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAuEA,SAAS,sBAAsC;CAC7C,MAAM,aACJ,QAAQ,OACN,IAAI,iBAAA,kBAEF,sKACF,CACF;CACF,OAAO;EAAE,YAAY;EAAM,WAAW;EAAM,eAAe;CAAK;AAClE;;;;;;;;AASA,eAAsB,YACpB,MACA,gBACA,YAC6B;CAC7B,MAAM,SAAS,sBAAsB,KAAK,MAAM;CAChD,MAAM,QAAQ,oBAAoB,YAAY,QAAQ,cAAc;CACpE,IAAI;EACF,MAAM,SAAS,aACX,oBAAoB,gBAAgB,OAAO,aAAa,IACxD,KAAA;EAGJ,MAAM,QAAQ,KAAK,SAAS,WAAW;EACvC,MAAM,SAAS,KAAK,UAAU;EAC9B,MAAM,UAAU,MAAM;EAEtB,MAAM,QAAQ,MAAM,MAAM,eAAe;EAGzC,IAAI,WAAW;EACf,MAAM,gBAAsB;GAC1B,IAAI,UAAU;GACd,WAAW;GACX,MAAM,WAAW;EACnB;EAMA,MAAM,OAAO;GAAE;GAAO;GAAO;GAAO;GAAQ;EAAQ;EAKpD,MAAM,SAJW,SAAS;GAAE,GAAG;GAAM;EAAO,IAAI;EAKhD,OAAO,OAAO,QAAQ;GACpB,aAAa,SAAiB,SAC5B,WAAW,QAAQ,SAAS,IAAI;GAClC,aAAa,GAAG,MAAiC,WAAW,QAAQ,GAAG,CAAC;GACxE,oBAAoB,GAAG,MACrB,kBAAkB,QAAQ,GAAG,CAAC;GAChC,oBAAoB,GAAG,MACrB,kBAAkB,QAAQ,GAAG,CAAC;GAChC,WAAW,GAAG,MAA+B,SAAS,QAAQ,GAAG,CAAC;GAClE,yBAAyB,GAAG,MAC1B,uBAAuB,QAAQ,GAAG,CAAC;GACrC,UAAU,GAAG,MAA8B,QAAQ,QAAQ,GAAG,CAAC;GAC/D,eAAe,GAAG,MAChB,aAAa,QAAQ,GAAG,CAAC;GAC3B,mBAAmB,GAAG,MACpB,iBAAiB,QAAQ,GAAG,CAAC;GAC/B,wBAAwB,GAAG,MACzB,sBAAsB,QAAQ,GAAG,CAAC;EACtC,CAAC;EACD,OAAO;CACT,SAAS,KAAK;EAIZ,MAAM,WAAW;EACjB,MAAM;CACR;AACF;;;;;;;;;;;AAYA,eAAsB,yBACpB,MAC6B;CAC7B,OAAO,YAAY,MAAM,oBAAoB,GAAG,KAAK;AACvD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|