@pulsepairs/sdk 0.9.0 → 0.9.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/DOCUMENTATION.md +6 -2
- package/README.md +46 -6
- package/dist/http.d.ts +4 -1
- package/dist/http.js +4 -1
- package/dist/index.d.ts +1 -1
- package/dist/types.d.ts +28 -3
- package/package.json +2 -2
package/DOCUMENTATION.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# `@pulsepairs/sdk` — Reference Documentation
|
|
2
2
|
|
|
3
|
-
**Version:** 0.
|
|
3
|
+
**Version:** 0.9.2 · **License:** UNLICENSED · **Runtime:** Node ≥ 18 or a modern browser
|
|
4
4
|
|
|
5
5
|
Complete reference for the UpDown TypeScript SDK: every export, its
|
|
6
6
|
units, its failure modes, and the protocol it speaks.
|
|
@@ -43,10 +43,14 @@ returns, what unit a number is in, or why a signature is being rejected.
|
|
|
43
43
|
## 1. What this SDK is
|
|
44
44
|
|
|
45
45
|
UpDown is a binary prediction market: *will BTC-USD (or ETH-USD) be UP or DOWN at
|
|
46
|
-
the end of this 5-minute
|
|
46
|
+
the end of this 5-minute or 15-minute cycle?* Trading is an **off-chain
|
|
47
47
|
central limit order book** (the "matcher"); settlement is **on-chain** on
|
|
48
48
|
Arbitrum.
|
|
49
49
|
|
|
50
|
+
60-minute cycles were retired on 2026-08-18 and no new ones are created. The
|
|
51
|
+
`3600` timeframe is still accepted and still returns the historical rounds — see
|
|
52
|
+
`getMarkets` under [§5 `UpDownHttpClient`](#5-updownhttpclient--rest-client).
|
|
53
|
+
|
|
50
54
|
The SDK gives you three layers, usable independently:
|
|
51
55
|
|
|
52
56
|
| Layer | Modules | What it does |
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @pulsepairs/sdk
|
|
2
2
|
|
|
3
3
|
Standalone SDK for the **UpDown** up/down prediction markets —
|
|
4
|
-
BTC-USD / ETH-USD, UP or DOWN, on 5-minute
|
|
4
|
+
BTC-USD / ETH-USD, UP or DOWN, on 5-minute and 15-minute cycles.
|
|
5
5
|
|
|
6
6
|
> **On the name:** the product is **UpDown**. "PulsePairs" is a retired name that
|
|
7
7
|
> survives in two places for compatibility reasons only — this npm package's name
|
|
@@ -456,6 +456,32 @@ for (const f of bulkFailures(res)) {
|
|
|
456
456
|
|
|
457
457
|
`index` is the position in the array you sent — results are positional.
|
|
458
458
|
|
|
459
|
+
**On success the order is NESTED, and the single routes spread it.** This is
|
|
460
|
+
the one asymmetry that bites, because nothing about the call site hints at it:
|
|
461
|
+
|
|
462
|
+
```ts
|
|
463
|
+
const single = await api.amendOrder({ cancelOrderId, order });
|
|
464
|
+
single.id; // flat — the replacement's id
|
|
465
|
+
|
|
466
|
+
const bulk = await api.amendOrdersBulk({ amends });
|
|
467
|
+
for (const r of bulk.results) {
|
|
468
|
+
if (!r.ok) continue; // narrow first; failures have no `order`
|
|
469
|
+
r.order.id; // NESTED — `r.id` is undefined
|
|
470
|
+
r.replaced; // the id that was retired
|
|
471
|
+
r.priorityKept; // false when queue position was forfeited
|
|
472
|
+
r.remaining; // atomic USDT carried to the replacement
|
|
473
|
+
}
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
`postOrdersBulk` nests the same way: `results[i].order`, never `results[i].id`.
|
|
477
|
+
|
|
478
|
+
Reading `results[i].id` yields `undefined` rather than throwing, so the mistake
|
|
479
|
+
survives to wherever that id is used — usually a later cancel that silently
|
|
480
|
+
matches nothing. SDK **0.9.0 typed the bulk result flat** and shipped that
|
|
481
|
+
mistake into the types themselves; 0.9.1 corrected them. The wire shape never
|
|
482
|
+
changed, so no server behaviour depends on which version you are on — but on
|
|
483
|
+
0.9.0 the compiler will agree with you while you read the wrong field.
|
|
484
|
+
|
|
459
485
|
Two behavioural differences worth knowing, because they change how latency
|
|
460
486
|
scales:
|
|
461
487
|
|
|
@@ -475,11 +501,25 @@ would otherwise see each other's half-applied state. Both cap at 20 per request.
|
|
|
475
501
|
UPND_INTEGRATION=1 PRIVATE_KEY=0x… npm run test:integration
|
|
476
502
|
```
|
|
477
503
|
|
|
478
|
-
It rests an order, amends it, bulk-places two,
|
|
479
|
-
everything in a `finally` — including on failure.
|
|
480
|
-
to run against prod without `UPND_ALLOW_PROD=1`,
|
|
481
|
-
and only dev's USDT is play money. Needs a live 5m
|
|
482
|
-
the keeper has to be cycling.
|
|
504
|
+
It grants the collateral allowance, rests an order, amends it, bulk-places two,
|
|
505
|
+
bulk-amends those, and cancels everything in a `finally` — including on failure.
|
|
506
|
+
It defaults to dev and refuses to run against prod without `UPND_ALLOW_PROD=1`,
|
|
507
|
+
because it places real orders and only dev's USDT is play money. Needs a live 5m
|
|
508
|
+
market with >120s left, so the keeper has to be cycling.
|
|
509
|
+
|
|
510
|
+
The key needs mock USDT and a little gas ETH. On dev the public faucet gives
|
|
511
|
+
both in one call:
|
|
512
|
+
|
|
513
|
+
```bash
|
|
514
|
+
curl -X POST https://dev-api-updown.rain.trade/test/devmint \
|
|
515
|
+
-H 'Content-Type: application/json' \
|
|
516
|
+
-d '{"address":"0x…","amount":"100000000"}'
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
The **allowance is granted by the test itself**, not by hand — a freshly
|
|
520
|
+
deployed Settlement has no approvals from anyone, and requiring a manual
|
|
521
|
+
approve made "run the acceptance test" a two-step nobody had written down. Use a
|
|
522
|
+
throwaway key: the faucet is public, so nothing valuable should sit on it.
|
|
483
523
|
|
|
484
524
|
---
|
|
485
525
|
|
package/dist/http.d.ts
CHANGED
|
@@ -112,7 +112,10 @@ export declare class UpDownHttpClient {
|
|
|
112
112
|
* amend's outcome in the body, so a rejection never reaches `parseJson`'s
|
|
113
113
|
* throw. `bulkFailures()` below exists to make that hard to forget.
|
|
114
114
|
*
|
|
115
|
-
* Results are positional: `results[i]` is the outcome of `amends[i]
|
|
115
|
+
* Results are positional: `results[i]` is the outcome of `amends[i]`, and a
|
|
116
|
+
* successful entry NESTS the replacement — `results[i].order.id`, not
|
|
117
|
+
* `results[i].id`. That differs from the single `amendOrder` above, which
|
|
118
|
+
* spreads the order at the top level; the asymmetry is the server's.
|
|
116
119
|
*
|
|
117
120
|
* Server-side these run SERIALLY, not concurrently — two amends racing on
|
|
118
121
|
* neighbouring price levels would otherwise see each other's half-applied
|
package/dist/http.js
CHANGED
|
@@ -215,7 +215,10 @@ export class UpDownHttpClient {
|
|
|
215
215
|
* amend's outcome in the body, so a rejection never reaches `parseJson`'s
|
|
216
216
|
* throw. `bulkFailures()` below exists to make that hard to forget.
|
|
217
217
|
*
|
|
218
|
-
* Results are positional: `results[i]` is the outcome of `amends[i]
|
|
218
|
+
* Results are positional: `results[i]` is the outcome of `amends[i]`, and a
|
|
219
|
+
* successful entry NESTS the replacement — `results[i].order.id`, not
|
|
220
|
+
* `results[i].id`. That differs from the single `amendOrder` above, which
|
|
221
|
+
* spreads the order at the top level; the asymmetry is the server's.
|
|
219
222
|
*
|
|
220
223
|
* Server-side these run SERIALLY, not concurrently — two amends racing on
|
|
221
224
|
* neighbouring price levels would otherwise see each other's half-applied
|
package/dist/index.d.ts
CHANGED
|
@@ -7,4 +7,4 @@ export { readOnChainHolderShares, reconcileFills, reportedFromPositions, type On
|
|
|
7
7
|
export { UpDownAccountKitSigner, bareErc1271Signer, stripErc6492Wrapper, isErc6492Signature, type UpDownAccountKitConfig, type Eip1193Provider, type GrantSessionResult, type RawTypedDataSigner, } from "./accountKit.js";
|
|
8
8
|
export { buildApproveSettlementTx, buildInstallOrderSessionTx, signWithOrderSession, type RawTransaction, type OrderSessionRecord, } from "./accountKit.js";
|
|
9
9
|
export { PRICE_BPS_SCALE, WIN_MARK_BPS, LOSE_MARK_BPS, DEFAULT_USDT_DECIMALS, atomicToUsdt, markValueAtomic, midBps, markForOption, isResolvedWinner, positionPnl, feesPaidByWallet, portfolioPnl, computePortfolioPnl, type MarkSource, type PositionPnl, type PortfolioPnl, type PositionPnlOptions, } from "./pnl.js";
|
|
10
|
-
export { OrderType, OrderSide, Option, takerPriceBps, type AmendOrderBody, type AmendOrderResult, type ApiConfig, type Balance, type BulkAmendBody, type BulkAmendResults, type BulkFailure, type BulkOrdersBody, type BulkOrdersResults, type CancelOrderBody, type Eip712Domain, type MarketDetail, type MarketListItem, type OptionValue, type OrderBookFull, type OrderBookLevel, type OrderBookSide, type OrderRow, type OrderSideKey, type OrderSideValue, type OrderStatus, type OrderTypeKey, type OrderTypeValue, type OrdersResponse, type PairConfig, type PairSymbol, type PostOrderBody, type Position, type SubmittedOrder, type Stats, type Trade, type Version, } from "./types.js";
|
|
10
|
+
export { OrderType, OrderSide, Option, takerPriceBps, type AmendOrderBody, type AmendOrderResult, type ApiConfig, type Balance, type BulkAmendBody, type BulkAmendResults, type BulkAmendSuccess, type BulkFailure, type BulkOrdersBody, type BulkOrdersResults, type CancelOrderBody, type Eip712Domain, type MarketDetail, type MarketListItem, type OptionValue, type OrderBookFull, type OrderBookLevel, type OrderBookSide, type OrderRow, type OrderSideKey, type OrderSideValue, type OrderStatus, type OrderTypeKey, type OrderTypeValue, type OrdersResponse, type PairConfig, type PairSymbol, type PostOrderBody, type Position, type SubmittedOrder, type Stats, type Trade, type Version, } from "./types.js";
|
package/dist/types.d.ts
CHANGED
|
@@ -315,10 +315,35 @@ export type AmendOrderResult = SubmittedOrder & {
|
|
|
315
315
|
export type BulkAmendBody = {
|
|
316
316
|
amends: AmendOrderBody[];
|
|
317
317
|
};
|
|
318
|
+
/**
|
|
319
|
+
* One successful entry of a bulk amend.
|
|
320
|
+
*
|
|
321
|
+
* NOTE THE SHAPE DIFFERS FROM THE SINGLE ROUTE, and this is the server's
|
|
322
|
+
* asymmetry rather than a choice made here. `POST /orders/amend` SPREADS the
|
|
323
|
+
* replacement order at the top level, so its id is `res.id`.
|
|
324
|
+
* `POST /orders/amend/bulk` NESTS it, so the id is `results[i].order.id` —
|
|
325
|
+
* matching `POST /orders/bulk`, which also nests.
|
|
326
|
+
*
|
|
327
|
+
* Typed wrongly in 0.9.0 (as the single route's flat shape), which made
|
|
328
|
+
* `results[i].id` read `undefined` for every entry. Caught by the live
|
|
329
|
+
* round-trip against dev, not by the stubbed tests — those used a fixture
|
|
330
|
+
* written from the same wrong assumption, so they agreed with themselves.
|
|
331
|
+
*/
|
|
332
|
+
export type BulkAmendSuccess = {
|
|
333
|
+
ok: true;
|
|
334
|
+
/** The replacement, nested — NOT spread, unlike `POST /orders/amend`. */
|
|
335
|
+
order: SubmittedOrder;
|
|
336
|
+
/** Echo of the `cancelOrderId` that was retired. */
|
|
337
|
+
replaced: string;
|
|
338
|
+
/** Whether the replacement kept the original's queue position. */
|
|
339
|
+
priorityKept: boolean;
|
|
340
|
+
/** Atomic USDT already filled on the ORIGINAL before it was retired. */
|
|
341
|
+
filled: string;
|
|
342
|
+
/** Atomic USDT that was still resting and has moved to the replacement. */
|
|
343
|
+
remaining: string;
|
|
344
|
+
};
|
|
318
345
|
export type BulkAmendResults = {
|
|
319
|
-
results: Array<
|
|
320
|
-
ok: true;
|
|
321
|
-
} & AmendOrderResult) | BulkFailure>;
|
|
346
|
+
results: Array<BulkAmendSuccess | BulkFailure>;
|
|
322
347
|
};
|
|
323
348
|
/** `POST /orders/bulk` — orders fan out CONCURRENTLY server-side. */
|
|
324
349
|
export type BulkOrdersBody = {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pulsepairs/sdk",
|
|
3
|
-
"version": "0.9.
|
|
4
|
-
"description": "Standalone SDK for the UpDown (PulsePairs) up/down prediction markets
|
|
3
|
+
"version": "0.9.2",
|
|
4
|
+
"description": "Standalone SDK for the UpDown (PulsePairs) up/down prediction markets — matcher REST/WS client, EIP-712 order signing, trade-math, and Alchemy Account Kit (smart-account) order signing for rain.trade integration.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|