Skip to content

Commit

Permalink
Extracted useTransact hook from Sui dApp Starter and adapted it to th…
Browse files Browse the repository at this point in the history
…e library context. Added documentation. Incremented project version.
  • Loading branch information
kkomelin committed Jan 11, 2025
1 parent 427c8f6 commit acfb57d
Show file tree
Hide file tree
Showing 6 changed files with 254 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/kit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
129 changes: 129 additions & 0 deletions packages/kit/docs/useTransact.md
Original file line number Diff line number Diff line change
@@ -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 (
<button onClick={handleTransaction}>
Perform Transaction
</button>
)
}
```

## 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 (
<button onClick={() => updateGreeting(packageId, objectId, 'Hello')}>
Update Greeting
</button>
)
}
```
12 changes: 11 additions & 1 deletion packages/kit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@suiware/kit",
"version": "0.4.5",
"version": "0.5.0",
"sideEffects": false,
"type": "module",
"license": "MIT",
Expand Down Expand Up @@ -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": [
Expand Down
1 change: 0 additions & 1 deletion packages/kit/src/components/AddressInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
112 changes: 112 additions & 0 deletions packages/kit/src/hooks/useTransact.ts
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions packages/kit/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit acfb57d

Please sign in to comment.