@lawrenceliang-btc/atel-sdk 1.1.26 → 1.1.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/atel.mjs +98 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/intent/index.d.ts +45 -0
- package/dist/intent/index.js +67 -0
- package/package.json +1 -1
- package/skill/atel-agent/SKILL.md +55 -0
package/bin/atel.mjs
CHANGED
|
@@ -5904,6 +5904,45 @@ async function cmdOrder(executorDid, capType, price) {
|
|
|
5904
5904
|
// Sign task request
|
|
5905
5905
|
const taskSignature = await signTaskRequest(taskRequest, id.secretKey);
|
|
5906
5906
|
|
|
5907
|
+
// ── AVIP: Create signed Intent ──
|
|
5908
|
+
const { default: nacl } = await import('tweetnacl');
|
|
5909
|
+
const { serializePayload } = await import('@lawrenceliang-btc/atel-sdk');
|
|
5910
|
+
const intentConstraints = {
|
|
5911
|
+
maxAmount: parseFloat(price),
|
|
5912
|
+
milestoneCount: 5,
|
|
5913
|
+
};
|
|
5914
|
+
const deadlineIdx = rawArgs.indexOf('--deadline');
|
|
5915
|
+
if (deadlineIdx >= 0 && rawArgs[deadlineIdx + 1]) {
|
|
5916
|
+
intentConstraints.deadline = rawArgs[deadlineIdx + 1];
|
|
5917
|
+
}
|
|
5918
|
+
const scopeIdx = rawArgs.indexOf('--scope');
|
|
5919
|
+
if (scopeIdx >= 0 && rawArgs[scopeIdx + 1]) {
|
|
5920
|
+
intentConstraints.scope = rawArgs[scopeIdx + 1].split(',').map(s => s.trim());
|
|
5921
|
+
}
|
|
5922
|
+
|
|
5923
|
+
const intentTimestamp = new Date().toISOString();
|
|
5924
|
+
const intentSignable = {
|
|
5925
|
+
action: 'execute_task',
|
|
5926
|
+
constraints: intentConstraints,
|
|
5927
|
+
issuerDid: id.did,
|
|
5928
|
+
subjectDid: executorDid,
|
|
5929
|
+
timestamp: intentTimestamp,
|
|
5930
|
+
};
|
|
5931
|
+
const intentSig = Buffer.from(
|
|
5932
|
+
nacl.sign.detached(Buffer.from(serializePayload(intentSignable)), id.secretKey)
|
|
5933
|
+
).toString('base64');
|
|
5934
|
+
|
|
5935
|
+
const intentData = {
|
|
5936
|
+
intentId: 'intent_' + crypto.randomUUID(),
|
|
5937
|
+
issuerDid: id.did,
|
|
5938
|
+
subjectDid: executorDid,
|
|
5939
|
+
action: 'execute_task',
|
|
5940
|
+
constraints: intentConstraints,
|
|
5941
|
+
delegationChain: [{ from: id.did, to: executorDid, attenuated: true, signature: intentSig }],
|
|
5942
|
+
timestamp: intentTimestamp,
|
|
5943
|
+
signature: intentSig,
|
|
5944
|
+
};
|
|
5945
|
+
|
|
5907
5946
|
// Send to Platform
|
|
5908
5947
|
const data = await signedFetch('POST', '/trade/v1/order', {
|
|
5909
5948
|
executorDid,
|
|
@@ -5914,7 +5953,8 @@ async function cmdOrder(executorDid, capType, price) {
|
|
|
5914
5953
|
description,
|
|
5915
5954
|
version: 2, // New version with signature
|
|
5916
5955
|
taskRequest: taskRequest,
|
|
5917
|
-
taskSignature: taskSignature
|
|
5956
|
+
taskSignature: taskSignature,
|
|
5957
|
+
intent: intentData, // AVIP intent
|
|
5918
5958
|
});
|
|
5919
5959
|
|
|
5920
5960
|
// For paid orders: show escrow info (chain escrow creation handled by Platform backend)
|
|
@@ -5943,6 +5983,60 @@ async function cmdOrder(executorDid, capType, price) {
|
|
|
5943
5983
|
}
|
|
5944
5984
|
}
|
|
5945
5985
|
|
|
5986
|
+
// ── AVIP Commands ──
|
|
5987
|
+
|
|
5988
|
+
async function cmdIntentInfo(orderId) {
|
|
5989
|
+
if (!orderId) { console.error('Usage: atel intent-info <orderId>'); process.exit(1); }
|
|
5990
|
+
try {
|
|
5991
|
+
const res = await fetch(`${PLATFORM_URL}/trade/v1/order/${orderId}/intent`);
|
|
5992
|
+
const data = await res.json();
|
|
5993
|
+
if (!res.ok) {
|
|
5994
|
+
console.log('No intent found for this order.');
|
|
5995
|
+
return;
|
|
5996
|
+
}
|
|
5997
|
+
console.log('\n=== Intent Declaration ===');
|
|
5998
|
+
console.log(`Intent ID: ${data.intent_id}`);
|
|
5999
|
+
console.log(`Action: ${data.action}`);
|
|
6000
|
+
console.log(`Issuer: ${data.issuer_did}`);
|
|
6001
|
+
console.log(`Subject: ${data.subject_did}`);
|
|
6002
|
+
if (data.max_amount) console.log(`Max Amount: $${data.max_amount}`);
|
|
6003
|
+
if (data.deadline) console.log(`Deadline: ${data.deadline}`);
|
|
6004
|
+
if (data.scope) console.log(`Scope: ${JSON.parse(data.scope).join(', ')}`);
|
|
6005
|
+
console.log(`Milestones: ${data.milestone_count}`);
|
|
6006
|
+
console.log(`Status: ${data.status}`);
|
|
6007
|
+
console.log(`Anchor: ${data.anchor_status}${data.anchor_tx ? ' tx=' + data.anchor_tx : ''}`);
|
|
6008
|
+
console.log(`Created: ${data.created_at}`);
|
|
6009
|
+
} catch (e) {
|
|
6010
|
+
console.error('Failed to fetch intent:', e.message);
|
|
6011
|
+
}
|
|
6012
|
+
}
|
|
6013
|
+
|
|
6014
|
+
async function cmdCompletionProof(orderId) {
|
|
6015
|
+
if (!orderId) { console.error('Usage: atel completion-proof <orderId>'); process.exit(1); }
|
|
6016
|
+
try {
|
|
6017
|
+
const res = await fetch(`${PLATFORM_URL}/trade/v1/order/${orderId}/completion-proof`);
|
|
6018
|
+
const data = await res.json();
|
|
6019
|
+
if (!res.ok) {
|
|
6020
|
+
console.log('No completion proof found for this order.');
|
|
6021
|
+
return;
|
|
6022
|
+
}
|
|
6023
|
+
console.log('\n=== Completion Proof ===');
|
|
6024
|
+
console.log(`Proof ID: ${data.proof_id}`);
|
|
6025
|
+
console.log(`Intent ID: ${data.intent_id}`);
|
|
6026
|
+
console.log(`Verdict: ${data.verdict}`);
|
|
6027
|
+
console.log(`Milestones: ${data.milestones_completed}/${data.milestones_expected}`);
|
|
6028
|
+
console.log(`Rate: ${(data.completion_rate * 100).toFixed(1)}%`);
|
|
6029
|
+
console.log(`Budget: ${data.within_budget ? '✅ Within' : '❌ Exceeded'}`);
|
|
6030
|
+
console.log(`Scope: ${data.within_scope ? '✅ Within' : '❌ Exceeded'} (${data.scope_check_type})`);
|
|
6031
|
+
console.log(`Deadline: ${data.within_deadline ? '✅ Within' : '❌ Exceeded'}`);
|
|
6032
|
+
console.log(`Anchor: ${data.anchor_status}${data.anchor_tx ? ' tx=' + data.anchor_tx : ''}`);
|
|
6033
|
+
console.log(`Intent Hash: ${data.intent_hash}`);
|
|
6034
|
+
console.log(`Exec Hash: ${data.execution_hash}`);
|
|
6035
|
+
} catch (e) {
|
|
6036
|
+
console.error('Failed to fetch completion proof:', e.message);
|
|
6037
|
+
}
|
|
6038
|
+
}
|
|
6039
|
+
|
|
5946
6040
|
async function cmdOrderInfo(orderId) {
|
|
5947
6041
|
if (!orderId) { console.error('Usage: atel order-info <orderId>'); process.exit(1); }
|
|
5948
6042
|
const res = await fetch(`${PLATFORM_URL}/trade/v1/order/${orderId}`);
|
|
@@ -8039,6 +8133,9 @@ const commands = {
|
|
|
8039
8133
|
'milestone-verify': () => cmdMilestoneVerify(args[0], args[1]),
|
|
8040
8134
|
'milestone-arbitrate': () => cmdMilestoneArbitrate(args[0], args[1]),
|
|
8041
8135
|
'chain-records': () => cmdChainRecords(args[0]),
|
|
8136
|
+
// AVIP
|
|
8137
|
+
'intent-info': () => cmdIntentInfo(args[0]),
|
|
8138
|
+
'completion-proof': () => cmdCompletionProof(args[0]),
|
|
8042
8139
|
// Dispute
|
|
8043
8140
|
dispute: () => cmdDispute(args[0], args[1], args[2]),
|
|
8044
8141
|
evidence: () => cmdEvidence(args[0], args[1]),
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -30,3 +30,5 @@ export * from './executor/index.js';
|
|
|
30
30
|
export * from './audit/index.js';
|
|
31
31
|
// ── Attachment Module ────────────────────────────────────────
|
|
32
32
|
export * from './attachment/index.js';
|
|
33
|
+
// ── AVIP (Verifiable Intent Protocol) ───────────────────────
|
|
34
|
+
export * from './intent/index.js';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AVIP — ATEL Verifiable Intent Protocol
|
|
3
|
+
*
|
|
4
|
+
* Intent represents a signed declaration of what an agent intends to do,
|
|
5
|
+
* with structured constraints (amount, deadline, scope, milestones).
|
|
6
|
+
*
|
|
7
|
+
* The Intent is signed by the issuer's Ed25519 key and submitted to the
|
|
8
|
+
* Platform alongside the order. The Platform verifies the signature and
|
|
9
|
+
* stores the Intent as-is (never reconstructed).
|
|
10
|
+
*/
|
|
11
|
+
import { AgentIdentity } from '../identity/index.js';
|
|
12
|
+
export interface IntentConstraints {
|
|
13
|
+
maxAmount?: number;
|
|
14
|
+
deadline?: string;
|
|
15
|
+
milestoneCount?: number;
|
|
16
|
+
scope?: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface DelegationStep {
|
|
19
|
+
from: string;
|
|
20
|
+
to: string;
|
|
21
|
+
attenuated: boolean;
|
|
22
|
+
signature: string;
|
|
23
|
+
}
|
|
24
|
+
export interface Intent {
|
|
25
|
+
intentId: string;
|
|
26
|
+
issuerDid: string;
|
|
27
|
+
subjectDid: string;
|
|
28
|
+
action: string;
|
|
29
|
+
constraints: IntentConstraints;
|
|
30
|
+
delegationChain: DelegationStep[];
|
|
31
|
+
timestamp: string;
|
|
32
|
+
signature: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create and sign an Intent.
|
|
36
|
+
*
|
|
37
|
+
* The signing input is a deterministic JSON of:
|
|
38
|
+
* { action, constraints, issuerDid, subjectDid, timestamp }
|
|
39
|
+
* with keys sorted alphabetically (matching Platform's deterministicJSON).
|
|
40
|
+
*/
|
|
41
|
+
export declare function createIntent(identity: AgentIdentity, subjectDid: string, action: string, constraints: IntentConstraints): Intent;
|
|
42
|
+
/**
|
|
43
|
+
* Verify an Intent's signature using the issuer's public key.
|
|
44
|
+
*/
|
|
45
|
+
export declare function verifyIntent(intent: Intent, publicKey: Uint8Array): boolean;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AVIP — ATEL Verifiable Intent Protocol
|
|
3
|
+
*
|
|
4
|
+
* Intent represents a signed declaration of what an agent intends to do,
|
|
5
|
+
* with structured constraints (amount, deadline, scope, milestones).
|
|
6
|
+
*
|
|
7
|
+
* The Intent is signed by the issuer's Ed25519 key and submitted to the
|
|
8
|
+
* Platform alongside the order. The Platform verifies the signature and
|
|
9
|
+
* stores the Intent as-is (never reconstructed).
|
|
10
|
+
*/
|
|
11
|
+
import { randomUUID } from 'crypto';
|
|
12
|
+
import { sign, verify } from '../identity/index.js';
|
|
13
|
+
// ── Core Functions ──
|
|
14
|
+
/**
|
|
15
|
+
* Create and sign an Intent.
|
|
16
|
+
*
|
|
17
|
+
* The signing input is a deterministic JSON of:
|
|
18
|
+
* { action, constraints, issuerDid, subjectDid, timestamp }
|
|
19
|
+
* with keys sorted alphabetically (matching Platform's deterministicJSON).
|
|
20
|
+
*/
|
|
21
|
+
export function createIntent(identity, subjectDid, action, constraints) {
|
|
22
|
+
const milestoneCount = constraints.milestoneCount ?? 5;
|
|
23
|
+
const normalizedConstraints = {
|
|
24
|
+
...constraints,
|
|
25
|
+
milestoneCount,
|
|
26
|
+
};
|
|
27
|
+
const timestamp = new Date().toISOString();
|
|
28
|
+
// Build the object to sign — keys will be sorted by serializePayload
|
|
29
|
+
const signable = {
|
|
30
|
+
action,
|
|
31
|
+
constraints: normalizedConstraints,
|
|
32
|
+
issuerDid: identity.did,
|
|
33
|
+
subjectDid,
|
|
34
|
+
timestamp,
|
|
35
|
+
};
|
|
36
|
+
// Sign using the SDK's standard sign() which calls serializePayload internally
|
|
37
|
+
const signature = sign(signable, identity.secretKey);
|
|
38
|
+
const intentId = 'intent_' + randomUUID();
|
|
39
|
+
return {
|
|
40
|
+
intentId,
|
|
41
|
+
issuerDid: identity.did,
|
|
42
|
+
subjectDid,
|
|
43
|
+
action,
|
|
44
|
+
constraints: normalizedConstraints,
|
|
45
|
+
delegationChain: [{
|
|
46
|
+
from: identity.did,
|
|
47
|
+
to: subjectDid,
|
|
48
|
+
attenuated: true,
|
|
49
|
+
signature,
|
|
50
|
+
}],
|
|
51
|
+
timestamp,
|
|
52
|
+
signature,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Verify an Intent's signature using the issuer's public key.
|
|
57
|
+
*/
|
|
58
|
+
export function verifyIntent(intent, publicKey) {
|
|
59
|
+
const signable = {
|
|
60
|
+
action: intent.action,
|
|
61
|
+
constraints: intent.constraints,
|
|
62
|
+
issuerDid: intent.issuerDid,
|
|
63
|
+
subjectDid: intent.subjectDid,
|
|
64
|
+
timestamp: intent.timestamp,
|
|
65
|
+
};
|
|
66
|
+
return verify(signable, intent.signature, publicKey);
|
|
67
|
+
}
|
package/package.json
CHANGED
|
@@ -837,3 +837,58 @@ curl $TOKENHUB/tokenhub/v1/transfers \
|
|
|
837
837
|
| Swap 手续费 | 5%(500 bps)|
|
|
838
838
|
| 最小提现 | 1,000 Token |
|
|
839
839
|
| 速率限制 | 60 次/分钟 |
|
|
840
|
+
|
|
841
|
+
---
|
|
842
|
+
|
|
843
|
+
## AVIP — 可验证意图执行协议
|
|
844
|
+
|
|
845
|
+
ATEL 实现了 AVIP(ATEL Verifiable Intent Protocol)。每笔订单可以附带一个结构化的、签名的意图声明,系统会在结算时自动比对意图与实际执行结果。
|
|
846
|
+
|
|
847
|
+
### 工作原理
|
|
848
|
+
|
|
849
|
+
1. **Intent(意图声明)** — 下单时自动创建,包含:金额上限、截止时间、能力范围、里程碑数量。由下单方 Ed25519 签名,链上锚定。
|
|
850
|
+
2. **Trace(执行追踪)** — 每个里程碑的提交记录自动关联到 Intent。
|
|
851
|
+
3. **Proof(完成度证明)** — 结算时系统自动比对 Intent 约束与实际执行,生成 CompletionProof:
|
|
852
|
+
- `FULFILLED` — 所有约束满足(里程碑全部完成、未超支、未越权、未超时)
|
|
853
|
+
- `PARTIAL` — 部分里程碑完成
|
|
854
|
+
- `VIOLATED` — 违反了意图约束(超支/越权/超时)
|
|
855
|
+
- `DISPUTED` — 进入争议流程
|
|
856
|
+
4. **Verdict(信任裁决)** — Proof 的结果自动反馈到信任评分。FULFILLED 加分更多(+3),VIOLATED 扣分(-5)。
|
|
857
|
+
|
|
858
|
+
### 使用方式
|
|
859
|
+
|
|
860
|
+
下单时自动附带 Intent(无需额外操作):
|
|
861
|
+
```bash
|
|
862
|
+
atel order <executorDid> <capability> <price>
|
|
863
|
+
```
|
|
864
|
+
|
|
865
|
+
可选参数扩展 Intent 约束:
|
|
866
|
+
```bash
|
|
867
|
+
atel order <executorDid> <capability> <price> --deadline 2026-04-15 --scope "data_analysis,report"
|
|
868
|
+
```
|
|
869
|
+
|
|
870
|
+
查看订单的 Intent:
|
|
871
|
+
```bash
|
|
872
|
+
atel intent-info <orderId>
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
查看结算后的 CompletionProof:
|
|
876
|
+
```bash
|
|
877
|
+
atel completion-proof <orderId>
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
### Intent 对信任评分的影响
|
|
881
|
+
|
|
882
|
+
| Verdict | Executor 评分变化 | Requester 评分变化 |
|
|
883
|
+
|---------|------------------|-------------------|
|
|
884
|
+
| FULFILLED | +3.0 | +1.5 |
|
|
885
|
+
| PARTIAL | +0.5 | +0.5 |
|
|
886
|
+
| VIOLATED | -5.0 | -1.0 |
|
|
887
|
+
| 无 Intent(旧订单) | +2.0 | +1.0 |
|
|
888
|
+
|
|
889
|
+
### 注意事项
|
|
890
|
+
|
|
891
|
+
- Intent 是可选增强,不是强制要求。没有 Intent 的旧订单照常运行。
|
|
892
|
+
- `--deadline` 格式为 ISO 8601(如 `2026-04-15T00:00:00.000Z`)
|
|
893
|
+
- `--scope` 为逗号分隔的能力类型(当前为结构化软校验)
|
|
894
|
+
- CompletionProof 在订单结算时自动生成,无需手动触发。
|