{"id":47698091,"url":"https://github.com/2wheeh/cosmock","last_synced_at":"2026-04-03T19:00:59.469Z","repository":{"id":347549586,"uuid":"1194380729","full_name":"2wheeh/cosmock","owner":"2wheeh","description":"HTTP testing instances for Cosmos","archived":false,"fork":false,"pushed_at":"2026-04-02T06:35:57.000Z","size":157,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-03T03:23:34.500Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/2wheeh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-28T09:22:35.000Z","updated_at":"2026-04-02T06:36:01.000Z","dependencies_parsed_at":"2026-04-03T19:00:48.668Z","dependency_job_id":null,"html_url":"https://github.com/2wheeh/cosmock","commit_stats":null,"previous_names":["2wheeh/cosmock"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/2wheeh/cosmock","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2wheeh%2Fcosmock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2wheeh%2Fcosmock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2wheeh%2Fcosmock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2wheeh%2Fcosmock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/2wheeh","download_url":"https://codeload.github.com/2wheeh/cosmock/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/2wheeh%2Fcosmock/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31371633,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T17:53:18.093Z","status":"ssl_error","status_checked_at":"2026-04-03T17:53:17.617Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-02T16:48:28.466Z","updated_at":"2026-04-03T19:00:59.461Z","avatar_url":"https://github.com/2wheeh.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cosmock\n\n\u003e [!WARNING]\n\u003e This project is under active development. APIs may change without notice until v1.0.\n\nHTTP testing instances for Cosmos.\n\nLightweight alternative to [Starship](https://github.com/cosmology-tech/starship) — run real Cosmos SDK chain nodes as child processes without Docker or Kubernetes.\n\nInspired by [prool](https://github.com/wevm/prool) (HTTP testing instances for Ethereum).\n\n## Features\n\n- Spawn real Cosmos SDK nodes as child processes\n- No Docker, no Kubernetes — just a Go binary\n- Genesis account injection with mnemonic recovery\n- Full lifecycle management (start/stop/restart)\n- Compatible with [@cosmjs/stargate](https://github.com/cosmos/cosmjs) and [@cosmjs/cosmwasm-stargate](https://github.com/cosmos/cosmjs) for testing\n- Extensible to any Cosmos SDK chain binary via `cosmosBase`\n\n## Instances\n\n| Instance           | Binary  | Modules                                         | Use case                     |\n| ------------------ | ------- | ----------------------------------------------- | ---------------------------- |\n| `Instance.simd()`  | `simd`  | bank, staking, gov, mint                        | Basic Cosmos SDK testing     |\n| `Instance.wasmd()` | `wasmd` | bank, staking, gov, mint, **IBC**, **CosmWasm** | Contract deploy/execute, IBC |\n\n## Install\n\n```bash\npnpm add -D cosmock\n```\n\n### Prerequisites\n\nInstall the binary for the instance you need. Requires [Go](https://go.dev/dl/) \u003e= 1.25.\n\n**simd** (Cosmos SDK simapp):\n\n```bash\ngit clone --depth 1 https://github.com/cosmos/cosmos-sdk.git /tmp/cosmos-sdk\ncd /tmp/cosmos-sdk/simapp \u0026\u0026 go build -o ~/go/bin/simd ./simd/\n```\n\n**wasmd** (CosmWasm — includes IBC):\n\n```bash\ngit clone --depth 1 https://github.com/CosmWasm/wasmd.git /tmp/wasmd\ncd /tmp/wasmd \u0026\u0026 go build -o ~/go/bin/wasmd ./cmd/wasmd/\n```\n\n### Prebuilt binaries (CI)\n\nPrebuilt `linux/amd64` binaries are available in [GitHub Releases](https://github.com/2wheeh/cosmock/releases/tag/binaries/latest) for CI environments:\n\n```bash\n# Download and install (e.g. in GitHub Actions)\ngh release download \"binaries/latest\" --repo 2wheeh/cosmock --pattern \"*.gz\" --dir /tmp\ngunzip -c /tmp/simd-linux-amd64.gz \u003e /usr/local/bin/simd\ngunzip -c /tmp/wasmd-linux-amd64.gz \u003e /usr/local/bin/wasmd\nchmod +x /usr/local/bin/simd /usr/local/bin/wasmd\n```\n\n\u003e For local development on macOS/Windows, build from source using the instructions above.\n\n## Usage\n\n### Basic (simd)\n\n```ts\nimport { Instance } from 'cosmock';\n\nconst instance = Instance.simd({\n  chainId: 'test-1',\n  denom: 'stake',\n  accounts: [\n    {\n      mnemonic: 'abandon abandon abandon ...',\n      coins: '1000000000stake',\n      name: 'alice',\n    },\n  ],\n});\n\nawait instance.start();\n\n// Connect with cosmjs\nimport { StargateClient } from '@cosmjs/stargate';\nconst client = await StargateClient.connect(`http://localhost:${instance.port}`);\nconst balance = await client.getBalance(address, 'stake');\n\nawait instance.stop();\n```\n\n### CosmWasm (wasmd)\n\n```ts\nimport { Instance } from 'cosmock';\nimport { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate';\nimport { GasPrice } from '@cosmjs/stargate';\n\nconst instance = Instance.wasmd({\n  chainId: 'wasm-test-1',\n  accounts: [{ mnemonic: '...', coins: '1000000000stake', name: 'alice' }],\n});\nawait instance.start();\n\nconst client = await SigningCosmWasmClient.connectWithSigner(`http://localhost:${instance.port}`, wallet, {\n  gasPrice: GasPrice.fromString('0stake'),\n});\n\n// Upload, instantiate, execute\nconst { codeId } = await client.upload(address, wasmBytecode, 'auto');\nconst { contractAddress } = await client.instantiate(address, codeId, initMsg, 'label', 'auto');\nconst result = await client.execute(address, contractAddress, executeMsg, 'auto');\n```\n\n### vitest globalSetup (provide/inject)\n\n```ts\n// test/global-setup.ts\nimport type { TestProject } from 'vitest/node';\nimport { Instance } from 'cosmock';\n\nexport default async function setup({ provide }: TestProject) {\n  const instance = Instance.wasmd({\n    chainId: 'test-1',\n    accounts: [{ mnemonic: '...', coins: '1000000000stake' }],\n  });\n  await instance.start();\n\n  provide('rpcUrl', `http://localhost:${instance.port}`);\n\n  return () =\u003e instance.stop();\n}\n\ndeclare module 'vitest' {\n  export interface ProvidedContext {\n    rpcUrl: string;\n  }\n}\n```\n\n```ts\n// vitest.config.ts\nexport default defineConfig({\n  test: {\n    globalSetup: './test/global-setup.ts',\n  },\n});\n```\n\n```ts\n// test/bank.test.ts\nimport { inject } from 'vitest';\n\nconst rpcUrl = inject('rpcUrl');\n\nit('queries balance', async () =\u003e {\n  const client = await StargateClient.connect(rpcUrl);\n  const balance = await client.getBalance(address, 'stake');\n  // ...\n});\n```\n\n### Multi-chain\n\n```ts\nconst chain1 = Instance.wasmd({\n  chainId: 'wasm-1',\n  rpcPort: 26657,\n  grpcPort: 9090,\n  apiPort: 1317,\n  p2pPort: 26656,\n});\n\nconst chain2 = Instance.wasmd({\n  chainId: 'wasm-2',\n  rpcPort: 26660,\n  grpcPort: 9092,\n  apiPort: 1318,\n  p2pPort: 26661,\n});\n\nawait Promise.all([chain1.start(), chain2.start()]);\n```\n\n### Custom chain binary\n\n```ts\nimport { Instance, cosmosBase } from 'cosmock';\n\n// Any Cosmos SDK binary works — same init/genesis/start flow\nconst gaiad = Instance.define(params =\u003e cosmosBase({ binary: 'gaiad', name: 'gaiad', ...params }));\n```\n\n## API\n\n### `Instance.simd(parameters?, options?)`\n\nCreates a simd (Cosmos SDK simapp) instance.\n\n### `Instance.wasmd(parameters?, options?)`\n\nCreates a wasmd (CosmWasm + IBC) instance. Same parameters as simd.\n\n### Parameters\n\nShared by all instances (`CosmosChainParameters`):\n\n| Parameter          | Type              | Default           | Description        |\n| ------------------ | ----------------- | ----------------- | ------------------ |\n| `binary`           | `string`          | instance-specific | Path to binary     |\n| `chainId`          | `string`          | `\"cosmock-1\"`     | Chain ID           |\n| `denom`            | `string`          | `\"stake\"`         | Default denom      |\n| `accounts`         | `CosmosAccount[]` | `[]`              | Genesis accounts   |\n| `minimumGasPrices` | `string`          | `\"0{denom}\"`      | Minimum gas prices |\n| `rpcPort`          | `number`          | `26657`           | CometBFT RPC port  |\n| `grpcPort`         | `number`          | `9090`            | gRPC port          |\n| `apiPort`          | `number`          | `1317`            | REST API port      |\n| `p2pPort`          | `number`          | `26656`           | P2P port           |\n| `grpcWebPort`      | `number`          | `9091`            | gRPC-Web port      |\n| `pprofPort`        | `number`          | `6060`            | pprof port         |\n\n### Instance options (second argument)\n\n| Option          | Type     | Default | Description                        |\n| --------------- | -------- | ------- | ---------------------------------- |\n| `messageBuffer` | `number` | `20`    | Max messages to store in-memory    |\n| `timeout`       | `number` | `60000` | Start/stop timeout in milliseconds |\n\n```ts\nconst instance = Instance.wasmd({ chainId: 'test-1' }, { timeout: 30_000 });\n```\n\n### Instance methods\n\n| Method                | Description                                                            |\n| --------------------- | ---------------------------------------------------------------------- |\n| `start()`             | Start the instance. Returns a stop function.                           |\n| `stop()`              | Stop the instance and cleanup temp directory.                          |\n| `restart()`           | Stop then start.                                                       |\n| `on(event, handler)`  | Listen to events (`message`, `stdout`, `stderr`, `listening`, `exit`). |\n| `off(event, handler)` | Remove event listener.                                                 |\n\n### Instance properties\n\n| Property   | Type     | Description                                                             |\n| ---------- | -------- | ----------------------------------------------------------------------- |\n| `status`   | `string` | `idle` / `starting` / `started` / `stopping` / `stopped` / `restarting` |\n| `host`     | `string` | Host (default: `localhost`)                                             |\n| `port`     | `number` | RPC port                                                                |\n| `name`     | `string` | Instance name                                                           |\n| `messages` | `object` | `.get()` returns buffered messages, `.clear()` clears them              |\n\n## Testing strategies\n\n| Strategy                 | Isolation | Speed     | Use case                                    |\n| ------------------------ | --------- | --------- | ------------------------------------------- |\n| **Account isolation**    | Practical | Fast      | Most tests — each test uses unique accounts |\n| **Suite-level instance** | Full      | ~5s setup | Tests that modify chain-wide state          |\n| **Shared instance**      | None      | Fastest   | Read-only queries, smoke tests              |\n\nRecommended: fund multiple accounts in genesis, assign each test its own account(s).\n\n## Why not Starship?\n\n|              | Starship                   | cosmock              |\n| ------------ | -------------------------- | -------------------- |\n| Infra        | Kubernetes + Helm + Docker | None (child process) |\n| Startup      | 2-5 min                    | 3-5 sec              |\n| Dependencies | K8s cluster                | Go binary            |\n| State reset  | Helm redeploy (minutes)    | kill + restart (~3s) |\n| Best for     | Production simulation      | Dev/test             |\n\n## TODO\n\n- [ ] `cosmosEvmBase` — EVM JSON-RPC port support for EVM-enabled chains (e.g. xpla, evmos)\n- [ ] `cosmock.config.ts` — config-based chain + relayer declaration\n- [ ] `cosmock/vitest` — vitest plugin (automatic setup/teardown via `vitestPlugin(config)`)\n- [ ] `cosmock/playwright` — playwright plugin (`playwrightPlugin(config)`)\n- [ ] Automatic port allocation (avoid port conflicts in parallel tests)\n- [ ] `findFreePorts()` utility for direct `Instance` users\n- [ ] `cosmock/setup-binaries` GitHub Action for CI binary setup\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F2wheeh%2Fcosmock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F2wheeh%2Fcosmock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F2wheeh%2Fcosmock/lists"}