@onchaindb/sdk 0.4.0 → 0.4.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/.DS_Store +0 -0
- package/.claude/settings.local.json +8 -0
- package/.gitignore +5 -0
- package/.idea/.gitignore +5 -0
- package/.idea/compiler.xml +6 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/jsLinters/eslint.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/prettier.xml +7 -0
- package/.idea/sdk.iml +12 -0
- package/.idea/vcs.xml +6 -0
- package/.idea/workspace.xml +257 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +11 -3
- package/dist/client.js.map +1 -1
- package/dist/database.d.ts +0 -20
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +0 -40
- package/dist/database.js.map +1 -1
- package/dist/query-sdk/tests/setup.d.ts +16 -0
- package/dist/query-sdk/tests/setup.d.ts.map +1 -0
- package/dist/query-sdk/tests/setup.js +49 -0
- package/dist/query-sdk/tests/setup.js.map +1 -0
- package/examples/basic-usage.ts +136 -0
- package/examples/blob-upload-example.ts +140 -0
- package/examples/collection-schema-example.ts +304 -0
- package/examples/server-side-joins.ts +201 -0
- package/examples/tweet-self-joins-example.ts +352 -0
- package/package-lock.json +3823 -0
- package/package.json +1 -1
- package/skills.md +1096 -0
- package/src/.env +1 -0
- package/src/batch.d.ts +121 -0
- package/src/batch.js +205 -0
- package/src/batch.ts +257 -0
- package/src/client.ts +1856 -0
- package/src/database.d.ts +268 -0
- package/src/database.js +294 -0
- package/src/database.ts +695 -0
- package/src/index.d.ts +160 -0
- package/src/index.js +186 -0
- package/src/index.ts +253 -0
- package/src/query-sdk/ConditionBuilder.ts +103 -0
- package/src/query-sdk/FieldConditionBuilder.ts +2 -0
- package/src/query-sdk/NestedBuilders.ts +186 -0
- package/src/query-sdk/OnChainDB.ts +294 -0
- package/src/query-sdk/QueryBuilder.ts +1191 -0
- package/src/query-sdk/QueryResult.ts +375 -0
- package/src/query-sdk/README.md +866 -0
- package/src/query-sdk/SelectionBuilder.ts +94 -0
- package/src/query-sdk/adapters/HttpClientAdapter.ts +249 -0
- package/src/query-sdk/dist/ConditionBuilder.d.ts +22 -0
- package/src/query-sdk/dist/ConditionBuilder.js +90 -0
- package/src/query-sdk/dist/FieldConditionBuilder.d.ts +1 -0
- package/src/query-sdk/dist/FieldConditionBuilder.js +6 -0
- package/src/query-sdk/dist/NestedBuilders.d.ts +43 -0
- package/src/query-sdk/dist/NestedBuilders.js +144 -0
- package/src/query-sdk/dist/OnChainDB.d.ts +19 -0
- package/src/query-sdk/dist/OnChainDB.js +123 -0
- package/src/query-sdk/dist/QueryBuilder.d.ts +70 -0
- package/src/query-sdk/dist/QueryBuilder.js +295 -0
- package/src/query-sdk/dist/QueryResult.d.ts +52 -0
- package/src/query-sdk/dist/QueryResult.js +293 -0
- package/src/query-sdk/dist/SelectionBuilder.d.ts +20 -0
- package/src/query-sdk/dist/SelectionBuilder.js +80 -0
- package/src/query-sdk/dist/adapters/HttpClientAdapter.d.ts +27 -0
- package/src/query-sdk/dist/adapters/HttpClientAdapter.js +170 -0
- package/src/query-sdk/dist/index.d.ts +36 -0
- package/src/query-sdk/dist/index.js +27 -0
- package/src/query-sdk/dist/operators.d.ts +56 -0
- package/src/query-sdk/dist/operators.js +289 -0
- package/src/query-sdk/dist/tests/setup.d.ts +15 -0
- package/src/query-sdk/dist/tests/setup.js +46 -0
- package/src/query-sdk/index.ts +59 -0
- package/src/query-sdk/jest.config.js +25 -0
- package/src/query-sdk/operators.ts +335 -0
- package/src/query-sdk/package.json +46 -0
- package/src/query-sdk/tests/FieldConditionBuilder.test.ts +84 -0
- package/src/query-sdk/tests/LogicalOperator.test.ts +85 -0
- package/src/query-sdk/tests/NestedBuilders.test.ts +321 -0
- package/src/query-sdk/tests/QueryBuilder.test.ts +348 -0
- package/src/query-sdk/tests/QueryResult.test.ts +464 -0
- package/src/query-sdk/tests/aggregations.test.ts +653 -0
- package/src/query-sdk/tests/comprehensive.test.ts +279 -0
- package/src/query-sdk/tests/integration.test.ts +608 -0
- package/src/query-sdk/tests/operators.test.ts +327 -0
- package/src/query-sdk/tests/setup.ts +59 -0
- package/src/query-sdk/tests/unit.test.ts +794 -0
- package/src/query-sdk/tsconfig.json +26 -0
- package/src/query-sdk/yarn.lock +3092 -0
- package/src/types.d.ts +131 -0
- package/src/types.js +46 -0
- package/src/types.ts +534 -0
- package/src/x402/index.ts +12 -0
- package/src/x402/types.ts +250 -0
- package/src/x402/utils.ts +332 -0
- package/tsconfig.json +20 -0
- package/yarn.lock +2309 -0
package/skills.md
ADDED
|
@@ -0,0 +1,1096 @@
|
|
|
1
|
+
# OnChainDB Agent Skills - Pure cURL Commands
|
|
2
|
+
|
|
3
|
+
Complete reference for working with OnChainDB using pure HTTP requests. No SDK required.
|
|
4
|
+
|
|
5
|
+
## Environment Variables
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
export ONCHAINDB_ENDPOINT="https://api.onchaindb.com"
|
|
9
|
+
export ONCHAINDB_APP_ID="your_app_id"
|
|
10
|
+
export ONCHAINDB_APP_KEY="your_app_key"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 1. Collection Management
|
|
16
|
+
|
|
17
|
+
### Create Collection
|
|
18
|
+
|
|
19
|
+
Create a new collection with schema definition.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/collections" \
|
|
23
|
+
-H "Content-Type: application/json" \
|
|
24
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
25
|
+
-d '{
|
|
26
|
+
"name": "orderbook_snapshots",
|
|
27
|
+
"namespace": "hyperliquid",
|
|
28
|
+
"primary_column": "id",
|
|
29
|
+
"sort_column": "timestamp",
|
|
30
|
+
"schema_definition": {
|
|
31
|
+
"fields": {
|
|
32
|
+
"id": { "type": "string", "index": true, "unique": true },
|
|
33
|
+
"market": { "type": "string", "index": true },
|
|
34
|
+
"timestamp": { "type": "number", "index": true },
|
|
35
|
+
"mid_price": { "type": "number" },
|
|
36
|
+
"spread_bps": { "type": "number" },
|
|
37
|
+
"bids": { "type": "array" },
|
|
38
|
+
"asks": { "type": "array" },
|
|
39
|
+
"total_bid_liquidity_usd": { "type": "number" },
|
|
40
|
+
"total_ask_liquidity_usd": { "type": "number" },
|
|
41
|
+
"order_book_imbalance": { "type": "number" },
|
|
42
|
+
"data_source": { "type": "string" }
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}'
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### List Collections
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
curl -X GET "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/collections" \
|
|
52
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Get Collection Details
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
curl -X GET "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/collections/orderbook_snapshots" \
|
|
59
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Delete Collection
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
curl -X DELETE "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/collections/orderbook_snapshots" \
|
|
66
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
67
|
+
-d '{ "force": true, "cascade": true }'
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 2. Sharding Configuration
|
|
73
|
+
|
|
74
|
+
### Update Collection Sharding
|
|
75
|
+
|
|
76
|
+
Configure time-series sharding for high-volume collections.
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
curl -X PATCH "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/collections/orderbook_snapshots/sharding" \
|
|
80
|
+
-H "Content-Type: application/json" \
|
|
81
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
82
|
+
-d '{
|
|
83
|
+
"keys": [
|
|
84
|
+
{
|
|
85
|
+
"field": "market",
|
|
86
|
+
"type": "hashed"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"field": "timestamp",
|
|
90
|
+
"type": "time_series",
|
|
91
|
+
"granularity": "hour"
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
"enforce_in_queries": true,
|
|
95
|
+
"max_shard_size": 100000000
|
|
96
|
+
}'
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Sharding Strategies:**
|
|
100
|
+
|
|
101
|
+
- **Time-series sharding**: Shard by timestamp (hour/day)
|
|
102
|
+
- **Hashed sharding**: Distribute by market/symbol
|
|
103
|
+
- **Combined**: Time + market for optimal distribution
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 3. Index Management
|
|
108
|
+
|
|
109
|
+
### Create Index
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/indexes" \
|
|
113
|
+
-H "Content-Type: application/json" \
|
|
114
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
115
|
+
-d '{
|
|
116
|
+
"name": "orderbook_market_idx",
|
|
117
|
+
"collection": "orderbook_snapshots",
|
|
118
|
+
"field_name": "market",
|
|
119
|
+
"index_type": "btree",
|
|
120
|
+
"options": {
|
|
121
|
+
"unique": false
|
|
122
|
+
}
|
|
123
|
+
}'
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Create Composite Index
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/indexes" \
|
|
130
|
+
-H "Content-Type: application/json" \
|
|
131
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
132
|
+
-d '{
|
|
133
|
+
"name": "orderbook_market_time_idx",
|
|
134
|
+
"collection": "orderbook_snapshots",
|
|
135
|
+
"field_name": "market",
|
|
136
|
+
"index_type": "composite",
|
|
137
|
+
"fields": ["market", "timestamp"],
|
|
138
|
+
"options": {
|
|
139
|
+
"unique": false
|
|
140
|
+
}
|
|
141
|
+
}'
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### List Indexes
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# All indexes for an app
|
|
148
|
+
curl -X GET "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/indexes" \
|
|
149
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}"
|
|
150
|
+
|
|
151
|
+
# Indexes for specific collection
|
|
152
|
+
curl -X GET "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/collections/orderbook_snapshots/indexes" \
|
|
153
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}"
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Drop Index
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
curl -X DELETE "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/collections/orderbook_snapshots/indexes/orderbook_market_idx" \
|
|
160
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}"
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 4. Data Ingestion (Store)
|
|
166
|
+
|
|
167
|
+
### Store Single Record
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/store" \
|
|
171
|
+
-H "Content-Type: application/json" \
|
|
172
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
173
|
+
-d '{
|
|
174
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
175
|
+
"data": [{
|
|
176
|
+
"id": "BTC_1735862400000",
|
|
177
|
+
"market": "BTC",
|
|
178
|
+
"timestamp": 1735862400000,
|
|
179
|
+
"mid_price": 98500.50,
|
|
180
|
+
"spread_bps": 2.5,
|
|
181
|
+
"bids": [
|
|
182
|
+
{ "px": "98500.00", "sz": "1.5", "n": 3 },
|
|
183
|
+
{ "px": "98499.00", "sz": "2.0", "n": 5 }
|
|
184
|
+
],
|
|
185
|
+
"asks": [
|
|
186
|
+
{ "px": "98501.00", "sz": "1.2", "n": 2 },
|
|
187
|
+
{ "px": "98502.00", "sz": "1.8", "n": 4 }
|
|
188
|
+
],
|
|
189
|
+
"total_bid_liquidity_usd": 295000.00,
|
|
190
|
+
"total_ask_liquidity_usd": 280000.00,
|
|
191
|
+
"order_book_imbalance": 0.026,
|
|
192
|
+
"data_source": "websocket"
|
|
193
|
+
}]
|
|
194
|
+
}'
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Store Batch Records
|
|
198
|
+
|
|
199
|
+
Store multiple records in a single request (up to 1000 records recommended per batch).
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/store" \
|
|
203
|
+
-H "Content-Type: application/json" \
|
|
204
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
205
|
+
-d '{
|
|
206
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
207
|
+
"data": [
|
|
208
|
+
{
|
|
209
|
+
"id": "BTC_1735862400000",
|
|
210
|
+
"market": "BTC",
|
|
211
|
+
"timestamp": 1735862400000,
|
|
212
|
+
"mid_price": 98500.50,
|
|
213
|
+
"spread_bps": 2.5,
|
|
214
|
+
"total_bid_liquidity_usd": 295000.00,
|
|
215
|
+
"total_ask_liquidity_usd": 280000.00,
|
|
216
|
+
"order_book_imbalance": 0.026
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"id": "ETH_1735862400000",
|
|
220
|
+
"market": "ETH",
|
|
221
|
+
"timestamp": 1735862400000,
|
|
222
|
+
"mid_price": 3850.25,
|
|
223
|
+
"spread_bps": 3.0,
|
|
224
|
+
"total_bid_liquidity_usd": 180000.00,
|
|
225
|
+
"total_ask_liquidity_usd": 175000.00,
|
|
226
|
+
"order_book_imbalance": 0.014
|
|
227
|
+
}
|
|
228
|
+
]
|
|
229
|
+
}'
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Response:**
|
|
233
|
+
```json
|
|
234
|
+
{
|
|
235
|
+
"ticket_id": "task_abc123",
|
|
236
|
+
"status": "queued",
|
|
237
|
+
"message": "Data queued for processing"
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Check Store Task Status
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
curl -X GET "${ONCHAINDB_ENDPOINT}/tasks/task_abc123" \
|
|
245
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}"
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## 5. Data Querying
|
|
251
|
+
|
|
252
|
+
### Simple Query - All Records
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
256
|
+
-H "Content-Type: application/json" \
|
|
257
|
+
-d '{
|
|
258
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
259
|
+
"find": {},
|
|
260
|
+
"select": {},
|
|
261
|
+
"limit": 100,
|
|
262
|
+
"offset": 0
|
|
263
|
+
}'
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Query with Filter - Single Field
|
|
267
|
+
|
|
268
|
+
Query records for a specific market.
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
272
|
+
-H "Content-Type: application/json" \
|
|
273
|
+
-d '{
|
|
274
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
275
|
+
"find": {
|
|
276
|
+
"market": { "eq": "BTC" }
|
|
277
|
+
},
|
|
278
|
+
"select": {},
|
|
279
|
+
"limit": 100,
|
|
280
|
+
"offset": 0
|
|
281
|
+
}'
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Query with Time Range
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
288
|
+
-H "Content-Type: application/json" \
|
|
289
|
+
-d '{
|
|
290
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
291
|
+
"find": {
|
|
292
|
+
"and": [
|
|
293
|
+
{ "market": { "eq": "BTC" } },
|
|
294
|
+
{ "timestamp": { "gte": 1735862400000 } },
|
|
295
|
+
{ "timestamp": { "lte": 1735948800000 } }
|
|
296
|
+
]
|
|
297
|
+
},
|
|
298
|
+
"select": {
|
|
299
|
+
"market": true,
|
|
300
|
+
"timestamp": true,
|
|
301
|
+
"mid_price": true,
|
|
302
|
+
"spread_bps": true
|
|
303
|
+
},
|
|
304
|
+
"limit": 1000,
|
|
305
|
+
"offset": 0,
|
|
306
|
+
"sortBy": "timestamp"
|
|
307
|
+
}'
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Query with Pagination
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
# Page 1
|
|
314
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
315
|
+
-H "Content-Type: application/json" \
|
|
316
|
+
-d '{
|
|
317
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
318
|
+
"find": { "market": { "eq": "BTC" } },
|
|
319
|
+
"select": {},
|
|
320
|
+
"limit": 9000,
|
|
321
|
+
"offset": 0,
|
|
322
|
+
"sortBy": "timestamp"
|
|
323
|
+
}'
|
|
324
|
+
|
|
325
|
+
# Page 2
|
|
326
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
327
|
+
-H "Content-Type: application/json" \
|
|
328
|
+
-d '{
|
|
329
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
330
|
+
"find": { "market": { "eq": "BTC" } },
|
|
331
|
+
"select": {},
|
|
332
|
+
"limit": 9000,
|
|
333
|
+
"offset": 9000,
|
|
334
|
+
"sortBy": "timestamp"
|
|
335
|
+
}'
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Query with Multiple Markets (IN operator)
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
342
|
+
-H "Content-Type: application/json" \
|
|
343
|
+
-d '{
|
|
344
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
345
|
+
"find": {
|
|
346
|
+
"market": { "in": ["BTC", "ETH", "SOL"] }
|
|
347
|
+
},
|
|
348
|
+
"select": {},
|
|
349
|
+
"limit": 1000,
|
|
350
|
+
"offset": 0
|
|
351
|
+
}'
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### Query with Complex Conditions
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
358
|
+
-H "Content-Type: application/json" \
|
|
359
|
+
-d '{
|
|
360
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
361
|
+
"find": {
|
|
362
|
+
"and": [
|
|
363
|
+
{ "market": { "in": ["BTC", "ETH"] } },
|
|
364
|
+
{ "timestamp": { "gte": 1735862400000 } },
|
|
365
|
+
{ "spread_bps": { "lt": 5.0 } },
|
|
366
|
+
{ "order_book_imbalance": { "between": [-0.1, 0.1] } }
|
|
367
|
+
]
|
|
368
|
+
},
|
|
369
|
+
"select": {
|
|
370
|
+
"market": true,
|
|
371
|
+
"timestamp": true,
|
|
372
|
+
"mid_price": true,
|
|
373
|
+
"spread_bps": true,
|
|
374
|
+
"order_book_imbalance": true
|
|
375
|
+
},
|
|
376
|
+
"limit": 500,
|
|
377
|
+
"sortBy": "timestamp"
|
|
378
|
+
}'
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## 6. Materialized Views
|
|
384
|
+
|
|
385
|
+
### Create Materialized View
|
|
386
|
+
|
|
387
|
+
Create aggregated view for market summary statistics.
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/views" \
|
|
391
|
+
-H "Content-Type: application/json" \
|
|
392
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
393
|
+
-d '{
|
|
394
|
+
"name": "market_summary",
|
|
395
|
+
"source_collections": ["orderbook_snapshots"],
|
|
396
|
+
"query": {
|
|
397
|
+
"select": [
|
|
398
|
+
"market",
|
|
399
|
+
"mid_price",
|
|
400
|
+
"spread_bps",
|
|
401
|
+
"total_bid_liquidity_usd",
|
|
402
|
+
"total_ask_liquidity_usd",
|
|
403
|
+
"timestamp"
|
|
404
|
+
],
|
|
405
|
+
"group_by": ["market"],
|
|
406
|
+
"aggregate": {
|
|
407
|
+
"avg_mid_price": { "$avg": "mid_price" },
|
|
408
|
+
"avg_spread_bps": { "$avg": "spread_bps" },
|
|
409
|
+
"avg_bid_liquidity": { "$avg": "total_bid_liquidity_usd" },
|
|
410
|
+
"avg_ask_liquidity": { "$avg": "total_ask_liquidity_usd" },
|
|
411
|
+
"max_timestamp": { "$max": "timestamp" },
|
|
412
|
+
"total_snapshots": { "$count": "*" }
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}'
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Create OHLC View (1-minute candles)
|
|
419
|
+
|
|
420
|
+
```bash
|
|
421
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/views" \
|
|
422
|
+
-H "Content-Type: application/json" \
|
|
423
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
424
|
+
-d '{
|
|
425
|
+
"name": "ohlc_1min_candles",
|
|
426
|
+
"source_collections": ["orderbook_snapshots"],
|
|
427
|
+
"query": {
|
|
428
|
+
"select": [],
|
|
429
|
+
"find": {},
|
|
430
|
+
"group_by": ["market", "timestamp"],
|
|
431
|
+
"aggregate": {
|
|
432
|
+
"open_price": { "$avg": "mid_price" },
|
|
433
|
+
"high_price": { "$max": "mid_price" },
|
|
434
|
+
"low_price": { "$min": "mid_price" },
|
|
435
|
+
"close_price": { "$avg": "mid_price" },
|
|
436
|
+
"avg_spread": { "$avg": "spread_bps" },
|
|
437
|
+
"total_bid_liquidity": { "$sum": "total_bid_liquidity_usd" },
|
|
438
|
+
"total_ask_liquidity": { "$sum": "total_ask_liquidity_usd" },
|
|
439
|
+
"snapshot_count": { "$count": "*" }
|
|
440
|
+
},
|
|
441
|
+
"sort_by": ["market", "timestamp"]
|
|
442
|
+
}
|
|
443
|
+
}'
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### List All Views
|
|
447
|
+
|
|
448
|
+
```bash
|
|
449
|
+
curl -X GET "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/views" \
|
|
450
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}"
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### Delete View
|
|
454
|
+
|
|
455
|
+
```bash
|
|
456
|
+
curl -X DELETE "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/views/market_summary" \
|
|
457
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}"
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### Query Materialized View
|
|
461
|
+
|
|
462
|
+
Query a view the same way as a regular collection.
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
466
|
+
-H "Content-Type: application/json" \
|
|
467
|
+
-d '{
|
|
468
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::market_summary",
|
|
469
|
+
"find": {},
|
|
470
|
+
"select": {},
|
|
471
|
+
"limit": 100
|
|
472
|
+
}'
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
## 7. Data Aggregation Patterns
|
|
478
|
+
|
|
479
|
+
### Pattern 1: OHLC Aggregation
|
|
480
|
+
|
|
481
|
+
Aggregate orderbook snapshots into 1-minute OHLC candles.
|
|
482
|
+
|
|
483
|
+
**Step 1: Fetch snapshots for a time range**
|
|
484
|
+
|
|
485
|
+
```bash
|
|
486
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
487
|
+
-H "Content-Type: application/json" \
|
|
488
|
+
-d '{
|
|
489
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
490
|
+
"find": {
|
|
491
|
+
"and": [
|
|
492
|
+
{ "market": { "eq": "BTC" } },
|
|
493
|
+
{ "timestamp": { "gte": 1735862400000 } },
|
|
494
|
+
{ "timestamp": { "lte": 1735866000000 } }
|
|
495
|
+
]
|
|
496
|
+
},
|
|
497
|
+
"select": {
|
|
498
|
+
"id": true,
|
|
499
|
+
"market": true,
|
|
500
|
+
"timestamp": true,
|
|
501
|
+
"mid_price": true,
|
|
502
|
+
"spread_bps": true,
|
|
503
|
+
"total_bid_liquidity_usd": true,
|
|
504
|
+
"total_ask_liquidity_usd": true
|
|
505
|
+
},
|
|
506
|
+
"sortBy": "timestamp",
|
|
507
|
+
"limit": 9000,
|
|
508
|
+
"offset": 0
|
|
509
|
+
}'
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
**Step 2: Aggregate client-side and store**
|
|
513
|
+
|
|
514
|
+
```bash
|
|
515
|
+
# After aggregating data into 1-minute candles client-side:
|
|
516
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/store" \
|
|
517
|
+
-H "Content-Type: application/json" \
|
|
518
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
519
|
+
-d '{
|
|
520
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::ohlc_1min",
|
|
521
|
+
"data": [{
|
|
522
|
+
"id": "BTC_1735862400000",
|
|
523
|
+
"timestamp_1min": 1735862400000,
|
|
524
|
+
"market": "BTC",
|
|
525
|
+
"open_mid": 98500.50,
|
|
526
|
+
"high_mid": 98550.00,
|
|
527
|
+
"low_mid": 98480.00,
|
|
528
|
+
"close_mid": 98520.25,
|
|
529
|
+
"avg_spread_bps": 2.8,
|
|
530
|
+
"avg_total_liquidity_usd": 575000.00,
|
|
531
|
+
"snapshot_count": 60
|
|
532
|
+
}]
|
|
533
|
+
}'
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### Pattern 2: Liquidity Scoring
|
|
537
|
+
|
|
538
|
+
Calculate liquidity metrics from orderbook data.
|
|
539
|
+
|
|
540
|
+
**Fetch and aggregate:**
|
|
541
|
+
|
|
542
|
+
```bash
|
|
543
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
544
|
+
-H "Content-Type: application/json" \
|
|
545
|
+
-d '{
|
|
546
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
547
|
+
"find": {
|
|
548
|
+
"and": [
|
|
549
|
+
{ "market": { "eq": "ETH" } },
|
|
550
|
+
{ "timestamp": { "gte": 1735862400000 } },
|
|
551
|
+
{ "timestamp": { "lt": 1735862700000 } }
|
|
552
|
+
]
|
|
553
|
+
},
|
|
554
|
+
"select": {
|
|
555
|
+
"market": true,
|
|
556
|
+
"timestamp": true,
|
|
557
|
+
"mid_price": true,
|
|
558
|
+
"bids": true,
|
|
559
|
+
"asks": true,
|
|
560
|
+
"total_bid_liquidity_usd": true,
|
|
561
|
+
"total_ask_liquidity_usd": true
|
|
562
|
+
},
|
|
563
|
+
"sortBy": "timestamp",
|
|
564
|
+
"limit": 9000
|
|
565
|
+
}'
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
**Store liquidity scores:**
|
|
569
|
+
|
|
570
|
+
```bash
|
|
571
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/store" \
|
|
572
|
+
-H "Content-Type: application/json" \
|
|
573
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
574
|
+
-d '{
|
|
575
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::liquidity_scores",
|
|
576
|
+
"data": [{
|
|
577
|
+
"id": "ETH_1735862400000",
|
|
578
|
+
"market": "ETH",
|
|
579
|
+
"timestamp": 1735862400000,
|
|
580
|
+
"total_liquidity_usd": 355000.00,
|
|
581
|
+
"bid_liquidity_usd": 180000.00,
|
|
582
|
+
"ask_liquidity_usd": 175000.00,
|
|
583
|
+
"liquidity_imbalance": 0.014,
|
|
584
|
+
"depth_score": 85.5,
|
|
585
|
+
"support_levels": [3848.50, 3847.00, 3845.00],
|
|
586
|
+
"resistance_levels": [3851.00, 3852.50, 3855.00]
|
|
587
|
+
}]
|
|
588
|
+
}'
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
### Pattern 3: Market Correlation Analysis
|
|
592
|
+
|
|
593
|
+
Calculate correlations between market pairs.
|
|
594
|
+
|
|
595
|
+
```bash
|
|
596
|
+
# Store correlation results
|
|
597
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/store" \
|
|
598
|
+
-H "Content-Type: application/json" \
|
|
599
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
600
|
+
-d '{
|
|
601
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::market_correlations",
|
|
602
|
+
"data": [{
|
|
603
|
+
"id": "BTC_ETH_1735862400000",
|
|
604
|
+
"timestamp": 1735862400000,
|
|
605
|
+
"market_pair": "BTC_ETH",
|
|
606
|
+
"correlation_1h": 0.85,
|
|
607
|
+
"correlation_24h": 0.78,
|
|
608
|
+
"correlation_7d": 0.82,
|
|
609
|
+
"covariance": 15.5,
|
|
610
|
+
"beta": 0.92
|
|
611
|
+
}]
|
|
612
|
+
}'
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
### Pattern 4: Volatility Metrics
|
|
616
|
+
|
|
617
|
+
Calculate and store volatility across time windows.
|
|
618
|
+
|
|
619
|
+
```bash
|
|
620
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/store" \
|
|
621
|
+
-H "Content-Type: application/json" \
|
|
622
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
623
|
+
-d '{
|
|
624
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::volatility_metrics",
|
|
625
|
+
"data": [{
|
|
626
|
+
"id": "SOL_1735862400000",
|
|
627
|
+
"market": "SOL",
|
|
628
|
+
"timestamp": 1735862400000,
|
|
629
|
+
"volatility_5min": 0.012,
|
|
630
|
+
"volatility_15min": 0.018,
|
|
631
|
+
"volatility_1h": 0.025,
|
|
632
|
+
"price_range_5min": 2.50,
|
|
633
|
+
"avg_price_5min": 125.75
|
|
634
|
+
}]
|
|
635
|
+
}'
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
---
|
|
639
|
+
|
|
640
|
+
## 8. Advanced Query Operators
|
|
641
|
+
|
|
642
|
+
### Comparison Operators
|
|
643
|
+
|
|
644
|
+
```bash
|
|
645
|
+
# Greater than / Less than
|
|
646
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
647
|
+
-H "Content-Type: application/json" \
|
|
648
|
+
-d '{
|
|
649
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
650
|
+
"find": {
|
|
651
|
+
"and": [
|
|
652
|
+
{ "mid_price": { "gt": 90000 } },
|
|
653
|
+
{ "spread_bps": { "lt": 3.0 } }
|
|
654
|
+
]
|
|
655
|
+
},
|
|
656
|
+
"select": {},
|
|
657
|
+
"limit": 100
|
|
658
|
+
}'
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
### Between Operator
|
|
662
|
+
|
|
663
|
+
```bash
|
|
664
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
665
|
+
-H "Content-Type: application/json" \
|
|
666
|
+
-d '{
|
|
667
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
668
|
+
"find": {
|
|
669
|
+
"mid_price": { "between": [95000, 100000] }
|
|
670
|
+
},
|
|
671
|
+
"select": {},
|
|
672
|
+
"limit": 100
|
|
673
|
+
}'
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
### String Operators
|
|
677
|
+
|
|
678
|
+
```bash
|
|
679
|
+
# Contains, starts with, ends with
|
|
680
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
681
|
+
-H "Content-Type: application/json" \
|
|
682
|
+
-d '{
|
|
683
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
684
|
+
"find": {
|
|
685
|
+
"or": [
|
|
686
|
+
{ "market": { "contains": "BTC" } },
|
|
687
|
+
{ "market": { "startsWith": "ETH" } },
|
|
688
|
+
{ "data_source": { "endsWith": "socket" } }
|
|
689
|
+
]
|
|
690
|
+
},
|
|
691
|
+
"select": {},
|
|
692
|
+
"limit": 100
|
|
693
|
+
}'
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
### Null Checks
|
|
697
|
+
|
|
698
|
+
```bash
|
|
699
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
700
|
+
-H "Content-Type: application/json" \
|
|
701
|
+
-d '{
|
|
702
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
703
|
+
"find": {
|
|
704
|
+
"and": [
|
|
705
|
+
{ "order_book_imbalance": { "isNotNull": true } },
|
|
706
|
+
{ "deletedAt": { "isNull": true } }
|
|
707
|
+
]
|
|
708
|
+
},
|
|
709
|
+
"select": {},
|
|
710
|
+
"limit": 100
|
|
711
|
+
}'
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
---
|
|
715
|
+
|
|
716
|
+
## 9. Historical Data Onboarding
|
|
717
|
+
|
|
718
|
+
### Pattern: Bulk Historical Import
|
|
719
|
+
|
|
720
|
+
For onboarding large historical datasets:
|
|
721
|
+
|
|
722
|
+
**Step 1: Download and decompress data** (external to OnChainDB)
|
|
723
|
+
**Step 2: Transform to JSON**
|
|
724
|
+
**Step 3: Batch insert in chunks**
|
|
725
|
+
|
|
726
|
+
```bash
|
|
727
|
+
# Insert batch of 1000 records
|
|
728
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/store" \
|
|
729
|
+
-H "Content-Type: application/json" \
|
|
730
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
731
|
+
-d '{
|
|
732
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
733
|
+
"data": [
|
|
734
|
+
{ "id": "BTC_1735862400000", "market": "BTC", "timestamp": 1735862400000, ... },
|
|
735
|
+
{ "id": "BTC_1735862460000", "market": "BTC", "timestamp": 1735862460000, ... },
|
|
736
|
+
...
|
|
737
|
+
{ "id": "BTC_1735922340000", "market": "BTC", "timestamp": 1735922340000, ... }
|
|
738
|
+
]
|
|
739
|
+
}'
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
**Best Practices:**
|
|
743
|
+
- Batch size: 500-1000 records per request
|
|
744
|
+
- Use waitForConfirmation=true to ensure data is committed
|
|
745
|
+
- Process hour-by-hour to manage memory
|
|
746
|
+
- Use parallel requests for different markets
|
|
747
|
+
|
|
748
|
+
---
|
|
749
|
+
|
|
750
|
+
## 10. Query Result Operators
|
|
751
|
+
|
|
752
|
+
### Available Operators in `find` Clause
|
|
753
|
+
|
|
754
|
+
| Operator | Usage | Example |
|
|
755
|
+
|----------|-------|---------|
|
|
756
|
+
| `eq` | Equals | `{ "market": { "eq": "BTC" } }` |
|
|
757
|
+
| `ne` | Not equals | `{ "market": { "ne": "BTC" } }` |
|
|
758
|
+
| `gt` | Greater than | `{ "price": { "gt": 100000 } }` |
|
|
759
|
+
| `gte` | Greater than or equal | `{ "price": { "gte": 100000 } }` |
|
|
760
|
+
| `lt` | Less than | `{ "spread": { "lt": 5.0 } }` |
|
|
761
|
+
| `lte` | Less than or equal | `{ "spread": { "lte": 5.0 } }` |
|
|
762
|
+
| `in` | In array | `{ "market": { "in": ["BTC", "ETH"] } }` |
|
|
763
|
+
| `notIn` | Not in array | `{ "status": { "notIn": ["deleted"] } }` |
|
|
764
|
+
| `between` | Between range | `{ "price": { "between": [90000, 100000] } }` |
|
|
765
|
+
| `contains` | String contains | `{ "market": { "contains": "BTC" } }` |
|
|
766
|
+
| `startsWith` | String starts with | `{ "market": { "startsWith": "BTC" } }` |
|
|
767
|
+
| `endsWith` | String ends with | `{ "source": { "endsWith": "socket" } }` |
|
|
768
|
+
| `isNull` | Is null | `{ "deletedAt": { "isNull": true } }` |
|
|
769
|
+
| `isNotNull` | Is not null | `{ "price": { "isNotNull": true } }` |
|
|
770
|
+
|
|
771
|
+
### Logical Operators
|
|
772
|
+
|
|
773
|
+
```bash
|
|
774
|
+
# AND - all conditions must match
|
|
775
|
+
{
|
|
776
|
+
"and": [
|
|
777
|
+
{ "market": { "eq": "BTC" } },
|
|
778
|
+
{ "timestamp": { "gte": 1735862400000 } }
|
|
779
|
+
]
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
# OR - any condition must match
|
|
783
|
+
{
|
|
784
|
+
"or": [
|
|
785
|
+
{ "market": { "eq": "BTC" } },
|
|
786
|
+
{ "market": { "eq": "ETH" } }
|
|
787
|
+
]
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
# Nested conditions
|
|
791
|
+
{
|
|
792
|
+
"and": [
|
|
793
|
+
{
|
|
794
|
+
"or": [
|
|
795
|
+
{ "market": { "eq": "BTC" } },
|
|
796
|
+
{ "market": { "eq": "ETH" } }
|
|
797
|
+
]
|
|
798
|
+
},
|
|
799
|
+
{ "timestamp": { "gte": 1735862400000 } }
|
|
800
|
+
]
|
|
801
|
+
}
|
|
802
|
+
```
|
|
803
|
+
|
|
804
|
+
---
|
|
805
|
+
|
|
806
|
+
## 11. Complete Examples by Use Case
|
|
807
|
+
|
|
808
|
+
### Use Case 1: Real-time Market Data Platform
|
|
809
|
+
|
|
810
|
+
```bash
|
|
811
|
+
# 1. Setup collection
|
|
812
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/collections" \
|
|
813
|
+
-H "Content-Type: application/json" \
|
|
814
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
815
|
+
-d '{
|
|
816
|
+
"name": "orderbook_snapshots",
|
|
817
|
+
"namespace": "markets",
|
|
818
|
+
"primary_column": "id",
|
|
819
|
+
"sort_column": "timestamp"
|
|
820
|
+
}'
|
|
821
|
+
|
|
822
|
+
# 2. Configure sharding
|
|
823
|
+
curl -X PATCH "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/collections/orderbook_snapshots/sharding" \
|
|
824
|
+
-H "Content-Type: application/json" \
|
|
825
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
826
|
+
-d '{
|
|
827
|
+
"keys": [
|
|
828
|
+
{ "field": "market", "type": "hashed" },
|
|
829
|
+
{ "field": "timestamp", "type": "time_series", "granularity": "hour" }
|
|
830
|
+
],
|
|
831
|
+
"enforce_in_queries": true
|
|
832
|
+
}'
|
|
833
|
+
|
|
834
|
+
# 3. Create indexes
|
|
835
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/indexes" \
|
|
836
|
+
-H "Content-Type: application/json" \
|
|
837
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
838
|
+
-d '{
|
|
839
|
+
"name": "orderbook_market_time_idx",
|
|
840
|
+
"collection": "orderbook_snapshots",
|
|
841
|
+
"field_name": "market",
|
|
842
|
+
"index_type": "composite",
|
|
843
|
+
"fields": ["market", "timestamp"]
|
|
844
|
+
}'
|
|
845
|
+
|
|
846
|
+
# 4. Ingest real-time data
|
|
847
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/store" \
|
|
848
|
+
-H "Content-Type: application/json" \
|
|
849
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
850
|
+
-d '{
|
|
851
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
852
|
+
"data": [...]
|
|
853
|
+
}'
|
|
854
|
+
|
|
855
|
+
# 5. Query latest prices
|
|
856
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
857
|
+
-H "Content-Type: application/json" \
|
|
858
|
+
-d '{
|
|
859
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
860
|
+
"find": { "market": { "eq": "BTC" } },
|
|
861
|
+
"sortBy": "timestamp",
|
|
862
|
+
"limit": 1
|
|
863
|
+
}'
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
### Use Case 2: Analytics Platform
|
|
867
|
+
|
|
868
|
+
```bash
|
|
869
|
+
# 1. Create OHLC view
|
|
870
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/api/apps/${ONCHAINDB_APP_ID}/views" \
|
|
871
|
+
-H "Content-Type: application/json" \
|
|
872
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
873
|
+
-d '{
|
|
874
|
+
"name": "ohlc_1min",
|
|
875
|
+
"source_collections": ["orderbook_snapshots"],
|
|
876
|
+
"query": {
|
|
877
|
+
"group_by": ["market", "timestamp"],
|
|
878
|
+
"aggregate": {
|
|
879
|
+
"open": { "$first": "mid_price" },
|
|
880
|
+
"high": { "$max": "mid_price" },
|
|
881
|
+
"low": { "$min": "mid_price" },
|
|
882
|
+
"close": { "$last": "mid_price" }
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
}'
|
|
886
|
+
|
|
887
|
+
# 2. Query aggregated data
|
|
888
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
889
|
+
-H "Content-Type: application/json" \
|
|
890
|
+
-d '{
|
|
891
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::ohlc_1min",
|
|
892
|
+
"find": {
|
|
893
|
+
"and": [
|
|
894
|
+
{ "market": { "eq": "BTC" } },
|
|
895
|
+
{ "timestamp": { "gte": 1735862400000 } }
|
|
896
|
+
]
|
|
897
|
+
},
|
|
898
|
+
"limit": 1440
|
|
899
|
+
}'
|
|
900
|
+
```
|
|
901
|
+
|
|
902
|
+
---
|
|
903
|
+
|
|
904
|
+
## 12. Error Handling
|
|
905
|
+
|
|
906
|
+
### Common HTTP Status Codes
|
|
907
|
+
|
|
908
|
+
- `200` - Success
|
|
909
|
+
- `400` - Bad Request (invalid JSON or parameters)
|
|
910
|
+
- `401` - Unauthorized (missing or invalid API key)
|
|
911
|
+
- `402` - Payment Required (x402 protocol - payment needed)
|
|
912
|
+
- `404` - Not Found (collection or view doesn't exist)
|
|
913
|
+
- `429` - Too Many Requests (rate limited)
|
|
914
|
+
- `500` - Internal Server Error
|
|
915
|
+
|
|
916
|
+
### Sample Error Response
|
|
917
|
+
|
|
918
|
+
```json
|
|
919
|
+
{
|
|
920
|
+
"error": "Collection not found",
|
|
921
|
+
"code": "COLLECTION_NOT_FOUND",
|
|
922
|
+
"details": {
|
|
923
|
+
"collection": "orderbook_snapshots",
|
|
924
|
+
"app_id": "app_12345"
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
```
|
|
928
|
+
|
|
929
|
+
---
|
|
930
|
+
|
|
931
|
+
## 13. Best Practices
|
|
932
|
+
|
|
933
|
+
### Performance Optimization
|
|
934
|
+
|
|
935
|
+
1. **Use pagination for large datasets** (limit ≤ 9000 per request)
|
|
936
|
+
2. **Create indexes on frequently queried fields**
|
|
937
|
+
3. **Use composite indexes for multi-field queries**
|
|
938
|
+
4. **Configure sharding for time-series data**
|
|
939
|
+
5. **Use materialized views for expensive aggregations**
|
|
940
|
+
6. **Batch inserts (500-1000 records per request)**
|
|
941
|
+
|
|
942
|
+
### Query Optimization
|
|
943
|
+
|
|
944
|
+
```bash
|
|
945
|
+
# GOOD: Use indexed fields in filters
|
|
946
|
+
{
|
|
947
|
+
"find": {
|
|
948
|
+
"and": [
|
|
949
|
+
{ "market": { "eq": "BTC" } }, # indexed
|
|
950
|
+
{ "timestamp": { "gte": 1735862400000 } } # indexed
|
|
951
|
+
]
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
# GOOD: Select only needed fields
|
|
956
|
+
{
|
|
957
|
+
"select": {
|
|
958
|
+
"market": true,
|
|
959
|
+
"timestamp": true,
|
|
960
|
+
"mid_price": true
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
# BAD: Don't query without filters on large collections
|
|
965
|
+
{
|
|
966
|
+
"find": {}, # This fetches everything!
|
|
967
|
+
"limit": 1000000
|
|
968
|
+
}
|
|
969
|
+
```
|
|
970
|
+
|
|
971
|
+
### Data Modeling
|
|
972
|
+
|
|
973
|
+
1. **Use unique IDs**: Combine fields like `${market}_${timestamp}`
|
|
974
|
+
2. **Normalize timestamps**: Use Unix milliseconds
|
|
975
|
+
3. **Denormalize for reads**: Duplicate data to avoid JOINs
|
|
976
|
+
4. **Shard high-volume collections**: Time-series + hashed keys
|
|
977
|
+
5. **Create aggregation collections**: Store pre-computed metrics
|
|
978
|
+
|
|
979
|
+
---
|
|
980
|
+
|
|
981
|
+
## 14. x402 Payment Protocol (Optional)
|
|
982
|
+
|
|
983
|
+
OnChainDB supports x402 payment protocol for paid queries. If a request requires payment, you'll receive a 402 response:
|
|
984
|
+
|
|
985
|
+
### Sample 402 Response
|
|
986
|
+
|
|
987
|
+
```json
|
|
988
|
+
{
|
|
989
|
+
"accepts": [{
|
|
990
|
+
"quoteId": "quote_abc123",
|
|
991
|
+
"network": "mocha-4",
|
|
992
|
+
"payTo": "celestia1abc...",
|
|
993
|
+
"maxAmountRequired": "1000000",
|
|
994
|
+
"token": { "symbol": "TIA", "decimals": 6 }
|
|
995
|
+
}]
|
|
996
|
+
}
|
|
997
|
+
```
|
|
998
|
+
|
|
999
|
+
### Retry with Payment
|
|
1000
|
+
|
|
1001
|
+
After paying via Celestia wallet:
|
|
1002
|
+
|
|
1003
|
+
```bash
|
|
1004
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
1005
|
+
-H "Content-Type: application/json" \
|
|
1006
|
+
-H "X-PAYMENT: eyJ4NDAyVmVyc2lvbiI6MSwic2NoZW1lIjoiZXhhY3QiLCJuZXR3b3JrIjoibW9jaGEtNCIsInF1b3RlSWQiOiJxdW90ZV9hYmMxMjMiLCJwYXlsb2FkIjp7InR4SGFzaCI6IjB4Li4uIiwic2VuZGVyIjoiY2VsZXN0aWExeHl6In19" \
|
|
1007
|
+
-d '{
|
|
1008
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
1009
|
+
"find": {},
|
|
1010
|
+
"limit": 100
|
|
1011
|
+
}'
|
|
1012
|
+
```
|
|
1013
|
+
|
|
1014
|
+
---
|
|
1015
|
+
|
|
1016
|
+
## 15. Shell Script Helpers
|
|
1017
|
+
|
|
1018
|
+
### Batch Insert Loop
|
|
1019
|
+
|
|
1020
|
+
```bash
|
|
1021
|
+
#!/bin/bash
|
|
1022
|
+
# Insert 1000 records per batch
|
|
1023
|
+
|
|
1024
|
+
for i in {0..9}; do
|
|
1025
|
+
start=$((i * 1000))
|
|
1026
|
+
end=$(((i + 1) * 1000))
|
|
1027
|
+
|
|
1028
|
+
echo "Inserting batch $i (records $start-$end)..."
|
|
1029
|
+
|
|
1030
|
+
curl -X POST "${ONCHAINDB_ENDPOINT}/store" \
|
|
1031
|
+
-H "Content-Type: application/json" \
|
|
1032
|
+
-H "X-App-Key: ${ONCHAINDB_APP_KEY}" \
|
|
1033
|
+
-d @batch_${i}.json
|
|
1034
|
+
|
|
1035
|
+
sleep 1 # Rate limiting
|
|
1036
|
+
done
|
|
1037
|
+
```
|
|
1038
|
+
|
|
1039
|
+
### Paginated Query Loop
|
|
1040
|
+
|
|
1041
|
+
```bash
|
|
1042
|
+
#!/bin/bash
|
|
1043
|
+
# Fetch all records with pagination
|
|
1044
|
+
|
|
1045
|
+
offset=0
|
|
1046
|
+
limit=9000
|
|
1047
|
+
total_fetched=0
|
|
1048
|
+
|
|
1049
|
+
while true; do
|
|
1050
|
+
echo "Fetching offset=$offset..."
|
|
1051
|
+
|
|
1052
|
+
response=$(curl -s -X POST "${ONCHAINDB_ENDPOINT}/list" \
|
|
1053
|
+
-H "Content-Type: application/json" \
|
|
1054
|
+
-d '{
|
|
1055
|
+
"root": "'"${ONCHAINDB_APP_ID}"'::orderbook_snapshots",
|
|
1056
|
+
"find": { "market": { "eq": "BTC" } },
|
|
1057
|
+
"limit": '"$limit"',
|
|
1058
|
+
"offset": '"$offset"'
|
|
1059
|
+
}')
|
|
1060
|
+
|
|
1061
|
+
count=$(echo "$response" | jq '.records | length')
|
|
1062
|
+
total_fetched=$((total_fetched + count))
|
|
1063
|
+
|
|
1064
|
+
echo "Fetched $count records (total: $total_fetched)"
|
|
1065
|
+
|
|
1066
|
+
# Save to file
|
|
1067
|
+
echo "$response" | jq '.records[]' >> output.jsonl
|
|
1068
|
+
|
|
1069
|
+
# Check if we got less than limit (last page)
|
|
1070
|
+
if [ "$count" -lt "$limit" ]; then
|
|
1071
|
+
echo "Done! Total records: $total_fetched"
|
|
1072
|
+
break
|
|
1073
|
+
fi
|
|
1074
|
+
|
|
1075
|
+
offset=$((offset + limit))
|
|
1076
|
+
done
|
|
1077
|
+
```
|
|
1078
|
+
|
|
1079
|
+
---
|
|
1080
|
+
|
|
1081
|
+
## Summary
|
|
1082
|
+
|
|
1083
|
+
This guide covers all OnChainDB operations using pure curl commands:
|
|
1084
|
+
|
|
1085
|
+
1. **Collection Management** - Create, list, update, delete collections
|
|
1086
|
+
2. **Sharding** - Configure time-series and hashed sharding
|
|
1087
|
+
3. **Indexing** - Create BTree, composite, and price indexes
|
|
1088
|
+
4. **Data Ingestion** - Store single and batch records
|
|
1089
|
+
5. **Querying** - Simple, filtered, paginated queries
|
|
1090
|
+
6. **Views** - Create materialized views for aggregations
|
|
1091
|
+
7. **Aggregation Patterns** - OHLC, liquidity, correlation, volatility
|
|
1092
|
+
8. **Advanced Operators** - All comparison and logical operators
|
|
1093
|
+
9. **Use Cases** - Complete examples for real-world scenarios
|
|
1094
|
+
10. **Best Practices** - Performance and data modeling tips
|
|
1095
|
+
|
|
1096
|
+
For more information, visit: https://docs.onchaindb.com
|