South Admin CRUD Generator
southliu/south-admin-react
Generates a full CRUD page - page component, data model and API client - from the south-admin-react project's own VS Code snippet templates.
React hooks for Cosmos blockchain interactions — connect wallets, query balances, send tokens, sign messages.
$ npx skills add graz-sh/graz --skill graz -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install graz-sh/graz graz --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/graz-sh/graz.git skills-src && mkdir -p .claude/skills && cp -r skills-src/docs/static .claude/skills/graz && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "graz" agent skill from https://github.com/graz-sh/graz/tree/dev/docs/static into .claude/skills/graz/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "graz", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/graz-sh/graz/tree/dev/docs/staticType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add graz-sh/graz --skill graz -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install graz-sh/graz graz --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/graz-sh/graz.git skills-src && mkdir -p .agents/skills && cp -r skills-src/docs/static .agents/skills/graz && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "graz" agent skill from https://github.com/graz-sh/graz/tree/dev/docs/static into .agents/skills/graz/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "graz", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add graz-sh/graz --skill graz -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install graz-sh/graz graz --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/graz-sh/graz.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/docs/static .cursor/skills/graz && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "graz" agent skill from https://github.com/graz-sh/graz/tree/dev/docs/static into .cursor/skills/graz/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "graz", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/graz-sh/graz.git --path docs/static--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add graz-sh/graz --skill graz -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install graz-sh/graz graz --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/graz-sh/graz.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/docs/static .gemini/skills/graz && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "graz" agent skill from https://github.com/graz-sh/graz/tree/dev/docs/static into .gemini/skills/graz/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "graz", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install graz-sh/graz grazInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add graz-sh/graz --skill graz -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/graz-sh/graz.git skills-src && mkdir -p .github/skills && cp -r skills-src/docs/static .github/skills/graz && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "graz" agent skill from https://github.com/graz-sh/graz/tree/dev/docs/static into .github/skills/graz/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "graz", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add graz-sh/graz --skill graz -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install graz-sh/graz graz --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/graz-sh/graz.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/docs/static .opencode/skills/graz && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "graz" agent skill from https://github.com/graz-sh/graz/tree/dev/docs/static into .opencode/skills/graz/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "graz", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
grazReact hooks for Cosmos blockchain interactions — connect wallets, query balances, send tokens, sign messages.
Graz is an agent skill from graz-sh/graz. 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.
Its SKILL.md is about 4.2k tokens, which your agent loads only when the skill is triggered. The skill folder holds 12 other files.
It sits in Frontend & Design, covering React components and Smart contracts. It works with React. The repository describes itself as: React hooks for Cosmos 🪐. The licence is MIT.
Read from SKILL.md and the folder at commit 48d3372. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
pnpmFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use pnpm, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Graz loads about 4.2k tokens when it runs. Until then it costs about 59 tokens; SKILL.md has 282 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from graz-sh/graz at commit 48d3372, republished under its MIT licence (© graz-sh). 282 words, ~4,202 tokens.
.claude/skills/graz/SKILL.md (or your agent's skills folder). This skill also uses 11 other files; get the full folder from GitHub.React hooks for Cosmos blockchain interactions.
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>
);
}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).
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
}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 safetypnpm 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 onlyOutput goes to packages/graz/chains/index.{js,mjs,ts} (gitignored).
import { cosmoshub, osmosis, mainnetChains, testnetChains } from "graz/chains";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 });// 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;// 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();const { disconnect, disconnectAsync, isLoading } = useDisconnect();
disconnect(); // All chains
disconnect({ chainId: ["cosmoshub-4"] }); // Specific chain only
// Actions
import { clearSession } from "graz";
clearSession(); // Reset session + clear storageUse useWalletEvents to react to committed wallet state changes. The hook owns
its subscription and automatically cleans it up when the component unmounts.
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:
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.
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 });// 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),
});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),
});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" }
);// 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: {} },
});// 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 });
// Add chain (add to GrazProvider config at runtime)
const { addChain } = useAddChain();
await addChain({ chainInfo: myNewChain });
// Chain info hooks
const { data: chainInfo } = useChainInfo({ chainId: "cosmoshub-4" }); // Single
const { data: chainInfos } = useChainInfos({ chainId: ["cosmoshub-4", "osmosis-1"] }); // Filtered
const { data: activeChains } = useActiveChains(); // Currently connected
const { data: activeChainIds } = useActiveChainIds(); // Connected chain IDs
// Recent chains
const { data: recentChainIds, clear: clearRecentIds } = useRecentChainIds();
const { data: recentChains, clear: clearRecentChains } = useRecentChains();
// Actions
import { addChain, suggestChain, suggestChainAndConnect, getChainInfo, getChainInfos } from "graz";All hooks that accept chainId support three overloads:
// 1. No chainId — returns generic Record<string, T>
useAccount(); // Record<string, Key | undefined>
// 2. Single element tuple — typed Record with one key
useAccount({ chainId: ["cosmoshub-4"] as const }); // ChainIdToRecord<["cosmoshub-4"], Key | undefined>
// 3. Multi-element tuple — typed Record with multiple keys
useAccount({ chainId: ["cosmoshub-4", "osmosis-1"] as const }); // ChainIdToRecord<["cosmoshub-4", "osmosis-1"], Key | undefined>This applies to: useAccount, useOfflineSigners, useStargateClient, useCosmWasmClient, useStargateSigningClient, useCosmWasmSigningClient.
The UseMultiChainQueryResult<TChainIds, TData> return type gives you:
TypeUseMultiChainQueryResult<TChainIds, TData> = UseQueryResult<
TChainIds extends readonly string[] ? ChainIdToRecord<TChainIds, TData> : Record<string, TData>
>;import { LOG_CATEGORIES, LOG_FUNCTIONS, LOG_HOOKS, LogLevel, LogCategory } from "graz";
// In GrazProvider
<GrazProvider grazOptions={{
chains: [...],
logger: {
enabled: true,
level: LogLevel.DEBUG,
categories: ["WALLET", "TRANSACTION"],
},
}}/>;import { WalletType, Key, Wallet, OfflineSigners, ConnectResult, UseMultiChainQueryResult, ChainConfig } from "graz";
// WalletType — enum for all supported wallets
WalletType.KEPLR, WalletType.COSMOSTATION,
WalletType.VECTIS, WalletType.WALLETCONNECT, WalletType.OKX,
WalletType.PARA, WalletType.INITIA, WalletType.CACTUSCOSMOS,
WalletType.COMPASS, WalletType.STATION, WalletType.XDEFI,
WalletType.COSMIFRAME, WalletType.METAMASK_SNAP_COSMOS,
WalletType.WC_KEPLR_MOBILE,
WalletType.WC_COSMOSTATION_MOBILE, WalletType.WC_CLOT_MOBILE
// Key — wallet account key
interface Key {
name: string;
algo: string;
pubKey: Uint8Array;
address: Uint8Array;
bech32Address: string;
isNanoLedger: boolean;
}
// OfflineSigners
interface OfflineSigners {
offlineSigner: OfflineSigner;
offlineSignerAmino: OfflineSignerAmino;
offlineSignerAuto: OfflineSigner;
}
// Query config
interface QueryConfig { enabled?: boolean; }
interface MutationEventArgs<T = unknown, S = T> {
onError?: (error: unknown, data: T) => unknown;
onLoading?: (data: T) => unknown;
onSuccess?: (data: S) => unknown;
}| Task | Hook/Action |
|---|---|
| Connect wallet | useConnect() → connect() |
| Disconnect | useDisconnect() → disconnect() |
| Account state | useAccount({ chainId }) |
| Wallet events | useWalletEvents(handlers), subscribeWalletEvents(handlers) |
| Check wallet availability | useCheckWallet(type), getAvailableWallets() |
| Active wallet info | useActiveWalletType() |
| Offline signers | useOfflineSigners({ chainId }) |
| Read client | useStargateClient({ chainId }), useCosmWasmClient({ chainId }) |
| Signing client | useStargateSigningClient({ chainId }), useCosmWasmSigningClient({ chainId }) |
| Balances | useBalances({ chainId, bech32Address }) |
| Single balance | useBalance({ chainId, bech32Address, denom }) |
| Staked balance | useBalanceStaked({ chainId, bech32Address }) |
| Send tokens | useSendTokens() |
| IBC transfer | useSendIbcTokens() |
| Execute contract | useExecuteContract() |
| Instantiate contract | useInstantiateContract() |
| Query contract | useQuerySmart({ address, queryMsg }) |
| Query raw | useQueryRaw({ address, key }) |
| Suggest chain | useSuggestChain(), useSuggestChainAndConnect() |
| Add chain | useAddChain() |
| Chain info | useChainInfo({ chainId }), useChainInfos({ chainId }) |
| Active chains | useActiveChains(), useActiveChainIds() |
| Validators | useQueryClientValidators({ queryClient }) |
© graz-sh, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 11 other files in docs/static of graz-sh/graz.
Open the folder on GitHubat commit 48d3372
Graz next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Graz this skillgraz-sh/graz | 123 | — | ~4.2k | Automated safety check: Pass | MIT | |
| South Admin CRUD Generatorsouthliu/south-admin-react | 580 | — | ~1.7k | Automated safety check: Pass | MIT | |
| Clerk React Patternsgeekskai/blog | 103 | 1 repos | ~1k | Automated safety check: Notes | MIT | |
| NEAR dApp Builderinternet-court/internet-court-skill | 6.5k | 1 repos | ~684 | Automated safety check: Pass | Custom licence | |
| Vechain Kitvechain/x-app-template | 450 | — | ~1.4k | Automated safety check: Pass | MIT | |
| React Emailaiskillstore/marketplace | 430 | 1 repos | ~3.6k | Automated safety check: Pass | MIT |
southliu/south-admin-react
Generates a full CRUD page - page component, data model and API client - from the south-admin-react project's own VS Code snippet templates.
geekskai/blog
React SPA auth patterns with @clerk/react for Vite/CRA - ClerkProvider setup, useAuth/useUser/useClerk hooks, React Router protected routes, custom sign-in flows.
internet-court/internet-court-skill
Scaffolds new NEAR dApps with create-near-app or adds NEAR wallet sign-in, contract calls and transaction signing to an existing React or plain JavaScript app.
vechain/x-app-template
VeChain Kit and dapp-kit packages — installation, hooks, components, wallet connection, social login, smart accounts, theming, and Privy setup.
aiskillstore/marketplace
A skill your agent uses when building HTML email templates with React components, adding a visual email editor to an application using the React Email visual editor, rendering emails to HTML, or…
viclafouch/meme-studio
Audit React components for unnecessary useEffect hooks. An agent skill from viclafouch/meme-studio.
Works with
Categories
React hooks for Cosmos blockchain interactions — connect wallets, query balances, send tokens, sign messages. Graz is an agent skill from graz-sh/graz. React hooks for Cosmos blockchain interactions — connect wallets, query balances, send tokens, sign messages.
Graz fits situations like: building Cosmos dApps with graz hooks; setting up GrazProvider; connecting wallets; performing transactions.
Run `npx skills add graz-sh/graz --skill graz -a claude-code`. Or copy the skill folder (docs/static in graz-sh/graz) into .claude/skills/graz in your project. Claude Code loads it when a task matches its description.
Run `npx skills add graz-sh/graz --skill graz -a codex`. Or copy the skill folder (docs/static in graz-sh/graz) into .agents/skills/graz in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add graz-sh/graz --skill graz -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/graz, .gemini/skills/graz, .github/skills/graz and .opencode/skills/graz in your project.
Going by SKILL.md and its folder, Graz needs the command-line tools its instructions call (pnpm).
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Graz is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.2k tokens (SKILL.md is roughly 17k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Graz: South Admin CRUD Generator (southliu/south-admin-react, 580 stars), Clerk React Patterns (geekskai/blog, 103 stars), NEAR dApp Builder (internet-court/internet-court-skill, 6.5k stars) and Vechain Kit (vechain/x-app-template, 450 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
graz-sh (a GitHub organization) maintains it in graz-sh/graz, which has 123 GitHub stars. The repository was last updated on September 17, 2026.
Source: graz-sh/graz on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.