-
Notifications
You must be signed in to change notification settings - Fork 49
Closed
Description
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
- Create
butterswap.tsfollowing existing tracker patterns - Implement
getTotalBalance()RPC call with block number parameter - Estimate block numbers from timestamps (5-second blocks)
- Return balance difference as single
Feesentry - Add 'butterswap' to services array in
models.ts - Import and integrate in
index.ts - Handle edge cases (negative balance change, contract not existing at old blocks)
Files 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
- 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/
coderabbitai
Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
Status
Done