@ arkade-os/ swap
交换客户端 阿卡德图谋说出一条路线 给什么,
买什么, 以及价值的终点—— 客户解决市场
合同,解码目的地,封存秘密,资金 与正确的包,坚持之前
它看,要求,和退款。 无框架类型脚本结束 @arkade-os/sdk: 没有DOM和没有
核心中的节点特有API,因此它运行在节点,浏览器和React Indigen等.
import { createSwapClient, IndexedDbAssetSwapRepository } from "@arkade-os/swap";
const client = createSwapClient({ wallet, repository: new IndexedDbAssetSwapRepository() });
构造是同步而惰性的:没有网络,没有读取钱包,没有打开寄存器. 第一个 呼叫需要一个人做.
市场发现也不需要配置:客户端默认为引用解析器
钱包网络的注册索引( e)REGISTRY_URL[network],导出)。 跟着你自己
登记改为 discovery: { registryUrl },或选择完全退出与
discovery: { registryUrl: null } —— 说 discovery: { snapshot } 对固定市场的解决
列表中不触及网络.
四条路线
每个都是一个 quote → accept 链条. quote 返回绑定、校验的术语和触摸到的任何东西
持久; accept 写记录 然后是资金.
const BTC = btcOn("arkade", "bitcoin"); // arkade:bitcoin/slip44:0 (slip44:1 on test networks)
const USDT = "arkade:bitcoin/asset:…";
// arkade -> lightning: pay an invoice. The amount is the invoice's.
await client.accept(await client.quote({ give: BTC, to: bolt11 }));
// arkade -> arkade: swap one asset for another.
await client.accept(
await client.quote({ give: BTC, take: USDT, amount: 1_000_000n, amountOn: "give" }),
);
// arkade -> onchain: withdraw to a bitcoin address.
await client.accept(
await client.quote({ give: BTC, to: "bc1p…", amount: 100_000n, amountOn: "take" }),
);
// lightning -> arkade: receive. The artifact is the invoice the solver minted.
const r = await client.receive({ via: "lightning", amount: 50_000n });
showToPayer(r.artifact.bolt11);
收受是一条不是分两步走的路线,而不对称是故意的. 内容
艺术品是一张发票,在付款人采取行动之前,其索赔秘密必须持久
receive 仅返回于 accept 坚持不懈。 达到 quote 并阅读发票
该动词将删除
来电者命令.
onchain -> arkade 也是一种接收: client.receive({ via: "onchain", amount }) 返回 a
deposit 文物命名L1HTLC 以资助, 确切地说它的 amount从任何比特币钱包.
客户端声称解决者的Arkade锁站一旦获得资金. 如果解决者从未资助它
一旦HTLC的退款叶子成熟 客户就拿回L1的资金 付登机费
此钱包的地址在引用时被固定, 并用钱包密钥签名 HTLC 来源
带。 退款是同一块的 claimFeeRateSatVb 作为 arkade -> onchain 索赔; 有线
拥有自己的 corridors: { onchain: { refund } }。 。 。 .
一个 arkade -> onchain 退款要求解案人的L1 HTLC本身, 和该要求的矿工费
由HTLC产出产生——所以客户用索赔成本和
收银网 amount ,将估计数折入所报 fee编辑
索赔由客户本身在可索赔的填充物一经填充后,即由客户自己建造和广播,并由索赔人签字
钱包的支付密钥,并按每个网络收费率下限定价。 一个线路UI应该把它提升到
拥堵——要求有一个协商一致的期限——通过
corridors: { onchain: { claimFeeRateSatVb } }; 设置为 null 手动接收索赔要求
(驱动器然后将L1半报告为您的工作而不是阻挡它). 连线你自己的建设者
与 corridors: { onchain: { claim } } 它胜过违约.
一通电话而不是两通
pay, (中文(简体) ), receive 财务报告和审定财务报表 exchange 为: quote 费用上限 accept,则不添加
客户端还没有。 他们加的就是天花板,减去的就是词汇——a
综合付款的产品从不键入文字路线、走廊、市场或引文.
await client.pay(destination, { amount: 50_000n, maxFee: { amount: 500n, asset: BTC } });
await client.receive({ via: "lightning", amount: 50_000n });
await client.exchange({ give: BTC, take: USDT, amount: 1_000_000n, amountOn: "give" });
pay 使用四种目的地表格中的任何一种——螺栓11发票、比特币地址、Arkade
地址,或载有其中之一的BIP21URI——而且各有一个走廊索赔。 一个平地
Arkade地址不是互换地址,不会变成一个:同一资产,同一铁路,速率1. 它返回一个
txid和没有互换id, 这就是为什么 PayResult 有两个手臂.
奥米 amount 当目的地把它钉上时 有金额的发票确实存在;通过一张
旁边是 AmountMismatch 而不是一个沉默的偏好.
资产编号和数额
资产编号是CAIP-19,铁路是CAIP-2命名空间, <rail>:<network>/<namespace>:<ref>。 。 。 .
arkade, (中文(简体) ), bolt11 财务报告和审定财务报表 bitcoin bTC每条铁路有一个ID。 使用
btcOn(rail, network) 财务报告和审定财务报表 arkadeAsset(network, id) 而不是写弦,和
canonicalAssetId 当输入为人时:
const asset = canonicalAssetId("BTC", {
network: "regtest",
assets: [{ ticker: "BTC", id: "arkade:regtest/slip44:1" }],
});
计票器匹配对大小写不敏感,可瞄准钱包网络,拒绝相撞 而不是猜测.
数额为 bigint 客户内部到处都是原子单位 小数字符串存在于两个
边框和表示不同事物的每个:显示小数("0.001")属于UI,原子
小数点("100000"属于记录和RFQ有效载荷. Amount.parse 财务报告和审定财务报表 Amount.format 横
; 客户端自行交叉.
观看、历史和取消
没有必要 start()客户端读取其寄存器一次—— await client.ready 实值
读取——当它找到活工时,或者在第一次工作时,将驱动器举起 accept 当它是
没有. start() 财务报告和审定财务报表 stop() 存在人工控制; stop() 是暂停,不是取消,还有
处置是终端清理,使每个持久的记录和钱包登记都可收回.
const off = client.onUpdate(({ swap, outcome, detail }) => render(swap.id, outcome, detail));
const live = await client.swaps({ outcome: "funded" });
const { outcome } = await client.cancel(swapId);
const result = await client.recover(swapId);
onUpdate 重放它所知道的每一次互换的当前结果,然后串流转换,按键
由此得出的结果 合法反滑一次. Outcome 一个以商人为中心的
两个家庭的词汇: refunded 总是意味着价值又回来了 和接收脚
解析器还原为 lapsed从来没有一个字。 协议的状态字符串已打开 detail
木头.
cancel 输入到资产交换中,因为这是存在取消权利的地方。 走廊互换
分解为引文过期、有时间限制的退款和有错误。 输掉比赛的取消
填报填充,而不是扔出.
错误
16个班,每个都有一个条件名词,都可从根得到; SWAP_ERROR_NAMES 这是
完整列表. SwapRefusal 解决者拒绝——决定,而不是过失——而这是
属于协议层。 客户拒绝的东西和原因
UnsupportedRoute, (中文(简体) ), AmbiguousDestination, (中文(简体) ), AmountMismatch, (中文(简体) ), QuoteExpired, (中文(简体) ), MaxFeeExceeded, (中文(简体) ),
InsufficientFunds, (中文(简体) ), QuoteVerificationFailed, (中文(简体) ), NotCancellable, (中文(简体) ), ClientDisposed, (中文(简体) ),
MissingCorridorDep 还有其他的.
存储后端
| 后端 | 从 | 对于 |
|---|---|---|
InMemoryAssetSwapRepository | @arkade-os/swap | 测试,一发脚本——无一幸存 |
IndexedDbAssetSwapRepository | @arkade-os/swap | 浏览器(或多填充索引DB) |
SQLiteAssetSwapRepository | @arkade-os/swap/repositories/sqlite | 原生反应, 在您的 SQLite 驱动程序上 |
RealmAssetSwapRepository | @arkade-os/swap/repositories/realm | 原生反应, 在您的本地实例上 |
nodeSwapRepository() | @arkade-os/swap/node | 节点 — 文件备份的 SQLite, 为您打开 |
没有隐含的默认,也永远不会出现记忆回落:接受无处可去的互换
写着这是无声的损失 规则存在禁止,所以 accept 拒绝使用
MissingCorridorDep("arkade", "repository") 换句话说 内存是显而易见的
唯一能保存麻黄的办法是放在桌子上.
反动原生子路径都没有增加一个依赖性——它们采用SDK的结构 SQLExecutor 财务报告和审定财务报表
RealmLike 控件,所以您通过您已经打开的数据库. @arkade-os/swap/node 这是
例外和进口的唯一切入点 node: 建筑,这就是为什么它是一个子路径
而不是什么 主条目回到。 它打开平台下的数据库
配置目录 : arkade/swaps/swaps-<network>.sqlite它是一个后端
处理关闭连接, 因为是打开连接的 :
import { nodeSwapRepository } from "@arkade-os/swap/node";
await using swaps = nodeSwapRepository({ network: "bitcoin" }); // or { path } to choose the file
记录全部被存储. SQLite 和 Realm 后端将每张唱片序列化为 JSON 仅限
绘制出可查询的列,所以一个他们不知道生存的字段——这就是
消费者的铸造扩展记录依赖. JSON比IndexedDB的结构克隆更窄,
ưμ㼯a Date 在您添加的字段中返回一个 ISO 字符串, a Set 或者说 Map 空空回来,
(单位:千美元) bigint 扔在储蓄。 套件本身的记录是JSON安全设计,留着你的
也一样.
四个后端都提供 getAssetSwapsPage, (中文(简体) ),
getRfqSwapsPage,以及 getSwapRecordsPage。通过 { limit, after? } 带有
限制 1 - 500, 然后使用每个结果 nextCursor 以下页.
资产互换和互换记录按身份排序. RFQ 交换排序 (updatedAt, rfqId)
并接受 { state?, since? }· ; since 是包含Unix秒。 留着
呼叫时过滤器已固定 。 仓库收藏直接读取使用页;
内部恢复和生命周期路径在行动前会消耗每一页.
SDK 交易历史页面 since 值使用 Unix 毫秒代替.
SQLite RFQ 页面使用行值比较,因此需要 SQLite 3.1.5.0 或
新来的.
恢复导入的钱包
运行核心钱包 restore() (地址、合同、历史), 接下来 创建客户端 :
await wallet.restore();
const client = createSwapClient({ wallet, repository: new IndexedDbAssetSwapRepository() });
await client.ready;
client.ready 重建历史上每笔押金的记录
market: { kind: "restored" }。之前创建的客户端 restore() 仅完成重建
这段历史一直持续到它的下个建设阶段。 走廊互换 a 0.0.x 客户端已存储
采用同样方式 backend: "rfq"。 。 。 .
运行时间要求
核心要求的全球性是: crypto.getRandomValues。节点和浏览器有它; React
本地没有,所以安装 react-native-get-random-values (或 expo-crypto)并导入
在这包裹之前. crypto.subtle 未使用. EventSource 财务报告和审定财务报表 WebSocket 仅需
手表和接力运输,每个都采用注入式执行.
客户端不使用操作员 URL 。 操作员信息, Arkade 链条读取和广播都来源于
从钱包,这是唯一一个知道它跟哪个操作员说话的地方。 链上
走廊是例外: IWallet 上面没有L1供应商 所以它从Esplora读取比特币
ESPLORA_URL[network]。指向别处
corridors: { onchain: { chain: { esploraUrl } } },或通过 { provider } 读取您的
拥有 OnchainProvider - 一个电源支撑的钱包,然后手表并声称HTLC是自己的
后端 .
子路径
| 子路径 | 这是什么 |
|---|---|
@arkade-os/swap | 客户端、动词、词汇、错误分类 |
@arkade-os/swap/advanced | 动词下方的管弦:驱动器、走廊、RFQ线 |
@arkade-os/swap/node | 节点存储默认值 |
@arkade-os/swap/repositories/* | 反应原生后端 |
@arkade-os/swap/nostr | 诺斯特RFQ运输,用于手建一 |
@arkade-os/swap/protocol | v1 构件,已折旧 |
根是一个被整理的表面——如果客户端模块定义的名称不在它上,它就在它上
./advanced (手动驾驶与 createSwapDrive,目标要求 corridorSet, (中文(简体) ),
自定义引用流量 acceptQuote编号 :quoteViaRfq,记录读取 recordLeg编号 :swapOf) (中文(简体) ).
"先入为主"是故意的深层潜行,不是第二个相容承诺:这些名字会移动
与客户端的内部跨越小版本;根是所停留的.
./nostr 是一层楼,不是地平线:客户打开卡片的会合点
潜行道是让逃生舱 而不是墙 这是一个单独的切入点
因为 nostr-tools 是一个可选的同伴依赖, 所以消费者谁从来没有手建一个
运输从不付钱.
./protocol 是另一条地道,它是一个地板,而不是一个中转区域。 每个
上面的名字是这个客户端之前的整合表面——请求,契约,记录,RFQ
管理器,恢复扫描,每个扫描都带有 @deprecated 指针命名替代它的东西.
没有一个在根上: 释放中断了 0.1.0-rc.1 无论如何,所以一个时期
再出口者会将一个迁移分成两个,并将200 v1 个名字留在一个根上,其要求是
成为v2表面。 副道上没有任何东西被计划去除,标记的意思是"The
客户现在为你做这个 而不是"这去去的下一次发布". MIGRATION.md 拥有
表格,包括没有地板的名称和原因.
进一步阅读
- 移民.md ——每个重名,每个去除,每个v1的名字去的地方.
- V2 API.md (英语) ——客户端表面的开发商UX注释.