@mfxhub/sdk 0.3.0 → 0.4.0

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/index.d.ts CHANGED
@@ -18,12 +18,12 @@ export type { Account, Deal, DealPageOptions, DealWindow, PendingOrder, PendingO
18
18
  export { Execution, POLL_CAP_MS, POLL_FROM_MS } from "./execution.js";
19
19
  export { CLOSE_LIFETIME, CLOSE_REAUTHENTICATE, CLOSE_SLOW_CONSUMER, Channel, ChannelRefused, MfxStream, Resync, StreamClosed, StreamMessage, wsConnector, } from "./stream.js";
20
20
  export type { Connector, StreamConnection, StreamEvent, StreamOptions, StreamStats, Timeframe, } from "./stream.js";
21
- export type { ClosePosition, ClosePositionBy, ClosePositionPartial, Keyed, ModifyOrder, ModifyPosition, OrderType, PlaceOrder, SetTrailingStop, Side, WaitFor, } from "./execution.js";
22
- export type { CommandState, ExecutionResult, Reason, Tickets } from "./results.js";
21
+ export type { ClosePosition, ClosePositionBy, ClosePositionPartial, Keyed, ModifyOrder, ModifyPosition, OrderType, PlaceOrder, Resource, SetTrailingStop, Side, WaitFor, } from "./execution.js";
22
+ export type { CommandState, ExecutionResult, Reason, Tickets, VenueDeal } from "./results.js";
23
23
  export { Terminals, isUsable } from "./terminals.js";
24
24
  export type { CreateTerminal, BulkAction, BulkAsk, JournalLine, JournalOptions, PageOptions, Redundancy, Terminal, TerminalFilter, TerminalJournal, TerminalQueue, TerminalState, WaitOptions, } from "./terminals.js";
25
25
  export { TradingAccounts } from "./trading-accounts.js";
26
- export type { AccountEnvironment, AccountState, TradingAccount, TradingAccountFilter, TradingAccountPageOptions, Venue, } from "./trading-accounts.js";
26
+ export type { AccountEnvironment, AccountState, CtraderGrant, CtraderGrantStarted, GrantScope, StartCtraderGrant, TradingAccount, TradingAccountFilter, TradingAccountPageOptions, TradingSymbol, TradingSymbolList, Venue, } from "./trading-accounts.js";
27
27
  export { RequestSigner, SigningKey, signingMessage } from "./signing.js";
28
28
  export { KEY_HEADER, NONCE_HEADER, SIGNATURE_HEADER, TIMESTAMP_HEADER } from "./signing.js";
29
29
  export type { components, operations, paths } from "./generated/api.js";
package/dist/results.d.ts CHANGED
@@ -6,13 +6,24 @@ export type CommandState = components["schemas"]["CommandState"];
6
6
  * (`transport_error`, `timeout`, `refused`, and `maintenance` when the API refuses outright).
7
7
  * A reason the platform adds later arrives in `reasonText` as it was sent, with `reason` null.
8
8
  */
9
- export type Reason = "success" | "requote" | "instrument_disabled" | "no_liquidity" | "market_closed" | "invalid_stops" | "invalid_volume" | "insufficient_funds" | "trade_disabled" | "rejected_other" | "rate_limited" | "expired" | "unknown" | "maintenance" | "transport_error" | "timeout" | "refused";
9
+ export type Reason = "success" | "requote" | "instrument_disabled" | "no_liquidity" | "market_closed" | "invalid_stops" | "invalid_volume" | "insufficient_funds" | "trade_disabled" | "rejected_other" | "rate_limited" | "expired" | "unknown" | "maintenance" | "venue_unavailable" | "not_on_this_venue" | "transport_error" | "timeout" | "refused";
10
10
  /** MT5 relates one order, one deal and one position per fill; null where MT5 has none yet. */
11
11
  export interface Tickets {
12
12
  readonly order: number | null;
13
13
  readonly deal: number | null;
14
14
  readonly position: number | null;
15
15
  }
16
+ /**
17
+ * One deal a command made, as the venue reported it (cTrader): two for an emulated close-by, one
18
+ * for an order filled at once. `volumeUnits` is in units of the instrument, not lots.
19
+ */
20
+ export interface VenueDeal {
21
+ readonly deal: number;
22
+ readonly order: number | null;
23
+ readonly position: number | null;
24
+ readonly volumeUnits: string | null;
25
+ readonly price: string | null;
26
+ }
16
27
  /**
17
28
  * The whole answer to one execution call. Never thrown, always returned.
18
29
  *
@@ -60,6 +71,21 @@ export interface ExecutionResult {
60
71
  readonly detail: string | null;
61
72
  /** When sending it again can work: a maintenance window's end, where the platform said. */
62
73
  readonly retryAt: Date | null;
74
+ /** The venue that answered, `mt5` or `ctrader`; null until there is a result. */
75
+ readonly venue: string | null;
76
+ /**
77
+ * The venue's own code for a refusal, verbatim, beside `reason` (cTrader: such as
78
+ * NOT_ENOUGH_MONEY). Null on MT5, whose code is `mt5Retcode`.
79
+ */
80
+ readonly venueCode: string | null;
81
+ /** Every deal the command made, in order (cTrader). Empty on MT5, where `tickets.deal` is it. */
82
+ readonly deals: readonly VenueDeal[];
83
+ /** The volume filled in units of the instrument; `execVolume` stays in lots. Null on MT5. */
84
+ readonly volumeUnits: string | null;
85
+ /** A close-by the venue has no equivalent for, done as two closes (cTrader). */
86
+ readonly closeByEmulated: boolean;
87
+ /** A market order filled but its stop loss or take profit could not be set: it is open without. */
88
+ readonly protectionNotSet: boolean;
63
89
  }
