mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-28 08:22:24 +00:00
83 lines
3.2 KiB
Markdown
83 lines
3.2 KiB
Markdown
# SigningAdapter guide
|
|
|
|
`SigningAdapter` is the lightweight interface bitvid uses to sign direct-message
|
|
payloads and message metadata without depending on a specific auth provider.
|
|
The canonical implementations live in `js/auth/signingAdapter.js`, and callers
|
|
such as `NostrClient.sendDirectMessage()` and the DM composer accept a
|
|
`signingAdapter` option so they can work with NIP-07 extensions, remote signers,
|
|
or test doubles.
|
|
|
|
## Interface contract
|
|
|
|
A `SigningAdapter` is an object with the following async methods:
|
|
|
|
- `getPubkey()` → resolves the hex public key that should be used as the DM
|
|
author.
|
|
- `getDisplayName()` → optional display name string for UI metadata.
|
|
- `signEvent(unsignedEvent)` → returns a fully signed Nostr event object.
|
|
- `signMessage(message)` → returns a signature for an arbitrary string.
|
|
|
|
`signEvent()` is required for DM publishing; `signMessage()` is optional but is
|
|
used by the DM composer to attach a signature to the outgoing payload metadata.
|
|
|
|
## Implementing a new adapter
|
|
|
|
1. **Normalize the pubkey**: resolve and return a lowercased hex pubkey from
|
|
`getPubkey()`. The NIP-07 adapter does this by delegating to
|
|
`window.nostr.getPublicKey()` and normalizing the result.
|
|
2. **Provide signing primitives**:
|
|
- `signEvent()` must return an event with `id` and `sig` populated.
|
|
- `signMessage()` should return a stable signature string for the message
|
|
body when you need message-level signatures (for example, the DM composer
|
|
includes this for UI payloads).
|
|
3. **Expose a type label**: include a `type` field (for example `nip07`, `dev`,
|
|
or `test`) to make debugging easier.
|
|
|
|
Reference implementations:
|
|
|
|
- `createNip07SigningAdapter({ extension })` uses a browser extension signer.
|
|
- `createEphemeralDevSigningAdapter()` generates a local, throwaway keypair for
|
|
development flows.
|
|
- `createTestSigningAdapter()` returns deterministic signatures for tests.
|
|
|
|
## Testing a SigningAdapter
|
|
|
|
### Unit tests
|
|
|
|
For Node-based tests, use `createTestSigningAdapter()` so signatures are stable
|
|
and deterministic. You can pass it directly to `NostrClient.sendDirectMessage()`
|
|
through the `options.signingAdapter` field to avoid relying on active signers:
|
|
|
|
```js
|
|
import { createTestSigningAdapter } from "../js/auth/signingAdapter.js";
|
|
import { nostrClient } from "../js/nostrClientFacade.js";
|
|
|
|
const adapter = createTestSigningAdapter({
|
|
pubkey: "f".repeat(64),
|
|
});
|
|
|
|
const result = await nostrClient.sendDirectMessage(
|
|
"npub...",
|
|
"hello",
|
|
null,
|
|
{ signingAdapter: adapter }
|
|
);
|
|
```
|
|
|
|
Assertions can then verify that `result.ok` is `true` and that the signed event
|
|
was built with the adapter's pubkey and signatures.
|
|
|
|
### Manual smoke checks
|
|
|
|
For browser-only checks, wire the adapter into the DM composer by passing it in
|
|
as the `signingAdapter` prop. The composer will call `getPubkey()`,
|
|
`getDisplayName()`, and `signMessage()` while building the outgoing payload
|
|
object so you can inspect the resulting metadata in your handler.
|
|
|
|
## Usage reminders
|
|
|
|
- When the signer does **not** implement NIP-44 encryption, NIP-17 sends are
|
|
blocked; keep the privacy toggle disabled until encryption is available.
|
|
- Always surface errors from `getPubkey()` or `signMessage()` to the caller so
|
|
the UI can display a meaningful failure state.
|