最近我开发了solana上的去中心化交易所,meteora的dlmm池子的交易协议对接,用的是golang语言,下面我详细讲解一下。期初我们想通过程序对对接meteoradlmm池子,但是找遍github,发现只有typescript版本的,跟我们的技术栈不一样,以后不好维护,我们的技术栈是
最近我开发了solana上的去中心化交易所,meteora的dlmm池子的交易协议对接,用的是golang语言,下面我详细讲解一下。
起初我们想通过程序对对接meteora dlmm池子,但是找遍github,发现只有typescript版本的,跟我们的技术栈不一样,以后不好维护,我们的技术栈是golang,于是我开始着手翻译typescript SDK。
目前我们实现了如下功能:
整个翻译过程很痛苦,因为dlmm的计算比传统的amm计算复杂太多,期初我是安排技术小哥开发,技术小哥研究了一个月,说不好搞,需要精通ts语言和golang语言,才能顺利翻译。
后来我自己通过ts版本sdk,翻译成golang,并于近期翻译完成,通过大量测试,发现和官方sdk计算的分毫不差,和meteora前端网页显示的也是分毫不差,和jupiter聚合器显示的也是分毫不差,最终正确完成。
整个项目结构如下:
其中:
下面是main.go测试部分:
package main
import (
"context"
"fmt"
"github.com/gagliardetto/solana-go"
"github.com/shopspring/decimal"
"tradebot/pkg/meteora_dlmm"
"tradebot/pkg/meteora_dlmm/constant"
)
func main() {
// rpc节点
httpsRpc := ""
wssRpc := ""
// DLMM program账号
DLMMProgramID := constant.DLMMProgramID
// 池子账号
poolAccount := solana.MustPublicKeyFromBase58("G7ixPyiyNeggVf1VanSetFMNbVuVCPtimJmd9axfQqng")
// 私钥
privateKey := solana.MustPrivateKeyFromBase58("")
// 交易from地址
toToken := "27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4"
// 交易to地址
fromToken := "So11111111111111111111111111111111111111112"
// 交易数量,已包含decimals(如果出现输出数量为0,请提高inAmount)
inAmount := decimal.NewFromInt(100000)
// 允许的滑点,这里的30代表0.003,表示0.3%,30个基点
allowedSlippage := decimal.NewFromInt(30)
// 优先费
yxf := uint64(1)
// jito小费
jitoAmount := uint64(0)
// jito小费账号,当小费不为空的情况下,该地址不能为空,请到jito官方文档查看小费地址列表,随机找个小费地址
jitoAccount := solana.PublicKey{}
dlmm := meteora_dlmm.NewDLMM(poolAccount, DLMMProgramID, privateKey, httpsRpc, wssRpc)
// 初始化池子,获取池子详细数据
dlmm.GetPoolInfo()
var swapForY bool
// 计算兑换方向
lbPair := dlmm.GetLbPair()
if fromToken == lbPair.TokenXMint.String() {
swapForY = true
}
binArrayAccount, err := dlmm.GetBinArrayForSwap(context.Background(), swapForY, 4)
if err != nil {
panic(err)
}
// remaining account,用于添加到交易的账号列表中
for _, v := range binArrayAccount {
dlmm.SetRemainingAccount(v.PublicKey)
}
swapQuote, err := dlmm.SwapQuote(inAmount.BigInt(), swapForY, allowedSlippage.BigInt(), binArrayAccount, true)
if err != nil {
panic(err)
}
fmt.Printf("计算结果:inAmount=%d,OutAmount=%d,MinOutAmount=%d\n",
inAmount.BigInt(), swapQuote.OutAmount, swapQuote.MinOutAmount)
// 执行兑换
signature, err := dlmm.Swap(inAmount.BigInt().Uint64(), swapQuote.MinOutAmount.Uint64(),
fromToken, toToken, yxf, jitoAmount, jitoAccount)
if err != nil {
panic(err)
}
fmt.Println("交易成功,signature:", signature)
}
实际的计算极为复杂,例如:
目前这套代码用于我们的交易机器人,用来对接meteora dlmm池子。 其实这个和raydium clmm池子类似,clmm池子翻译也很复杂,期初我们用的是ts版本的sdk做的,但是集成到项目中,会遇到一些问题,由于我们的技术栈限制,无法便捷修改代码,导致很被动。
感兴趣的朋友可以一起讨论下,有任何问题也可以进行评论,我看到都会一一解答,对于solana感兴趣的朋友,也可以一起讨论。
接下来继续完善本文档涉及到的知识点。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!