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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/.github/workflows/publish.yml +4 -2
  2. package/CLAUDE.md +9 -3
  3. package/README.md +6 -1
  4. package/dist/client.d.ts +13 -1
  5. package/dist/client.d.ts.map +1 -1
  6. package/dist/client.js +105 -9
  7. package/dist/client.js.map +1 -1
  8. package/dist/config.d.ts +4 -0
  9. package/dist/config.d.ts.map +1 -1
  10. package/dist/config.js +52 -7
  11. package/dist/config.js.map +1 -1
  12. package/dist/config.test.js +128 -0
  13. package/dist/config.test.js.map +1 -1
  14. package/dist/cosmos.d.ts.map +1 -1
  15. package/dist/cosmos.js +11 -57
  16. package/dist/cosmos.js.map +1 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +16 -25
  19. package/dist/index.js.map +1 -1
  20. package/dist/modules.d.ts +30 -1
  21. package/dist/modules.d.ts.map +1 -1
  22. package/dist/modules.js +67 -3
  23. package/dist/modules.js.map +1 -1
  24. package/dist/modules.test.js +58 -1
  25. package/dist/modules.test.js.map +1 -1
  26. package/dist/queries/auth.d.ts +7 -1
  27. package/dist/queries/auth.d.ts.map +1 -1
  28. package/dist/queries/auth.js +18 -45
  29. package/dist/queries/auth.js.map +1 -1
  30. package/dist/queries/bank.d.ts +7 -1
  31. package/dist/queries/bank.d.ts.map +1 -1
  32. package/dist/queries/bank.js +24 -38
  33. package/dist/queries/bank.js.map +1 -1
  34. package/dist/queries/billing.d.ts +7 -1
  35. package/dist/queries/billing.d.ts.map +1 -1
  36. package/dist/queries/billing.js +28 -54
  37. package/dist/queries/billing.js.map +1 -1
  38. package/dist/queries/distribution.d.ts +7 -1
  39. package/dist/queries/distribution.d.ts.map +1 -1
  40. package/dist/queries/distribution.js +18 -36
  41. package/dist/queries/distribution.js.map +1 -1
  42. package/dist/queries/gov.d.ts +7 -1
  43. package/dist/queries/gov.d.ts.map +1 -1
  44. package/dist/queries/gov.js +24 -41
  45. package/dist/queries/gov.js.map +1 -1
  46. package/dist/queries/index.d.ts +2 -1
  47. package/dist/queries/index.d.ts.map +1 -1
  48. package/dist/queries/index.js +1 -1
  49. package/dist/queries/index.js.map +1 -1
  50. package/dist/queries/staking.d.ts +7 -1
  51. package/dist/queries/staking.d.ts.map +1 -1
  52. package/dist/queries/staking.js +36 -59
  53. package/dist/queries/staking.js.map +1 -1
  54. package/dist/queries/utils.d.ts +42 -10
  55. package/dist/queries/utils.d.ts.map +1 -1
  56. package/dist/queries/utils.js +64 -12
  57. package/dist/queries/utils.js.map +1 -1
  58. package/dist/queries/utils.test.js +68 -8
  59. package/dist/queries/utils.test.js.map +1 -1
  60. package/dist/transactions/bank.d.ts +2 -2
  61. package/dist/transactions/bank.d.ts.map +1 -1
  62. package/dist/transactions/bank.js +9 -18
  63. package/dist/transactions/bank.js.map +1 -1
  64. package/dist/transactions/billing.d.ts +2 -2
  65. package/dist/transactions/billing.d.ts.map +1 -1
  66. package/dist/transactions/billing.js +52 -34
  67. package/dist/transactions/billing.js.map +1 -1
  68. package/dist/transactions/distribution.d.ts +2 -2
  69. package/dist/transactions/distribution.d.ts.map +1 -1
  70. package/dist/transactions/distribution.js +7 -13
  71. package/dist/transactions/distribution.js.map +1 -1
  72. package/dist/transactions/gov.d.ts +2 -2
  73. package/dist/transactions/gov.d.ts.map +1 -1
  74. package/dist/transactions/gov.js +32 -17
  75. package/dist/transactions/gov.js.map +1 -1
  76. package/dist/transactions/index.d.ts +1 -1
  77. package/dist/transactions/index.d.ts.map +1 -1
  78. package/dist/transactions/index.js +1 -1
  79. package/dist/transactions/index.js.map +1 -1
  80. package/dist/transactions/manifest.d.ts +2 -2
  81. package/dist/transactions/manifest.d.ts.map +1 -1
  82. package/dist/transactions/manifest.js +7 -14
  83. package/dist/transactions/manifest.js.map +1 -1
  84. package/dist/transactions/staking.d.ts +2 -2
  85. package/dist/transactions/staking.d.ts.map +1 -1
  86. package/dist/transactions/staking.js +7 -13
  87. package/dist/transactions/staking.js.map +1 -1
  88. package/dist/transactions/utils.d.ts +63 -1
  89. package/dist/transactions/utils.d.ts.map +1 -1
  90. package/dist/transactions/utils.js +121 -2
  91. package/dist/transactions/utils.js.map +1 -1
  92. package/dist/transactions/utils.test.js +351 -1
  93. package/dist/transactions/utils.test.js.map +1 -1
  94. package/dist/types.d.ts +212 -8
  95. package/dist/types.d.ts.map +1 -1
  96. package/dist/types.js.map +1 -1
  97. package/dist/wallet/mnemonic.d.ts +1 -0
  98. package/dist/wallet/mnemonic.d.ts.map +1 -1
  99. package/dist/wallet/mnemonic.js +34 -13
  100. package/dist/wallet/mnemonic.js.map +1 -1
  101. package/package.json +11 -6
  102. package/src/client.ts +119 -9
  103. package/src/config.test.ts +156 -0
  104. package/src/config.ts +59 -7
  105. package/src/cosmos.ts +19 -109
  106. package/src/index.ts +17 -23
  107. package/src/modules.test.ts +60 -0
  108. package/src/modules.ts +124 -7
  109. package/src/queries/auth.ts +35 -74
  110. package/src/queries/bank.ts +40 -58
  111. package/src/queries/billing.ts +46 -86
  112. package/src/queries/distribution.ts +35 -59
  113. package/src/queries/gov.ts +40 -64
  114. package/src/queries/index.ts +10 -1
  115. package/src/queries/staking.ts +55 -91
  116. package/src/queries/utils.test.ts +103 -8
  117. package/src/queries/utils.ts +92 -12
  118. package/src/transactions/bank.ts +9 -33
  119. package/src/transactions/billing.ts +64 -59
  120. package/src/transactions/distribution.ts +7 -29
  121. package/src/transactions/gov.ts +40 -34
  122. package/src/transactions/index.ts +1 -1
  123. package/src/transactions/manifest.ts +7 -29
  124. package/src/transactions/staking.ts +7 -29
  125. package/src/transactions/utils.test.ts +390 -1
  126. package/src/transactions/utils.ts +191 -2
  127. package/src/types.ts +328 -9
  128. package/src/wallet/mnemonic.ts +41 -17
  129. package/.claude/settings.local.json +0 -17
  130. package/dist/browser.d.ts.map +0 -1
  131. package/dist/browser.js.map +0 -1
  132. package/dist/queries/manifest.d.ts +0 -10
  133. package/dist/queries/manifest.d.ts.map +0 -1
  134. package/dist/queries/manifest.js +0 -14
  135. package/dist/queries/manifest.js.map +0 -1
  136. package/dist/wallet/keplr.d.ts.map +0 -1
  137. package/dist/wallet/keplr.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA4EA;;GAEG;AACH,MAAM,CAAN,IAAY,oBAkCX;AAlCD,WAAY,oBAAoB;IAC9B,uBAAuB;IACvB,yDAAiC,CAAA;IACjC,yDAAiC,CAAA;IAEjC,gBAAgB;IAChB,qEAA6C,CAAA;IAC7C,6EAAqD,CAAA;IACrD,mEAA2C,CAAA;IAC3C,6DAAqC,CAAA;IAErC,gBAAgB;IAChB,yEAAiD,CAAA;IACjD,uEAA+C,CAAA;IAE/C,eAAe;IACf,qDAA6B,CAAA;IAC7B,+DAAuC,CAAA;IACvC,2DAAmC,CAAA;IAEnC,qBAAqB;IACrB,+CAAuB,CAAA;IACvB,qEAA6C,CAAA;IAC7C,mEAA2C,CAAA;IAC3C,2EAAmD,CAAA;IACnD,yDAAiC,CAAA;IACjC,iEAAyC,CAAA;IAEzC,gBAAgB;IAChB,yDAAiC,CAAA;IACjC,iEAAyC,CAAA;IAEzC,iBAAiB;IACjB,uDAA+B,CAAA;AACjC,CAAC,EAlCW,oBAAoB,KAApB,oBAAoB,QAkC/B;AAED;;GAEG;AACH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAIzC,YACE,IAA0B,EAC1B,OAAe,EACf,OAAiC;QAEjC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAEvB,sDAAsD;QACtD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM;QACJ,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAiFA;;GAEG;AACH,MAAM,CAAN,IAAY,oBAkCX;AAlCD,WAAY,oBAAoB;IAC9B,uBAAuB;IACvB,yDAAiC,CAAA;IACjC,yDAAiC,CAAA;IAEjC,gBAAgB;IAChB,qEAA6C,CAAA;IAC7C,6EAAqD,CAAA;IACrD,mEAA2C,CAAA;IAC3C,6DAAqC,CAAA;IAErC,gBAAgB;IAChB,yEAAiD,CAAA;IACjD,uEAA+C,CAAA;IAE/C,eAAe;IACf,qDAA6B,CAAA;IAC7B,+DAAuC,CAAA;IACvC,2DAAmC,CAAA;IAEnC,qBAAqB;IACrB,+CAAuB,CAAA;IACvB,qEAA6C,CAAA;IAC7C,mEAA2C,CAAA;IAC3C,2EAAmD,CAAA;IACnD,yDAAiC,CAAA;IACjC,iEAAyC,CAAA;IAEzC,gBAAgB;IAChB,yDAAiC,CAAA;IACjC,iEAAyC,CAAA;IAEzC,iBAAiB;IACjB,uDAA+B,CAAA;AACjC,CAAC,EAlCW,oBAAoB,KAApB,oBAAoB,QAkC/B;AAED;;GAEG;AACH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAIzC,YACE,IAA0B,EAC1B,OAAe,EACf,OAAiC;QAEjC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAEvB,sDAAsD;QACtD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM;QACJ,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC;IACJ,CAAC;CACF"}
