Transactions
Execute transactions using useFlowTransaction
:
import { useFlowTransaction } from '@doodlesteam/flooks';
const transaction = `
import NonFungibleToken from 0x...
import Doodles from 0x...
transaction(recipient: Address, nftID: UInt64) {
let withdrawRef: &Doodles.Collection
let depositRef: &Doodles.Collection{NonFungibleToken.Receiver}
prepare(signer: AuthAccount) {
self.withdrawRef = signer.borrow<&Doodles.Collection>(from: Doodles.CollectionStoragePath)
?? panic("Account does not store an object at the specified path")
self.depositRef = getAccount(recipient).getCapability(Doodles.CollectionPublicPath)
.borrow<&Doodles.Collection{NonFungibleToken.CollectionPublic}>()
?? panic("Could not borrow a reference to the receiver's collection")
}
execute {
let nft <- self.withdrawRef.withdraw(withdrawID: nftID)
self.depositRef.deposit(token: <-nft)
}
}`;
function Component {
const { execute, isIdle, isLoading, isSealed, isError } =
useFlowTransaction({
code: transaction,
args: ['0x...', 1],
onTransactionSealed(result) {
console.log('Transaction completed!', result.transactionId);
for (const event of result.events) {
console.log(event.type, event.data);
}
},
onTransactionError(result) {
console.error(result.error);
},
});
return (
<button disabled={!isIdle} onClick={() => execute()}>
{isIdle && 'Transfer NFT'}
{isLoading && 'Loading...'}
{isSealed && 'Sealed!'}
{isError && 'Error'}
</button>
);
}
useFlowTransaction
also provides you with automatic parsed and validated arguments, and also subscribes to transaction status.
Doing the same with fcl:
import { useEffect, useState } from "react";
import * as fcl from "@onflow/fcl";
const transaction = `
import NonFungibleToken from 0x...
import Doodles from 0x...
transaction(recipient: Address, nftID: UInt64) {
let withdrawRef: &Doodles.Collection
let depositRef: &Doodles.Collection{NonFungibleToken.Receiver}
prepare(signer: AuthAccount) {
self.withdrawRef = signer.borrow<&Doodles.Collection>(from: Doodles.CollectionStoragePath)
?? panic("Account does not store an object at the specified path")
self.depositRef = getAccount(recipient).getCapability(Doodles.CollectionPublicPath)
.borrow<&Doodles.Collection{NonFungibleToken.CollectionPublic}>()
?? panic("Could not borrow a reference to the receiver's collection")
}
execute {
let nft <- self.withdrawRef.withdraw(withdrawID: nftID)
self.depositRef.deposit(token: <-nft)
}
}`;
function Component {
const [txStatus, setTxStatus] = useState();
const [txUnsubscribe, setTxUnsubscribe] = useState();
const execute = async () => {
const transactionId = await fcl.mutate({
cadence: transaction,
args: (arg, t) => [arg("0x...", t.Address), arg("1", t.UInt64)],
});
const unsubscribe = fcl.tx(txId).subscribe(setTxStatus);
setTxUnsubscribe(unsubscribe);
}
useEffect(() => {
if (txStatus?.status === 4) {
console.log('Transaction completed!', txStatus.transactionId);
for (const event of txStatus.events) {
console.log(event.type, event.data);
}
txUnsubscribe();
} else if (txStatus?.errorMessage !== '') {
console.error(result.error);
txUnsubscribe();
}
}, [txStatus]);
return (
<button disabled={!isIdle} onClick={() => execute()}>
{!txStatus && 'Transfer NFT'}
{[1, 2, 3].includes(txStatus?.status) && 'Loading...'}
{txStatus?.status === 4 && 'Sealed!'}
{txStatus?.errorMessage !== '' && 'Error'}
</button>
);
}