@unicitylabs/sphere-sdk 0.7.1-dev.2 → 0.7.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 CHANGED
@@ -32,91 +32,19 @@ Choose your platform:
32
32
  |----------|-------|----------|----------|
33
33
  | **Browser** | [QUICKSTART-BROWSER.md](docs/QUICKSTART-BROWSER.md) | SDK only | IPFS sync (built-in) |
34
34
  | **Node.js** | [QUICKSTART-NODEJS.md](docs/QUICKSTART-NODEJS.md) | SDK + `ws` | IPFS sync (built-in) |
35
- | **CLI** | See below | SDK + `tsx` | - |
35
+ | **CLI** | [@unicity-sphere/cli](https://github.com/unicity-sphere/sphere-cli) | Separate package | - |
36
36
  | **dApp integration** | [CONNECT.md](docs/CONNECT.md) | SDK only | Sphere extension |
37
37
 
38
38
  ## CLI (Command Line Interface)
39
39
 
40
- The SDK includes a CLI for quick testing and development:
40
+ The CLI has moved to a dedicated package: [`@unicity-sphere/cli`](https://github.com/unicity-sphere/sphere-cli).
41
41
 
42
42
  ```bash
43
- # Show help
44
- npm run cli -- --help
45
-
46
- # Initialize new wallet on testnet
47
- npm run cli -- init --network testnet
48
-
49
- # Initialize with nametag (mints token on-chain)
50
- npm run cli -- init --network testnet --nametag alice
51
-
52
- # Import existing wallet
53
- npm run cli -- init --mnemonic "your 24 words here"
54
-
55
- # Check wallet status
56
- npm run cli -- status
57
-
58
- # Check balance
59
- npm run cli -- balance
60
-
61
- # Fetch pending transfers and finalize unconfirmed tokens
62
- npm run cli -- balance --finalize
63
-
64
- # Check for incoming transfers
65
- npm run cli -- receive
66
-
67
- # Check for incoming transfers and finalize unconfirmed tokens
68
- npm run cli -- receive --finalize
69
-
70
- # Send tokens (instant mode, default)
71
- npm run cli -- send @alice 1 UCT --instant
72
-
73
- # Send tokens (conservative mode — collect all proofs first)
74
- npm run cli -- send @alice 1 UCT --conservative
75
-
76
- # Request test tokens from faucet
77
- npm run cli -- topup
78
-
79
- # Register nametag
80
- npm run cli -- nametag myname
81
-
82
- # Show transaction history
83
- npm run cli -- history 10
84
-
85
- # Verify tokens against aggregator (detect spent tokens)
86
- npm run cli -- verify-balance
43
+ npm install -g @unicity-sphere/cli
44
+ sphere --help
87
45
  ```
88
46
 
89
- ### Available CLI Commands
90
-
91
- | Category | Command | Description |
92
- |----------|---------|-------------|
93
- | **Wallet** | `init [--network <net>] [--mnemonic "<words>"] [--nametag <name>]` | Create or import wallet |
94
- | | `status` | Show wallet identity |
95
- | | `config` | Show/set configuration |
96
- | **Profiles** | `wallet list` | List all wallet profiles |
97
- | | `wallet use <name>` | Switch to a wallet profile |
98
- | | `wallet create <name> [--network <net>]` | Create a new wallet profile |
99
- | | `wallet delete <name>` | Delete a wallet profile |
100
- | | `wallet current` | Show current wallet profile |
101
- | **Balance** | `balance [--finalize]` | Show L3 token balance (--finalize: fetch pending + resolve) |
102
- | | `tokens` | List all tokens with details |
103
- | | `l1-balance` | Show L1 (ALPHA) balance |
104
- | | `topup [<amount> <symbol>]` | Request test tokens from faucet |
105
- | | `verify-balance [--remove] [-v]` | Verify tokens against aggregator |
106
- | **Transfers** | `send <to> <amount> <symbol> [--instant\|--conservative]` | Send tokens |
107
- | | `receive [--finalize]` | Check for incoming transfers |
108
- | | `history [limit]` | Show transaction history |
109
- | **Nametags** | `nametag <name>` | Register a nametag |
110
- | | `nametag-info <name>` | Lookup nametag info |
111
- | | `my-nametag` | Show current nametag |
112
- | | `nametag-sync` | Re-publish nametag with chainPubkey |
113
- | **Utils** | `generate-key` | Generate random key |
114
- | | `to-human <amount>` | Convert to human readable |
115
- | | `parse-wallet <file>` | Parse wallet file |
116
-
117
- CLI data is stored in `./.sphere-cli/` directory.
118
-
119
- > **Shell completion:** Run `npm link && sphere-cli completions bash >> ~/.bashrc` for tab-completion of all commands. See [CLI Quickstart](docs/QUICKSTART-CLI.md) for details.
47
+ See [docs/QUICKSTART-CLI.md](docs/QUICKSTART-CLI.md) for the full command reference.
120
48
 
121
49
  ## Quick Start
122
50
 
@@ -231,6 +159,64 @@ sphere.setPriceProvider(createPriceProvider({
231
159
  }));
232
160
  ```
233
161
 
162
+ ## Building a Sphere-authenticated backend
163
+
164
+ If your service needs to authenticate users via their Sphere wallet, use `verifySphereAuth`. It performs signature verification and identity derivation in one misuse-resistant call.
165
+
166
+ ```typescript
167
+ import { randomBytes } from 'crypto';
168
+ import { verifySphereAuth, AuthVerificationError } from '@unicitylabs/sphere-sdk';
169
+
170
+ const challenges = new Map<string, { challenge: string; expiresAt: number }>();
171
+
172
+ // POST /auth/challenge — issue a one-shot nonce challenge
173
+ server.post('/auth/challenge', async (req) => {
174
+ const { chainPubkey } = req.body;
175
+ const nonce = randomBytes(16).toString('hex');
176
+ const challenge = `Sign in to MyApp\nPubkey: ${chainPubkey}\nNonce: ${nonce}\nIssued At: ${new Date().toISOString()}`;
177
+ challenges.set(chainPubkey, { challenge, expiresAt: Date.now() + 5 * 60_000 });
178
+ return { challenge };
179
+ });
180
+
181
+ // POST /auth/verify — turn a signed challenge into a session
182
+ server.post('/auth/verify', async (req, reply) => {
183
+ const { chainPubkey, signature } = req.body;
184
+ const stored = challenges.get(chainPubkey);
185
+ if (!stored || Date.now() > stored.expiresAt) {
186
+ return reply.status(401).send({ error: 'No valid challenge — request a new one' });
187
+ }
188
+ challenges.delete(chainPubkey); // one-shot
189
+
190
+ try {
191
+ const { chainPubkey: pk, directAddress } = await verifySphereAuth({
192
+ challenge: stored.challenge,
193
+ signature,
194
+ chainPubkey,
195
+ });
196
+ // pk and directAddress are now safe to use as user identifiers —
197
+ // neither is a client claim, both are derived from cryptographic proof.
198
+ const token = server.jwt.sign({ sub: pk, addr: directAddress }, { expiresIn: '24h' });
199
+ return { token };
200
+ } catch (err) {
201
+ if (err instanceof AuthVerificationError) {
202
+ return reply.status(401).send({ error: err.message, code: err.code });
203
+ }
204
+ throw err;
205
+ }
206
+ });
207
+ ```
208
+
209
+ ### Why not accept `directAddress` from the client?
210
+
211
+ `verifySphereAuth` deliberately does not take a `directAddress` parameter. The signature proves that the client owns the privkey to the pubkey they presented — but it does NOT prove that the pubkey corresponds to any particular `directAddress`. If you accept `directAddress` as a separate body field and use it as the user-identifier key, an attacker can pre-bind any unregistered address to their own pubkey — locking the rightful owner out forever. `verifySphereAuth` derives `directAddress` from `chainPubkey` server-side instead, eliminating the bug class.
212
+
213
+ If you need just the address derivation in a custom flow, use the primitive directly:
214
+
215
+ ```typescript
216
+ import { computeDirectAddressFromChainPubkey } from '@unicitylabs/sphere-sdk';
217
+ const addr = await computeDirectAddressFromChainPubkey(chainPubkey);
218
+ ```
219
+
234
220
  ## Testnet Faucet
235
221
 
236
222
  To get test tokens on testnet, you **must first register a nametag**: