graz-sh/graz/static

Claude Code and agent skill by graz-sh/graz

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

React hooks for Cosmos blockchain interactions — connect wallets, query balances, send tokens, sign messages. Use when building Cosmos dApps with graz hooks, setting up GrazProvider, connecting wallets, or performing transactions.

Install

npx vskill@latest install graz-sh/graz/static

SKILL.md

Using the graz Library

React hooks for Cosmos blockchain interactions.

Quick start

tsx
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { GrazProvider, useConnect, useAccount, useSendTokens, useStargateSigningClient } from "graz";
import { cosmoshub } from "graz/chains";
const queryClient = new QueryClient();
export function App() {
return (
<QueryClientProvider client={queryClient}>
<GrazProvider grazOptions={{ chains: [cosmoshub] }}>
<Wallet />
</GrazProvider>
</QueryClientProvider>
);
}
function Wallet() {
const { connect } = useConnect();
const { data: accounts, isConnected } = useAccount({ chainId: ["cosmoshub-4"] as const });
const { data: signingClients } = useStargateSigningClient({ chainId: ["cosmoshub-4"] as const, enabled: isConnected });
const { sendTokens } = useSendTokens();
const addr = accounts?.["cosmoshub-4"]?.bech32Address;
return (
<button onClick={async () => {
if (!addr) return connect();
await sendTokens({ signingClient: signingClients?.["cosmoshub-4"], senderAddress: addr, recipientAddress: "cosmos1...", amount: [{ denom: "uatom", amount: "1000" }], fee: { amount: [{ denom: "uatom", amount: "500" }], gas: "200000" } });
}}>{addr || "Connect"}</button>
);
}

Provider Setup

tsx
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { GrazProvider } from "graz";
import { cosmoshub } from "graz/chains";
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<GrazProvider grazOptions={{ chains: [cosmoshub] }}>
<YourApp />
</GrazProvider>
</QueryClientProvider>
);
}

GrazProvider must be inside QueryClientProvider. The chains prop is required — pass ChainInfo[] (from graz/chains, defineChainInfo(), or manually).

Configure Options

ts
interface ConfigureGrazArgs {
chains: ChainInfo[];
defaultWallet?: WalletType; // Default: Keplr
chainsConfig?: Record<string, ChainConfig>; // Per-chain: { rpcHeaders, gas: { price, denom } }
autoReconnect?: boolean; // Default: true
walletConnect?: { // WalletConnect config
options: { projectId: string };
modalOptions?: ModalConfig;
};
walletDefaultOptions?: Keplr["defaultOptions"];
multiChainFetchConcurrency?: number; // Default: 3
onNotFound?: () => void;
onReconnectFailed?: () => void;
iframeOptions?: IframeOptions; // Cosmiframe config
pingInteval?: number; // MS between pings, default: 1hr
logger?: { enabled?: boolean; level?: LogLevel; categories?: (keyof typeof LogCategory)[] };
paraConfig?: ParaGrazConfig; // Para wallet config
}

Chain Info

ts
import { defineChainInfo, defineChains } from "graz";
// Type-safe helpers (identity functions)
const myChain = defineChainInfo({
chainId: "mychain-1",
currencies: [{ coinDenom: "TOKEN", coinMinimalDenom: "utoken", coinDecimals: 6 }],
rpc: "https://rpc.example.com",
rest: "https://rest.example.com",
bech32Config: {
bech32PrefixAccAddr: "mychain",
bech32PrefixAccPub: "mychainpub",
bech32PrefixValAddr: "mychainvaloper",
bech32PrefixValPub: "mychainvaloperpub",
bech32PrefixConsAddr: "mychainvalcons",
bech32PrefixConsPub: "mychainvalconspub",
},
chainName: "My Chain",
feeCurrencies: [{ coinDenom: "TOKEN", coinMinimalDenom: "utoken", coinDecimals: 6 }],
stakeCurrency: { coinDenom: "TOKEN", coinMinimalDenom: "utoken", coinDecimals: 6 },
bip44: { coinType: 118 },
});
defineChains({ cosmoshub, osmosis }); // Wraps Record<string, ChainInfo> for type safety
CLI Generate
bash
pnpm graz cli --generate # Generate all chains
pnpm graz cli --generate --mainnet cosmoshub,osmosis --testnet osmosistestnet
pnpm graz cli --generate --endpoint <url> # Custom registry endpoint
pnpm graz cli --generate --best # Use lowest-latency endpoints
pnpm graz cli --generate --authz # Authz-compatible chains only

