Migration Guide: Scaffold-Stark v2 โ v3
This guide covers the breaking changes when migrating from Scaffold-Stark v2 (using @starknet-react/core) to Scaffold-Stark v3 (using @starknet-start/react).
Package Changesโ
Update your imports across the codebase:
| Old Package | New Package |
|---|---|
@starknet-react/core | @starknet-start/react |
@starknet-react/chains | @starknet-start/chains |
# Example: find and replace in your project
grep -r "@starknet-react/core" --include="*.ts" --include="*.tsx" -l
grep -r "@starknet-react/chains" --include="*.ts" --include="*.tsx" -l
Wallet Connectionโ
Before (v2): Wallets were configured manually using connector classes like InjectedConnector.
After (v3): Wallets are auto-discovered via the wallet standard (get-starknet). No manual connector setup is needed for standard wallets.
Hook Changesโ
useAccountโ
The useAccount hook no longer returns an account: AccountInterface object.
// v2
const { account, address, status } = useAccount();
// account was an AccountInterface instance
// v3
const { address, status, chainId, connector } = useAccount();
// No account object โ use address and other fields directly
useScaffoldContractโ
The hook no longer accepts an account parameter. It returns a read-only contract instance.
// v2
import { useAccount } from "@starknet-react/core";
const { account } = useAccount();
const { data: contract } = useScaffoldContract({
contractName: "YourContract",
account, // No longer supported
});
await contract?.write.setGreeting(["Hello"]);
// v3
const { data: contract } = useScaffoldContract({
contractName: "YourContract",
});
// Read-only โ use .call() for reads
await contract?.call("greeting");
// For writes, use useScaffoldWriteContract instead
useContractWrite โ Removedโ
useContractWrite no longer exists in @starknet-start/react. Use useSendTransaction or the scaffold wrapper useScaffoldWriteContract.
// v2
const { sendAsync, isPending } = useContractWrite({ calls });
await sendAsync();
// v3 โ use useScaffoldWriteContract
const { sendAsync } = useScaffoldWriteContract({
contractName: "YourContract",
functionName: "set_greeting",
args: ["Hello"],
});
await sendAsync();
useContract โ Removedโ
useContract no longer exists. Use starknet.js Contract class directly if you need low-level contract instances.
// v2
import { useContract } from "@starknet-react/core";
const { contract } = useContract({ abi, address });
// v3 โ use starknet.js directly
import { Contract, RpcProvider } from "starknet";
const provider = new RpcProvider({ nodeUrl: "..." });
const contract = new Contract(abi, address, provider);
useTransactorโ
The API has changed significantly:
// v2
const writeTx = useTransactor(_walletClient); // accepted optional wallet client
await writeTx(() => sendAsync()); // took a callback function
// v3
const { writeTransaction, transactionReceiptInstance, sendTransactionInstance } = useTransactor();
// No arguments to useTransactor()
// writeTransaction takes Call[] directly, not a callback
await writeTransaction([
{
contractAddress: "0x...",
entrypoint: "transfer",
calldata: ["0x...", "1", "0"],
},
]);
Key differences:
useTransactor()takes no arguments (no_walletClientparameter)- Returns
{ writeTransaction, transactionReceiptInstance, sendTransactionInstance } writeTransaction(calls: Call[])takes aCall[]array directly instead of a callback function- Use
sendTransactionInstance.isPendingfor loading state
Burner Walletโ
The burner wallet integration has changed completely:
// v2 โ BurnerConnector class added to connectors array
import { BurnerConnector } from "@scaffold-stark/stark-burner";
const burnerConnector = new BurnerConnector();
connectors.push(burnerConnector);
// Switch accounts via: burnerConnector.burnerAccount = accounts[index];
// v3 โ createBurnerWallet() factory returns a MockWallet, passed via extraWallets
import { createBurnerWallet } from "@scaffold-stark/stark-burner";
const burnerWallet = createBurnerWallet(chain);
// Pass to StarknetConfig via extraWallets prop:
// <StarknetConfig extraWallets={[burnerWallet]} ...>
// Switch accounts via: burnerWallet.switchAccount(index);
Key differences:
- Package version:
@scaffold-stark/stark-burner@0.2.0(v3) vs0.1.x(v2) BurnerConnectorclass โcreateBurnerWallet()factory function- Returns a
MockWalletinstance (from@starknet-start/react), not a connector - Passed via
extraWalletsprop toStarknetConfig, not added toconnectorsarray - Account switching:
connector.switchAccount(index)instead ofconnector.burnerAccount = ...
URL Changes for starknet-react Documentationโ
If you reference starknet-react docs, the domain and URL format have changed:
| Old URL | New URL |
|---|---|
https://starknet-react.com/... | https://start.starknet-react.com/... |
https://www.starknet-react.com/... | https://start.starknet-react.com/... |
Hook URL paths changed from kebab-case to camelCase:
| Old Path | New Path |
|---|---|
/docs/hooks/use-read-contract | /docs/hooks/useReadContract |
/docs/hooks/use-send-transaction | /docs/hooks/useSendTransaction |
/docs/hooks/use-transaction-receipt | /docs/hooks/useTransactionReceipt |
Block Explorer: Starkscan โ Voyagerโ
The default block explorer is now Voyager instead of Starkscan. Block explorer links in the UI (transaction links, address links, etc.) will now point to voyager.online and sepolia.voyager.online instead of starkscan.co.
No changes are required in your app code โ this is handled internally by the template. The only case where you need to act is if you customized ScaffoldStarkAppWithProviders.tsx to pass explorer={starkscan}:
// If you have this in your customized ScaffoldStarkAppWithProviders.tsx:
import { starkscan } from "@starknet-react/core"; // remove this
// Replace with:
import { voyager } from "@starknet-start/explorers";
// <StarknetConfig explorer={voyager} ...>
Keplr: Custom Connector Removedโ
The custom KeplrConnector has been removed in v3 โ Keplr is still usable, but you no longer need to import and configure it manually. If Keplr supports the Starknet wallet standard in the user's browser, it will be auto-discovered without any connector code, saving you the bundle size cost of the @keplr-wallet/* packages.
If your v2 project explicitly installed those packages, you can remove them:
npm uninstall @keplr-wallet/types @keplr-wallet/cosmos @keplr-wallet/crypto @keplr-wallet/common @keplr-wallet/unit
Quick Migration Checklistโ
- Replace all
@starknet-react/coreimports with@starknet-start/react - Replace all
@starknet-react/chainsimports with@starknet-start/chains - Remove
accountparameter fromuseScaffoldContractcalls - Replace
useContractWriteusage withuseScaffoldWriteContractoruseSendTransaction - Replace
useContractusage with starknet.jsContractdirectly - Update
useTransactorusage: remove arguments, usewriteTransaction(calls)instead of callback pattern - Remove manual connector setup โ wallets are auto-discovered via wallet standard
- Migrate burner wallet from
BurnerConnectortocreateBurnerWallet()+extraWalletsprop - Update
@scaffold-stark/stark-burnerto0.2.0 - Update any starknet-react documentation links to use
start.starknet-react.com - Remove
@keplr-wallet/*packages frompackage.json(optional โ Keplr is auto-discovered if installed) - If you customized
ScaffoldStarkAppWithProviders.tsx: updateexplorerfromstarkscantovoyager(@starknet-start/explorers)