64
90
  /** A result from a Command or a CommandAccepted body, whichever the call answered with. */
65
91
  export declare function fromCommand(body: unknown, idempotencyKey: string, clientRttMs: number): ExecutionResult;
package/dist/results.js CHANGED
@@ -40,10 +40,31 @@ const REASONS = new Set([
40
40
  "expired",
41
41
  "unknown",
42
42
  "maintenance",
43
+ "venue_unavailable",
44
+ "not_on_this_venue",
43
45
  "transport_error",
44
46
  "timeout",
45
47
  "refused",
46
48
  ]);
49
+ function deals(value) {
50
+ if (!Array.isArray(value))
51
+ return [];
52
+ const out = [];
53
+ for (const item of value) {
54
+ const one = record(item);
55
+ const deal = int(one.deal);
56
+ if (deal === null)
57
+ continue;
58
+ out.push({
59
+ deal,
60
+ order: int(one.order),
61
+ position: int(one.position),
62
+ volumeUnits: decimalOut(one.volume_units),
63
+ price: decimalOut(one.price),
64
+ });
65
+ }
66
+ return out;
67
+ }
47
68
  function int(value) {
48
69
  return typeof value === "number" && Number.isInteger(value) ? value : null;
49
70
  }
@@ -95,6 +116,12 @@ export function fromCommand(body, idempotencyKey, clientRttMs) {
95
116
  reroutedFrom: text(result.rerouted_from),
96
117
  detail: null,
97
118
  retryAt: null,
119
+ venue: text(result.venue),
120
+ venueCode: text(result.venue_code),
121
+ deals: deals(result.deals),
122
+ volumeUnits: decimalOut(result.volume_units),
123
+ closeByEmulated: result.close_by_emulated === true,
124
+ protectionNotSet: result.protection_not_set === true,
98
125
  };
99
126
  }
100
127
  /**
@@ -1,6 +1,9 @@
1
+ import { type Account, type Deal, type DealPageOptions, type DealWindow, type PendingOrderList, type PositionList } from "./accounts.js";
1
2
  import type { MfxClient } from "./client.js";
3
+ import { type ClosePosition, type ClosePositionBy, type ClosePositionPartial, type Keyed, type ModifyOrder, type ModifyPosition, type PlaceOrder, type SetTrailingStop } from "./execution.js";
2
4
  import type { components } from "./generated/api.js";
3
5
  import { type Page } from "./pages.js";
6
+ import type { ExecutionResult } from "./results.js";
4
7
  /** One trading account at one venue, as the API describes it. */
5
8
  export type TradingAccount = components["schemas"]["TradingAccount"];
6
9
  /** The trading technology an account is on. */
@@ -9,6 +12,27 @@ export type Venue = TradingAccount["venue"];
9
12
  export type AccountState = TradingAccount["state"];
10
13
  /** Live or demo. */
11
14
  export type AccountEnvironment = NonNullable<TradingAccount["environment"]>;
