SettlementContract reference
ABI, storage layout, and deployment addresses for SettlementContract.sol.
The SettlementContract is the on-chain endpoint of every aa-native payment. This page is the contract's reference card. The conceptual overview is on the Settlement contract concept page.
Deployment addresses
| Network | Proxy | Implementation |
|---|---|---|
NERO mainnet (eip155:1689) | 0x5eCfc64f2339992668f555918674B604F97B412D | 0xb7f16185619c476ce3fd3fd9e8b6186e340802f6 |
NERO testnet (eip155:689) | 0x925dbba44570683ac8da99be08bc5ece8cf5a8c6 | (proxy implementation address) |
The proxy is the address callers reference. Implementation addresses change on upgrade.
Public interface
settle(address merchant, address token, uint256 amount, bytes32 requestHash)
Settles one payment. Reverts on:
| Condition | Custom error |
|---|---|
msg.value != 0 | UnexpectedNativeValue() |
merchant == address(0) | ZeroAddress() |
token == address(0) | ZeroAddress() |
amount == 0 | ZeroAmount() |
requestHash == bytes32(0) | ZeroRequestHash() |
!isTokenAllowed[token] | TokenNotAllowed(address token) |
isSettled[requestHash] | AlreadySettled(bytes32 requestHash) |
| Reentrancy guard tripped | (ReentrancyGuardReentrantCall()) |
| Contract is paused | (EnforcedPause()) |
After validation, isSettled[requestHash] is set to true, then IERC20(token).safeTransferFrom(msg.sender, merchant, amount) runs. The contract post-checks that the merchant's balance increased by exactly amount. On success, ReceiptLog is emitted.
msg.sender is the paying SCW. It must have approved the contract for amount of token before the call.
View functions
mapping(bytes32 requestHash => bool settled) public isSettled;
mapping(address token => bool allowed) public isTokenAllowed;Owner-only functions
function setTokenAllowed(address token, bool allowed) external onlyOwner;
function pause() external onlyOwner;
function unpause() external onlyOwner;
function _authorizeUpgrade(address newImplementation) internal override onlyOwner;Events
event ReceiptLog(
address indexed merchant,
address indexed payer,
address indexed token,
uint256 amount,
bytes32 requestHash
);Emitted on every successful settlement. The three indexed arguments allow efficient getLogs filtering by merchant, payer, or token.
ABI fragments (TypeScript)
const SETTLEMENT_ABI = [
"function settle(address merchant, address token, uint256 amount, bytes32 requestHash) external payable",
"function isSettled(bytes32 requestHash) view returns (bool)",
"function isTokenAllowed(address token) view returns (bool)",
"event ReceiptLog(address indexed merchant, address indexed payer, address indexed token, uint256 amount, bytes32 requestHash)",
"error UnexpectedNativeValue()",
"error ZeroAddress()",
"error ZeroAmount()",
"error ZeroRequestHash()",
"error TokenNotAllowed(address token)",
"error AlreadySettled(bytes32 requestHash)",
] as const;Indexing settlements
A merchant or external indexer can read all settlements without querying the facilitator:
import { createPublicClient, http, parseAbiItem } from "viem";
const RECEIPT_LOG = parseAbiItem(
"event ReceiptLog(address indexed merchant, address indexed payer, address indexed token, uint256 amount, bytes32 requestHash)",
);
const logs = await client.getLogs({
address: SETTLEMENT_CONTRACT,
event: RECEIPT_LOG,
fromBlock: BigInt(0),
toBlock: "latest",
});The reference Playground's live ledger panel uses exactly this pattern.
Source
The contract source is at contracts/src/SettlementContract.sol. The interface is at contracts/src/interfaces/ISettlement.sol. The deployment scripts are in contracts/script/.