> ## 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 Contract with Foundry

> Scaffold a Foundry project, write a WKRC payment contract, and deploy it to StableNet Testnet.

> 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:

  ```shell theme={null}
  curl -L https://foundry.paradigm.xyz | bash
  foundryup
  ```

* Testnet WKRC from the [Faucet](https://faucet.stablenet.network)

## Scaffold your project

```shell theme={null}
forge init stablenet-demo
cd stablenet-demo
```

## Configure foundry.toml

Add the StableNet Testnet endpoint to `foundry.toml`:

```toml theme={null}
[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`:

```shell theme={null}
rm src/Counter.sol
```

```solidity theme={null}
// 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:

```shell theme={null}
forge build
```

```text theme={null}
[⠒] Compiling...
Compiler run successful!
```

## Write the deploy script

Create `script/DeployWKRCPayment.s.sol`:

```solidity theme={null}
// 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

<Warning>
  Never commit your private key to version control. Store it in a `.env` file and add `.env` to `.gitignore`.
</Warning>

```shell theme={null}
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
```

```text theme={null}
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.

<Note>
  StableNet enforces a minimum priority fee set by the GovValidator contract. Pass `--priority-gas-price 27600000000000` on every `forge script` and `cast send` call.
</Note>

## Approve WKRC and send a payment

Before calling `pay()`, approve the deployed contract to spend WKRC from your wallet:

```shell theme={null}
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:

```shell theme={null}
cast call $CONTRACT \
  "allowanceOf(address)(uint256)" $RECIPIENT \
  --rpc-url https://api.test.stablenet.network
```

```text theme={null}
0
```

## Verify on Explorer

Open [explorer.stablenet.network](https://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

<CardGroup cols={2}>
  <Card title="Deploy with Hardhat" href="/en/v0.3/build/tutorials/deploy-with-hardhat">Deploy the same contract using Hardhat and ethers.js.</Card>
  <Card title="Listen to Events" href="/en/v0.3/build/tutorials/listen-to-events">Subscribe to on-chain events with WebSocket.</Card>
  <Card title="RPC API Reference" href="/en/v0.3/reference/rpc-api">Full list of supported JSON-RPC methods.</Card>
  <Card title="Fee Delegation" href="/en/v0.3/build/tutorials/fee-delegation">Let a separate account pay gas for your users.</Card>
</CardGroup>
