[TWIL] Week of June 16, 2024
![[TWIL] Week of June 16, 2024](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1720021320161%2F2aeb9a7c-1f2d-4b5e-81bf-2156288bfe65.png&w=3840&q=75)
This week marked the third week of the Onchain Summer Buildathon, where our focus was on refining our code to support interactions with Externally Owned Accounts (EOAs). Here’s a deep dive into what I learned and achieved during this week of building.
EOA with Smart Wallet Integration
Our platform already had artists using EOAs to mint music NFTs, so migrating them entirely to Smart Wallets wasn't feasible. Instead, we had to adapt our client-side code to support both Smart Wallet accounts and EOAs. This involved implementing conditional logic to handle each type of account using the useCapabilities hook.
Here's an example of how we managed batch transactions for both account types:
const Component = () => {
const { data: capabilities } = useCapabilities({
account,
});
const isSmartWallet = Object.keys(capabilities).length > 0;
const methodOne = {
// args...
}
const methodTwo = {
// args...
}
const { writeContractsAsync } = useWriteContracts();
const { writeContractAsync } = useWriteContract();
const { data: methodOneData } = useSimulateContract(methodOne);
const { data: methodTwoData } = useSimulateContract({
...methodTwo,
skipSimulation: true
});
const handler = async () => {
if (isSmartWallet) {
await writeContractAsync({
contracts: [methodOne, methodTwo]
});
return;
}
const hash = await writeContractAsync(methodOneData);
await waitForTransactionReceipt(config, { hash });
await writeContractAsync(methodTwoData);
}
}
Key Learnings and Highlights
Detecting Smart Wallet vs. EOA: We used the
useCapabilitieshook to check if the user has capabilities associated with a Smart Wallet. Ifcapabilitieshas at least one key-value pair, it indicates a Smart Wallet; otherwise, it’s an EOA. TheisSmartWalletvariable serves as this indicator.Handling Simulation and Execution: Include
skipSimulation: trueon the seconduseSimulateContractargument if themethodTwotransaction depends onmethodOnebeing executed and confirmed. This avoids errors during simulation. Additionally, invokewaitForTransactionReceiptto ensure the first transaction is confirmed before executing the second one.
Hardhat Network Variable
The Hardhat npm package provides many useful variables, including network, which tells you which chain you're executing your script on at runtime. This is particularly useful if you have identical smart contracts deployed on multiple blockchains. Here’s a handy way to get smart contract addresses across supported blockchains:
// main.ts
import { network } from "hardhat";
enum EthereumSCAddresses {
NFT = "<smart-contract-address>"
}
enum BaseSCAddresses {
NFT = "<smart-contract-address>"
}
function getContractAddress() {
switch (network.name) {
case "ethereum":
return EthereumSCAddresses
case "base":
return BaseSCAddresses;
default:
throw new Error("Invalid network name");
}
}
function main() {
const nftAddress = getContractAddress().NFT;
}
When you run npx hardhat run main.ts --network ethereum, getContractAddress will return EthereumSCAddresses, and .NFT will return the corresponding smart contract address.
Wrapping Up
That’s it for this week! As we head into the final week of the Onchain Summer Buildathon, we'll continue to fix issues and build new features. Happy hacking everyone ☕️!




![[TWIL] Week of August 11, 2024](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1724192926501%2F2ba38d69-5f89-4c41-b2fe-7f994fa97f71.png&w=3840&q=75)
![[TWIL] Week of August 04, 2024](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1723410046529%2F77c9c1f6-e0e2-4422-aa2c-0b82b769631c.png&w=3840&q=75)
![[TWIL] Week of July 28, 2024](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1723335244607%2F22b5f8ee-4c35-4cf0-9666-405c09aae03c.png&w=3840&q=75)