pmxt-core 2.20.1 → 2.20.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/dist/exchanges/baozi/fetcher.d.ts +40 -0
- package/dist/exchanges/baozi/fetcher.js +155 -0
- package/dist/exchanges/baozi/index.d.ts +2 -0
- package/dist/exchanges/baozi/index.js +60 -131
- package/dist/exchanges/baozi/normalizer.d.ts +14 -0
- package/dist/exchanges/baozi/normalizer.js +208 -0
- package/dist/exchanges/interfaces.d.ts +28 -0
- package/dist/exchanges/interfaces.js +2 -0
- package/dist/exchanges/kalshi/api.d.ts +1 -1
- package/dist/exchanges/kalshi/api.js +1 -1
- package/dist/exchanges/kalshi/fetcher.d.ts +126 -0
- package/dist/exchanges/kalshi/fetcher.js +313 -0
- package/dist/exchanges/kalshi/index.d.ts +6 -6
- package/dist/exchanges/kalshi/index.js +119 -202
- package/dist/exchanges/kalshi/normalizer.d.ts +25 -0
- package/dist/exchanges/kalshi/normalizer.js +294 -0
- package/dist/exchanges/limitless/api.d.ts +1 -1
- package/dist/exchanges/limitless/api.js +1 -1
- package/dist/exchanges/limitless/fetcher.d.ts +81 -0
- package/dist/exchanges/limitless/fetcher.js +238 -0
- package/dist/exchanges/limitless/index.d.ts +6 -9
- package/dist/exchanges/limitless/index.js +81 -79
- package/dist/exchanges/limitless/normalizer.d.ts +14 -0
- package/dist/exchanges/limitless/normalizer.js +117 -0
- package/dist/exchanges/limitless/websocket.d.ts +3 -0
- package/dist/exchanges/limitless/websocket.js +5 -4
- package/dist/exchanges/myriad/api.d.ts +1 -1
- package/dist/exchanges/myriad/api.js +1 -1
- package/dist/exchanges/myriad/fetcher.d.ts +73 -0
- package/dist/exchanges/myriad/fetcher.js +217 -0
- package/dist/exchanges/myriad/index.d.ts +2 -0
- package/dist/exchanges/myriad/index.js +40 -97
- package/dist/exchanges/myriad/normalizer.d.ts +14 -0
- package/dist/exchanges/myriad/normalizer.js +167 -0
- package/dist/exchanges/myriad/websocket.d.ts +3 -1
- package/dist/exchanges/myriad/websocket.js +4 -3
- package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
- package/dist/exchanges/polymarket/api-clob.js +1 -1
- package/dist/exchanges/polymarket/api-data.d.ts +1 -1
- package/dist/exchanges/polymarket/api-data.js +1 -1
- package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
- package/dist/exchanges/polymarket/api-gamma.js +1 -1
- package/dist/exchanges/polymarket/fetcher.d.ts +99 -0
- package/dist/exchanges/polymarket/fetcher.js +335 -0
- package/dist/exchanges/polymarket/index.d.ts +2 -0
- package/dist/exchanges/polymarket/index.js +80 -66
- package/dist/exchanges/polymarket/normalizer.d.ts +18 -0
- package/dist/exchanges/polymarket/normalizer.js +126 -0
- package/dist/exchanges/probable/api.d.ts +1 -1
- package/dist/exchanges/probable/api.js +1 -1
- package/dist/exchanges/probable/fetcher.d.ts +106 -0
- package/dist/exchanges/probable/fetcher.js +357 -0
- package/dist/exchanges/probable/index.d.ts +3 -1
- package/dist/exchanges/probable/index.js +73 -105
- package/dist/exchanges/probable/normalizer.d.ts +14 -0
- package/dist/exchanges/probable/normalizer.js +109 -0
- package/package.json +3 -3
- package/dist/exchanges/baozi/fetchEvents.d.ts +0 -8
- package/dist/exchanges/baozi/fetchEvents.js +0 -39
- package/dist/exchanges/baozi/fetchMarkets.d.ts +0 -5
- package/dist/exchanges/baozi/fetchMarkets.js +0 -160
- package/dist/exchanges/baozi/fetchOHLCV.d.ts +0 -6
- package/dist/exchanges/baozi/fetchOHLCV.js +0 -10
- package/dist/exchanges/baozi/fetchOrderBook.d.ts +0 -12
- package/dist/exchanges/baozi/fetchOrderBook.js +0 -36
- package/dist/exchanges/baozi/fetchTrades.d.ts +0 -6
- package/dist/exchanges/baozi/fetchTrades.js +0 -10
- package/dist/exchanges/kalshi/fetchEvents.d.ts +0 -5
- package/dist/exchanges/kalshi/fetchEvents.js +0 -196
- package/dist/exchanges/kalshi/fetchMarkets.d.ts +0 -6
- package/dist/exchanges/kalshi/fetchMarkets.js +0 -247
- package/dist/exchanges/kalshi/fetchOHLCV.d.ts +0 -3
- package/dist/exchanges/kalshi/fetchOHLCV.js +0 -97
- package/dist/exchanges/kalshi/fetchOrderBook.d.ts +0 -2
- package/dist/exchanges/kalshi/fetchOrderBook.js +0 -60
- package/dist/exchanges/kalshi/fetchTrades.d.ts +0 -3
- package/dist/exchanges/kalshi/fetchTrades.js +0 -33
- package/dist/exchanges/limitless/fetchEvents.d.ts +0 -4
- package/dist/exchanges/limitless/fetchEvents.js +0 -173
- package/dist/exchanges/limitless/fetchMarkets.d.ts +0 -3
- package/dist/exchanges/limitless/fetchMarkets.js +0 -152
- package/dist/exchanges/limitless/fetchOHLCV.d.ts +0 -7
- package/dist/exchanges/limitless/fetchOHLCV.js +0 -49
- package/dist/exchanges/limitless/fetchOrderBook.d.ts +0 -6
- package/dist/exchanges/limitless/fetchOrderBook.js +0 -41
- package/dist/exchanges/limitless/fetchTrades.d.ts +0 -8
- package/dist/exchanges/limitless/fetchTrades.js +0 -27
- package/dist/exchanges/myriad/fetchEvents.d.ts +0 -4
- package/dist/exchanges/myriad/fetchEvents.js +0 -48
- package/dist/exchanges/myriad/fetchMarkets.d.ts +0 -4
- package/dist/exchanges/myriad/fetchMarkets.js +0 -102
- package/dist/exchanges/myriad/fetchOHLCV.d.ts +0 -3
- package/dist/exchanges/myriad/fetchOHLCV.js +0 -83
- package/dist/exchanges/myriad/fetchOrderBook.d.ts +0 -2
- package/dist/exchanges/myriad/fetchOrderBook.js +0 -39
- package/dist/exchanges/polymarket/fetchEvents.d.ts +0 -4
- package/dist/exchanges/polymarket/fetchEvents.js +0 -135
- package/dist/exchanges/polymarket/fetchMarkets.d.ts +0 -4
- package/dist/exchanges/polymarket/fetchMarkets.js +0 -214
- package/dist/exchanges/polymarket/fetchOHLCV.d.ts +0 -7
- package/dist/exchanges/polymarket/fetchOHLCV.js +0 -98
- package/dist/exchanges/polymarket/fetchOrderBook.d.ts +0 -6
- package/dist/exchanges/polymarket/fetchOrderBook.js +0 -33
- package/dist/exchanges/polymarket/fetchTrades.d.ts +0 -9
- package/dist/exchanges/polymarket/fetchTrades.js +0 -43
- package/dist/exchanges/probable/fetchEvents.d.ts +0 -6
- package/dist/exchanges/probable/fetchEvents.js +0 -151
- package/dist/exchanges/probable/fetchMarkets.d.ts +0 -4
- package/dist/exchanges/probable/fetchMarkets.js +0 -239
- package/dist/exchanges/probable/fetchTrades.d.ts +0 -10
- package/dist/exchanges/probable/fetchTrades.js +0 -40
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Connection, PublicKey } from '@solana/web3.js';
|
|
2
|
+
import { MarketFetchParams, EventFetchParams } from '../../BaseExchange';
|
|
3
|
+
import { IExchangeFetcher } from '../interfaces';
|
|
4
|
+
import { BaoziMarket, BaoziRaceMarket, BaoziUserPosition, BaoziRacePosition } from './utils';
|
|
5
|
+
export interface BaoziRawBooleanMarket {
|
|
6
|
+
pubkey: string;
|
|
7
|
+
parsed: BaoziMarket;
|
|
8
|
+
}
|
|
9
|
+
export interface BaoziRawRaceMarket {
|
|
10
|
+
pubkey: string;
|
|
11
|
+
parsed: BaoziRaceMarket;
|
|
12
|
+
}
|
|
13
|
+
export type BaoziRawMarket = BaoziRawBooleanMarket | BaoziRawRaceMarket;
|
|
14
|
+
export interface BaoziRawBooleanPosition {
|
|
15
|
+
pubkey: string;
|
|
16
|
+
parsed: BaoziUserPosition;
|
|
17
|
+
}
|
|
18
|
+
export interface BaoziRawRacePosition {
|
|
19
|
+
pubkey: string;
|
|
20
|
+
parsed: BaoziRacePosition;
|
|
21
|
+
}
|
|
22
|
+
export interface BaoziRawBalance {
|
|
23
|
+
lamports: number;
|
|
24
|
+
}
|
|
25
|
+
export declare function isRawBooleanMarket(raw: BaoziRawMarket): raw is BaoziRawBooleanMarket;
|
|
26
|
+
export declare function isRawRaceMarket(raw: BaoziRawMarket): raw is BaoziRawRaceMarket;
|
|
27
|
+
export declare class BaoziFetcher implements IExchangeFetcher<BaoziRawMarket, BaoziRawMarket> {
|
|
28
|
+
private readonly connection;
|
|
29
|
+
constructor(connection: Connection);
|
|
30
|
+
fetchRawMarkets(_params?: MarketFetchParams): Promise<BaoziRawMarket[]>;
|
|
31
|
+
fetchRawEvents(params: EventFetchParams): Promise<BaoziRawMarket[]>;
|
|
32
|
+
fetchRawSingleMarket(pubkey: string): Promise<BaoziRawMarket | null>;
|
|
33
|
+
fetchRawOrderBook(id: string): Promise<BaoziRawMarket | null>;
|
|
34
|
+
fetchRawUserPositions(walletAddress: PublicKey): Promise<{
|
|
35
|
+
booleanPositions: BaoziRawBooleanPosition[];
|
|
36
|
+
racePositions: BaoziRawRacePosition[];
|
|
37
|
+
}>;
|
|
38
|
+
fetchRawUserBalance(walletAddress: PublicKey): Promise<BaoziRawBalance>;
|
|
39
|
+
fetchRawMarketAccount(pubkey: PublicKey): Promise<BaoziRawMarket | null>;
|
|
40
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaoziFetcher = void 0;
|
|
4
|
+
exports.isRawBooleanMarket = isRawBooleanMarket;
|
|
5
|
+
exports.isRawRaceMarket = isRawRaceMarket;
|
|
6
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
7
|
+
const utils_1 = require("./utils");
|
|
8
|
+
const errors_1 = require("./errors");
|
|
9
|
+
function isRawBooleanMarket(raw) {
|
|
10
|
+
return 'parsed' in raw && 'yesPool' in raw.parsed;
|
|
11
|
+
}
|
|
12
|
+
function isRawRaceMarket(raw) {
|
|
13
|
+
return 'parsed' in raw && 'outcomeCount' in raw.parsed;
|
|
14
|
+
}
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Fetcher
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
const marketsCache = new utils_1.Cache(30_000); // 30s TTL
|
|
19
|
+
class BaoziFetcher {
|
|
20
|
+
connection;
|
|
21
|
+
constructor(connection) {
|
|
22
|
+
this.connection = connection;
|
|
23
|
+
}
|
|
24
|
+
async fetchRawMarkets(_params) {
|
|
25
|
+
try {
|
|
26
|
+
const cached = marketsCache.get();
|
|
27
|
+
if (cached) {
|
|
28
|
+
return cached;
|
|
29
|
+
}
|
|
30
|
+
const [booleanAccounts, raceAccounts] = await Promise.all([
|
|
31
|
+
this.connection.getProgramAccounts(utils_1.PROGRAM_ID, {
|
|
32
|
+
filters: [{ memcmp: { offset: 0, bytes: utils_1.MARKET_DISCRIMINATOR_BS58 } }],
|
|
33
|
+
}),
|
|
34
|
+
this.connection.getProgramAccounts(utils_1.PROGRAM_ID, {
|
|
35
|
+
filters: [{ memcmp: { offset: 0, bytes: utils_1.RACE_MARKET_DISCRIMINATOR_BS58 } }],
|
|
36
|
+
}),
|
|
37
|
+
]);
|
|
38
|
+
const markets = [];
|
|
39
|
+
for (const account of booleanAccounts) {
|
|
40
|
+
try {
|
|
41
|
+
const parsed = (0, utils_1.parseMarket)(account.account.data);
|
|
42
|
+
markets.push({ pubkey: account.pubkey.toString(), parsed });
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Skip malformed accounts
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
for (const account of raceAccounts) {
|
|
49
|
+
try {
|
|
50
|
+
const parsed = (0, utils_1.parseRaceMarket)(account.account.data);
|
|
51
|
+
markets.push({ pubkey: account.pubkey.toString(), parsed });
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Skip malformed accounts
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
marketsCache.set(markets);
|
|
58
|
+
return markets;
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
throw errors_1.baoziErrorMapper.mapError(error);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async fetchRawEvents(params) {
|
|
65
|
+
// Baozi markets are 1:1 with events
|
|
66
|
+
return this.fetchRawMarkets({
|
|
67
|
+
query: params.query,
|
|
68
|
+
limit: params.limit,
|
|
69
|
+
offset: params.offset,
|
|
70
|
+
status: params.status,
|
|
71
|
+
searchIn: params.searchIn,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async fetchRawSingleMarket(pubkey) {
|
|
75
|
+
try {
|
|
76
|
+
const pk = new web3_js_1.PublicKey(pubkey);
|
|
77
|
+
const accountInfo = await this.connection.getAccountInfo(pk);
|
|
78
|
+
if (!accountInfo)
|
|
79
|
+
return null;
|
|
80
|
+
const data = accountInfo.data;
|
|
81
|
+
const discriminator = data.subarray(0, 8);
|
|
82
|
+
if (Buffer.from(discriminator).equals(utils_1.MARKET_DISCRIMINATOR)) {
|
|
83
|
+
const parsed = (0, utils_1.parseMarket)(data);
|
|
84
|
+
return { pubkey, parsed };
|
|
85
|
+
}
|
|
86
|
+
if (Buffer.from(discriminator).equals(utils_1.RACE_MARKET_DISCRIMINATOR)) {
|
|
87
|
+
const parsed = (0, utils_1.parseRaceMarket)(data);
|
|
88
|
+
return { pubkey, parsed };
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async fetchRawOrderBook(id) {
|
|
97
|
+
const marketPubkey = id.replace(/-YES$|-NO$|-\d+$/, '');
|
|
98
|
+
return this.fetchRawSingleMarket(marketPubkey);
|
|
99
|
+
}
|
|
100
|
+
async fetchRawUserPositions(walletAddress) {
|
|
101
|
+
try {
|
|
102
|
+
const [booleanAccounts, raceAccounts] = await Promise.all([
|
|
103
|
+
this.connection.getProgramAccounts(utils_1.PROGRAM_ID, {
|
|
104
|
+
filters: [
|
|
105
|
+
{ memcmp: { offset: 0, bytes: utils_1.USER_POSITION_DISCRIMINATOR_BS58 } },
|
|
106
|
+
{ memcmp: { offset: 8, bytes: walletAddress.toBase58() } },
|
|
107
|
+
],
|
|
108
|
+
}),
|
|
109
|
+
this.connection.getProgramAccounts(utils_1.PROGRAM_ID, {
|
|
110
|
+
filters: [
|
|
111
|
+
{ memcmp: { offset: 0, bytes: utils_1.RACE_POSITION_DISCRIMINATOR_BS58 } },
|
|
112
|
+
{ memcmp: { offset: 8, bytes: walletAddress.toBase58() } },
|
|
113
|
+
],
|
|
114
|
+
}),
|
|
115
|
+
]);
|
|
116
|
+
const booleanPositions = [];
|
|
117
|
+
for (const account of booleanAccounts) {
|
|
118
|
+
try {
|
|
119
|
+
const parsed = (0, utils_1.parseUserPosition)(account.account.data);
|
|
120
|
+
booleanPositions.push({ pubkey: account.pubkey.toString(), parsed });
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// Skip malformed
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const racePositions = [];
|
|
127
|
+
for (const account of raceAccounts) {
|
|
128
|
+
try {
|
|
129
|
+
const parsed = (0, utils_1.parseRacePosition)(account.account.data);
|
|
130
|
+
racePositions.push({ pubkey: account.pubkey.toString(), parsed });
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
// Skip malformed
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return { booleanPositions, racePositions };
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
throw errors_1.baoziErrorMapper.mapError(error);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async fetchRawUserBalance(walletAddress) {
|
|
143
|
+
try {
|
|
144
|
+
const lamports = await this.connection.getBalance(walletAddress);
|
|
145
|
+
return { lamports };
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
throw errors_1.baoziErrorMapper.mapError(error);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
async fetchRawMarketAccount(pubkey) {
|
|
152
|
+
return this.fetchRawSingleMarket(pubkey.toString());
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
exports.BaoziFetcher = BaoziFetcher;
|
|
@@ -30,6 +30,8 @@ export declare class BaoziExchange extends PredictionMarketExchange {
|
|
|
30
30
|
private auth?;
|
|
31
31
|
private connection;
|
|
32
32
|
private ws?;
|
|
33
|
+
private readonly fetcher;
|
|
34
|
+
private readonly normalizer;
|
|
33
35
|
constructor(options?: ExchangeCredentials | BaoziExchangeOptions);
|
|
34
36
|
get name(): string;
|
|
35
37
|
protected fetchMarketsImpl(params?: MarketFetchParams): Promise<UnifiedMarket[]>;
|
|
@@ -4,14 +4,11 @@ exports.BaoziExchange = void 0;
|
|
|
4
4
|
const web3_js_1 = require("@solana/web3.js");
|
|
5
5
|
const BaseExchange_1 = require("../../BaseExchange");
|
|
6
6
|
const errors_1 = require("../../errors");
|
|
7
|
-
const fetchMarkets_1 = require("./fetchMarkets");
|
|
8
|
-
const fetchEvents_1 = require("./fetchEvents");
|
|
9
|
-
const fetchOHLCV_1 = require("./fetchOHLCV");
|
|
10
|
-
const fetchOrderBook_1 = require("./fetchOrderBook");
|
|
11
|
-
const fetchTrades_1 = require("./fetchTrades");
|
|
12
7
|
const auth_1 = require("./auth");
|
|
13
8
|
const websocket_1 = require("./websocket");
|
|
14
9
|
const errors_2 = require("./errors");
|
|
10
|
+
const fetcher_1 = require("./fetcher");
|
|
11
|
+
const normalizer_1 = require("./normalizer");
|
|
15
12
|
const utils_1 = require("./utils");
|
|
16
13
|
class BaoziExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
17
14
|
has = {
|
|
@@ -39,6 +36,8 @@ class BaoziExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
39
36
|
auth;
|
|
40
37
|
connection;
|
|
41
38
|
ws;
|
|
39
|
+
fetcher;
|
|
40
|
+
normalizer;
|
|
42
41
|
constructor(options) {
|
|
43
42
|
let credentials;
|
|
44
43
|
let rpcUrl;
|
|
@@ -59,163 +58,97 @@ class BaoziExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
59
58
|
if (credentials?.privateKey) {
|
|
60
59
|
this.auth = new auth_1.BaoziAuth(credentials);
|
|
61
60
|
}
|
|
61
|
+
this.fetcher = new fetcher_1.BaoziFetcher(this.connection);
|
|
62
|
+
this.normalizer = new normalizer_1.BaoziNormalizer();
|
|
62
63
|
}
|
|
63
64
|
get name() {
|
|
64
65
|
return 'Baozi';
|
|
65
66
|
}
|
|
66
67
|
// -----------------------------------------------------------------------
|
|
67
|
-
// Market Data
|
|
68
|
+
// Market Data (fetcher -> normalizer)
|
|
68
69
|
// -----------------------------------------------------------------------
|
|
69
70
|
async fetchMarketsImpl(params) {
|
|
70
|
-
|
|
71
|
+
const rawMarkets = await this.fetcher.fetchRawMarkets(params);
|
|
72
|
+
return this.normalizer.normalizeMarkets(rawMarkets, params);
|
|
71
73
|
}
|
|
72
74
|
async fetchEventsImpl(params) {
|
|
73
|
-
|
|
75
|
+
const rawMarkets = await this.fetcher.fetchRawEvents(params);
|
|
76
|
+
return this.normalizer.normalizeEvents(rawMarkets, {
|
|
77
|
+
query: params.query,
|
|
78
|
+
limit: params.limit,
|
|
79
|
+
offset: params.offset,
|
|
80
|
+
status: params.status,
|
|
81
|
+
searchIn: params.searchIn,
|
|
82
|
+
});
|
|
74
83
|
}
|
|
75
84
|
async fetchOHLCV() {
|
|
76
|
-
|
|
85
|
+
// Baozi has no historical price/trade API without a custom indexer
|
|
86
|
+
return [];
|
|
77
87
|
}
|
|
78
88
|
async fetchOrderBook(id) {
|
|
79
|
-
|
|
89
|
+
const rawMarket = await this.fetcher.fetchRawOrderBook(id);
|
|
90
|
+
return this.normalizer.normalizeOrderBook(rawMarket, id);
|
|
80
91
|
}
|
|
81
92
|
async fetchTrades() {
|
|
82
|
-
|
|
93
|
+
// Baozi has no trade history API without a custom indexer
|
|
94
|
+
return [];
|
|
83
95
|
}
|
|
84
96
|
// -----------------------------------------------------------------------
|
|
85
|
-
// User Data
|
|
97
|
+
// User Data (fetcher -> normalizer)
|
|
86
98
|
// -----------------------------------------------------------------------
|
|
87
99
|
async fetchBalance() {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const solBalance = lamports / utils_1.LAMPORTS_PER_SOL;
|
|
92
|
-
return [{
|
|
93
|
-
currency: 'SOL',
|
|
94
|
-
total: solBalance,
|
|
95
|
-
available: solBalance,
|
|
96
|
-
locked: 0,
|
|
97
|
-
}];
|
|
98
|
-
}
|
|
99
|
-
catch (error) {
|
|
100
|
-
throw errors_2.baoziErrorMapper.mapError(error);
|
|
101
|
-
}
|
|
100
|
+
const auth = this.ensureAuth();
|
|
101
|
+
const rawBalance = await this.fetcher.fetchRawUserBalance(auth.getPublicKey());
|
|
102
|
+
return this.normalizer.normalizeBalance(rawBalance);
|
|
102
103
|
}
|
|
103
104
|
async fetchPositions() {
|
|
104
105
|
try {
|
|
105
106
|
const auth = this.ensureAuth();
|
|
106
107
|
const userPubkey = auth.getPublicKey();
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
filters: [
|
|
117
|
-
{ memcmp: { offset: 0, bytes: utils_1.RACE_POSITION_DISCRIMINATOR_BS58 } },
|
|
118
|
-
{ memcmp: { offset: 8, bytes: userPubkey.toBase58() } },
|
|
119
|
-
],
|
|
120
|
-
}),
|
|
121
|
-
]);
|
|
122
|
-
const positions = [];
|
|
123
|
-
// Process boolean positions
|
|
124
|
-
for (const account of booleanPositions) {
|
|
125
|
-
try {
|
|
126
|
-
const pos = (0, utils_1.parseUserPosition)(account.account.data);
|
|
127
|
-
if (pos.claimed)
|
|
128
|
-
continue;
|
|
129
|
-
// Try to fetch the market to get current prices
|
|
130
|
-
const marketPda = (0, utils_1.deriveMarketPda)(pos.marketId);
|
|
131
|
-
let currentYesPrice = 0;
|
|
132
|
-
let currentNoPrice = 0;
|
|
133
|
-
let marketTitle = `Market #${pos.marketId}`;
|
|
108
|
+
const { booleanPositions, racePositions } = await this.fetcher.fetchRawUserPositions(userPubkey);
|
|
109
|
+
// Build market lookup for current prices
|
|
110
|
+
const marketLookup = new Map();
|
|
111
|
+
for (const { parsed: pos } of booleanPositions) {
|
|
112
|
+
if (pos.claimed)
|
|
113
|
+
continue;
|
|
114
|
+
const marketPda = (0, utils_1.deriveMarketPda)(pos.marketId);
|
|
115
|
+
const marketPdaStr = marketPda.toString();
|
|
116
|
+
if (!marketLookup.has(marketPdaStr)) {
|
|
134
117
|
try {
|
|
135
|
-
const
|
|
136
|
-
if (
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
currentNoPrice = unified.no?.price ?? 0;
|
|
141
|
-
marketTitle = market.question;
|
|
118
|
+
const rawMarket = await this.fetcher.fetchRawMarketAccount(marketPda);
|
|
119
|
+
if (rawMarket) {
|
|
120
|
+
const unified = this.normalizer.normalizeMarket(rawMarket);
|
|
121
|
+
if (unified)
|
|
122
|
+
marketLookup.set(marketPdaStr, unified);
|
|
142
123
|
}
|
|
143
124
|
}
|
|
144
125
|
catch {
|
|
145
126
|
// Use defaults if market fetch fails
|
|
146
127
|
}
|
|
147
|
-
const yesSOL = Number(pos.yesAmount) / utils_1.LAMPORTS_PER_SOL;
|
|
148
|
-
const noSOL = Number(pos.noAmount) / utils_1.LAMPORTS_PER_SOL;
|
|
149
|
-
if (yesSOL > 0) {
|
|
150
|
-
positions.push({
|
|
151
|
-
marketId: marketPda.toString(),
|
|
152
|
-
outcomeId: `${marketPda.toString()}-YES`,
|
|
153
|
-
outcomeLabel: 'Yes',
|
|
154
|
-
size: yesSOL,
|
|
155
|
-
entryPrice: 0, // Not tracked on-chain for pari-mutuel
|
|
156
|
-
currentPrice: currentYesPrice,
|
|
157
|
-
unrealizedPnL: 0, // Pari-mutuel doesn't have fixed unrealized P&L
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
if (noSOL > 0) {
|
|
161
|
-
positions.push({
|
|
162
|
-
marketId: marketPda.toString(),
|
|
163
|
-
outcomeId: `${marketPda.toString()}-NO`,
|
|
164
|
-
outcomeLabel: 'No',
|
|
165
|
-
size: noSOL,
|
|
166
|
-
entryPrice: 0,
|
|
167
|
-
currentPrice: currentNoPrice,
|
|
168
|
-
unrealizedPnL: 0,
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
catch {
|
|
173
|
-
// Skip malformed position accounts
|
|
174
128
|
}
|
|
175
129
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const racePda = (0, utils_1.deriveRaceMarketPda)(pos.marketId);
|
|
183
|
-
const racePdaStr = racePda.toString();
|
|
184
|
-
// Try to fetch the race market to get current prices and labels
|
|
185
|
-
let outcomePrices = [];
|
|
186
|
-
let outcomeLabels = [];
|
|
130
|
+
for (const { parsed: pos } of racePositions) {
|
|
131
|
+
if (pos.claimed)
|
|
132
|
+
continue;
|
|
133
|
+
const racePda = (0, utils_1.deriveRaceMarketPda)(pos.marketId);
|
|
134
|
+
const racePdaStr = racePda.toString();
|
|
135
|
+
if (!marketLookup.has(racePdaStr)) {
|
|
187
136
|
try {
|
|
188
|
-
const
|
|
189
|
-
if (
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
outcomeLabels = unified.outcomes.map(o => o.label);
|
|
137
|
+
const rawMarket = await this.fetcher.fetchRawMarketAccount(racePda);
|
|
138
|
+
if (rawMarket) {
|
|
139
|
+
const unified = this.normalizer.normalizeMarket(rawMarket);
|
|
140
|
+
if (unified)
|
|
141
|
+
marketLookup.set(racePdaStr, unified);
|
|
194
142
|
}
|
|
195
143
|
}
|
|
196
144
|
catch {
|
|
197
145
|
// Use defaults if market fetch fails
|
|
198
146
|
}
|
|
199
|
-
for (let i = 0; i < pos.bets.length; i++) {
|
|
200
|
-
const betSOL = Number(pos.bets[i]) / utils_1.LAMPORTS_PER_SOL;
|
|
201
|
-
if (betSOL <= 0)
|
|
202
|
-
continue;
|
|
203
|
-
positions.push({
|
|
204
|
-
marketId: racePdaStr,
|
|
205
|
-
outcomeId: `${racePdaStr}-${i}`,
|
|
206
|
-
outcomeLabel: outcomeLabels[i] || `Outcome ${i}`,
|
|
207
|
-
size: betSOL,
|
|
208
|
-
entryPrice: 0,
|
|
209
|
-
currentPrice: outcomePrices[i] ?? 0,
|
|
210
|
-
unrealizedPnL: 0,
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
catch {
|
|
215
|
-
// Skip malformed position accounts
|
|
216
147
|
}
|
|
217
148
|
}
|
|
218
|
-
|
|
149
|
+
const boolPos = this.normalizer.normalizeBooleanPositions(booleanPositions, marketLookup);
|
|
150
|
+
const racePos = this.normalizer.normalizeRacePositions(racePositions, marketLookup);
|
|
151
|
+
return [...boolPos, ...racePos];
|
|
219
152
|
}
|
|
220
153
|
catch (error) {
|
|
221
154
|
throw errors_2.baoziErrorMapper.mapError(error);
|
|
@@ -257,7 +190,7 @@ class BaoziExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
257
190
|
{ pubkey: configPda, isSigner: false, isWritable: false },
|
|
258
191
|
{ pubkey: marketPubkey, isSigner: false, isWritable: true },
|
|
259
192
|
{ pubkey: positionPda, isSigner: false, isWritable: true },
|
|
260
|
-
{ pubkey: utils_1.PROGRAM_ID, isSigner: false, isWritable: false },
|
|
193
|
+
{ pubkey: utils_1.PROGRAM_ID, isSigner: false, isWritable: false },
|
|
261
194
|
{ pubkey: keypair.publicKey, isSigner: true, isWritable: true },
|
|
262
195
|
{ pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
|
|
263
196
|
],
|
|
@@ -293,7 +226,7 @@ class BaoziExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
293
226
|
{ pubkey: configPda, isSigner: false, isWritable: false },
|
|
294
227
|
{ pubkey: marketPubkey, isSigner: false, isWritable: true },
|
|
295
228
|
{ pubkey: racePositionPda, isSigner: false, isWritable: true },
|
|
296
|
-
{ pubkey: utils_1.PROGRAM_ID, isSigner: false, isWritable: false },
|
|
229
|
+
{ pubkey: utils_1.PROGRAM_ID, isSigner: false, isWritable: false },
|
|
297
230
|
{ pubkey: keypair.publicKey, isSigner: true, isWritable: true },
|
|
298
231
|
{ pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
|
|
299
232
|
],
|
|
@@ -313,10 +246,10 @@ class BaoziExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
313
246
|
marketId: params.marketId,
|
|
314
247
|
outcomeId: params.outcomeId,
|
|
315
248
|
side: 'buy',
|
|
316
|
-
type: 'market',
|
|
249
|
+
type: 'market',
|
|
317
250
|
price: undefined,
|
|
318
251
|
amount: params.amount,
|
|
319
|
-
status: 'filled',
|
|
252
|
+
status: 'filled',
|
|
320
253
|
filled: params.amount,
|
|
321
254
|
remaining: 0,
|
|
322
255
|
timestamp: Date.now(),
|
|
@@ -330,8 +263,6 @@ class BaoziExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
330
263
|
throw new errors_1.InvalidOrder('Pari-mutuel bets are irrevocable and cannot be cancelled', 'Baozi');
|
|
331
264
|
}
|
|
332
265
|
async fetchOrder(orderId) {
|
|
333
|
-
// In pari-mutuel, there are no pending orders. The "order" is the tx signature.
|
|
334
|
-
// We can verify the transaction was confirmed and extract market info.
|
|
335
266
|
try {
|
|
336
267
|
const tx = await this.connection.getTransaction(orderId, {
|
|
337
268
|
maxSupportedTransactionVersion: 0,
|
|
@@ -339,7 +270,6 @@ class BaoziExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
339
270
|
if (!tx) {
|
|
340
271
|
throw new Error(`Transaction not found: ${orderId}`);
|
|
341
272
|
}
|
|
342
|
-
// Try to extract market/outcome from the transaction instruction
|
|
343
273
|
let marketId = '';
|
|
344
274
|
let outcomeId = '';
|
|
345
275
|
let amount = 0;
|
|
@@ -357,7 +287,6 @@ class BaoziExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
357
287
|
const isRaceBet = discriminator.equals(utils_1.BET_ON_RACE_OUTCOME_SOL_DISCRIMINATOR);
|
|
358
288
|
if (!isBooleanBet && !isRaceBet)
|
|
359
289
|
continue;
|
|
360
|
-
// Account keys[1] is the market PDA for both instruction types
|
|
361
290
|
const marketKeyIndex = ix.accountKeyIndexes[1];
|
|
362
291
|
const marketKey = message.staticAccountKeys[marketKeyIndex];
|
|
363
292
|
marketId = marketKey.toString();
|
|
@@ -392,7 +321,7 @@ class BaoziExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
392
321
|
}
|
|
393
322
|
}
|
|
394
323
|
async fetchOpenOrders() {
|
|
395
|
-
// Pari-mutuel bets execute instantly
|
|
324
|
+
// Pari-mutuel bets execute instantly -- there are never open orders
|
|
396
325
|
return [];
|
|
397
326
|
}
|
|
398
327
|
// -----------------------------------------------------------------------
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { MarketFetchParams } from '../../BaseExchange';
|
|
2
|
+
import { UnifiedMarket, UnifiedEvent, OrderBook, Position, Balance } from '../../types';
|
|
3
|
+
import { IExchangeNormalizer } from '../interfaces';
|
|
4
|
+
import { BaoziRawMarket, BaoziRawBooleanPosition, BaoziRawRacePosition, BaoziRawBalance } from './fetcher';
|
|
5
|
+
export declare class BaoziNormalizer implements IExchangeNormalizer<BaoziRawMarket, BaoziRawMarket> {
|
|
6
|
+
normalizeMarket(raw: BaoziRawMarket): UnifiedMarket | null;
|
|
7
|
+
normalizeEvent(raw: BaoziRawMarket): UnifiedEvent | null;
|
|
8
|
+
normalizeMarkets(rawMarkets: BaoziRawMarket[], params?: MarketFetchParams): UnifiedMarket[];
|
|
9
|
+
normalizeEvents(rawMarkets: BaoziRawMarket[], params?: MarketFetchParams): UnifiedEvent[];
|
|
10
|
+
normalizeOrderBook(raw: BaoziRawMarket | null, outcomeId: string): OrderBook;
|
|
11
|
+
normalizeBooleanPositions(positions: BaoziRawBooleanPosition[], marketLookup: Map<string, UnifiedMarket>): Position[];
|
|
12
|
+
normalizeRacePositions(positions: BaoziRawRacePosition[], marketLookup: Map<string, UnifiedMarket>): Position[];
|
|
13
|
+
normalizeBalance(raw: BaoziRawBalance): Balance[];
|
|
14
|
+
}
|