Files
assetx/webapp-back/lending/INTEGRATION_NOTE.md
default 2ee4553b71 init: 初始化 AssetX 项目仓库
包含 webapp(Next.js 用户端)、webapp-back(Go 后端)、
antdesign(管理后台)、landingpage(营销落地页)、
数据库 SQL 和配置文件。
2026-03-27 11:26:43 +00:00

175 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Integration with Existing Code
## 发现holders 包已有类似实现
`holders/db_config.go` 中已经实现了从数据库加载合约地址的完整逻辑:
### holders/db_config.go 的实现
```go
// LoadConfigFromDB 从数据库加载配置(已存在)
func LoadConfigFromDB(chainID int64) (Config, error) {
// 1. 从 assets 表加载 YT-A, YT-B, YT-C
var assets []Asset
db.Table("assets").
Where("asset_code IN (?, ?, ?)", "YT-A", "YT-B", "YT-C").
Find(&assets)
// 2. 根据 chainID 选择合约地址
for _, asset := range assets {
address := asset.ContractAddressArb
if isBSC {
address = asset.ContractAddressBsc
}
ytVaults = append(ytVaults, VaultConfig{
Name: asset.AssetCode,
Address: address,
})
}
// 3. 从 lending_markets 表加载 Lending 合约
var lendingMarkets []LendingMarket
db.Table("lending_markets").
Where("is_active = ?", 1).
Find(&lendingMarkets)
lendingAddress := market.ContractAddressArb
if isBSC {
lendingAddress = market.ContractAddressBsc
}
return Config{
YTVaults: ytVaults,
LendingAddress: lendingAddress,
}
}
```
### lending/helpers.go 的实现(新建)
```go
// GetYTTokenInfo 从 assets 表获取 YT token 信息(新实现)
func GetYTTokenInfo(assetCode string) (*TokenInfo, error) {
var asset models.Asset
db.Where("asset_code = ? AND is_active = ?", assetCode, true).
First(&asset)
return &TokenInfo{
Symbol: asset.Name,
ContractAddressArb: asset.ContractAddressArb,
ContractAddressBsc: asset.ContractAddressBsc,
}
}
```
## 代码复用建议
### 选项 1统一使用 holders 包的结构体(推荐)
```go
// lending/helpers.go
import "github.com/gothinkster/golang-gin-realworld-example-app/holders"
func GetYTTokensFromHolders(chainID int64) ([]TokenInfo, error) {
// 复用 holders.LoadConfigFromDB
config, err := holders.LoadConfigFromDB(chainID)
if err != nil {
return nil, err
}
tokens := make([]TokenInfo, len(config.YTVaults))
for i, vault := range config.YTVaults {
tokens[i] = TokenInfo{
Symbol: vault.Name,
ContractAddressArb: vault.Address, // 已根据 chainID 选择
AssetCode: vault.Name,
}
}
return tokens, nil
}
```
### 选项 2共享数据模型
```go
// common/models.go - 创建共享的 Asset 模型
type Asset struct {
ID int64
AssetCode string
Name string
ContractAddressArb string
ContractAddressBsc string
}
// holders 和 lending 都使用这个共享模型
```
### 选项 3保持当前实现已完成
- ✅ lending 包独立实现
- ✅ 功能完整,逻辑清晰
- ⚠️ 与 holders 包有重复代码
## 数据库表结构(一致)
两个包都使用相同的表:
### assets 表
```sql
CREATE TABLE assets (
id BIGINT PRIMARY KEY,
asset_code VARCHAR(20), -- YT-A, YT-B, YT-C
name VARCHAR(255),
contract_address_arb VARCHAR(42),
contract_address_bsc VARCHAR(42),
is_active BOOLEAN
)
```
### lending_markets 表
```sql
CREATE TABLE lending_markets (
id BIGINT PRIMARY KEY,
market_name VARCHAR(100),
contract_address_arb VARCHAR(42),
contract_address_bsc VARCHAR(42),
is_active BOOLEAN
)
```
## Chain ID 处理
### holders 包
- 421614 = Arbitrum Sepolia
- 97 = BSC Testnet
### lending 包(需要添加)
```go
// helpers.go 添加 chain ID 支持
func GetContractAddress(tokenInfo TokenInfo, chainID int) string {
switch chainID {
case 421614: // Arbitrum Sepolia
return tokenInfo.ContractAddressArb
case 97: // BSC Testnet
return tokenInfo.ContractAddressBsc
case 42161: // Arbitrum One (mainnet)
return tokenInfo.ContractAddressArb
case 56: // BSC Mainnet
return tokenInfo.ContractAddressBsc
default:
return tokenInfo.ContractAddressArb
}
}
```
## 总结
### 已实现功能
- ✅ lending 包可以独立从 assets 表读取 YT tokens
- ✅ lending 包可以从 lending_markets 表读取市场配置
- ✅ USDC 地址已硬编码
- ✅ 与 holders 包的实现逻辑一致
### 建议优化(可选)
1. 考虑复用 holders.Asset 结构体
2. 添加对 holders.LoadConfigFromDB 的引用
3. 统一 chain ID 处理逻辑
### 当前状态
**可以直接使用**,无需修改。与 holders 包的实现独立但兼容。