買賣與詢價對接

本頁面面向前端與量化開發者,說明如何直接對接 Portal 完成:

  • quoteBuy / quoteSell 詢價

  • buy / sell 交易

circle-exclamation

一、先理解資料精度

在對接前,請先統一數值單位:

  • token 數量:固定 18 位(WAD)

  • quoteIn / quoteOut:使用 quote token 原始精度

    • Native:18 位

    • USDT(6) 之類 ERC20:依該 token decimals

  • postPrice:18 位

  • progressBps:基點(10000 = 100%)

二、關鍵方法與簽名

IPortalUser 交易相關方法:

function quoteBuy(address token, uint256 quoteIn)
  external view
  returns (uint256 tokenOut, uint256 feeQuote, uint256 postPrice, uint256 progressBps);

function quoteSell(address token, uint256 tokenIn)
  external view
  returns (uint256 quoteOut, uint256 feeQuote, uint256 postPrice, uint256 progressBps);

function buy(address token, uint256 quoteIn, uint256 minTokenOut) external payable;
function sell(address token, uint256 tokenIn, uint256 minQuoteOut) external;

三、交易前檢查(必要)

建議在送交易前執行:

  1. 讀取 token 狀態(getToken 或 API GET /tokens/:address

  2. 確認 status == TradingInternal

  3. 讀取 quoteToken

  4. 若 quote 為 ERC20:檢查 allowance 與餘額

  5. 先呼叫 quoteBuyquoteSell 計算最小可接受值(滑點保護)

若狀態已是 LaunchedToDEX,應改走 DEX Router,不再走 Portal.buy/sell

四、詢價流程(Quote)

4.1 買入詢價

呼叫:quoteBuy(token, quoteInRaw)

回傳:

  • tokenOut:可買到的 token(18 位)

  • feeQuote:quote 手續費(quote 原始精度)

  • postPrice:成交後價格(18 位)

  • progressBps:成交後進度

4.2 賣出詢價

呼叫:quoteSell(token, tokenInWad)

回傳:

  • quoteOut:預計可得 quote(原始精度)

  • feeQuote:quote 手續費

  • postPrice:成交後價格(18 位)

  • progressBps:成交後進度

五、買入流程(Buy)

5.1 Native quote(例如 BNB)

  • msg.value 必須等於 quoteIn

  • 不可多送或少送,否則會 revert:QuoteMismatch

5.2 ERC20 quote(例如 USDT)

  • msg.value 必須是 0

  • 先對 Portalapprove(quoteIn)

5.3 滑點保護

  • minTokenOut 建議來自 quoteBuy.tokenOut 再扣滑點

  • 若最終輸出低於 minTokenOut,會 revert:SlippageExceeded

5.4 重要行為:買單可能被裁剪

當買單接近發射門檻時,合約會把實際可成交的 quoteIn 裁剪到剩餘容量,超出部分會退款。

  • Native:退回 ETH/BNB

  • ERC20:退回 quote token

因此前端應以鏈上事件與回執為準,不要假設「輸入多少就消耗多少」。

六、賣出流程(Sell)

  1. quoteSell 取得 quoteOut

  2. 依滑點計算 minQuoteOut

  3. approve(tokenIn)Portal

  4. 呼叫 sell(token, tokenIn, minQuoteOut)

若狀態不是 TradingInternal,會 revert:NotTrading

七、常見錯誤與對應處理

  • NotTrading:狀態不允許(未啟用或已發射)

  • QuoteMismatch:Native / ERC20 的 msg.value 使用錯誤

  • NotWhitelisted:白名單模式下地址未授權(買入時)

  • SlippageExceeded:滑點設定過緊

  • InsufficientReserve:池子儲備不足(常見於極端賣壓)

  • InvalidAmount:輸入數量為 0 或無效

八、TypeScript(ethers v6)範例

九、與 API 的搭配方式(建議)

  • 用 API 做展示與查詢:

    • GET /tokens/:address

    • GET /tokens/:address/metrics

    • GET /tokens/:address/trades

    • GET /tokens/:address/candles

  • 用 RPC 直連 Portal 做詢價與交易。

這樣可以避免把寫操作耦合到後端 API,並保持鏈上交易的即時性與可驗證性。

这有帮助吗?