useSignAndBroadcast
Mutation hook to sign and broadcast arbitrary encoded Cosmos messages with a SigningStargateClient.
Use this when you already have one or more EncodeObject messages and want Graz to call CosmJS'
signAndBroadcast directly.
Important: senderAddress is a required parameter that must be explicitly provided.
Enhanced: This hook returns all React Query mutation properties, giving you access to utilities like
reset, variables, context, failureCount, and more.
Usage
Basic Example
import type { EncodeObject } from "@cosmjs/proto-signing";
import { useAccount, useSignAndBroadcast, useStargateSigningClient } from "graz";
function BroadcastMessages() {
const { data: accounts } = useAccount({ chainId: ["cosmoshub-4"] });
const { data: signingClients } = useStargateSigningClient({ chainId: ["cosmoshub-4"] });
const { signAndBroadcastAsync, isPending } = useSignAndBroadcast();
const account = accounts?.["cosmoshub-4"];
const signingClient = signingClients?.["cosmoshub-4"];
async function broadcast() {
if (!account || !signingClient) return;
const messages: EncodeObject[] = [
{
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
value: {
fromAddress: account.bech32Address,
toAddress: "cosmos1recipient...",
amount: [{ denom: "uatom", amount: "1000" }],
},
},
];
const result = await signAndBroadcastAsync({
signingClient,
senderAddress: account.bech32Address,
messages,
fee: "auto",
memo: "Sent via Graz",
});
console.log(result.transactionHash);
}
return (
<button onClick={broadcast} disabled={isPending}>
Broadcast
</button>
);
}
With Event Handlers
import { useSignAndBroadcast } from "graz";
function BroadcastWithEvents() {
const { signAndBroadcastAsync } = useSignAndBroadcast({
onSuccess: (data) => {
console.log("Transaction successful!", data.transactionHash);
},
onError: (error) => {
console.error("Transaction failed:", error);
},
onLoading: (args) => {
console.log("Broadcasting messages...", args.messages.length);
},
});
// ... rest of component
}
Framework-Agnostic Action
signAndBroadcast is also available as a public action for non-React usage.
import type { EncodeObject } from "@cosmjs/proto-signing";
import { signAndBroadcast } from "graz";
const messages: EncodeObject[] = [
{
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
value: {
fromAddress: senderAddress,
toAddress: "cosmos1recipient...",
amount: [{ denom: "uatom", amount: "1000" }],
},
},
];
const result = await signAndBroadcast({
signingClient,
senderAddress,
messages,
fee: "auto",
memo: "Sent via Graz",
});
console.log(result.transactionHash);
Types
SignAndBroadcastArgs
{
signingClient?: SigningStargateClient; // Required at runtime
senderAddress?: string; // Required at runtime - address signing the messages
messages: readonly EncodeObject[]; // Cosmos messages to sign and broadcast
fee: number | StdFee | "auto";
memo?: string;
timeoutHeight?: bigint;
}
signingClient and senderAddress are optional at the TypeScript action boundary so mutation args can be
assembled from wallet state that may still be loading. The action still requires them at runtime and throws if
either value is missing.
Hook Params
Object params for event handlers:
{
onError?: (error: unknown, args: SignAndBroadcastArgs) => void | Promise<void>;
onLoading?: (args: SignAndBroadcastArgs) => void;
onSuccess?: (data: DeliverTxResponse) => void | Promise<void>;
}
Return Value
{
// Custom mutation functions
signAndBroadcast: (args: SignAndBroadcastArgs) => void;
signAndBroadcastAsync: (args: SignAndBroadcastArgs) => Promise<DeliverTxResponse>;
// All React Query mutation properties
data?: DeliverTxResponse; // From @cosmjs/stargate
error: unknown;
failureCount: number;
failureReason: Error | null;
isError: boolean;
isIdle: boolean;
isPending: boolean;
isPaused: boolean;
isSuccess: boolean;
status: "idle" | "pending" | "error" | "success";
variables?: SignAndBroadcastArgs; // Arguments passed to the last mutation call
submittedAt: number;
// Mutation methods
reset: () => void; // Reset mutation state
// Context (from onLoading)
context: unknown;
}
Note: isLoading has been replaced by isPending in React Query v5. Both work, but isPending is the modern property name.