@msgboard/sdk 0.0.28
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 +314 -0
- package/dist/index.d.ts +96 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +233 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +4 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +8 -0
- package/dist/logger.js.map +1 -0
- package/dist/render-reference.d.ts +44 -0
- package/dist/render-reference.d.ts.map +1 -0
- package/dist/render-reference.js +74 -0
- package/dist/render-reference.js.map +1 -0
- package/openrpc.json +97 -0
- package/package.json +68 -0
package/README.md
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
# @msgboard/sdk
|
|
2
|
+
|
|
3
|
+
Distribute ephemeral messages across EVM networks using proof of work as the gate — no gas, no token, no account. You mint your own proof-of-work "stamp" for each message; that stamp is what keeps the board spam-resistant.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm i --save @msgboard/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quickstart
|
|
12
|
+
|
|
13
|
+
You need an RPC endpoint whose node runs the `msgboard_` module. Public PulseChain/Ethereum RPCs do **not** run it yet; valve.city does (for example `https://one.valve.city/rpc/vk_demo/evm/369`). You can also run your own node with the module.
|
|
14
|
+
|
|
15
|
+
### with viem
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import * as msgboard from '@msgboard/sdk'
|
|
19
|
+
import { createPublicClient, http } from 'viem'
|
|
20
|
+
import { pulsechain } from 'viem/chains'
|
|
21
|
+
|
|
22
|
+
const client = createPublicClient({
|
|
23
|
+
chain: pulsechain,
|
|
24
|
+
transport: http('https://one.valve.city/rpc/vk_demo/evm/369'),
|
|
25
|
+
})
|
|
26
|
+
const board = new msgboard.MsgBoardClient(client)
|
|
27
|
+
|
|
28
|
+
// do the work for your category and data
|
|
29
|
+
const work = await board.doPoW('gasmoneyplease', 'hello board')
|
|
30
|
+
// submit the valid message
|
|
31
|
+
const hash = await board.addMessage(work.message)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### with ethers
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import * as msgboard from '@msgboard/sdk'
|
|
38
|
+
import { providers } from 'ethers'
|
|
39
|
+
|
|
40
|
+
const provider = new providers.JsonRpcProvider('https://one.valve.city/rpc/vk_demo/evm/369')
|
|
41
|
+
const board = new msgboard.MsgBoardClient(msgboard.wrapLegacySend(provider))
|
|
42
|
+
|
|
43
|
+
const work = await board.doPoW('gasmoneyplease', 'hello board')
|
|
44
|
+
const hash = await board.addMessage(work.message)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### read the board
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
const status = await board.status() // enabled, counts, difficulty factors
|
|
51
|
+
const categories = await board.categories()
|
|
52
|
+
const content = await board.content() // messages grouped by category
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Finding a node
|
|
56
|
+
|
|
57
|
+
A node must run the `msgboard_` module to serve these methods. If `status()` reports `enabled: false`, or a call returns JSON-RPC error `-32601` (method not found), the node does not have the module — point at one that does. See the live status badge on https://msgboard.xyz for working endpoints.
|
|
58
|
+
|
|
59
|
+
## Proof of work and difficulty
|
|
60
|
+
|
|
61
|
+
Submission is gated by proof of work, not a fee. Difficulty scales with message size:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
((2n ** 24n + BigInt(dataLen) * 10_000n) * workMultiplier) / workDivisor
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`dataLen` is measured in **bytes** (not hex characters); each byte adds 10,000 to the difficulty under the default factors, which rewards compact message packing. Compute the difficulty for a payload with:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
board.getDifficulty('0x...') // bigint
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`workMultiplier` and `workDivisor` come from `status()` and are applied automatically by `doPoW`.
|
|
74
|
+
|
|
75
|
+
## Categories
|
|
76
|
+
|
|
77
|
+
A category is a 32-byte hash. Pass a string and the client hashes it for you (`categoryHash`); pass hex and it is used as-is. The demo board uses the `gasmoneyplease` category.
|
|
78
|
+
|
|
79
|
+
## Ephemerality
|
|
80
|
+
|
|
81
|
+
Messages are short-lived: the board retains roughly the last 120 blocks of messages, so the board is a live signal, not durable storage.
|
|
82
|
+
|
|
83
|
+
## Keeping work off the UI thread
|
|
84
|
+
|
|
85
|
+
`doPoW` is a busy loop; JavaScript blocks while it runs. In a browser, run it in a Web Worker so the interface stays responsive. The client yields periodically (`breakInterval`) to let block updates resolve, but the heavy hashing still occupies the thread it runs on.
|
|
86
|
+
|
|
87
|
+
<!-- GENERATED:OPENRPC:START -->
|
|
88
|
+
|
|
89
|
+
## JSON-RPC methods
|
|
90
|
+
|
|
91
|
+
### msgboard_status
|
|
92
|
+
|
|
93
|
+
Board status and the difficulty factors required for valid messages.
|
|
94
|
+
|
|
95
|
+
| Parameter | Type | Required |
|
|
96
|
+
| --- | --- | --- |
|
|
97
|
+
| _(none)_ | | |
|
|
98
|
+
|
|
99
|
+
**Returns:** `Status`
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"jsonrpc": "2.0",
|
|
104
|
+
"id": 1,
|
|
105
|
+
"method": "msgboard_status",
|
|
106
|
+
"params": []
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"jsonrpc": "2.0",
|
|
113
|
+
"id": 1,
|
|
114
|
+
"result": {
|
|
115
|
+
"enabled": true,
|
|
116
|
+
"count": "0x0",
|
|
117
|
+
"size": "0x0",
|
|
118
|
+
"workMultiplier": "0x2710",
|
|
119
|
+
"workDivisor": "0xf4240"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### msgboard_categories
|
|
125
|
+
|
|
126
|
+
The list of 32-byte category hashes currently present on the board.
|
|
127
|
+
|
|
128
|
+
| Parameter | Type | Required |
|
|
129
|
+
| --- | --- | --- |
|
|
130
|
+
| _(none)_ | | |
|
|
131
|
+
|
|
132
|
+
**Returns:** `Categories`
|
|
133
|
+
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"jsonrpc": "2.0",
|
|
137
|
+
"id": 1,
|
|
138
|
+
"method": "msgboard_categories",
|
|
139
|
+
"params": []
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"jsonrpc": "2.0",
|
|
146
|
+
"id": 1,
|
|
147
|
+
"result": [
|
|
148
|
+
"0x6761736d6f6e6579706c65617365000000000000000000000000000000000000"
|
|
149
|
+
]
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### msgboard_content
|
|
154
|
+
|
|
155
|
+
All messages on the board, grouped by category hash. Optionally filtered.
|
|
156
|
+
|
|
157
|
+
| Parameter | Type | Required |
|
|
158
|
+
| --- | --- | --- |
|
|
159
|
+
| `filter` | `ContentFilter` | no |
|
|
160
|
+
|
|
161
|
+
**Returns:** `Content`
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"jsonrpc": "2.0",
|
|
166
|
+
"id": 1,
|
|
167
|
+
"method": "msgboard_content",
|
|
168
|
+
"params": [
|
|
169
|
+
{}
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
```json
|
|
175
|
+
{
|
|
176
|
+
"jsonrpc": "2.0",
|
|
177
|
+
"id": 1,
|
|
178
|
+
"result": {}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### msgboard_addMessage
|
|
183
|
+
|
|
184
|
+
Submit a proof-of-work message (RLP-encoded) to the board.
|
|
185
|
+
|
|
186
|
+
| Parameter | Type | Required |
|
|
187
|
+
| --- | --- | --- |
|
|
188
|
+
| `rlp` | `Hex` | yes |
|
|
189
|
+
|
|
190
|
+
**Returns:** `Hex`
|
|
191
|
+
|
|
192
|
+
```json
|
|
193
|
+
{
|
|
194
|
+
"jsonrpc": "2.0",
|
|
195
|
+
"id": 1,
|
|
196
|
+
"method": "msgboard_addMessage",
|
|
197
|
+
"params": [
|
|
198
|
+
"0xf800"
|
|
199
|
+
]
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
```json
|
|
204
|
+
{
|
|
205
|
+
"jsonrpc": "2.0",
|
|
206
|
+
"id": 1,
|
|
207
|
+
"result": "0x0d1e2f00000000000000000000000000000000000000000000000000c46845f9"
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### msgboard_getMessage
|
|
212
|
+
|
|
213
|
+
Fetch a single message by its hash.
|
|
214
|
+
|
|
215
|
+
| Parameter | Type | Required |
|
|
216
|
+
| --- | --- | --- |
|
|
217
|
+
| `hash` | `Hex` | yes |
|
|
218
|
+
|
|
219
|
+
**Returns:** `RPCMessage`
|
|
220
|
+
|
|
221
|
+
```json
|
|
222
|
+
{
|
|
223
|
+
"jsonrpc": "2.0",
|
|
224
|
+
"id": 1,
|
|
225
|
+
"method": "msgboard_getMessage",
|
|
226
|
+
"params": [
|
|
227
|
+
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
|
228
|
+
]
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
```json
|
|
233
|
+
{
|
|
234
|
+
"jsonrpc": "2.0",
|
|
235
|
+
"id": 1,
|
|
236
|
+
"result": {
|
|
237
|
+
"version": "0x1",
|
|
238
|
+
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
239
|
+
"blockNumber": "0x0",
|
|
240
|
+
"category": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
241
|
+
"data": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
242
|
+
"nonce": "0x0",
|
|
243
|
+
"hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
244
|
+
"workMultiplier": "0x0",
|
|
245
|
+
"workDivisor": "0x0"
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Schemas
|
|
251
|
+
|
|
252
|
+
### Hex
|
|
253
|
+
|
|
254
|
+
String matching `^0x[0-9a-fA-F]*$`.
|
|
255
|
+
|
|
256
|
+
### Status
|
|
257
|
+
|
|
258
|
+
| Field | Type | Description |
|
|
259
|
+
| --- | --- | --- |
|
|
260
|
+
| `enabled` (required) | `boolean` | Whether the module is enabled on this node. |
|
|
261
|
+
| `count` (required) | `Hex` | Overall count of messages stored on the board. |
|
|
262
|
+
| `size` (required) | `Hex` | Overall size of messages stored on the board. |
|
|
263
|
+
| `workMultiplier` (required) | `Hex` | Factor that increases required work. |
|
|
264
|
+
| `workDivisor` (required) | `Hex` | Factor that decreases required work. |
|
|
265
|
+
|
|
266
|
+
### Categories
|
|
267
|
+
|
|
268
|
+
Array of `Hex`.
|
|
269
|
+
|
|
270
|
+
### ContentFilter
|
|
271
|
+
|
|
272
|
+
| Field | Type | Description |
|
|
273
|
+
| --- | --- | --- |
|
|
274
|
+
| `category` | `Hex` | Restrict to one category hash. |
|
|
275
|
+
| `fromBlock` | `Hex` | Lower block bound (hex quantity). |
|
|
276
|
+
| `toBlock` | `Hex` | Upper block bound (hex quantity). |
|
|
277
|
+
|
|
278
|
+
### RPCMessage
|
|
279
|
+
|
|
280
|
+
| Field | Type | Description |
|
|
281
|
+
| --- | --- | --- |
|
|
282
|
+
| `version` (required) | `Hex` | Message/encoding version. |
|
|
283
|
+
| `blockHash` (required) | `Hex` | Hash of the block the message is rooted to. |
|
|
284
|
+
| `blockNumber` (required) | `Hex` | Number of the block the message is rooted to. |
|
|
285
|
+
| `category` (required) | `Hex` | 32-byte category hash. |
|
|
286
|
+
| `data` (required) | `Hex` | Arbitrary message data. |
|
|
287
|
+
| `nonce` (required) | `Hex` | Nonce discovered through proof of work. |
|
|
288
|
+
| `hash` (required) | `Hex` | The message hash. |
|
|
289
|
+
| `workMultiplier` (required) | `Hex` | Work multiplier in force when posted. |
|
|
290
|
+
| `workDivisor` (required) | `Hex` | Work divisor in force when posted. |
|
|
291
|
+
|
|
292
|
+
### Content
|
|
293
|
+
|
|
294
|
+
Messages grouped by category hash.
|
|
295
|
+
|
|
296
|
+
Object whose values are `RPCMessage[]`.
|
|
297
|
+
|
|
298
|
+
<!-- GENERATED:OPENRPC:END -->
|
|
299
|
+
|
|
300
|
+
## Client methods (not JSON-RPC)
|
|
301
|
+
|
|
302
|
+
These run in the client, not on the node, so they are not in the OpenRPC spec:
|
|
303
|
+
|
|
304
|
+
- `doPoW(category, data, limit?)` — grind a valid proof-of-work message. Returns `{ message, stats }`.
|
|
305
|
+
- `getDifficulty(data)` — the difficulty for a given payload, as a `bigint`.
|
|
306
|
+
- Utilities: `categoryHash`, `checkWork`, `difficulty`, `encodeData`, `toRLP`, `fromRLP`, `fromRPCMessage`, `toRPCMessage`, `wrapLegacySend`.
|
|
307
|
+
|
|
308
|
+
## Machine-readable spec
|
|
309
|
+
|
|
310
|
+
The JSON-RPC surface is published as an OpenRPC document at `openrpc.json` in this package. Point the OpenRPC Playground or a code generator at it.
|
|
311
|
+
|
|
312
|
+
## License
|
|
313
|
+
|
|
314
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { type Hex } from 'viem';
|
|
2
|
+
import type { Config, Content, ContentFilter, DifficultyFactors, Logger, MessageSeed, Provider, RPCMessage, Status, WorkResult, WorkStats } from '@msgboard/core';
|
|
3
|
+
export * from '@msgboard/core';
|
|
4
|
+
/**
|
|
5
|
+
* MsgboardClient can be used for interacting with the msgboard API
|
|
6
|
+
* and performing necessary work to find valid messages.
|
|
7
|
+
*/
|
|
8
|
+
export declare class MsgBoardClient {
|
|
9
|
+
protected provider: Provider;
|
|
10
|
+
private _difficultyFactors;
|
|
11
|
+
log: Logger;
|
|
12
|
+
breakInterval: bigint;
|
|
13
|
+
cancelled: boolean;
|
|
14
|
+
progressHandler: (stats: WorkStats) => void;
|
|
15
|
+
version: number;
|
|
16
|
+
constructor(provider: Provider, config?: Config);
|
|
17
|
+
get difficultyFactors(): DifficultyFactors;
|
|
18
|
+
set difficultyFactors(factors: DifficultyFactors);
|
|
19
|
+
/** Can be called to cancel a doPoW operation in progress. */
|
|
20
|
+
cancel(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Starts a busy work loop, in search of a nonce to create a valid pow message
|
|
23
|
+
* with the given inputs and configured difficulty.
|
|
24
|
+
* @param category The 32-byte hash or string to be used as the message category
|
|
25
|
+
* @param data the data bytes or string to embed in the message
|
|
26
|
+
* @param limit an optional limit to the number of iterations that will be attempted
|
|
27
|
+
* @returns a promise that will resolve with a valid work object, containing a pow
|
|
28
|
+
* message that can be submitted to the API and a stats object about the work that was done
|
|
29
|
+
*/
|
|
30
|
+
doPoW(category: Hex | string, data: Hex | string, limit?: bigint): Promise<WorkResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Fetches the latest block from the RPC.
|
|
33
|
+
* @returns the block details
|
|
34
|
+
* @throws error responses from the RPC
|
|
35
|
+
*/
|
|
36
|
+
lastestBlock(): Promise<{
|
|
37
|
+
hash: Hex;
|
|
38
|
+
number: Hex;
|
|
39
|
+
}>;
|
|
40
|
+
/**
|
|
41
|
+
* Submits a message to the board RPC.
|
|
42
|
+
* @param input the RLP encoded message to add
|
|
43
|
+
* @returns the message hash
|
|
44
|
+
* @throws error responses from the RPC
|
|
45
|
+
*/
|
|
46
|
+
addMessage(input: Hex | MessageSeed): Promise<`0x${string}`>;
|
|
47
|
+
/**
|
|
48
|
+
* Fetches a message from the board RPC.
|
|
49
|
+
* @param category category to lookup message
|
|
50
|
+
* @param msgHash hash of the message to look up message on RPC
|
|
51
|
+
* @returns a message from the RPC
|
|
52
|
+
* @throws error responses from the RPC
|
|
53
|
+
*/
|
|
54
|
+
getMessage(msgHash: Hex): Promise<RPCMessage>;
|
|
55
|
+
/**
|
|
56
|
+
* Fetches message categories from the board RPC.
|
|
57
|
+
* @returns the list category hashes available on the board
|
|
58
|
+
* @throws error responses from the RPC
|
|
59
|
+
*/
|
|
60
|
+
categories(): Promise<`0x${string}`[]>;
|
|
61
|
+
/**
|
|
62
|
+
* Fetches all messages from the board RPC.
|
|
63
|
+
* @returns the board messages, grouped by category
|
|
64
|
+
* @throws error responses from the RPC
|
|
65
|
+
*/
|
|
66
|
+
content(filter?: ContentFilter): Promise<Content>;
|
|
67
|
+
/**
|
|
68
|
+
* Fetches the status of the msgboard from the board RPC.
|
|
69
|
+
* @returns the status info of the msgboard
|
|
70
|
+
* @throws error responses from the RPC
|
|
71
|
+
*/
|
|
72
|
+
status(): Promise<Status>;
|
|
73
|
+
/**
|
|
74
|
+
* Updates the difficulty factors for performing message work.
|
|
75
|
+
* @param workMultiplier the work multiplier increases difficulty
|
|
76
|
+
* @param workDivisor the work divisor decreases difficulty
|
|
77
|
+
*/
|
|
78
|
+
setDifficultyFactors(workMultiplier: bigint, workDivisor: bigint): void;
|
|
79
|
+
/**
|
|
80
|
+
* Calculates the difficulty for a given message.
|
|
81
|
+
* @param data the data bytes or string to embed in the message
|
|
82
|
+
* @returns the difficulty
|
|
83
|
+
*/
|
|
84
|
+
getDifficulty(data: Hex): bigint;
|
|
85
|
+
/**
|
|
86
|
+
* Calls the provider RPC directly
|
|
87
|
+
* @param method the method to call
|
|
88
|
+
* @param params the parameters to pass to the method
|
|
89
|
+
* @returns the response from the RPC
|
|
90
|
+
*/
|
|
91
|
+
request<T, U extends unknown[]>(arg: {
|
|
92
|
+
method: string;
|
|
93
|
+
params: U;
|
|
94
|
+
}): Promise<T>;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAwB,MAAM,MAAM,CAAA;AAErD,OAAO,KAAK,EACV,MAAM,EACN,OAAO,EACP,aAAa,EACb,iBAAiB,EACjB,MAAM,EAEN,WAAW,EACX,QAAQ,EACR,UAAU,EACV,MAAM,EACN,UAAU,EACV,SAAS,EACV,MAAM,gBAAgB,CAAA;AAGvB,cAAc,gBAAgB,CAAA;AAO9B;;;GAGG;AACH,qBAAa,cAAc;IAcvB,SAAS,CAAC,QAAQ,EAAE,QAAQ;IAb9B,OAAO,CAAC,kBAAkB,CAAmB;IAE7C,GAAG,EAAE,MAAM,CAAA;IAEX,aAAa,EAAE,MAAM,CAAA;IAErB,SAAS,EAAE,OAAO,CAAQ;IAE1B,eAAe,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAA;IAE3C,OAAO,EAAE,MAAM,CAAI;gBAGP,QAAQ,EAAE,QAAQ,EAC5B,MAAM,GAAE,MAAW;IAYrB,IAAI,iBAAiB,IAMU,iBAAiB,CAD/C;IACD,IAAI,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,EAK/C;IAED,6DAA6D;IAC7D,MAAM;IAIN;;;;;;;;OAQG;IACG,KAAK,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,MAAM,EAAE,KAAK,SAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IA8EnG;;;;OAIG;IACG,YAAY;cACY,GAAG;gBAAU,GAAG;;IAM9C;;;;;OAKG;IACG,UAAU,CAAC,KAAK,EAAE,GAAG,GAAG,WAAW;IAKzC;;;;;;OAMG;IACG,UAAU,CAAC,OAAO,EAAE,GAAG;IAI7B;;;;OAIG;IACG,UAAU;IAIhB;;;;OAIG;IACG,OAAO,CAAC,MAAM,GAAE,aAAkB;IAIxC;;;;OAIG;IACG,MAAM;IAIZ;;;;OAIG;IACH,oBAAoB,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAGhE;;;;OAIG;IACH,aAAa,CAAC,IAAI,EAAE,GAAG;IAIvB;;;;;OAKG;IACG,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,EAAE,EAAE,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC;CAItF"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.MsgBoardClient = void 0;
|
|
21
|
+
const viem_1 = require("viem");
|
|
22
|
+
const logger_js_1 = __importDefault(require("./logger.js"));
|
|
23
|
+
const core_1 = require("@msgboard/core");
|
|
24
|
+
__exportStar(require("@msgboard/core"), exports);
|
|
25
|
+
const veryHighLimit = 100000000n;
|
|
26
|
+
// eslint-disable-next-line
|
|
27
|
+
const defaultLogger = (prefix, ...args) => (0, logger_js_1.default)(prefix, ...args);
|
|
28
|
+
/**
|
|
29
|
+
* MsgboardClient can be used for interacting with the msgboard API
|
|
30
|
+
* and performing necessary work to find valid messages.
|
|
31
|
+
*/
|
|
32
|
+
class MsgBoardClient {
|
|
33
|
+
provider;
|
|
34
|
+
_difficultyFactors;
|
|
35
|
+
log;
|
|
36
|
+
breakInterval;
|
|
37
|
+
cancelled = false;
|
|
38
|
+
progressHandler;
|
|
39
|
+
version = 1;
|
|
40
|
+
constructor(provider, config = {}) {
|
|
41
|
+
this.provider = provider;
|
|
42
|
+
this._difficultyFactors = {
|
|
43
|
+
workMultiplier: 10000n,
|
|
44
|
+
workDivisor: 1000000n,
|
|
45
|
+
...(config.difficultyFactors ?? {}),
|
|
46
|
+
};
|
|
47
|
+
this.log = config.logger || defaultLogger;
|
|
48
|
+
this.breakInterval = config.breakInterval || 10000n;
|
|
49
|
+
this.progressHandler = config.progress || (() => { });
|
|
50
|
+
}
|
|
51
|
+
get difficultyFactors() {
|
|
52
|
+
return {
|
|
53
|
+
workMultiplier: this._difficultyFactors.workMultiplier,
|
|
54
|
+
workDivisor: this._difficultyFactors.workDivisor,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
set difficultyFactors(factors) {
|
|
58
|
+
this._difficultyFactors = {
|
|
59
|
+
...this._difficultyFactors,
|
|
60
|
+
...factors,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** Can be called to cancel a doPoW operation in progress. */
|
|
64
|
+
cancel() {
|
|
65
|
+
this.cancelled = true;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Starts a busy work loop, in search of a nonce to create a valid pow message
|
|
69
|
+
* with the given inputs and configured difficulty.
|
|
70
|
+
* @param category The 32-byte hash or string to be used as the message category
|
|
71
|
+
* @param data the data bytes or string to embed in the message
|
|
72
|
+
* @param limit an optional limit to the number of iterations that will be attempted
|
|
73
|
+
* @returns a promise that will resolve with a valid work object, containing a pow
|
|
74
|
+
* message that can be submitted to the API and a stats object about the work that was done
|
|
75
|
+
*/
|
|
76
|
+
async doPoW(category, data, limit = veryHighLimit) {
|
|
77
|
+
this.log('starting pow on message');
|
|
78
|
+
this.cancelled = false;
|
|
79
|
+
let killPoll = false;
|
|
80
|
+
const message = {
|
|
81
|
+
blockHash: viem_1.zeroHash,
|
|
82
|
+
blockNumber: 0n,
|
|
83
|
+
category: (0, core_1.categoryHash)(category),
|
|
84
|
+
data: (0, core_1.encodeData)(data),
|
|
85
|
+
hash: viem_1.zeroHash,
|
|
86
|
+
nonce: 0n,
|
|
87
|
+
version: this.version,
|
|
88
|
+
workMultiplier: this.difficultyFactors.workMultiplier,
|
|
89
|
+
workDivisor: this.difficultyFactors.workDivisor,
|
|
90
|
+
};
|
|
91
|
+
const dataLen = (0, viem_1.hexToBytes)(message.data).length;
|
|
92
|
+
const stats = {
|
|
93
|
+
difficulty: (0, core_1.difficulty)(this.difficultyFactors, dataLen),
|
|
94
|
+
duration: 0,
|
|
95
|
+
isValid: false,
|
|
96
|
+
iterations: 0n,
|
|
97
|
+
};
|
|
98
|
+
// if we want to support multiple pow searches,
|
|
99
|
+
// then we need to move this polling outside of this method
|
|
100
|
+
// otherwise get block will be fetching at a commenserate rate
|
|
101
|
+
// to the number of outstanding pow searches are currently running
|
|
102
|
+
const getBlock = async () => {
|
|
103
|
+
if (killPoll)
|
|
104
|
+
return;
|
|
105
|
+
const { hash, ...block } = await this.lastestBlock();
|
|
106
|
+
const number = BigInt(block.number);
|
|
107
|
+
if (!killPoll && (message.blockNumber === 0n || message.blockNumber !== number)) {
|
|
108
|
+
message.blockHash = hash;
|
|
109
|
+
message.blockNumber = number;
|
|
110
|
+
this.log('updated block info %o@%o', hash, number);
|
|
111
|
+
}
|
|
112
|
+
// queue next operation
|
|
113
|
+
setTimeout(() => {
|
|
114
|
+
getBlock().catch(logger_js_1.default);
|
|
115
|
+
}, 1_000);
|
|
116
|
+
};
|
|
117
|
+
// start the polling for block updates
|
|
118
|
+
await getBlock();
|
|
119
|
+
const { breakInterval } = this;
|
|
120
|
+
const start = Date.now();
|
|
121
|
+
this.progressHandler({ ...stats });
|
|
122
|
+
while (true) {
|
|
123
|
+
if (this.cancelled) {
|
|
124
|
+
killPoll = true;
|
|
125
|
+
return { message, stats };
|
|
126
|
+
}
|
|
127
|
+
message.nonce += 1n;
|
|
128
|
+
stats.duration = Date.now() - start;
|
|
129
|
+
stats.iterations += 1n;
|
|
130
|
+
const hash = (0, core_1.checkWork)(message, stats.difficulty);
|
|
131
|
+
if (hash) {
|
|
132
|
+
message.hash = hash;
|
|
133
|
+
stats.isValid = true;
|
|
134
|
+
killPoll = true;
|
|
135
|
+
return { message, stats };
|
|
136
|
+
}
|
|
137
|
+
if (stats.iterations >= limit) {
|
|
138
|
+
killPoll = true;
|
|
139
|
+
throw new Error('limit met');
|
|
140
|
+
}
|
|
141
|
+
if (breakInterval && message.nonce % breakInterval === 0n) {
|
|
142
|
+
this.progressHandler({ ...stats });
|
|
143
|
+
// pauses the PoW busy loop to allow the event loop to resolve the block updates
|
|
144
|
+
await new Promise((resolve) => {
|
|
145
|
+
setTimeout(resolve, 10);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Fetches the latest block from the RPC.
|
|
152
|
+
* @returns the block details
|
|
153
|
+
* @throws error responses from the RPC
|
|
154
|
+
*/
|
|
155
|
+
async lastestBlock() {
|
|
156
|
+
return this.request({
|
|
157
|
+
method: 'eth_getBlockByNumber',
|
|
158
|
+
params: ['latest', false],
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Submits a message to the board RPC.
|
|
163
|
+
* @param input the RLP encoded message to add
|
|
164
|
+
* @returns the message hash
|
|
165
|
+
* @throws error responses from the RPC
|
|
166
|
+
*/
|
|
167
|
+
async addMessage(input) {
|
|
168
|
+
const rlp = typeof input !== 'string' ? (0, core_1.toRLP)(input) : input;
|
|
169
|
+
return this.request({ method: 'msgboard_addMessage', params: [rlp] });
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Fetches a message from the board RPC.
|
|
173
|
+
* @param category category to lookup message
|
|
174
|
+
* @param msgHash hash of the message to look up message on RPC
|
|
175
|
+
* @returns a message from the RPC
|
|
176
|
+
* @throws error responses from the RPC
|
|
177
|
+
*/
|
|
178
|
+
async getMessage(msgHash) {
|
|
179
|
+
return this.request({ method: 'msgboard_getMessage', params: [msgHash] });
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Fetches message categories from the board RPC.
|
|
183
|
+
* @returns the list category hashes available on the board
|
|
184
|
+
* @throws error responses from the RPC
|
|
185
|
+
*/
|
|
186
|
+
async categories() {
|
|
187
|
+
return this.request({ method: 'msgboard_categories', params: [] });
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Fetches all messages from the board RPC.
|
|
191
|
+
* @returns the board messages, grouped by category
|
|
192
|
+
* @throws error responses from the RPC
|
|
193
|
+
*/
|
|
194
|
+
async content(filter = {}) {
|
|
195
|
+
return this.request({ method: 'msgboard_content', params: [filter] });
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Fetches the status of the msgboard from the board RPC.
|
|
199
|
+
* @returns the status info of the msgboard
|
|
200
|
+
* @throws error responses from the RPC
|
|
201
|
+
*/
|
|
202
|
+
async status() {
|
|
203
|
+
return this.request({ method: 'msgboard_status', params: [] });
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Updates the difficulty factors for performing message work.
|
|
207
|
+
* @param workMultiplier the work multiplier increases difficulty
|
|
208
|
+
* @param workDivisor the work divisor decreases difficulty
|
|
209
|
+
*/
|
|
210
|
+
setDifficultyFactors(workMultiplier, workDivisor) {
|
|
211
|
+
this.difficultyFactors = { workMultiplier, workDivisor };
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Calculates the difficulty for a given message.
|
|
215
|
+
* @param data the data bytes or string to embed in the message
|
|
216
|
+
* @returns the difficulty
|
|
217
|
+
*/
|
|
218
|
+
getDifficulty(data) {
|
|
219
|
+
return (0, core_1.difficulty)(this.difficultyFactors, (0, viem_1.hexToBytes)(data).length);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Calls the provider RPC directly
|
|
223
|
+
* @param method the method to call
|
|
224
|
+
* @param params the parameters to pass to the method
|
|
225
|
+
* @returns the response from the RPC
|
|
226
|
+
*/
|
|
227
|
+
async request(arg) {
|
|
228
|
+
this.log('%s(%o)', arg.method, arg.params);
|
|
229
|
+
return this.provider.request(arg);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
exports.MsgBoardClient = MsgBoardClient;
|
|
233
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,+BAAqD;AACrD,4DAA6B;AAe7B,yCAAuF;AAEvF,iDAA8B;AAE9B,MAAM,aAAa,GAAG,UAAY,CAAA;AAElC,2BAA2B;AAC3B,MAAM,aAAa,GAAG,CAAC,MAAc,EAAE,GAAG,IAAW,EAAE,EAAE,CAAC,IAAA,mBAAG,EAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAA;AAE9E;;;GAGG;AACH,MAAa,cAAc;IAcb;IAbJ,kBAAkB,CAAmB;IAE7C,GAAG,CAAQ;IAEX,aAAa,CAAQ;IAErB,SAAS,GAAY,KAAK,CAAA;IAE1B,eAAe,CAA4B;IAE3C,OAAO,GAAW,CAAC,CAAA;IAEnB,YACY,QAAkB,EAC5B,SAAiB,EAAE;QADT,aAAQ,GAAR,QAAQ,CAAU;QAG5B,IAAI,CAAC,kBAAkB,GAAG;YACxB,cAAc,EAAE,MAAO;YACvB,WAAW,EAAE,QAAU;YACvB,GAAG,CAAC,MAAM,CAAC,iBAAiB,IAAI,EAAE,CAAC;SACpC,CAAA;QACD,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,aAAa,CAAA;QACzC,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,MAAO,CAAA;QACpD,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,QAAQ,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IACtD,CAAC;IAED,IAAI,iBAAiB;QACnB,OAAO;YACL,cAAc,EAAE,IAAI,CAAC,kBAAkB,CAAC,cAAc;YACtD,WAAW,EAAE,IAAI,CAAC,kBAAkB,CAAC,WAAW;SACjD,CAAA;IACH,CAAC;IACD,IAAI,iBAAiB,CAAC,OAA0B;QAC9C,IAAI,CAAC,kBAAkB,GAAG;YACxB,GAAG,IAAI,CAAC,kBAAkB;YAC1B,GAAG,OAAO;SACX,CAAA;IACH,CAAC;IAED,6DAA6D;IAC7D,MAAM;QACJ,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;IACvB,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,KAAK,CAAC,QAAsB,EAAE,IAAkB,EAAE,KAAK,GAAG,aAAa;QAC3E,IAAI,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;QACnC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAA;QACtB,IAAI,QAAQ,GAAG,KAAK,CAAA;QACpB,MAAM,OAAO,GAAY;YACvB,SAAS,EAAE,eAAQ;YACnB,WAAW,EAAE,EAAE;YACf,QAAQ,EAAE,IAAA,mBAAY,EAAC,QAAQ,CAAC;YAChC,IAAI,EAAE,IAAA,iBAAU,EAAC,IAAI,CAAC;YACtB,IAAI,EAAE,eAAQ;YACd,KAAK,EAAE,EAAE;YACT,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,cAAc,EAAE,IAAI,CAAC,iBAAiB,CAAC,cAAc;YACrD,WAAW,EAAE,IAAI,CAAC,iBAAiB,CAAC,WAAW;SAChD,CAAA;QACD,MAAM,OAAO,GAAG,IAAA,iBAAU,EAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAA;QAC/C,MAAM,KAAK,GAAc;YACvB,UAAU,EAAE,IAAA,iBAAU,EAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC;YACvD,QAAQ,EAAE,CAAC;YACX,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,EAAE;SACf,CAAA;QAED,+CAA+C;QAC/C,2DAA2D;QAC3D,8DAA8D;QAC9D,kEAAkE;QAClE,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;YAC1B,IAAI,QAAQ;gBAAE,OAAM;YACpB,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAA;YACpD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YACnC,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,EAAE,IAAI,OAAO,CAAC,WAAW,KAAK,MAAM,CAAC,EAAE,CAAC;gBAChF,OAAO,CAAC,SAAS,GAAG,IAAI,CAAA;gBACxB,OAAO,CAAC,WAAW,GAAG,MAAM,CAAA;gBAC5B,IAAI,CAAC,GAAG,CAAC,0BAA0B,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;YACpD,CAAC;YACD,uBAAuB;YACvB,UAAU,CAAC,GAAG,EAAE;gBACd,QAAQ,EAAE,CAAC,KAAK,CAAC,mBAAG,CAAC,CAAA;YACvB,CAAC,EAAE,KAAK,CAAC,CAAA;QACX,CAAC,CAAA;QACD,sCAAsC;QACtC,MAAM,QAAQ,EAAE,CAAA;QAChB,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAA;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACxB,IAAI,CAAC,eAAe,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAA;QAElC,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,QAAQ,GAAG,IAAI,CAAA;gBACf,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;YAC3B,CAAC;YACD,OAAO,CAAC,KAAK,IAAI,EAAE,CAAA;YACnB,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAA;YACnC,KAAK,CAAC,UAAU,IAAI,EAAE,CAAA;YACtB,MAAM,IAAI,GAAG,IAAA,gBAAS,EAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,CAAA;YACjD,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO,CAAC,IAAI,GAAG,IAAI,CAAA;gBACnB,KAAK,CAAC,OAAO,GAAG,IAAI,CAAA;gBACpB,QAAQ,GAAG,IAAI,CAAA;gBACf,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;YAC3B,CAAC;YAED,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,EAAE,CAAC;gBAC9B,QAAQ,GAAG,IAAI,CAAA;gBACf,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,CAAA;YAC9B,CAAC;YAED,IAAI,aAAa,IAAI,OAAO,CAAC,KAAK,GAAG,aAAa,KAAK,EAAE,EAAE,CAAC;gBAC1D,IAAI,CAAC,eAAe,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAA;gBAClC,gFAAgF;gBAChF,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;oBAC5B,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;gBACzB,CAAC,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,YAAY;QAChB,OAAO,IAAI,CAAC,OAAO,CAAgD;YACjE,MAAM,EAAE,sBAAsB;YAC9B,MAAM,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC;SAC1B,CAAC,CAAA;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,UAAU,CAAC,KAAwB;QACvC,MAAM,GAAG,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAA,YAAK,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;QAC5D,OAAO,IAAI,CAAC,OAAO,CAAa,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACnF,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,UAAU,CAAC,OAAY;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAoB,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAC9F,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,UAAU;QACd,OAAO,IAAI,CAAC,OAAO,CAAY,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAA;IAC/E,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,SAAwB,EAAE;QACtC,OAAO,IAAI,CAAC,OAAO,CAA2B,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACjG,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM;QACV,OAAO,IAAI,CAAC,OAAO,CAAa,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAA;IAC5E,CAAC;IAED;;;;OAIG;IACH,oBAAoB,CAAC,cAAsB,EAAE,WAAmB;QAC9D,IAAI,CAAC,iBAAiB,GAAG,EAAE,cAAc,EAAE,WAAW,EAAE,CAAA;IAC1D,CAAC;IACD;;;;OAIG;IACH,aAAa,CAAC,IAAS;QACrB,OAAO,IAAA,iBAAU,EAAC,IAAI,CAAC,iBAAiB,EAAE,IAAA,iBAAU,EAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAA;IACpE,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,OAAO,CAAyB,GAAkC;QACtE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;QAC1C,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACnC,CAAC;CACF;AA5ND,wCA4NC"}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;;AAEzB,wBAAgC"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const debug_1 = __importDefault(require("debug"));
|
|
7
|
+
exports.default = (0, debug_1.default)('msgboard');
|
|
8
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";;;;;AAAA,kDAAyB;AAEzB,kBAAe,IAAA,eAAK,EAAC,UAAU,CAAC,CAAA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Renders an OpenRPC document into a markdown API reference. Pure: no file I/O. */
|
|
2
|
+
type Schema = {
|
|
3
|
+
$ref?: string;
|
|
4
|
+
title?: string;
|
|
5
|
+
type?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
pattern?: string;
|
|
8
|
+
items?: Schema;
|
|
9
|
+
properties?: Record<string, Schema>;
|
|
10
|
+
required?: string[];
|
|
11
|
+
additionalProperties?: Schema | boolean;
|
|
12
|
+
};
|
|
13
|
+
type Param = {
|
|
14
|
+
name: string;
|
|
15
|
+
required?: boolean;
|
|
16
|
+
schema: Schema;
|
|
17
|
+
};
|
|
18
|
+
type Method = {
|
|
19
|
+
name: string;
|
|
20
|
+
summary?: string;
|
|
21
|
+
params: Param[];
|
|
22
|
+
result: {
|
|
23
|
+
name: string;
|
|
24
|
+
schema: Schema;
|
|
25
|
+
};
|
|
26
|
+
examples?: Array<{
|
|
27
|
+
name: string;
|
|
28
|
+
params: Array<{
|
|
29
|
+
value: unknown;
|
|
30
|
+
}>;
|
|
31
|
+
result: {
|
|
32
|
+
value: unknown;
|
|
33
|
+
};
|
|
34
|
+
}>;
|
|
35
|
+
};
|
|
36
|
+
type Doc = {
|
|
37
|
+
methods: Method[];
|
|
38
|
+
components: {
|
|
39
|
+
schemas: Record<string, Schema>;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
export declare const renderReference: (doc: Doc) => string;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=render-reference.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-reference.d.ts","sourceRoot":"","sources":["../src/render-reference.ts"],"names":[],"mappings":"AAAA,oFAAoF;AAEpF,KAAK,MAAM,GAAG;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,oBAAoB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACxC,CAAA;AACD,KAAK,KAAK,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AACjE,KAAK,MAAM,GAAG;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IACxC,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;QAAC,MAAM,EAAE;YAAE,KAAK,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE,CAAC,CAAA;CAClG,CAAA;AACD,KAAK,GAAG,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAA;CAAE,CAAA;AA0DjF,eAAO,MAAM,eAAe,GAAI,KAAK,GAAG,KAAG,MAO1C,CAAA"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** Renders an OpenRPC document into a markdown API reference. Pure: no file I/O. */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.renderReference = void 0;
|
|
5
|
+
const refName = (schema) => {
|
|
6
|
+
if (schema.$ref)
|
|
7
|
+
return schema.$ref.split('/').pop();
|
|
8
|
+
if (schema.type === 'array' && schema.items)
|
|
9
|
+
return `${refName(schema.items)}[]`;
|
|
10
|
+
return schema.type ?? 'any';
|
|
11
|
+
};
|
|
12
|
+
const renderMethod = (m) => {
|
|
13
|
+
const lines = [];
|
|
14
|
+
lines.push(`### ${m.name}`, '');
|
|
15
|
+
if (m.summary)
|
|
16
|
+
lines.push(m.summary, '');
|
|
17
|
+
lines.push('| Parameter | Type | Required |', '| --- | --- | --- |');
|
|
18
|
+
if (m.params.length === 0) {
|
|
19
|
+
lines.push('| _(none)_ | | |');
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
for (const p of m.params) {
|
|
23
|
+
lines.push(`| \`${p.name}\` | \`${refName(p.schema)}\` | ${p.required ? 'yes' : 'no'} |`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
lines.push('', `**Returns:** \`${refName(m.result.schema)}\``, '');
|
|
27
|
+
const example = m.examples?.[0];
|
|
28
|
+
if (example) {
|
|
29
|
+
const req = { jsonrpc: '2.0', id: 1, method: m.name, params: example.params.map((p) => p.value) };
|
|
30
|
+
const res = { jsonrpc: '2.0', id: 1, result: example.result.value };
|
|
31
|
+
lines.push('```json', JSON.stringify(req, null, 2), '```', '');
|
|
32
|
+
lines.push('```json', JSON.stringify(res, null, 2), '```', '');
|
|
33
|
+
}
|
|
34
|
+
return lines.join('\n');
|
|
35
|
+
};
|
|
36
|
+
const renderSchema = (name, schema) => {
|
|
37
|
+
const lines = [];
|
|
38
|
+
lines.push(`### ${name}`, '');
|
|
39
|
+
if (schema.description)
|
|
40
|
+
lines.push(schema.description, '');
|
|
41
|
+
if (schema.type === 'string' && schema.pattern) {
|
|
42
|
+
lines.push(`String matching \`${schema.pattern}\`.`, '');
|
|
43
|
+
return lines.join('\n');
|
|
44
|
+
}
|
|
45
|
+
if (schema.type === 'array' && schema.items) {
|
|
46
|
+
lines.push(`Array of \`${refName(schema.items)}\`.`, '');
|
|
47
|
+
return lines.join('\n');
|
|
48
|
+
}
|
|
49
|
+
if (schema.properties) {
|
|
50
|
+
lines.push('| Field | Type | Description |', '| --- | --- | --- |');
|
|
51
|
+
for (const [field, prop] of Object.entries(schema.properties)) {
|
|
52
|
+
const required = schema.required?.includes(field) ? ' (required)' : '';
|
|
53
|
+
lines.push(`| \`${field}\`${required} | \`${refName(prop)}\` | ${prop.description ?? ''} |`);
|
|
54
|
+
}
|
|
55
|
+
lines.push('');
|
|
56
|
+
return lines.join('\n');
|
|
57
|
+
}
|
|
58
|
+
if (typeof schema.additionalProperties === 'object') {
|
|
59
|
+
lines.push(`Object whose values are \`${refName(schema.additionalProperties)}\`.`, '');
|
|
60
|
+
}
|
|
61
|
+
return lines.join('\n');
|
|
62
|
+
};
|
|
63
|
+
const renderReference = (doc) => {
|
|
64
|
+
const out = [];
|
|
65
|
+
out.push('## JSON-RPC methods', '');
|
|
66
|
+
for (const m of doc.methods)
|
|
67
|
+
out.push(renderMethod(m));
|
|
68
|
+
out.push('## Schemas', '');
|
|
69
|
+
for (const [name, schema] of Object.entries(doc.components.schemas))
|
|
70
|
+
out.push(renderSchema(name, schema));
|
|
71
|
+
return out.join('\n').trimEnd() + '\n';
|
|
72
|
+
};
|
|
73
|
+
exports.renderReference = renderReference;
|
|
74
|
+
//# sourceMappingURL=render-reference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-reference.js","sourceRoot":"","sources":["../src/render-reference.ts"],"names":[],"mappings":"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"}
|
package/openrpc.json
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
{
|
|
2
|
+
"openrpc": "1.2.6",
|
|
3
|
+
"info": {
|
|
4
|
+
"title": "MsgBoard JSON-RPC API",
|
|
5
|
+
"version": "0.0.28",
|
|
6
|
+
"description": "JSON-RPC methods exposed by the msgboard_ module. Any node running the module serves these methods. Proof of work, not a fee, gates message submission.",
|
|
7
|
+
"license": { "name": "MIT" }
|
|
8
|
+
},
|
|
9
|
+
"methods": [
|
|
10
|
+
{
|
|
11
|
+
"name": "msgboard_status",
|
|
12
|
+
"summary": "Board status and the difficulty factors required for valid messages.",
|
|
13
|
+
"params": [],
|
|
14
|
+
"result": { "name": "status", "schema": { "$ref": "#/components/schemas/Status" } },
|
|
15
|
+
"examples": [
|
|
16
|
+
{ "name": "default", "params": [], "result": { "name": "status", "value": { "enabled": true, "count": "0x0", "size": "0x0", "workMultiplier": "0x2710", "workDivisor": "0xf4240" } } }
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "msgboard_categories",
|
|
21
|
+
"summary": "The list of 32-byte category hashes currently present on the board.",
|
|
22
|
+
"params": [],
|
|
23
|
+
"result": { "name": "categories", "schema": { "$ref": "#/components/schemas/Categories" } },
|
|
24
|
+
"examples": [
|
|
25
|
+
{ "name": "gasmoneyplease", "params": [], "result": { "name": "categories", "value": ["0x6761736d6f6e6579706c65617365000000000000000000000000000000000000"] } }
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "msgboard_content",
|
|
30
|
+
"summary": "All messages on the board, grouped by category hash. Optionally filtered.",
|
|
31
|
+
"params": [ { "name": "filter", "required": false, "schema": { "$ref": "#/components/schemas/ContentFilter" } } ],
|
|
32
|
+
"result": { "name": "content", "schema": { "$ref": "#/components/schemas/Content" } },
|
|
33
|
+
"examples": [
|
|
34
|
+
{ "name": "empty", "params": [{ "name": "filter", "value": {} }], "result": { "name": "content", "value": {} } }
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"name": "msgboard_addMessage",
|
|
39
|
+
"summary": "Submit a proof-of-work message (RLP-encoded) to the board.",
|
|
40
|
+
"params": [ { "name": "rlp", "required": true, "schema": { "$ref": "#/components/schemas/Hex" } } ],
|
|
41
|
+
"result": { "name": "hash", "schema": { "$ref": "#/components/schemas/Hex" } },
|
|
42
|
+
"examples": [
|
|
43
|
+
{ "name": "submit", "params": [{ "name": "rlp", "value": "0xf800" }], "result": { "name": "hash", "value": "0x0d1e2f00000000000000000000000000000000000000000000000000c46845f9" } }
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "msgboard_getMessage",
|
|
48
|
+
"summary": "Fetch a single message by its hash.",
|
|
49
|
+
"params": [ { "name": "hash", "required": true, "schema": { "$ref": "#/components/schemas/Hex" } } ],
|
|
50
|
+
"result": { "name": "message", "schema": { "$ref": "#/components/schemas/RPCMessage" } },
|
|
51
|
+
"examples": [
|
|
52
|
+
{ "name": "zero", "params": [{ "name": "hash", "value": "0x0000000000000000000000000000000000000000000000000000000000000000" }], "result": { "name": "message", "value": { "version": "0x1", "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x0", "category": "0x0000000000000000000000000000000000000000000000000000000000000000", "data": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0", "hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "workMultiplier": "0x0", "workDivisor": "0x0" } } }
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
"components": {
|
|
57
|
+
"schemas": {
|
|
58
|
+
"Hex": { "title": "Hex", "type": "string", "pattern": "^0x[0-9a-fA-F]*$" },
|
|
59
|
+
"Status": {
|
|
60
|
+
"title": "Status", "type": "object",
|
|
61
|
+
"required": ["enabled", "count", "size", "workMultiplier", "workDivisor"],
|
|
62
|
+
"properties": {
|
|
63
|
+
"enabled": { "type": "boolean", "description": "Whether the module is enabled on this node." },
|
|
64
|
+
"count": { "$ref": "#/components/schemas/Hex", "description": "Overall count of messages stored on the board." },
|
|
65
|
+
"size": { "$ref": "#/components/schemas/Hex", "description": "Overall size of messages stored on the board." },
|
|
66
|
+
"workMultiplier": { "$ref": "#/components/schemas/Hex", "description": "Factor that increases required work." },
|
|
67
|
+
"workDivisor": { "$ref": "#/components/schemas/Hex", "description": "Factor that decreases required work." }
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"Categories": { "title": "Categories", "type": "array", "items": { "$ref": "#/components/schemas/Hex" } },
|
|
71
|
+
"ContentFilter": {
|
|
72
|
+
"title": "ContentFilter", "type": "object",
|
|
73
|
+
"properties": {
|
|
74
|
+
"category": { "$ref": "#/components/schemas/Hex", "description": "Restrict to one category hash." },
|
|
75
|
+
"fromBlock": { "$ref": "#/components/schemas/Hex", "description": "Lower block bound (hex quantity)." },
|
|
76
|
+
"toBlock": { "$ref": "#/components/schemas/Hex", "description": "Upper block bound (hex quantity)." }
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"RPCMessage": {
|
|
80
|
+
"title": "RPCMessage", "type": "object",
|
|
81
|
+
"required": ["version", "blockHash", "blockNumber", "category", "data", "nonce", "hash", "workMultiplier", "workDivisor"],
|
|
82
|
+
"properties": {
|
|
83
|
+
"version": { "$ref": "#/components/schemas/Hex", "description": "Message/encoding version." },
|
|
84
|
+
"blockHash": { "$ref": "#/components/schemas/Hex", "description": "Hash of the block the message is rooted to." },
|
|
85
|
+
"blockNumber": { "$ref": "#/components/schemas/Hex", "description": "Number of the block the message is rooted to." },
|
|
86
|
+
"category": { "$ref": "#/components/schemas/Hex", "description": "32-byte category hash." },
|
|
87
|
+
"data": { "$ref": "#/components/schemas/Hex", "description": "Arbitrary message data." },
|
|
88
|
+
"nonce": { "$ref": "#/components/schemas/Hex", "description": "Nonce discovered through proof of work." },
|
|
89
|
+
"hash": { "$ref": "#/components/schemas/Hex", "description": "The message hash." },
|
|
90
|
+
"workMultiplier": { "$ref": "#/components/schemas/Hex", "description": "Work multiplier in force when posted." },
|
|
91
|
+
"workDivisor": { "$ref": "#/components/schemas/Hex", "description": "Work divisor in force when posted." }
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"Content": { "title": "Content", "type": "object", "description": "Messages grouped by category hash.", "additionalProperties": { "type": "array", "items": { "$ref": "#/components/schemas/RPCMessage" } } }
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@msgboard/sdk",
|
|
3
|
+
"version": "0.0.28",
|
|
4
|
+
"description": "MsgBoard client SDK for the msgboard_ JSON-RPC module",
|
|
5
|
+
"repository": "github:valve-tech/msgboard",
|
|
6
|
+
"author": "MsgBoard",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"module": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"commonjs": "./dist/index.js",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"require": "./dist/index.js",
|
|
18
|
+
"default": "./dist/index.js",
|
|
19
|
+
"import": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"ethereum",
|
|
25
|
+
"smart-contracts",
|
|
26
|
+
"pow",
|
|
27
|
+
"proof-of-work"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"lint:fix": "eslint --fix --format=stylish src",
|
|
31
|
+
"lint": "eslint --format=stylish src",
|
|
32
|
+
"test": "DEBUG=msgboard vitest run",
|
|
33
|
+
"prebuild": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
34
|
+
"build": "tsc",
|
|
35
|
+
"watch": "tsc -w",
|
|
36
|
+
"gen:docs": "tsx scripts/generate-reference.ts"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist/",
|
|
40
|
+
"openrpc.json"
|
|
41
|
+
],
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@eslint/js": "^9.25.1",
|
|
44
|
+
"@open-rpc/schema-utils-js": "^2.2.1",
|
|
45
|
+
"@types/bn.js": "^5.1.6",
|
|
46
|
+
"@types/debug": "^4.1.12",
|
|
47
|
+
"@types/elliptic": "^6.4.18",
|
|
48
|
+
"@typescript-eslint/eslint-plugin": "^8.29.0",
|
|
49
|
+
"@typescript-eslint/parser": "^8.29.0",
|
|
50
|
+
"eslint": "^9.23.0",
|
|
51
|
+
"eslint-config-prettier": "^10.1.2",
|
|
52
|
+
"eslint-plugin-prettier": "^5.2.6",
|
|
53
|
+
"ethers": "^6.13.5",
|
|
54
|
+
"globals": "^16.0.0",
|
|
55
|
+
"jiti": "^2.4.2",
|
|
56
|
+
"tsx": "^4.19.3",
|
|
57
|
+
"typescript": "^5.8.2",
|
|
58
|
+
"typescript-eslint": "^8.31.0",
|
|
59
|
+
"vitest": "^3.1.1"
|
|
60
|
+
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"@msgboard/core": "^0.0.1",
|
|
63
|
+
"bn.js": "^5.2.1",
|
|
64
|
+
"debug": "^4.4.0",
|
|
65
|
+
"elliptic": "^6.6.1",
|
|
66
|
+
"viem": "^2.25.0"
|
|
67
|
+
}
|
|
68
|
+
}
|