Output goes to packages/graz/chains/index.{js,mjs,ts} (gitignored).

ts
import { cosmoshub, osmosis, mainnetChains, testnetChains } from "graz/chains";

Wallet Connection

Connect
ts
import { useConnect, useAccount, useDisconnect, useActiveWalletType, useCheckWallet } from "graz";
import { WalletType } from "graz";
// Mutation hook
const { connect, connectAsync, isLoading, isSuccess, isSupported, error } = useConnect();
connect(); // Default wallet
connect({ walletType: WalletType.KEPLR }); // Specific wallet
connect({ chainId: ["cosmoshub-4", "osmosis-1"] }); // Specific chains
connect({ walletType: WalletType.LEAP, chainId: ["cosmoshub-4"] });
connect({ autoReconnect: false });
// Actions (no hook)
import { connect, disconnect, getAvailableWallets, checkWallet, clearSession } from "graz";
await connect({ walletType: WalletType.KEPLR });
Reactive Account State
ts
// Single chain (generic Record)
const { data: accounts, isConnected, isConnecting, isDisconnected, status, reconnect } = useAccount();
const address = Object.values(accounts || {})[0]?.bech32Address;
// Multi-chain with typed chain IDs (use `as const`)
const { data: accounts } = useAccount({ chainId: ["cosmoshub-4", "osmosis-1"] as const });
// accounts?.["cosmoshub-4"] is Key | undefined — fully typed
// accounts?.["osmosis-1"] is Key | undefined
const atomAddress = accounts?.["cosmoshub-4"]?.bech32Address;
Check Wallet Availability
ts
// Reactive hook
const { data: isKeplrAvailable } = useCheckWallet(WalletType.KEPLR);
const { data: isCosmostationAvailable } = useCheckWallet(WalletType.COSMOSTATION);
// Imperative
const available = getAvailableWallets(); // Record<WalletType, boolean>
const supported = checkWallet(); // Default wallet
const cosmostationSupported = checkWallet(WalletType.COSMOSTATION);
// Active wallet info
const { walletType, isKeplr, isCosmostation, isWalletConnect } = useActiveWalletType();
Disconnect
ts
const { disconnect, disconnectAsync, isLoading } = useDisconnect();
disconnect(); // All chains
disconnect({ chainId: ["cosmoshub-4"] }); // Specific chain only
// Actions
import { clearSession } from "graz";
clearSession(); // Reset session + clear storage
Wallet Events

Use useWalletEvents to react to committed wallet state changes. The hook owns its subscription and automatically cleans it up when the component unmounts.

tsx
import { useWalletEvents } from "graz";
function WalletEventObserver() {
useWalletEvents({
onAccountChange: ({ accounts, previousAccounts, changedChainIds, walletType }) => {
console.log({ accounts, previousAccounts, changedChainIds, walletType });
},
onActiveChainsChange: ({ activeChainIds, previousActiveChainIds, walletType }) => {
console.log({ activeChainIds, previousActiveChainIds, walletType });
},
onDisconnect: ({ chainIds, reason, walletType }) => {
console.log({ chainIds, reason, walletType });
},
});
return null;
}

onActiveChainsChange reports the complete set of connected activeChainIds. It does not represent an EVM-style switch to one active chain. Initial connection does not emit account or active-chain events.

For non-React consumers, subscribe imperatively and retain the cleanup function:

ts
import { subscribeWalletEvents } from "graz";
const unsubscribe = subscribeWalletEvents({
onDisconnect: ({ reason }) => console.log(reason),
});
unsubscribe();

Balance changes are not wallet events. Use useBalance or useBalances and an explicit refetch strategy when balance monitoring is required.

Offline Signers

ts
const { data: signers } = useOfflineSigners();
const { data: signers } = useOfflineSigners({ chainId: ["cosmoshub-4"] as const });
// signers?.["cosmoshub-4"] is OfflineSigners
const { offlineSigner, offlineSignerAmino, offlineSignerAuto } = signers?.["cosmoshub-4"] || {};
// Imperative
import { getOfflineSigners } from "graz";
const signers = await getOfflineSigners({ chainId: "cosmoshub-4", walletType: WalletType.KEPLR });

