@ostium/builder-sdk 0.2.0 → 0.3.1
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/cli.js +74 -17
- package/dist/index.cjs +74 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -3
- package/dist/index.d.ts +21 -3
- package/dist/index.js +74 -17
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/dist/cli.js
CHANGED
|
@@ -59,6 +59,32 @@ var ERC20_ABI = [
|
|
|
59
59
|
}
|
|
60
60
|
];
|
|
61
61
|
|
|
62
|
+
// src/internal/builder-fee.ts
|
|
63
|
+
var MAX_BUILDER_FEE_BPS = 50;
|
|
64
|
+
var MIN_BUILDER_FEE_BPS_STEP = 0.01;
|
|
65
|
+
var MAX_BUILDER_FEE_CONTRACT = 5e5;
|
|
66
|
+
var BPS_TO_CONTRACT = 1e4;
|
|
67
|
+
function bpsToContractBuilderFee(feeBps) {
|
|
68
|
+
if (feeBps === 0) return 0n;
|
|
69
|
+
return BigInt(Math.round(feeBps * BPS_TO_CONTRACT));
|
|
70
|
+
}
|
|
71
|
+
function validateBuilderFeeBps(feeBps) {
|
|
72
|
+
if (!Number.isFinite(feeBps)) {
|
|
73
|
+
return "builder.feeBps must be a finite number";
|
|
74
|
+
}
|
|
75
|
+
if (feeBps < 0 || feeBps > MAX_BUILDER_FEE_BPS) {
|
|
76
|
+
return `builder.feeBps must be between 0 and ${MAX_BUILDER_FEE_BPS} (0%\u20130.5%)`;
|
|
77
|
+
}
|
|
78
|
+
const centiBps = Math.round(feeBps * 100);
|
|
79
|
+
if (Math.abs(feeBps * 100 - centiBps) > 1e-6) {
|
|
80
|
+
return `builder.feeBps must be a multiple of ${MIN_BUILDER_FEE_BPS_STEP} (0.01 bps)`;
|
|
81
|
+
}
|
|
82
|
+
if (bpsToContractBuilderFee(feeBps) > MAX_BUILDER_FEE_CONTRACT) {
|
|
83
|
+
return "builder.feeBps exceeds on-chain maximum (0.5%)";
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
|
|
62
88
|
// src/internal/decimal.ts
|
|
63
89
|
function parseUsdc(amount) {
|
|
64
90
|
const amountStr = typeof amount === "number" ? amount.toString() : amount;
|
|
@@ -215,7 +241,7 @@ function buildBuilderFee(builder) {
|
|
|
215
241
|
}
|
|
216
242
|
return {
|
|
217
243
|
builder: builder.b,
|
|
218
|
-
builderFee:
|
|
244
|
+
builderFee: bpsToContractBuilderFee(builder.f)
|
|
219
245
|
};
|
|
220
246
|
}
|
|
221
247
|
|
|
@@ -2917,6 +2943,17 @@ query GetTraderOpenTrades($trader: String!, $skip: Int!, $first: Int!) {
|
|
|
2917
2943
|
${PAIR_FULL}
|
|
2918
2944
|
}
|
|
2919
2945
|
}`;
|
|
2946
|
+
var GetAllOpenTradesQuery = `
|
|
2947
|
+
query GetAllOpenTrades($skip: Int!, $first: Int!) {
|
|
2948
|
+
trades(
|
|
2949
|
+
where: { isOpen: true }
|
|
2950
|
+
skip: $skip first: $first
|
|
2951
|
+
orderBy: timestamp orderDirection: desc
|
|
2952
|
+
) {
|
|
2953
|
+
${TRADE_CORE}
|
|
2954
|
+
${PAIR_FULL}
|
|
2955
|
+
}
|
|
2956
|
+
}`;
|
|
2920
2957
|
var ORDER_FIELDS = `
|
|
2921
2958
|
id tradeID limitID trader
|
|
2922
2959
|
pair { id from to group { id name } }
|
|
@@ -2996,9 +3033,9 @@ query GetTraderActiveLimits($trader: String!, $skip: Int!, $first: Int!) {
|
|
|
2996
3033
|
}`;
|
|
2997
3034
|
|
|
2998
3035
|
// src/data/internal/pagination.ts
|
|
2999
|
-
async function paginateAll(fetcher, batchSize = 1e3, max = Infinity) {
|
|
3036
|
+
async function paginateAll(fetcher, batchSize = 1e3, max = Infinity, initialSkip = 0) {
|
|
3000
3037
|
const results = [];
|
|
3001
|
-
let skip =
|
|
3038
|
+
let skip = initialSkip;
|
|
3002
3039
|
while (results.length < max) {
|
|
3003
3040
|
const remaining = max - results.length;
|
|
3004
3041
|
const fetchSize = Math.min(batchSize, remaining);
|
|
@@ -3927,15 +3964,28 @@ var OstiumSubgraphClient = class _OstiumSubgraphClient {
|
|
|
3927
3964
|
* PnL fields are zeroed.
|
|
3928
3965
|
*/
|
|
3929
3966
|
async getOpenPositions(params) {
|
|
3930
|
-
const { user, blockNumber } = params;
|
|
3967
|
+
const { user, blockNumber, limit = Infinity, skip: initialSkip = 0 } = params;
|
|
3968
|
+
const isGlobal = user === "ALL";
|
|
3931
3969
|
const [trades, prices] = await Promise.all([
|
|
3932
|
-
paginateAll(
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3970
|
+
paginateAll(
|
|
3971
|
+
async (skip, first) => {
|
|
3972
|
+
if (isGlobal) {
|
|
3973
|
+
const data2 = await this.query(
|
|
3974
|
+
GetAllOpenTradesQuery,
|
|
3975
|
+
{ skip, first }
|
|
3976
|
+
);
|
|
3977
|
+
return data2.trades;
|
|
3978
|
+
}
|
|
3979
|
+
const data = await this.query(
|
|
3980
|
+
GetTraderOpenTradesQuery,
|
|
3981
|
+
{ trader: user.toLowerCase(), skip, first }
|
|
3982
|
+
);
|
|
3983
|
+
return data.trades;
|
|
3984
|
+
},
|
|
3985
|
+
1e3,
|
|
3986
|
+
limit,
|
|
3987
|
+
initialSkip
|
|
3988
|
+
),
|
|
3939
3989
|
this.fetchLivePricesSafe()
|
|
3940
3990
|
]);
|
|
3941
3991
|
const pairPositions = trades.map((trade) => {
|
|
@@ -4303,11 +4353,11 @@ function validateConfig(config) {
|
|
|
4303
4353
|
"INVALID_CONFIG" /* INVALID_CONFIG */
|
|
4304
4354
|
);
|
|
4305
4355
|
}
|
|
4306
|
-
if (config.builder !== void 0
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
"INVALID_CONFIG" /* INVALID_CONFIG */
|
|
4310
|
-
|
|
4356
|
+
if (config.builder !== void 0) {
|
|
4357
|
+
const feeError = validateBuilderFeeBps(config.builder.feeBps);
|
|
4358
|
+
if (feeError) {
|
|
4359
|
+
throw new OstiumError(feeError, "INVALID_CONFIG" /* INVALID_CONFIG */);
|
|
4360
|
+
}
|
|
4311
4361
|
}
|
|
4312
4362
|
let mode;
|
|
4313
4363
|
try {
|
|
@@ -5103,11 +5153,18 @@ var OstiumClient = class _OstiumClient {
|
|
|
5103
5153
|
/**
|
|
5104
5154
|
* Open positions + margin summary for a user. Defaults to the connected
|
|
5105
5155
|
* trader. Live prices and the current block number are fetched automatically.
|
|
5156
|
+
*
|
|
5157
|
+
* - `user`: pass an address to scope to a single trader, or `'ALL'` to fetch
|
|
5158
|
+
* positions across every trader (no trader filter).
|
|
5159
|
+
* - `limit`: cap the number of positions returned (default: all).
|
|
5160
|
+
* - `skip`: offset into the result set for pagination (default: `0`).
|
|
5106
5161
|
*/
|
|
5107
5162
|
async getOpenPositions(params) {
|
|
5108
5163
|
return this.subgraph.getOpenPositions({
|
|
5109
5164
|
user: params?.user ?? this.getTraderAddress(),
|
|
5110
|
-
blockNumber: params?.blockNumber ?? await this.publicClient.getBlockNumber()
|
|
5165
|
+
blockNumber: params?.blockNumber ?? await this.publicClient.getBlockNumber(),
|
|
5166
|
+
limit: params?.limit,
|
|
5167
|
+
skip: params?.skip
|
|
5111
5168
|
});
|
|
5112
5169
|
}
|
|
5113
5170
|
/**
|
package/dist/index.cjs
CHANGED
|
@@ -60,6 +60,32 @@ var ERC20_ABI = [
|
|
|
60
60
|
}
|
|
61
61
|
];
|
|
62
62
|
|
|
63
|
+
// src/internal/builder-fee.ts
|
|
64
|
+
var MAX_BUILDER_FEE_BPS = 50;
|
|
65
|
+
var MIN_BUILDER_FEE_BPS_STEP = 0.01;
|
|
66
|
+
var MAX_BUILDER_FEE_CONTRACT = 5e5;
|
|
67
|
+
var BPS_TO_CONTRACT = 1e4;
|
|
68
|
+
function bpsToContractBuilderFee(feeBps) {
|
|
69
|
+
if (feeBps === 0) return 0n;
|
|
70
|
+
return BigInt(Math.round(feeBps * BPS_TO_CONTRACT));
|
|
71
|
+
}
|
|
72
|
+
function validateBuilderFeeBps(feeBps) {
|
|
73
|
+
if (!Number.isFinite(feeBps)) {
|
|
74
|
+
return "builder.feeBps must be a finite number";
|
|
75
|
+
}
|
|
76
|
+
if (feeBps < 0 || feeBps > MAX_BUILDER_FEE_BPS) {
|
|
77
|
+
return `builder.feeBps must be between 0 and ${MAX_BUILDER_FEE_BPS} (0%\u20130.5%)`;
|
|
78
|
+
}
|
|
79
|
+
const centiBps = Math.round(feeBps * 100);
|
|
80
|
+
if (Math.abs(feeBps * 100 - centiBps) > 1e-6) {
|
|
81
|
+
return `builder.feeBps must be a multiple of ${MIN_BUILDER_FEE_BPS_STEP} (0.01 bps)`;
|
|
82
|
+
}
|
|
83
|
+
if (bpsToContractBuilderFee(feeBps) > MAX_BUILDER_FEE_CONTRACT) {
|
|
84
|
+
return "builder.feeBps exceeds on-chain maximum (0.5%)";
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
63
89
|
// src/internal/decimal.ts
|
|
64
90
|
function parseUsdc(amount) {
|
|
65
91
|
const amountStr = typeof amount === "number" ? amount.toString() : amount;
|
|
@@ -218,7 +244,7 @@ function buildBuilderFee(builder) {
|
|
|
218
244
|
}
|
|
219
245
|
return {
|
|
220
246
|
builder: builder.b,
|
|
221
|
-
builderFee:
|
|
247
|
+
builderFee: bpsToContractBuilderFee(builder.f)
|
|
222
248
|
};
|
|
223
249
|
}
|
|
224
250
|
|
|
@@ -2944,6 +2970,17 @@ query GetTraderOpenTrades($trader: String!, $skip: Int!, $first: Int!) {
|
|
|
2944
2970
|
${PAIR_FULL}
|
|
2945
2971
|
}
|
|
2946
2972
|
}`;
|
|
2973
|
+
var GetAllOpenTradesQuery = `
|
|
2974
|
+
query GetAllOpenTrades($skip: Int!, $first: Int!) {
|
|
2975
|
+
trades(
|
|
2976
|
+
where: { isOpen: true }
|
|
2977
|
+
skip: $skip first: $first
|
|
2978
|
+
orderBy: timestamp orderDirection: desc
|
|
2979
|
+
) {
|
|
2980
|
+
${TRADE_CORE}
|
|
2981
|
+
${PAIR_FULL}
|
|
2982
|
+
}
|
|
2983
|
+
}`;
|
|
2947
2984
|
var ORDER_FIELDS = `
|
|
2948
2985
|
id tradeID limitID trader
|
|
2949
2986
|
pair { id from to group { id name } }
|
|
@@ -3023,9 +3060,9 @@ query GetTraderActiveLimits($trader: String!, $skip: Int!, $first: Int!) {
|
|
|
3023
3060
|
}`;
|
|
3024
3061
|
|
|
3025
3062
|
// src/data/internal/pagination.ts
|
|
3026
|
-
async function paginateAll(fetcher, batchSize = 1e3, max = Infinity) {
|
|
3063
|
+
async function paginateAll(fetcher, batchSize = 1e3, max = Infinity, initialSkip = 0) {
|
|
3027
3064
|
const results = [];
|
|
3028
|
-
let skip =
|
|
3065
|
+
let skip = initialSkip;
|
|
3029
3066
|
while (results.length < max) {
|
|
3030
3067
|
const remaining = max - results.length;
|
|
3031
3068
|
const fetchSize = Math.min(batchSize, remaining);
|
|
@@ -3954,15 +3991,28 @@ var OstiumSubgraphClient = class _OstiumSubgraphClient {
|
|
|
3954
3991
|
* PnL fields are zeroed.
|
|
3955
3992
|
*/
|
|
3956
3993
|
async getOpenPositions(params) {
|
|
3957
|
-
const { user, blockNumber } = params;
|
|
3994
|
+
const { user, blockNumber, limit = Infinity, skip: initialSkip = 0 } = params;
|
|
3995
|
+
const isGlobal = user === "ALL";
|
|
3958
3996
|
const [trades, prices] = await Promise.all([
|
|
3959
|
-
paginateAll(
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3997
|
+
paginateAll(
|
|
3998
|
+
async (skip, first) => {
|
|
3999
|
+
if (isGlobal) {
|
|
4000
|
+
const data2 = await this.query(
|
|
4001
|
+
GetAllOpenTradesQuery,
|
|
4002
|
+
{ skip, first }
|
|
4003
|
+
);
|
|
4004
|
+
return data2.trades;
|
|
4005
|
+
}
|
|
4006
|
+
const data = await this.query(
|
|
4007
|
+
GetTraderOpenTradesQuery,
|
|
4008
|
+
{ trader: user.toLowerCase(), skip, first }
|
|
4009
|
+
);
|
|
4010
|
+
return data.trades;
|
|
4011
|
+
},
|
|
4012
|
+
1e3,
|
|
4013
|
+
limit,
|
|
4014
|
+
initialSkip
|
|
4015
|
+
),
|
|
3966
4016
|
this.fetchLivePricesSafe()
|
|
3967
4017
|
]);
|
|
3968
4018
|
const pairPositions = trades.map((trade) => {
|
|
@@ -4330,11 +4380,11 @@ function validateConfig(config) {
|
|
|
4330
4380
|
"INVALID_CONFIG" /* INVALID_CONFIG */
|
|
4331
4381
|
);
|
|
4332
4382
|
}
|
|
4333
|
-
if (config.builder !== void 0
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
"INVALID_CONFIG" /* INVALID_CONFIG */
|
|
4337
|
-
|
|
4383
|
+
if (config.builder !== void 0) {
|
|
4384
|
+
const feeError = validateBuilderFeeBps(config.builder.feeBps);
|
|
4385
|
+
if (feeError) {
|
|
4386
|
+
throw new OstiumError(feeError, "INVALID_CONFIG" /* INVALID_CONFIG */);
|
|
4387
|
+
}
|
|
4338
4388
|
}
|
|
4339
4389
|
let mode;
|
|
4340
4390
|
try {
|
|
@@ -5130,11 +5180,18 @@ var OstiumClient = class _OstiumClient {
|
|
|
5130
5180
|
/**
|
|
5131
5181
|
* Open positions + margin summary for a user. Defaults to the connected
|
|
5132
5182
|
* trader. Live prices and the current block number are fetched automatically.
|
|
5183
|
+
*
|
|
5184
|
+
* - `user`: pass an address to scope to a single trader, or `'ALL'` to fetch
|
|
5185
|
+
* positions across every trader (no trader filter).
|
|
5186
|
+
* - `limit`: cap the number of positions returned (default: all).
|
|
5187
|
+
* - `skip`: offset into the result set for pagination (default: `0`).
|
|
5133
5188
|
*/
|
|
5134
5189
|
async getOpenPositions(params) {
|
|
5135
5190
|
return this.subgraph.getOpenPositions({
|
|
5136
5191
|
user: params?.user ?? this.getTraderAddress(),
|
|
5137
|
-
blockNumber: params?.blockNumber ?? await this.publicClient.getBlockNumber()
|
|
5192
|
+
blockNumber: params?.blockNumber ?? await this.publicClient.getBlockNumber(),
|
|
5193
|
+
limit: params?.limit,
|
|
5194
|
+
skip: params?.skip
|
|
5138
5195
|
});
|
|
5139
5196
|
}
|
|
5140
5197
|
/**
|