useSendIbcTokens
Mutation hook to send IBC tokens and returns @cosmjs/stargate's DeliverTxResponse
.
Important: senderAddress
is a required parameter that must be explicitly provided.
Enhanced: This hook now returns all React Query mutation properties, giving you access to utilities like reset
, variables
, context
, failureCount
, and more.
Usage
Basic Example
import { useSendIbcTokens, useAccount, useStargateSigningClient } from "graz";
function SendIbcTokensComponent() {
const { data: accounts } = useAccount({ chainId: ["cosmoshub-4"] });
const { data: signingClients } = useStargateSigningClient({ chainId: ["cosmoshub-4"] });
const { sendIbcTokensAsync, isLoading } = useSendIbcTokens();
const account = accounts?.["cosmoshub-4"];
const signingClient = signingClients?.["cosmoshub-4"];
async function handleSendIbc() {
if (!signingClient || !account) return;
const result = await sendIbcTokensAsync({
signingClient,
senderAddress: account.bech32Address, // Explicit sender address
recipientAddress: "osmo1g3jjhgkyf36pjhe7u5cw8j9u6cgl8x929ej430",
transferAmount: { denom: "uatom", amount: "1000" },
sourcePort: "transfer",
sourceChannel: "channel-141", // Cosmos Hub -> Osmosis
fee: "auto",
memo: "IBC transfer via Graz",
});
console.log("Transaction hash:", result.transactionHash);
}
return (
<button onClick={handleSendIbc} disabled={isLoading}>
{isLoading ? "Sending..." : "Send IBC Tokens"}
</button>
);
}
With Timeout
import { useSendIbcTokens, useAccount, useStargateSigningClient } from "graz";
function SendIbcWithTimeout() {
const { data: accounts } = useAccount({ chainId: ["cosmoshub-4"] });
const { data: signingClients } = useStargateSigningClient({ chainId: ["cosmoshub-4"] });
const { sendIbcTokensAsync } = useSendIbcTokens();
const account = accounts?.["cosmoshub-4"];
const signingClient = signingClients?.["cosmoshub-4"];
async function handleSend() {
if (!signingClient || !account) return;
// Set timeout to 10 minutes from now
const timeoutTimestamp = Math.floor(Date.now() / 1000) + 600;
await sendIbcTokensAsync({
signingClient,
senderAddress: account.bech32Address,
recipientAddress: "osmo1...",
transferAmount: { denom: "uatom", amount: "1000" },
sourcePort: "transfer",
sourceChannel: "channel-141",
timeoutTimestamp,
fee: "auto",
});
}
return <button onClick={handleSend}>Send IBC</button>;
}
With Event Handlers
import { useSendIbcTokens } from "graz";
function SendIbcWithEvents() {
const { sendIbcTokensAsync } = useSendIbcTokens({
onSuccess: (data) => {
console.log("IBC transfer successful!", data.transactionHash);
},
onError: (error) => {
console.error("IBC transfer failed:", error);
},
onMutate: (args) => {
console.log("Starting IBC transfer...", args);
},
});
// ... rest of component
}
Types
SendIbcTokensArgs
{
signingClient: SigningStargateClient;
senderAddress: string; // Required - address sending the tokens
recipientAddress: string;
transferAmount: Coin; // { denom: string, amount: string }
sourcePort: string;
sourceChannel: string;
timeoutHeight?: Height; // From cosmjs-types/ibc/core/client/v1/client
timeoutTimestamp?: number; // Unix timestamp in seconds
fee: number | StdFee | "auto";
memo?: string;
}
Hook Params
Object params for event handlers:
{
onError?: (error: unknown, args: SendIbcTokensArgs) => void | Promise<void>;
onMutate?: (args: SendIbcTokensArgs) => void;
onSuccess?: (data: DeliverTxResponse) => void | Promise<void>;
}
Return Value
{
// Custom mutation functions
sendIbcTokens: (args: SendIbcTokensArgs) => void;
sendIbcTokensAsync: (args: SendIbcTokensArgs) => 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?: SendIbcTokensArgs; // Arguments passed to the last mutation call
submittedAt: number;
// Mutation methods
reset: () => void; // Reset mutation state
// Context (from onMutate)
context: unknown;
}
Note: isLoading
has been replaced by isPending
in React Query v5. Both work, but isPending
is the modern property name.
Migration from Previous Version
If upgrading from an older version where senderAddress
was optional:
const { data: accounts } = useAccount({ chainId: ["cosmoshub-4"] });
+ const account = accounts?.["cosmoshub-4"];
const { data: signingClients } = useStargateSigningClient({ chainId: ["cosmoshub-4"] });
+ const signingClient = signingClients?.["cosmoshub-4"];
const { sendIbcTokensAsync } = useSendIbcTokens();
await sendIbcTokensAsync({
signingClient,
+ senderAddress: account.bech32Address, // Now required
recipientAddress: "osmo1...",
transferAmount: { denom: "uatom", amount: "1000" },
sourcePort: "transfer",
sourceChannel: "channel-141",
fee: "auto",
});