代币列表Doc设计
{
"_id": "{chainId}_{address}",
"chainId": "{chainId}",
"address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"name": "{name}",
"symbol": "{symbol}",
"decimals": {dicimals},
"logo": "https://...",
"id": "xxxx", // the token id
"supportedProviders": [支持的provider: "openocean", "1inch", ...],
"lastSynced": number, // ms timestamp
}
从每一个渠道商,获取到的token list, 为每一个token在mongodb中, 建立一个对应的文档, 以 openocean-base-USDC
为例:
{
"_id": "8543_0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
"chainId": "8453",
"address": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
"name": "USDC",
"symbol": "USDC",
"decimals": 6,
"logo": "<https://s3.openocean.finance/token_logos/logos/1697507306331_35406629884386076.png>",
"supportedProviders": ["openocean"],
"lastSynced": 1753583808000
}
如果后续我们接入 其他 渠道商,比如 1inch
, 如果我们查询到支持 base-USDC
, 那么就会在 supportedProviders
保存。这样不需要为每一个渠道商建立一个 doc
const tokenSchema = new mongoose.Schema({
// 我们不再自定义 _id,而是创建一个唯一复合索引来保证唯一性
// 这样做更符合 Mongoose 的习惯
chainId: { type: String, required: true },
address: { type: String, required: true },
name: { type: String },
symbol: { type: String },
decimals: { type: Number },
logoURI: { type: String },
supportedProviders: [{ type: String }], // 字符串数组
lastSynced: { type: Date }
});
// chainId+address 构建唯一性的索引
tokenSchema.index({ chainId: 1, address: 1 }, { unique: true });
//在name和symbol 上添加text的索引, 方便进行搜索, 不实用regex是为了提高搜索性能。
tokenSchema.index({ name: 'text', symbol: 'text' });
const Token = mongoose.model('Token', tokenSchema);
构建查询语句, 要求:
这里的code为伪代码, 不代表最终代码
Token.find(
{
chainId: {chainId},
$text: { $search: {tokenName} }
},
{
skip: (page-1) * pageSize,
limit: pageSize
}
).exec()
Token.find(
{
chainId: {chainId},
address: {fromTokenAddress}
},
'supportedProviders'
)
Token.find(
{
chainId: {chainId},
address: [outTokenAddress},
},
'supportedProviders'
)