@hyperbridge/simplex 0.17.0 → 0.18.0
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 +85 -151
- package/dist/bin/simplex.js +7769 -1943
- package/dist/bin/simplex.js.map +1 -1
- package/dist/error-reporting.cjs +123 -0
- package/dist/error-reporting.cjs.map +1 -0
- package/dist/error-reporting.d.cts +46 -0
- package/dist/error-reporting.d.ts +46 -0
- package/dist/error-reporting.js +95 -0
- package/dist/error-reporting.js.map +1 -0
- package/dist/index.cjs +1364 -557
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +311 -1896
- package/dist/index.d.ts +311 -1896
- package/dist/index.js +1362 -523
- package/dist/index.js.map +1 -1
- package/dist/sqlite.cjs +1 -0
- package/dist/sqlite.cjs.map +1 -1
- package/dist/sqlite.d.cts +7 -1
- package/dist/sqlite.d.ts +7 -1
- package/dist/sqlite.js +1 -0
- package/dist/sqlite.js.map +1 -1
- package/dist/types-6MEltdkX.d.cts +2297 -0
- package/dist/types-6MEltdkX.d.ts +2297 -0
- package/dist/ui/assets/bridge-BB9cnjYo.png +0 -0
- package/dist/ui/assets/hyperbridge-B8MVl-Oj.png +0 -0
- package/dist/ui/assets/index-DWJcHNgO.css +1 -0
- package/dist/ui/assets/index-Dy5dPCr_.js +2168 -0
- package/dist/ui/assets/usdr-gm4f6KeA.png +0 -0
- package/dist/ui/index.html +2 -2
- package/package.json +19 -4
- package/dist/types-BPyUX8qu.d.cts +0 -663
- package/dist/types-BPyUX8qu.d.ts +0 -663
- package/dist/ui/assets/index-CK8E6aPx.css +0 -1
- package/dist/ui/assets/index-D8DLeEH0.js +0 -106
package/README.md
CHANGED
|
@@ -1,62 +1,53 @@
|
|
|
1
1
|
# @hyperbridge/simplex
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@hyperbridge/simplex)
|
|
4
|
+
[](https://nodejs.org)
|
|
5
|
+
[](https://github.com/polytope-labs/hyperbridge/blob/main/sdk/packages/simplex/LICENSE)
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
[docs.hyperbridge.network/developers/sdk/simplex](https://docs.hyperbridge.network/developers/sdk/simplex/)
|
|
7
|
+
An automated solver for [Hyperbridge](https://hyperbridge.network) intents.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Simplex watches the IntentGateway on the chains you configure. It prices each swap against the
|
|
10
|
+
limit orders you post to the HyperFX orderbook, then bids for and fills the swaps you have priced.
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
for macOS, Windows, or Linux. Choose the newest stable `simplex-desktop-v…` release and its installer
|
|
13
|
-
for your platform. The app bundles this package and the matching Node runtime, opens the setup wizard
|
|
14
|
-
on first launch, and keeps the solver running from the system tray. macOS and Windows install
|
|
15
|
-
authenticated updates; Linux updates remain manual until release metadata is independently signed.
|
|
12
|
+
Embed it in your own Node service, or run it as a ready-made app:
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
`
|
|
14
|
+
- **Library**: call `Simplex.start()` in your process, with your own signer and storage.
|
|
15
|
+
- **CLI**: `simplex` sets itself up in the browser and serves a local dashboard.
|
|
16
|
+
- **Desktop app**: installers for macOS, Windows and Linux.
|
|
17
|
+
- **Docker**: the [`polytopelabs/simplex`](https://hub.docker.com/r/polytopelabs/simplex) image.
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
- macOS: `~/Library/Application Support/Simplex/filler-config.toml`
|
|
23
|
-
- Windows: `%APPDATA%\Simplex\filler-config.toml`
|
|
24
|
-
- Linux: `$XDG_CONFIG_HOME/Simplex/filler-config.toml`, or `~/.config/Simplex/filler-config.toml`
|
|
25
|
-
|
|
26
|
-
`filler-config.toml` contains private keys and credentials in plaintext. New files are mode `0600`
|
|
27
|
-
on Unix, but software running as the operator can still read them. Keep the file out of source
|
|
28
|
-
control and broadly shared backups. `simplex.substratePrivateKey` is required in every signer mode,
|
|
29
|
-
so Turnkey and MPC Vault operators still have a raw Substrate key on disk.
|
|
30
|
-
|
|
31
|
-
The browser-installable PWA remains the remote/mobile dashboard for an existing solver. It is a UI
|
|
32
|
-
shell, not a packaged solver, and is not the preferred local installation.
|
|
33
|
-
|
|
34
|
-
See the [installation guide](https://docs.hyperbridge.network/developers/evm/simplex/installation/)
|
|
35
|
-
for installer names, lifecycle details, and the advanced Docker and npm paths.
|
|
36
|
-
|
|
37
|
-
## Advanced: embed as a library
|
|
19
|
+
## Install
|
|
38
20
|
|
|
39
21
|
```bash
|
|
40
22
|
npm install @hyperbridge/simplex
|
|
41
23
|
```
|
|
42
24
|
|
|
25
|
+
Requires Node.js 22.16 or later.
|
|
26
|
+
|
|
27
|
+
## Quick start
|
|
28
|
+
|
|
43
29
|
```ts
|
|
44
|
-
import { Simplex, privateKeySigner } from "@hyperbridge/simplex"
|
|
30
|
+
import { Simplex, privateKeySigner, type SimplexConfig } from "@hyperbridge/simplex"
|
|
45
31
|
import { SqliteDataStore } from "@hyperbridge/simplex/sqlite"
|
|
46
32
|
|
|
33
|
+
const config: SimplexConfig = {
|
|
34
|
+
simplex: {
|
|
35
|
+
maxConcurrentOrders: 5,
|
|
36
|
+
substratePrivateKey: process.env.SUBSTRATE_KEY!,
|
|
37
|
+
hyperbridgeWsUrl: "wss://nexus.rpc.polytope.technology",
|
|
38
|
+
},
|
|
39
|
+
chains: [{ rpcUrls: ["https://base.example"] }, { rpcUrls: ["https://ethereum.example"] }],
|
|
40
|
+
orderbook: { url: "https://orderbook.hyperfx.finance/mainnet/graphql" },
|
|
41
|
+
}
|
|
42
|
+
|
|
47
43
|
const simplex = await Simplex.start({
|
|
48
44
|
config,
|
|
49
45
|
signer: privateKeySigner(process.env.SOLVER_KEY as `0x${string}`),
|
|
50
46
|
data: new SqliteDataStore("./simplex-data"),
|
|
47
|
+
logger: process.stdout,
|
|
51
48
|
})
|
|
52
49
|
|
|
53
|
-
|
|
54
|
-
console.log(`filled ${orderId} for $${profitUsd}`)
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
// Every runtime control the dashboard offers is a method — nothing needs a restart.
|
|
58
|
-
// Prices come from limit orders posted to the HyperFX orderbook: 10,000 USDC in for
|
|
59
|
-
// 13,900,000 CNGN out, filled on Base, for swaps from Ethereum or Base.
|
|
50
|
+
// Pay out 13,900,000 cNGN on Base for 10,000 USDC, to swaps from Ethereum or Base.
|
|
60
51
|
await simplex.limitOrders.create({
|
|
61
52
|
fillChain: "EVM-8453",
|
|
62
53
|
tokenIn: "USDC",
|
|
@@ -65,148 +56,91 @@ await simplex.limitOrders.create({
|
|
|
65
56
|
amountOut: "13900000",
|
|
66
57
|
acceptedSources: ["EVM-1", "EVM-8453"],
|
|
67
58
|
})
|
|
68
|
-
await simplex.chains.setRpcUrls(8453, ["https://base-new.example"])
|
|
69
59
|
|
|
60
|
+
simplex.on("order:filled", ({ orderId, profitUsd }) => {
|
|
61
|
+
console.log(`filled ${orderId} for $${profitUsd}`)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
// When you are done:
|
|
70
65
|
await simplex.stop()
|
|
71
66
|
```
|
|
72
67
|
|
|
73
|
-
`Simplex.start`
|
|
74
|
-
|
|
75
|
-
the limit orders you create while it runs. It logs nothing until you point `logger` at a sink, so importing the package never writes to
|
|
76
|
-
your stdout.
|
|
68
|
+
`Simplex.start` resolves once the solver is running. The config holds no prices. Simplex fills only
|
|
69
|
+
against the limit orders you create, so a fresh solver quotes nothing until you post one.
|
|
77
70
|
|
|
78
|
-
|
|
79
|
-
typed data, this EIP-7702 authorization, this transaction — with no viem types on it, so satisfying
|
|
80
|
-
it never means matching this package's viem version. `privateKeySigner`, `secretPhraseSigner`,
|
|
81
|
-
`turnkeySigner` and `mpcVaultSigner` ship with the package, `viemSigner` adapts any viem account (a
|
|
82
|
-
`toAccount` wrapper around an HSM or a remote signing service included), and your own implementation
|
|
83
|
-
is a first-class citizen. Persistence is pluggable the same way: the default
|
|
84
|
-
store is in-memory, `SqliteDataStore` is durable, and `SimplexDataStore` is a small async interface
|
|
85
|
-
you can implement over Postgres, Redis or anything else. A solver that submits bids should use a
|
|
86
|
-
durable store, since bid records are how locked deposits are found again for retraction.
|
|
71
|
+
## Features
|
|
87
72
|
|
|
88
|
-
|
|
73
|
+
- **Priced by your limit orders.** No price feeds. Each order says what you take in, what you pay
|
|
74
|
+
out, and on which chain.
|
|
75
|
+
- **Bring your own signer.** `Signer` is a small interface with no viem types. Simplex ships
|
|
76
|
+
`privateKeySigner`, `secretPhraseSigner`, `turnkeySigner` and `mpcVaultSigner`, and `viemSigner`
|
|
77
|
+
wraps any viem account.
|
|
78
|
+
- **Bring your own storage.** The default store is in memory. `SqliteDataStore` is durable, and
|
|
79
|
+
`SimplexDataStore` is a small interface you can implement over any database. Use a durable store
|
|
80
|
+
when bidding, because bid records are how locked deposits are found again.
|
|
81
|
+
- **Live control.** Limit orders, chains, vaults, assets and rebalancing all change at runtime
|
|
82
|
+
through `simplex.limitOrders`, `simplex.chains` and the other controllers. Nothing needs a restart.
|
|
83
|
+
- **Typed events.** Subscribe to `order:detected`, `order:filled`, `limit-order:filled` and more.
|
|
84
|
+
- **Quiet by default.** Simplex logs nothing until you pass `logger`, so it never writes to your
|
|
85
|
+
stdout uninvited.
|
|
89
86
|
|
|
90
|
-
##
|
|
87
|
+
## Command line
|
|
91
88
|
|
|
92
89
|
```bash
|
|
93
90
|
npm install -g @hyperbridge/simplex
|
|
94
91
|
simplex
|
|
95
92
|
```
|
|
96
93
|
|
|
97
|
-
|
|
98
|
-
still `simplex`. Prefer a container? The same binary ships as
|
|
99
|
-
[`polytopelabs/simplex`](https://hub.docker.com/r/polytopelabs/simplex) — quickstart on the Docker
|
|
100
|
-
Hub page.
|
|
94
|
+
Install the scoped package. The bare `simplex` package on npm is unrelated.
|
|
101
95
|
|
|
102
|
-
With no config
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
`simplex init` is the equivalent terminal wizard.
|
|
96
|
+
With no config, `simplex` opens a setup wizard in your browser. The wizard writes
|
|
97
|
+
`filler-config.toml` and starts the solver. With a config, `simplex` starts the solver and serves its
|
|
98
|
+
dashboard at `http://127.0.0.1:8686`.
|
|
106
99
|
|
|
107
|
-
|
|
108
|
-
|
|
100
|
+
```bash
|
|
101
|
+
simplex run -c filler-config.toml # run with an existing config
|
|
102
|
+
simplex run -c filler-config.toml --no-ui # run without the dashboard
|
|
103
|
+
simplex init # set up in the terminal instead
|
|
104
|
+
```
|
|
109
105
|
|
|
110
|
-
|
|
106
|
+
The same binary runs in Docker as
|
|
107
|
+
[`polytopelabs/simplex`](https://hub.docker.com/r/polytopelabs/simplex).
|
|
111
108
|
|
|
112
|
-
|
|
109
|
+
## Desktop app
|
|
113
110
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
- limit orders: post, inspect with the fills that drew them down, and cancel
|
|
118
|
-
- operations: manual vault sweep/redeem, runtime allowlist editing, log level switch, rebalancing trigger view, masked config view
|
|
111
|
+
Simplex Desktop bundles this package with its own Node runtime. It runs the setup wizard on first
|
|
112
|
+
launch and keeps the solver running from the system tray.
|
|
113
|
+
[Download it for macOS, Windows or Linux](https://docs.hyperbridge.network/developers/evm/simplex/installation/).
|
|
119
114
|
|
|
120
|
-
|
|
115
|
+
## Security
|
|
121
116
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
simplex
|
|
127
|
-
simplex run --log-format json # NDJSON on stdout instead of colourised lines
|
|
128
|
-
```
|
|
117
|
+
- `filler-config.toml` holds private keys in plain text. It is written with mode `0600`, but keep it
|
|
118
|
+
out of source control and shared backups.
|
|
119
|
+
- The dashboard has no login. It listens only on `127.0.0.1` by default. Do not expose it on a
|
|
120
|
+
network you do not trust. To reach it from a phone, use
|
|
121
|
+
[remote access](https://docs.hyperbridge.network/developers/evm/simplex/api/remote-access/).
|
|
129
122
|
|
|
130
|
-
|
|
131
|
-
starts and still reports its URL under `--no-open`; only the browser launch is skipped. `json` makes
|
|
132
|
-
every line simplex writes to stdout one JSON object, with no ANSI escapes, which is what a captured log
|
|
133
|
-
file needs. (One caveat: `@polkadot/api` prints a plain-text line to stdout if the Hyperbridge runtime
|
|
134
|
-
upgrades while the solver is running, so parse defensively.)
|
|
123
|
+
## Documentation
|
|
135
124
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
-d '{"fillChain": "EVM-8453", "tokenIn": "USDC", "amountIn": "10000",
|
|
144
|
-
"tokenOut": "CNGN", "amountOut": "13900000", "acceptedSources": ["EVM-1", "EVM-8453"]}'
|
|
145
|
-
curl http://127.0.0.1:8686/api/limit-orders/<id> # { order, fills, bids }
|
|
146
|
-
curl -X DELETE http://127.0.0.1:8686/api/limit-orders/<id> -H "X-Simplex-UI: 1"
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
Amounts are whole tokens as decimal strings. `acceptedSources` must name at least one source chain,
|
|
150
|
-
and `ttlSecs` is optional (default `[orderbook] defaultTtlSecs`, or 365 days). Orders live in
|
|
151
|
-
`bids.db`, not the config file: a fill draws an order down and reposts the rest, and it lapses when
|
|
152
|
-
its TTL runs out. See the
|
|
153
|
-
[limit orders guide](https://docs.hyperbridge.network/developers/evm/simplex/limit-orders/).
|
|
154
|
-
|
|
155
|
-
The server is unauthenticated — mutating requests need the `X-Simplex-UI: 1` header (CSRF
|
|
156
|
-
hygiene), and both the wizard and the operator UI bind loopback unless told otherwise. Only bind
|
|
157
|
-
another interface (e.g. `--ui 0.0.0.0:8686`, which the docker image does inside its own network
|
|
158
|
-
namespace) on a trusted network.
|
|
159
|
-
|
|
160
|
-
Loopback is machine-local, not user-local. On a shared machine, another OS user may be able to reach
|
|
161
|
-
the unauthenticated TCP UI and invoke operator actions. Prefer `--ui-socket` in an owner-only
|
|
162
|
-
directory or the authenticated, opt-in tunnel when other local users are not trusted. The generated
|
|
163
|
-
`filler-config.toml` stores signing keys in plaintext; it is written atomically with mode `0600` on
|
|
164
|
-
Unix, but must still be kept out of source control and broadly shared backups.
|
|
165
|
-
|
|
166
|
-
## Remote access from a phone
|
|
167
|
-
|
|
168
|
-
The UI is loopback-only, and most operator machines sit behind NAT. Remote access keeps an
|
|
169
|
-
outbound SSH tunnel from simplex to a relay ([polytope-labs/simplex-tunnel](https://github.com/polytope-labs/simplex-tunnel),
|
|
170
|
-
hosted at `simplex.tunnel.polytope.technology`) that leases this simplex a stable public port.
|
|
171
|
-
A phone's SSH client connects to that port with a local port forward, and the browser opens
|
|
172
|
-
`http://localhost:8686`.
|
|
173
|
-
|
|
174
|
-
The phone's SSH session terminates in an SSH server embedded in simplex, not in sshd and not in
|
|
175
|
-
the relay, so the relay only ever carries ciphertext. That server accepts public-key auth against
|
|
176
|
-
the devices paired in the UI and `direct-tcpip` channels to the UI bind, and nothing else: no
|
|
177
|
-
shell, exec, PTY or other destinations.
|
|
178
|
-
|
|
179
|
-
It is off by default. Turn it on and pair devices under **Operations > Remote access** in the UI;
|
|
180
|
-
the choice is written to `[simplex.tunnel]` in the config. To pair, create a key in the phone's SSH
|
|
181
|
-
app and paste its public key into the panel, so the private key never leaves the phone; for apps
|
|
182
|
-
that cannot make their own, simplex can generate a pair instead and shows the private key exactly
|
|
183
|
-
once, as text and as a QR code. Either way the panel shows the host, port, username, host-key
|
|
184
|
-
fingerprint and local forward to enter in the SSH app (Blink and Termius on iOS, ConnectBot and
|
|
185
|
-
JuiceSSH on Android). A paired key opens the whole dashboard, including the
|
|
186
|
-
Send and treasury tools, so keep it on the device and revoke it from the same panel if the
|
|
187
|
-
device is lost. Keys live under `<data-dir>/tunnel/` in plain OpenSSH formats.
|
|
188
|
-
|
|
189
|
-
The hosted relay's host key is pinned in the binary, so first contact is verified. A self-hosted
|
|
190
|
-
relay is pinned on first contact unless `relayHostKey` in `[simplex.tunnel]` names its fingerprint.
|
|
191
|
-
|
|
192
|
-
The tunnel is best-effort: it retries with backoff and never affects filling. It only runs in
|
|
193
|
-
operator mode, never while the setup wizard holds secrets.
|
|
125
|
+
- [Library guide](https://docs.hyperbridge.network/developers/sdk/simplex/)
|
|
126
|
+
- [API reference](https://docs.hyperbridge.network/developers/sdk/api/simplex/)
|
|
127
|
+
- [Configuration](https://docs.hyperbridge.network/developers/evm/simplex/configuration/)
|
|
128
|
+
- [Limit orders](https://docs.hyperbridge.network/developers/evm/simplex/limit-orders/)
|
|
129
|
+
- [Dashboard](https://docs.hyperbridge.network/developers/evm/simplex/dashboard/) and
|
|
130
|
+
[HTTP API](https://docs.hyperbridge.network/developers/evm/simplex/api/overview/)
|
|
131
|
+
- [Troubleshooting](https://docs.hyperbridge.network/developers/evm/simplex/troubleshooting/)
|
|
194
132
|
|
|
195
133
|
## Development
|
|
196
134
|
|
|
135
|
+
This package lives in the [Hyperbridge monorepo](https://github.com/polytope-labs/hyperbridge) at
|
|
136
|
+
`sdk/packages/simplex`.
|
|
137
|
+
|
|
197
138
|
```bash
|
|
198
139
|
pnpm install
|
|
199
|
-
pnpm build
|
|
140
|
+
pnpm build # library, CLI and dashboard
|
|
200
141
|
pnpm test
|
|
201
|
-
pnpm cli run -c filler-config.toml
|
|
202
|
-
pnpm ui:dev # web UI dev server with /api proxied to a running solver
|
|
203
142
|
```
|
|
204
143
|
|
|
205
|
-
The build emits two shapes from one source tree: the library entry points
|
|
206
|
-
(`dist/index.js`, `dist/sqlite.js`) leave dependencies external so a consumer resolves one copy of
|
|
207
|
-
`viem` and `decimal.js`, while the CLI (`dist/bin/simplex.js`) bundles everything into a single file
|
|
208
|
-
so a global install or the docker image runs without a dependency tree.
|
|
209
|
-
|
|
210
144
|
## License
|
|
211
145
|
|
|
212
|
-
Apache-2.0
|
|
146
|
+
[Apache-2.0](https://github.com/polytope-labs/hyperbridge/blob/main/sdk/packages/simplex/LICENSE)
|