跳转到主要内容
Li.FI 意图目前在测试网上!下一次部署将是主网。
订单服务器是一个有用的中介,允许用户提交意图(订单)并将这些意图广播给求解器。它充当中心枢纽:
  1. 从各种来源收集用户意图。
  2. 实时向连接的求解器广播这些意图。
  3. 跟踪所有交易的链上状态。
虽然订单服务器由于其内置的安全辅助功能而是推荐的集成界面,但重要的是要注意——对于链上订单——订单服务器完全是可选的。但是,并非所有意图都在链上发出,lintent.org 不在链上发出意图。在链上发出的意图需要充实并非常彻底地验证。

订单订阅

有 2 种方法可以收集订单。通过 websocket 订阅推送订单或通过 GET 端点。建议通过 websocket 订阅推送订单。这两种方法都可以在 lintent.org 演示实现中找到。 如果您过于激进地使用 GET 端点,您可能会被限流或暂时超时。您可以在 https://order-dev.li.fi/docs 上找到有关 api 接口的 swagger 文档。

订单服务器事件

连接到订单服务器时,订单服务器将持续发送 ping 消息,客户端应使用 pong 响应。这用于断开行为不当的客户端并用于调试目的。您可以在此处找到示例实现 对于订单收集,重要的事件是 user:vm-order-submit。数据将以类似于提交的方式返回。

订单验证

LI.FI 意图允许高度可定制的订单。因此,您应该添加进一步的验证以确保您支持转发给您的订单。正确验证订单很重要。 下面,术语白名单是指由信任和验证的。当代币_必须_被白名单时,意味着信任该代币。如果验证层被白名单,则意味着信任验证层等。白名单并不意味着由中心实体许可;它意味着由信任。 以下是求解器必须实现的验证的详尽列表尝试。虽然此列表可能看起来过多,但您可能已经为其中大多数实现了检查。

一般验证

  1. fillDeadline:确保您有足够的时间填充订单:
    • 在目标链上填充的时间,包括潜在的源链最终性。
  2. expiry:确保您有足够的时间填充、中继和索取订单:
    • 在目标链上填充的时间,包括潜在的源链最终性。
    • 将消息验证证明发送到输入链的时间。
    • 在验证交付后索取订单的时间。
  3. 验证层:确保您支持向验证层提交证明(如果不是自动的,还包括中继)。此外,inputOracleoutput.oracle 必须属于同一验证层。
  4. 确保您已将每个 input 代币列入白名单。如果一个输入代币是恶意的,订单可能无法索取。此外,对于像 USDC 这样的可列入黑名单的代币,请确保您不在黑名单上。
    • 如果订单的输入或输出为 0 的代币您尚未列入白名单,则订单可能无法填充。填充包含不熟悉代币的订单时要小心。
  5. 对于每个输出:
    1. output.chainId 被列入白名单。
    2. output.oracleinputOracle 关于 originChainIdoutput.chainId 正确配置。链上配置是不可变的,因此可以为每个链对执行一次。
    3. output.settler 被列入白名单。
    4. output.context 可解码,并且订单类型受支持并与 output.settler 兼容。
    5. output.token 被列入白名单。此外,对于像 USDC 这样的可列入黑名单的代币,请确保您和接收者都不在黑名单上。
      • 如果订单的输入或输出为 0 的代币您尚未列入白名单,则订单可能无法填充。填充包含不熟悉代币的订单时要小心。
    6. 您有足够的代币用于 output.amount
    7. 如果输出有 calldata,请确保您可以原子地执行它和其他输出。对于不同链上的输出,如果有 calldata,您可能必须将接收者列入白名单。
      • 在 OP 链上,CrossL2Inbox 需要在整个调用树中列入黑名单。如果另一个链上存在类似的合约,它们也需要列入黑名单。
    8. call.lengthcontext.length 都不超过 65’535 字节。
    9. 根据订单类型验证上下文。特别是对于比特币,请确保编码的乘数相对于比特币值。
  6. 如果订单有多个输出,请确保您可以填充所有输出,并且第一个输出设置为您的求解器标识符。如果所有输出都在同一链上,可以使用 fillBatch 作为保护措施。
  7. 如果 InputSettler 有任何费用,请检查即将发生的费用变更。
代币输入以 uint256 提供。这是资源锁和跨链地址的标准格式。对于 EVM,前 12 个字节表示潜在的锁标签,地址是最后 20 个字节。

托管验证

  1. 确保没有输入代币是转账费用。
  2. 确保每个 inputs 代币的高 12 位字节中没有设置位。
  3. 确保订单已通过 event Openfunction orderStatus 打开,或者您在填充订单之前通过 function openFor 打开订单。

Compact 验证

  1. 确保每个 input 代币使用相同的 AllocatorId。如果 lockId 不同,应检查每个 lockId 的锁到期时间。或者,检查所有 lockId 是否相等。
  2. 确保资源锁的潜在 reset period 延长到 expiry 之后,并且没有活动的提款。
  3. 确保 allocatorID 被列入白名单。分配者可以阻止索赔处理(通过撤回签名或重用 nonce)。
    • allocatorID 是 inputslock tag 的一部分(前 12 个字节)。
    • 可选地,确保用户有足够的代币。不过,这应该已经由分配者验证了。
  4. 确保用户提供 ECDSA 签名他们已注册白名单使者您在填充索赔之前在链上注册索赔。
    • 注意:如果采取这些操作中的任何一项,则可以假定签名是可信的。
    • 使者签名无法在链上注册。必须信任使者不会撤回签名。
  5. 验证 allocatorData。您可能必须进行链上调用。
  6. 验证分配者 nonce 之前没有被任何用户花费。订单 nonce 不是用户 nonce。

签名验证

StandardOrder 将用于接口输入链上的所有函数。此外,一旦使用签名充实,它允许人们验证订单的有效性。 StandardOrder 结构将被签名并存储为适当的锁/索赔结构中的见证。对于 TheCompact,这是:
struct BatchCompact {
    address arbiter; // 关联的结算合约
    address sponsor; // StandardOrder.user
    uint256 nonce; // StandardOrder.nonce
    uint256 expires; // StandardOrder.expires
    uint256[2][] idsAndAmounts; // StandardOrder.inputs
    Mandate mandate;
}

struct Mandate {
    uint32 fillDeadline; // StandardOrder.fillDeadline
    address inputOracle; // StandardOrder.inputOracle
    OutputDescription[] outputs; // StandardOrder.outputs
}
要验证订单,请确保赞助商和分配者签名对此 EIP-712 签名结构有效。

链上订单广播

当意图在链上注册时,它们可以通过 IntentRegistered 事件在输入结算合约上广播:
event IntentRegistered(bytes32 indexed orderId, StandardOrder order);
收集无需许可的订单时,请确保它们经过适当验证和共同签名。订单服务器有助于验证,但在链上,可能会发出潜在的欺诈性消息。
I