@msgboard/relayer 0.0.1 → 0.0.30
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 +59 -2
- package/dist/actions/forward-message.d.ts +13 -0
- package/dist/actions/forward-message.d.ts.map +1 -0
- package/dist/actions/forward-message.js +17 -0
- package/dist/actions/forward-message.js.map +1 -0
- package/dist/actions/send-value.d.ts.map +1 -1
- package/dist/actions/send-value.js +2 -2
- package/dist/actions/send-value.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/relayer.d.ts +2 -1
- package/dist/relayer.d.ts.map +1 -1
- package/dist/relayer.js +42 -25
- package/dist/relayer.js.map +1 -1
- package/dist/sinks/postgres-archive.js +1 -1
- package/dist/sinks/postgres-archive.js.map +1 -1
- package/dist/sources/http-queue.d.ts +55 -0
- package/dist/sources/http-queue.d.ts.map +1 -0
- package/dist/sources/http-queue.js +97 -0
- package/dist/sources/http-queue.js.map +1 -0
- package/dist/types.d.ts +9 -6
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
A controllable, safe-by-default pool-watcher engine for the msgboard board. Runs a heartbeat: poll a **Source**, record every item to an always-on **Sink**, filter by a **Condition**, dedup via a **Store**, then gate the **Action** based on mode.
|
|
4
4
|
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm i @msgboard/relayer
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
`pg` is an optional peer dependency — only required if you use `postgresStore` or `postgresArchiveSink`.
|
|
12
|
+
|
|
5
13
|
## Safe by default
|
|
6
14
|
|
|
7
15
|
The engine has two modes:
|
|
@@ -23,10 +31,12 @@ Sink and Store are intentionally separate: the sink runs in **both** modes; the
|
|
|
23
31
|
## Minimal usage
|
|
24
32
|
|
|
25
33
|
```ts
|
|
34
|
+
import { http } from 'viem'
|
|
26
35
|
import { Relayer, msgboardContentSource, noopAction } from '@msgboard/relayer'
|
|
27
36
|
|
|
28
37
|
const relayer = new Relayer({
|
|
29
|
-
node: {
|
|
38
|
+
node: { transport: http('https://rpc.pulsechain.com') },
|
|
39
|
+
// chain auto-detected via eth_chainId; pass node.chain to override
|
|
30
40
|
// mode defaults to 'observe' — no on-chain writes
|
|
31
41
|
source: msgboardContentSource({ category: 'myapp' }),
|
|
32
42
|
key: (msg) => msg.hash,
|
|
@@ -51,6 +61,52 @@ const recent = await archive.query({ chainId: 943, category: 'lorem', limit: 20
|
|
|
51
61
|
|
|
52
62
|
`query()` filters by `chainId`, `category` (hex or decoded text), `since`/`until`, `contains` (substring match on decoded content), `limit`, and `offset`.
|
|
53
63
|
|
|
64
|
+
## "Write for me" relay
|
|
65
|
+
|
|
66
|
+
A push-based relay pattern where clients solve proof-of-work locally and POST the result — the relay forwards it on-chain on their behalf.
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { http, isHex, type Hex } from 'viem'
|
|
70
|
+
import { Relayer, httpQueueSource, forwardMessageAction, defaultLogger } from '@msgboard/relayer'
|
|
71
|
+
|
|
72
|
+
const queue = httpQueueSource<Hex>({
|
|
73
|
+
port: 3001,
|
|
74
|
+
token: process.env.RELAY_TOKEN,
|
|
75
|
+
parse: (body) => {
|
|
76
|
+
const { rlp } = body as { rlp: string }
|
|
77
|
+
if (!isHex(rlp)) throw new Error('expected hex rlp')
|
|
78
|
+
return rlp as Hex
|
|
79
|
+
},
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
const relayer = new Relayer<Hex>({
|
|
83
|
+
node: { transport: http('https://rpc.pulsechain.com') },
|
|
84
|
+
mode: 'live',
|
|
85
|
+
source: queue,
|
|
86
|
+
key: (rlp) => rlp,
|
|
87
|
+
action: forwardMessageAction(),
|
|
88
|
+
logger: defaultLogger('relay'),
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
relayer.start()
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Clients submit with:
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
curl -X POST http://localhost:3001/submit \
|
|
98
|
+
-H 'Content-Type: application/json' \
|
|
99
|
+
-d '{"rlp":"0x..."}'
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The `rlp` value comes from the SDK client's `doPoW()` result: `work.message`. The relay calls `msgboard_addMessage` with it directly — no wallet, no second proof-of-work.
|
|
103
|
+
|
|
104
|
+
`httpQueueSource` buffers POSTed items in memory and drains them on each heartbeat tick. An optional `token` field enables bearer-token auth. See `examples/write-for-me.ts` for a full runnable version.
|
|
105
|
+
|
|
106
|
+
### Transform anything
|
|
107
|
+
|
|
108
|
+
Because `httpQueueSource` is generic and `forwardMessageAction` only needs a `Hex` RLP, you can build relays for arbitrary protocols by adding a transform step: accept whatever your protocol produces, convert it to a `msgboard_addMessage`-compatible RLP in `parse`, and let the relayer forward it.
|
|
109
|
+
|
|
54
110
|
## Example relayers
|
|
55
111
|
|
|
56
112
|
| Relayer | source | store | sink | action (live only) | demonstrates |
|
|
@@ -59,10 +115,11 @@ const recent = await archive.query({ chainId: 943, category: 'lorem', limit: 20
|
|
|
59
115
|
| Bridge watcher (`bridge.ts`) | `bridgeAffirmationSource` (per chain) | memory-ttl | — | `submitMessageAction` | finalized event source, multi-node |
|
|
60
116
|
| Spam writer (`spam.ts`) | `generatedSource(sentence)` | noop | — | `submitMessageAction` | producer source, noop dedup |
|
|
61
117
|
| Archivist | all content | — | `postgresArchiveSink` 1yr | `noopAction` | sink-only; records in observe mode |
|
|
118
|
+
| "Write for me" relay (`write-for-me.ts`) | `httpQueueSource` (POSTed RLP) | noop | — | `forwardMessageAction` | push-based, client-side PoW |
|
|
62
119
|
| Cross-chain mirror | content on 369 | memory-ttl | — | `submitMessageAction` on 943 | source node ≠ action node |
|
|
63
120
|
| Moderation flagger | all content + blocklist predicate | — | `postgresSink('flagged')` | `noopAction` | condition + sink, no action |
|
|
64
121
|
|
|
65
|
-
See `examples/` for runnable code for the archivist, mirror, and
|
|
122
|
+
See `examples/` for runnable code for the archivist, mirror, flagger, and write-for-me relay.
|
|
66
123
|
|
|
67
124
|
## Known limitations
|
|
68
125
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Hex } from 'viem';
|
|
2
|
+
import type { RelayerAction } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Forwards a pre-computed RLP-encoded message to the board without doing
|
|
5
|
+
* proof-of-work. The item must already be a valid RLP hex string produced by
|
|
6
|
+
* the client's `doPoW` → `message` field.
|
|
7
|
+
*
|
|
8
|
+
* Use this with `httpQueueSource` to build a "write for you" relay: clients
|
|
9
|
+
* solve their own proof-of-work locally then POST the result; the relay
|
|
10
|
+
* submits it on-chain.
|
|
11
|
+
*/
|
|
12
|
+
export declare const forwardMessageAction: () => RelayerAction<Hex>;
|
|
13
|
+
//# sourceMappingURL=forward-message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forward-message.d.ts","sourceRoot":"","sources":["../../src/actions/forward-message.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAA;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,QAAO,aAAa,CAAC,GAAG,CAMvD,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forwards a pre-computed RLP-encoded message to the board without doing
|
|
3
|
+
* proof-of-work. The item must already be a valid RLP hex string produced by
|
|
4
|
+
* the client's `doPoW` → `message` field.
|
|
5
|
+
*
|
|
6
|
+
* Use this with `httpQueueSource` to build a "write for you" relay: clients
|
|
7
|
+
* solve their own proof-of-work locally then POST the result; the relay
|
|
8
|
+
* submits it on-chain.
|
|
9
|
+
*/
|
|
10
|
+
export const forwardMessageAction = () => ({
|
|
11
|
+
describe: (item) => `forward pre-computed message ${item.slice(0, 10)}…`,
|
|
12
|
+
execute: async (item, context) => {
|
|
13
|
+
const hash = await context.client.addMessage(item);
|
|
14
|
+
return { ok: true, ref: hash };
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=forward-message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forward-message.js","sourceRoot":"","sources":["../../src/actions/forward-message.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAuB,EAAE,CAAC,CAAC;IAC7D,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,gCAAgC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG;IACxE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;QAC/B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QAClD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAA;IAChC,CAAC;CACF,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send-value.d.ts","sourceRoot":"","sources":["../../src/actions/send-value.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,OAAO,EACZ,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"send-value.d.ts","sourceRoot":"","sources":["../../src/actions/send-value.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,OAAO,EACZ,KAAK,YAAY,EAGlB,MAAM,MAAM,CAAA;AACb,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEhE,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAAI;IACtC,2DAA2D;IAC3D,OAAO,EAAE,OAAO,CAAA;IAChB,iDAAiD;IACjD,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,cAAc,KAAK,OAAO,CAAA;IACxD,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAA;IACX,6DAA6D;IAC7D,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,YAAY,CAAA;CAC1D,CAAA;AAED,qFAAqF;AACrF,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,SAAS,sBAAsB,CAAC,CAAC,CAAC,KAAG,aAAa,CAAC,CAAC,CAyBtF,CAAA"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { createWalletClient, formatEther,
|
|
1
|
+
import { createWalletClient, formatEther, } from 'viem';
|
|
2
2
|
/** Sends native coin to an address derived from each item; waits for the receipt. */
|
|
3
3
|
export const sendValueAction = (options) => {
|
|
4
4
|
const makeWallet = (context) => options.walletFactory?.(context) ??
|
|
5
5
|
createWalletClient({
|
|
6
6
|
account: options.account,
|
|
7
7
|
chain: context.chain,
|
|
8
|
-
transport:
|
|
8
|
+
transport: context.node.transport,
|
|
9
9
|
});
|
|
10
10
|
return {
|
|
11
11
|
describe: (item, context) => `send ${formatEther(options.amount)} to ${options.recipient(item, context)}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send-value.js","sourceRoot":"","sources":["../../src/actions/send-value.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,kBAAkB,EAClB,WAAW,
|
|
1
|
+
{"version":3,"file":"send-value.js","sourceRoot":"","sources":["../../src/actions/send-value.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,kBAAkB,EAClB,WAAW,GACZ,MAAM,MAAM,CAAA;AAgBb,qFAAqF;AACrF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAI,OAAkC,EAAoB,EAAE;IACzF,MAAM,UAAU,GAAG,CAAC,OAAuB,EAAgB,EAAE,CAC3D,OAAO,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC;QAChC,kBAAkB,CAAC;YACjB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS;SAClC,CAAC,CAAA;IACJ,OAAO;QACL,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAC1B,QAAQ,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;QAC9E,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;YAC/B,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAA;YAClC,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;YAC3C,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC;gBACxC,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,EAAE;gBACF,KAAK,EAAE,OAAO,CAAC,MAAM;gBACrB,GAAG,EAAE,OAAO,CAAC,GAAG;aACjB,CAAC,CAAA;YACF,MAAM,OAAO,CAAC,YAAY,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAA;YAC9D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAA;QAChC,CAAC;KACF,CAAA;AACH,CAAC,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,7 +14,10 @@ export { msgboardContentSource } from './sources/msgboard-content.js';
|
|
|
14
14
|
export { bridgeAffirmationSource } from './sources/bridge-affirmation.js';
|
|
15
15
|
export { generatedSource } from './sources/generated.js';
|
|
16
16
|
export { submitMessageAction } from './actions/submit-message.js';
|
|
17
|
+
export { forwardMessageAction } from './actions/forward-message.js';
|
|
17
18
|
export { sendValueAction } from './actions/send-value.js';
|
|
18
19
|
export { webhookAction } from './actions/webhook.js';
|
|
19
20
|
export { noopAction } from './actions/noop.js';
|
|
21
|
+
export { httpQueueSource } from './sources/http-queue.js';
|
|
22
|
+
export type { HttpQueueSource, HttpQueueSourceOptions } from './sources/http-queue.js';
|
|
20
23
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,YAAY,EACV,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,UAAU,EACV,WAAW,EACX,WAAW,EACX,WAAW,EACX,aAAa,EACb,YAAY,EACZ,UAAU,GACX,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAErD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAClG,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,YAAY,EACV,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,UAAU,EACV,WAAW,EACX,WAAW,EACX,WAAW,EACX,aAAa,EACb,YAAY,EACZ,UAAU,GACX,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAErD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAClG,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,YAAY,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,9 @@ export { msgboardContentSource } from './sources/msgboard-content.js';
|
|
|
10
10
|
export { bridgeAffirmationSource } from './sources/bridge-affirmation.js';
|
|
11
11
|
export { generatedSource } from './sources/generated.js';
|
|
12
12
|
export { submitMessageAction } from './actions/submit-message.js';
|
|
13
|
+
export { forwardMessageAction } from './actions/forward-message.js';
|
|
13
14
|
export { sendValueAction } from './actions/send-value.js';
|
|
14
15
|
export { webhookAction } from './actions/webhook.js';
|
|
15
16
|
export { noopAction } from './actions/noop.js';
|
|
17
|
+
export { httpQueueSource } from './sources/http-queue.js';
|
|
16
18
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAgB1C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AAEjE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAgB1C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AAEjE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAA;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA"}
|
package/dist/relayer.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { RelayerConfig, RelayerMode, TickReport } from './types.js';
|
|
|
6
6
|
export declare class Relayer<T> {
|
|
7
7
|
private readonly config;
|
|
8
8
|
private readonly logger;
|
|
9
|
-
private
|
|
9
|
+
private contextPromise;
|
|
10
10
|
private readonly intervalMs;
|
|
11
11
|
private readonly pruneEveryTicks;
|
|
12
12
|
private tickCount;
|
|
@@ -15,6 +15,7 @@ export declare class Relayer<T> {
|
|
|
15
15
|
private abort;
|
|
16
16
|
constructor(config: RelayerConfig<T>);
|
|
17
17
|
get mode(): RelayerMode;
|
|
18
|
+
private ensureContext;
|
|
18
19
|
/** Runs a single tick and returns a report. Used by tests and one-shot runs. */
|
|
19
20
|
runOnce(): Promise<TickReport>;
|
|
20
21
|
/** Begins the poll loop. Idempotent — a second call is a no-op while running. */
|
package/dist/relayer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relayer.d.ts","sourceRoot":"","sources":["../src/relayer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAkB,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"relayer.d.ts","sourceRoot":"","sources":["../src/relayer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAkB,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAoDxF;;;GAGG;AACH,qBAAa,OAAO,CAAC,CAAC;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,cAAc,CAAuC;IAC7D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IACxC,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,KAAK,CAA+B;gBAEhC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;IAOpC,IAAI,IAAI,IAAI,WAAW,CAEtB;IAED,OAAO,CAAC,aAAa;IAOrB,gFAAgF;IAC1E,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IAoBpC,iFAAiF;IACjF,KAAK,IAAI,IAAI;IAQb,oDAAoD;IAC9C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YASb,IAAI;YAYJ,UAAU;YAWV,UAAU;YAMV,UAAU;YAeV,SAAS;YAiBT,UAAU;CAKzB"}
|
package/dist/relayer.js
CHANGED
|
@@ -1,19 +1,30 @@
|
|
|
1
|
-
import { createPublicClient
|
|
1
|
+
import { createPublicClient } from 'viem';
|
|
2
2
|
import { MsgBoardClient } from '@msgboard/sdk';
|
|
3
3
|
import { resolveChain } from './chains.js';
|
|
4
4
|
import { defaultLogger } from './logger.js';
|
|
5
5
|
const DEFAULT_INTERVAL_MS = 30_000;
|
|
6
6
|
const DEFAULT_PRUNE_EVERY_TICKS = 30;
|
|
7
|
+
/** Calls eth_chainId on the node and returns the numeric chain id. */
|
|
8
|
+
const detectChainId = async (transport) => {
|
|
9
|
+
const probe = createPublicClient({ transport });
|
|
10
|
+
return probe.getChainId();
|
|
11
|
+
};
|
|
7
12
|
/** Builds the runtime context (viem + SDK clients) for a relayer config. */
|
|
8
|
-
const buildContext = (config, logger) => {
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
const buildContext = async (config, logger) => {
|
|
14
|
+
const node = config.node;
|
|
15
|
+
const chain = node.chain ?? await (async () => {
|
|
16
|
+
const id = await detectChainId(node.transport);
|
|
17
|
+
try {
|
|
18
|
+
return resolveChain(id);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
throw new Error(`detected chain ${id} from the node is not a known network — pass node.chain explicitly to support it`);
|
|
22
|
+
}
|
|
23
|
+
})();
|
|
24
|
+
const publicClient = createPublicClient({ chain, transport: node.transport });
|
|
14
25
|
const client = new MsgBoardClient(publicClient);
|
|
15
26
|
return {
|
|
16
|
-
node
|
|
27
|
+
node,
|
|
17
28
|
mode: config.mode ?? 'observe',
|
|
18
29
|
chain,
|
|
19
30
|
publicClient,
|
|
@@ -44,7 +55,7 @@ const sleep = (ms, signal) => {
|
|
|
44
55
|
export class Relayer {
|
|
45
56
|
config;
|
|
46
57
|
logger;
|
|
47
|
-
|
|
58
|
+
contextPromise = null;
|
|
48
59
|
intervalMs;
|
|
49
60
|
pruneEveryTicks;
|
|
50
61
|
tickCount = 0;
|
|
@@ -54,15 +65,21 @@ export class Relayer {
|
|
|
54
65
|
constructor(config) {
|
|
55
66
|
this.config = config;
|
|
56
67
|
this.logger = config.logger ?? defaultLogger('relayer');
|
|
57
|
-
this.context = buildContext(config, this.logger);
|
|
58
68
|
this.intervalMs = config.intervalMs ?? DEFAULT_INTERVAL_MS;
|
|
59
69
|
this.pruneEveryTicks = config.pruneEveryTicks ?? DEFAULT_PRUNE_EVERY_TICKS;
|
|
60
70
|
}
|
|
61
71
|
get mode() {
|
|
62
|
-
return this.
|
|
72
|
+
return this.config.mode ?? 'observe';
|
|
73
|
+
}
|
|
74
|
+
ensureContext() {
|
|
75
|
+
if (!this.contextPromise) {
|
|
76
|
+
this.contextPromise = buildContext(this.config, this.logger);
|
|
77
|
+
}
|
|
78
|
+
return this.contextPromise;
|
|
63
79
|
}
|
|
64
80
|
/** Runs a single tick and returns a report. Used by tests and one-shot runs. */
|
|
65
81
|
async runOnce() {
|
|
82
|
+
const ctx = await this.ensureContext();
|
|
66
83
|
const report = {
|
|
67
84
|
polled: 0,
|
|
68
85
|
recorded: 0,
|
|
@@ -71,10 +88,10 @@ export class Relayer {
|
|
|
71
88
|
described: 0,
|
|
72
89
|
deduped: 0,
|
|
73
90
|
};
|
|
74
|
-
const items = await this.config.source.poll(
|
|
91
|
+
const items = await this.config.source.poll(ctx);
|
|
75
92
|
report.polled = items.length;
|
|
76
93
|
for (const item of items) {
|
|
77
|
-
await this.handleItem(item, report);
|
|
94
|
+
await this.handleItem(item, report, ctx);
|
|
78
95
|
}
|
|
79
96
|
this.tickCount += 1;
|
|
80
97
|
await this.maybePrune();
|
|
@@ -112,26 +129,26 @@ export class Relayer {
|
|
|
112
129
|
await sleep(this.intervalMs, signal);
|
|
113
130
|
}
|
|
114
131
|
}
|
|
115
|
-
async handleItem(item, report) {
|
|
116
|
-
await this.recordItem(item, report);
|
|
117
|
-
const eligible = await this.isEligible(item);
|
|
132
|
+
async handleItem(item, report, ctx) {
|
|
133
|
+
await this.recordItem(item, report, ctx);
|
|
134
|
+
const eligible = await this.isEligible(item, ctx);
|
|
118
135
|
if (!eligible.proceed) {
|
|
119
136
|
if (eligible.reason === 'deduped')
|
|
120
137
|
report.deduped += 1;
|
|
121
138
|
return;
|
|
122
139
|
}
|
|
123
140
|
report.eligible += 1;
|
|
124
|
-
await this.actOnItem(item, report);
|
|
141
|
+
await this.actOnItem(item, report, ctx);
|
|
125
142
|
}
|
|
126
|
-
async recordItem(item, report) {
|
|
143
|
+
async recordItem(item, report, ctx) {
|
|
127
144
|
if (!this.config.sink)
|
|
128
145
|
return;
|
|
129
|
-
await this.config.sink.record(item,
|
|
146
|
+
await this.config.sink.record(item, ctx);
|
|
130
147
|
report.recorded += 1;
|
|
131
148
|
}
|
|
132
|
-
async isEligible(item) {
|
|
149
|
+
async isEligible(item, ctx) {
|
|
133
150
|
if (this.config.condition) {
|
|
134
|
-
const ok = await this.config.condition(item,
|
|
151
|
+
const ok = await this.config.condition(item, ctx);
|
|
135
152
|
if (!ok)
|
|
136
153
|
return { proceed: false, reason: 'condition' };
|
|
137
154
|
}
|
|
@@ -142,14 +159,14 @@ export class Relayer {
|
|
|
142
159
|
}
|
|
143
160
|
return { proceed: true };
|
|
144
161
|
}
|
|
145
|
-
async actOnItem(item, report) {
|
|
146
|
-
if (
|
|
147
|
-
this.logger('observe: %s', this.config.action.describe(item,
|
|
162
|
+
async actOnItem(item, report, ctx) {
|
|
163
|
+
if (ctx.mode === 'observe') {
|
|
164
|
+
this.logger('observe: %s', this.config.action.describe(item, ctx));
|
|
148
165
|
report.described += 1;
|
|
149
166
|
return;
|
|
150
167
|
}
|
|
151
168
|
try {
|
|
152
|
-
const result = await this.config.action.execute(item,
|
|
169
|
+
const result = await this.config.action.execute(item, ctx);
|
|
153
170
|
report.executed += 1;
|
|
154
171
|
if (this.config.store) {
|
|
155
172
|
await this.config.store.remember(this.config.key(item), result);
|
package/dist/relayer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relayer.js","sourceRoot":"","sources":["../src/relayer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"relayer.js","sourceRoot":"","sources":["../src/relayer.ts"],"names":[],"mappings":"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"}
|
|
@@ -45,7 +45,7 @@ export const postgresArchiveSink = (options) => {
|
|
|
45
45
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
46
46
|
ON CONFLICT (hash, chain_id) DO NOTHING`, [
|
|
47
47
|
message.hash,
|
|
48
|
-
context.
|
|
48
|
+
context.chain.id,
|
|
49
49
|
message.category,
|
|
50
50
|
tryDecodeText(message.category),
|
|
51
51
|
message.data,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-archive.js","sourceRoot":"","sources":["../../src/sinks/postgres-archive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,WAAW,EAAE,MAAM,MAAM,CAAA;AAyC5C,8FAA8F;AAC9F,MAAM,aAAa,GAAG,CAAC,GAAQ,EAAiB,EAAE;IAChD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;QACzD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;QAClC,qDAAqD;QACrD,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;QAC9C,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,OAA+B,EAI/B,EAAE;IACF,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAA;IACxB,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAA;IAE5C,MAAM,OAAO,GAAG,KAAK,IAAmB,EAAE;QACxC,MAAM,IAAI,CAAC,KAAK,CACd;;;;;;;;;;;QAWE,CACH,CAAA;QACD,MAAM,IAAI,CAAC,KAAK,CACd,wFAAwF,CACzF,CAAA;QACD,MAAM,IAAI,CAAC,KAAK,CACd,oGAAoG,CACrG,CAAA;QACD,MAAM,IAAI,CAAC,KAAK,CACd,uFAAuF,CACxF,CAAA;IACH,CAAC,CAAA;IAED,MAAM,MAAM,GAAG,KAAK,EAAE,OAAmB,EAAE,OAAuB,EAAiB,EAAE;QACnF,MAAM,IAAI,CAAC,KAAK,CACd;;;+CAGyC,EACzC;YACE,OAAO,CAAC,IAAI;YACZ,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"postgres-archive.js","sourceRoot":"","sources":["../../src/sinks/postgres-archive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,WAAW,EAAE,MAAM,MAAM,CAAA;AAyC5C,8FAA8F;AAC9F,MAAM,aAAa,GAAG,CAAC,GAAQ,EAAiB,EAAE;IAChD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;QACzD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;QAClC,qDAAqD;QACrD,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;QAC9C,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,OAA+B,EAI/B,EAAE;IACF,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAA;IACxB,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAA;IAE5C,MAAM,OAAO,GAAG,KAAK,IAAmB,EAAE;QACxC,MAAM,IAAI,CAAC,KAAK,CACd;;;;;;;;;;;QAWE,CACH,CAAA;QACD,MAAM,IAAI,CAAC,KAAK,CACd,wFAAwF,CACzF,CAAA;QACD,MAAM,IAAI,CAAC,KAAK,CACd,oGAAoG,CACrG,CAAA;QACD,MAAM,IAAI,CAAC,KAAK,CACd,uFAAuF,CACxF,CAAA;IACH,CAAC,CAAA;IAED,MAAM,MAAM,GAAG,KAAK,EAAE,OAAmB,EAAE,OAAuB,EAAiB,EAAE;QACnF,MAAM,IAAI,CAAC,KAAK,CACd;;;+CAGyC,EACzC;YACE,OAAO,CAAC,IAAI;YACZ,OAAO,CAAC,KAAK,CAAC,EAAE;YAChB,OAAO,CAAC,QAAQ;YAChB,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC/B,OAAO,CAAC,IAAI;YACZ,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC;YAC3B,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE;YACtC,OAAO,CAAC,SAAS;SAClB,CACF,CAAA;IACH,CAAC,CAAA;IAED,MAAM,KAAK,GAAG,KAAK,IAAmB,EAAE;QACtC,MAAM,IAAI,CAAC,KAAK,CACd,uEAAuE,aAAa,QAAQ,CAC7F,CAAA;IACH,CAAC,CAAA;IAED,MAAM,KAAK,GAAG,KAAK,EAAE,MAAoB,EAA8B,EAAE;QACvE,MAAM,OAAO,GAAa,EAAE,CAAA;QAC5B,MAAM,MAAM,GAAc,EAAE,CAAA;QAC5B,MAAM,GAAG,GAAG,CAAC,MAAc,EAAE,KAAc,EAAQ,EAAE;YACnD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YAClB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;QAC5D,CAAC,CAAA;QACD,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;YAAE,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;QACtE,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS;YAAE,GAAG,CAAC,uCAAuC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAA;QAChG,IAAI,MAAM,CAAC,KAAK;YAAE,GAAG,CAAC,qBAAqB,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAA;QACxE,IAAI,MAAM,CAAC,KAAK;YAAE,GAAG,CAAC,qBAAqB,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAA;QACxE,IAAI,MAAM,CAAC,QAAQ;YAAE,GAAG,CAAC,kBAAkB,EAAE,IAAI,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAA;QACpE,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QACxE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;QAClG,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;QAChF,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAC/B,+HAA+H,KAAK,sCAAsC,KAAK,WAAW,MAAM,EAAE,EAClM,MAAM,CACP,CAAA;QACD,OAAO,IAAyB,CAAA;IAClC,CAAC,CAAA;IAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;AAC1C,CAAC,CAAA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { RelayerSource } from '../types.js';
|
|
2
|
+
export type HttpQueueSourceOptions<T> = {
|
|
3
|
+
/** Port to listen on. Defaults to 3001. */
|
|
4
|
+
port?: number;
|
|
5
|
+
/**
|
|
6
|
+
* Host / interface to bind. Defaults to `'127.0.0.1'` (loopback only).
|
|
7
|
+
* Set to `'0.0.0.0'` for LAN/Internet exposure — requires `token` to be
|
|
8
|
+
* set, or the server refuses to start.
|
|
9
|
+
*/
|
|
10
|
+
host?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Parses the raw JSON body into a typed item. Throw to reject.
|
|
13
|
+
* The returned item is added to the next poll batch.
|
|
14
|
+
*/
|
|
15
|
+
parse: (body: unknown) => T;
|
|
16
|
+
/**
|
|
17
|
+
* Optional bearer token — requests without `Authorization: Bearer <token>`
|
|
18
|
+
* receive a 401 and are not queued.
|
|
19
|
+
*/
|
|
20
|
+
token?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Maximum number of items held in memory before new submissions are
|
|
23
|
+
* rejected with 429. Defaults to 1000. Set to 0 to disable the cap.
|
|
24
|
+
*/
|
|
25
|
+
maxQueueSize?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Maximum number of items drained per poll tick. Defaults to 100.
|
|
28
|
+
* Prevents a single heartbeat from firing an unbounded burst of on-chain
|
|
29
|
+
* transactions if the queue fills up.
|
|
30
|
+
*/
|
|
31
|
+
maxBatchSize?: number;
|
|
32
|
+
};
|
|
33
|
+
export type HttpQueueSource<T> = RelayerSource<T> & {
|
|
34
|
+
/** Closes the HTTP server. Call after `relayer.stop()` to free the port. */
|
|
35
|
+
close(): Promise<void>;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Opens an HTTP server that accepts `POST /submit` requests. Each accepted
|
|
39
|
+
* item is held in memory until the next `poll()` cycle drains the queue.
|
|
40
|
+
*
|
|
41
|
+
* Clients POST JSON matching whatever shape `parse` expects. On success they
|
|
42
|
+
* receive `{ ok: true, queued: true }` immediately — they don't wait for the
|
|
43
|
+
* relayer to process the item.
|
|
44
|
+
*
|
|
45
|
+
* Security defaults:
|
|
46
|
+
* - Binds to `127.0.0.1` (loopback only) unless `host` is set.
|
|
47
|
+
* - Non-loopback binds require `token` to be set; the server throws otherwise.
|
|
48
|
+
* - Queue is capped at 1000 items (429 when full).
|
|
49
|
+
* - Each poll drains at most 100 items.
|
|
50
|
+
* - Request bodies are rejected above 64 KiB.
|
|
51
|
+
* - `server.headersTimeout` and `server.requestTimeout` are set to 10 s
|
|
52
|
+
* to bound slow-loris connections.
|
|
53
|
+
*/
|
|
54
|
+
export declare const httpQueueSource: <T>(options: HttpQueueSourceOptions<T>) => HttpQueueSource<T>;
|
|
55
|
+
//# sourceMappingURL=http-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-queue.d.ts","sourceRoot":"","sources":["../../src/sources/http-queue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAKhD,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAAI;IACtC,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,CAAC,CAAA;IAC3B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,GAAG;IAClD,4EAA4E;IAC5E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB,CAAA;AA+BD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,SAAS,sBAAsB,CAAC,CAAC,CAAC,KAAG,eAAe,CAAC,CAAC,CAmDxF,CAAA"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { createServer } from 'node:http';
|
|
2
|
+
/** 64 KiB — generous ceiling for any single RLP payload. */
|
|
3
|
+
const MAX_BODY_BYTES = 65_536;
|
|
4
|
+
const readBody = (req) => new Promise((resolve, reject) => {
|
|
5
|
+
const contentLength = Number(req.headers['content-length'] ?? 0);
|
|
6
|
+
if (contentLength > MAX_BODY_BYTES) {
|
|
7
|
+
req.resume();
|
|
8
|
+
return reject(new Error('request body too large'));
|
|
9
|
+
}
|
|
10
|
+
let size = 0;
|
|
11
|
+
const chunks = [];
|
|
12
|
+
req.on('data', (chunk) => {
|
|
13
|
+
size += chunk.length;
|
|
14
|
+
if (size > MAX_BODY_BYTES) {
|
|
15
|
+
req.destroy();
|
|
16
|
+
return reject(new Error('request body too large'));
|
|
17
|
+
}
|
|
18
|
+
chunks.push(chunk);
|
|
19
|
+
});
|
|
20
|
+
req.on('end', () => {
|
|
21
|
+
try {
|
|
22
|
+
resolve(JSON.parse(Buffer.concat(chunks).toString()));
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
reject(new Error('invalid JSON'));
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
req.on('error', reject);
|
|
29
|
+
});
|
|
30
|
+
const respond = (res, status, body) => {
|
|
31
|
+
const json = JSON.stringify(body);
|
|
32
|
+
res.writeHead(status, { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(json) });
|
|
33
|
+
res.end(json);
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Opens an HTTP server that accepts `POST /submit` requests. Each accepted
|
|
37
|
+
* item is held in memory until the next `poll()` cycle drains the queue.
|
|
38
|
+
*
|
|
39
|
+
* Clients POST JSON matching whatever shape `parse` expects. On success they
|
|
40
|
+
* receive `{ ok: true, queued: true }` immediately — they don't wait for the
|
|
41
|
+
* relayer to process the item.
|
|
42
|
+
*
|
|
43
|
+
* Security defaults:
|
|
44
|
+
* - Binds to `127.0.0.1` (loopback only) unless `host` is set.
|
|
45
|
+
* - Non-loopback binds require `token` to be set; the server throws otherwise.
|
|
46
|
+
* - Queue is capped at 1000 items (429 when full).
|
|
47
|
+
* - Each poll drains at most 100 items.
|
|
48
|
+
* - Request bodies are rejected above 64 KiB.
|
|
49
|
+
* - `server.headersTimeout` and `server.requestTimeout` are set to 10 s
|
|
50
|
+
* to bound slow-loris connections.
|
|
51
|
+
*/
|
|
52
|
+
export const httpQueueSource = (options) => {
|
|
53
|
+
const host = options.host ?? '127.0.0.1';
|
|
54
|
+
const maxQueueSize = options.maxQueueSize ?? 1000;
|
|
55
|
+
const maxBatchSize = options.maxBatchSize ?? 100;
|
|
56
|
+
const isNonLoopback = host !== '127.0.0.1' && host !== 'localhost' && host !== '::1';
|
|
57
|
+
if (isNonLoopback && !options.token) {
|
|
58
|
+
throw new Error(`httpQueueSource: non-loopback bind (${host}) requires a token to be set — ` +
|
|
59
|
+
`pass token or set host to '127.0.0.1'`);
|
|
60
|
+
}
|
|
61
|
+
const queue = [];
|
|
62
|
+
const server = createServer(async (req, res) => {
|
|
63
|
+
if (req.method !== 'POST' || req.url !== '/submit') {
|
|
64
|
+
return respond(res, 404, { ok: false, error: 'not found' });
|
|
65
|
+
}
|
|
66
|
+
if (options.token) {
|
|
67
|
+
const auth = req.headers['authorization'];
|
|
68
|
+
if (auth !== `Bearer ${options.token}`) {
|
|
69
|
+
return respond(res, 401, { ok: false, error: 'unauthorized' });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (maxQueueSize > 0 && queue.length >= maxQueueSize) {
|
|
73
|
+
return respond(res, 429, { ok: false, error: 'queue full — try again later' });
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const body = await readBody(req);
|
|
77
|
+
const item = options.parse(body);
|
|
78
|
+
queue.push(item);
|
|
79
|
+
respond(res, 200, { ok: true, queued: true });
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
respond(res, 400, { ok: false, error: err instanceof Error ? err.message : 'bad request' });
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
// Bound slow-loris connections.
|
|
86
|
+
server.headersTimeout = 10_000;
|
|
87
|
+
server.requestTimeout = 10_000;
|
|
88
|
+
server.listen(options.port ?? 3001, host);
|
|
89
|
+
return {
|
|
90
|
+
poll: async () => {
|
|
91
|
+
const batch = queue.splice(0, maxBatchSize);
|
|
92
|
+
return batch;
|
|
93
|
+
},
|
|
94
|
+
close: () => new Promise((resolve, reject) => server.close((err) => err ? reject(err) : resolve())),
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
//# sourceMappingURL=http-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-queue.js","sourceRoot":"","sources":["../../src/sources/http-queue.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
import type { MsgBoardClient } from '@msgboard/sdk';
|
|
2
|
-
import type { Chain, PublicClient } from 'viem';
|
|
2
|
+
import type { Chain, PublicClient, Transport } from 'viem';
|
|
3
3
|
import type { Logger } from './logger.js';
|
|
4
4
|
/** The two operating modes. `observe` never produces an outbound side effect. */
|
|
5
5
|
export type RelayerMode = 'observe' | 'live';
|
|
6
6
|
/** Identifies the msgboard node a relayer watches. */
|
|
7
7
|
export type RelayerNode = {
|
|
8
|
-
/**
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
|
|
8
|
+
/** viem Transport for the node (e.g. `http('https://...')`). */
|
|
9
|
+
transport: Transport;
|
|
10
|
+
/**
|
|
11
|
+
* viem Chain definition. When omitted, the chain id is detected automatically
|
|
12
|
+
* via `eth_chainId` on the first tick. Pass explicitly for custom networks.
|
|
13
|
+
*/
|
|
14
|
+
chain?: Chain;
|
|
12
15
|
};
|
|
13
16
|
/** Everything a source, action, or sink may need at runtime. */
|
|
14
17
|
export type RelayerContext = {
|
|
15
18
|
node: RelayerNode;
|
|
16
19
|
mode: RelayerMode;
|
|
17
20
|
chain: Chain;
|
|
18
|
-
/** A viem public client
|
|
21
|
+
/** A viem public client backed by `node.transport`. */
|
|
19
22
|
publicClient: PublicClient;
|
|
20
23
|
/** A msgboard SDK client wrapping `publicClient`. */
|
|
21
24
|
client: MsgBoardClient;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@msgboard/relayer",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.30",
|
|
4
4
|
"description": "Controllable, safe-by-default pool-watcher relayer for the msgboard board",
|
|
5
5
|
"repository": "github:valve-tech/msgboard",
|
|
6
6
|
"author": "MsgBoard",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"files": ["dist/"],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@msgboard/sdk": "^0.0.
|
|
34
|
+
"@msgboard/sdk": "^0.0.30",
|
|
35
35
|
"viem": "^2.25.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|