Custom Contracts
schemos works with any CosmWasm contract that has JSON Schema output from cargo schema.
Generate Schemas
In your contract's Rust project:
cargo schema
# → schema/raw/
# execute.json
# query.json
# response_to_balance.json
# response_to_get_config.json
# ...Import as as const
Copy the JSON files into your TypeScript project and paste them as as const objects:
const executeSchema = { /* paste cargo schema JSON here */ } as const
const querySchema = { /* paste cargo schema JSON here */ } as constBasic Usage
import { createTypedContract } from 'schemos'
const contract = createTypedContract(client, 'osmo1...', {
execute: executeSchema,
query: querySchema,
})
// Full autocomplete + type checking for your contract messages
await contract.execute(sender, 'your_msg', { /* typed fields */ }, 'auto')
const result = await contract.query('get_state', {})
// result: unknown (no response schemas provided)With Response Typing
Paste response schemas and map them by query message name:
const responseSchemas = {
get_state: { /* paste response_to_get_state.json */ } as const,
get_config: { /* paste response_to_get_config.json */ } as const,
}
const contract = createTypedContract(client, 'osmo1...', {
execute: executeSchema,
query: querySchema,
responses: responseSchemas,
})
// Return type inferred from response schema
const state = await contract.query('get_state', {})
// state: { owner: string; count: number; ... } — inferred from response JSON SchemaStandalone Message Building
Use createMsgBuilder when you need typed messages without a client:
import { createMsgBuilder } from 'schemos'
const myMsg = createMsgBuilder(executeSchema)
const envelope = myMsg('your_msg', { /* typed fields */ })
// Use envelope with any client or SDK
await client.execute(sender, contract, envelope, fee)Type Extraction
Extract TypeScript types from your schemas for use elsewhere:
import type { InferMsg, MessageNames, MessageArgs, InferResponse } from 'schemos'
// Full message union type
type MyExecuteMsg = InferMsg<typeof executeSchema>
// Just the message names
type MyMsgNames = MessageNames<MyExecuteMsg>
// Args for a specific message
type YourMsgArgs = MessageArgs<MyExecuteMsg, 'your_msg'>
// Response type for a specific query
type StateResponse = InferResponse<typeof responseSchemas, 'get_state'>Limitations
- Source required: JSON Schema is not stored on-chain. You need the contract source (or its published schema) to use schemos. This is the same limitation as EVM contracts without verified source/ABI.
as constrequired: JSON imports lose literal types during module resolution (TypeScript#32063). Paste the JSON directly and mark itas const.