@0xmonaco/core 0.8.11 → 0.8.14
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/api/margin-accounts/api.d.ts +8 -3
- package/dist/api/margin-accounts/api.js +51 -7
- package/dist/api/market/api.d.ts +2 -2
- package/dist/api/market/api.js +5 -3
- package/dist/api/perp/routes.d.ts +14 -2
- package/dist/api/perp/routes.js +8 -2
- package/dist/api/positions/api.d.ts +2 -1
- package/dist/api/positions/api.js +13 -1
- package/dist/api/trading/api.d.ts +4 -4
- package/dist/api/trading/api.js +6 -6
- package/dist/api/vault/api.d.ts +71 -28
- package/dist/api/vault/api.js +138 -38
- package/dist/api/withdrawals/api.d.ts +6 -4
- package/dist/api/withdrawals/api.js +7 -4
- package/dist/coverage.d.ts +8 -2
- package/dist/coverage.js +8 -2
- package/dist/sdk.d.ts +2 -2
- package/package.json +3 -3
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import type { GetAvailableCollateralParams, GetAvailableCollateralResponse, GetMarginAccountMovementsParams, GetMarginAccountMovementsResponse, GetMarginAccountSummaryParams, ListMarginAccountsParams, ListMarginAccountsResponse, MarginAccountSummary, MarginAccountsAPI,
|
|
1
|
+
import type { GetAvailableCollateralParams, GetAvailableCollateralResponse, GetMarginAccountMovementsParams, GetMarginAccountMovementsResponse, GetMarginAccountSummaryParams, ListMarginAccountsParams, ListMarginAccountsResponse, MarginAccountSummary, MarginAccountsAPI, SimulateOrderRiskRequest, SimulateOrderRiskResponse, SimulateRiskBucketOrderRiskRequest, TransferCollateralFromParentMarginAccountRequest, TransferCollateralRequest, TransferCollateralResponse, TransferCollateralToParentMarginAccountRequest, TransferCollateralToRiskBucketRequest } from "@0xmonaco/types";
|
|
2
2
|
import { BaseAPI } from "../base";
|
|
3
3
|
export declare class MarginAccountsAPIImpl extends BaseAPI implements MarginAccountsAPI {
|
|
4
4
|
listMarginAccounts(params?: ListMarginAccountsParams): Promise<ListMarginAccountsResponse>;
|
|
5
5
|
getMarginAccountSummary(marginAccountId: string, params?: GetMarginAccountSummaryParams): Promise<MarginAccountSummary>;
|
|
6
|
+
getParentMarginAccountSummary(params?: GetMarginAccountSummaryParams): Promise<MarginAccountSummary>;
|
|
6
7
|
getAvailableCollateral(params?: GetAvailableCollateralParams): Promise<GetAvailableCollateralResponse>;
|
|
7
8
|
transferCollateralToMarginAccount(marginAccountId: string, request: TransferCollateralRequest): Promise<TransferCollateralResponse>;
|
|
8
|
-
|
|
9
|
+
transferCollateralToParentMarginAccount(request: TransferCollateralToParentMarginAccountRequest): Promise<TransferCollateralResponse>;
|
|
10
|
+
transferCollateralToRiskBucket(request: TransferCollateralToRiskBucketRequest): Promise<TransferCollateralResponse>;
|
|
9
11
|
transferCollateralFromMarginAccount(marginAccountId: string, request: TransferCollateralRequest): Promise<TransferCollateralResponse>;
|
|
12
|
+
transferCollateralFromParentMarginAccount(request: TransferCollateralFromParentMarginAccountRequest): Promise<TransferCollateralResponse>;
|
|
10
13
|
getMarginAccountMovements(marginAccountId: string, params?: GetMarginAccountMovementsParams): Promise<GetMarginAccountMovementsResponse>;
|
|
14
|
+
getParentMarginAccountMovements(params?: GetMarginAccountMovementsParams): Promise<GetMarginAccountMovementsResponse>;
|
|
11
15
|
simulateOrderRisk(marginAccountId: string, request: SimulateOrderRiskRequest): Promise<SimulateOrderRiskResponse>;
|
|
12
|
-
|
|
16
|
+
simulateParentMarginOrderRisk(request: SimulateOrderRiskRequest): Promise<SimulateOrderRiskResponse>;
|
|
17
|
+
simulateRiskBucketOrderRisk(request: SimulateRiskBucketOrderRiskRequest): Promise<SimulateOrderRiskResponse>;
|
|
13
18
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GetAvailableCollateralSchema, GetMarginAccountMovementsSchema, GetMarginAccountSummarySchema,
|
|
1
|
+
import { GetAvailableCollateralSchema, GetMarginAccountMovementsSchema, GetMarginAccountSummarySchema, GetParentMarginAccountMovementsSchema, GetParentMarginAccountSummarySchema, ListMarginAccountsSchema, SimulateOrderRiskSchema, SimulateParentMarginOrderRiskSchema, SimulateRiskBucketOrderRiskSchema, TransferCollateralFromParentMarginAccountSchema, TransferCollateralSchema, TransferCollateralToParentMarginAccountSchema, TransferCollateralToRiskBucketSchema, validate, } from "@0xmonaco/types";
|
|
2
2
|
import { BaseAPI } from "../base";
|
|
3
3
|
import { perpRoutes } from "../perp";
|
|
4
4
|
export class MarginAccountsAPIImpl extends BaseAPI {
|
|
@@ -19,6 +19,10 @@ export class MarginAccountsAPIImpl extends BaseAPI {
|
|
|
19
19
|
validate(GetMarginAccountSummarySchema, { marginAccountId, ...params });
|
|
20
20
|
return await this.makeAuthenticatedRequest(perpRoutes.marginAccounts.summary(marginAccountId, { trading_pair_id: params?.tradingPairId }));
|
|
21
21
|
}
|
|
22
|
+
async getParentMarginAccountSummary(params) {
|
|
23
|
+
validate(GetParentMarginAccountSummarySchema, params);
|
|
24
|
+
return await this.makeAuthenticatedRequest(perpRoutes.marginAccounts.parentSummary({ trading_pair_id: params?.tradingPairId }));
|
|
25
|
+
}
|
|
22
26
|
async getAvailableCollateral(params) {
|
|
23
27
|
validate(GetAvailableCollateralSchema, params);
|
|
24
28
|
return await this.makeAuthenticatedRequest(perpRoutes.marginAccounts.availableCollateral(params));
|
|
@@ -35,9 +39,19 @@ export class MarginAccountsAPIImpl extends BaseAPI {
|
|
|
35
39
|
}),
|
|
36
40
|
});
|
|
37
41
|
}
|
|
38
|
-
async
|
|
39
|
-
validate(
|
|
40
|
-
return await this.makeAuthenticatedRequest(perpRoutes.marginAccounts.
|
|
42
|
+
async transferCollateralToParentMarginAccount(request) {
|
|
43
|
+
validate(TransferCollateralToParentMarginAccountSchema, { request });
|
|
44
|
+
return await this.makeAuthenticatedRequest(perpRoutes.marginAccounts.transferInParent(), {
|
|
45
|
+
method: "POST",
|
|
46
|
+
body: JSON.stringify({
|
|
47
|
+
asset: request.asset,
|
|
48
|
+
amount: request.amount,
|
|
49
|
+
}),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
async transferCollateralToRiskBucket(request) {
|
|
53
|
+
validate(TransferCollateralToRiskBucketSchema, { request });
|
|
54
|
+
return await this.makeAuthenticatedRequest(perpRoutes.marginAccounts.transferInRiskBucket(), {
|
|
41
55
|
method: "POST",
|
|
42
56
|
body: JSON.stringify({
|
|
43
57
|
asset: request.asset,
|
|
@@ -59,10 +73,24 @@ export class MarginAccountsAPIImpl extends BaseAPI {
|
|
|
59
73
|
}),
|
|
60
74
|
});
|
|
61
75
|
}
|
|
76
|
+
async transferCollateralFromParentMarginAccount(request) {
|
|
77
|
+
validate(TransferCollateralFromParentMarginAccountSchema, { request });
|
|
78
|
+
return await this.makeAuthenticatedRequest(perpRoutes.marginAccounts.transferOutParent(), {
|
|
79
|
+
method: "POST",
|
|
80
|
+
body: JSON.stringify({
|
|
81
|
+
asset: request.asset,
|
|
82
|
+
amount: request.amount,
|
|
83
|
+
}),
|
|
84
|
+
});
|
|
85
|
+
}
|
|
62
86
|
async getMarginAccountMovements(marginAccountId, params) {
|
|
63
87
|
validate(GetMarginAccountMovementsSchema, { marginAccountId, ...params });
|
|
64
88
|
return await this.makeAuthenticatedRequest(perpRoutes.marginAccounts.movements(marginAccountId, params));
|
|
65
89
|
}
|
|
90
|
+
async getParentMarginAccountMovements(params) {
|
|
91
|
+
validate(GetParentMarginAccountMovementsSchema, params);
|
|
92
|
+
return await this.makeAuthenticatedRequest(perpRoutes.marginAccounts.parentMovements(params));
|
|
93
|
+
}
|
|
66
94
|
async simulateOrderRisk(marginAccountId, request) {
|
|
67
95
|
validate(SimulateOrderRiskSchema, { marginAccountId, request });
|
|
68
96
|
return await this.makeAuthenticatedRequest(perpRoutes.marginAccounts.simulateOrderRisk(marginAccountId), {
|
|
@@ -79,9 +107,25 @@ export class MarginAccountsAPIImpl extends BaseAPI {
|
|
|
79
107
|
}),
|
|
80
108
|
});
|
|
81
109
|
}
|
|
82
|
-
async
|
|
83
|
-
validate(
|
|
84
|
-
return await this.makeAuthenticatedRequest(perpRoutes.marginAccounts.
|
|
110
|
+
async simulateParentMarginOrderRisk(request) {
|
|
111
|
+
validate(SimulateParentMarginOrderRiskSchema, { request });
|
|
112
|
+
return await this.makeAuthenticatedRequest(perpRoutes.marginAccounts.simulateParentMarginOrderRisk(), {
|
|
113
|
+
method: "POST",
|
|
114
|
+
body: JSON.stringify({
|
|
115
|
+
trading_pair_id: request.tradingPairId,
|
|
116
|
+
side: request.side,
|
|
117
|
+
position_side: request.positionSide,
|
|
118
|
+
order_type: request.orderType,
|
|
119
|
+
price: request.price,
|
|
120
|
+
quantity: request.quantity,
|
|
121
|
+
leverage: request.leverage,
|
|
122
|
+
reduce_only: request.reduceOnly,
|
|
123
|
+
}),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
async simulateRiskBucketOrderRisk(request) {
|
|
127
|
+
validate(SimulateRiskBucketOrderRiskSchema, { request });
|
|
128
|
+
return await this.makeAuthenticatedRequest(perpRoutes.marginAccounts.simulateRiskBucketOrderRisk(), {
|
|
85
129
|
method: "POST",
|
|
86
130
|
body: JSON.stringify({
|
|
87
131
|
trading_pair_id: request.tradingPairId,
|
package/dist/api/market/api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Candlestick, FundingState, GetCandlesticksParams, GetScreenerParams, GetScreenerResponse, GetTradingPairsParams, GetTradingPairsResponse, IndexPrice, Interval, ListFundingHistoryParams, ListFundingHistoryResponse, MarketAPI, MarketMetadata, MarketStats, MarkPrice, OpenInterest, PerpMarketConfig, PerpMarketSummary, TradingPair } from "@0xmonaco/types";
|
|
1
|
+
import type { Candlestick, FundingState, GetCandlesticksParams, GetScreenerParams, GetScreenerResponse, GetTradingPairsParams, GetTradingPairsResponse, IndexPrice, Interval, ListFundingHistoryParams, ListFundingHistoryResponse, MarketAPI, MarketMetadata, MarketStats, MarkPrice, OpenInterest, PerpMarketConfig, PerpMarketSummary, TradingMode, TradingPair } from "@0xmonaco/types";
|
|
2
2
|
import { BaseAPI } from "../base";
|
|
3
3
|
/**
|
|
4
4
|
* Market API Implementation
|
|
@@ -8,7 +8,7 @@ import { BaseAPI } from "../base";
|
|
|
8
8
|
export declare class MarketAPIImpl extends BaseAPI implements MarketAPI {
|
|
9
9
|
getPaginatedTradingPairs(params?: GetTradingPairsParams): Promise<GetTradingPairsResponse>;
|
|
10
10
|
getTradingPair(tradingPairId: string): Promise<TradingPair>;
|
|
11
|
-
getTradingPairBySymbol(symbol: string): Promise<TradingPair | undefined>;
|
|
11
|
+
getTradingPairBySymbol(symbol: string, marketType?: TradingMode): Promise<TradingPair | undefined>;
|
|
12
12
|
getCandlesticks(tradingPairId: string, interval: Interval, params?: GetCandlesticksParams): Promise<Candlestick[]>;
|
|
13
13
|
getMarketMetadata(tradingPairId: string): Promise<MarketMetadata>;
|
|
14
14
|
getPerpMarketConfig(tradingPairId: string): Promise<PerpMarketConfig>;
|
package/dist/api/market/api.js
CHANGED
|
@@ -39,9 +39,11 @@ export class MarketAPIImpl extends BaseAPI {
|
|
|
39
39
|
const response = await this.makePublicRequest(perpRoutes.market.getTradingPair(tradingPairId));
|
|
40
40
|
return response.trading_pair;
|
|
41
41
|
}
|
|
42
|
-
async getTradingPairBySymbol(symbol) {
|
|
43
|
-
// Backend endpoint expects UUID, not symbol, so we fetch all pairs and filter
|
|
44
|
-
|
|
42
|
+
async getTradingPairBySymbol(symbol, marketType) {
|
|
43
|
+
// Backend endpoint expects UUID, not symbol, so we fetch all pairs and filter.
|
|
44
|
+
// An optional market_type narrows the listing so a symbol present in both
|
|
45
|
+
// SPOT and MARGIN resolves unambiguously instead of returning the first match.
|
|
46
|
+
const response = await this.getPaginatedTradingPairs({ page_size: 100, market_type: marketType });
|
|
45
47
|
return response.trading_pairs.find((pair) => pair.symbol === symbol);
|
|
46
48
|
}
|
|
47
49
|
async getCandlesticks(tradingPairId, interval, params) {
|
|
@@ -151,6 +151,7 @@ export declare const perpRoutes: {
|
|
|
151
151
|
}) => string;
|
|
152
152
|
readonly get: (positionId: string) => string;
|
|
153
153
|
readonly close: (positionId: string) => string;
|
|
154
|
+
readonly batchCloseAll: () => string;
|
|
154
155
|
readonly risk: (positionId: string) => string;
|
|
155
156
|
readonly addMargin: (positionId: string) => string;
|
|
156
157
|
readonly reduceMargin: (positionId: string) => string;
|
|
@@ -170,6 +171,9 @@ export declare const perpRoutes: {
|
|
|
170
171
|
state?: string;
|
|
171
172
|
trading_pair_id?: string;
|
|
172
173
|
}) => string;
|
|
174
|
+
readonly parentSummary: (params?: {
|
|
175
|
+
trading_pair_id?: string;
|
|
176
|
+
}) => string;
|
|
173
177
|
readonly summary: (marginAccountId: string, params?: {
|
|
174
178
|
trading_pair_id?: string;
|
|
175
179
|
}) => string;
|
|
@@ -177,15 +181,23 @@ export declare const perpRoutes: {
|
|
|
177
181
|
asset?: string;
|
|
178
182
|
}) => string;
|
|
179
183
|
readonly transferIn: (marginAccountId: string) => string;
|
|
180
|
-
readonly
|
|
184
|
+
readonly transferInParent: () => string;
|
|
185
|
+
readonly transferInRiskBucket: () => string;
|
|
181
186
|
readonly transferOut: (marginAccountId: string) => string;
|
|
187
|
+
readonly transferOutParent: () => string;
|
|
182
188
|
readonly movements: (marginAccountId: string, params?: {
|
|
183
189
|
movement_type?: string;
|
|
184
190
|
page?: number;
|
|
185
191
|
page_size?: number;
|
|
186
192
|
}) => string;
|
|
193
|
+
readonly parentMovements: (params?: {
|
|
194
|
+
movement_type?: string;
|
|
195
|
+
page?: number;
|
|
196
|
+
page_size?: number;
|
|
197
|
+
}) => string;
|
|
198
|
+
readonly simulateParentMarginOrderRisk: () => string;
|
|
187
199
|
readonly simulateOrderRisk: (marginAccountId: string) => string;
|
|
188
|
-
readonly
|
|
200
|
+
readonly simulateRiskBucketOrderRisk: () => string;
|
|
189
201
|
};
|
|
190
202
|
readonly streams: {
|
|
191
203
|
readonly orderbook: () => string;
|
package/dist/api/perp/routes.js
CHANGED
|
@@ -85,6 +85,7 @@ export const perpRoutes = {
|
|
|
85
85
|
list: (params) => withQuery(`${API_V1}/positions`, params),
|
|
86
86
|
get: (positionId) => `${API_V1}/positions/${encodeSegment(positionId)}`,
|
|
87
87
|
close: (positionId) => `${API_V1}/positions/${encodeSegment(positionId)}/close`,
|
|
88
|
+
batchCloseAll: () => `${API_V1}/positions/batch-close-all`,
|
|
88
89
|
risk: (positionId) => `${API_V1}/positions/${encodeSegment(positionId)}/risk`,
|
|
89
90
|
addMargin: (positionId) => `${API_V1}/positions/${encodeSegment(positionId)}/margin/add`,
|
|
90
91
|
reduceMargin: (positionId) => `${API_V1}/positions/${encodeSegment(positionId)}/margin/reduce`,
|
|
@@ -93,14 +94,19 @@ export const perpRoutes = {
|
|
|
93
94
|
},
|
|
94
95
|
marginAccounts: {
|
|
95
96
|
list: (params) => withQuery(`${API_V1}/margin/accounts`, params),
|
|
97
|
+
parentSummary: (params) => withQuery(`${API_V1}/margin/parent-margin-account`, params),
|
|
96
98
|
summary: (marginAccountId, params) => withQuery(`${API_V1}/margin/accounts/${encodeSegment(marginAccountId)}`, params),
|
|
97
99
|
availableCollateral: (params) => withQuery(`${API_V1}/margin/collateral/available`, params),
|
|
98
100
|
transferIn: (marginAccountId) => `${API_V1}/margin/accounts/${encodeSegment(marginAccountId)}/collateral/transfer-in`,
|
|
99
|
-
|
|
101
|
+
transferInParent: () => `${API_V1}/margin/parent-margin-account/collateral/transfer-in`,
|
|
102
|
+
transferInRiskBucket: () => `${API_V1}/margin/risk-buckets/collateral/transfer-in`,
|
|
100
103
|
transferOut: (marginAccountId) => `${API_V1}/margin/accounts/${encodeSegment(marginAccountId)}/collateral/transfer-out`,
|
|
104
|
+
transferOutParent: () => `${API_V1}/margin/parent-margin-account/collateral/transfer-out`,
|
|
101
105
|
movements: (marginAccountId, params) => withQuery(`${API_V1}/margin/accounts/${encodeSegment(marginAccountId)}/movements`, params),
|
|
106
|
+
parentMovements: (params) => withQuery(`${API_V1}/margin/parent-margin-account/movements`, params),
|
|
107
|
+
simulateParentMarginOrderRisk: () => `${API_V1}/margin/parent-margin-account/simulate-order-risk`,
|
|
102
108
|
simulateOrderRisk: (marginAccountId) => `${API_V1}/margin/accounts/${encodeSegment(marginAccountId)}/simulate-order-risk`,
|
|
103
|
-
|
|
109
|
+
simulateRiskBucketOrderRisk: () => `${API_V1}/margin/risk-buckets/simulate-order-risk`,
|
|
104
110
|
},
|
|
105
111
|
streams: {
|
|
106
112
|
orderbook: () => `${API_V1}/streaming/orderbook`,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { AddPositionMarginRequest, AttachPositionTpSlRequest, AttachPositionTpSlResponse, ClosePositionRequest, ClosePositionResponse, GetPositionResponse, ListPositionHistoryParams, ListPositionHistoryResponse, ListPositionsParams, ListPositionsResponse, PositionMarginResponse, PositionRisk, PositionsAPI, ReducePositionMarginRequest } from "@0xmonaco/types";
|
|
1
|
+
import type { AddPositionMarginRequest, AttachPositionTpSlRequest, AttachPositionTpSlResponse, BatchCloseAllRequest, BatchCloseAllResponse, ClosePositionRequest, ClosePositionResponse, GetPositionResponse, ListPositionHistoryParams, ListPositionHistoryResponse, ListPositionsParams, ListPositionsResponse, PositionMarginResponse, PositionRisk, PositionsAPI, ReducePositionMarginRequest } from "@0xmonaco/types";
|
|
2
2
|
import { BaseAPI } from "../base";
|
|
3
3
|
export declare class PositionsAPIImpl extends BaseAPI implements PositionsAPI {
|
|
4
4
|
listPositions(params?: ListPositionsParams): Promise<ListPositionsResponse>;
|
|
5
5
|
getPosition(positionId: string): Promise<GetPositionResponse>;
|
|
6
6
|
closePosition(positionId: string, request: ClosePositionRequest): Promise<ClosePositionResponse>;
|
|
7
|
+
batchCloseAllPositions(request?: BatchCloseAllRequest): Promise<BatchCloseAllResponse>;
|
|
7
8
|
getPositionRisk(positionId: string): Promise<PositionRisk>;
|
|
8
9
|
addPositionMargin(positionId: string, request: AddPositionMarginRequest): Promise<PositionMarginResponse>;
|
|
9
10
|
reducePositionMargin(positionId: string, request: ReducePositionMarginRequest): Promise<PositionMarginResponse>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AddPositionMarginSchema, AttachPositionTpSlSchema, ClosePositionSchema, GetPositionRiskSchema, GetPositionSchema, ListPositionHistorySchema, ListPositionsSchema, ReducePositionMarginSchema, validate, } from "@0xmonaco/types";
|
|
1
|
+
import { AddPositionMarginSchema, AttachPositionTpSlSchema, BatchCloseAllSchema, ClosePositionSchema, GetPositionRiskSchema, GetPositionSchema, ListPositionHistorySchema, ListPositionsSchema, ReducePositionMarginSchema, validate, } from "@0xmonaco/types";
|
|
2
2
|
import { BaseAPI } from "../base";
|
|
3
3
|
import { perpRoutes } from "../perp";
|
|
4
4
|
export class PositionsAPIImpl extends BaseAPI {
|
|
@@ -24,6 +24,18 @@ export class PositionsAPIImpl extends BaseAPI {
|
|
|
24
24
|
}),
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
|
+
async batchCloseAllPositions(request) {
|
|
28
|
+
if (request) {
|
|
29
|
+
validate(BatchCloseAllSchema, request);
|
|
30
|
+
}
|
|
31
|
+
return await this.makeAuthenticatedRequest(perpRoutes.positions.batchCloseAll(), {
|
|
32
|
+
method: "POST",
|
|
33
|
+
body: JSON.stringify({
|
|
34
|
+
trading_pair_id: request?.tradingPairId,
|
|
35
|
+
slippage_tolerance_bps: request?.slippageToleranceBps,
|
|
36
|
+
}),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
27
39
|
async getPositionRisk(positionId) {
|
|
28
40
|
validate(GetPositionRiskSchema, { positionId });
|
|
29
41
|
return await this.makeAuthenticatedRequest(perpRoutes.positions.risk(positionId));
|
|
@@ -80,8 +80,8 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
|
|
|
80
80
|
expirationDate?: string;
|
|
81
81
|
timeInForce?: TimeInForce;
|
|
82
82
|
marginAccountId?: string;
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
riskBucketId?: string;
|
|
84
|
+
riskBucketCollateral?: string;
|
|
85
85
|
strategyKey?: string;
|
|
86
86
|
positionSide?: PositionSide;
|
|
87
87
|
leverage?: string;
|
|
@@ -134,8 +134,8 @@ export declare class TradingAPIImpl extends BaseAPI implements TradingAPI {
|
|
|
134
134
|
tradingMode?: TradingMode;
|
|
135
135
|
slippageTolerance?: number;
|
|
136
136
|
marginAccountId?: string;
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
riskBucketId?: string;
|
|
138
|
+
riskBucketCollateral?: string;
|
|
139
139
|
strategyKey?: string;
|
|
140
140
|
positionSide?: PositionSide;
|
|
141
141
|
leverage?: string;
|
package/dist/api/trading/api.js
CHANGED
|
@@ -107,8 +107,8 @@ export class TradingAPIImpl extends BaseAPI {
|
|
|
107
107
|
expiration_date: options?.expirationDate,
|
|
108
108
|
time_in_force: options?.timeInForce,
|
|
109
109
|
margin_account_id: options?.marginAccountId,
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
risk_bucket_id: options?.riskBucketId,
|
|
111
|
+
risk_bucket_collateral: options?.riskBucketCollateral,
|
|
112
112
|
strategy_key: options?.strategyKey,
|
|
113
113
|
position_side: options?.positionSide,
|
|
114
114
|
leverage: options?.leverage,
|
|
@@ -179,8 +179,8 @@ export class TradingAPIImpl extends BaseAPI {
|
|
|
179
179
|
quantity,
|
|
180
180
|
trading_mode: options?.tradingMode || "SPOT",
|
|
181
181
|
margin_account_id: options?.marginAccountId,
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
risk_bucket_id: options?.riskBucketId,
|
|
183
|
+
risk_bucket_collateral: options?.riskBucketCollateral,
|
|
184
184
|
strategy_key: options?.strategyKey,
|
|
185
185
|
position_side: options?.positionSide,
|
|
186
186
|
leverage: options?.leverage,
|
|
@@ -344,8 +344,8 @@ export class TradingAPIImpl extends BaseAPI {
|
|
|
344
344
|
expiration_date: order.expirationDate,
|
|
345
345
|
time_in_force: order.timeInForce,
|
|
346
346
|
margin_account_id: order.marginAccountId,
|
|
347
|
-
|
|
348
|
-
|
|
347
|
+
risk_bucket_id: order.riskBucketId,
|
|
348
|
+
risk_bucket_collateral: order.riskBucketCollateral,
|
|
349
349
|
strategy_key: order.strategyKey,
|
|
350
350
|
position_side: order.positionSide,
|
|
351
351
|
leverage: order.leverage,
|
package/dist/api/vault/api.d.ts
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* console.log(`Deposit transaction: ${result.hash}`);
|
|
24
24
|
* ```
|
|
25
25
|
*/
|
|
26
|
-
import type { ApplicationsAPI, Balance, DepositTarget, ProfileAPI, TransactionResult, VaultAPI, WithdrawResult } from "@0xmonaco/types";
|
|
26
|
+
import type { ApplicationsAPI, Balance, DepositTarget, ProfileAPI, TransactionResult, VaultAPI, WithdrawalRetryOptions, WithdrawalSource, WithdrawResult } from "@0xmonaco/types";
|
|
27
27
|
import { type Address, type Chain, type PublicClient, type WalletClient } from "viem";
|
|
28
28
|
import { BaseAPI } from "../base";
|
|
29
29
|
/**
|
|
@@ -172,21 +172,52 @@ export declare class VaultAPIImpl extends BaseAPI implements VaultAPI {
|
|
|
172
172
|
*/
|
|
173
173
|
deposit(assetId: string, amount: bigint, autoWait?: boolean, target?: DepositTarget): Promise<TransactionResult>;
|
|
174
174
|
/**
|
|
175
|
-
*
|
|
176
|
-
*
|
|
175
|
+
* Polls `GET /api/v1/withdrawals/{index}` until the gateway can serve the
|
|
176
|
+
* `executeWithdrawal` calldata, then returns it with the vault address.
|
|
177
177
|
*
|
|
178
|
-
* The
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
178
|
+
* The calldata only exists once the withdrawal's root is confirmed on-chain
|
|
179
|
+
* and its merkle proof is persisted. Until then the gateway returns 404 (the
|
|
180
|
+
* row is written asynchronously by the persistor after `initiate`) or 409
|
|
181
|
+
* (the proof is not confirmed yet); both are transient for a freshly-allocated
|
|
182
|
+
* index, so we retry on each until ready or the timeout elapses.
|
|
183
|
+
*
|
|
184
|
+
* Returns `null` when the timeout elapses before the proof is available — the
|
|
185
|
+
* index is still valid and the balance already debited, so callers surface
|
|
186
|
+
* this as `awaiting_proof` (with the index intact) rather than as a thrown
|
|
187
|
+
* error that would strand the index. Only non-transient errors (anything
|
|
188
|
+
* other than 404/409) throw.
|
|
189
|
+
*
|
|
190
|
+
* @throws {APIError} On non-transient errors while polling.
|
|
191
|
+
*/
|
|
192
|
+
private pollWithdrawalCalldata;
|
|
193
|
+
/**
|
|
194
|
+
* Initiates a withdrawal through the API Gateway, waits for its on-chain
|
|
195
|
+
* confirmation, then submits the resulting `executeWithdrawal` calldata via
|
|
196
|
+
* the connected wallet.
|
|
197
|
+
*
|
|
198
|
+
* The gateway allocates a `withdrawalIndex` via the matching engine and debits
|
|
199
|
+
* the balance immediately, but the executable calldata needs the withdrawal's
|
|
200
|
+
* merkle proof, which only exists once its root is confirmed on-chain. This
|
|
201
|
+
* method polls until the calldata is available (see `retry`), then submits it.
|
|
202
|
+
* The connected wallet pays gas; the contract authorises the withdrawal
|
|
203
|
+
* against the merkle proof embedded in the calldata. The wallet's address is
|
|
204
|
+
* sent as the on-chain `destination`.
|
|
205
|
+
*
|
|
206
|
+
* If the proof does not become available within the poll window, this method
|
|
207
|
+
* does NOT throw — it returns `{ withdrawalIndex, status: "awaiting_proof" }`
|
|
208
|
+
* with nothing submitted on-chain. The balance is already debited, so losing
|
|
209
|
+
* the index would strand the funds; the caller keeps it and finishes the
|
|
210
|
+
* withdrawal later with `retryWithdrawal(withdrawalIndex)`.
|
|
184
211
|
*
|
|
185
212
|
* @param assetId - The asset identifier (UUID) to withdraw
|
|
186
213
|
* @param amount - The raw token amount to withdraw (as bigint)
|
|
187
214
|
* @param autoWait - Whether to automatically wait for transaction confirmation (defaults to true)
|
|
188
|
-
* @
|
|
189
|
-
* @
|
|
215
|
+
* @param sourceOrRetry - Source ledger (`"spot"` or `"margin"`) or legacy retry options
|
|
216
|
+
* @param retry - Polling cadence/timeout while waiting for the proof when a source is supplied
|
|
217
|
+
* @returns Promise resolving to a [`WithdrawResult`]: on success the submitted
|
|
218
|
+
* transaction plus `withdrawalIndex`; on poll-timeout `{ withdrawalIndex,
|
|
219
|
+
* status: "awaiting_proof" }`.
|
|
220
|
+
* @throws {APIError} When the asset is not found or the initiate request is rejected
|
|
190
221
|
* @throws {ContractError} When the on-chain submission fails
|
|
191
222
|
* @throws {InvalidConfigError} When wallet account is not available
|
|
192
223
|
*
|
|
@@ -198,38 +229,50 @@ export declare class VaultAPIImpl extends BaseAPI implements VaultAPI {
|
|
|
198
229
|
* parseUnits("50", 6),
|
|
199
230
|
* );
|
|
200
231
|
* console.log(`Withdrawal index: ${result.withdrawalIndex}`);
|
|
201
|
-
*
|
|
232
|
+
* if (result.status === "awaiting_proof") {
|
|
233
|
+
* // Proof not ready yet — balance already debited. Finish later:
|
|
234
|
+
* await vaultAPI.retryWithdrawal(result.withdrawalIndex);
|
|
235
|
+
* } else {
|
|
236
|
+
* console.log(`Tx hash: ${result.hash}, status: ${result.status}`);
|
|
237
|
+
* }
|
|
202
238
|
*
|
|
203
|
-
* //
|
|
239
|
+
* // Custom polling (check every 10s, wait up to an hour)
|
|
204
240
|
* const result = await vaultAPI.withdraw(
|
|
205
241
|
* "123e4567-e89b-12d3-a456-426614174000",
|
|
206
242
|
* parseUnits("50", 6),
|
|
207
|
-
*
|
|
243
|
+
* true,
|
|
244
|
+
* { pollIntervalMs: 10_000, timeoutMs: 3_600_000 },
|
|
208
245
|
* );
|
|
209
|
-
* const receipt = await sdk.waitForTransaction(result.hash);
|
|
210
246
|
* ```
|
|
211
247
|
*/
|
|
212
|
-
withdraw(assetId: string, amount: bigint, autoWait?: boolean): Promise<WithdrawResult>;
|
|
248
|
+
withdraw(assetId: string, amount: bigint, autoWait?: boolean, sourceOrRetry?: WithdrawalSource | WithdrawalRetryOptions, retry?: WithdrawalRetryOptions): Promise<WithdrawResult>;
|
|
213
249
|
/**
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
250
|
+
* Submits (or resubmits) a previously-initiated withdrawal on-chain.
|
|
251
|
+
*
|
|
252
|
+
* Use this when the original `withdraw()` could not complete — e.g. the proof
|
|
253
|
+
* was not yet confirmed within its polling window, the wallet rejected the tx,
|
|
254
|
+
* the page reloaded before the receipt came back, or a stuck mempool entry
|
|
255
|
+
* needs resending. Polls `GET /withdrawals/{index}` for the
|
|
256
|
+
* `executeWithdrawal` calldata (retrying while it is not yet confirmed), then
|
|
257
|
+
* submits it through the connected wallet. Does NOT initiate a new withdrawal
|
|
258
|
+
* — the matching engine already debited the balance and allocated the index.
|
|
259
|
+
* The contract is idempotent against double-submission of a settled
|
|
260
|
+
* withdrawal: it reverts once the index is consumed on-chain.
|
|
217
261
|
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
* already debited the balance and allocated the index. The contract is
|
|
222
|
-
* idempotent against double-submission of a settled withdrawal: it will
|
|
223
|
-
* revert once the index is consumed on-chain.
|
|
262
|
+
* Like `withdraw()`, if the proof is still unavailable within the poll window
|
|
263
|
+
* this returns `{ withdrawalIndex, status: "awaiting_proof" }` instead of
|
|
264
|
+
* throwing, so the caller can simply retry again later.
|
|
224
265
|
*
|
|
225
266
|
* @param withdrawalIndex - The index returned by the original `withdraw()` call
|
|
226
267
|
* @param autoWait - Whether to await on-chain confirmation (defaults to true)
|
|
227
|
-
* @
|
|
228
|
-
* @
|
|
268
|
+
* @param retry - Polling cadence/timeout while waiting for the proof
|
|
269
|
+
* @returns Promise resolving to a [`WithdrawResult`]: the submitted transaction
|
|
270
|
+
* plus `withdrawalIndex`, or `{ withdrawalIndex, status: "awaiting_proof" }`
|
|
271
|
+
* if the proof did not arrive within the poll window.
|
|
229
272
|
* @throws {ContractError} When the on-chain submission fails
|
|
230
273
|
* @throws {InvalidConfigError} When wallet account is not available
|
|
231
274
|
*/
|
|
232
|
-
retryWithdrawal(withdrawalIndex: number, autoWait?: boolean): Promise<WithdrawResult>;
|
|
275
|
+
retryWithdrawal(withdrawalIndex: number, autoWait?: boolean, retry?: WithdrawalRetryOptions): Promise<WithdrawResult>;
|
|
233
276
|
/**
|
|
234
277
|
* Retrieves the user's token balance in the vault.
|
|
235
278
|
*
|
package/dist/api/vault/api.js
CHANGED
|
@@ -28,6 +28,17 @@ import { ApproveTokenSchema, DepositSchema, validate, WithdrawSchema } from "@0x
|
|
|
28
28
|
import { erc20Abi, zeroAddress } from "viem";
|
|
29
29
|
import { APIError, ContractError, InvalidConfigError } from "../../errors";
|
|
30
30
|
import { BaseAPI } from "../base";
|
|
31
|
+
/** Default delay between polls while waiting for a withdrawal's proof. */
|
|
32
|
+
const DEFAULT_WITHDRAWAL_POLL_INTERVAL_MS = 5_000;
|
|
33
|
+
/**
|
|
34
|
+
* Default total wait for a withdrawal's proof (5 minutes). A withdrawal's merkle
|
|
35
|
+
* proof only lands after its root is confirmed on-chain, which on a healthy
|
|
36
|
+
* pipeline takes ~20s but can lag behind a brief proposer hiccup; the previous
|
|
37
|
+
* 60s tripped too eagerly. On timeout the SDK returns `awaiting_proof` rather
|
|
38
|
+
* than throwing, so the caller never loses the index — it just retries later.
|
|
39
|
+
*/
|
|
40
|
+
const DEFAULT_WITHDRAWAL_TIMEOUT_MS = 300_000;
|
|
41
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
31
42
|
/**
|
|
32
43
|
* Encode the on-chain `applicationData` for a deposit.
|
|
33
44
|
*
|
|
@@ -304,21 +315,80 @@ export class VaultAPIImpl extends BaseAPI {
|
|
|
304
315
|
return await this.waitForTransaction(txResult, autoWait);
|
|
305
316
|
}
|
|
306
317
|
/**
|
|
307
|
-
*
|
|
308
|
-
*
|
|
318
|
+
* Polls `GET /api/v1/withdrawals/{index}` until the gateway can serve the
|
|
319
|
+
* `executeWithdrawal` calldata, then returns it with the vault address.
|
|
320
|
+
*
|
|
321
|
+
* The calldata only exists once the withdrawal's root is confirmed on-chain
|
|
322
|
+
* and its merkle proof is persisted. Until then the gateway returns 404 (the
|
|
323
|
+
* row is written asynchronously by the persistor after `initiate`) or 409
|
|
324
|
+
* (the proof is not confirmed yet); both are transient for a freshly-allocated
|
|
325
|
+
* index, so we retry on each until ready or the timeout elapses.
|
|
309
326
|
*
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
327
|
+
* Returns `null` when the timeout elapses before the proof is available — the
|
|
328
|
+
* index is still valid and the balance already debited, so callers surface
|
|
329
|
+
* this as `awaiting_proof` (with the index intact) rather than as a thrown
|
|
330
|
+
* error that would strand the index. Only non-transient errors (anything
|
|
331
|
+
* other than 404/409) throw.
|
|
332
|
+
*
|
|
333
|
+
* @throws {APIError} On non-transient errors while polling.
|
|
334
|
+
*/
|
|
335
|
+
async pollWithdrawalCalldata(withdrawalIndex, retry) {
|
|
336
|
+
const pollIntervalMs = retry?.pollIntervalMs ?? DEFAULT_WITHDRAWAL_POLL_INTERVAL_MS;
|
|
337
|
+
const timeoutMs = retry?.timeoutMs ?? DEFAULT_WITHDRAWAL_TIMEOUT_MS;
|
|
338
|
+
const deadline = Date.now() + timeoutMs;
|
|
339
|
+
for (;;) {
|
|
340
|
+
try {
|
|
341
|
+
const { vault_address: vaultAddress, calldata } = await this.makePublicRequest(`/api/v1/withdrawals/${withdrawalIndex}`);
|
|
342
|
+
// Ready: non-empty calldata. (Defensively treat an empty/`0x` body as
|
|
343
|
+
// not-ready too, though the gateway returns an error in that case.)
|
|
344
|
+
if (calldata && calldata !== "0x") {
|
|
345
|
+
return { vaultAddress, calldata };
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
catch (error) {
|
|
349
|
+
// 404 (row not persisted yet) and 409 (proof not confirmed yet) are
|
|
350
|
+
// transient for a valid index — keep polling. Anything else is fatal.
|
|
351
|
+
const isTransient = error instanceof APIError && (error.statusCode === 404 || error.statusCode === 409);
|
|
352
|
+
if (!isTransient) {
|
|
353
|
+
throw error;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if (Date.now() + pollIntervalMs > deadline) {
|
|
357
|
+
// Timed out waiting for the proof. Signal not-ready; the caller keeps the
|
|
358
|
+
// index and retries later rather than losing it inside a thrown error.
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
await sleep(pollIntervalMs);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Initiates a withdrawal through the API Gateway, waits for its on-chain
|
|
366
|
+
* confirmation, then submits the resulting `executeWithdrawal` calldata via
|
|
367
|
+
* the connected wallet.
|
|
368
|
+
*
|
|
369
|
+
* The gateway allocates a `withdrawalIndex` via the matching engine and debits
|
|
370
|
+
* the balance immediately, but the executable calldata needs the withdrawal's
|
|
371
|
+
* merkle proof, which only exists once its root is confirmed on-chain. This
|
|
372
|
+
* method polls until the calldata is available (see `retry`), then submits it.
|
|
373
|
+
* The connected wallet pays gas; the contract authorises the withdrawal
|
|
374
|
+
* against the merkle proof embedded in the calldata. The wallet's address is
|
|
375
|
+
* sent as the on-chain `destination`.
|
|
376
|
+
*
|
|
377
|
+
* If the proof does not become available within the poll window, this method
|
|
378
|
+
* does NOT throw — it returns `{ withdrawalIndex, status: "awaiting_proof" }`
|
|
379
|
+
* with nothing submitted on-chain. The balance is already debited, so losing
|
|
380
|
+
* the index would strand the funds; the caller keeps it and finishes the
|
|
381
|
+
* withdrawal later with `retryWithdrawal(withdrawalIndex)`.
|
|
316
382
|
*
|
|
317
383
|
* @param assetId - The asset identifier (UUID) to withdraw
|
|
318
384
|
* @param amount - The raw token amount to withdraw (as bigint)
|
|
319
385
|
* @param autoWait - Whether to automatically wait for transaction confirmation (defaults to true)
|
|
320
|
-
* @
|
|
321
|
-
* @
|
|
386
|
+
* @param sourceOrRetry - Source ledger (`"spot"` or `"margin"`) or legacy retry options
|
|
387
|
+
* @param retry - Polling cadence/timeout while waiting for the proof when a source is supplied
|
|
388
|
+
* @returns Promise resolving to a [`WithdrawResult`]: on success the submitted
|
|
389
|
+
* transaction plus `withdrawalIndex`; on poll-timeout `{ withdrawalIndex,
|
|
390
|
+
* status: "awaiting_proof" }`.
|
|
391
|
+
* @throws {APIError} When the asset is not found or the initiate request is rejected
|
|
322
392
|
* @throws {ContractError} When the on-chain submission fails
|
|
323
393
|
* @throws {InvalidConfigError} When wallet account is not available
|
|
324
394
|
*
|
|
@@ -330,18 +400,23 @@ export class VaultAPIImpl extends BaseAPI {
|
|
|
330
400
|
* parseUnits("50", 6),
|
|
331
401
|
* );
|
|
332
402
|
* console.log(`Withdrawal index: ${result.withdrawalIndex}`);
|
|
333
|
-
*
|
|
403
|
+
* if (result.status === "awaiting_proof") {
|
|
404
|
+
* // Proof not ready yet — balance already debited. Finish later:
|
|
405
|
+
* await vaultAPI.retryWithdrawal(result.withdrawalIndex);
|
|
406
|
+
* } else {
|
|
407
|
+
* console.log(`Tx hash: ${result.hash}, status: ${result.status}`);
|
|
408
|
+
* }
|
|
334
409
|
*
|
|
335
|
-
* //
|
|
410
|
+
* // Custom polling (check every 10s, wait up to an hour)
|
|
336
411
|
* const result = await vaultAPI.withdraw(
|
|
337
412
|
* "123e4567-e89b-12d3-a456-426614174000",
|
|
338
413
|
* parseUnits("50", 6),
|
|
339
|
-
*
|
|
414
|
+
* true,
|
|
415
|
+
* { pollIntervalMs: 10_000, timeoutMs: 3_600_000 },
|
|
340
416
|
* );
|
|
341
|
-
* const receipt = await sdk.waitForTransaction(result.hash);
|
|
342
417
|
* ```
|
|
343
418
|
*/
|
|
344
|
-
async withdraw(assetId, amount, autoWait = true) {
|
|
419
|
+
async withdraw(assetId, amount, autoWait = true, sourceOrRetry, retry) {
|
|
345
420
|
if (!this.walletClient) {
|
|
346
421
|
throw new InvalidConfigError("Wallet client not set. Connect a wallet first.", "walletClient");
|
|
347
422
|
}
|
|
@@ -350,21 +425,33 @@ export class VaultAPIImpl extends BaseAPI {
|
|
|
350
425
|
throw new InvalidConfigError("No account available in wallet client", "account");
|
|
351
426
|
}
|
|
352
427
|
const destination = walletAccount.address.toLowerCase();
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
//
|
|
357
|
-
//
|
|
358
|
-
//
|
|
359
|
-
const { withdrawal_index: withdrawalIndex
|
|
428
|
+
const source = typeof sourceOrRetry === "string" ? sourceOrRetry : "spot";
|
|
429
|
+
const retryOptions = typeof sourceOrRetry === "string" ? retry : sourceOrRetry;
|
|
430
|
+
validate(WithdrawSchema, { assetId, amount, destination, autoWait, source });
|
|
431
|
+
// 1. Gateway allocates the withdrawal_index and debits the balance. No
|
|
432
|
+
// executable calldata yet — it needs the merkle proof, available only once
|
|
433
|
+
// the withdrawal root is confirmed on-chain.
|
|
434
|
+
const { withdrawal_index: withdrawalIndex } = await this.makeAuthenticatedRequest("/api/v1/withdrawals", {
|
|
360
435
|
method: "POST",
|
|
361
436
|
body: JSON.stringify({
|
|
362
437
|
asset_id: assetId,
|
|
363
438
|
amount: amount.toString(),
|
|
364
439
|
destination,
|
|
440
|
+
source,
|
|
365
441
|
}),
|
|
366
442
|
});
|
|
367
|
-
// 2.
|
|
443
|
+
// 2. Poll for the executeWithdrawal calldata until the proof is confirmed.
|
|
444
|
+
// The vault address comes back with it, keeping calldata + target contract
|
|
445
|
+
// in lockstep.
|
|
446
|
+
const poll = await this.pollWithdrawalCalldata(withdrawalIndex, retryOptions);
|
|
447
|
+
if (!poll) {
|
|
448
|
+
// Proof not available within the poll window. The balance is already
|
|
449
|
+
// debited and the index is valid; return it (without submitting anything
|
|
450
|
+
// on-chain) so the caller can finish later via retryWithdrawal(index).
|
|
451
|
+
return { withdrawalIndex, status: "awaiting_proof" };
|
|
452
|
+
}
|
|
453
|
+
const { vaultAddress, calldata } = poll;
|
|
454
|
+
// 3. Submit the calldata on-chain through the connected wallet.
|
|
368
455
|
let hash;
|
|
369
456
|
try {
|
|
370
457
|
hash = await this.walletClient.sendTransaction({
|
|
@@ -375,7 +462,7 @@ export class VaultAPIImpl extends BaseAPI {
|
|
|
375
462
|
});
|
|
376
463
|
}
|
|
377
464
|
catch (error) {
|
|
378
|
-
throw new ContractError(`Failed to submit
|
|
465
|
+
throw new ContractError(`Failed to submit executeWithdrawal for withdrawal ${withdrawalIndex}: ${error instanceof Error ? error.message : "unknown error"}`, { cause: error instanceof Error ? error : undefined });
|
|
379
466
|
}
|
|
380
467
|
const nonce = walletAccount.getNonce ? await walletAccount.getNonce() : 0n;
|
|
381
468
|
const txResult = {
|
|
@@ -387,25 +474,32 @@ export class VaultAPIImpl extends BaseAPI {
|
|
|
387
474
|
return { ...settled, withdrawalIndex };
|
|
388
475
|
}
|
|
389
476
|
/**
|
|
390
|
-
*
|
|
391
|
-
* landed — e.g. the wallet rejected the tx, the page reloaded before the
|
|
392
|
-
* receipt came back, or a stuck mempool entry needs resending.
|
|
477
|
+
* Submits (or resubmits) a previously-initiated withdrawal on-chain.
|
|
393
478
|
*
|
|
394
|
-
*
|
|
395
|
-
*
|
|
396
|
-
*
|
|
397
|
-
*
|
|
398
|
-
*
|
|
399
|
-
*
|
|
479
|
+
* Use this when the original `withdraw()` could not complete — e.g. the proof
|
|
480
|
+
* was not yet confirmed within its polling window, the wallet rejected the tx,
|
|
481
|
+
* the page reloaded before the receipt came back, or a stuck mempool entry
|
|
482
|
+
* needs resending. Polls `GET /withdrawals/{index}` for the
|
|
483
|
+
* `executeWithdrawal` calldata (retrying while it is not yet confirmed), then
|
|
484
|
+
* submits it through the connected wallet. Does NOT initiate a new withdrawal
|
|
485
|
+
* — the matching engine already debited the balance and allocated the index.
|
|
486
|
+
* The contract is idempotent against double-submission of a settled
|
|
487
|
+
* withdrawal: it reverts once the index is consumed on-chain.
|
|
488
|
+
*
|
|
489
|
+
* Like `withdraw()`, if the proof is still unavailable within the poll window
|
|
490
|
+
* this returns `{ withdrawalIndex, status: "awaiting_proof" }` instead of
|
|
491
|
+
* throwing, so the caller can simply retry again later.
|
|
400
492
|
*
|
|
401
493
|
* @param withdrawalIndex - The index returned by the original `withdraw()` call
|
|
402
494
|
* @param autoWait - Whether to await on-chain confirmation (defaults to true)
|
|
403
|
-
* @
|
|
404
|
-
* @
|
|
495
|
+
* @param retry - Polling cadence/timeout while waiting for the proof
|
|
496
|
+
* @returns Promise resolving to a [`WithdrawResult`]: the submitted transaction
|
|
497
|
+
* plus `withdrawalIndex`, or `{ withdrawalIndex, status: "awaiting_proof" }`
|
|
498
|
+
* if the proof did not arrive within the poll window.
|
|
405
499
|
* @throws {ContractError} When the on-chain submission fails
|
|
406
500
|
* @throws {InvalidConfigError} When wallet account is not available
|
|
407
501
|
*/
|
|
408
|
-
async retryWithdrawal(withdrawalIndex, autoWait = true) {
|
|
502
|
+
async retryWithdrawal(withdrawalIndex, autoWait = true, retry) {
|
|
409
503
|
if (!this.walletClient) {
|
|
410
504
|
throw new InvalidConfigError("Wallet client not set. Connect a wallet first.", "walletClient");
|
|
411
505
|
}
|
|
@@ -413,7 +507,13 @@ export class VaultAPIImpl extends BaseAPI {
|
|
|
413
507
|
if (!walletAccount) {
|
|
414
508
|
throw new InvalidConfigError("No account available in wallet client", "account");
|
|
415
509
|
}
|
|
416
|
-
const
|
|
510
|
+
const poll = await this.pollWithdrawalCalldata(withdrawalIndex, retry);
|
|
511
|
+
if (!poll) {
|
|
512
|
+
// Still not confirmed on-chain within the poll window — return the index
|
|
513
|
+
// so the caller can retry again later, rather than throwing.
|
|
514
|
+
return { withdrawalIndex, status: "awaiting_proof" };
|
|
515
|
+
}
|
|
516
|
+
const { vaultAddress, calldata } = poll;
|
|
417
517
|
let hash;
|
|
418
518
|
try {
|
|
419
519
|
hash = await this.walletClient.sendTransaction({
|
|
@@ -424,7 +524,7 @@ export class VaultAPIImpl extends BaseAPI {
|
|
|
424
524
|
});
|
|
425
525
|
}
|
|
426
526
|
catch (error) {
|
|
427
|
-
throw new ContractError(`Failed to resubmit
|
|
527
|
+
throw new ContractError(`Failed to resubmit executeWithdrawal for withdrawal ${withdrawalIndex}: ${error instanceof Error ? error.message : "unknown error"}`, { cause: error instanceof Error ? error : undefined });
|
|
428
528
|
}
|
|
429
529
|
const nonce = walletAccount.getNonce ? await walletAccount.getNonce() : 0n;
|
|
430
530
|
const txResult = {
|
|
@@ -4,10 +4,12 @@ import { BaseAPI } from "../base";
|
|
|
4
4
|
* Low-level withdrawals client.
|
|
5
5
|
*
|
|
6
6
|
* `initiateWithdrawal` debits the caller's balance via the matching engine and
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* allocates a `withdrawal_index` (its `calldata` is empty — the proof is not
|
|
8
|
+
* available until the withdrawal root is confirmed on-chain). `getWithdrawal`
|
|
9
|
+
* returns the `executeWithdrawal` calldata once that proof is ready, and throws
|
|
10
|
+
* an `APIError` (404 not-persisted-yet / 409 not-confirmed-yet) while it is not.
|
|
11
|
+
* Neither submits on-chain — use the high-level vault API, which polls for the
|
|
12
|
+
* calldata and broadcasts the transaction.
|
|
11
13
|
*/
|
|
12
14
|
export declare class WithdrawalsAPIImpl extends BaseAPI implements WithdrawalsAPI {
|
|
13
15
|
initiateWithdrawal(request: InitiateWithdrawalRequest): Promise<WithdrawalResponse>;
|
|
@@ -4,10 +4,12 @@ import { perpRoutes } from "../perp";
|
|
|
4
4
|
* Low-level withdrawals client.
|
|
5
5
|
*
|
|
6
6
|
* `initiateWithdrawal` debits the caller's balance via the matching engine and
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* allocates a `withdrawal_index` (its `calldata` is empty — the proof is not
|
|
8
|
+
* available until the withdrawal root is confirmed on-chain). `getWithdrawal`
|
|
9
|
+
* returns the `executeWithdrawal` calldata once that proof is ready, and throws
|
|
10
|
+
* an `APIError` (404 not-persisted-yet / 409 not-confirmed-yet) while it is not.
|
|
11
|
+
* Neither submits on-chain — use the high-level vault API, which polls for the
|
|
12
|
+
* calldata and broadcasts the transaction.
|
|
11
13
|
*/
|
|
12
14
|
export class WithdrawalsAPIImpl extends BaseAPI {
|
|
13
15
|
async initiateWithdrawal(request) {
|
|
@@ -17,6 +19,7 @@ export class WithdrawalsAPIImpl extends BaseAPI {
|
|
|
17
19
|
asset_id: request.assetId,
|
|
18
20
|
amount: request.amount,
|
|
19
21
|
destination: request.destination,
|
|
22
|
+
source: request.source ?? "spot",
|
|
20
23
|
}),
|
|
21
24
|
});
|
|
22
25
|
}
|
package/dist/coverage.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare const COVERED: {
|
|
|
5
5
|
batch_cancel_all: string;
|
|
6
6
|
batch_cancel_all_by_pair: string;
|
|
7
7
|
batch_cancel_orders: string;
|
|
8
|
+
batch_close_all_positions: string;
|
|
8
9
|
batch_create_orders: string;
|
|
9
10
|
batch_replace_orders: string;
|
|
10
11
|
cancel_conditional_order: string;
|
|
@@ -36,6 +37,8 @@ export declare const COVERED: {
|
|
|
36
37
|
get_portfolio_stats: string;
|
|
37
38
|
get_position: string;
|
|
38
39
|
get_position_risk: string;
|
|
40
|
+
get_parent_margin_account_movements: string;
|
|
41
|
+
get_parent_margin_account_summary: string;
|
|
39
42
|
get_screener: string;
|
|
40
43
|
get_sub_account_limits: string;
|
|
41
44
|
get_trade_by_id: string;
|
|
@@ -68,13 +71,16 @@ export declare const COVERED: {
|
|
|
68
71
|
replace_order: string;
|
|
69
72
|
revoke_delegated_agent: string;
|
|
70
73
|
revoke_session: string;
|
|
71
|
-
|
|
74
|
+
simulate_risk_bucket_order_risk: string;
|
|
72
75
|
simulate_fees: string;
|
|
73
76
|
simulate_order_risk: string;
|
|
77
|
+
simulate_parent_margin_order_risk: string;
|
|
74
78
|
submit_whitelist: string;
|
|
79
|
+
transfer_collateral_from_parent_margin_account: string;
|
|
75
80
|
transfer_collateral_from_margin_account: string;
|
|
76
|
-
transfer_collateral_to_auto_margin_account: string;
|
|
77
81
|
transfer_collateral_to_margin_account: string;
|
|
82
|
+
transfer_collateral_to_parent_margin_account: string;
|
|
83
|
+
transfer_collateral_to_risk_bucket: string;
|
|
78
84
|
update_sub_account_limit: string;
|
|
79
85
|
upsert_delegated_agent: string;
|
|
80
86
|
verify_signature: string;
|
package/dist/coverage.js
CHANGED
|
@@ -5,6 +5,7 @@ export const COVERED = {
|
|
|
5
5
|
batch_cancel_all: "batchCancelAll",
|
|
6
6
|
batch_cancel_all_by_pair: "batchCancelAll (with tradingPairId)",
|
|
7
7
|
batch_cancel_orders: "batchCancel",
|
|
8
|
+
batch_close_all_positions: "batchCloseAllPositions",
|
|
8
9
|
batch_create_orders: "batchCreate",
|
|
9
10
|
batch_replace_orders: "batchReplace",
|
|
10
11
|
cancel_conditional_order: "cancelConditionalOrder",
|
|
@@ -36,6 +37,8 @@ export const COVERED = {
|
|
|
36
37
|
get_portfolio_stats: "getPortfolioStats",
|
|
37
38
|
get_position: "getPosition",
|
|
38
39
|
get_position_risk: "getPositionRisk",
|
|
40
|
+
get_parent_margin_account_movements: "getParentMarginAccountMovements",
|
|
41
|
+
get_parent_margin_account_summary: "getParentMarginAccountSummary",
|
|
39
42
|
get_screener: "getScreener",
|
|
40
43
|
get_sub_account_limits: "subAccounts.getLimits",
|
|
41
44
|
get_trade_by_id: "getTradeById",
|
|
@@ -68,13 +71,16 @@ export const COVERED = {
|
|
|
68
71
|
replace_order: "replaceOrder",
|
|
69
72
|
revoke_delegated_agent: "revokeDelegatedAgent",
|
|
70
73
|
revoke_session: "revokeSession",
|
|
71
|
-
|
|
74
|
+
simulate_risk_bucket_order_risk: "simulateRiskBucketOrderRisk",
|
|
72
75
|
simulate_fees: "simulateFees",
|
|
73
76
|
simulate_order_risk: "simulateOrderRisk",
|
|
77
|
+
simulate_parent_margin_order_risk: "simulateParentMarginOrderRisk",
|
|
74
78
|
submit_whitelist: "whitelist.submit",
|
|
79
|
+
transfer_collateral_from_parent_margin_account: "transferCollateralFromParentMarginAccount",
|
|
75
80
|
transfer_collateral_from_margin_account: "transferCollateralFromMarginAccount",
|
|
76
|
-
transfer_collateral_to_auto_margin_account: "transferCollateralToAutoMarginAccount",
|
|
77
81
|
transfer_collateral_to_margin_account: "transferCollateralToMarginAccount",
|
|
82
|
+
transfer_collateral_to_parent_margin_account: "transferCollateralToParentMarginAccount",
|
|
83
|
+
transfer_collateral_to_risk_bucket: "transferCollateralToRiskBucket",
|
|
78
84
|
update_sub_account_limit: "subAccounts.updateLimit",
|
|
79
85
|
upsert_delegated_agent: "upsertDelegatedAgent",
|
|
80
86
|
verify_signature: "verifySignature",
|
package/dist/sdk.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ApplicationsAPI, AuthAPI, AuthState, DelegatedAgentsAPI, FaucetAPI, FeesAPI, MarginAccountsAPI, MarketAPI, MonacoSDK, Network, PositionsAPI, ProfileAPI, SDKConfig, SubAccountsAPI, TradingAPI, VaultAPI, WhitelistAPI, WithdrawalsAPI } from "@0xmonaco/types";
|
|
2
|
-
import { type PublicClient, type TransactionReceipt, type WalletClient } from "viem";
|
|
2
|
+
import { type Address, type PublicClient, type TransactionReceipt, type WalletClient } from "viem";
|
|
3
3
|
import { type MonacoWebSocket, OrderbookAPIImpl, TradesAPIImpl } from "./api";
|
|
4
4
|
export declare class MonacoSDKImpl implements MonacoSDK {
|
|
5
5
|
auth: AuthAPI;
|
|
@@ -147,7 +147,7 @@ export declare class MonacoSDKImpl implements MonacoSDK {
|
|
|
147
147
|
/**
|
|
148
148
|
* Get the current account address
|
|
149
149
|
*/
|
|
150
|
-
getAccountAddress():
|
|
150
|
+
getAccountAddress(): Address;
|
|
151
151
|
/**
|
|
152
152
|
* Get the current network
|
|
153
153
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@0xmonaco/core",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"viem": "^2.45.2"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@0xmonaco/contracts": "0.8.
|
|
27
|
-
"@0xmonaco/types": "0.8.
|
|
26
|
+
"@0xmonaco/contracts": "0.8.14",
|
|
27
|
+
"@0xmonaco/types": "0.8.14",
|
|
28
28
|
"@noble/curves": "^1.9.1",
|
|
29
29
|
"@noble/hashes": "^1.8.0",
|
|
30
30
|
"http-status-codes": "^2.3.0"
|