Documentation Index
Fetch the complete documentation index at: https://docs.stablenet.network/llms.txt
Use this file to discover all available pages before exploring further.
Deploy a Solidity contract to StableNet Testnet using Foundry’s forge and cast tools.
What you’ll learn
By the end of this tutorial, you’ll be able to:
- Configure a Foundry project for StableNet Testnet
- Deploy a WKRC payment contract using
forge script
- Call contract functions with
cast send and verify the result on Explorer
Prerequisites
-
Foundry installed — run
forge --version to check. If not installed:
curl -L https://foundry.paradigm.xyz | bash
foundryup
-
Testnet WKRC from the Faucet
Scaffold your project
forge init stablenet-demo
cd stablenet-demo
Add the StableNet Testnet endpoint to foundry.toml:
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
[rpc_endpoints]
stablenet_testnet = "https://api.test.stablenet.network"
Write WKRCPayment.sol
Delete the placeholder and create src/WKRCPayment.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IERC20 {
function transferFrom(address from, address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
}
/// @title WKRCPayment
/// @notice Accepts WKRC payments from an approved sender.
contract WKRCPayment {
/// @dev NativeCoinAdapter (WKRC) — fixed system contract address on StableNet.
IERC20 public constant WKRC =
IERC20(0x0000000000000000000000000000000000001000);
event Payment(address indexed from, address indexed to, uint256 amount);
/// @notice Pull `amount` of WKRC from msg.sender and forward it to `to`.
/// Requires prior WKRC.approve(address(this), amount).
function pay(address to, uint256 amount) external {
require(WKRC.transferFrom(msg.sender, to, amount), "WKRC transfer failed");
emit Payment(msg.sender, to, amount);
}
function allowanceOf(address owner) external view returns (uint256) {
return WKRC.allowance(owner, address(this));
}
}
Compile to confirm there are no errors:
[⠒] Compiling...
Compiler run successful!
Write the deploy script
Create script/DeployWKRCPayment.s.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script, console} from "forge-std/Script.sol";
import {WKRCPayment} from "../src/WKRCPayment.sol";
contract DeployWKRCPayment is Script {
function run() external {
vm.startBroadcast();
WKRCPayment payment = new WKRCPayment();
console.log("WKRCPayment deployed at:", address(payment));
vm.stopBroadcast();
}
}
Deploy to Testnet
Never commit your private key to version control. Store it in a .env file and add .env to .gitignore.
export PRIVATE_KEY=0xYourPrivateKey
forge script script/DeployWKRCPayment.s.sol \
--rpc-url https://api.test.stablenet.network \
--private-key $PRIVATE_KEY \
--priority-gas-price 27600000000000 \
--broadcast
Script ran successfully.
== Logs ==
WKRCPayment deployed at: 0xABC...
Chain 8283
✅ Hash: 0xDEF...
Contract Address: 0xABC...
Block: NNNN
Save the Contract Address — you need it in the next step.
StableNet enforces a minimum priority fee set by the GovValidator contract. Pass --priority-gas-price 27600000000000 on every forge script and cast send call.
Approve WKRC and send a payment
Before calling pay(), approve the deployed contract to spend WKRC from your wallet:
export CONTRACT=0xABC...
export RECIPIENT=0xRecipientAddress
export AMOUNT=1000000000000000000
export WKRC=0x0000000000000000000000000000000000001000
# Approve the contract to spend 1 WKRC
cast send $WKRC \
"approve(address,uint256)" $CONTRACT $AMOUNT \
--rpc-url https://api.test.stablenet.network \
--private-key $PRIVATE_KEY \
--priority-gas-price 27600000000000
# Call pay() to transfer to the recipient
cast send $CONTRACT \
"pay(address,uint256)" $RECIPIENT $AMOUNT \
--rpc-url https://api.test.stablenet.network \
--private-key $PRIVATE_KEY \
--priority-gas-price 27600000000000
Confirm the allowance was consumed:
cast call $CONTRACT \
"allowanceOf(address)(uint256)" $RECIPIENT \
--rpc-url https://api.test.stablenet.network
Verify on Explorer
Open explorer.stablenet.network and search for your contract address. You should see the deployment transaction, the approve call on the WKRC contract, and the pay call with a Payment event in the logs.
Next steps
Deploy with Hardhat
Deploy the same contract using Hardhat and ethers.js.
Listen to Events
Subscribe to on-chain events with WebSocket.
RPC API Reference
Full list of supported JSON-RPC methods.
Fee Delegation
Let a separate account pay gas for your users.