hive-stream 3.0.0 → 3.0.2
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/AGENTS.md +35 -0
- package/DOCUMENTATION.md +396 -0
- package/README.md +160 -39
- package/dist/actions.d.ts +3 -3
- package/dist/actions.js +7 -7
- package/dist/actions.js.map +1 -1
- package/dist/adapters/base.adapter.d.ts +19 -1
- package/dist/adapters/base.adapter.js +16 -0
- package/dist/adapters/base.adapter.js.map +1 -1
- package/dist/adapters/mongodb.adapter.d.ts +5 -11
- package/dist/adapters/mongodb.adapter.js +10 -10
- package/dist/adapters/mongodb.adapter.js.map +1 -1
- package/dist/adapters/postgresql.adapter.d.ts +17 -0
- package/dist/adapters/postgresql.adapter.js +99 -8
- package/dist/adapters/postgresql.adapter.js.map +1 -1
- package/dist/adapters/sqlite.adapter.d.ts +17 -0
- package/dist/adapters/sqlite.adapter.js +99 -8
- package/dist/adapters/sqlite.adapter.js.map +1 -1
- package/dist/api.js +86 -0
- package/dist/api.js.map +1 -1
- package/dist/config.d.ts +26 -0
- package/dist/config.js +76 -4
- package/dist/config.js.map +1 -1
- package/dist/contracts/coinflip.contract.d.ts +8 -26
- package/dist/contracts/coinflip.contract.js +123 -144
- package/dist/contracts/coinflip.contract.js.map +1 -1
- package/dist/contracts/contract.d.ts +3 -0
- package/dist/contracts/contract.js +26 -0
- package/dist/contracts/contract.js.map +1 -0
- package/dist/contracts/dice.contract.d.ts +9 -36
- package/dist/contracts/dice.contract.js +135 -200
- package/dist/contracts/dice.contract.js.map +1 -1
- package/dist/contracts/exchange.contract.d.ts +11 -0
- package/dist/contracts/exchange.contract.js +492 -0
- package/dist/contracts/exchange.contract.js.map +1 -0
- package/dist/contracts/lotto.contract.d.ts +15 -19
- package/dist/contracts/lotto.contract.js +154 -162
- package/dist/contracts/lotto.contract.js.map +1 -1
- package/dist/contracts/nft.contract.d.ts +4 -0
- package/dist/contracts/nft.contract.js +65 -0
- package/dist/contracts/nft.contract.js.map +1 -1
- package/dist/contracts/poll.contract.d.ts +4 -0
- package/dist/contracts/poll.contract.js +105 -0
- package/dist/contracts/poll.contract.js.map +1 -0
- package/dist/contracts/rps.contract.d.ts +9 -0
- package/dist/contracts/rps.contract.js +217 -0
- package/dist/contracts/rps.contract.js.map +1 -0
- package/dist/contracts/tipjar.contract.d.ts +4 -0
- package/dist/contracts/tipjar.contract.js +60 -0
- package/dist/contracts/tipjar.contract.js.map +1 -0
- package/dist/contracts/token.contract.d.ts +3 -17
- package/dist/contracts/token.contract.js +128 -80
- package/dist/contracts/token.contract.js.map +1 -1
- package/dist/exchanges/coingecko.d.ts +7 -1
- package/dist/exchanges/coingecko.js +38 -21
- package/dist/exchanges/coingecko.js.map +1 -1
- package/dist/exchanges/exchange.d.ts +15 -8
- package/dist/exchanges/exchange.js +65 -11
- package/dist/exchanges/exchange.js.map +1 -1
- package/dist/hive-rates.d.ts +29 -4
- package/dist/hive-rates.js +179 -92
- package/dist/hive-rates.js.map +1 -1
- package/dist/index.d.ts +11 -3
- package/dist/index.js +19 -4
- package/dist/index.js.map +1 -1
- package/dist/metadata.d.ts +63 -0
- package/dist/metadata.js +407 -0
- package/dist/metadata.js.map +1 -0
- package/dist/streamer.d.ts +104 -11
- package/dist/streamer.js +415 -143
- package/dist/streamer.js.map +1 -1
- package/dist/test.js +11 -12
- package/dist/test.js.map +1 -1
- package/dist/types/hive-stream.d.ts +85 -14
- package/dist/types/rates.d.ts +47 -0
- package/dist/types/rates.js +29 -0
- package/dist/types/rates.js.map +1 -0
- package/dist/utils.d.ts +318 -11
- package/dist/utils.js +804 -115
- package/dist/utils.js.map +1 -1
- package/examples/contracts/README.md +8 -0
- package/examples/contracts/exchange.ts +38 -0
- package/examples/contracts/poll.ts +21 -0
- package/examples/contracts/rps.ts +19 -0
- package/examples/contracts/tipjar.ts +19 -0
- package/package.json +20 -19
- package/test-contract-block.md +3 -3
- package/tests/actions.spec.ts +7 -7
- package/tests/adapters/actions-persistence.spec.ts +4 -4
- package/tests/adapters/sqlite.adapter.spec.ts +2 -2
- package/tests/config-input.spec.ts +90 -0
- package/tests/contracts/coinflip.contract.spec.ts +26 -154
- package/tests/contracts/dice.contract.spec.ts +24 -140
- package/tests/contracts/exchange.contract.spec.ts +84 -0
- package/tests/contracts/lotto.contract.spec.ts +30 -295
- package/tests/contracts/token.contract.spec.ts +72 -316
- package/tests/exchanges/coingecko.exchange.spec.ts +169 -0
- package/tests/exchanges/exchange.base.spec.ts +246 -0
- package/tests/helpers/mock-fetch.ts +165 -0
- package/tests/hive-chain-features.spec.ts +319 -0
- package/tests/hive-rates.spec.ts +443 -0
- package/tests/integration/hive-rates.integration.spec.ts +35 -0
- package/tests/metadata.spec.ts +63 -0
- package/tests/streamer-actions.spec.ts +29 -18
- package/tests/streamer.spec.ts +142 -49
- package/tests/types/rates.spec.ts +216 -0
- package/tests/utils.spec.ts +27 -6
package/AGENTS.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Repository Guidelines
|
|
2
|
+
|
|
3
|
+
## Project Structure & Module Organization
|
|
4
|
+
- `src/` holds TypeScript source. Core entry points are `streamer.ts`, `api.ts`, and `index.ts`.
|
|
5
|
+
- `src/adapters/` contains SQLite/Mongo/Postgres adapters; `src/contracts/` has contract examples; `src/exchanges/` has rate helpers; `src/types/` centralizes shared types.
|
|
6
|
+
- `tests/` contains Jest specs (`**/*.spec.ts`) plus `tests/integration/` and `tests/helpers/`.
|
|
7
|
+
- `dist/` is generated build output; `examples/` provides usage samples; `ecosystem.config.js` is a PM2 reference.
|
|
8
|
+
|
|
9
|
+
## Build, Test, and Development Commands
|
|
10
|
+
- `npm install` installs dependencies.
|
|
11
|
+
- `npm run build` compiles TypeScript to `dist/`.
|
|
12
|
+
- `npm run start` runs the local dev harness (`src/test.ts`) via ts-node.
|
|
13
|
+
- `npm run watch` enables TypeScript watch mode.
|
|
14
|
+
- `npm test` runs the Jest suite.
|
|
15
|
+
- `npm run clean-tests` clears Jest cache if tests act stale.
|
|
16
|
+
|
|
17
|
+
## Coding Style & Naming Conventions
|
|
18
|
+
- TypeScript with CommonJS output; keep module boundaries within `src/`.
|
|
19
|
+
- Indent 4 spaces; prefer single quotes (see `tslint.json`).
|
|
20
|
+
- File naming conventions: `*.adapter.ts`, `*.contract.ts`, `*.spec.ts`; shared types live in `src/types/`.
|
|
21
|
+
- TSLint rules in `tslint.json` are the baseline; match existing style before introducing new tooling.
|
|
22
|
+
|
|
23
|
+
## Testing Guidelines
|
|
24
|
+
- Framework: Jest + `ts-jest` (see `jest.config.js`).
|
|
25
|
+
- Place specs under `tests/` and name `*.spec.ts` (example: `tests/utils.spec.ts`).
|
|
26
|
+
- Use `tests/setup.ts` for shared mocks; integration tests live under `tests/integration/`.
|
|
27
|
+
- No coverage thresholds are configured; add focused tests for new adapters, contracts, or API routes.
|
|
28
|
+
|
|
29
|
+
## Commit & Pull Request Guidelines
|
|
30
|
+
- Follow Conventional Commits with scopes, as in history: `feat(api): ...`, `fix(contract): ...`, `chore(deps): ...`, `docs(readme): ...`.
|
|
31
|
+
- PRs should include: a clear summary, testing notes (`npm test`/`npm run build`), and docs/CHANGELOG updates for user-facing changes.
|
|
32
|
+
|
|
33
|
+
## Configuration & Security Notes
|
|
34
|
+
- Keys and usernames should come from env/config (see `src/config.ts`); never commit secrets.
|
|
35
|
+
- When adding new config, document defaults and keep backward compatibility.
|
package/DOCUMENTATION.md
ADDED
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
# Hive-Stream Documentation
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
Hive Stream is a Node.js library for streaming Hive blockchain activity and routing it to contracts you define. Contracts can react to:
|
|
5
|
+
- `custom_json` operations
|
|
6
|
+
- transfer memos
|
|
7
|
+
- time-based actions
|
|
8
|
+
- escrow operations
|
|
9
|
+
|
|
10
|
+
This document focuses on the contract system and how to build robust contracts using the new `defineContract`/`action` API.
|
|
11
|
+
|
|
12
|
+
By default, `new Streamer()` registers the SQLite adapter and starts the built-in Express API server on port `5001` when `NODE_ENV !== 'test'`.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Concepts
|
|
17
|
+
|
|
18
|
+
### Contracts
|
|
19
|
+
A **contract** is a definition object with:
|
|
20
|
+
- a **name**
|
|
21
|
+
- one or more **actions**
|
|
22
|
+
- optional **lifecycle hooks**
|
|
23
|
+
|
|
24
|
+
Contracts are registered with the `Streamer` and called when a payload matches `contract` + `action`.
|
|
25
|
+
|
|
26
|
+
### Actions
|
|
27
|
+
An **action** is a handler function plus metadata such as:
|
|
28
|
+
- the trigger (`custom_json`, `transfer`, `time`, `escrow_transfer`, `escrow_approve`, `escrow_dispute`, `escrow_release`, or `recurrent_transfer`)
|
|
29
|
+
- an optional Zod schema to validate payloads
|
|
30
|
+
- whether it requires an active key signature
|
|
31
|
+
|
|
32
|
+
### Payload Identifier
|
|
33
|
+
Hive Stream extracts payloads from:
|
|
34
|
+
- **custom_json**: `op[1].json`
|
|
35
|
+
- **transfer memo**: `op[1].memo`
|
|
36
|
+
- **recurrent transfer memo**: `op[1].memo`
|
|
37
|
+
- **escrow metadata**: `op[1].json_meta`
|
|
38
|
+
|
|
39
|
+
It expects a wrapper object that looks like:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
{
|
|
43
|
+
"hive_stream": {
|
|
44
|
+
"contract": "mycontract",
|
|
45
|
+
"action": "doSomething",
|
|
46
|
+
"payload": { "any": "data" },
|
|
47
|
+
"meta": { "optional": true }
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The wrapper key `hive_stream` is the default `PAYLOAD_IDENTIFIER`. You can change it in config.
|
|
53
|
+
|
|
54
|
+
Relevant configuration defaults:
|
|
55
|
+
|
|
56
|
+
- `PAYLOAD_IDENTIFIER`: `hive_stream`
|
|
57
|
+
- `JSON_ID`: `hivestream`
|
|
58
|
+
- `HIVE_ENGINE_ID`: `ssc-mainnet-hive`
|
|
59
|
+
- `HIVE_ENGINE_API`: `https://api.hive-engine.com/rpc`
|
|
60
|
+
|
|
61
|
+
### Event Handlers vs Contracts
|
|
62
|
+
Streamer event handlers (`onTransfer`, `onCustomJson`, `onCustomJsonId`, etc.) and contract actions are different execution paths.
|
|
63
|
+
|
|
64
|
+
- Event handlers fire for matching blockchain operations.
|
|
65
|
+
- Contract actions only run when a valid wrapper exists under `PAYLOAD_IDENTIFIER` and the `contract` + `action` values match a registered contract action.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Contract API
|
|
70
|
+
|
|
71
|
+
### Define a Contract
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { defineContract, action } from 'hive-stream';
|
|
75
|
+
|
|
76
|
+
const MyContract = defineContract({
|
|
77
|
+
name: 'mycontract',
|
|
78
|
+
actions: {
|
|
79
|
+
hello: action(async (payload, ctx) => {
|
|
80
|
+
console.log('hello', payload.name, ctx.sender);
|
|
81
|
+
}, {
|
|
82
|
+
trigger: 'custom_json'
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Register a Contract
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { Streamer } from 'hive-stream';
|
|
92
|
+
|
|
93
|
+
const streamer = new Streamer();
|
|
94
|
+
await streamer.registerContract(MyContract);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Unregister a Contract
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
await streamer.unregisterContract('mycontract');
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Contract Lifecycle Hooks
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
const MyContract = defineContract({
|
|
107
|
+
name: 'mycontract',
|
|
108
|
+
hooks: {
|
|
109
|
+
create: async ({ streamer, adapter, config }) => {
|
|
110
|
+
// initialize tables, cache config, etc
|
|
111
|
+
},
|
|
112
|
+
destroy: async ({ streamer, adapter }) => {
|
|
113
|
+
// cleanup resources
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
actions: { ... }
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Contract Context
|
|
123
|
+
|
|
124
|
+
Every action receives a `ContractContext` with:
|
|
125
|
+
|
|
126
|
+
- `trigger`: `custom_json | transfer | time | escrow_transfer | escrow_approve | escrow_dispute | escrow_release | recurrent_transfer`
|
|
127
|
+
- `streamer`: access to Hive client and helpers
|
|
128
|
+
- `adapter`: database adapter
|
|
129
|
+
- `config`: resolved config values
|
|
130
|
+
- `block`: `{ number, id, previousId, time }`
|
|
131
|
+
- `transaction`: `{ id }`
|
|
132
|
+
- `sender`: Hive account invoking the action
|
|
133
|
+
- `transfer`: transfer details (only for `transfer` trigger)
|
|
134
|
+
- `customJson`: custom JSON details (only for `custom_json` trigger)
|
|
135
|
+
- `escrow`: escrow details (only for escrow triggers)
|
|
136
|
+
- `operation`: raw operation data and operation type for advanced use cases
|
|
137
|
+
|
|
138
|
+
### Example
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
action((payload, ctx) => {
|
|
142
|
+
console.log(ctx.trigger);
|
|
143
|
+
console.log(ctx.block.number, ctx.transaction.id);
|
|
144
|
+
if (ctx.transfer) {
|
|
145
|
+
console.log(ctx.transfer.amount, ctx.transfer.asset);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Payload Validation (Zod)
|
|
153
|
+
|
|
154
|
+
Use Zod to validate payloads and enforce strong inputs:
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import { z } from 'zod';
|
|
158
|
+
|
|
159
|
+
const schema = z.object({
|
|
160
|
+
amount: z.string().min(1),
|
|
161
|
+
to: z.string().min(1)
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
const MyContract = defineContract({
|
|
165
|
+
name: 'payments',
|
|
166
|
+
actions: {
|
|
167
|
+
send: action((payload, ctx) => {
|
|
168
|
+
// payload is validated here
|
|
169
|
+
}, { schema, trigger: 'custom_json' })
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
If validation fails, the action is not executed and the error is logged.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Triggers
|
|
179
|
+
|
|
180
|
+
Actions can be scoped to a trigger:
|
|
181
|
+
|
|
182
|
+
- `custom_json`: called when a custom JSON payload matches
|
|
183
|
+
- `transfer`: called when a transfer memo matches
|
|
184
|
+
- `time`: called by a `TimeAction`
|
|
185
|
+
- `escrow_transfer`: called when escrow transfer payload in `json_meta` matches
|
|
186
|
+
- `escrow_approve`: available as a trigger for escrow-related contracts
|
|
187
|
+
- `escrow_dispute`: available as a trigger for escrow-related contracts
|
|
188
|
+
- `escrow_release`: available as a trigger for escrow-related contracts
|
|
189
|
+
- `recurrent_transfer`: called when recurrent transfer memo payload matches
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
action(handler, { trigger: 'transfer' });
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
You can also allow multiple triggers:
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
action(handler, { trigger: ['custom_json', 'transfer'] });
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Active Key Enforcement
|
|
204
|
+
|
|
205
|
+
Some actions should only run when the transaction is signed with an active key. Mark them with:
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
action(handler, { trigger: 'custom_json', requiresActiveKey: true });
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
This prevents posting-key JSONs from triggering sensitive actions like withdrawals.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Error Handling
|
|
216
|
+
|
|
217
|
+
- Errors inside contract actions are caught and logged.
|
|
218
|
+
- **Time actions** bubble errors back into the scheduler so the action does **not** increment execution count if it fails.
|
|
219
|
+
|
|
220
|
+
Write actions defensively and always validate inputs.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Time-Based Actions
|
|
225
|
+
|
|
226
|
+
Time-based actions let you run contract logic on a schedule:
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
import { TimeAction } from 'hive-stream';
|
|
230
|
+
|
|
231
|
+
const matchAction = new TimeAction('30s', 'exchange-matcher', 'exchange', 'matchOrders', { limit: 50 });
|
|
232
|
+
await streamer.registerAction(matchAction);
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
The action must have `trigger: 'time'` in its definition.
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Adapter Requirements
|
|
240
|
+
|
|
241
|
+
Contracts can use any adapter, but some require SQL features:
|
|
242
|
+
|
|
243
|
+
- **SQL adapters** (SQLite/Postgres) support `adapter.query(...)`.
|
|
244
|
+
- **MongoDB adapter** does not support raw SQL.
|
|
245
|
+
|
|
246
|
+
If a contract uses `adapter.query`, it must document that it requires a SQL adapter.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Building Contracts Step-by-Step
|
|
251
|
+
|
|
252
|
+
1. **Define the contract** with `defineContract`.
|
|
253
|
+
2. **Define actions** with `action`, specifying trigger and optional schema.
|
|
254
|
+
3. **Use hooks** (`create`, `destroy`) to initialize tables or cache configuration.
|
|
255
|
+
4. **Validate input** using Zod.
|
|
256
|
+
5. **Use `ctx`** for block/transaction context.
|
|
257
|
+
6. **Return void** (actions are fire-and-forget).
|
|
258
|
+
7. **Register the contract** with the streamer.
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Example Contract
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
import { defineContract, action } from 'hive-stream';
|
|
266
|
+
import { z } from 'zod';
|
|
267
|
+
|
|
268
|
+
const tipSchema = z.object({
|
|
269
|
+
message: z.string().max(280).optional()
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
export const TipJar = defineContract({
|
|
273
|
+
name: 'tipjar',
|
|
274
|
+
actions: {
|
|
275
|
+
tip: action(async (payload, ctx) => {
|
|
276
|
+
if (!ctx.transfer) {
|
|
277
|
+
throw new Error('Transfer context required');
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
console.log(`Tip from ${ctx.sender}: ${ctx.transfer.amount} ${ctx.transfer.asset}`);
|
|
281
|
+
if (payload.message) {
|
|
282
|
+
console.log(`Message: ${payload.message}`);
|
|
283
|
+
}
|
|
284
|
+
}, {
|
|
285
|
+
schema: tipSchema,
|
|
286
|
+
trigger: 'transfer'
|
|
287
|
+
})
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## Built-in Contract Examples
|
|
295
|
+
|
|
296
|
+
- `createDiceContract` - Dice game using transfer bets
|
|
297
|
+
- `createCoinflipContract` - Coin flip game using transfer bets
|
|
298
|
+
- `createLottoContract` - Lottery system with scheduled draws
|
|
299
|
+
- `createTokenContract` - SQL-backed fungible tokens
|
|
300
|
+
- `createNFTContract` - SQL-backed NFTs
|
|
301
|
+
- `createRpsContract` - Rock/Paper/Scissors
|
|
302
|
+
- `createPollContract` - Polls and votes
|
|
303
|
+
- `createTipJarContract` - Tip jar + message log
|
|
304
|
+
- `createExchangeContract` - Deposits/withdrawals/orders/matching (SQL)
|
|
305
|
+
|
|
306
|
+
### Example Snippets
|
|
307
|
+
|
|
308
|
+
Quick-start snippets live in `examples/contracts/`:
|
|
309
|
+
|
|
310
|
+
- `examples/contracts/rps.ts`
|
|
311
|
+
- `examples/contracts/poll.ts`
|
|
312
|
+
- `examples/contracts/tipjar.ts`
|
|
313
|
+
- `examples/contracts/exchange.ts`
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## Exchange Contract Guide
|
|
318
|
+
|
|
319
|
+
The exchange contract gives you a basic on-chain orderbook experience backed by a SQL adapter.
|
|
320
|
+
|
|
321
|
+
### Features
|
|
322
|
+
- Deposits via transfer memo
|
|
323
|
+
- Internal balances (available + locked)
|
|
324
|
+
- Order placement and cancellation
|
|
325
|
+
- Order matching
|
|
326
|
+
- Withdrawals (active key required)
|
|
327
|
+
- Internal transfers between exchange users
|
|
328
|
+
- Maker/taker fees (basis points)
|
|
329
|
+
- Order book snapshots for API consumption
|
|
330
|
+
|
|
331
|
+
### Notes
|
|
332
|
+
- Requires a SQL adapter (SQLite or Postgres).
|
|
333
|
+
- Uses `TimeAction` to run `matchOrders` periodically.
|
|
334
|
+
- Fees are charged on received assets (base for buyers, quote for sellers).
|
|
335
|
+
|
|
336
|
+
### Configuration Options
|
|
337
|
+
```
|
|
338
|
+
createExchangeContract({
|
|
339
|
+
name: 'exchange',
|
|
340
|
+
account: 'my-exchange',
|
|
341
|
+
feeAccount: 'my-exchange-fees',
|
|
342
|
+
makerFeeBps: 10,
|
|
343
|
+
takerFeeBps: 20
|
|
344
|
+
})
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Example Payloads
|
|
348
|
+
|
|
349
|
+
**Create pair**
|
|
350
|
+
```
|
|
351
|
+
{"hive_stream": {"contract":"exchange","action":"createPair","payload":{"base":"HIVE","quote":"HBD"}}}
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
**Deposit** (send transfer to exchange account with memo)
|
|
355
|
+
```
|
|
356
|
+
{"hive_stream": {"contract":"exchange","action":"deposit","payload":{}}}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
**Place order**
|
|
360
|
+
```
|
|
361
|
+
{"hive_stream": {"contract":"exchange","action":"placeOrder","payload":{"side":"buy","base":"HIVE","quote":"HBD","price":"2","amount":"5"}}}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
**Cancel order**
|
|
365
|
+
```
|
|
366
|
+
{"hive_stream": {"contract":"exchange","action":"cancelOrder","payload":{"orderId":"..."}}}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**Snapshot orderbook**
|
|
370
|
+
```
|
|
371
|
+
{"hive_stream": {"contract":"exchange","action":"snapshotOrderBook","payload":{"base":"HIVE","quote":"HBD","depth":20}}}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
**Withdraw**
|
|
375
|
+
```
|
|
376
|
+
{"hive_stream": {"contract":"exchange","action":"withdraw","payload":{"asset":"HBD","amount":"5.000"}}}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### API Endpoints
|
|
380
|
+
|
|
381
|
+
If you run the built-in API server, the following endpoints are available:
|
|
382
|
+
|
|
383
|
+
- `GET /exchange/balances` (optional query `?account=alice`)
|
|
384
|
+
- `GET /exchange/orders` (query `account`, `base`, `quote`, `status`)
|
|
385
|
+
- `GET /exchange/trades` (query `account`, `base`, `quote`)
|
|
386
|
+
- `GET /exchange/orderbook` (query `base`, `quote`, `limit`)
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## Utilities
|
|
391
|
+
The library includes helpers for JSON parsing, randomness, and transfer verification. See `src/utils.ts` for details.
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## Tests
|
|
396
|
+
Contract tests live under `tests/contracts/`. Time action tests are in `tests/streamer-actions.spec.ts`.
|