@bsv/overlay 0.6.0 → 0.6.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.
@@ -0,0 +1,203 @@
1
+ ## About
2
+
3
+ **GASP (Graph Aware Sync Protocol)** is the synchronization protocol overlay nodes use to replicate overlay-relevant transaction data between peers in a way that is **verifiable**, **complete**, and **bandwidth-efficient**. Instead of just sending raw TXIDs or copying a flat UTXO list, GASP reconciles **transaction graphs** by exchanging transactions/outputs with proof material and then **recursively requesting any missing input transactions** needed to validate what was received.
4
+
5
+ At a high level, GASP is built around:
6
+
7
+ - **Legitimacy:** Nodes only finalize data they can validate by anchoring it back to the blockchain (e.g., using merkle proofs / SPV-style verification).
8
+ - **Completeness:** If a transaction depends on other transactions, the protocol recursively fetches all required inputs so the end result isn’t partial or broken.
9
+ - **Efficiency:** Nodes only sync what they don’t have, reducing duplicates and bandwidth.
10
+ - **Redundancy / availability:** Multiple nodes can converge on the same overlay view over time, improving uptime and reducing single-host dependency.
11
+
12
+ ## Importance
13
+
14
+ Overlays are useful because they let you track only the topic you care about. But once an overlay is distributed (multiple nodes serving the same topic), nodes need a path to **catch up** and **stay consistent** over time.
15
+
16
+ GASP matters because it gives you:
17
+
18
+ - **Redundancy and uptime:** If one overlay host goes offline, other synced hosts can still serve the same topic, reducing single points of failure.
19
+ - **Fast bootstrap:** A fresh node can synchronize overlay state from peers instead of re-ingesting all previous transactions from scratch.
20
+ - **Lower-trust sync (for correctness):** Peers exchange transactions with proofs and recursively prove inputs, so received data can be validated instead of trusted blindly. *(This doesn’t replace your auth policy; it reduces trust needed for correctness.)*
21
+ - **Scaling the ecosystem:** As more apps and topics exist, GASP enables horizontal growth (more hosts for the same topic) instead of centralizing into one massive indexer.
22
+
23
+ ## How GASP Works
24
+
25
+ One party initiates sync by summarizing what it currently has, then the peer responds with what’s missing, and both sides iterate until they converge.
26
+
27
+ A typical flow looks like:
28
+
29
+ 1) **Summarize local state**
30
+ The initiator summarizes known spendable outpoints (commonly via a Bloom filter over TXID+VOUT).
31
+
32
+ 2) **Responder sends “missing” inventory**
33
+ The responder identifies items the initiator likely doesn’t have and returns inventory entries containing the output/transaction plus proof material (and optional metadata).
34
+
35
+ 3) **Recursive completion**
36
+ If the initiator is missing any input transactions required to validate what it received, it requests them. This repeats recursively until the needed graph is complete.
37
+
38
+ 4) **Verification + finalize**
39
+ Anything that can’t be validated/anchored is ignored rather than partially imported.
40
+
41
+ ## Usage
42
+
43
+ There are two main ways to activate and run GASP sync:
44
+
45
+ - **With CARS (cloud / managed):** Use CARS menus to enable sync options and deploy.
46
+ - **Without CARS (direct / self-managed):** Run your own Overlay Express server and trigger sync using the admin endpoints.
47
+
48
+ > **Important:** For GASP sync to work, *both* parties must have GASP enabled and must be configured to sync the same topic(s).
49
+
50
+ ---
51
+
52
+ ### With CARS
53
+
54
+ > If your project has a package.json script called `cars`, you can use `npm run cars`. Otherwise you typically run `cars` directly.
55
+
56
+ ### Using CARS (high level)
57
+
58
+ - `npm run cars` *(or `cars`)*
59
+ - Manage Projects
60
+ - Edit Advanced Engine Config
61
+ - Choose correct CARS config
62
+ - Toggle `gaspSync`
63
+ - Edit `syncConfiguration`
64
+ - Add your topic manager name(s) (e.g. `tm_example`)
65
+ - Back → Done
66
+ - Back to main menu
67
+ - Build Artifact → Auto-create new release and upload latest artifact now
68
+
69
+ ### Side notes
70
+
71
+ - Simply toggling `gaspSync` is not enough if your node is not “interested” in syncing your topic.
72
+ You must also ensure your topic manager name is included in `syncConfiguration` so the engine knows which topic(s) to sync.
73
+
74
+ ---
75
+
76
+ ### Without CARS
77
+
78
+ Without CARS, you run your own Overlay Express server and configure the overlay engine so it:
79
+ 1) **discovers peers / publishes ads** (via an advertiser), and
80
+ 2) knows **which topic managers to sync** (via `syncConfiguration`), and
81
+ 3) has **GASP enabled**.
82
+
83
+ ## Minimal engine config you must have
84
+
85
+ The most important lines are:
86
+
87
+ ```ts
88
+ server.configureEngineParams({
89
+ advertiser: wa,
90
+ syncConfiguration: {
91
+ 'tm_plite': 'SHIP',
92
+ 'tm_blockbeta': 'SHIP',
93
+ },
94
+ logTime: false,
95
+ logPrefix: '[OVERLAY] ',
96
+ throwOnBroadcastFailure: false,
97
+ suppressDefaultSyncAdvertisements: true,
98
+ })
99
+ // ^ tells the engine which topic(s) you want to sync, and the discovery mechanism to use (e.g. SHIP)
100
+
101
+ server.configureEnableGASPSync(true)
102
+ // ^ enables GASP sync in Overlay Express
103
+ ```
104
+
105
+ ## **Overlay Express Setup Example**
106
+
107
+ ```ts
108
+ import { WalletAdvertiser } from '@bsv/overlay-discovery-services'
109
+ import OverlayExpress from '@bsv/overlay-express'
110
+ import { config } from 'dotenv'
111
+ import packageJson from '../package.json'
112
+ import PollrTopicManager from './services/pollroverlay/PollrTopicManager'
113
+ import PollrLookupServiceFactory from './services/pollroverlay/PollrLookupServiceFactory'
114
+ import ForumTopicManager from './services/blockitoverlay/ForumTopicManager'
115
+ import ForumLookupService from './services/blockitoverlay/ForumLookupServiceFactory'
116
+
117
+ config()
118
+
119
+ const main = async () => {
120
+ const server = new OverlayExpress(
121
+ process.env.NODE_NAME!,
122
+ process.env.SERVER_PRIVATE_KEY!,
123
+ process.env.HOSTING_URL!,
124
+ process.env.ADMIN_TOKEN! // your chosen admin token to use the admin API
125
+ )
126
+
127
+ const wa = new WalletAdvertiser(
128
+ process.env.NETWORK! as 'main' | 'test',
129
+ process.env.SERVER_PRIVATE_KEY!,
130
+ process.env.WALLET_STORAGE_URL!,
131
+ process.env.HOSTING_URL!
132
+ )
133
+
134
+ await wa.init()
135
+
136
+ server.configureEngineParams({
137
+ advertiser: wa,
138
+ syncConfiguration: {
139
+ 'tm_plite': 'SHIP',
140
+ 'tm_blockbeta': 'SHIP',
141
+ },
142
+ logTime: false,
143
+ logPrefix: '[OVERLAY] ',
144
+ throwOnBroadcastFailure: false,
145
+ suppressDefaultSyncAdvertisements: true,
146
+ })
147
+
148
+ server.configureArcApiKey(process.env.ARC_API_KEY!)
149
+ server.configurePort(8080)
150
+
151
+ await server.configureKnex(process.env.KNEX_URL!)
152
+ await server.configureMongo(process.env.MONGO_URL!)
153
+
154
+ server.configureTopicManager('tm_plite', new PollrTopicManager())
155
+ server.configureLookupServiceWithMongo('ls_plite', PollrLookupServiceFactory)
156
+
157
+ server.configureTopicManager('tm_blockbeta', new ForumTopicManager())
158
+ server.configureLookupServiceWithMongo('ls_blockbeta', ForumLookupService)
159
+
160
+ server.configureEnableGASPSync(true)
161
+
162
+ await server.configureEngine()
163
+
164
+ server.app.get('/version', (req, res) => res.json(packageJson))
165
+
166
+ await server.start()
167
+ }
168
+
169
+ main()
170
+ ```
171
+
172
+ # **Validation**
173
+
174
+ A practical way to validate sync is to compare per-topic records in your SQL database before and after sync.
175
+
176
+ Example (adapt the table/query to your schema):
177
+ ### **Before sync**
178
+
179
+ ```
180
+ +-------------+----+
181
+ | topic | n |
182
+ +-------------+----+
183
+ | tm_plite | 2 |
184
+ | tm_blockbeta| 1 |
185
+ | tm_ship | 2 |
186
+ | tm_slap | 2 |
187
+ +-------------+----+
188
+ ```
189
+
190
+ ### **After sync**
191
+
192
+ ```
193
+ +-------------+------+
194
+ | topic | n |
195
+ +-------------+------+
196
+ | tm_plite | 10 |
197
+ | tm_blockbeta| 17 |
198
+ | tm_ship | 2177 |
199
+ | tm_slap | 2 |
200
+ +-------------+------+
201
+ ```
202
+
203
+ **What you’re looking for:** the topic(s) you care about (e.g. tm_plite, tm_blockbeta) should move toward the same counts/data across nodes after sync, and your lookup results for identical queries should converge as well.
@@ -0,0 +1,85 @@
1
+ # Overlay Use and Optimization in the BSV Ecosystem
2
+
3
+ [🏠 Home](../README.md) | [📚 API](../API.md) | [💡 Concepts](./README.md) | [📖 Examples](../examples/README.md) | [⚙️ Internal](../internal/README.md)
4
+
5
+ **Navigation:** [Overview](./00-overview.md) | [Best Practices](./01-best-practices.md) | [Query Performance](./02-query-performance.md) | [Database Monitoring](./03-database-monitoring.md) | [Pagination Example](./04-pagination-example.md) | [Recommendations Summary](./05-recommendations-summary.md)
6
+
7
+ ---
8
+
9
+ ## Introduction
10
+
11
+ Overlays are distributed application layers built on top of Bitcoin SV (BSV). They allow applications to publish structured data and then query it efficiently through **Lookup Services** and **Topic Managers**. This pattern enables developers to build scalable, high‑performance, privacy‑aware applications without needing to index or scan the entire blockchain themselves.
12
+
13
+ Applications such as **Convo Messenger**, **Tempo**, and **MetaMarket** use overlays to organize messages, content references, metadata, and other application‑specific data in a predictable and queryable way.
14
+
15
+ This documentation is written for **developers who want to build overlays for their own applications**. It explains how overlays work, what must be stored, how to structure queries, and how to keep overlay implementations efficient and maintainable.
16
+
17
+ ---
18
+
19
+ ## Purpose of This Documentation
20
+
21
+ Developers implementing overlays commonly need guidance on:
22
+
23
+ * What data a Lookup Service should store
24
+ * How to design efficient queries for retrieving overlay data
25
+ * How to index and structure Lookup Service databases
26
+ * How to keep overlays healthy and performant as they scale
27
+
28
+ This documentation focuses on **practical guidance** that helps developers design overlays correctly and avoid common pitfalls. Examples from real applications—such as Convo Messenger—are used when relevant.
29
+
30
+ This documentation does **not** cover internal BSVA system design, Overlay Express internals, or future platform development proposals.
31
+
32
+ ---
33
+
34
+ ## What This Series Covers
35
+
36
+ Each document in this series focuses on a key aspect of overlay implementation.
37
+
38
+ ### 1. Best Practices for Overlay Design
39
+
40
+ * What Lookup Services are required to store
41
+ * What additional metadata overlays often include
42
+ * What kinds of data should *not* be stored (e.g., large payloads)
43
+ * How to use UHRP references for external content
44
+
45
+ ### 2. Query Optimization and Performance
46
+
47
+ * How to design efficient queries
48
+ * How to choose indexes for common access patterns
49
+ * How to avoid unbounded or slow query patterns
50
+
51
+ ### 3. Monitoring and Debugging Overlays
52
+
53
+ * How to monitor your own overlay deployment
54
+ * How to inspect stored data safely
55
+ * How to track ingestion issues from your Topic Manager
56
+
57
+ ### 4. Pagination and Practical Examples
58
+
59
+ * Why pagination is critical for performance
60
+ * How to implement pagination in Lookup Services and clients
61
+ * Examples drawn from live overlay behavior (e.g., Convo Messenger)
62
+
63
+ ### 5. Summary of Recommendations
64
+
65
+ * A concise reference of best practices
66
+ * Quick reminders for developers building overlays
67
+
68
+ ---
69
+
70
+ ## Deliverables
71
+
72
+ This documentation includes:
73
+
74
+ * **Markdown files** that explain how to build, index, and monitor overlay implementations
75
+ * **Examples** demonstrating common patterns such as pagination and indexed lookup queries
76
+ * **Guidelines** that help ensure overlays remain scalable and consistent across different applications
77
+
78
+ ---
79
+
80
+ ## Next Steps
81
+
82
+ 1. Read the general best practices for overlay storage (`01-best-practices.md`).
83
+ 2. Review query performance and indexing fundamentals (`02-query-performance.md`).
84
+ 3. Explore examples using Convo Messenger (`04-pagination-example.md`).
85
+ 4. Refer to the summary document for quick reminders or cross-references.
@@ -0,0 +1,202 @@
1
+ # Overlay Best Practices for Developers
2
+
3
+ [🏠 Home](../README.md) | [📚 API](../API.md) | [💡 Concepts](./README.md) | [📖 Examples](../examples/README.md) | [⚙️ Internal](../internal/README.md)
4
+
5
+ **Navigation:** [Overview](./00-overview.md) | [Best Practices](./01-best-practices.md) | [Query Performance](./02-query-performance.md) | [Database Monitoring](./03-database-monitoring.md) | [Pagination Example](./04-pagination-example.md) | [Recommendations Summary](./05-recommendations-summary.md)
6
+
7
+ ---
8
+
9
+ ## Overview
10
+
11
+ This document provides **best practices for designing and maintaining overlay services** in the BSV ecosystem. It focuses on the practical concerns of developers who are building their **own overlays**—not on BSVA internals or modifications to Overlay Express.
12
+
13
+ The goal is to help developers make consistent and scalable decisions when implementing **Topic Managers**, **Lookup Services**, and associated **MongoDB storage layers**. Examples reference **Convo Messenger**, but the principles apply to all overlay-based systems.
14
+
15
+ ---
16
+
17
+ ## 1. Data Storage Principles
18
+
19
+ Overlay Lookup Services should store **small, structured metadata**, not entire payloads. The goal is fast, predictable querying.
20
+
21
+ ### 1.1 Required Fields for Any Overlay
22
+
23
+ Every Lookup Service must store enough information to uniquely reference an on-chain output. This includes:
24
+
25
+ * **`txid`** — transaction ID containing the output
26
+ * **`outputIndex`** — index of the admitted output
27
+ * **`protocol`** — identifies which overlay protocol this entry belongs to
28
+
29
+ These fields ensure that applications can always locate the exact on-chain output referenced by the overlay.
30
+
31
+ ### 1.2 Common Metadata Fields
32
+
33
+ In addition to required fields, overlays typically store small metadata extracted from PushDrop fields or derived from application logic.
34
+
35
+ Examples:
36
+
37
+ * **`timestamp` / `createdAt`** — when the message or record was created
38
+ * **`sender`** — sender's pubkey or DID
39
+ * **`threadId`** — group/thread identifier
40
+ * **`parentMessageId`** (optional) — for reply messages
41
+ * **reaction fields** (when applicable)
42
+
43
+ Example (Convo Messenger):
44
+
45
+ ```ts
46
+ {
47
+ txid: "abc123...",
48
+ outputIndex: 0,
49
+ protocol: [2, "convo"],
50
+ threadId: "thread-xyz",
51
+ sender: "035a1b...",
52
+ createdAt: 1730000000000,
53
+ encryptedPayload: [...], // ciphertext array
54
+ header: [...], // CurvePoint header
55
+ uniqueId: "optional-value",
56
+ parentMessageId: "optional-parent-txid"
57
+ }
58
+ ```
59
+
60
+ **Note:** Convo stores *encryptedPayload* and *header* because these remain small arrays needed by the client. Overlays must avoid storing anything large (e.g., full media files).
61
+
62
+ ### 1.3 When to Use UHRP
63
+
64
+ If an overlay needs to handle large data (text bodies, images, files), Lookup Services should **only store a UHRP reference**:
65
+
66
+ * Never store full file contents
67
+ * Never store large plaintext or ciphertext blobs
68
+ * Let the client fetch large data from UHRP when needed
69
+
70
+ Lookup Services should remain lightweight.
71
+
72
+ ---
73
+
74
+ ## 2. What Lookup Services Should *Not* Store
75
+
76
+ To maintain performance and predictable scaling, Lookup Services must avoid:
77
+
78
+ * Full PushDrop payloads or full scripts
79
+ * Large encrypted or plaintext message bodies
80
+ * Media files or binary attachments
81
+ * Identity certificates
82
+ * Redundant or duplicate on-chain data
83
+
84
+ **Rule of thumb:**
85
+ If it cannot be indexed efficiently, it does not belong in the Lookup DB.
86
+
87
+ ---
88
+
89
+ ## 3. Structuring Lookup Queries
90
+
91
+ ### 3.1 Use Indexed, Selective Fields
92
+
93
+ All queries should filter using indexed, selective fields such as:
94
+
95
+ * `threadId`
96
+ * `sender`
97
+ * `parentMessageId`
98
+ * `createdAt`
99
+
100
+ Examples from Convo’s actual Mongo indexes:
101
+
102
+ ```js
103
+ db.convoMessages.createIndex({ threadId: 1 })
104
+ db.convoMessages.createIndex({ parentMessageId: 1 })
105
+ db.convoMessages.createIndex({ threadId: 1, createdAt: -1 })
106
+ db.convoReactions.createIndex({ threadId: 1 })
107
+ ```
108
+
109
+ ### 3.2 Use Pagination Everywhere
110
+
111
+ List endpoints must support:
112
+
113
+ * **`skip`** — starting offset
114
+ * **`limit`** — number of items
115
+
116
+ Typical defaults:
117
+
118
+ * `limit = 50`
119
+ * `skip = 0`
120
+
121
+ Example (Convo):
122
+
123
+ ```ts
124
+ const messages = await this.storage.listThreadMessages(threadId, skip, limit)
125
+ ```
126
+
127
+ ### 3.3 Avoid Expensive Query Patterns
128
+
129
+ Do **not**:
130
+
131
+ * Perform unbounded collection scans
132
+ * Query across all protocols
133
+ * Sort without an index
134
+ * Use `$regex` or `$text` filters
135
+
136
+ If complex queries are needed, break them into:
137
+
138
+ * Indexed filters
139
+ * Bounded pagination
140
+ * Incremental lookups
141
+
142
+ ---
143
+
144
+ ## 4. Topic Manager Best Practices
145
+
146
+ Topic Managers determine which outputs belong to your overlay. They must validate and parse data correctly.
147
+
148
+ Best practices:
149
+
150
+ 1. **Validate admissible outputs** using PushDrop decoding.
151
+ 2. **Store only necessary fields** extracted from PushDrop.
152
+ 3. **Reject malformed or irrelevant outputs** early.
153
+ 4. **Handle duplicate admissions** cleanly.
154
+ 5. **Avoid heavy computation** inside the Topic Manager.
155
+
156
+ Example (Convo):
157
+
158
+ ```ts
159
+ const decoded = PushDrop.decode(output.lockingScript)
160
+ const marker = Utils.toUTF8(fields[0])
161
+ const protocol = Utils.toUTF8(fields[1])
162
+
163
+ if (marker === 'convo' && protocol === 'tmconvo') {
164
+ admissibleOutputs.push(index)
165
+ }
166
+ ```
167
+
168
+ ---
169
+
170
+ ## 5. Data Retention and Cleanup
171
+
172
+ Overlays accumulate data continuously. Without retention logic, performance may degrade.
173
+
174
+ Common retention approaches:
175
+
176
+ * Delete old entries if your application doesn’t need them
177
+ * Archive long-lived data to another collection
178
+ * Rebuild indexes periodically
179
+ * Limit history for ephemeral overlays
180
+
181
+ Retention periods depend on the app:
182
+
183
+ * **Convo Messenger:** often stores all messages indefinitely
184
+ * **Task-based overlays:** may delete resolved items after 30–90 days
185
+
186
+ ---
187
+
188
+ ## 6. Summary of Recommendations
189
+
190
+ | Area | Recommendation |
191
+ | --------------- | ---------------------------------------------------------------- |
192
+ | Required Fields | Always store `txid`, `outputIndex`, and protocol ID. |
193
+ | Metadata | Store only small, queryable fields (e.g., `threadId`, `sender`). |
194
+ | Large Data | Use UHRP references instead of storing raw data. |
195
+ | Queries | Use selective, indexed fields. |
196
+ | Pagination | Always include `skip` and `limit` in list endpoints. |
197
+ | Topic Manager | Validate and parse overlay-specific outputs only. |
198
+ | Retention | Prune or archive data as needed. |
199
+
200
+ ---
201
+
202
+ Next file: [`02-query-performance.md`](./02-query-performance.md) — how to design and optimize overlay queries.