passkey-kit 0.16.2 → 0.16.4
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 +16 -7
- package/SECURITY.md +27 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -5,8 +5,8 @@ A TypeScript SDK for creating and using **smart-wallet accounts on Stellar with
|
|
|
5
5
|
- **Client (`PasskeyKit`)** — runs in the browser: create/connect wallets, sign transactions, build signer-management transactions. Holds no secrets.
|
|
6
6
|
- **Server (`PasskeyServer`)** — runs server-side: submits transactions through a relayer (fee sponsorship), plus convenience signer-discovery helpers over the keyless Mercury indexer. Holds the relayer secret.
|
|
7
7
|
|
|
8
|
-
> [!
|
|
9
|
-
> **
|
|
8
|
+
> [!CAUTION]
|
|
9
|
+
> **Unaudited software.** This repository's smart-wallet contract, SDKs, and relayer proxy have not received an independent third-party security audit. Defects can cause unauthorized transactions, loss of access, or permanent asset loss. Do not store or control assets you cannot afford to lose. Limit balances and signer permissions. Monitor wallets and maintain recovery and authorized upgrade paths. You use this software and related services at your own risk. The software has no warranty; see [LICENCE](./LICENCE), [Caveats](#caveats), and [SECURITY.md](./SECURITY.md).
|
|
10
10
|
|
|
11
11
|
> [!NOTE]
|
|
12
12
|
> **Looking for context rules, thresholds, and spending-limit policies?** [smart-account-kit](https://github.com/stellar/smart-account-kit) is a sibling SDK built on the audited [OpenZeppelin stellar-contracts](https://github.com/OpenZeppelin/stellar-contracts) account. It uses a different on-chain authorization model (context rules + an auth digest) than passkey-kit's flat `Signatures` map, so the two are not drop-in compatible — pick the model that fits your app.
|
|
@@ -70,8 +70,8 @@ import { PasskeyKit } from "passkey-kit";
|
|
|
70
70
|
const kit = new PasskeyKit({
|
|
71
71
|
rpcUrl: "https://soroban-testnet.stellar.org",
|
|
72
72
|
networkPassphrase: "Test SDF Network ; September 2015",
|
|
73
|
-
// Canonical
|
|
74
|
-
walletWasmHash: "
|
|
73
|
+
// Canonical smart-wallet WASM hash; see docs/deployments-*.md
|
|
74
|
+
walletWasmHash: "502ea4e7bdb3ea99880941f1d35ceb67fb598692c0bb40f842ef9c9f17d58b58",
|
|
75
75
|
});
|
|
76
76
|
```
|
|
77
77
|
|
|
@@ -235,7 +235,7 @@ Each method builds an `AssembledTransaction` (`WalletTx`) that wraps one contrac
|
|
|
235
235
|
| `updateEd25519(publicKey, limits, store, expiration?)` | `update_signer` | Update an Ed25519 signer. |
|
|
236
236
|
| `addPolicy(policy, limits, store, expiration?)` | `add_signer` | Add a policy signer (`policy` = `C…`). Invokes the policy's `install` hook. |
|
|
237
237
|
| `updatePolicy(policy, limits, store, expiration?)` | `update_signer` | Update a policy signer. |
|
|
238
|
-
| `remove(signerKey)` | `remove_signer` | Remove a signer.
|
|
238
|
+
| `remove(signerKey)` | `remove_signer` | Remove a signer. A policy entry must pass its own `policy__` check. |
|
|
239
239
|
| `upgrade(newWasmHash)` | `upgrade` | Replace the wallet's WASM (`Buffer`/`Uint8Array`, 32 bytes). |
|
|
240
240
|
| `getSigner(signerKey)` | `get_signer` | Read a signer entry from the ledger (temporary before persistent). Returns `SignerVal \| null`. |
|
|
241
241
|
|
|
@@ -427,6 +427,11 @@ type SignerLimits = Map<string, SignerKey[] | undefined> | undefined;
|
|
|
427
427
|
- `Map` present but a contract → `undefined` — may authorize any call to that contract, no co-signers.
|
|
428
428
|
- `Map` present, contract → `[keys]` — may authorize calls to that contract **only if every listed key also approves** (required co-signers).
|
|
429
429
|
|
|
430
|
+
A required policy key must remain installed as a signer and unexpired. Removing
|
|
431
|
+
that policy immediately revokes every signer whose limits require it. A
|
|
432
|
+
`Signature::Policy` always invokes `policy__`, including for the policy's own
|
|
433
|
+
`remove_signer` context.
|
|
434
|
+
|
|
430
435
|
```ts
|
|
431
436
|
// This signer may only call C…token, and only alongside a passkey co-signer.
|
|
432
437
|
const limits = new Map([["C…token", [SignerKey.Secp256r1(keyId)]]]);
|
|
@@ -450,13 +455,16 @@ Signer and signature expiration are **UNIX timestamps in seconds** (inclusive: v
|
|
|
450
455
|
## Caveats
|
|
451
456
|
|
|
452
457
|
> [!WARNING]
|
|
453
|
-
> These are
|
|
458
|
+
> These risks are not exhaustive. Tests and reviews do not prove that the software has no defects.
|
|
454
459
|
|
|
460
|
+
- **Limit value and authority.** Limit wallet balances, signer permissions, policy allowances, and relayer permissions. Monitor wallet activity. Keep independent recovery, submission, and authorized upgrade paths.
|
|
461
|
+
- **Hosted services can fail or return stale data.** Do not treat relayer or indexer responses as authoritative chain state. Confirm security-sensitive state through Stellar RPC.
|
|
455
462
|
- **Keep at least one durable admin signer.** The contract rejects any change that would remove or demote its last durable (`Persistent`, non-expiring) admin signer (`LastAdminSigner = 103`) or leave it without any durable signer (`LastSigner = 104`), so a wallet always retains one signer that cannot evict or expire. Signers outside that guard — `Temporary` storage or with an expiration — lapse on their own: add a replacement *before* removing or demoting an existing signer.
|
|
456
463
|
- **The default deployer is a shared, public keypair — its secret is publicly derivable.** It salts deployment and signs only the CreateContractV2 authorization entry; the relayer supplies the envelope source, sequence, and fees. It never controls the wallet. Its determinism is load-bearing for discovery: overriding `deploySource` changes every derived address and breaks keyId → wallet lookup. Use a separate funded `restoreSource` for `restoreFootprint`; never fund the shared deployer. A third-party `bumpSequence` to `INT64_MAX` no longer blocks the current SDK because it never uses the shared deployer as an envelope source. Full analysis: [`docs/security-deterministic-deployer.md`](docs/security-deterministic-deployer.md).
|
|
457
464
|
- **Deploy front-running remains an accepted residual.** Anyone who learns a `keyId` before deployment could place arbitrary code at the derived address. A signer getter check alone is not proof of ownership, because arbitrary code can answer it however the client expects. Since `0.16.0` `connectWallet` binds accepted code identity (`acceptedWasmHashes`) before reading any signer state, for any address that did not come from trusted local storage. A derivation-resolved address is still not authenticated by that check alone — see the [security analysis](docs/security-deterministic-deployer.md#accepted-residual-address-squatting).
|
|
458
465
|
- **WebAuthn requires User Presence (UP), not User Verification (UV).** The contract requires the UP flag but not UV (biometric/PIN), so it stays compatible with non-UV authenticators. Enforce UV at the client/relayer layer if you need it.
|
|
459
466
|
- **Value-moving policies need a cumulative cap or a co-signer.** A `Signature::Policy` carries no secret, so a per-transfer cap alone is trivially drained by repeated capped transfers. See the [contract interface](#contract-interface) and `sample-policy`.
|
|
467
|
+
- **Existing `binver = 1.0.0` wallets require an authorized upgrade.** Installing the fixed WASM does not change deployed wallet instances. Upgrade each wallet to the canonical `binver = 1.0.1` hash in the current deployment manifest.
|
|
460
468
|
|
|
461
469
|
## Contract interface
|
|
462
470
|
|
|
@@ -491,7 +499,7 @@ contractId = sha256(XDR(HashIdPreimage::EnvelopeTypeContractId {
|
|
|
491
499
|
- The canonical deployer keypair is `Keypair.fromRawEd25519Seed(sha256("kalepail"))`. It salts the deploy and signs the deploy authorization — it never pays fees and never controls the wallet — but its determinism is **load-bearing**: overriding `deploySource` changes every derived address and breaks keyId → wallet discovery.
|
|
492
500
|
- The WASM hash is deliberately **not** in the preimage, so an `upgrade` never moves a wallet's address.
|
|
493
501
|
|
|
494
|
-
This tuple is normative and must never change. See [`docs/deployments-
|
|
502
|
+
This tuple is normative and must never change. See [`docs/deployments-2026-08-19.md`](./docs/deployments-2026-08-19.md) for the canonical WASM hash, upload transactions, and upgrade guidance.
|
|
495
503
|
|
|
496
504
|
## Repository layout & development
|
|
497
505
|
|
|
@@ -512,6 +520,7 @@ pnpm verify:bindings # assert the committed bindings match the canonical WASM
|
|
|
512
520
|
```
|
|
513
521
|
|
|
514
522
|
- **[CHANGELOG.md](./CHANGELOG.md)** — the v1 overhaul, by component.
|
|
523
|
+
- **[SECURITY.md](./SECURITY.md)** — supported versions and private vulnerability reporting.
|
|
515
524
|
- **[docs/migration-v1.md](./docs/migration-v1.md)** — upgrading from 0.12.x, with Before/After and a gap analysis.
|
|
516
525
|
- **[docs/releasing.md](./docs/releasing.md)** — the dependency-ordered publish flow.
|
|
517
526
|
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Security status
|
|
4
|
+
|
|
5
|
+
The smart-wallet contract, SDKs, and repository relayer proxy have not received an independent third-party security audit.
|
|
6
|
+
|
|
7
|
+
Tests and reviews reduce risk. They do not prove that the software has no defects.
|
|
8
|
+
|
|
9
|
+
Do not store or control assets you cannot afford to lose. Limit balances and permissions. Monitor wallets and maintain recovery and authorized upgrade paths.
|
|
10
|
+
|
|
11
|
+
## Supported versions
|
|
12
|
+
|
|
13
|
+
Only the latest npm releases and the canonical smart-wallet WASM receive security fixes.
|
|
14
|
+
|
|
15
|
+
The current deployment manifest in [`docs/`](./docs/) identifies the canonical WASM. Existing wallet instances do not upgrade automatically.
|
|
16
|
+
|
|
17
|
+
## Report a vulnerability privately
|
|
18
|
+
|
|
19
|
+
Do not open a public issue, pull request, discussion, or chat message for a suspected vulnerability.
|
|
20
|
+
|
|
21
|
+
Email `tyler@stellar.org` with the subject `passkey-kit security report`. If email is unsuitable, request a private channel without including sensitive details.
|
|
22
|
+
|
|
23
|
+
Include the affected version or commit, impact, reproduction steps, and a minimal proof of concept. Do not include secrets or personal data.
|
|
24
|
+
|
|
25
|
+
Use local tests or isolated test accounts. Do not test against public user wallets or move assets that you do not own.
|
|
26
|
+
|
|
27
|
+
The maintainers will confirm receipt, investigate the report, prepare a fix, and coordinate disclosure with the reporter.
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "passkey-kit",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.4",
|
|
4
4
|
"description": "A helper library for creating and using smart wallet accounts on the Stellar blockchain.",
|
|
5
5
|
"author": "Tyler van der Hoeven <tyler@stellar.org>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"files": [
|
|
27
27
|
"dist",
|
|
28
28
|
"README.md",
|
|
29
|
-
"LICENCE"
|
|
29
|
+
"LICENCE",
|
|
30
|
+
"SECURITY.md"
|
|
30
31
|
],
|
|
31
32
|
"dependencies": {
|
|
32
33
|
"@openzeppelin/relayer-plugin-channels": "^0.20.0",
|
|
@@ -35,7 +36,7 @@
|
|
|
35
36
|
"base64url": "^3.0.1",
|
|
36
37
|
"buffer": "^6.0.3",
|
|
37
38
|
"sac-sdk": "0.4.4",
|
|
38
|
-
"passkey-kit-sdk": "0.8.
|
|
39
|
+
"passkey-kit-sdk": "0.8.2"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
42
|
"@types/node": "^24.6.0",
|
|
@@ -82,6 +83,6 @@
|
|
|
82
83
|
"clean": "rm -rf dist packages/passkey-kit-sdk/dist packages/sac-sdk/dist",
|
|
83
84
|
"build:demo": "cd demo && pnpm --ignore-workspace install && pnpm run build",
|
|
84
85
|
"deploy:demo": "npx wrangler pages deploy",
|
|
85
|
-
"deploy:demo:prod": "npx wrangler pages deploy --branch
|
|
86
|
+
"deploy:demo:prod": "npx wrangler pages deploy --branch main"
|
|
86
87
|
}
|
|
87
88
|
}
|