Skip to main content

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;