Balance Queries

ts
// All balances
const { data: balances } = useBalances({
chainId: "cosmoshub-4",
bech32Address: "cosmos1...",
enabled: Boolean(address),
});
// balances is Coin[] | undefined
// Single denom
const { data: atomBalance } = useBalance({
chainId: "cosmoshub-4",
bech32Address: "cosmos1...",
denom: "uatom",
enabled: Boolean(address),
});
// atomBalance is Coin | undefined
// Staked balance
const { data: staked } = useBalanceStaked({
chainId: "cosmoshub-4",
bech32Address: "cosmos1...",
enabled: Boolean(address),
});

Clients

Read Clients
ts
const { data: stargateClients } = useStargateClient({
chainId: ["cosmoshub-4"] as const,
enabled: Boolean(connected),
});
// stargateClients?.["cosmoshub-4"] is StargateClient | undefined
const { data: cosmwasmClients } = useCosmWasmClient({
chainId: ["neutron-1"] as const,
enabled: Boolean(connected),
});
Signing Clients (requires wallet connected)
ts
const { data: signingClients, isLoading } = useStargateSigningClient({
chainId: ["cosmoshub-4"] as const,
enabled: isConnected,
offlineSigner: "offlineSignerAuto", // "offlineSigner" | "offlineSignerAuto" | "offlineSignerOnlyAmino"
});
const { data: cosmwasmSigningClients } = useCosmWasmSigningClient({
chainId: ["neutron-1"] as const,
enabled: isConnected,
});
// Use client
await signingClients?.["cosmoshub-4"]?.sendTokens(
senderAddress,
recipientAddress,
[{ denom: "uatom", amount: "1000" }],
{ amount: [{ denom: "uatom", amount: "500" }], gas: "200000" }
);

Transaction Hooks

ts
// Send tokens
const { sendTokens, sendTokensAsync, isPending, isSuccess, isError, data, reset } = useSendTokens();
sendTokens({
signingClient: signingClients?.["cosmoshub-4"],
senderAddress: account?.bech32Address,
recipientAddress: "cosmos1...",
amount: [{ denom: "uatom", amount: "1000" }],
fee: { amount: [{ denom: "uatom", amount: "500" }], gas: "200000" },
memo: "optional memo",
});
// IBC transfer
const { sendIbcTokens } = useSendIbcTokens();
sendIbcTokens({
signingClient,
senderAddress,
recipientAddress: "osmo1...",
transferAmount: { denom: "uatom", amount: "1000" },
sourcePort: "transfer",
sourceChannel: "channel-0",
timeoutTimestamp: (Date.now() + 600_000) * 1_000_000, // 10 min in nanos
fee: { amount: [{ denom: "uatom", amount: "500" }], gas: "200000" },
});
// Execute smart contract
const { executeContract } = useExecuteContract();
executeContract({
signingClient,
senderAddress: account?.bech32Address,
contractAddress: "cosmos1contract...",
msg: { transfer: { recipient: "cosmos1...", amount: "100" } },
fee: { amount: [{ denom: "uatom", amount: "500" }], gas: "300000" },
funds: [{ denom: "uatom", amount: "100" }],
});
// Instantiate contract
const { instantiateContract } = useInstantiateContract();
instantiateContract({
codeId: 1,
signingClient,
senderAddress: account?.bech32Address,
msg: { name: "My Contract", symbol: "MYC" },
label: "my-contract",
fee: { amount: [{ denom: "uatom", amount: "5000" }], gas: "500000" },
});
// Query smart contract
const { data: queryResult } = useQuerySmart({
address: "cosmos1contract...",
queryMsg: { get_info: {} },
});

Chain Management

ts
// Suggest chain to wallet (no auto-connect)
const { suggest } = useSuggestChain();
await suggest({ chainInfo: cosmoshub, walletType: WalletType.KEPLR });
// Suggest + auto-connect
const { suggestAndConnect } = useSuggestChainAndConnect();
await suggestAndConnect({ chainInfo: osmosistestnet });

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
123
Repository forks
36
7-day trend score
24

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/graz-sh/graz/static/badge)](https://verified-skill.com/skills/graz-sh/graz/static)

Something wrong with this skill or its page? Tell us.