diff --git a/packages/kit/README.md b/packages/kit/README.md
index 4c3f031..b0b9dcc 100644
--- a/packages/kit/README.md
+++ b/packages/kit/README.md
@@ -84,6 +84,7 @@ function App() {
## Hooks
+- [useTransact](https://github.com/suiware/kit/blob/main/packages/kit/docs/useTransact.md)
- [useBalance](https://github.com/suiware/kit/blob/main/packages/kit/docs/useBalance.md)
- [useFaucet](https://github.com/suiware/kit/blob/main/packages/kit/docs/useFaucet.md)
- [useNetworkType](https://github.com/suiware/kit/blob/main/packages/kit/docs/useNetworkType.md)
diff --git a/packages/kit/docs/useTransact.md b/packages/kit/docs/useTransact.md
new file mode 100644
index 0000000..adedc74
--- /dev/null
+++ b/packages/kit/docs/useTransact.md
@@ -0,0 +1,129 @@
+# useTransact
+
+`useTransact` is a React hook that facilitates performing transactions on the Sui network, handling wallet interactions and transaction lifecycle events.
+
+## Usage
+
+```tsx
+import { useTransact } from '@suiware/kit'
+import { Transaction } from '@mysten/sui/transactions'
+
+function MyComponent() {
+ const { transact } = useTransact({
+ onBeforeStart: () => console.log('Transaction starting...'),
+ onSuccess: (data) => console.log('Transaction succeeded:', data),
+ onError: (e) => console.error('Transaction failed:', e)
+ })
+
+ const handleTransaction = () => {
+ const tx = new Transaction()
+ // Configure transaction...
+ transact(tx)
+ }
+
+ return (
+
+ )
+}
+```
+
+## Parameters
+
+The hook accepts an options object with the following properties:
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| onBeforeStart | () => void | (Optional) Callback executed when user triggers a transaction |
+| onSuccess | (data: SuiSignAndExecuteTransactionOutput) => void | (Optional) Callback executed after successful transaction completion |
+| onError | (e: Error) => void | (Optional) Callback executed if transaction fails |
+
+## Return Value
+
+The hook returns an object with:
+
+| Property | Type | Description |
+| --- | --- | --- |
+| transact | (tx: Transaction) => void | Function to execute a transaction on the Sui network |
+
+## Features
+
+- Handles wallet interaction for transaction signing
+
+- Automatic transaction confirmation tracking
+
+- Success/error notification management
+
+- Integration with Sui Explorer for transaction viewing
+
+- Complete transaction lifecycle management
+
+## Usage Examples
+
+### Basic Transaction
+
+```tsx
+const { transact } = useTransact()
+
+const handleTransaction = () => {
+ const tx = new Transaction()
+ tx.moveCall({
+ target: `${packageId}::module::function`,
+ arguments: [/* ... */],
+ })
+ transact(tx)
+}
+```
+
+### With Event Handlers
+
+```tsx
+const { transact } = useTransact({
+ onBeforeStart: () => {
+ setLoading(true)
+ },
+ onSuccess: (data) => {
+ setLoading(false)
+ refreshData()
+ },
+ onError: (e) => {
+ setLoading(false)
+ showError(e.message)
+ }
+})
+```
+
+### Full Example with Move Call
+
+```tsx
+import { useTransact } from '@suiware/kit'
+import { Transaction } from '@mysten/sui/transactions'
+
+function GreetingComponent() {
+ const { transact } = useTransact({
+ onSuccess: () => {
+ console.log('Greeting updated!')
+ }
+ })
+
+ const updateGreeting = (packageId: string, objectId: string, name: string) => {
+ const tx = new Transaction()
+ tx.moveCall({
+ arguments: [
+ tx.object(objectId),
+ tx.pure.string(name),
+ tx.object('0x8')
+ ],
+ target: `${packageId}::greeting::set_greeting`,
+ })
+ transact(tx)
+ }
+
+ return (
+
+ )
+}
+```
diff --git a/packages/kit/package.json b/packages/kit/package.json
index be87cb5..8b09e55 100644
--- a/packages/kit/package.json
+++ b/packages/kit/package.json
@@ -1,6 +1,6 @@
{
"name": "@suiware/kit",
- "version": "0.4.5",
+ "version": "0.5.0",
"sideEffects": false,
"type": "module",
"license": "MIT",
@@ -107,6 +107,16 @@
"types": "./dist/components/AmountInput.d.cts",
"default": "./dist/components/AmountInput.cjs"
}
+ },
+ "./useTransact": {
+ "import": {
+ "types": "./dist/hooks/useTransact.d.mts",
+ "default": "./dist/hooks/useTransact.mjs"
+ },
+ "require": {
+ "types": "./dist/hooks/useTransact.d.cts",
+ "default": "./dist/hooks/useTransact.cjs"
+ }
}
},
"files": [
diff --git a/packages/kit/src/components/AddressInput.tsx b/packages/kit/src/components/AddressInput.tsx
index 1b622a4..7385e15 100644
--- a/packages/kit/src/components/AddressInput.tsx
+++ b/packages/kit/src/components/AddressInput.tsx
@@ -4,7 +4,6 @@ import debounce from 'lodash.debounce'
import { ChangeEvent, FC, useCallback, useEffect, useState } from 'react'
import { resolveSuinsName } from '~~/helpers/suins'
-
const DEBOUNCE_DELAY = 500
export interface IAddressInput {
diff --git a/packages/kit/src/hooks/useTransact.ts b/packages/kit/src/hooks/useTransact.ts
new file mode 100644
index 0000000..8a3a4ad
--- /dev/null
+++ b/packages/kit/src/hooks/useTransact.ts
@@ -0,0 +1,112 @@
+import { useSignAndExecuteTransaction, useSuiClient } from '@mysten/dapp-kit'
+import { Transaction } from '@mysten/sui/transactions'
+import type { SuiSignAndExecuteTransactionOutput } from '@mysten/wallet-standard'
+
+export interface IUseTransactParams {
+ /**
+ * (Optional) Is executed when user triggers a transaction.
+ */
+ onBeforeStart?: () => void
+ /**
+ * (Optional) React on success, e.g. refetch dependent queries.
+ *
+ * @param {SuiSignAndExecuteTransactionOutput} data The transaction output.
+ */
+ onSuccess?: (data: SuiSignAndExecuteTransactionOutput) => void
+ /**
+ * (Optional) React on error.
+ *
+ * @param {Error} e The error.
+ */
+ onError?: (e: Error) => void
+}
+
+export interface IUseTransactResponse {
+ /**
+ * Perform a transaction on the Sui network.
+ *
+ * @param {Transaction} tx The transaction to perform.
+ */
+ transact: (tx: Transaction) => void
+}
+
+/**
+ * The useTransact() hook lets you perform a transaction on the Sui network.
+ *
+ * When user triggers a transaction, we display a notification to confirm that transaction in their wallet.
+ * Once user confirmed or rejected the transaction, we convert that notification to a success message or error message.
+ * The success message will have a link to a Sui Explorer depending on the active network.
+ * In case of error, we additionally print full error message in the browser console.
+ *
+ * Usage:
+ * ```ts
+ * import type { SuiSignAndExecuteTransactionOutput } from '@mysten/wallet-standard'
+ * import { Transaction } from '@mysten/sui/transactions'
+ * const { transact: greet } = useTransact({
+ * onBeforeStart: () => {},
+ * onSuccess: (data: SuiSignAndExecuteTransactionOutput) => {},
+ * onError: (e: Error) => {}
+ * })
+ *
+ * const prepareTransaction = (packageId: string, objectId: string, name: string) => {
+ * const tx = new Transaction()
+ * tx.moveCall({
+ * arguments: [tx.object(objectId), tx.pure.string(name), tx.object('0x8')],
+ * target: `${packageId}::greeting::set_greeting`,
+ * })
+ * return tx
+ * }
+ *
+ * greet(prepareTransaction(packageId, objectId, name))
+ * ```
+ *
+ * @param {IUseTransactParams} The hook params.
+ * @returns {IUseTransactResponse} An object with the transact function.
+ */
+const useTransact = ({
+ onBeforeStart,
+ onSuccess,
+ onError,
+}: IUseTransactParams = {}): IUseTransactResponse => {
+ const client = useSuiClient()
+ const { mutate: signAndExecute } = useSignAndExecuteTransaction()
+
+ const transact = (tx: Transaction) => {
+ if (onBeforeStart != null) {
+ onBeforeStart()
+ }
+
+ signAndExecute(
+ {
+ transaction: tx,
+ },
+ {
+ onError: (e: Error) => {
+ if (onError != null) {
+ onError(e)
+ }
+ },
+ onSuccess: (data: SuiSignAndExecuteTransactionOutput) => {
+ client
+ .waitForTransaction({
+ digest: data.digest,
+ })
+ .then(() => {
+ if (onSuccess != null) {
+ onSuccess(data)
+ }
+ })
+ .catch((e) => {
+ if (onError != null) {
+ onError(e)
+ }
+ })
+ },
+ }
+ )
+ }
+
+ return { transact }
+}
+
+export default useTransact
diff --git a/packages/kit/tsup.config.ts b/packages/kit/tsup.config.ts
index 891423f..0e940a2 100644
--- a/packages/kit/tsup.config.ts
+++ b/packages/kit/tsup.config.ts
@@ -12,6 +12,7 @@ export default defineConfig((options) => ({
"src/providers/SuiProvider.tsx",
"src/components/AddressInput.tsx",
"src/components/AmountInput.tsx",
+ "src/hooks/useTransact.tsx",
],
format: ["cjs", "esm"],
dts: true,