Build
Deploy with Foundry
Configure Foundry for Lib Testnet, deploy with forge create or a script, test against the live chain, and read state with cast.
Foundry works with LibChain without plugins. This guide assumes you have it installed (foundryup) and a testnet key funded from the faucet.
#Configure
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc_version = "0.8.28"
evm_version = "cancun"
optimizer = true
optimizer_runs = 200
[rpc_endpoints]
lib_testnet = "https://rpc-testnet.libchain.tech"Keep your key out of the repository. Put it in an environment variable, or better, in Foundry's encrypted keystore:
cast wallet import lib-testnet --interactive # paste a testnet-only key, set a password
cast wallet address --account lib-testnet#Deploy a single contract
forge create src/Counter.sol:Counter \
--rpc-url lib_testnet \
--account lib-testnet \
--broadcastConstructor arguments go last: --constructor-args 42 "hello". Without --broadcast, recent Foundry versions only simulate.
#Deploy with a script
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {Script, console} from "forge-std/Script.sol";
import {Counter} from "../src/Counter.sol";
contract Deploy is Script {
function run() external {
vm.startBroadcast();
Counter counter = new Counter();
counter.setNumber(1);
vm.stopBroadcast();
console.log("Counter deployed at", address(counter));
}
}forge script script/Deploy.s.sol \
--rpc-url lib_testnet \
--account lib-testnet \
--broadcastEach transaction is final in its block, so the script's receipts are final as soon as Foundry prints them. Broadcast logs are saved under broadcast/.
#Test against the live chain
Fork tests run your tests on a local copy of Lib Testnet's state, so you can call deployed contracts such as WtLIB:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {Test} from "forge-std/Test.sol";
interface IWtLIB {
function deposit() external payable;
function balanceOf(address) external view returns (uint256);
}
contract WtLIBForkTest is Test {
IWtLIB constant WTLIB = IWtLIB(0x87052f1f17b2b4054b014e93e53d6ce6dc912bda);
function setUp() public {
vm.createSelectFork("lib_testnet");
}
function test_wrap() public {
vm.deal(address(this), 1 ether);
WTLIB.deposit{value: 1 ether}();
assertEq(WTLIB.balanceOf(address(this)), 1 ether);
}
}forge test --match-contract WtLIBForkTest -vv#Read and write with cast
cast block-number --rpc-url lib_testnet
cast balance 0xYourAddress --ether --rpc-url lib_testnet
cast call 0x87052f1f17b2b4054b014e93e53d6ce6dc912bda "totalSupply()(uint256)" --rpc-url lib_testnet
cast send 0xYourContract "setNumber(uint256)" 7 --account lib-testnet --rpc-url lib_testnet
cast receipt 0xTxHash --rpc-url lib_testnetThe public RPC doesn't expose debug_* or trace_* methods, so cast run can't replay a transaction from the chain. Reproduce failures in a fork test instead: forge test -vvvv traces locally.
#Next
Publish your source with Verify a contract, or call your contract from a web page with Build a dApp.