Secure Scuttlebutt TypeScript Types
ssb-typescript provides comprehensive TypeScript type definitions for the Secure Scuttlebutt (SSB) protocol, enabling developers to build SSB applications with strong type safety. It defines core SSB concepts such as `FeedId`, `MsgId`, `BlobId`, and various message interfaces like `Msg`, `UnboxedMsg`, and `Content` (which is a union of specific content types like `PostContent`, `ContactContent`, `VoteContent`, `BlogContent`, and more). The current stable version is 2.8.0. As a type-only package, its release cadence is typically driven by changes in the underlying SSB protocol or common application patterns, rather than frequent functional updates. Its key differentiator is providing a standardized, community-maintained set of types for the decentralized SSB ecosystem, helping to ensure interoperability and reduce development errors when working with SSB data structures.
Common errors
-
TS2307: Cannot find module 'ssb-typescript' or its corresponding type declarations.
cause The `ssb-typescript` package is not installed, or TypeScript cannot locate its type definitions.fixEnsure the package is installed: `npm install ssb-typescript` or `yarn add ssb-typescript`. Verify your `tsconfig.json` includes `node_modules/@types` or has appropriate `typeRoots`. -
TS2322: Type '{ type: "post"; text: string; }' is not assignable to type 'PostContent'. Property 'mentions' is missing in type '{ type: "post"; text: string; }' but required in type 'PostContent'.cause An object being assigned as `PostContent` is missing required properties, or properties are of the wrong type, according to the `PostContent` interface definition.fixAdd all required properties (e.g., `mentions?: Array<any>;`) to your object, even if they are empty arrays or `undefined`, or ensure optional properties are explicitly set. Check the `PostContent` interface for exact requirements. -
TS2345: Argument of type 'string' is not assignable to parameter of type 'FeedId'.
cause Attempting to assign a plain string literal or `string` variable to a type like `FeedId`, `MsgId`, or `BlobId`, which are typically branded string types for stronger type checking.fixWhile `FeedId` is an alias for `string`, TypeScript might enforce stricter checks depending on context or other utilities. Ensure the string format is correct (e.g., starts with `@` for `FeedId`). If you are certain about the string's correctness, you can use a type assertion: `someString as FeedId`. -
TS2740: Type 'PostContent' is missing the following properties from type 'Msg<Content>': key, value, timestamp.
cause You are trying to use a `PostContent` object where a full `Msg` interface is expected. `PostContent` is only the `content` property of a `Msg`.fixEnsure you are constructing a complete `Msg` object (which includes `key`, `value`, `timestamp`) and placing your `PostContent` inside the `value.content` field when a full message is required.
Warnings
- breaking The `Msg` and `Content` interfaces have evolved over time to reflect changes in the SSB protocol. If upgrading from very old versions, verify the structure of message content and metadata, especially around private messages and new content types.
- gotcha The `mentions` property in `PostContent` and `BlogContent` is typed as `Array<any>`. This means TypeScript will not enforce types within this array, potentially leading to runtime errors if not carefully validated at the application level.
- gotcha The `Content` union type is very broad, encompassing all known SSB message content types. If you need to work with a specific content type (e.g., `PostContent`), always use type guards or explicit generics (`Msg<PostContent>`) to narrow the type and enable full type safety.
- gotcha Using `ssb-typescript` with vastly different versions of SSB client libraries or schema definitions (e.g., `ssb-db`, `ssb-client`) can lead to type mismatches where the types don't accurately reflect the runtime data structures. This is particularly true if the SSB ecosystem itself undergoes significant protocol changes.
Install
-
npm install ssb-typescript -
yarn add ssb-typescript -
pnpm add ssb-typescript
Imports
- Msg
import Msg from 'ssb-typescript';
import { Msg } from 'ssb-typescript'; - FeedId, MsgId, BlobId
import { FeedId, MsgId, BlobId } from 'ssb-typescript'; - Content, PostContent
const Content = require('ssb-typescript').Content;import { Content, PostContent } from 'ssb-typescript';
Quickstart
import { Msg, PostContent, FeedId, MsgId, Content } from 'ssb-typescript';
// Example FeedId, MsgId, BlobId (standard SSB identifiers)
const exampleFeedId: FeedId = '@HXjeG7t2p8zU9gT0t2p8zU9gT0t2p8zU9gT0t2p8zU9gT0.ed25519';
const exampleMsgId: MsgId = '%mS3G7t2p8zU9gT0t2p8zU9gT0t2p8zU9gT0t2p8zU9gT0.sha256';
const exampleRootMsgId: MsgId = '%mS3G7t2p8zU9gT0t2p8zU9gT0t2p8zU9gT0t2p8zU9gT0.sha256';
// Define a PostContent message
const postContent: PostContent = {
type: 'post',
text: 'Hello, Secure Scuttlebutt! This is a test post from ssb-typescript.',
channel: 'testing',
mentions: [], // Empty array for no mentions
root: exampleRootMsgId,
};
// Define an SSB Message wrapper
const ssbMessage: Msg<PostContent> = {
key: exampleMsgId,
value: {
previous: '%prevMsgId.sha256',
author: exampleFeedId,
sequence: 123,
timestamp: 1678886400000, // UTC epoch milliseconds
hash: 'sha256',
content: postContent,
signature: 'fake-signature-string-here',
},
timestamp: 1678886400000,
};
// Demonstrate generic Content type usage
const genericContent: Content = {
type: 'contact',
contact: exampleFeedId,
following: true
};
console.log('Example SSB Post Message:', JSON.stringify(ssbMessage, null, 2));
console.log('Example generic Content:', JSON.stringify(genericContent, null, 2));
// To compile and run this example:
// 1. Install dependencies: `npm install typescript ssb-typescript ts-node`
// 2. Save the code as `example.ts`.
// 3. Execute: `npx ts-node example.ts`