Appearance
Contract ABIs
Where each ABI lives, and the rule that keeps the duplicated ones in sync.
The three that matter
| Contract | Backend | Frontend | SDK |
|---|---|---|---|
BlazpayRelayer | via swap-sdk | via swap-sdk | swap-sdk/src/utils/jsons/relayerAbi.ts (relayerJson) |
| DCA vault | bz-backend/utils/abi/dcaAbi.json | defi-dex/src/constants/abis/dca.json | — |
| Autopilot vault | bz-backend/utils/abi/autopilotAbi.json | defi-dex/src/constants/abis/autopilot.json | — |
Re-export both copies after every contract upgrade
The DCA and Autopilot ABIs are duplicated by hand in two repos. Upgrading a proxy without refreshing both produces a silent mismatch: the old ABI still encodes calls against the new implementation, so a new function is simply invisible and a changed signature reverts with no useful error.
Both were re-exported after the DCA V2/V2.1 upgrades and after the Autopilot C-1 fix (39 functions).
The relayer ABI lives only in the SDK
Because both consumers reach the relayer through swap-sdk (RelayerFactory), there is one copy. That is the better pattern — and the reason the two vault ABIs are duplicated is that the vaults are called directly rather than via the SDK.
Backend ABIs
bz-backend/utils/abi/
| File | Contract |
|---|---|
autopilotAbi.json | BlazpayAutopilotV1 — 39 functions |
dcaAbi.json | DCAInvestmentV2 |
erc20Abi.json | Standard ERC-20 |
utilityAbi.json | Shared utilities |
NFTMarketplace.json | Marketplace |
stake.json | Token staking |
stakeStone.json | StakeStone |
games.json | Games |
entrypass.json | Entry pass NFT |
Per-chain ABI directories
The ecosystem contracts are deployed per chain with per-chain ABIs rather than one parameterised set:
| Directory | Files |
|---|---|
arbitrum/ | MarketplaceNFT, NFTStaking, ProductGames, ProductNFTs, ProductStake, ProductToken, RewardsHub |
binance/ | entrypass |
holesky/ | BlazPayPointsToken, BlazpayProducts, StakeShardeum, v2Testnet |
manta/ | entrypass, games, products, stake, token |
taiko/ | entrypass, games, products, stake, token |
viction/ | games, products, stake, token |
zkfair/ | entrypass, games, products, stake, token |
This mirrors the contract sprawl
contract-deployment/contracts/ duplicates the same Solidity per chain (arbitrum_sepolia/, avax/, hemi/, qubetics/, soneium/). Adding a chain to the ecosystem layer means copying a directory in two places. The trading core does not have this problem because the relayer is genuinely identical everywhere.
Frontend ABIs
defi-dex/src/constants/abis/
| File | Contract |
|---|---|
autopilot.json | BlazpayAutopilotV1 |
dca.json | DCAInvestmentV2 |
erc20.json, erc20.ts | Standard ERC-20 (JSON and typed) |
erc20_bytes32.json | Tokens with bytes32 name/symbol (early tokens like MKR) |
weth.json | WETH wrap/unwrap |
ens-registrar.json, ens-public-resolver.json | ENS |
ens-*.json is present but ENS resolution is not wired
The wallet card resolves .eth names against the internal username database only. Real on-chain resolution is one ENS Universal Resolver eth_call away, and the ABIs are already here.
Solidity sources
| Path | Contents |
|---|---|
bz-backend/contract-deployment/contracts/BlazpayRelayer.sol | v2 — the authoritative relayer source |
contracts/dca/{BlazpayDcaV1,BlazpayDcaV2,Types}.sol | DCA vault. V1 was fetched from Arbiscan |
contracts/autopilot/{BlazpayAutopilotV1,AutopilotTypes}.sol | Autopilot vault |
contracts/mocks/AutopilotMocks.sol | Test doubles |
contracts/modular/*.sol | Current NFT, staking and marketplace contracts |
contracts/poker/PokerManager.sol | Poker |
contracts/{arbitrum_sepolia,avax,hemi,qubetics,soneium}/ | Per-chain copies |
contracts/deprecated/ | Eight superseded contracts — do not extend |
defi-set/finalContracts/ | Frozen v1 relayer + OZ tree, a verification artefact |
finalContracts/ is v1, not what is deployed
Its signature check is signer == msg.sender; v2's is recovered == signer where signer is the platform's TX_SIGNER. That is a substantive behavioural difference. Read contract-deployment/contracts/BlazpayRelayer.sol.
Getting a fresh ABI
After a Hardhat compile:
bash
cd bz-backend/contract-deployment
npx hardhat compile
# Autopilot
node -e "
const a=require('./artifacts/contracts/autopilot/BlazpayAutopilotV1.sol/BlazpayAutopilotV1.json');
require('fs').writeFileSync('../utils/abi/autopilotAbi.json', JSON.stringify(a.abi,null,2));
"
# then copy the same JSON to defi-dex/src/constants/abis/autopilot.jsonVerify the function count after re-exporting
The Autopilot ABI should have 39 functions. A count that drops means the export picked up a stale artefact — run npx hardhat clean and recompile.
Verification status
| Contract | Verified on |
|---|---|
| BlazpayRelayer v2 | Per-chain explorers |
| DCA V2 and V2.1 | Arbiscan + Sourcify |
| Autopilot proxy + implementation | Arbiscan |
finalContracts/deployed/metadata.json and creator-tx-hash.txt hold the original v1 relayer verification artefacts.
Explorer API keys for verification: ETHERSCAN_API_KEY (v2 unified), plus ARBISCAN_API_KEY, BSCSCAN_API_KEY, POLYGONSCAN_API_KEY, BASESCAN_API_KEY, OPSCAN_API_KEY.
Struct definitions
For hand-encoding calls, the three important structs:
MetaTransaction (relayer)
solidity
struct MetaTransaction {
address targetContract; // aggregator router
bytes data;
uint256 amount;
address token;
bool isNative;
address recipient; // ⚠ the SPENDER, not the end user
uint256 nativeValue;
uint256 nonce;
uint256 deadline;
}EIP-712 type string:
MetaTransaction(address targetContract,bytes data,uint256 amount,address token,
bool isNative,address recipient,uint256 nativeValue,
uint256 nonce,uint256 deadline)Domain: name="BlazpayRelayer", version="1", chainId, verifyingContract=relayerAddresses(chainId).
Limits and TradeParams (Autopilot)
solidity
struct Limits {
uint128 maxPerTrade;
uint128 maxPerDay;
uint64 expiry;
uint16 maxTradesPerDay; // 0 = unlimited
}
struct TradeParams {
uint256 agentId;
address fromToken; // address(0) == native
address toToken;
uint256 amountIn;
uint256 minOut;
address targetContract; // must be allow-listed
address spender; // must be allow-listed if different
bytes data;
}Full type reference: Autopilot vault.