1英寸限制顺序协议 v4 SDK
安装
npm install '@1inch/limit-order-sdk'
文档
用法实例
顺序创建
import {LimitOrder, MakerTraits, Address, Sdk, randBigInt, FetchProviderConnector} from "@1inch/limit-order-sdk"
import {UINT_40_MAX} from "@1inch/byte-utils"
import {Wallet} from 'ethers'
// it is a well-known test private key, do not use it in production
const privKey =
'0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'
const authKey = '...'
const maker = new Wallet(privKey)
const expiresIn = 120n // 2m
const expiration = BigInt(Math.floor(Date.now() / 1000)) + expiresIn
// see MakerTraits.ts
const makerTraits = MakerTraits.default()
.withExpiration(expiration)
.withNonce(randBigInt(UINT_40_MAX))
const sdk = new Sdk({ authKey, networkId: 1, httpConnector: new FetchProviderConnector() })
const order = await sdk.createOrder({
makerAsset: new Address('0xdac17f958d2ee523a2206206994597c13d831ec7'),
takerAsset: new Address('0x111111111117dc0aa78b770fa6a738034120c302'),
makingAmount: 100_000000n, // 100 USDT
takingAmount: 10_00000000000000000n, // 10 1INCH
maker: new Address(maker.address),
// salt? : bigint
// receiver? : Address
}, makerTraits)
const typedData = order.getTypedData()
const signature = await maker.signTypedData(
typedData.domain,
{Order: typedData.types.Order},
typedData.message
)
await sdk.submitOrder(order, signature)
集成商费(非港口伙伴)
当限制顺序 API 返回集成器收费字段时 /fee-info, (中文(简体) ), Sdk.createOrder 自动 :
- 嵌入层
IntegratorFee从integratorFeeBps, (中文(简体) ),integratorFeeReceiver,以及integratorFeeSharePercent - 设置盐道代码
source(仅在orderInfo.salt删除)
integratorFeeSharePercent 全数百分比( API 拒绝分数) rev-share) (中文(简体) ). 如果设置了收费bps,但缺少共享,SDK将响应视为不正确,并使用零整数收费. 过 extra.integratorFee 以覆盖。 没有付费配置的集成商不受影响——订单保持与前作一样的零集成商费.
源/ 音轨代码 : aPI 返回赤色十六进制( 例如 ). aba10994(没有) 0x- 预设. setSource {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}别..0x 值输入盐轨位元——不添加“固定”API值 0x,否则归属会破裂。 如果你通过一个明确 orderInfo.salt时,API source 未应用; 您的盐道位胜出 .
Bps.fromPercent 编号 : fromSharePercent数字 : 有2个以上小数位数的值被缩短为1 bps精度(例如:. 0.125 ——12个bps),而不是投掷. 负值被否决.
含有部分填充功能的订单已禁用(填充或杀活)
默认情况下,限制令可以被填入多部分. 要创建一个必须完全在单项交易中填写的命令, 则禁用部分填充 :
import {MakerTraits, randBigInt} from "@1inch/limit-order-sdk"
import {UINT_40_MAX} from "@1inch/byte-utils"
const expiration = BigInt(Math.floor(Date.now() / 1000)) + 3600n // 1h
const makerTraits = MakerTraits.default()
.withExpiration(expiration)
.withNonce(randBigInt(UINT_40_MAX)) // required: unique nonce per order
.disablePartialFills()
.disableMultipleFills()
// then create, sign and submit the order as usual - see "Order creation" above
规则:
- 给每个这样的命令 自己的随机非曲直通过
withNonce- 绝对不能重复使用非曲直. - 不要打电话
withEpoch根据这些命令提交拒绝的填充或杀害命令. - 如果命令不能立即全部填写,则要保持开放,直至其填充,到期或被取消. 它永远不会被部分填满.
命令书 API 返回 partialFillsAllowed: false 为这些命令.
取消订单
取消在链上,使用制造器特性和顺序的散列(提交后保留两者):
import {getLimitOrderContract} from "@1inch/limit-order-sdk"
import {Contract, JsonRpcProvider, Wallet} from "ethers"
const chainId = 1 // same chainId as create/submit
const abi = [
'function cancelOrder(uint256 makerTraits, bytes32 orderHash)',
'function cancelOrders(uint256[] makerTraits, bytes32[] orderHashes)'
]
const signer = new Wallet(privKey, new JsonRpcProvider(rpcUrl))
const lop = new Contract(getLimitOrderContract(chainId), abi, signer)
// keep after submit
const traits = order.build().makerTraits // string
const orderHash = order.getOrderHash(chainId)
// single order
await (await lop.cancelOrder(BigInt(traits), orderHash)).wait()
// several orders in one transaction (traits[i] must belong to hashes[i])
await (await lop.cancelOrders(
openOrders.map((o) => BigInt(o.build().makerTraits)),
openOrders.map((o) => o.getOrderHash(chainId))
)).wait()
注意: 按日期取消所有订单( Q)increaseEpoch如上所示,不影响有部分填充功能的订单----用散列方式取消.
报告问题 顺序创建
RfqOrder 是一个轻而易举的气体高效版本 LimitedOrder,但它不支持多个填充和扩展
主要被市场制造者使用
import {RfqOrder, Address, randBigInt} from "@1inch/limit-order-sdk"
import {UINT_40_MAX} from "@1inch/byte-utils"
import {Wallet} from 'ethers'
// it is a well-known test private key, do not use it in production
const privKey =
'0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'
const maker = new Wallet(privKey)
const expiresIn = 120n // 2m
const expiration = BigInt(Math.floor(Date.now() / 1000)) + expiresIn
const order = new RfqOrder({
makerAsset: new Address('0xdac17f958d2ee523a2206206994597c13d831ec7'),
takerAsset: new Address('0x111111111117dc0aa78b770fa6a738034120c302'),
makingAmount: 100_000000n, // 100 USDT
takingAmount: 10_00000000000000000n, // 10 1INCH
maker: new Address(maker.address)
}, {
allowedSender: new Address('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'),
expiration,
nonce: randBigInt(UINT_40_MAX),
})
const typedData = order.getTypedData()
const signature = await maker.signTypedData(
typedData.domain,
{Order: typedData.types.Order},
typedData.message
)
顺序填充
要执行限制顺序,需要使用 LimitOrderContract 课。 根据订单是否具有扩展/互通,以及制造者是EOA还是智能合同,有不同的方法.
import {LimitOrderContract, TakerTraits, LimitOrder} from '@1inch/limit-order-sdk'
// Assume you already have a FusionOrder in `order` variable
const order = ... // your LimitOrder instance
const signature = '0x...' // order signature
const amount = 100_000000n // amount to fill (in taker or maker asset units, based on set `AmountMode`)
// Create taker traits
const takerTraits = TakerTraits.default()
// Optional: Configure taker preferences
// .setAmountMode(AmountMode.TakerAmount) // or MakerAmount
// .enableNativeUnwrap() // for WETH -> ETH conversion
// .setAmountThreshold(minAmount) // minimum/maximum acceptable amount (based on set `AmountMode`)
// Build calldata for different scenarios:
// 1. Simple order fill (no extensions, no interactions)
const simpleCalldata = LimitOrderContract.getFillOrderCalldata(
order.build(), // converts to LimitOrderV4Struct
signature,
takerTraits,
amount
)
// 2. Fill contract order (when maker is a smart contract)
const contractCalldata = LimitOrderContract.getFillContractOrderCalldata(
order.build(),
signature,
takerTraits,
amount
)
// 3. Order with extensions or taker interactions
const extension = '0x...' // extension calldata
const interaction = '0x...' // taker interaction calldata
const takerTraitsWithArgs = TakerTraits.default()
.setExtension(extension)
.setInteraction(interaction)
// .setReceiver(receiverAddress) // optional: custom receiver
const argsCalldata = LimitOrderContract.getFillOrderArgsCalldata(
order.build(),
signature,
takerTraitsWithArgs,
amount
)
// 4. Contract order with extensions/interactions
const contractArgsCalldata = LimitOrderContract.getFillContractOrderArgsCalldata(
order.build(),
signature,
takerTraitsWithArgs,
amount
)
该调用数据应发送到1英寸限制令协议合同地址,可在 文档
带走特质配置
TakerTraits 允许您配置各种执行参数 :
import {TakerTraits, AmountMode, Address} from '@1inch/limit-order-sdk'
const takerTraits = TakerTraits.default()
// Set amount calculation mode
.setAmountMode(AmountMode.MakerAmount) // fill by maker amount
// or
// .setAmountMode(AmountMode.TakerAmount) // fill by taker amount (default)
// Enable WETH unwrapping to ETH
.enableNativeUnwrap()
// Skip order permit (if not needed)
.skipOrderPermit()
// Enable Permit2
.enablePermit2()
// Set amount threshold
.setAmountThreshold(1000000n)
// Set custom receiver for maker assets
.setReceiver(new Address('0x...'))
// Add extension calldata (for order extensions)
.setExtension('0x...')
// Add taker interaction calldata
.setInteraction('0x...')
选择正确的填充方法
| 方法 | 使用时间 |
|---|---|
getFillOrderCalldata | EOA 生成器,无扩展/交互 |
getFillContractOrderCalldata | 智能合同订立者,不延期/互动 |
getFillOrderArgsCalldata | EOA 制作器,带有扩展/交互 |
getFillContractOrderArgsCalldata | 具有扩展/互动功能的智能合同制定者 |
API 密码
import {Api, FetchProviderConnector, LimitOrder, HttpProviderConnector} from '@1inch/limit-order-sdk'
const networkId = 1 // ethereum
const api = new Api({
networkId,
authKey: 'key', // get it at https://portal.1inch.dev/
httpConnector: new FetchProviderConnector() // or use any connector which implements `HttpProviderConnector`
})
// submit order
const order = ... /// see `Order creation` section
const signature = '0x'
await api.submitOrder(order, signature)
// get order by hash
const orderHash = order.getOrderHash(networkId)
const orderInfo = await api.getOrderByHash(orderHash)
// get orders by maker with cursor pagination
import { CursorPager } from '@1inch/limit-order-sdk'
// First page - no cursor needed
const firstPager = new CursorPager({ limit: 10 })
const response = await api.getOrdersByMaker(order.maker, {
pager: firstPager,
statuses: [1] // only valid orders
})
const orders = response.items
const { hasMore, nextCursor, count } = response.meta
// Get next page if available
if (hasMore && nextCursor) {
const nextPager = new CursorPager({ limit: 10, cursor: nextCursor })
const nextPage = await api.getOrdersByMaker(order.maker, {
pager: nextPager,
statuses: [1]
})
}
// Or use without explicit pager (defaults to limit: 100, no cursor)
const makerOrders = await api.getOrdersByMaker(order.maker, {
statuses: [1]
})
// get all orders from orderbook with pagination
const allOrdersPager = new CursorPager({ limit: 20 })
const allOrdersResponse = await api.getAllOrders({
pager: allOrdersPager,
statuses: [1, 2] // valid and temporarily invalid orders
})
// pagination works the same way
if (allOrdersResponse.meta.hasMore && allOrdersResponse.meta.nextCursor) {
const nextAllOrders = await api.getAllOrders({
pager: new CursorPager({
limit: 20,
cursor: allOrdersResponse.meta.nextCursor
})
})
}
与 axios 作为 http 提供者
axios 软件包应安装
import {Api, LimitOrder} from "@1inch/limit-order-sdk"
import {AxiosProviderConnector} from '@1inch/limit-order-sdk/axios'
const api = new Api({
networkId: 1, // ethereum
authKey: 'key', // get it at https://portal.1inch.dev/
httpConnector: new AxiosProviderConnector()
})
测试
单位测试
安装依赖关系
pnpm install
运行测试
pnpm test
融合测试
综合测试在内 测试 文件夹. 他们用 铸造 分叉节点并在上面执行交易.
安装依赖关系
pnpm install && forge install
运行测试
pnpm test:integration