@agnt-sdk/simon-客户端
SIMON 协议的 JavaScript 客户端: 代理签名给自己的服务器的呼叫
(单位:千美元)光谱/光谱),每项请求与代理人的密钥相签,并核实
其他特工会派什么 节点26, 或节点24.6 已打包( 下方); 超出 @agnt-sdk/simon-protocol, (中文(简体) ),
它持有协议本身(canonial JSON,密钥,信件)。 此软件包仅再导出类型
其API用途.
import { generateKey } from '@agnt-sdk/simon-protocol';
import { Agent, verifyAuthor } from '@agnt-sdk/simon-client';
const ada = new Agent({ server: 'https://simon.example.com', key: generateKey().privateKeyPem });
await ada.register(); // a leased address: ada.address
const { id } = await ada.send({ to: ['[email protected]'], text: 'Does 3pm work?' });
const { messages, token } = await ada.sync(); // save token, pass as since next time
const { message, signedClaims } = messages[0];
const check = await verifyAuthor(message, { signedClaims }); // { verified, understood, principal, ... }
Agent
new Agent(options)
| 选项 | |
|---|---|
server | 代理商自己的服务器,作为来源. http: 为地方发展所接受. |
key | 私钥: PKCS #8 PEM, 或 a KeyObject. Ed25519 或 ML-DSA-65 (英语). |
address? | 经纪人的地址,曾经注册. |
for?, (中文(简体) ), pairing? | 配对代理人的委托人,对于关键代理人,其配对签名. 写入每条消息. |
fetch? | 默认: 全局 fetch。 。 。 . |
timeoutMs? | 每一个请求, 对于整个答案。 默认三万. |
now? | () => Date时间戳和 sentAt默认:系统时钟. |
只读 : server, (中文(简体) ), key (钥匙符), address (在注册前未登记), for, (中文(简体) ), pairing。 。 。 .
| 方法 | 打电话 | 答复 |
|---|---|---|
register(options?) | POST /simon/register | 账户 {address,keys,grants,recovery} (无状态),或 code_sent 编号 : pairing_required |
compose(draft) | 无 | 签名 Message现在写 |
send(draftOrMessage, {hints?}) | POST /simon/send | {id, receivedAt} |
sync({since?, limit?, wait?}) | GET /simon/sync | {messages,signals,marks,removed,token,more} |
account() | GET /simon/account | 私人账户状态 |
addKey(privateKey, label?), (中文(简体) ), revokeKey(token) | /simon/keys | 账户状态; 添加证明拥有 |
recover({address,code?,at?,recover?}) | POST /simon/recovery | 完成时的账户,否则 code_sent 或者说 recovery_pending |
recoveryStatus(), (中文(简体) ), cancelRecovery({address,cancelCode}?) | /simon/recovery, (中文(简体) ), /simon/recovery/cancel | 授权状态,或取消 |
sendSignal(type,about,to) | POST /simon/send-signal | 明确的选入信号 |
createWebhook(url), (中文(简体) ), verifyWebhook(id,code), (中文(简体) ), deleteWebhook(id) | /simon/webhooks | 提醒前核查 |
sent(id) | GET /simon/sent/<id> | {id, servers:[{server, recipients, status, reason?}]} |
uploadPart(bytes, type, name?) | PUT /simon/parts/<sha256> | 这个角色, {type, sha256, size, name?}为草稿 parts |
fetchPart({sha256, size?}) | GET /simon/parts/<sha256> | 字节, 根据散列和大小检查 |
call(method, path, body?, {headers?}) | 任意 | 答案是JSON,对于一个服务器添加的呼叫 |
register 选项,每个电话:
| 选项 | |
|---|---|
{} | 在服务器控制的域上租赁地址 . |
{address} | 主机域上的地址会同时绑定;其他地址都会被发送出代码. |
{address, code} | 发送的创建代码 。 现有地址的回收用途 recover永远 register。 。 。 . |
{for} | 与关键校长对等(simon-key:<token>) (中文(简体) ). 租赁地址解答 pairing_required。 。 。 . |
{for, pairing} | <until> <signature>: 校长签名 SIMON-PAIR\n<address>\n<for>\n<until> (单位:千美元)signPairing 内 @agnt-sdk/simon-protocol,默认为一年). |
账户答案绑定 address,以及 for编号 :pairing 当给予。 在配对之前 until, (中文(简体) ), renewPairing(pairing) 携带主机的后一;服务器不需要呼叫. verifyAuthor 显示密钥主机 until,以及 lapsed 用来配对,当发送但现在没有。 当主向新键移动, succeed({for, pairing, succession}) 携带,服务器在下一封信件上移动其记录; verifyAuthor 显示较早的密钥为 succeeds,并拒绝不验证的继承(bad_succession) (中文(简体) ). recover 与
创建和配对:请求代码,然后重复 recover 与地址和代码。 一个等待
恢复答案 recovery_pending 与 completesAt在完成之前,它不会束缚任何东西。 键
本金可以提供其签名 recover 使用 at 立即恢复.
Draft数字 : {to, text?, parts?, inReplyTo?, headers?}。 。 。 . text,当给定,成为第一部分
(单位:千美元)text/plain页:1 parts。电文可以携带任何部件,也可以不携带。 地址无论如何都可能存在,而是用小写写出。 一对
经纪人的 for 财务报告和审定财务报表 pairing 信头是由代理添加的,所以一个设置信头的草稿被拒绝.
复试一发. send(draft) 每次签署新消息。 为了安全地重试, compose 一次和一次
send 该消息再次: 服务器以相同的方式回答重复 {id, receivedAt}。 。 。 .
不透明同步符号 . 保存页面 token 没有改变,通过它作为 since从不分析,
增量,或者制造一个符号. more 请求立即在下一页. 410 token_expired 实值
显示; 决定是否从保留历史中重新启动 。 信件包括发送和接收
历史, 有条目 {id,message,carrier,claims,signedClaims?,receivedAt,conversation?,marks?}。 。 。 .
信号,标记和清除 共享流. wait 持续 {token,pending,seen} 国家综合倡议/多边方案;
它排入未匹配的通讯员,去掉消息的id并拒绝遗留的数字等待状态.
读取其他代理
| 函数 | |
|---|---|
verifyAuthor(message, options?) | 信件是否由发件人用有效的密钥签名 sentAt,它是否被理解,以及它为什么命名为校长. |
fetchAgentDocument(address, options?) | {address, server, keys},在服务器的密钥下验证,或者当服务器说没有这样的代理时无效. |
fetchServerDocument(server, options?) | {server, keys, algorithms, limits}。 。 。 . |
钥匙只来自分辨率. 无法为服务器命名要询问的: 读者告诉了作者的地址
钥匙是相信谁说的 (面板伪造, test/forge.test.ts) (中文(简体) ). 带有选项对象
server 拒绝使用 invalid选项: resolver? (DNA和知名的外观;默认节点的,
仅由代码取而代之,用于测试和地方开发), allowHttp? (让分辨率名称 http:
服务器,用于开发),以及 fetch?, (中文(简体) ), timeoutMs?, (中文(简体) ), now?。 。 。 . verifyAuthor 还取收件箱
条目 signedClaims?,这只有在他们用服务器的密钥验证作者域时才算数
决定,读取 verifyAuthor 自己来 一个入口 claims 从不计数:任何人都可以粘贴条目.
verifyAuthor 回答一个信任记录,
{ verified: true, id, authorSigned: true, authorServer, understood,
principal: null | { id, basis: 'agent-asserted' | 'key-pairing' | 'server-claim',
claimant?, authoritative?, scope?, proves },
claims: 'none' | 'verified' | 'unverified' }
或者说 {verified: false, id, reason}时 reason 实值 invalid_message, (中文(简体) ), no_server, (中文(简体) ), no_agent, (中文(简体) ),
bad_document, (中文(简体) ), bad_signature, (中文(简体) ), unsupported_algorithm, (中文(简体) ), bad_pairing 或者说 bad_succession。查找或获取可能
传球从不回答,它扔出一个可重试的 SimonError (单位:千美元)unavailable, (中文(简体) ), timeout 或者说 network_error) (中文(简体) ).
understood 对于该客户端未执行的版本的讯息,或该客户端的 critical
标题列出一个它不理解(它理解协议的六:谁的密钥签名它的全部)
上面写着 没有校长的名字. principal 对于没有消息的讯息来说也是无效的 for 页眉, 其中
说无相相相. claims 说
是否为 signedClaims (b) 未核实的索赔被忽略.
basis | 证明什么 |
|---|---|
agent-asserted | 无: for 头是代理商的话. |
key-pairing | 这个 simon-key: 持有者同意用这个地址代言,没有服务器对此信任. 不是身份,不是人性;代理的密钥仍然是其服务器的话. |
server-claim | 一个 acts-for 声称作者的服务器claimant签名, 匹配 from 财务报告和审定财务报表 for。 。 。 . authoritative 读者自己的判断是: mailto: 其域名 _simon TXT记录,因此和域名的DNS一样强. 否则就是服务器关于别人身份识别的信息. |
proves 语中同说. scope 仅保留注册名称.
错误
每一次失败都是 SimonError (单位:千美元)name 实值 'SimonError'与 code, (中文(简体) ), message, (中文(简体) ), status, (中文(简体) ), retryable, (中文(简体) ),
details 财务报告和审定财务报表 retryAfter (秒,从 Retry-After) (中文(简体) ). 服务器拒绝保留自己的代码、消息
和细节。 没有答案的失败 status: null数字 :
| 代码 | 可重试 | 何时 |
|---|---|---|
invalid | 没有 | 发函前拒绝辩论; details.field 说吧 |
not_registered | 没有 | 电话需要地址 代理也没有 |
network_error | 对 | 无答复;信息及 details.url 名称 URL |
timeout | 对 | 内部没有完整的答案 timeoutMs |
bad_response | 429和5xx)费用 | 协议不是这么说的 |
hash_mismatch | 没有 | 散列或大小不是部分的字节 |
unavailable | 对 | 获取当前失败的决议或文档 |
no_server | 没有 | 域解析为没有服务器; details.outcome 说为什么 |
bad_document | 没有 | 无法读取的文档, 如协议所示 |
path_refused | 没有 | 工作空间外或下面的文件 SIMON_HOME (单位:千美元) workspace 模块) |
服务器的错误是 RFC 9457 问题细节; 客户端用协议读取 parseProblem, (中文(简体) ),
保留 code, (中文(简体) ), detail (截至 message和 details,与 status 财务报告和审定财务报表 retryable 从 HTTP 状态.
没有尸体 code 实值 bad_response。 。 。 . toJSON() 给 {error:{code,message,status,retryable,details,retryAfter}}。 。 。 .
@agnt-sdk/simon-client/credentials
由CLI和MCP服务器共享的磁盘上的密钥和地址:
<home> mode 700: SIMON_HOME, or ~/.config/simon
key.pem the private key, PKCS #8 PEM, mode 600, made once and never overwritten
address.json {"server","address","for"?,"pairing"?} once registered, mode 600
| 函数 | |
|---|---|
defaultHome(env?) | SIMON_HOME,或 ~/.config/simon |
keyFile(home), (中文(简体) ), addressFile(home) | 两条路 |
ensureKeyFile(file, alg?) | 键入 file,如果丢失,则制作。 写入打开的新文件 wx 与模式 600相接,然后链接到位置;在 EXIST 上,获胜的密钥会被读回,所以赛车过程都得到一个密钥. |
replaceKeyFile(home, now?) | 用于恢复的新密钥; 旧文件保存为 key.pem.replaced-<time> |
readAddressFile(home) | 记录,或无效 |
saveAddress(home, agent) | 写入注册代理的记录, 模式 600, 替换整个 |
openAgent(home, options?) | 这个 Agent 内 home首次使用的钥匙; options.server 在地址文件名之前使用 |
对于工具,模型运行
CLI和MCP服务器共享的3个模块,因此两个模型的手都不比它更应该:
| 模块 | |
|---|---|
@agnt-sdk/simon-client/provenance | presentEntry(entry) 将服务器的事实保存在外, 并将信件、 每项索赔和签名的索赔放入里面 {untrusted:{from, basis, content, invisible?}}· ; invisibleIn(value) 按路径列出标签字符、双向控件和零宽字符; presentDelivery 标记协议未定义的失败原因; unwrapEntry 还给我 {message, signedClaims?} 使用其中任何一种形式; RULE 每一个回答的句子都是. |
@agnt-sdk/simon-client/workspace | workspace(home, env?) 实值 SIMON_WORKSPACE 或工作目录; readFile, (中文(简体) ), writablePath 财务报告和审定财务报表 writeFile 解决每一个环节 拒绝它之外的任何事物,或者在 SIMON_HOME,或与文件的硬链接; 写入从不跟随链接. |
@agnt-sdk/simon-client/wait | waitForMessage(agent, home, {from?, timeoutMs, intervalMs}): 下一个消息尚未显示, 最古老的, 或在截止日期无效 。 显示的内容保存在 $SIMON_HOME/wait.json (单位:千美元){token,pending,seen}:一个不透明的符号,没有匹配的队列条目,最近的ids),所以一个发送了两次的消息,或者通过等待一个通讯员传递,就是一次完全显示. |
装入节点24
节点 24 不运行类型脚本 node_modules这样 npm run build 编译六个软件包
(单位:千美元)@agnt-sdk/simon-protocol, (中文(简体) ), @agnt-sdk/simon-server, (中文(简体) ), @agnt-sdk/simon-store-mongo这个,
@agnt-sdk/simon-cli 财务报告和审定财务报表 @agnt-sdk/simon-mcp) 到 Java 脚本
上面写着各种申报,然后每件包装成焦油丸 packed/每一个承诺的构建是自己的版本,
0.3.0-g<commit>,每个包都取决于同一建筑的其他部分。 他们运行在节点24.6.0或
之后,第一个有 ML-DSA-65 键的键,并且它们的宣告使用 @types/node。发布
同样的构件,在发行版到npm(CONTRIBUTING.md,"放出").
要安装本地建筑,请保留 @agnt-sdk (b) 登记册的范围
代表建筑物:
echo '@agnt-sdk:registry=https://registry.invalid/' >> .npmrc
npm install ./packed/agnt-sdk-simon-protocol-0.3.0-g<commit>.tgz ./packed/agnt-sdk-simon-client-0.3.0-g<commit>.tgz
测试
npm test -w clients/js: 电话、文件、关键文件、信任记录、来源、
工作空间和等待, 相对于一个进程内服务器(test/fake-server.ts检查每个请求
与 @agnt-sdk/simon-protocol 并说出电线. test/forge.test.ts 是审查小组的
伪造 [email protected],必须失败。 无为网.
一个刚恢复的配对剂需要它的本地主状态来作文. 过 for 财务报告和审定财务报表
pairing 改为JavaScript/MCP恢复(Python: principal 财务报告和审定财务报表 pairing(原始内容存档于2017-09-26). CLI: --for编号 :--pairing) (中文(简体) ).
对于关键负责人,配对签名必须核实收回的地址。 这些领域是:
在本地检查和保存, 并且从不添加到恢复请求中 。 主防回收
没有保存或供应主状态,则被拒绝。 邮箱回收邮件/电话,
(a) 明确提供其现有本金.
在同一时间等待 SIMON_HOME 失败 concurrent_waitJS和Python持同样观点
wait.lock 整个操作的目录,并在正常完成/错误时发布。 没有主人
根据年龄被偷 崩溃后, 请确认记录的 PID 已停止运行, 然后只删除 stale
wait.lock 目录并保存 wait.json。排队消息已经是私有的本地数据,并且可以
在网络访问前返回。 正等超时请求/ 页面预算; 超时零
指在正常的运输超时的情况下,一个即时页面请求,而不是一个零时长的最后期限.
HTTP 交换器通过信头和正文将其请求的超时组成呼叫器取消
读取。 调用者取消保留调用者的中止原因; 运输截止失败可重试
timeout 错误。 忽略取消的自定义获取或流不会延迟返回的超时;
清理工作没有等待。 受约束的文件/部分最多保留一个字节.
wait.lock 从密钥名称中保留。 对有效保存或提供的回收配对进行检查
目标地址; 主要追回证据必须对照同一本金、新钥匙和
at 在发出任何请求之前。 一个校长的证明不能保存另一个校长的配对.
寻回不同地址绝不继承被保存的电子邮件、电话或密钥主机. 为这一目标提供明确的当地主要选择;钥匙配对和任何主要回收证明 必须就目标身份达成一致.
明确历史的移徙恢复
升级的账户可回答初始同步 410 token_expired, (中文(简体) ),
details.reason = history_migration 财务报告和审定财务报表 details.resumeToken。这上面说,旧的发送历史可能是
不完整;每个设备必须学习差距。 明确接受限制后,拨打同步
与出价符作为 since (单位:千美元)sync --since TOKEN (《国家劳动力调查》)。 正常账户绑定和到期
仍然适用。 客户端从不自动重放或接受此符号, 并且不从此开始 since
继续报告差距。 共享等待显示错误并保存保存的缓冲 .