15
+ /** The symbols one cTrader account can trade, with their volume rules in lots and leverage. */
16
+ export type TradingSymbolList = components["schemas"]["TradingSymbolList"];
17
+ /** One symbol of a cTrader account. */
18
+ export type TradingSymbol = components["schemas"]["TradingSymbol"];
19
+ /** A cTrader grant: its state and, once ACTIVE, the accounts the trader shared. */
20
+ export type CtraderGrant = components["schemas"]["CtraderGrant"];
21
+ /** A started grant: the consent link to send the trader to, and until when it works. */
22
+ export type CtraderGrantStarted = components["schemas"]["CtraderGrantStarted"];
23
+ /** What a grant lets MFX Hub do: `accounts` reads only, `trading` reads and trades. */
24
+ export type GrantScope = components["schemas"]["CtraderGrantCreate"]["scope"];
25
+ /** What {@link TradingAccounts.startCtraderGrant} takes. */
26
+ export interface StartCtraderGrant {
27
+ /** One grant covers live or demo accounts. */
28
+ readonly environment: AccountEnvironment;
29
+ readonly scope: GrantScope;
30
+ /** Where the trader comes back to, https only, with `grant_id`, `result` and your state. */
31
+ readonly returnUrl: string;
32
+ /** Your own value, returned unchanged on the return URL; never read by MFX Hub. */
33
+ readonly tenantState?: string;
34
+ readonly idempotencyKey: string;
35
+ }
12
36
  /** Narrow the list on the platform, before the page is cut. */
