@trezo/strk - Starknet
Type-safe toolkit for interacting with Starknet smart contracts and wallets.
Install Package
pnpm add @trezo/strk
@trezo/strk provides a type-safe layer for building Starknet applications, with strongly typed contract interactions and seamless wallet integration for frontend developers.
Create Configuration
Example Usage
import { create, StarknetChains } from "@trezo/strk";
const contractAbi = [...] as const; // must be as const
const infuraApiKey = "py7n3kjba74bflasfe738";
export const useConfig = create({
address: "0x...",
abi: contractAbi,
chains: [StarknetChains.sepolia],
rpcUrls: {
sepolia: `https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_10/${infuraApiKey}`,
mainnet: `https://starknet-mainnet.g.alchemy.com/starknet/version/rpc/v0_10/${infuraApiKey}`
},
modalConfig: {
from: "starknetkit",
options: {
connection: { autoConnect: true },
explorer: "voyager",
network: { provider: "jsonRpc", defaultChain: StarknetChains.sepolia },
ui: { modalTheme: "system", dappName: "My Dapp" },
wallets: { enabled: ["argent", "braavos", "webwallet"] },
},
},
});
export const Provider = useConfig.Provider;
export const ConnectButton = useConfig.ConnectButton;address— deployed contract addressabi— contract ABI typedas const. Withoutas constyou lose all type safety.chains— supported network (mainnet,sepolia, ordevnet).rpcUrls— required custom RPC endpoints (do not rely on public nodes)modalConfig— wallet modal provider (fully typed with autocomplete)
RPC Requirement
Using a public node RPC may result in CORS (Cross-Origin) errors in browser environments.
If no RPC is provided, the library falls back to a default public node, which will show this warning:
INFO: Using default public node url,
please provide nodeUrl in provider options!To avoid errors and ensure reliability, you must provide your own RPC endpoint from a provider such as:
Add Provider
Must wrap your entire app.
import { Provider } from "@/hooks/useConfig";
export default function Root({ children }) {
return <Provider>{children}</Provider>;
}Basic Usage
import { useConfig, ConnectButton } from "@/hooks/useConfig";
export default function App() {
const { wallet, call } = useConfig();
// Read — view functions
const fetchCounter = async () => {
const { data, error } = await call.queryFn("get_counter", []);
if (error) console.error(error.message);
else console.log(data); // bigint
};
// Write — external functions
const increase = async () => {
const { data, error } = await call.mutateFn("increase_counter", [
BigInt(1),
]);
if (error) console.error(error.message);
else console.log(data?.hash);
};
// Listen — events
useEffect(() => {
return call.listenFn({
increase: {
eventName: "counter_starknetjs::test_session::CounterIncreased",
listener: fetchCounter,
},
});
}, [wallet.account.address]);
return (
<>
<ConnectButton>
{({ isConnected, truncatedAddress, open }) => (
<button className="counter" onClick={() => open()}>
{isConnected ? truncatedAddress : "Connect"}
</button>
)}
</ConnectButton>
<button className="counter" onClick={increase}>
Increment by 1
</button>
<button className="counter">Count is {count}</button>
</>
);
}wallet— connection state (isConnected,address, etc.)call— contract helpers (queryFn,mutateFn,listenFn)
Plugins Setup
Use plugins when you get "Invalid hook call" errors
Vite Plugin
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import trezoVitePlugin from "@trezo/strk/plugins/vite";
export default defineConfig({
plugins: [react(), trezoVitePlugin()],
});ABI Type Mapping
| Cairo Type | TypeScript Input | TypeScript Output |
|---|---|---|
felt252 | string | string |
u8 / u16 / u32 / u64 / u128 / u256 | BigNumberish | bigint |
bool | boolean | boolean |
ContractAddress | string | string |
ClassHash | string | string |