Working with the Contracts
Setup
cd contracts
npm install
Compile & test
npx hardhat compile
npx hardhat test # 71 tests
Tests run on the in-memory Hardhat network with a MockUSDC (6 decimals), covering sends, batches, requests, subscriptions, refunds, pausing, token allowlisting, and two-step ownership.
Deploy to Arc Testnet
- Copy
.env.exampleto.envand setPRIVATE_KEY - Fund the deployer with USDC from faucet.circle.com - gas is paid in USDC, so nothing else is needed
- Deploy:
npm run deploy:arc
The script deploys AruviPaymentGateway pointed at Arc's canonical USDC (0x3600…0000) and enables EURC as a second settlement token. It prints the gateway address and an ArcScan link.
- Verify (optional):
npx hardhat verify --network arcTestnet <GATEWAY_ADDRESS> 0x3600000000000000000000000000000000000000
- Wire the frontend: put the gateway address and deploy block into
frontend/.env:
VITE_ARUVI_GATEWAY_ADDRESS=0x…
VITE_GATEWAY_DEPLOY_BLOCK=123456
Network config
hardhat.config.ts ships with:
arcTestnet: {
chainId: 5042002,
url: process.env.ARC_TESTNET_RPC_URL ?? "https://rpc.testnet.arc.network",
accounts: [process.env.PRIVATE_KEY],
}
Arc targets the Osaka hard fork; the contracts compile with evmVersion: cancun, which is fully compatible.
Calling the gateway from your own contract
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IAruviGateway {
function send(address recipient, uint256 amount, string calldata memo)
external returns (bytes32 paymentId);
}
contract MyDapp {
IAruviGateway constant ARUVI = IAruviGateway(0x /* gateway */);
IERC20 constant USDC = IERC20(0x3600000000000000000000000000000000000000);
function payOut(address to, uint256 amount) external {
USDC.approve(address(ARUVI), amount);
ARUVI.send(to, amount, "protocol payout");
}
}
Full function reference: API → Payment Gateway.