Skip to content
5 changes: 5 additions & 0 deletions .changeset/tender-terms-repeat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@gillsdk/react": minor
---

added `useSendTransaction` hook
3 changes: 3 additions & 0 deletions packages/react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ Fetch data from the Solana blockchain with the gill hooks:
- [`useTokenMint`](#get-token-mint-account) - get a decoded token's Mint account
- [`useTokenAccount`](#get-token-account) - get the token account for a given mint and owner (or ATA)

Send data to the Solana blockchain with the gill hooks:
- [`useSendTransaction`](#send-transaction) - send a transaction to the Solana blockchain

### Wrap your React app in a context provider

Wrap your app with the `SolanaProvider` React context provider and pass your Solana client to it:
Expand Down
38 changes: 38 additions & 0 deletions packages/react/src/__typeset__/send-transaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useSendTransaction } from "../hooks/send-transaction";
import { Base64EncodedWireTransaction, SendTransactionApi} from "gill";

// [DESCRIBE] useSendTransaction
{
const signature = null as unknown as Base64EncodedWireTransaction | string;
{
const transaction = useSendTransaction({ signature });
transaction.signature satisfies ReturnType<SendTransactionApi["sendTransaction"]>;
// @ts-expect-error - Should not allow no argument
useSendTransaction();

// @ts-expect-error - Should not allow empty argument object
useSendTransaction({});
}

{
// Should accept `config` input
const transaction = useSendTransaction({
config: {
encoding: "base64",
preflightCommitment: "confirmed",
skipPreflight: false,
},
signature,
});
transaction.signature satisfies ReturnType<SendTransactionApi["sendTransaction"]>;
}

{
// Should require `signature` input
const transaction = useSendTransaction({
signature: "5Pj5fCupXLUePYn18JkY8SrRaWFiUctuDTRwvUy2ML9yvkENLb1QMYbcBGcBXRrSVDjp7RjUwk9a3rLC6gpvtYpZ",
});

transaction.signature satisfies ReturnType<SendTransactionApi["sendTransaction"]>;
}
}
1 change: 1 addition & 0 deletions packages/react/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from "./slot";
export * from "./token-account";
export * from "./token-mint";
export * from "./transaction";
export * from "./send-transaction";
57 changes: 57 additions & 0 deletions packages/react/src/hooks/send-transaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"use client";

import { GillUseRpcHook } from "./types";
import { useSolanaClient } from "./client";
import { GILL_HOOK_CLIENT_KEY } from "../const";
import { useMutation } from "@tanstack/react-query";
import { Base64EncodedWireTransaction, SendTransactionApi, Simplify } from "gill";

// Define the configuration type for the RPC method
type RpConfig = Simplify<Parameters<SendTransactionApi["sendTransaction"]>[1]>;

// Define the response type for the hook
type UseSendTransactionResponse = ReturnType<SendTransactionApi["sendTransaction"]>;

type UseSendTransactionInput<TConfig extends RpConfig = RpConfig> = GillUseRpcHook<TConfig> & {
config?: TConfig;
/**
* The signed transaction in wire format, as a base-64 encoded string.
*/
signature: Base64EncodedWireTransaction | string;
};

/**
* Send a transaction using the Solana RPC method of
* [`sendTransaction`](https://solana.com/docs/rpc/http/sendtransaction)
*
* @returns An object from useMutation, including `signature`(the transaction signature) in an object
*/
export function useSendTransaction<TConfig extends RpConfig = RpConfig>({
signature,
config,
}: UseSendTransactionInput<TConfig>) {
const { rpc } = useSolanaClient();

const { data, ...rest } = useMutation({
mutationFn: async () => {
// The RPC method expects the base-64 encoded transaction as the first argument.
const response = await rpc
.sendTransaction(signature as Base64EncodedWireTransaction, {
encoding: "base64",
preflightCommitment: "confirmed",
skipPreflight: false,
...(config || {}),
})
.send();
// return the transaction signature as a base-64 encoded string
return response;
},
mutationKey: [GILL_HOOK_CLIENT_KEY, "sendTransaction"],
networkMode: "offlineFirst",
});

return {
...rest,
signature: data as UseSendTransactionResponse,
};
}