13
37
  export interface TradingAccountFilter {
14
38
  /** Only accounts on this venue, or on one of these. */
@@ -25,7 +49,7 @@ export interface TradingAccountPageOptions extends TradingAccountFilter {
25
49
  /** How many to a page, 1 to 200. */
26
50
  readonly limit?: number;
27
51
  }
28
- /** Read the trading accounts this key's tenant holds. Needs `acct:read`. */
52
+ /** Read, trade and connect the trading accounts this key's tenant holds. */
29
53
  export declare class TradingAccounts {
30
54
  #private;
31
55
  constructor(client: MfxClient);
@@ -41,4 +65,66 @@ export declare class TradingAccounts {
41
65
  * filters narrow the list on the platform, so a filtered page is never short for being filtered.
42
66
  */
43
67
  list(options?: Omit<TradingAccountPageOptions, "cursor">): AsyncGenerator<TradingAccount, void, undefined>;
68
+ /**
69
+ * Balance, equity, margin and profile, answered by the account's lead runner. On cTrader the
70
+ * equity is computed by the platform (the venue sends none); `stale` says when it could not be.
71
+ */
72
+ funds(accountId: string): Promise<Account>;
73
+ /** Every open position, as one snapshot. On cTrader `volume` is in lots. */
74
+ positions(accountId: string): Promise<PositionList>;
75
+ /** Every pending order, as one snapshot. */
76
+ pendingOrders(accountId: string): Promise<PendingOrderList>;
77
+ /**
78
+ * One page of deals inside a window of at most 31 days, newest first, optionally of one
79
+ * position. On cTrader every time is UTC and `magic` is the order's origin marker.
80
+ */
81
+ dealsPage(accountId: string, options: DealPageOptions): Promise<Page<Deal>>;
82
+ /** Every deal inside the window, following the cursor, one request a page. */
83
+ deals(accountId: string, window: DealWindow): AsyncGenerator<Deal, void, undefined>;
84
+ /**
85
+ * The symbols a cTrader account can trade: a volume a command sends must be a whole
86
+ * `volume_step` between `volume_min` and `volume_max`, in lots. An MT5 account is refused.
87
+ */
88
+ symbols(accountId: string): Promise<TradingSymbolList>;
89
+ /**
90
+ * Place a market or pending order on the account. `volume` is in lots on every venue, and on
91
+ * cTrader a whole step of the symbol (`symbols`). On cTrader `magic` stays on the order as its
92
+ * label, and a market order's stops are set just after the fill (`protectionNotSet` says when
93
+ * that failed).
94
+ */
95
+ placeOrder(accountId: string, order: PlaceOrder): Promise<ExecutionResult>;
96
+ /** Amend a pending order's price, stops or expiry. */
97
+ modifyOrder(accountId: string, ticket: number, change: ModifyOrder): Promise<ExecutionResult>;
98
+ /** Cancel a pending order. */
99
+ cancelOrder(accountId: string, ticket: number, options: Keyed): Promise<ExecutionResult>;
100
+ /** Move a position's stop loss, take profit, or both. */
101
+ modifyPosition(accountId: string, ticket: number, change: ModifyPosition): Promise<ExecutionResult>;
102
+ /** Close a position in full. */
103
+ closePosition(accountId: string, ticket: number, options: ClosePosition): Promise<ExecutionResult>;
104
+ /** Close part of a position, in lots. */
105
+ closePositionPartial(accountId: string, ticket: number, options: ClosePositionPartial): Promise<ExecutionResult>;
106
+ /**
107
+ * Close a position against an opposite one. cTrader has no close-by: it is done as two closes,
108
+ * the result says `closeByEmulated` and `deals` holds both.
109
+ */
110
+ closePositionBy(accountId: string, ticket: number, options: ClosePositionBy): Promise<ExecutionResult>;
111
+ /** Trail a position's stop loss. A venue without a trailing stop refuses it, as a result. */
112
+ setTrailingStop(accountId: string, ticket: number, options: SetTrailingStop): Promise<ExecutionResult>;
113
+ /** Remove a position's trailing stop. */
114
+ clearTrailingStop(accountId: string, ticket: number, options: Keyed): Promise<ExecutionResult>;
115
+ /**
116
+ * Start connecting a trader's cTrader accounts; resolves to the consent link to send them to.
117
+ * They sign in at cTrader (MFX Hub never sees the password), choose the accounts to share and
118
+ * come back to `returnUrl`. The link lives 15 minutes. A plan without cTrader is forbidden.
119
+ */
120
+ startCtraderGrant(grant: StartCtraderGrant): Promise<CtraderGrantStarted>;
121
+ /** One grant: PENDING, ACTIVE, REVOKED or EXPIRED, and once ACTIVE the accounts shared. */
122
+ ctraderGrant(grantId: string): Promise<CtraderGrant>;
123
+ /**
124
+ * Make some of an ACTIVE grant's accounts trading accounts of yours, by cTrader's ids (1 to
125
+ * 50). Each starts PENDING and is CONNECTED once authorised at cTrader.
126
+ */
127
+ connectCtraderAccounts(grantId: string, ctidTraderAccountIds: readonly (string | number)[], options: Keyed): Promise<TradingAccount[]>;
128
+ /** Revoke a grant: its accounts move to REAUTH_NEEDED; a new grant reconnects them. */
129
+ revokeCtraderGrant(grantId: string, options: Keyed): Promise<CtraderGrant>;
44
130
  }
@@ -1,15 +1,23 @@
1
1
  // `client.tradingAccounts`: the tenant's trading accounts over every venue.
2
2
  //
3
3
  // One trading account is one account at one venue: an MT5 account (run by one terminal, or two with
4
- // HA), and from the cTrader release a cTrader account. An MT5 account's id is its terminal's id, so
5
- // an id you already hold reads its account, and `get` also takes either HA terminal's id. Its state
6
- // is the venue-neutral word (CONNECTED, DEGRADED, REAUTH_NEEDED, ...); `client.terminals.get` has
7
- // the MT5 detail.
4
+ // HA), and a cTrader account. An MT5 account takes its first terminal's id, and `get` also takes
5
+ // any of its terminals' ids. Its state is the venue-neutral word (CONNECTED, DEGRADED,
6
+ // REAUTH_NEEDED, ...); `client.terminals.get` has the MT5 detail.
7
+ //
8
+ // The same object trades an account and reads it on any venue: the nine commands of
9
+ // `client.execution` keyed on the account (`exec:write`), and its funds, positions, pending orders,
10
+ // deals and symbols (`acct:read`). The platform hands each to the account's lead runner. A cTrader
11
+ // account is connected through a grant: `startCtraderGrant` answers the consent link to send the
12
+ // trader to, `ctraderGrant` lists the accounts they shared, and `connectCtraderAccounts` makes the
13
+ // chosen ones trading accounts of yours (`term:write`).
8
14
  //
9
15
  // DECISION: a namespace of its own beside `client.accounts`, which stays what it was: the balance,
10
16
  // positions and deals of a terminal's account. Folding the two together would give `accounts.get`
11
17
  // two meanings.
12
- import { limit as pageLimit, uuid } from "./arguments.js";
18
+ import { Accounts, } from "./accounts.js";
19
+ import { idempotencyKey, limit as pageLimit, uuid } from "./arguments.js";
20
+ import { Execution, } from "./execution.js";
13
21
  import { everyItem, pageOf } from "./pages.js";
14
22
  function joined(name, value) {
15
23
  if (value === undefined)
@@ -23,11 +31,15 @@ function joined(name, value) {
23
31
  }
24
32
  return words.join(",");
25
33
  }
26
- /** Read the trading accounts this key's tenant holds. Needs `acct:read`. */
34
+ /** Read, trade and connect the trading accounts this key's tenant holds. */
27
35
  export class TradingAccounts {
28
36
  #client;
37
+ #orders;
38
+ #reads;
29
39
  constructor(client) {
30
40
  this.#client = client;
41
+ this.#orders = new Execution(client, "accounts");
42
+ this.#reads = new Accounts(client, "accounts");
31
43
  }
32
44
  /**
33
45
  * One trading account, by its own id or by one of its terminals' ids. Another tenant's, or an id
@@ -73,4 +85,144 @@ export class TradingAccounts {
73
85
  };
74
86
  return everyItem((cursor) => this.page({ ...rest, ...(cursor === undefined ? {} : { cursor }) }));
75
87
  }
88
+ // ------------------------------------------------------------------------------------- reads
89
+ /**
90
+ * Balance, equity, margin and profile, answered by the account's lead runner. On cTrader the
91
+ * equity is computed by the platform (the venue sends none); `stale` says when it could not be.
92
+ */
93
+ async funds(accountId) {
94
+ return this.#reads.account(accountId);
95
+ }
96
+ /** Every open position, as one snapshot. On cTrader `volume` is in lots. */
97
+ async positions(accountId) {
98
+ return this.#reads.positions(accountId);
99
+ }
100
+ /** Every pending order, as one snapshot. */
101
+ async pendingOrders(accountId) {
102
+ return this.#reads.pendingOrders(accountId);
103
+ }
104
+ /**
105
+ * One page of deals inside a window of at most 31 days, newest first, optionally of one
106
+ * position. On cTrader every time is UTC and `magic` is the order's origin marker.
107
+ */
108
+ async dealsPage(accountId, options) {
109
+ return this.#reads.dealsPage(accountId, options);
110
+ }
111
+ /** Every deal inside the window, following the cursor, one request a page. */
112
+ deals(accountId, window) {
113
+ return this.#reads.deals(accountId, window);
114
+ }
115
+ /**
116
+ * The symbols a cTrader account can trade: a volume a command sends must be a whole
117
+ * `volume_step` between `volume_min` and `volume_max`, in lots. An MT5 account is refused.
118
+ */
119
+ async symbols(accountId) {
120
+ const id = uuid("accountId", accountId);
121
+ const path = `/accounts/${id}/symbols`;
122
+ return (await this.#client.read({ method: "GET", path }));
123
+ }
124
+ // ---------------------------------------------------------------------------------- commands
125
+ // The same bodies and rules as `client.execution`, sent to /accounts/{id}/...: each resolves to
126
+ // a result and never rejects. Read the outcome with `client.execution.waitFor`.
127
+ /**
128
+ * Place a market or pending order on the account. `volume` is in lots on every venue, and on
129
+ * cTrader a whole step of the symbol (`symbols`). On cTrader `magic` stays on the order as its
130
+ * label, and a market order's stops are set just after the fill (`protectionNotSet` says when
131
+ * that failed).
132
+ */
133
+ async placeOrder(accountId, order) {
134
+ return this.#orders.placeOrder(accountId, order);
135
+ }
136
+ /** Amend a pending order's price, stops or expiry. */
137
+ async modifyOrder(accountId, ticket, change) {
138
+ return this.#orders.modifyOrder(accountId, ticket, change);
139
+ }
140
+ /** Cancel a pending order. */
141
+ async cancelOrder(accountId, ticket, options) {
142
+ return this.#orders.cancelOrder(accountId, ticket, options);
143
+ }
144
+ /** Move a position's stop loss, take profit, or both. */
145
+ async modifyPosition(accountId, ticket, change) {
146
+ return this.#orders.modifyPosition(accountId, ticket, change);
147
+ }
148
+ /** Close a position in full. */
149
+ async closePosition(accountId, ticket, options) {
150
+ return this.#orders.closePosition(accountId, ticket, options);
151
+ }
152
+ /** Close part of a position, in lots. */
153
+ async closePositionPartial(accountId, ticket, options) {
154
+ return this.#orders.closePositionPartial(accountId, ticket, options);
155
+ }
156
+ /**
157
+ * Close a position against an opposite one. cTrader has no close-by: it is done as two closes,
158
+ * the result says `closeByEmulated` and `deals` holds both.
159
+ */
160
+ async closePositionBy(accountId, ticket, options) {
161
+ return this.#orders.closePositionBy(accountId, ticket, options);
162
+ }
163
+ /** Trail a position's stop loss. A venue without a trailing stop refuses it, as a result. */
164
+ async setTrailingStop(accountId, ticket, options) {
165
+ return this.#orders.setTrailingStop(accountId, ticket, options);
166
+ }
167
+ /** Remove a position's trailing stop. */
168
+ async clearTrailingStop(accountId, ticket, options) {
169
+ return this.#orders.clearTrailingStop(accountId, ticket, options);
170
+ }
171
+ // ----------------------------------------------------------------------------- cTrader grants
172
+ /**
173
+ * Start connecting a trader's cTrader accounts; resolves to the consent link to send them to.
174
+ * They sign in at cTrader (MFX Hub never sees the password), choose the accounts to share and
175
+ * come back to `returnUrl`. The link lives 15 minutes. A plan without cTrader is forbidden.
176
+ */
177
+ async startCtraderGrant(grant) {
178
+ const key = idempotencyKey(grant.idempotencyKey);
179
+ if (typeof grant.returnUrl !== "string" || !grant.returnUrl.startsWith("https://")) {
180
+ throw new TypeError("returnUrl is an https:// URL");
181
+ }
182
+ const body = {
183
+ environment: grant.environment,
184
+ scope: grant.scope,
185
+ return_url: grant.returnUrl,
186
+ ...(grant.tenantState === undefined ? {} : { tenant_state: grant.tenantState }),
187
+ };
188
+ return (await this.#client.write({
189
+ method: "POST",
190
+ path: "/accounts/ctrader/grants",
191
+ body,
192
+ idempotencyKey: key,
193
+ }));
194
+ }
195
+ /** One grant: PENDING, ACTIVE, REVOKED or EXPIRED, and once ACTIVE the accounts shared. */
196
+ async ctraderGrant(grantId) {
197
+ const id = uuid("grantId", grantId);
198
+ const path = `/accounts/ctrader/grants/${id}`;
199
+ return (await this.#client.read({ method: "GET", path }));
200
+ }
201
+ /**
202
+ * Make some of an ACTIVE grant's accounts trading accounts of yours, by cTrader's ids (1 to
203
+ * 50). Each starts PENDING and is CONNECTED once authorised at cTrader.
204
+ */
205
+ async connectCtraderAccounts(grantId, ctidTraderAccountIds, options) {
206
+ const id = uuid("grantId", grantId);
207
+ const key = idempotencyKey(options.idempotencyKey);
208
+ const ids = ctidTraderAccountIds.map(String);
209
+ if (ids.length === 0)
210
+ throw new RangeError("connect at least one account");
211
+ const body = (await this.#client.write({
212
+ method: "POST",
213
+ path: `/accounts/ctrader/grants/${id}/accounts`,
214
+ body: { ctid_trader_account_ids: ids },
215
+ idempotencyKey: key,
216
+ }));
217
+ return body.items;
218
+ }
219
+ /** Revoke a grant: its accounts move to REAUTH_NEEDED; a new grant reconnects them. */
220
+ async revokeCtraderGrant(grantId, options) {
221
+ const id = uuid("grantId", grantId);
222
+ return (await this.#client.write({
223
+ method: "DELETE",
224
+ path: `/accounts/ctrader/grants/${id}`,
225
+ idempotencyKey: idempotencyKey(options.idempotencyKey),
226
+ }));
227
+ }
76
228
  }
package/dist/version.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  /** This package's version. */
2
- export declare const VERSION = "0.3.0";
2
+ export declare const VERSION = "0.4.0";
3
3
  /** What every request says it is, as a product token: the SDK's language and its version. */
4
- export declare const USER_AGENT = "mfx-sdk-typescript/0.3.0";
4
+ export declare const USER_AGENT = "mfx-sdk-typescript/0.4.0";
package/dist/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // This package's version, in one place: exported by the package, and named by every request.
2
2
  /** This package's version. */
3
- export const VERSION = "0.3.0";
3
+ export const VERSION = "0.4.0";
4
4
  /** What every request says it is, as a product token: the SDK's language and its version. */
5
5
  export const USER_AGENT = `mfx-sdk-typescript/${VERSION}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mfxhub/sdk",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Typed TypeScript client for the MFX Hub API: hosted trading terminals, market data, execution and a live event stream",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",