Appearance
Coinfair DeFi 平台技术文档
1. 系统概述
1.1 整体架构
Coinfair 是一个基于 Aptos 区块链构建的去中心化交易平台,包含三个核心合约系统:
区块链层 - Aptos Network
存储层
缓存层
业务层
API 层
用户层
Web 前端应用
移动端 DApp
API 网关
REST API 服务
WebSocket 服务
价格引擎
订单状态服务
事件监听器
Redis 集群
PostgreSQL
CoinfairClmm 合约
BMM AMM DEX
OrderBook 合约
限价订单簿
Referral 合约
推荐系统
1.2 核心功能模块
| 模块 | 功能 | 技术特点 |
|---|---|---|
| CoinfairClmm | 集中流动性做市商 (CLMM) | x⁴·y=k 曲线,NFT 头寸,多奖励机制 |
| OrderBook | 限价订单簿系统 | 中心化撮合 + CLMM 执行,多 TIF 类型 |
| Referral | 推荐奖励系统 | NFT 关系证明,多级推荐,不可转移 |
2. 智能合约架构
2.1 合约模块关系图
Referral 合约系统
├── referral - 推荐核心
├── GlobalState - 全局状态
└── NFT Collection - 关系证明
OrderBook 合约系统
├── multi_order_book - 订单簿核心
├── ManagerStore - 权限管理
└── OrderBook - 单池订单簿
CoinfairClmm 合约系统
├── clmm_router - 路由层
├── factory - 池创建
├── pool - 核心池
├── config - 配置
├── fee_tier - 费率层
├── tick_math - 价格转换
├── clmm_math - BMM 数学
└── position_nft - NFT 管理2.2 CoinfairClmm 核心架构
Pool
├── +u64 index
├── +u128 liquidity
├── +u128 current_fifrt_price
├── +I64 current_tick_index
├── +Table<I64,Tick> ticks
├── +Table<u64,Position> positions
├── +vector<Rewarder> rewarder_infos
├── +flash_swap()
├── +add_liquidity()
├── +remove_liquidity()
└── +collect_fee()
Position
├── +u64 index
├── +u128 liquidity
├── +I64 tick_lower_index
├── +I64 tick_upper_index
├── +u128 fee_growth_inside_a
└── +u128 fee_growth_inside_b
Tick
├── +I64 index
├── +u128 fifrt_price
├── +I128 liquidity_net
├── +u128 liquidity_gross
├── +u128 fee_growth_outside_a
└── +u128 fee_growth_outside_b
GlobalConfig
├── +address protocol_authority
├── +u64 protocol_fee_rate
├── +u64 creator_fee_rate
├── +u64 referrer_fee_rate
└── +bool is_pause
FeeTier
├── +u64 tick_spacing
└── +u64 fee_rate关键特性:
BMM 曲线 (x⁴·y=k)
- 更集中的流动性分布
- 更高的资金效率
- 适应高波动市场
统一费用机制
- 所有费用从 token B 收取
- A→B 交易:从输出中扣除
- B→A 交易:从输入中扣除
NFT 头寸管理
- 使用 Aptos Token 标准
- 可转让的所有权
- NFT 属性存储位置信息
2.3 OrderBook 核心架构
OrderBook
├── +u64 id
├── +SmartTable<u128,LimitOrder> orders
├── +SmartTable~address,vector<u128> user_orders
├── +SmartTable~I64,vector<u128> buy_orders_by_tick
├── +SmartTable~I64,vector<u128> sell_orders_by_tick
├── +vector<I64> active_buy_ticks
├── +vector<I64> active_sell_ticks
├── +Option<I64> best_bid_tick
├── +Option<I64> best_ask_tick
├── +create_limit_order()
├── +cancel_order()
├── +try_centralized_crossing()
└── +execute_order_match()
LimitOrder
├── +u128 id
├── +address owner
├── +address pool
├── +u64 amount_x
├── +I64 tick
├── +u64 filled_x
├── +u8 status
├── +u8 order_type
├── +u64 created_at
└── +u64 expiration_time
MultiOrderBook
├── +vector<address> registered_pools
├── +SmartTable<address,address> pool_orderbooks
├── +u128 global_order_book_id
└── +u64 total_pools
ManagerStore
├── +address admin
├── +address fee_recipient
└── +SignerCapability resource_sig执行流程:
CLMM 池 ←→ 撮合引擎 ←→ OrderBook ←→ 用户
[未完全成交] [仍有剩余]
[TIF = POST_ONLY] [TIF = GTC_EXEC_ON_ADD]
create_limit_order(amount, tick, TIF)
→ 锁定用户资金
→ 直接存储订单
→ 返回 order_id
try_centralized_crossing()
→ 匹配现有订单
→ 返回已成交量
try_execute_on_add_clmm(剩余量)
→ flash_swap()
→ 返回成交结果
存储剩余部分订单
返回成交详情2.4 Referral 核心架构
GlobalState
├── +u64 referral_code_counter
├── +Table<address,ReferrerInfo> referrer_info_table
├── +Table<u64,address> referral_code_table
├── +Table<address,ReferralRelation> referral_relation_table
├── +u64 total_referrers
├── +u64 total_relations
└── +SignerCapability nft_creator_cap
ReferrerInfo
├── +address referrer_address
├── +u64 referral_code
├── +u64 total_nft_amount
├── +u64 claimed_amount
├── +u64 created_at
└── +u64 updated_at
ReferralRelation
├── +address referee_address
├── +address referrer
├── +u64 referral_code
├── +String token_name
└── +u64 created_at
ReferralNFT
├── +String name
├── +u64 referral_code
├── +bool transferable
└── +bool burnable_by_creator推荐关系流程:
用户 A 注册成为推荐人
→ 创建推荐码
→ [有效/无效]
→ [是/否]分配推荐配额
total_nft_amount
用户 B 使用推荐码
验证推荐码
铸造 NFT 给用户 B
抛出错误
创建推荐关系记录
递减推荐人配额
claimed_amount++
用户 B 成为推荐人?
创建新推荐码
结束
用户 C 使用 B 的推荐码
形成多级链
C -> B -> A
3. 前端架构
3.1 技术栈
图表 & 可视化
区块链集成
前端技术栈
React 18
UI 框架
TypeScript
类型安全
Zustand
状态管理
React Query
数据获取
TailwindCSS
样式系统
Vite
构建工具
Aptos Wallet Adapter
@aptos-labs/ts-sdk
@aptos-labs/wallet-adapter
TradingView Charting
Recharts
数据图表
3.2 组件架构
Hooks 层
组件层 Components
容器层 Containers
页面层 Pages
交易页面
流动性池页面
头寸管理页面
订单管理页面
推荐页面
数据分析页面
Swap 容器
池列表容器
订单簿容器
推荐容器
代币选择器
价格图表
流动性分布图
订单表单
订单列表
推荐关系树
useWallet
钱包连接
usePool
池数据
useSwap
交易
useOrders
订单
useReferral
推荐
3.3 状态管理架构
Components
React Query Cache
Zustand Store
更新
更新
钱包状态
address, connected
池状态
pools, selected
订单状态
orders, history
UI 状态
theme, modal
池查询
price, liquidity
订单查询
user orders
事件查询
swaps, adds
UI 组件
3.4 与合约交互的数据流
事件监听器智能合约钱包插件 Aptos SDKCustom Hook 前端组件事件监听器智能合约钱包插件 Aptos SDKCustom Hook 前端组件调用操作 (如 swap)构建交易 payloadgenerateTransaction()请求签名用户确认返回签名提交交易执行交易交易哈希交易结果更新 UI 状态发出事件监听事件实时更新数据
4. 后端架构
4.1 微服务架构
Data Layer
Message Queue
Worker Layer
Service Layer
API Gateway Layer
NGINX
负载均衡
Kong Gateway
API 网关
价格服务
Rust + Axum
订单服务
Rust + Axum
分析服务
Rust + Axum
通知服务
Rust + Tonic gRPC
事件监听 Worker
Rust + Tokio
数据聚合 Worker
Rust + Tokio
缓存预热 Worker
Rust
RabbitMQ
消息队列
Redis Cluster
缓存层
PostgreSQL
关系数据
TimescaleDB
时序数据
ClickHouse
分析数据
InfluxDB
4.2 事件监听架构
PostgreSQLRedis 缓存业务服务消息队列事件监听 WorkerAptos Indexer APIAptos 合约 PostgreSQLRedis 缓存业务服务消息队列事件监听 WorkerAptos Indexer APIAptos 合约 loop[每 1 秒轮询]alt[SwapEvent][AddLiquidityEvent][OrderExecutedEvent-]执行交易发出事件 GET /events?start_seq={last}返回新事件解析事件数据 publish('swap.executed')更新价格更新价格缓存 publish('liquidity.added')更新 TVLpublish('order.executed')更新订单状态持久化事件数据
4.3 价格服务架构
存储
数据源
价格服务 Price Service
实时推送
REST API
Express Router
WebSocket Server
Socket.io
价格计算引擎
OHLCV 构建器
链上事件
SwapEvent
CLMM View 函数
get_fifrt_price
Redis
实时价格
InfluxDB
历史价格
4.4 订单服务架构
链上撮合
缓存
数据库
订单服务 Order Service
创建订单
监控撮合
REST API
订单验证器
撮合监控
状态同步
过期检查器
PostgreSQL
订单表
Redis
活跃订单
OrderBook 合约
🔥 实际撮合逻辑
🎯 关键设计说明:
- 撮合逻辑:完全在 OrderBook 合约的
try_centralized_crossing()中实现 - 后端职责:仅负责状态监控、数据同步、过期检查等辅助功能
- 订单执行:通过合约的两阶段执行(中心化撮合 + CLMM 执行)
- 数据一致性:通过事件监听确保链上与数据库状态同步
数据库设计:
-- 订单表
CREATE TABLE orders (
id BIGINT PRIMARY KEY, -- 订单 ID (链上)
pool_address VARCHAR(66) NOT NULL,
owner_address VARCHAR(66) NOT NULL,
order_type SMALLINT NOT NULL, -- 0=买, 1=卖
token_x VARCHAR(66) NOT NULL,
amount_x NUMERIC(38, 8) NOT NULL,
tick BIGINT NOT NULL,
filled_x NUMERIC(38, 8) DEFAULT 0,
status SMALLINT NOT NULL, -- 0=活跃, 1=部分成交, 2=完全成交, 3=取消, 4=过期
tif_type SMALLINT NOT NULL, -- 0=POST_ONLY, 1=IOC, 2=FOK, 3=GTC_EXEC
created_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL,
expiration_time TIMESTAMP,
INDEX idx_owner (owner_address),
INDEX idx_pool_status (pool_address, status),
INDEX idx_pool_tick (pool_address, tick),
INDEX idx_expiration (expiration_time) WHERE status IN (0, 1)
);
-- 订单执行历史
CREATE TABLE order_executions (
id SERIAL PRIMARY KEY,
order_id BIGINT REFERENCES orders(id),
counterparty_order_id BIGINT,
executed_amount NUMERIC(38, 8),
execution_price NUMERIC(38, 18),
fee_amount NUMERIC(38, 8),
executed_at TIMESTAMP NOT NULL,
tx_hash VARCHAR(66),
INDEX idx_order (order_id),
INDEX idx_time (executed_at)
);5. 交互流程设计
5.1 用户交易流程 (CLMM Swap)
事件服务 CLMM 合约后端 APIAptos 钱包前端 UI 事件服务 CLMM 合约后端 APIAptos 钱包前端 UI 用户 1. 输入交易对和数量 2. GET /quote (估算输出)3. 调用 view 函数估算价格 4. 返回估算结果 5. 返回 quote6. 显示预期输出和滑点 7. 确认交易 8. 构建交易 payloadclmm_router::swap()9. 请求签名 10. 用户授权 11. 签名完成 12. 提交交易到链上 13. 执行 swap 逻辑- try_centralized_crossing- flash_swap14. 更新池状态- current_price- liquidity15. 发出 SwapEvent16. 返回交易哈希 17. 查询交易状态 18. 交易确认 19. 监听到 SwapEvent20. 更新价格缓存 21. WebSocket 推送更新 22. 刷新余额和价格用户
5.2 添加流动性流程
CLMM 合约钱包前端 UICLMM 合约钱包前端 UI 用户 1. 选择价格区间(tick_lower, tick_upper)2. 计算所需代币数量 clmm_math::get_amount_by_liquidity3. 显示所需数量 4. 输入代币数量 5. 验证余额 6. 确认添加流动性 7. 请求签名 8. 签名完成 9. clmm_router::add_liquidity_fix_token(pool, tick_lower, tick_upper, amount_a, amount_b)10. 计算流动性 get_liquidity_from_amount11. 更新 tick 数据 liquidity_net, liquidity_gross12. 铸造/更新 Position NFT13. 转移代币到池 14. 发出 AddLiquidityEvent15. 返回 position_id16. 显示 NFT 和头寸详情用户
5.3 创建限价订单流程
CLMM 合约 OrderBook 合约钱包后端 API 前端 UICLMM 合约 OrderBook 合约钱包后端 API 前端 UIalt[未完全成交]alt[仍有剩余]alt[TIF = POST_ONLY][TIF = GTC_EXEC_ON_ADD]用户 1. 输入限价订单参数(价格, 数量, TIF)2. 将价格转换为 tick3. 验证订单参数 4. 参数有效 5. 确认创建订单 6. 请求签名 7. 签名完成 8. create_limit_order_for_pool_with_tif(pool, amount, tick, order_type, expiration, tif)9. 锁定用户代币 transfer to FungibleStore10a. 直接存储订单 11a. 返回 order_id10b. Phase 1: 中心化撮合 try_centralized_crossing()匹配现有订单 10c. Phase 2: CLMM 执行 flash_swap(剩余量)执行交易返回成交量 10d. 存储剩余部分订单 11b. 返回成交详情 12. 发出 OrderCreatedEvent13. 存储订单到数据库 14. WebSocket 推送订单状态用户
5.4 推荐流程
Referral 合约后端 API 前端 UIReferral 合约后端 API 前端 UI 形成多级推荐链新用户 -> 推荐人 -> ...opt[新用户也成为推荐人]推荐人新用户 1. 注册成为推荐人 2. create_referrer(nft_amount=100)3. 生成推荐码 generate_referral_code()4. 存储推荐人信息 5. 返回 referral_code6. 生成推荐链接https://coinfair.io?ref={code}7. 分享推荐链接 8. 访问推荐链接 9. 验证推荐码 10. referral_code_exists(code)11. 有效 12. 显示推荐人信息 13. 连接钱包并领取 14. claim_nft_by_code(referral_code)15. 验证条件- 未领取- 配额充足- 非自我推荐 16. 铸造不可转移 NFT17. 创建推荐关系记录 18. 递增 claimed_amount19. 返回 NFT20. 显示 NFT 和关系链 21. 注册成为推荐人 22. create_referrer23. 获得新推荐码推荐人新用户
6. 数据流架构
6.1 实时数据流
客户端
分发层
存储层
数据处理层
消息队列
事件收集层
链上数据源
实时推送
Swap 事件
流动性事件
订单事件
推荐事件
事件监听器
RabbitMQ
Kafka
价格处理器
交易量处理器
订单处理器
Redis
实时缓存
InfluxDB
时序数据
PostgreSQL
关系数据
WebSocket Server
前端应用
6.2 缓存策略
缓存层次结构
缓存未命中
缓存未命中
缓存未命中
写回
写回
L1: 浏览器缓存
React Query
L2: CDN 缓存
静态资源
L3: Redis 缓存
热数据
L4: 数据库
持久化数据
用户请求
缓存键设计:
// 价格缓存 (TTL: 5秒)
const PRICE_KEY = (pool: string) => `price:${pool}`;
// 流动性缓存 (TTL: 30秒)
const LIQUIDITY_KEY = (pool: string) => `liquidity:${pool}`;
// 用户订单缓存 (TTL: 10秒)
const USER_ORDERS_KEY = (user: string) => `orders:user:${user}`;
// 订单簿深度缓存 (TTL: 5秒)
const ORDERBOOK_DEPTH_KEY = (pool: string) => `depth:${pool}`;
// 推荐关系缓存 (TTL: 300秒)
const REFERRAL_CHAIN_KEY = (user: string) => `ref:chain:${user}`;6.3 数据同步机制
前端 PostgreSQLRedis 消息队列事件监听器 Aptos IndexerAptos 链前端 PostgreSQLRedis 消息队列事件监听器 Aptos IndexerAptos 链 loop[每 1 秒]par[并行处理]alt[WebSocket 连接存在][轮询模式]轮询新事件 GET /events 返回事件列表解析事件发布事件消息更新缓存(价格、TVL 等)持久化事件(订单、交易等)推送实时更新定期查询返回最新数据
7. 接口文档
7.1 智能合约接口
CLMM Router 接口
module coinfair::clmm_router {
/// 创建交易池
public entry fun create_pool<X, Y>(
sender: &signer,
tick_spacing: u64,
initialize_price: u128
);
/// 交换代币
public entry fun swap<X, Y>(
account: &signer,
pool: address,
a2b: bool,
by_amount_in: bool,
amount: u64,
amount_limit: u64,
fifrt_price_limit: u128,
referrer: address // 推荐人地址
);
/// 添加流动性 (固定流动性数量)
public entry fun add_liquidity<X, Y>(
account: &signer,
pool: address,
delta_liquidity: u128,
tick_lower_index: I64,
tick_upper_index: I64
);
/// 添加流动性 (固定代币数量)
public entry fun add_liquidity_fix_token<X, Y>(
account: &signer,
pool: address,
amount_a: u64,
amount_b: u64,
tick_lower_index: I64,
tick_upper_index: I64,
fix_amount_a: bool
);
/// 移除流动性
public entry fun remove_liquidity<X, Y>(
account: &signer,
pool: address,
position_id: u64,
delta_liquidity: u128
);
/// 收取手续费
public entry fun collect_fee<X, Y>(
account: &signer,
pool: address,
position_id: u64
);
}OrderBook 接口
module coinfair_orderbook::multi_order_book {
/// 创建限价订单
public entry fun create_limit_order_for_pool_with_tif(
account: &signer,
pool: address,
amount_x: u64,
tick_abs: u64,
is_negative: bool,
order_type: u8, // 0=BUY, 1=SELL
expiration_time: u64,
tif: u8 // 0=POST_ONLY, 1=IOC, 2=FOK, 3=GTC_EXEC
);
/// 取消订单
public entry fun cancel_order(
account: &signer,
pool: address,
order_id: u128
);
/// 批量取消订单
public entry fun cancel_batch_orders(
account: &signer,
pools: vector<address>,
order_ids: vector<u128>
);
/// 查询用户订单
#[view]
public fun get_user_orders(
order_book_address: address,
user: address
): vector<LimitOrder>;
/// 查询最佳买卖价
#[view]
public fun get_best_prices(
order_book_address: address
): (Option<I64>, Option<I64>);
}Referral 接口
module referral::referral {
/// 创建推荐人
public entry fun create_referrer(
referrer: &signer,
nft_amount: u64
);
/// 通过地址领取 NFT
public entry fun claim_nft_by_address(
user: &signer,
referrer_address: address
);
/// 通过推荐码领取 NFT
public entry fun claim_nft_by_code(
user: &signer,
referral_code: u64
);
/// 增加 NFT 数量
public entry fun increase_nft_amount(
referrer: &signer,
additional_amount: u64
);
/// 查询推荐人信息
#[view]
public fun get_referrer_info(
referrer_address: address
): ReferrerInfo;
/// 查询推荐关系
#[view]
public fun get_referral_relation(
user_address: address
): ReferralRelation;
/// 查询推荐链
#[view]
public fun get_user_referral_chain(
user_address: address,
levels: u64
): vector<address>;
}7.2 REST API 接口
价格 API
// GET /api/v1/pools/:poolAddress/price
interface PriceResponse {
poolAddress: string;
tokenA: string;
tokenB: string;
currentPrice: string; // Decimal string
tick: number;
timestamp: number;
}
// GET /api/v1/pools/:poolAddress/ohlcv?interval=1h&from=timestamp&to=timestamp
interface OHLCVResponse {
data: Array<{
timestamp: number;
open: string;
high: string;
low: string;
close: string;
volume: string;
}>;
}
// GET /api/v1/pools/:poolAddress/quote?fromToken=X&toToken=Y&amount=1000&isExactIn=true
interface QuoteResponse {
inputAmount: string;
outputAmount: string;
priceImpact: string; // 百分比
fee: string;
route: string[];
}订单 API
// GET /api/v1/orders/user/:address
interface UserOrdersResponse {
orders: Array<{
orderId: string;
pool: string;
orderType: 'BUY' | 'SELL';
amountX: string;
tick: number;
price: string;
filledAmount: string;
status: 'ACTIVE' | 'PARTIALLY_FILLED' | 'FILLED' | 'CANCELLED' | 'EXPIRED';
createdAt: number;
expirationTime?: number;
}>;
total: number;
}
// GET /api/v1/orderbook/:poolAddress/depth
interface OrderBookDepthResponse {
bids: Array<{
price: string;
amount: string;
total: string; // 累计
orderCount: number;
}>;
asks: Array<{
price: string;
amount: string;
total: string;
orderCount: number;
}>;
}推荐 API
// GET /api/v1/referral/info/:address
interface ReferralInfoResponse {
referrerAddress: string;
referralCode: string;
totalNftAmount: number;
claimedAmount: number;
referralLink: string;
createdAt: number;
}
// GET /api/v1/referral/chain/:address?levels=3
interface ReferralChainResponse {
user: string;
chain: Array<{
address: string;
referralCode: string;
level: number;
}>;
directReferrals: number;
totalReferrals: number;
}7.3 WebSocket 接口
// 连接
const ws = new WebSocket('wss://ws.coinfair.io');
// 订阅价格更新
ws.send(JSON.stringify({
type: 'subscribe',
channel: 'price',
poolAddress: '0x...'
}));
// 接收消息
interface PriceUpdateMessage {
type: 'price_update';
data: {
poolAddress: string;
price: string;
tick: number;
timestamp: number;
};
}
// 订阅订单更新
ws.send(JSON.stringify({
type: 'subscribe',
channel: 'orders',
userAddress: '0x...'
}));
interface OrderUpdateMessage {
type: 'order_update';
data: {
orderId: string;
status: string;
filledAmount: string;
timestamp: number;
};
}