Context
The ShapeShift affiliate revenue API aggregates fee data from multiple swap providers. ButterSwap is a cross-chain swap provider on MAP Protocol. Unlike other providers, ButterSwap doesn't have a public API for transaction-level affiliate data, but we can query historical balances directly from their smart contract.
Repository: shapeshift/unchained
Location: node/proxy/api/src/affiliateRevenue/
Technical Approach
ButterSwap's affiliate contract on MAP Protocol supports historical block queries via eth_call. We can estimate block numbers from timestamps and query the balance difference.
Key Details:
- Contract:
0x4De2ADb9cB88c10Bf200F76c18035cbB8906b6bC
- RPC:
https://rpc.maplabs.io/
- Chain ID: 22776 (MAP Protocol)
- Block time: ~5 seconds
- Function:
getTotalBalance(uint256 affiliateId, address[] tokens, address quoteToken)
- Affiliate ID: 26
- Quote token (USDT):
0x33daba9618a75a7aff103e53afe530fbacf4a3dd
Implementation
export const getFees = async (startTimestamp: number, endTimestamp: number): Promise<Fees[]> => {
const currentBlock = await getBlockNumber()
const now = Math.floor(Date.now() / 1000)
const BLOCK_TIME = 5 // MAP Protocol 5-second blocks
// Estimate block numbers from timestamps
const startBlock = currentBlock - Math.floor((now - startTimestamp) / BLOCK_TIME)
const endBlock = currentBlock - Math.floor((now - endTimestamp) / BLOCK_TIME)
// Query balance at both blocks
const balanceAtStart = await getTotalBalance(startBlock)
const balanceAtEnd = await getTotalBalance(endBlock)
const feesForPeriod = balanceAtEnd - balanceAtStart
// Return as single fee entry at end of period to conform to Fees[] shape
if (feesForPeriod <= 0) return []
return [{
service: 'butterswap',
amount: feesForPeriod.toString(),
amountUsd: feesForPeriod.toString(), // Already in USDT
chainId: 'eip155:22776',
assetId: 'eip155:22776/erc20:0x33daba9618a75a7aff103e53afe530fbacf4a3dd',
timestamp: endTimestamp,
txHash: '', // No single tx - aggregate balance change
}]
}
Acceptance Criteria
Files to Create/Modify
node/proxy/api/src/affiliateRevenue/butterswap.ts (new)
node/proxy/api/src/affiliateRevenue/index.ts
node/proxy/api/src/models.ts
node/proxy/api/src/affiliateRevenue/constants.ts (add MAP Protocol chain ID, contract address)
Notes
- Returns aggregate fees for the period, not per-transaction data
- Block estimation is ~99% accurate (sufficient for revenue tracking)
- No database or caching required - stateless queries
- USDT has 18 decimals on MAP Protocol
Reference
- Python implementation:
newrfox3.0/butterswap_tracker.py
- MAP Protocol block explorer: https://maposcan.io/
Context
The ShapeShift affiliate revenue API aggregates fee data from multiple swap providers. ButterSwap is a cross-chain swap provider on MAP Protocol. Unlike other providers, ButterSwap doesn't have a public API for transaction-level affiliate data, but we can query historical balances directly from their smart contract.
Repository:
shapeshift/unchainedLocation:
node/proxy/api/src/affiliateRevenue/Technical Approach
ButterSwap's affiliate contract on MAP Protocol supports historical block queries via
eth_call. We can estimate block numbers from timestamps and query the balance difference.Key Details:
0x4De2ADb9cB88c10Bf200F76c18035cbB8906b6bChttps://rpc.maplabs.io/getTotalBalance(uint256 affiliateId, address[] tokens, address quoteToken)0x33daba9618a75a7aff103e53afe530fbacf4a3ddImplementation
Acceptance Criteria
butterswap.tsfollowing existing tracker patternsgetTotalBalance()RPC call with block number parameterFeesentrymodels.tsindex.tsFiles to Create/Modify
node/proxy/api/src/affiliateRevenue/butterswap.ts(new)node/proxy/api/src/affiliateRevenue/index.tsnode/proxy/api/src/models.tsnode/proxy/api/src/affiliateRevenue/constants.ts(add MAP Protocol chain ID, contract address)Notes
Reference
newrfox3.0/butterswap_tracker.py