Write to a Contract with sendAsync button using the useScaffoldWriteContract hook.
This recipe demonstrates how to create a button for contract interaction using the useScaffoldWriteContract hook from Scaffold-Stark.
Here is the full code, which we will be implementing in the guide below:
components/ContractInteraction.tsx
"use client";
import { useState } from "react";
import { useScaffoldWriteContract } from "~~/hooks/scaffold-stark/useScaffoldWriteContract";
const SetGreeting = () => {
const [greeting, setGreeting] = useState<string>("");
const { sendAsync, isPending } = useScaffoldWriteContract({
contractName: "YourContract",
functionName: "set_greeting",
args: [greeting, 0n], // `inputAmount` fixed at 0n
});
const handleSetGreeting = async () => {
try {
await sendAsync();
} catch (e) {
console.error("Error setting greeting", e);
}
};
return (
<div>
<input
type="text"
placeholder="Enter your greeting"
className="input border border-primary"
onChange={e => setGreeting(e.target.value)}
/>
<button className="btn btn-primary" onClick={handleSetGreeting} disabled={isPending}>
{isPending ? <span className="loading loading-spinner loading-sm"></span> : "Submit"}
</button>
</div>
);
};
export default SetGreeting;
Implementationโ
1. Set Up Your Componentโ
Create a new component in the components folder. This component will display an input field and a button to interact with your smart contract.
components/ContractInteraction.tsx
"use client";
const SetGreeting = () => {
return (
<div>
<input type="text" placeholder="Enter your greeting" className="input border border-primary" />
<button className="btn btn-primary">Submit</button>
</div>
);
};
export default SetGreeting;
2. Initialize useScaffoldWriteContract Hookโ
Now we'll add state management and initialize the hook for contract interaction:
components/ContractInteraction.tsx
"use client";
import { useState } from "react";
import { useScaffoldWriteContract } from "~~/hooks/scaffold-stark/useScaffoldWriteContract";
const SetGreeting = () => {
const [greeting, setGreeting] = useState<string>("");
const { sendAsync } = useScaffoldWriteContract({
contractName: "YourContract",
functionName: "set_greeting",
args: [greeting, 0n], // `inputAmount` fixed at 0n
});
const handleSetGreeting = async () => {
try {
await sendAsync();
} catch (e) {
console.error("Error setting greeting", e);
}
};
return (
<div>
<input type="text" placeholder="Enter your greeting" className="input border border-primary" />
<button className="btn btn-primary">Send</button>
</div>
);
};
export default SetGreeting;
3. Add Input Change Logic and Connect Buttonโ
Now we'll connect the input to our state and wire up the button click handler:
components/ContractInteraction.tsx
"use client";
import { useState } from "react";
import { useScaffoldWriteContract } from "~~/hooks/scaffold-stark/useScaffoldWriteContract";
const SetGreeting = () => {
const [greeting, setGreeting] = useState<string>("");
const { sendAsync } = useScaffoldWriteContract({
contractName: "YourContract",
functionName: "set_greeting",
args: [greeting, 0n], // `inputAmount` fixed at 0n
});
const handleSetGreeting = async () => {
try {
await sendAsync();
} catch (e) {
console.error("Error setting greeting", e);
}
};
return (
<div>
<input
type="text"
placeholder="Enter your greeting"
className="input border border-primary"
onChange={e => setGreeting(e.target.value)}
/>
<button className="btn btn-primary" onClick={handleSetGreeting}>
Submit
</button>
</div>
);
};
export default SetGreeting;
4. Add Loading Stateโ
Finally, we'll add loading state handling to improve the user experience:
components/ContractInteraction.tsx
"use client";
import { useState } from "react";
import { useScaffoldWriteContract } from "~~/hooks/scaffold-stark/useScaffoldWriteContract";
const SetGreeting = () => {
const [greeting, setGreeting] = useState<string>("");
const { sendAsync, isPending } = useScaffoldWriteContract({
contractName: "YourContract",
functionName: "set_greeting",
args: [greeting, 0n], // `inputAmount` fixed at 0n
});
const handleSetGreeting = async () => {
try {
await sendAsync();
} catch (e) {
console.error("Error setting greeting", e);
}
};
return (
<div>
<input
type="text"
placeholder="Enter your greeting"
className="input border border-primary"
onChange={e => setGreeting(e.target.value)}
/>
<button className="btn btn-primary" onClick={handleSetGreeting} disabled={isPending}>
{isPending ? <span className="loading loading-spinner loading-sm"></span> : "Submit"}
</button>
</div>
);
};
export default SetGreeting;