@lawrenceliang-btc/atel-sdk 1.1.34 → 1.1.36

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 CHANGED
@@ -1971,8 +1971,19 @@ async function promptInput(question) {
1971
1971
  // ─── Anchor Configuration ────────────────────────────────────────
1972
1972
 
1973
1973
  async function configureAnchor() {
1974
- console.log('\n🔗 Configure On-Chain Anchoring\n');
1975
-
1974
+ console.log('\n🔗 Configure On-Chain Anchoring (legacy V1 mode)\n');
1975
+ console.log('⚠️ In V2 the ATEL Platform anchors on behalf of agents using its own');
1976
+ console.log(' executor wallets — you do NOT need this for paid orders.');
1977
+ console.log(' Your smart wallet addresses (derived from your DID) already receive');
1978
+ console.log(' USDC and the platform pays gas for you. Only continue if you are');
1979
+ console.log(' running a legacy V1 self-anchoring agent.');
1980
+ console.log('');
1981
+ const go = await promptYesNo('Continue anyway?');
1982
+ if (!go) {
1983
+ console.log('Aborted. Your identity is unchanged.');
1984
+ return;
1985
+ }
1986
+
1976
1987
  // 1. Select chain
1977
1988
  const chain = await promptChoice(
1978
1989
  'Select blockchain for anchoring:',
@@ -2033,69 +2044,106 @@ async function cmdInit(agentId) {
2033
2044
  const identity = new AgentIdentity({ agent_id: name });
2034
2045
  saveIdentity(identity);
2035
2046
  savePolicy(DEFAULT_POLICY);
2036
-
2047
+
2037
2048
  // Create default agent-context.md for built-in executor
2038
2049
  const ctxFile = resolve(ATEL_DIR, 'agent-context.md');
2039
2050
  if (!existsSync(ctxFile)) {
2040
2051
  writeFileSync(ctxFile, `# Agent Context\n\nYou are an ATEL agent (${name}) processing tasks from other agents via the ATEL protocol.\n\n## Guidelines\n- Complete the task accurately and concisely\n- Return only the requested result, no extra commentary\n- If the task is unclear, do your best interpretation\n- Do not access private files or sensitive data\n- Do not make external network requests unless the task requires it\n`);
2041
2052
  }
2042
-
2043
- // Ask about paid order services
2044
- console.log('');
2045
- const providePaidOrders = await promptYesNo(
2046
- 'Do you want to provide paid order services? (requires on-chain anchoring)'
2047
- );
2048
-
2049
- let anchorConfigured = false;
2050
- if (providePaidOrders) {
2051
- try {
2052
- await configureAnchor();
2053
- anchorConfigured = true;
2054
- } catch (e) {
2055
- console.error(`❌ Failed to configure anchor: ${e.message}`);
2056
- }
2057
- }
2058
-
2059
- console.log(JSON.stringify({
2060
- status: 'created',
2061
- agent_id: identity.agent_id,
2062
- did: identity.did,
2053
+
2054
+ // NOTE (2026-04-09): We intentionally do NOT prompt for an on-chain anchor
2055
+ // private key here any more. That prompt is a V1 leftover — in V2 the
2056
+ // Platform handles all on-chain anchoring on behalf of agents using its own
2057
+ // registered executor wallets, and the user's USDC lives in a smart wallet
2058
+ // (AA) whose address is derived from the ATEL identity key. Asking users to
2059
+ // paste a raw Base/BSC/Solana private key at install time is both
2060
+ // unnecessary and intimidating. If someone genuinely needs legacy
2061
+ // self-anchoring they can opt in later via `atel anchor config`.
2062
+
2063
+ // Derive the smart-wallet addresses from the identity so the user can see
2064
+ // where to top up USDC for paid orders.
2065
+ let smartWallet = null;
2066
+ try {
2067
+ const info = identity.toJSON?.() || {};
2068
+ smartWallet = info.smart_wallet || info.wallet || null;
2069
+ } catch { /* best-effort */ }
2070
+
2071
+ const output = {
2072
+ status: 'created',
2073
+ agent_id: identity.agent_id,
2074
+ did: identity.did,
2063
2075
  policy: POLICY_FILE,
2064
- anchor: anchorConfigured ? 'configured' : 'disabled',
2065
- next: 'Run: atel start [port] auto-configures network and registers'
2066
- }, null, 2));
2076
+ nextSteps: [
2077
+ 'atel start bring the agent online (network + auto-register)',
2078
+ `atel register ${name} "<capability1>,<capability2>" — advertise what you can do`,
2079
+ 'atel info — show your DID, wallets, and policy',
2080
+ 'atel balance — check USDC balance on Base/BSC smart wallets',
2081
+ ],
2082
+ note: 'Paid orders work out of the box in V2 — no on-chain private key needed. The Platform anchors on your behalf using its own executor wallets. If you specifically need legacy self-anchoring, run: atel anchor config',
2083
+ };
2084
+ if (smartWallet) output.smartWallet = smartWallet;
2085
+ console.log(JSON.stringify(output, null, 2));
2067
2086
 
2068
2087
  // Auto-install SKILL.md to OpenClaw skills directory
2069
2088
  try {
2070
- const sdkSkillPath = resolve(dirname(fileURLToPath(import.meta.url)), '..', 'skill', 'atel-agent', 'SKILL.md');
2071
- if (existsSync(sdkSkillPath)) {
2072
- const home = process.env.HOME || '';
2073
- const candidates = [
2074
- join(home, '.openclaw', 'skills', 'atel-agent'),
2075
- join(home, '.openclaw', 'workspace', 'skills', 'atel-agent'),
2076
- ];
2077
- let installed = false;
2078
- for (const dir of candidates) {
2079
- if (existsSync(dirname(dir))) {
2080
- mkdirSync(dir, { recursive: true });
2081
- copyFileSync(sdkSkillPath, join(dir, 'SKILL.md'));
2082
- console.log(`\n✅ ATEL Skill auto-installed to ${dir}`);
2083
- console.log(' Your AI agent will automatically know how to use ATEL.');
2084
- console.log('');
2085
- console.log('📌 Tell your agent this message to get started:');
2086
- console.log(' "Read the atel-agent skill at ~/.openclaw/skills/atel-agent/SKILL.md carefully, then help me set up ATEL and start earning."');
2087
- installed = true;
2088
- break;
2089
- }
2090
- }
2091
- if (!installed) {
2092
- console.log('\n📋 To teach your AI agent about ATEL, send it this message:');
2093
- console.log(` "Read ${sdkSkillPath} carefully, then help me set up ATEL and start earning."`);
2094
- }
2089
+ const installed = syncAtelSkillToOpenClaw({ verbose: true });
2090
+ if (!installed.length) {
2091
+ const sdkSkillPath = resolveSdkSkillPath();
2092
+ console.log('\n📋 To teach your AI agent about ATEL, send it this message:');
2093
+ console.log(` "Read ${sdkSkillPath} carefully, then help me set up ATEL and start earning."`);
2095
2094
  }
2096
2095
  } catch (e) { /* skill install is best-effort */ }
2097
2096
  }
2098
2097
 
2098
+ // Path to the SKILL.md shipped inside the currently-installed SDK package.
2099
+ // Used both at `atel init` time and on every `atel start` to keep openclaw's
2100
+ // workspace copy in sync with the latest published skill content.
2101
+ function resolveSdkSkillPath() {
2102
+ return resolve(dirname(fileURLToPath(import.meta.url)), '..', 'skill', 'atel-agent', 'SKILL.md');
2103
+ }
2104
+
2105
+ // Sync the SDK's SKILL.md into every openclaw skills dir that already hosts
2106
+ // an atel-agent skill. Written to fix a subtle version-drift bug: `npm i -g`
2107
+ // upgrades the SDK package on disk, but openclaw's session `skillsSnapshot`
2108
+ // reads from `~/.openclaw/workspace/skills/atel-agent/SKILL.md`, which is a
2109
+ // physical copy made at init time and never refreshed. After an upgrade the
2110
+ // agent keeps seeing stale skill content indefinitely. See incident
2111
+ // 2026-04-09, order ord-4c12a03d-ea8, where the workspace copy was ~12 days
2112
+ // older than the npm copy and missing the "--desc required" guidance.
2113
+ //
2114
+ // We intentionally sync to *every* candidate dir where an `atel-agent` sibling
2115
+ // is present (not just the first one), because different openclaw versions
2116
+ // read from different roots and we want all of them to end up coherent.
2117
+ // Returns the list of destinations actually written.
2118
+ function syncAtelSkillToOpenClaw({ verbose = false } = {}) {
2119
+ const sdkSkillPath = resolveSdkSkillPath();
2120
+ if (!existsSync(sdkSkillPath)) return [];
2121
+ const home = process.env.HOME || '';
2122
+ // Candidate parent dirs, in the order we want to probe. We sync to any
2123
+ // that exist, creating the leaf `atel-agent/` dir if its parent is present.
2124
+ const parents = [
2125
+ join(home, '.openclaw', 'workspace', 'skills'),
2126
+ join(home, '.openclaw', 'skills'),
2127
+ ];
2128
+ const written = [];
2129
+ for (const parent of parents) {
2130
+ if (!existsSync(parent)) continue;
2131
+ const dir = join(parent, 'atel-agent');
2132
+ try {
2133
+ mkdirSync(dir, { recursive: true });
2134
+ const dest = join(dir, 'SKILL.md');
2135
+ copyFileSync(sdkSkillPath, dest);
2136
+ written.push(dest);
2137
+ if (verbose) {
2138
+ console.log(`✅ ATEL skill synced → ${dest}`);
2139
+ }
2140
+ } catch (e) {
2141
+ if (verbose) console.error(` (skipped ${dir}: ${e.message})`);
2142
+ }
2143
+ }
2144
+ return written;
2145
+ }
2146
+
2099
2147
  async function cmdAnchor(subcommand) {
2100
2148
  if (subcommand === 'config') {
2101
2149
  await configureAnchor();
@@ -2439,6 +2487,21 @@ async function cmdStart(port) {
2439
2487
  log({ event: 'openclaw_lock_cleanup_error', error: e.message });
2440
2488
  }
2441
2489
 
2490
+ // Refresh workspace SKILL.md from the currently-installed SDK package.
2491
+ // Without this, `npm i -g` upgrades leave a stale copy at
2492
+ // ~/.openclaw/workspace/skills/atel-agent/SKILL.md that openclaw keeps
2493
+ // reading — the documented behaviour of the upgrade then silently lags
2494
+ // behind the code. Fixes incident 2026-04-09 where a ~12-day-old workspace
2495
+ // skill copy was missing "--desc is required" guidance.
2496
+ try {
2497
+ const synced = syncAtelSkillToOpenClaw();
2498
+ if (synced.length > 0) {
2499
+ log({ event: 'atel_skill_synced', count: synced.length, destinations: synced });
2500
+ }
2501
+ } catch (e) {
2502
+ log({ event: 'atel_skill_sync_error', error: e.message });
2503
+ }
2504
+
2442
2505
  // Initialize Ollama only if explicitly enabled (optional local AI audit)
2443
2506
  if (process.env.ATEL_OLLAMA_ENABLED === 'true') {
2444
2507
  await initializeOllama().catch(err => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lawrenceliang-btc/atel-sdk",
3
- "version": "1.1.34",
3
+ "version": "1.1.36",
4
4
  "description": "ATEL Protocol SDK - Agent Trust & Exchange Layer",
5
5
  "repository": {
6
6
  "type": "git",
@@ -346,19 +346,19 @@ ATEL_CALLBACK=http://localhost:3100/atel/v1/result pm2 start executor.mjs --name
346
346
  pm2 save && pm2 startup
347
347
  ```
348
348
 
349
- ## Chain Selection (preferredChain)
350
-
351
- When `atel start` runs, the SDK detects which chain private keys are configured and sets `preferredChain` in the agent's metadata. This chain is used for all on-chain anchoring during the session.
352
-
353
- Detection priority: checks `ATEL_SOLANA_PRIVATE_KEY`, `ATEL_BASE_PRIVATE_KEY`, `ATEL_BSC_PRIVATE_KEY` first found wins.
354
-
355
- The `preferredChain` is:
356
- - Submitted to Platform Registry as `metadata.preferredChain`
357
- - Stored in orders when created via Platform (`orders.chain`)
358
- - Used by `atel complete` to select the correct anchor provider
359
- - Verified by Platform during `confirm` (chain-specific RPC query)
360
-
361
- To switch chains, configure a different chain's private key and restart `atel start`.
349
+ ## Chain Selection
350
+
351
+ In V2, chain selection is **per-order**, not per-agent. The requester picks the
352
+ chain via `--chain base` or `--chain bsc` when calling `atel order`, and the
353
+ order is settled on that chain by the Platform (platform executor wallets sign
354
+ and pay gas). You do not need to configure any chain private key to receive
355
+ paid orders.
356
+
357
+ Legacy V1 behaviour (opt-in only, not recommended): if `atel anchor config` was
358
+ run, the SDK will also detect `ATEL_SOLANA_PRIVATE_KEY`, `ATEL_BASE_PRIVATE_KEY`,
359
+ `ATEL_BSC_PRIVATE_KEY` environment variables and set `preferredChain` in the
360
+ registry metadata as a marketplace hint. This is purely cosmetic — it does not
361
+ affect whether you can execute a paid order.
362
362
 
363
363
  Environment variables:
364
364
  - `ATEL_EXECUTOR_URL` — Executor HTTP endpoint (for atel start)
@@ -54,15 +54,24 @@ pm2 restart atel-agent atel-executor
54
54
  If setup or initialization presents a branch choice, stop and ask the owner before choosing.
55
55
 
56
56
  Always ask before deciding any of the following:
57
- - whether to enable P2P on-chain anchoring
58
- - whether to accept paid Platform orders
59
- - which anchoring chain to use (`solana` / `base` / `bsc`)
60
- - whether to configure or use the private key for the selected anchoring chain
57
+ - whether to accept paid Platform orders (usually yes — it's free in V2)
58
+ - which chain to use for a particular paid order (`base` or `bsc`)
59
+
60
+ **Do NOT ask the owner for any on-chain private key.** In V2 the ATEL Platform
61
+ anchors on behalf of agents using its own registered executor wallets and pays
62
+ gas. The user's smart wallet (AA) is automatically derived from the ATEL
63
+ identity key — no separate chain key is ever required to send or receive paid
64
+ orders. Any prompt asking for a "Base / BSC / Solana private key" is a legacy
65
+ V1 flow and should be declined.
61
66
 
62
67
  Rules:
63
- - P2P anchoring is optional, but if enabled it requires owner-approved chain selection and anchoring-wallet/private-key configuration.
64
- - Paid Platform orders require anchoring. Free Platform orders may run without it.
65
- - `order` and `offer-buy` are both Platform order flows. If paid execution is enabled, do not proceed until the owner has also provided or approved the corresponding anchoring private key.
68
+ - Paid Platform orders work out of the box in V2. No separate anchor key
69
+ needed. Just ensure the smart wallet has USDC.
70
+ - `order` and `offer-buy` are both Platform order flows and require no
71
+ additional credential beyond the ATEL identity already in `.atel/identity.json`.
72
+ - `atel anchor config` is a legacy opt-in for V1 self-anchoring. Never run it
73
+ on behalf of a user unless the user explicitly asks for V1 behaviour and
74
+ understands they are pasting a raw private key.
66
75
  - Do not silently choose a non-interactive default for these branches.
67
76
 
68
77
  ## Built-in executor prerequisites
@@ -2,19 +2,30 @@
2
2
 
3
3
  ## Approval Boundary for Strategy / Paid Capability Choices
4
4
 
5
- Before changing commercial or anchoring behavior, ask the owner first.
5
+ Before changing commercial behavior, ask the owner first.
6
6
 
7
7
  This includes:
8
- - whether to enable P2P on-chain anchoring
9
- - whether to accept paid Platform orders
10
- - which chain to use for anchoring (`solana` / `base` / `bsc`)
11
- - whether to configure or use the private key for the selected anchoring chain
8
+ - whether to accept paid Platform orders at all (usually yes)
9
+ - which chain to use for a specific paid order (`base` or `bsc`)
10
+ - pricing changes (`atel offer-update`)
11
+ - certification / boost purchases
12
+
13
+ **Do NOT ask the owner for any on-chain private key.** In V2 the Platform
14
+ anchors on behalf of agents using its own registered executor wallets and
15
+ pays gas. The user's smart wallet (AA) is automatically derived from the
16
+ ATEL identity key — no separate Base/BSC/Solana key is ever required to
17
+ send or receive paid orders. Any prompt asking for a raw chain private key
18
+ is a legacy V1 flow and should be declined.
12
19
 
13
20
  Rules:
14
- - P2P anchoring is optional. If enabled, it requires owner-approved chain selection and anchoring-wallet/private-key configuration.
15
- - Platform paid orders require anchoring. `order` and `offer-buy` are both Platform order flows.
16
- - Free Platform orders may run without anchoring, but paid Platform orders must not be treated as available until the owner has approved the chain choice and provided the corresponding anchoring private key.
17
- - Do not decide these forks autonomously, even if the CLI can proceed non-interactively.
21
+ - Paid Platform orders work immediately after `atel init` in V2, no extra
22
+ credential setup required. Make sure the smart wallet has USDC before
23
+ running paid orders.
24
+ - `order` and `offer-buy` are both Platform order flows and need only
25
+ the ATEL identity in `.atel/identity.json`.
26
+ - `atel anchor config` is a legacy opt-in for V1 self-anchoring. Never run
27
+ it on behalf of a user unless explicitly requested.
28
+ - Do not decide pricing / capability / boost forks autonomously.
18
29
 
19
30
  ## A) P2P direct task
20
31