@@ -12,6 +12,7 @@ export declare class MnemonicWalletProvider implements WalletProvider {
12
12
  private wallet;
13
13
  private address;
14
14
  private disconnected;
15
+ private initPromise;
15
16
  constructor(config: ManifestMCPConfig, mnemonic: string);
16
17
  /**
17
18
  * Initialize the wallet from the mnemonic
@@ -1 +1 @@
1
- {"version":3,"file":"mnemonic.d.ts","sourceRoot":"","sources":["../../src/wallet/mnemonic.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAA0C,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAExG;;;;;GAKG;AACH,qBAAa,sBAAuB,YAAW,cAAc;IAC3D,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,YAAY,CAAkB;gBAE1B,MAAM,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM;IAKvD;;OAEG;YACW,UAAU;IA2CxB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B;;;;;OAKG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAUjC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAanC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,aAAa,CAAC;CAY1C"}
1
+ {"version":3,"file":"mnemonic.d.ts","sourceRoot":"","sources":["../../src/wallet/mnemonic.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAA0C,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAExG;;;;;GAKG;AACH,qBAAa,sBAAuB,YAAW,cAAc;IAC3D,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,YAAY,CAAkB;IAGtC,OAAO,CAAC,WAAW,CAA8B;gBAErC,MAAM,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM;IAKvD;;OAEG;YACW,UAAU;IA+DxB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B;;;;;OAKG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAWjC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAanC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,aAAa,CAAC;CAY1C"}
@@ -11,6 +11,8 @@ export class MnemonicWalletProvider {
11
11
  this.wallet = null;
12
12
  this.address = null;
13
13
  this.disconnected = false;
14
+ // Promise to prevent concurrent wallet initialization (lazy init race condition)
15
+ this.initPromise = null;
14
16
  this.config = config;
15
17
  this.mnemonic = mnemonic;
16
18
  }
@@ -21,26 +23,44 @@ export class MnemonicWalletProvider {
21
23
  if (this.disconnected) {
22
24
  throw new ManifestMCPError(ManifestMCPErrorCode.WALLET_NOT_CONNECTED, 'Wallet has been disconnected and cannot be reconnected. Create a new MnemonicWalletProvider instance.');
23
25
  }
26
+ // Return if already initialized
24
27
  if (this.wallet) {
25
28
  return;
26
29
  }
30
+ // If initialization is already in progress, wait for it
31
+ if (this.initPromise) {
32
+ return this.initPromise;
33
+ }
27
34
  if (!this.mnemonic) {
28
35
  throw new ManifestMCPError(ManifestMCPErrorCode.WALLET_NOT_CONNECTED, 'Mnemonic has been cleared. Create a new MnemonicWalletProvider instance.');
29
36
  }
30
- const prefix = this.config.addressPrefix ?? 'manifest';
31
- try {
32
- this.wallet = await DirectSecp256k1HdWallet.fromMnemonic(this.mnemonic, {
33
- prefix,
34
- });
35
- const accounts = await this.wallet.getAccounts();
36
- if (accounts.length === 0) {
37
- throw new ManifestMCPError(ManifestMCPErrorCode.INVALID_MNEMONIC, 'No accounts derived from mnemonic');
37
+ // Start initialization and cache the promise to prevent concurrent init
38
+ this.initPromise = (async () => {
39
+ const prefix = this.config.addressPrefix ?? 'manifest';
40
+ try {
41
+ this.wallet = await DirectSecp256k1HdWallet.fromMnemonic(this.mnemonic, {
42
+ prefix,
43
+ });
44
+ const accounts = await this.wallet.getAccounts();
45
+ if (accounts.length === 0) {
46
+ throw new ManifestMCPError(ManifestMCPErrorCode.INVALID_MNEMONIC, 'No accounts derived from mnemonic');
47
+ }
48
+ this.address = accounts[0].address;
49
+ // Clear promise after successful init - wallet check will short-circuit future calls
50
+ this.initPromise = null;
38
51
  }
39
- this.address = accounts[0].address;
40
- }
41
- catch (error) {
42
- throw new ManifestMCPError(ManifestMCPErrorCode.INVALID_MNEMONIC, `Failed to create wallet from mnemonic: ${error instanceof Error ? error.message : String(error)}`);
43
- }
52
+ catch (error) {
53
+ // Clear state on failure so retry is possible
54
+ this.initPromise = null;
55
+ this.wallet = null;
56
+ this.address = null;
57
+ if (error instanceof ManifestMCPError) {
58
+ throw error;
59
+ }
60
+ throw new ManifestMCPError(ManifestMCPErrorCode.INVALID_MNEMONIC, `Failed to create wallet from mnemonic: ${error instanceof Error ? error.message : String(error)}`);
61
+ }
62
+ })();
63
+ return this.initPromise;
44
64
  }
45
65
  /**
46
66
  * Connect (initialize) the wallet
@@ -61,6 +81,7 @@ export class MnemonicWalletProvider {
61
81
  this.mnemonic = null;
62
82
  this.wallet = null;
63
83
  this.address = null;
84
+ this.initPromise = null;
64
85
  this.disconnected = true;
65
86
  }
66
87
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"mnemonic.js","sourceRoot":"","sources":["../../src/wallet/mnemonic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mnemonic.js","sourceRoot":"","sources":["../../src/wallet/mnemonic.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@manifest-network/manifest-mcp-browser",
3
- "version": "0.1.0",
3
+ "version": "0.1.5",
4
4
  "description": "Browser-compatible MCP server for Cosmos SDK blockchain interactions with Manifest Network using CosmJS",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -26,15 +26,20 @@
26
26
  "manifest",
27
27
  "browser"
28
28
  ],
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/manifest-network/manifest-mcp-browser"
32
+ },
29
33
  "author": "Felix C. Morency",
30
34
  "license": "MIT",
31
35
  "dependencies": {
32
- "@manifest-network/manifestjs": "2.2.0-billing-v2.0",
33
- "@modelcontextprotocol/sdk": "^1.3.0"
36
+ "@manifest-network/manifestjs": "2.2.0-billing-v2.1",
37
+ "@modelcontextprotocol/sdk": "1.25.3",
38
+ "limiter": "3.0.0"
34
39
  },
35
40
  "devDependencies": {
36
- "@types/node": "^20.10.6",
37
- "typescript": "^5.3.3",
38
- "vitest": "^4.0.18"
41
+ "@types/node": "20.19.30",
42
+ "typescript": "5.9.3",
43
+ "vitest": "4.0.18"
39
44
  }
40
45
  }
package/src/client.ts CHANGED
@@ -12,7 +12,9 @@ import {
12
12
  } from '@manifest-network/manifestjs';
13
13
  import { Registry } from '@cosmjs/proto-signing';
14
14
  import { AminoTypes } from '@cosmjs/stargate';
15
+ import { RateLimiter } from 'limiter';
15
16
  import { ManifestMCPConfig, WalletProvider, ManifestMCPError, ManifestMCPErrorCode } from './types.js';
17
+ import { DEFAULT_REQUESTS_PER_SECOND } from './config.js';
16
18
 
17
19
  // Type for the RPC query client from manifestjs liftedinit bundle
18
20
  // This includes cosmos modules + liftedinit-specific modules (billing, manifest, sku)
@@ -55,14 +57,30 @@ export class CosmosClientManager {
55
57
  private walletProvider: WalletProvider;
56
58
  private queryClient: ManifestQueryClient | null = null;
57
59
  private signingClient: SigningStargateClient | null = null;
60
+ private rateLimiter: RateLimiter;
61
+
62
+ // Promises to prevent concurrent client initialization (lazy init race condition)
63
+ private queryClientPromise: Promise<ManifestQueryClient> | null = null;
64
+ private signingClientPromise: Promise<SigningStargateClient> | null = null;
58
65
 
59
66
  private constructor(config: ManifestMCPConfig, walletProvider: WalletProvider) {
60
67
  this.config = config;
61
68
  this.walletProvider = walletProvider;
69
+
70
+ // Initialize rate limiter with configured or default requests per second
71
+ const requestsPerSecond = config.rateLimit?.requestsPerSecond ?? DEFAULT_REQUESTS_PER_SECOND;
72
+ this.rateLimiter = new RateLimiter({
73
+ tokensPerInterval: requestsPerSecond,
74
+ interval: 'second',
75
+ });
62
76
  }
63
77
 
64
78
  /**
65
- * Get or create a singleton instance for the given config
79
+ * Get or create a singleton instance for the given config.
80
+ * Instances are keyed by chainId:rpcUrl. For existing instances:
81
+ * - Config and walletProvider references are always updated
82
+ * - Signing client is disconnected/recreated if gasPrice or walletProvider changed
83
+ * - Rate limiter is updated if requestsPerSecond changed (without affecting signing client)
66
84
  */
67
85
  static getInstance(
68
86
  config: ManifestMCPConfig,
@@ -74,6 +92,37 @@ export class CosmosClientManager {
74
92
  if (!instance) {
75
93
  instance = new CosmosClientManager(config, walletProvider);
76
94
  CosmosClientManager.instances.set(key, instance);
95
+ } else {
96
+ // Check what changed to determine what needs updating
97
+ const signingClientAffected =
98
+ instance.config.gasPrice !== config.gasPrice ||
99
+ instance.walletProvider !== walletProvider;
100
+
101
+ const rateLimitChanged =
102
+ instance.config.rateLimit?.requestsPerSecond !== config.rateLimit?.requestsPerSecond;
103
+
104
+ // Always update config reference
105
+ instance.config = config;
106
+ instance.walletProvider = walletProvider;
107
+
108
+ // Only invalidate signing client if fields it depends on changed
109
+ if (signingClientAffected) {
110
+ if (instance.signingClient) {
111
+ instance.signingClient.disconnect();
112
+ instance.signingClient = null;
113
+ }
114
+ // Also clear the promise to allow re-initialization with new config
115
+ instance.signingClientPromise = null;
116
+ }
117
+
118
+ // Update rate limiter independently (doesn't affect signing client)
119
+ if (rateLimitChanged) {
120
+ const newRps = config.rateLimit?.requestsPerSecond ?? DEFAULT_REQUESTS_PER_SECOND;
121
+ instance.rateLimiter = new RateLimiter({
122
+ tokensPerInterval: newRps,
123
+ interval: 'second',
124
+ });
125
+ }
77
126
  }
78
127
 
79
128
  return instance;
@@ -90,28 +139,65 @@ export class CosmosClientManager {
90
139
  * Get the manifestjs RPC query client with all module extensions
91
140
  */
92
141
  async getQueryClient(): Promise<ManifestQueryClient> {
93
- if (!this.queryClient) {
142
+ // Return cached client if available
143
+ if (this.queryClient) {
144
+ return this.queryClient;
145
+ }
146
+
147
+ // If initialization is already in progress, wait for it
148
+ if (this.queryClientPromise) {
149
+ return this.queryClientPromise;
150
+ }
151
+
152
+ // Start initialization and cache the promise to prevent concurrent init
153
+ this.queryClientPromise = (async () => {
154
+ // Capture reference to detect if superseded by disconnect/config change
155
+ const thisInitPromise = this.queryClientPromise;
94
156
  try {
95
157
  // Use liftedinit ClientFactory which includes cosmos + liftedinit modules
96
- this.queryClient = await liftedinit.ClientFactory.createRPCQueryClient({
158
+ const client = await liftedinit.ClientFactory.createRPCQueryClient({
97
159
  rpcEndpoint: this.config.rpcUrl,
98
160
  });
161
+ // Only store if this is still the active promise
162
+ if (this.queryClientPromise === thisInitPromise) {
163
+ this.queryClient = client;
164
+ this.queryClientPromise = null;
165
+ }
166
+ return client;
99
167
  } catch (error) {
168
+ // Clear promise on failure so retry is possible (only if still active)
169
+ if (this.queryClientPromise === thisInitPromise) {
170
+ this.queryClientPromise = null;
171
+ }
100
172
  throw new ManifestMCPError(
101
173
  ManifestMCPErrorCode.RPC_CONNECTION_FAILED,
102
174
  `Failed to connect to RPC endpoint: ${error instanceof Error ? error.message : String(error)}`,
103
175
  { rpcUrl: this.config.rpcUrl }
104
176
  );
105
177
  }
106
- }
107
- return this.queryClient;
178
+ })();
179
+
180
+ return this.queryClientPromise;
108
181
  }
109
182
 
110
183
  /**
111
184
  * Get a signing client with all Manifest registries (for transactions)
112
185
  */
113
186
  async getSigningClient(): Promise<SigningStargateClient> {
114
- if (!this.signingClient) {
187
+ // Return cached client if available
188
+ if (this.signingClient) {
189
+ return this.signingClient;
190
+ }
191
+
192
+ // If initialization is already in progress, wait for it
193
+ if (this.signingClientPromise) {
194
+ return this.signingClientPromise;
195
+ }
196
+
197
+ // Start initialization and cache the promise to prevent concurrent init
198
+ this.signingClientPromise = (async () => {
199
+ // Capture reference to detect if superseded by disconnect/config change
200
+ const thisInitPromise = this.signingClientPromise;
115
201
  try {
116
202
  const signer = await this.walletProvider.getSigner();
117
203
  const gasPrice = GasPrice.fromString(this.config.gasPrice);
@@ -126,7 +212,7 @@ export class CosmosClientManager {
126
212
  // Note: Registry type from @cosmjs/proto-signing doesn't perfectly match
127
213
  // SigningStargateClientOptions due to telescope-generated proto types.
128
214
  // This is a known limitation with custom cosmos-sdk module registries.
129
- this.signingClient = await SigningStargateClient.connectWithSigner(
215
+ const client = await SigningStargateClient.connectWithSigner(
130
216
  endpoint,
131
217
  signer,
132
218
  {
@@ -137,7 +223,20 @@ export class CosmosClientManager {
137
223
  broadcastPollIntervalMs: DEFAULT_BROADCAST_POLL_INTERVAL_MS,
138
224
  }
139
225
  );
226
+ // Only store if this is still the active promise
227
+ if (this.signingClientPromise === thisInitPromise) {
228
+ this.signingClient = client;
229
+ this.signingClientPromise = null;
230
+ } else {
231
+ // Promise was superseded, clean up the client we just created
232
+ client.disconnect();
233
+ }
234
+ return client;
140
235
  } catch (error) {
236
+ // Clear promise on failure so retry is possible (only if still active)
237
+ if (this.signingClientPromise === thisInitPromise) {
238
+ this.signingClientPromise = null;
239
+ }
141
240
  if (error instanceof ManifestMCPError) {
142
241
  throw error;
143
242
  }
@@ -147,8 +246,9 @@ export class CosmosClientManager {
147
246
  { rpcUrl: this.config.rpcUrl }
148
247
  );
149
248
  }
150
- }
151
- return this.signingClient;
249
+ })();
250
+
251
+ return this.signingClientPromise;
152
252
  }
153
253
 
154
254
  /**
@@ -165,6 +265,14 @@ export class CosmosClientManager {
165
265
  return this.config;
166
266
  }
167
267
 
268
+ /**
269
+ * Acquire a rate limit token before making an RPC request.
270
+ * This will wait if the rate limit has been exceeded.
271
+ */
272
+ async acquireRateLimit(): Promise<void> {
273
+ await this.rateLimiter.removeTokens(1);
274
+ }
275
+
168
276
  /**
169
277
  * Disconnect all clients
170
278
  */
@@ -173,6 +281,8 @@ export class CosmosClientManager {
173
281
  this.signingClient.disconnect();
174
282
  this.signingClient = null;
175
283
  }
284
+ this.signingClientPromise = null;
176
285
  this.queryClient = null;
286
+ this.queryClientPromise = null;
177
287
  }
178
288
  }
@@ -29,6 +29,28 @@ describe('createConfig', () => {
29
29
  expect(config.gasAdjustment).toBe(2.0);
30
30
  expect(config.addressPrefix).toBe('custom');
31
31
  });
32
+
33
+ it('should apply default rateLimit', () => {
34
+ const config = createConfig({
35
+ chainId: 'test-chain',
36
+ rpcUrl: 'https://example.com',
37
+ gasPrice: '1.0umfx',
38
+ });
39
+
40
+ expect(config.rateLimit).toBeDefined();
41
+ expect(config.rateLimit?.requestsPerSecond).toBe(10);
42
+ });
43
+
44
+ it('should preserve provided rateLimit', () => {
45
+ const config = createConfig({
46
+ chainId: 'test-chain',
47
+ rpcUrl: 'https://example.com',
48
+ gasPrice: '1.0umfx',
49
+ rateLimit: { requestsPerSecond: 20 },
50
+ });
51
+
52
+ expect(config.rateLimit?.requestsPerSecond).toBe(20);
53
+ });
32
54
  });
33
55
 
34
56
  describe('validateConfig', () => {
@@ -108,6 +130,140 @@ describe('validateConfig', () => {
108
130
  expect(result.valid).toBe(false);
109
131
  expect(result.errors.some(e => e.includes('addressPrefix'))).toBe(true);
110
132
  });
133
+
134
+ it('should accept HTTPS URLs', () => {
135
+ const result = validateConfig({
136
+ chainId: 'test',
137
+ rpcUrl: 'https://rpc.example.com',
138
+ gasPrice: '1.0umfx',
139
+ });
140
+
141
+ expect(result.valid).toBe(true);
142
+ });
143
+
144
+ it('should accept HTTP URLs for localhost', () => {
145
+ const result = validateConfig({
146
+ chainId: 'test',
147
+ rpcUrl: 'http://localhost:26657',
148
+ gasPrice: '1.0umfx',
149
+ });
150
+
151
+ expect(result.valid).toBe(true);
152
+ });
153
+
154
+ it('should accept HTTP URLs for 127.0.0.1', () => {
155
+ const result = validateConfig({
156
+ chainId: 'test',
157
+ rpcUrl: 'http://127.0.0.1:26657',
158
+ gasPrice: '1.0umfx',
159
+ });
160
+
161
+ expect(result.valid).toBe(true);
162
+ });
163
+
164
+ it('should accept HTTP URLs for IPv6 localhost', () => {
165
+ const result = validateConfig({
166
+ chainId: 'test',
167
+ rpcUrl: 'http://[::1]:26657',
168
+ gasPrice: '1.0umfx',
169
+ });
170
+
171
+ expect(result.valid).toBe(true);
172
+ });
173
+
174
+ it('should reject HTTP URLs for non-localhost', () => {
175
+ const result = validateConfig({
176
+ chainId: 'test',
177
+ rpcUrl: 'http://rpc.example.com',
178
+ gasPrice: '1.0umfx',
179
+ });
180
+
181
+ expect(result.valid).toBe(false);
182
+ expect(result.errors.some(e => e.includes('HTTPS'))).toBe(true);
183
+ });
184
+
185
+ it('should accept valid rateLimit config', () => {
186
+ const result = validateConfig({
187
+ chainId: 'test',
188
+ rpcUrl: 'https://example.com',
189
+ gasPrice: '1.0umfx',
190
+ rateLimit: { requestsPerSecond: 5 },
191
+ });
192
+
193
+ expect(result.valid).toBe(true);
194
+ });
195
+
196
+ it('should reject non-integer rateLimit.requestsPerSecond', () => {
197
+ const result = validateConfig({
198
+ chainId: 'test',
199
+ rpcUrl: 'https://example.com',
200
+ gasPrice: '1.0umfx',
201
+ rateLimit: { requestsPerSecond: 5.5 },
202
+ });
203
+
204
+ expect(result.valid).toBe(false);
205
+ expect(result.errors.some(e => e.includes('requestsPerSecond'))).toBe(true);
206
+ });
207
+
208
+ it('should reject negative rateLimit.requestsPerSecond', () => {
209
+ const result = validateConfig({
210
+ chainId: 'test',
211
+ rpcUrl: 'https://example.com',
212
+ gasPrice: '1.0umfx',
213
+ rateLimit: { requestsPerSecond: -1 },
214
+ });
215
+
216
+ expect(result.valid).toBe(false);
217
+ expect(result.errors.some(e => e.includes('requestsPerSecond'))).toBe(true);
218
+ });
219
+
220
+ it('should reject zero rateLimit.requestsPerSecond', () => {
221
+ const result = validateConfig({
222
+ chainId: 'test',
223
+ rpcUrl: 'https://example.com',
224
+ gasPrice: '1.0umfx',
225
+ rateLimit: { requestsPerSecond: 0 },
226
+ });
227
+
228
+ expect(result.valid).toBe(false);
229
+ expect(result.errors.some(e => e.includes('requestsPerSecond'))).toBe(true);
230
+ });
231
+
232
+ it('should reject null rateLimit', () => {
233
+ const result = validateConfig({
234
+ chainId: 'test',
235
+ rpcUrl: 'https://example.com',
236
+ gasPrice: '1.0umfx',
237
+ rateLimit: null as unknown as { requestsPerSecond?: number },
238
+ });
239
+
240
+ expect(result.valid).toBe(false);
241
+ expect(result.errors.some(e => e.includes('rateLimit must be a plain object'))).toBe(true);
242
+ });
243
+
244
+ it('should reject non-object rateLimit', () => {
245
+ const result = validateConfig({
246
+ chainId: 'test',
247
+ rpcUrl: 'https://example.com',
248
+ gasPrice: '1.0umfx',
249
+ rateLimit: 'invalid' as unknown as { requestsPerSecond?: number },
250
+ });
251
+
252
+ expect(result.valid).toBe(false);
253
+ expect(result.errors.some(e => e.includes('rateLimit must be a plain object'))).toBe(true);
254
+ });
255
+
256
+ it('should reject array rateLimit', () => {
257
+ const result = validateConfig({
258
+ chainId: 'test',
259
+ rpcUrl: 'https://example.com',
260
+ gasPrice: '1.0umfx',
261
+ rateLimit: [] as unknown as { requestsPerSecond?: number },
262
+ });
263
+
264
+ expect(result.valid).toBe(false);
265
+ expect(result.errors.some(e => e.includes('rateLimit must be a plain object'))).toBe(true);
266
+ });
111
267
  });
112
268
 
113
269
  describe('createValidatedConfig', () => {
package/src/config.ts CHANGED
@@ -11,15 +11,47 @@ const DEFAULT_GAS_ADJUSTMENT = 1.3;
11
11
  const DEFAULT_ADDRESS_PREFIX = 'manifest';
12
12
 
13
13
  /**
14
- * Validate a URL string
14
+ * Default requests per second for rate limiting
15
15
  */
16
- function isValidUrl(url: string): boolean {
17
- try {
18
- new URL(url);
16
+ export const DEFAULT_REQUESTS_PER_SECOND = 10;
17
+
18
+ /**
19
+ * Check if a hostname is localhost (IPv4, IPv6, or hostname)
20
+ * Handles both bracketed and unbracketed IPv6 formats
21
+ */
22
+ function isLocalhostHostname(hostname: string): boolean {
23
+ if (hostname === 'localhost' || hostname === '127.0.0.1') {
19
24
  return true;
25
+ }
26
+ // Handle IPv6 localhost - hostname may be '::1' or '[::1]' depending on environment
27
+ const normalizedHostname = hostname.replace(/^\[|\]$/g, '');
28
+ return normalizedHostname === '::1';
29
+ }
30
+
31
+ /**
32
+ * Validate URL format and check if it uses HTTPS or is localhost (HTTP allowed for local dev)
33
+ * Returns validation result with error reason if invalid
34
+ */
35
+ function validateRpcUrl(url: string): { valid: boolean; reason?: string } {
36
+ let parsed: URL;
37
+ try {
38
+ parsed = new URL(url);
20
39
  } catch {
21
- return false;
40
+ return { valid: false, reason: 'rpcUrl must be a valid URL' };
22
41
  }
42
+
43
+ if (parsed.protocol === 'https:') {
44
+ return { valid: true };
45
+ }
46
+
47
+ if (parsed.protocol === 'http:' && isLocalhostHostname(parsed.hostname)) {
48
+ return { valid: true }; // HTTP allowed for localhost
49
+ }
50
+
51
+ return {
52
+ valid: false,
53
+ reason: `RPC URL must use HTTPS (got ${parsed.protocol}//). HTTP is only allowed for local development (localhost, 127.0.0.1, ::1).`,
54
+ };
23
55
  }
24
56
 
25
57
  /**
@@ -48,6 +80,9 @@ export function createConfig(input: ManifestMCPConfig): ManifestMCPConfig {
48
80
  gasPrice: input.gasPrice,
49
81
  gasAdjustment: input.gasAdjustment ?? DEFAULT_GAS_ADJUSTMENT,
50
82
  addressPrefix: input.addressPrefix ?? DEFAULT_ADDRESS_PREFIX,
83
+ rateLimit: {
84
+ requestsPerSecond: input.rateLimit?.requestsPerSecond ?? DEFAULT_REQUESTS_PER_SECOND,
85
+ },
51
86
  };
52
87
  }
53
88
 
@@ -74,8 +109,11 @@ export function validateConfig(config: Partial<ManifestMCPConfig>): ValidationRe
74
109
 
75
110
  if (!config.rpcUrl) {
76
111
  errors.push('rpcUrl is required');
77
- } else if (!isValidUrl(config.rpcUrl)) {
78
- errors.push('rpcUrl must be a valid URL');
112
+ } else {
113
+ const urlCheck = validateRpcUrl(config.rpcUrl);
114
+ if (!urlCheck.valid) {
115
+ errors.push(urlCheck.reason!);
116
+ }
79
117
  }
80
118
 
81
119
  if (!config.gasPrice) {
@@ -97,6 +135,20 @@ export function validateConfig(config: Partial<ManifestMCPConfig>): ValidationRe
97
135
  }
98
136
  }
99
137
 
138
+ if (config.rateLimit !== undefined) {
139
+ if (typeof config.rateLimit !== 'object' || config.rateLimit === null || Array.isArray(config.rateLimit)) {
140
+ errors.push('rateLimit must be a plain object');
141
+ } else if (config.rateLimit.requestsPerSecond !== undefined) {
142
+ if (
143
+ typeof config.rateLimit.requestsPerSecond !== 'number' ||
144
+ config.rateLimit.requestsPerSecond <= 0 ||
145
+ !Number.isInteger(config.rateLimit.requestsPerSecond)
146
+ ) {
147
+ errors.push('rateLimit.requestsPerSecond must be a positive integer');
148
+ }
149
+ }
150
+ }
151
+
100
152
  return {
101
153
  valid: errors.length === 0,
102
154
  errors,