services/mwa/useSignAndSendTransaction.ts
import type { KitMobileWallet } from "@solana-mobile/mobile-wallet-adapter-protocol-kit"
import { transact } from "@solana-mobile/mobile-wallet-adapter-protocol-kit"
import type { SignatureBytes, TransactionSendingSignerConfig } from "@solana/kit"
import type { Transaction } from "@solana/transactions"
import { getAbortablePromise } from "@solana/promises"
type AuthorizeInput = Readonly<{
chain: `solana:${string}`;
identity: Readonly<{
name?: string;
uri?: `https://${string}`;
icon?: string;
}>;
auth_token?: string;
}>;
type Input = Readonly<{
transactions: readonly Transaction[]
options?: Readonly<{
minContextSlot?: number
commitment?: string
skipPreflight?: boolean
maxRetries?: number
waitForCommitmentToSendNextTransaction?: boolean
}>
}>
type Output = Readonly<{
signatures: readonly SignatureBytes[]
auth_token: string
}>
export function useSignAndSendTransaction(
authInput: AuthorizeInput,
): (input: Input, config?: TransactionSendingSignerConfig) => Promise<Output> {
return useCallback(
async (input: Input, config?: TransactionSendingSignerConfig): Promise<Output> => {
const { abortSignal } = config ?? {}
abortSignal?.throwIfAborted()
const promise = transact(async (wallet: KitMobileWallet): Promise<Output> => {
const authResult = await wallet.authorize(authInput)
const signAndSendTransactionsInput = {
transactions: [...input.transactions],
...input.options,
}
const signatures = await wallet.signAndSendTransactions(signAndSendTransactionsInput)
return { signatures, auth_token: authResult.auth_token }
})
return getAbortablePromise(promise, abortSignal)
},
[authInput],
)
}