xno-skills 2.2.1 → 2.3.1
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/README.md +109 -525
- package/assets/xno-skills-cli.png +0 -0
- package/dist/cjs/banner.d.ts +3 -0
- package/dist/cjs/banner.d.ts.map +1 -0
- package/dist/cjs/banner.js +26 -0
- package/dist/cjs/banner.js.map +1 -0
- package/dist/cjs/cli.js +110 -89
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/mcp.d.ts.map +1 -1
- package/dist/cjs/mcp.js +109 -67
- package/dist/cjs/mcp.js.map +1 -1
- package/dist/cjs/nano-actions.d.ts +26 -10
- package/dist/cjs/nano-actions.d.ts.map +1 -1
- package/dist/cjs/nano-actions.js +55 -6
- package/dist/cjs/nano-actions.js.map +1 -1
- package/dist/cjs/ows.js +1 -1
- package/dist/cjs/qr.d.ts +1 -0
- package/dist/cjs/qr.d.ts.map +1 -1
- package/dist/cjs/qr.js +30 -2
- package/dist/cjs/qr.js.map +1 -1
- package/dist/cjs/rpc.d.ts +13 -0
- package/dist/cjs/rpc.d.ts.map +1 -1
- package/dist/cjs/rpc.js +14 -1
- package/dist/cjs/rpc.js.map +1 -1
- package/dist/cjs/version.d.ts +2 -2
- package/dist/cjs/version.js +1 -1
- package/dist/esm/.xno-mcp/requests.json +8 -8
- package/dist/esm/banner.d.ts +3 -0
- package/dist/esm/banner.d.ts.map +1 -0
- package/dist/esm/banner.js +26 -0
- package/dist/esm/banner.js.map +1 -0
- package/dist/esm/cli.js +110 -89
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/mcp.d.ts.map +1 -1
- package/dist/esm/mcp.js +109 -67
- package/dist/esm/mcp.js.map +1 -1
- package/dist/esm/nano-actions.d.ts +26 -10
- package/dist/esm/nano-actions.d.ts.map +1 -1
- package/dist/esm/nano-actions.js +55 -6
- package/dist/esm/nano-actions.js.map +1 -1
- package/dist/esm/ows.js +1 -1
- package/dist/esm/qr.d.ts +1 -0
- package/dist/esm/qr.d.ts.map +1 -1
- package/dist/esm/qr.js +30 -2
- package/dist/esm/qr.js.map +1 -1
- package/dist/esm/rpc.d.ts +13 -0
- package/dist/esm/rpc.d.ts.map +1 -1
- package/dist/esm/rpc.js +14 -1
- package/dist/esm/rpc.js.map +1 -1
- package/dist/esm/version.d.ts +2 -2
- package/dist/esm/version.js +1 -1
- package/package.json +3 -1
- package/skills/nano-block-lattice-expert/SKILL.md +30 -16
- package/skills/nano-check-balance/SKILL.md +2 -2
- package/skills/nano-convert-units/SKILL.md +26 -138
- package/skills/nano-generate-qr/SKILL.md +4 -4
- package/skills/nano-mcp-wallet/SKILL.md +2 -4
- package/skills/nano-sign-message/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -4,24 +4,24 @@
|
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
[](https://www.typescriptlang.org/)
|
|
6
6
|
|
|
7
|
-
A
|
|
7
|
+
A CLI, MCP server, and AI skills for Nano (XNO). Pairs with [Open Wallet Standard (OWS)](https://github.com/open-wallet-standard/core) for secure key custody.
|
|
8
8
|
|
|
9
9
|

|
|
10
10
|
|
|
11
11
|
## AI Skills
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Built-in skills for AI agents (Claude Code, Cursor, etc.):
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
npx skills add CasualSecurityInc/xno-skills
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
Available skills
|
|
19
|
+
Available skills:
|
|
20
20
|
- `nano-check-balance`: Check balance/pending via Nano node RPC.
|
|
21
21
|
- `nano-convert-units`: High-precision unit conversion reference.
|
|
22
22
|
- `nano-create-wallet`: Wallet creation/import guidance (BIP39/Legacy support).
|
|
23
23
|
- `nano-generate-qr`: Terminal-friendly Nano payment QR codes.
|
|
24
|
-
- `nano-mcp-wallet`: Use `xno-mcp` as a private
|
|
24
|
+
- `nano-mcp-wallet`: Use `xno-mcp` as a private "wallet" custody blackbox.
|
|
25
25
|
- `nano-request-payment`: Request XNO from operator (payment request workflow).
|
|
26
26
|
- `nano-return-funds`: Return XNO to sender safely.
|
|
27
27
|
- `nano-sign-message`: Sign off-chain messages (NOMS/ORIS-001).
|
|
@@ -29,70 +29,109 @@ Available skills (v2.0.0+):
|
|
|
29
29
|
- `nano-verify-message`: Verify off-chain message signatures.
|
|
30
30
|
- `nano-block-lattice-expert`: Deep protocol wisdom and 2026 operational facts.
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
If you have old skills installed without the `nano-` prefix, you should remove them and re-add the repo to avoid name collisions and "ghost" skills:
|
|
32
|
+
## CLI
|
|
35
33
|
|
|
36
34
|
```bash
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
# 2. Add the new prefixed skills
|
|
41
|
-
npx skills add -g CasualSecurityInc/xno-skills
|
|
35
|
+
npm install -g xno-skills
|
|
36
|
+
xno-skills --help
|
|
42
37
|
```
|
|
43
38
|
|
|
44
|
-
|
|
39
|
+
### Wallet Operations
|
|
40
|
+
|
|
41
|
+
| Command | Description |
|
|
42
|
+
|---|---|
|
|
43
|
+
| `wallets` | List wallets that have Nano accounts |
|
|
44
|
+
| `balance --wallet <name>` | Show balance and pending amount |
|
|
45
|
+
| `receive --wallet <name>` | Receive pending blocks |
|
|
46
|
+
| `send --wallet <name> --to <addr> --amount-xno <n>` | Send Nano |
|
|
47
|
+
| `change-rep --wallet <name> --representative <addr>` | Change representative |
|
|
48
|
+
| `submit-block --wallet <name> --tx-hex <hex> --subtype <type>` | Sign and submit a prepared block hex |
|
|
49
|
+
| `history --wallet <name>` | Show transaction history |
|
|
50
|
+
|
|
51
|
+
### Utilities
|
|
52
|
+
|
|
53
|
+
| Command | Description |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `info --wallet <name>` or `--address <addr>` | Account state, representative, weight |
|
|
56
|
+
| `convert <amount> <from>` | Convert units (xno, raw, mnano, knano) |
|
|
57
|
+
| `qr <address>` | Generate QR code (ASCII or `--format svg`) |
|
|
58
|
+
| `validate <input>` | Validate a Nano address |
|
|
59
|
+
|
|
60
|
+
### Cryptography & Signing
|
|
45
61
|
|
|
46
|
-
|
|
62
|
+
| Command | Description |
|
|
63
|
+
|---|---|
|
|
64
|
+
| `sign <message> --key <hex>` | Sign a NOMS message with a private key |
|
|
65
|
+
| `verify <address> <message> <signature>` | Verify a NOMS message signature |
|
|
66
|
+
|
|
67
|
+
### Advanced & RPC
|
|
68
|
+
|
|
69
|
+
| Command | Description |
|
|
70
|
+
|---|---|
|
|
71
|
+
| `rpc account-balance <address>` | Fetch balance from a Nano node |
|
|
72
|
+
| `rpc receivable <address>` | List receivable blocks |
|
|
73
|
+
| `rpc account-info <address>` | Fetch account info |
|
|
74
|
+
| `rpc probe-caps [url]` | Probe node capabilities |
|
|
75
|
+
| `block send -a <addr> -t <addr> --amount-xno <n>` | Build unsigned send block |
|
|
76
|
+
| `block receive`, `block change` | Build unsigned receive/change blocks |
|
|
77
|
+
|
|
78
|
+
### System
|
|
79
|
+
|
|
80
|
+
| Command | Description |
|
|
81
|
+
|---|---|
|
|
82
|
+
| `mcp` | Start the MCP server |
|
|
83
|
+
|
|
84
|
+
All commands support `-j` / `--json` for machine-readable output.
|
|
85
|
+
|
|
86
|
+
Wallet lifecycle (create, import, rename, delete) is managed by [OWS](https://github.com/open-wallet-standard/core). `xno-skills` bundles OWS as a dependency — no separate install needed. See the [OWS quick-start](https://openwallet.sh/#quickstart) for terminal usage, or install OWS agent skills with `npx skills add open-wallet-standard/core@ows`.
|
|
87
|
+
|
|
88
|
+
## MCP Server
|
|
47
89
|
|
|
48
|
-
|
|
90
|
+
Exposes Nano wallet functions as tools for AI agents (Claude Desktop, Cursor, Codex, etc.).
|
|
49
91
|
|
|
50
92
|
```json
|
|
51
93
|
{
|
|
52
94
|
"mcpServers": {
|
|
53
95
|
"xno": {
|
|
54
96
|
"command": "npx",
|
|
55
|
-
"args": ["-y", "xno-skills@latest", "xno-mcp"]
|
|
97
|
+
"args": ["-y", "-p", "xno-skills@latest", "xno-mcp"]
|
|
56
98
|
}
|
|
57
99
|
}
|
|
58
100
|
}
|
|
59
101
|
```
|
|
60
102
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
All examples run the MCP server via `npx` (swap `@latest` for a pinned version if you prefer).
|
|
94
|
-
|
|
95
|
-
### Codex
|
|
103
|
+
### Tools
|
|
104
|
+
|
|
105
|
+
| Tool | Description |
|
|
106
|
+
|---|---|
|
|
107
|
+
| `wallets` | List OWS wallets and their Nano addresses |
|
|
108
|
+
| `address` | Get the Nano address for a wallet account index |
|
|
109
|
+
| `balance` | Check confirmed balance and pending |
|
|
110
|
+
| `receive` | Receive pending blocks (handles open automatically) |
|
|
111
|
+
| `send` | Send XNO (max per tx configurable via `config_set`) |
|
|
112
|
+
| `change_rep` | Change the representative for a wallet |
|
|
113
|
+
| `submit_block` | Broadcast a pre-signed block hex |
|
|
114
|
+
| `history` | View on-chain transaction history |
|
|
115
|
+
| `info` | Account state and representative for any address |
|
|
116
|
+
| `convert_units` | High-precision unit conversion |
|
|
117
|
+
| `validate_address` | Offline address validation |
|
|
118
|
+
| `rpc_account_balance` | Direct RPC balance check for any address |
|
|
119
|
+
| `generate_qr` | Generate ASCII or SVG QR codes |
|
|
120
|
+
| `sign_message` / `verify_message` | Off-chain message signing (NOMS) |
|
|
121
|
+
| `ows_health_check` | Verify OWS wallet daemon is reachable |
|
|
122
|
+
| `payment_request_create` | Create a tracked payment request |
|
|
123
|
+
| `payment_request_list` | List payment requests |
|
|
124
|
+
| `payment_request_status` | Check payment request status |
|
|
125
|
+
| `payment_request_receive` | Receive funds for a payment request |
|
|
126
|
+
| `payment_request_refund` | Refund a payment request |
|
|
127
|
+
| `config_get` / `config_set` | Manage RPC URL, representative, spending cap |
|
|
128
|
+
|
|
129
|
+
> **Compatibility aliases**: `wallet_list`, `wallet_balance`, `wallet_receive`, `wallet_send`, `wallet_history` map to the canonical tools above.
|
|
130
|
+
|
|
131
|
+
### Client Setup Examples
|
|
132
|
+
|
|
133
|
+
<details>
|
|
134
|
+
<summary>Codex</summary>
|
|
96
135
|
|
|
97
136
|
```bash
|
|
98
137
|
codex mcp add xno \
|
|
@@ -100,10 +139,10 @@ codex mcp add xno \
|
|
|
100
139
|
-c 'sandbox_permissions=["network-access"]' \
|
|
101
140
|
-- npx -y -p xno-skills@latest xno-mcp
|
|
102
141
|
```
|
|
142
|
+
</details>
|
|
103
143
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
Add via Claude Desktop: Settings -> Developer -> Edit Config.
|
|
144
|
+
<details>
|
|
145
|
+
<summary>Claude Desktop (<code>claude_desktop_config.json</code>)</summary>
|
|
107
146
|
|
|
108
147
|
```json
|
|
109
148
|
{
|
|
@@ -115,8 +154,10 @@ Add via Claude Desktop: Settings -> Developer -> Edit Config.
|
|
|
115
154
|
}
|
|
116
155
|
}
|
|
117
156
|
```
|
|
157
|
+
</details>
|
|
118
158
|
|
|
119
|
-
|
|
159
|
+
<details>
|
|
160
|
+
<summary>OpenCode (<code>opencode.jsonc</code>)</summary>
|
|
120
161
|
|
|
121
162
|
```jsonc
|
|
122
163
|
{
|
|
@@ -130,8 +171,10 @@ Add via Claude Desktop: Settings -> Developer -> Edit Config.
|
|
|
130
171
|
}
|
|
131
172
|
}
|
|
132
173
|
```
|
|
174
|
+
</details>
|
|
133
175
|
|
|
134
|
-
|
|
176
|
+
<details>
|
|
177
|
+
<summary>Gemini CLI (<code>settings.json</code>)</summary>
|
|
135
178
|
|
|
136
179
|
```json
|
|
137
180
|
{
|
|
@@ -143,8 +186,10 @@ Add via Claude Desktop: Settings -> Developer -> Edit Config.
|
|
|
143
186
|
}
|
|
144
187
|
}
|
|
145
188
|
```
|
|
189
|
+
</details>
|
|
146
190
|
|
|
147
|
-
|
|
191
|
+
<details>
|
|
192
|
+
<summary>VS Code (<code>.vscode/mcp.json</code>)</summary>
|
|
148
193
|
|
|
149
194
|
```json
|
|
150
195
|
{
|
|
@@ -157,486 +202,25 @@ Add via Claude Desktop: Settings -> Developer -> Edit Config.
|
|
|
157
202
|
}
|
|
158
203
|
}
|
|
159
204
|
```
|
|
205
|
+
</details>
|
|
160
206
|
|
|
161
|
-
##
|
|
162
|
-
|
|
163
|
-
Install globally or use with `npx`:
|
|
164
|
-
|
|
165
|
-
```bash
|
|
166
|
-
# Install globally
|
|
167
|
-
npm install -g xno-skills
|
|
168
|
-
|
|
169
|
-
# Or use with npx
|
|
170
|
-
npx xno-skills --help
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### Wallet Discovery
|
|
174
|
-
|
|
175
|
-
Wallet lifecycle (create, import, rename, delete) is managed by [Open Wallet Standard (OWS)](https://github.com/open-wallet-standard/core). Use the `nano-create-wallet` skill or the OWS skill for that.
|
|
176
|
-
|
|
177
|
-
> **Note:** `xno-skills` bundles OWS as an npm dependency — you do **not** need to install it separately. If you want to manage wallets directly from the terminal (outside of an agent), the [OWS quick-start guide](https://openwallet.sh/#quickstart) explains how. To install OWS agent skills, run:
|
|
178
|
-
> ```bash
|
|
179
|
-
> npx skills add open-wallet-standard/core@ows
|
|
180
|
-
> ```
|
|
181
|
-
|
|
182
|
-
Once you have an OWS wallet, use these commands to interact with it on Nano:
|
|
183
|
-
|
|
184
|
-
```bash
|
|
185
|
-
# List OWS wallets and their Nano addresses
|
|
186
|
-
xno-skills wallets
|
|
187
|
-
|
|
188
|
-
# Get the Nano address for a specific wallet and account index
|
|
189
|
-
xno-skills address --wallet my-wallet --index 0
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
#### Restore from mnemonic
|
|
193
|
-
|
|
194
|
-
```bash
|
|
195
|
-
# Safer import via stdin (recommended)
|
|
196
|
-
echo "word1 word2 ... word24" | xno-skills wallet from-mnemonic --stdin --json
|
|
197
|
-
|
|
198
|
-
# JSON output
|
|
199
|
-
xno-skills wallet from-mnemonic --stdin --json
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
#### Probe mnemonic ambiguity (24-word)
|
|
203
|
-
|
|
204
|
-
If you have a specific Nano RPC endpoint you want to use, you can set `NANO_RPC_URL`. Otherwise, it will automatically use public zero-config nodes:
|
|
205
|
-
|
|
206
|
-
```bash
|
|
207
|
-
echo "word1 word2 ... word24" | xno-skills wallet probe-mnemonic --stdin --json
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### Convert Units
|
|
211
|
-
|
|
212
|
-
```bash
|
|
213
|
-
# Convert XNO to raw
|
|
214
|
-
xno-skills convert 1.5 xno --to raw
|
|
215
|
-
|
|
216
|
-
# Convert raw to XNO
|
|
217
|
-
xno-skills convert 1500000000000000000000000000000 raw --to xno
|
|
218
|
-
|
|
219
|
-
# Convert between units
|
|
220
|
-
xno-skills convert 1 mnano --to knano
|
|
221
|
-
|
|
222
|
-
# JSON output
|
|
223
|
-
xno-skills convert 1 xno --to raw --json
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
Supported units:
|
|
227
|
-
- `xno` or `nano` - Nano (10^30 raw)
|
|
228
|
-
- `knano` - Kilo-nano (10^27 raw)
|
|
229
|
-
- `mnano` - Mega-nano (10^24 raw)
|
|
230
|
-
- `raw` - Base unit
|
|
231
|
-
|
|
232
|
-
### Generate QR Codes
|
|
233
|
-
|
|
234
|
-
```bash
|
|
235
|
-
# QR code for address
|
|
236
|
-
xno-skills qr nano_1abc123...
|
|
237
|
-
|
|
238
|
-
# QR code with amount
|
|
239
|
-
xno-skills qr nano_1abc123... --amount 1.5
|
|
240
|
-
|
|
241
|
-
# JSON output
|
|
242
|
-
xno-skills qr nano_1abc123... --json
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
### Validate Addresses
|
|
246
|
-
|
|
247
|
-
```bash
|
|
248
|
-
xno-skills validate nano_1abc123...
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
### RPC (balance/pending)
|
|
252
|
-
|
|
253
|
-
Check balance using built-in public nodes:
|
|
254
|
-
|
|
255
|
-
```bash
|
|
256
|
-
xno-skills rpc account-balance nano_1abc123... --json --xno
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
Or override with a specific URL:
|
|
260
|
-
|
|
261
|
-
```bash
|
|
262
|
-
xno-skills rpc account-balance nano_1abc123... --url "http://127.0.0.1:7076" --json --xno
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
## API Reference
|
|
266
|
-
|
|
267
|
-
### Seed Generation
|
|
268
|
-
|
|
269
|
-
#### `generateMnemonic(wordCount = 24): string`
|
|
270
|
-
|
|
271
|
-
Generate a BIP39 mnemonic (12/15/18/21/24 words).
|
|
272
|
-
|
|
273
|
-
```typescript
|
|
274
|
-
import { generateMnemonic } from 'xno-skills';
|
|
275
|
-
|
|
276
|
-
const mnemonic = generateMnemonic(24);
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
#### `generateSeed(): string`
|
|
280
|
-
|
|
281
|
-
Generate a cryptographically secure 32-byte seed (256 bits).
|
|
282
|
-
|
|
283
|
-
```typescript
|
|
284
|
-
import { generateSeed } from 'xno-skills';
|
|
285
|
-
|
|
286
|
-
const seed = generateSeed();
|
|
287
|
-
// Returns: "0123456789abcdef..." (64 hex characters)
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
#### `seedToMnemonic(seed: string): string`
|
|
291
|
-
|
|
292
|
-
Convert a hex-encoded seed to a BIP39 mnemonic phrase.
|
|
293
|
-
|
|
294
|
-
```typescript
|
|
295
|
-
import { seedToMnemonic } from 'xno-skills';
|
|
296
|
-
|
|
297
|
-
const mnemonic = seedToMnemonic(seed);
|
|
298
|
-
// Returns: "word1 word2 word3 ... word24"
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
#### `mnemonicToSeed(mnemonic: string): string`
|
|
302
|
-
|
|
303
|
-
Convert a BIP39 mnemonic phrase back to its underlying entropy (hex).
|
|
304
|
-
|
|
305
|
-
Note: this is **not** the BIP39 PBKDF2 “seed”; it’s the raw entropy the mnemonic encodes.
|
|
306
|
-
|
|
307
|
-
```typescript
|
|
308
|
-
import { mnemonicToSeed } from 'xno-skills';
|
|
309
|
-
|
|
310
|
-
const seed = mnemonicToSeed(mnemonic);
|
|
311
|
-
// Returns: "0123456789abcdef..." (64 hex characters)
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
#### `mnemonicToBIP39Seed(mnemonic: string, passphrase?: string): string`
|
|
315
|
-
|
|
316
|
-
Convert a BIP39 mnemonic (+ optional passphrase) to the PBKDF2 “seed” hex used for HD derivation.
|
|
317
|
-
|
|
318
|
-
#### `validateMnemonic(mnemonic: string): boolean`
|
|
319
|
-
|
|
320
|
-
Validate a BIP39 mnemonic phrase.
|
|
321
|
-
|
|
322
|
-
```typescript
|
|
323
|
-
import { validateMnemonic } from 'xno-skills';
|
|
324
|
-
|
|
325
|
-
const isValid = validateMnemonic(mnemonic);
|
|
326
|
-
// Returns: true or false
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
### Legacy Address Derivation
|
|
330
|
-
|
|
331
|
-
#### `deriveAddressLegacy(seed: string, index: number): LegacyAddressResult`
|
|
332
|
-
|
|
333
|
-
Derive a Nano address from a seed using the legacy derivation method.
|
|
334
|
-
|
|
335
|
-
```typescript
|
|
336
|
-
import { deriveAddressLegacy } from 'xno-skills';
|
|
337
|
-
|
|
338
|
-
const result = deriveAddressLegacy(seed, 0);
|
|
339
|
-
// Returns: { address, privateKey, publicKey }
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
#### `derivePrivateKeyLegacy(seed: string, index: number): string`
|
|
343
|
-
|
|
344
|
-
Derive a private key from a seed at the specified index.
|
|
345
|
-
|
|
346
|
-
```typescript
|
|
347
|
-
import { derivePrivateKeyLegacy } from 'xno-skills';
|
|
348
|
-
|
|
349
|
-
const privateKey = derivePrivateKeyLegacy(seed, 0);
|
|
350
|
-
// Returns: "0123456789abcdef..." (64 hex characters)
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
#### `derivePublicKeyLegacy(privateKey: string): string`
|
|
207
|
+
## Library
|
|
354
208
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
```typescript
|
|
358
|
-
import { derivePublicKeyLegacy } from 'xno-skills';
|
|
359
|
-
|
|
360
|
-
const publicKey = derivePublicKeyLegacy(privateKey);
|
|
361
|
-
// Returns: "0123456789abcdef..." (64 hex characters)
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
#### `publicKeyToAddress(publicKey: string): string`
|
|
365
|
-
|
|
366
|
-
Convert a public key to a Nano address.
|
|
367
|
-
|
|
368
|
-
```typescript
|
|
369
|
-
import { publicKeyToAddress } from 'xno-skills';
|
|
370
|
-
|
|
371
|
-
const address = publicKeyToAddress(publicKey);
|
|
372
|
-
// Returns: "nano_1abc123..."
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
### BIP44 Address Derivation
|
|
376
|
-
|
|
377
|
-
#### `deriveAddressBIP44(mnemonic: string, index: number, passphrase?: string): BIP44AddressResult`
|
|
378
|
-
|
|
379
|
-
Derive a Nano address from a mnemonic using BIP44 path `m/44'/165'/[index]'`.
|
|
380
|
-
|
|
381
|
-
```typescript
|
|
382
|
-
import { deriveAddressBIP44 } from 'xno-skills';
|
|
383
|
-
|
|
384
|
-
const result = deriveAddressBIP44(mnemonic, 0);
|
|
385
|
-
// Returns: { address, privateKey, publicKey }
|
|
386
|
-
|
|
387
|
-
// With optional passphrase
|
|
388
|
-
const result = deriveAddressBIP44(mnemonic, 0, 'my-passphrase');
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
#### `derivePrivateKeyBIP44(mnemonic: string, index: number, passphrase?: string): string`
|
|
392
|
-
|
|
393
|
-
Derive a private key from a mnemonic using BIP44.
|
|
394
|
-
|
|
395
|
-
```typescript
|
|
396
|
-
import { derivePrivateKeyBIP44 } from 'xno-skills';
|
|
397
|
-
|
|
398
|
-
const privateKey = derivePrivateKeyBIP44(mnemonic, 0);
|
|
399
|
-
// Returns: "0123456789abcdef..." (64 hex characters)
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
#### `derivePublicKeyBIP44(privateKey: string): string`
|
|
403
|
-
|
|
404
|
-
Derive a public key from a BIP44-derived private key.
|
|
405
|
-
|
|
406
|
-
```typescript
|
|
407
|
-
import { derivePublicKeyBIP44 } from 'xno-skills';
|
|
408
|
-
|
|
409
|
-
const publicKey = derivePublicKeyBIP44(privateKey);
|
|
410
|
-
// Returns: "0123456789abcdef..." (64 hex characters)
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
#### `publicKeyToAddressBIP44(publicKey: string): string`
|
|
414
|
-
|
|
415
|
-
Convert a BIP44-derived public key to a Nano address.
|
|
416
|
-
|
|
417
|
-
```typescript
|
|
418
|
-
import { publicKeyToAddressBIP44 } from 'xno-skills';
|
|
419
|
-
|
|
420
|
-
const address = publicKeyToAddressBIP44(publicKey);
|
|
421
|
-
// Returns: "nano_1abc123..."
|
|
422
|
-
```
|
|
423
|
-
|
|
424
|
-
#### `validateMnemonicBIP44(mnemonic: string): boolean`
|
|
425
|
-
|
|
426
|
-
Validate a BIP39 mnemonic phrase for BIP44 usage.
|
|
427
|
-
|
|
428
|
-
```typescript
|
|
429
|
-
import { validateMnemonicBIP44 } from 'xno-skills';
|
|
430
|
-
|
|
431
|
-
const isValid = validateMnemonicBIP44(mnemonic);
|
|
432
|
-
// Returns: true or false
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
#### `mnemonicToBIP39Seed(mnemonic: string, passphrase?: string): string`
|
|
436
|
-
|
|
437
|
-
Convert a mnemonic to a BIP39 seed (512-bit).
|
|
438
|
-
|
|
439
|
-
```typescript
|
|
440
|
-
import { mnemonicToBIP39Seed } from 'xno-skills';
|
|
441
|
-
|
|
442
|
-
const seed = mnemonicToBIP39Seed(mnemonic);
|
|
443
|
-
// Returns: "0123456789abcdef..." (128 hex characters)
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
### Address Validation
|
|
447
|
-
|
|
448
|
-
#### `validateAddress(address: string): ValidateAddressResult`
|
|
449
|
-
|
|
450
|
-
Validate a Nano address and extract the public key.
|
|
451
|
-
|
|
452
|
-
```typescript
|
|
453
|
-
import { validateAddress } from 'xno-skills';
|
|
454
|
-
|
|
455
|
-
const result = validateAddress('nano_1abc123...');
|
|
456
|
-
// Returns: { valid: true, publicKey: "..." }
|
|
457
|
-
// Or: { valid: false, error: "Invalid prefix..." }
|
|
458
|
-
```
|
|
459
|
-
|
|
460
|
-
### Unit Conversion
|
|
461
|
-
|
|
462
|
-
#### `nanoToRaw(nano: string): string`
|
|
463
|
-
|
|
464
|
-
Convert Nano (XNO) to raw units.
|
|
465
|
-
|
|
466
|
-
```typescript
|
|
467
|
-
import { nanoToRaw } from 'xno-skills';
|
|
468
|
-
|
|
469
|
-
const raw = nanoToRaw('1.5');
|
|
470
|
-
// Returns: "1500000000000000000000000000000"
|
|
471
|
-
```
|
|
472
|
-
|
|
473
|
-
#### `rawToNano(raw: string, decimals?: number): string`
|
|
474
|
-
|
|
475
|
-
Convert raw units to Nano (XNO).
|
|
476
|
-
|
|
477
|
-
```typescript
|
|
478
|
-
import { rawToNano } from 'xno-skills';
|
|
479
|
-
|
|
480
|
-
const nano = rawToNano('1500000000000000000000000000000');
|
|
481
|
-
// Returns: "1.5"
|
|
482
|
-
|
|
483
|
-
// With specific decimal places
|
|
484
|
-
const nano = rawToNano(raw, 6);
|
|
485
|
-
// Returns: "1.500000"
|
|
486
|
-
```
|
|
487
|
-
|
|
488
|
-
#### `formatNano(raw: string): string`
|
|
489
|
-
|
|
490
|
-
Format raw units as Nano with full precision.
|
|
491
|
-
|
|
492
|
-
```typescript
|
|
493
|
-
import { formatNano } from 'xno-skills';
|
|
494
|
-
|
|
495
|
-
const formatted = formatNano('1500000000000000000000000000000');
|
|
496
|
-
// Returns: "1.5"
|
|
497
|
-
```
|
|
498
|
-
|
|
499
|
-
#### `knanoToRaw(knano: string): string`
|
|
500
|
-
|
|
501
|
-
Convert kilo-nano to raw units.
|
|
502
|
-
|
|
503
|
-
```typescript
|
|
504
|
-
import { knanoToRaw } from 'xno-skills';
|
|
505
|
-
|
|
506
|
-
const raw = knanoToRaw('1.5');
|
|
507
|
-
// Returns: "1500000000000000000000000000000000"
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
#### `mnanoToRaw(mnano: string): string`
|
|
511
|
-
|
|
512
|
-
Convert mega-nano to raw units.
|
|
513
|
-
|
|
514
|
-
```typescript
|
|
515
|
-
import { mnanoToRaw } from 'xno-skills';
|
|
516
|
-
|
|
517
|
-
const raw = mnanoToRaw('1.5');
|
|
518
|
-
// Returns: "1500000000000000000000000000000000000"
|
|
519
|
-
```
|
|
520
|
-
|
|
521
|
-
### Cryptographic Functions
|
|
522
|
-
|
|
523
|
-
#### `blake2b256(data: Uint8Array): Uint8Array`
|
|
524
|
-
|
|
525
|
-
Compute BLAKE2b-256 hash (32 bytes).
|
|
526
|
-
|
|
527
|
-
```typescript
|
|
528
|
-
import { blake2b256 } from 'xno-skills';
|
|
529
|
-
|
|
530
|
-
const hash = blake2b256(new TextEncoder().encode('hello'));
|
|
531
|
-
// Returns: Uint8Array(32)
|
|
532
|
-
```
|
|
533
|
-
|
|
534
|
-
#### `blake2b512(data: Uint8Array): Uint8Array`
|
|
535
|
-
|
|
536
|
-
Compute BLAKE2b-512 hash (64 bytes).
|
|
537
|
-
|
|
538
|
-
```typescript
|
|
539
|
-
import { blake2b512 } from 'xno-skills';
|
|
540
|
-
|
|
541
|
-
const hash = blake2b512(new TextEncoder().encode('hello'));
|
|
542
|
-
// Returns: Uint8Array(64)
|
|
543
|
-
```
|
|
544
|
-
|
|
545
|
-
#### `blake2b256Hex(data: Uint8Array): string`
|
|
546
|
-
|
|
547
|
-
Compute BLAKE2b-256 hash and return as hex string.
|
|
548
|
-
|
|
549
|
-
```typescript
|
|
550
|
-
import { blake2b256Hex } from 'xno-skills';
|
|
551
|
-
|
|
552
|
-
const hash = blake2b256Hex(new TextEncoder().encode('hello'));
|
|
553
|
-
// Returns: "abc123..." (64 hex characters)
|
|
554
|
-
```
|
|
555
|
-
|
|
556
|
-
### Base32 Encoding
|
|
557
|
-
|
|
558
|
-
#### `base32Encode(bytes: Uint8Array): string`
|
|
559
|
-
|
|
560
|
-
Encode bytes to Nano's Base32 format.
|
|
561
|
-
|
|
562
|
-
```typescript
|
|
563
|
-
import { base32Encode } from 'xno-skills';
|
|
564
|
-
|
|
565
|
-
const encoded = base32Encode(new Uint8Array([0x00, 0xff]));
|
|
566
|
-
// Returns: "1z"
|
|
567
|
-
```
|
|
568
|
-
|
|
569
|
-
#### `base32Decode(str: string): Uint8Array`
|
|
570
|
-
|
|
571
|
-
Decode Nano's Base32 format to bytes.
|
|
572
|
-
|
|
573
|
-
```typescript
|
|
574
|
-
import { base32Decode } from 'xno-skills';
|
|
575
|
-
|
|
576
|
-
const bytes = base32Decode('1z');
|
|
577
|
-
// Returns: Uint8Array([0x00, 0xff])
|
|
578
|
-
```
|
|
579
|
-
|
|
580
|
-
### QR Code Generation
|
|
581
|
-
|
|
582
|
-
#### `generateAsciiQr(address: string, amount?: number): Promise<string>`
|
|
583
|
-
|
|
584
|
-
Generate an ASCII QR code for a Nano address.
|
|
585
|
-
|
|
586
|
-
```typescript
|
|
587
|
-
import { generateAsciiQr } from 'xno-skills';
|
|
588
|
-
|
|
589
|
-
const qr = await generateAsciiQr('nano_1abc123...');
|
|
590
|
-
console.log(qr);
|
|
591
|
-
|
|
592
|
-
// With amount
|
|
593
|
-
const qr = await generateAsciiQr('nano_1abc123...', 1.5);
|
|
594
|
-
```
|
|
209
|
+
For using `xno-skills` as a TypeScript library, see [LIBRARY.md](./LIBRARY.md).
|
|
595
210
|
|
|
596
211
|
## Security Notes
|
|
597
212
|
|
|
598
|
-
**
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
2. **Store seeds securely.** Use hardware wallets, encrypted storage, or offline backup methods. Never store seeds in plain text files, cloud storage, or version control.
|
|
603
|
-
|
|
604
|
-
3. **Use environment variables for seeds in development.** Never hardcode seeds in your source code.
|
|
605
|
-
|
|
606
|
-
4. **BIP44 vs Legacy derivation.** This library supports both:
|
|
607
|
-
- **Legacy**: Uses Blake2b-based path derivation (original Nano method)
|
|
608
|
-
- **BIP44**: Standard HD wallet derivation path `m/44'/165'/[index]'`
|
|
609
|
-
|
|
610
|
-
Choose the method compatible with your existing wallet. Most Nano wallets use legacy derivation.
|
|
611
|
-
|
|
612
|
-
5. **Mnemonic phrases.** When using BIP44, the mnemonic phrase is the master key. Protect it as carefully as a seed.
|
|
613
|
-
|
|
614
|
-
6. **Passphrase protection.** BIP44 supports optional passphrases for additional security. A passphrase acts as a "25th word" - even if someone obtains your mnemonic, they cannot access funds without the passphrase.
|
|
615
|
-
|
|
616
|
-
7. **Address validation.** Always validate addresses before sending funds. Nano addresses include a checksum to catch typos.
|
|
617
|
-
|
|
618
|
-
8. **Unit precision.** Nano uses 30 decimal places. Always use string-based conversion functions to avoid floating-point precision errors.
|
|
213
|
+
- **Never share your seed or private keys.** Anyone with access can fully control your wallet.
|
|
214
|
+
- **Store seeds securely.** Use hardware wallets or encrypted storage — never in plain text or version control.
|
|
215
|
+
- **Address validation.** Always validate addresses before sending. Nano addresses include checksums.
|
|
216
|
+
- **Unit precision.** Nano uses 30 decimal places. Always use string-based conversion to avoid floating-point errors.
|
|
619
217
|
|
|
620
218
|
## Development
|
|
621
219
|
|
|
622
220
|
```bash
|
|
623
|
-
# Install dependencies
|
|
624
221
|
npm install
|
|
625
|
-
|
|
626
|
-
# Run unit tests
|
|
627
222
|
npm test
|
|
628
|
-
|
|
629
|
-
# Run integration tests
|
|
630
|
-
npx vitest run test/integration.test.ts
|
|
631
|
-
|
|
632
|
-
# Build
|
|
633
223
|
npm run build
|
|
634
|
-
|
|
635
|
-
# Build ESM
|
|
636
|
-
npm run build:esm
|
|
637
|
-
|
|
638
|
-
# Build CJS
|
|
639
|
-
npm run build:cjs
|
|
640
224
|
```
|
|
641
225
|
|
|
642
226
|
## Releasing
|