@2bad/walt 0.0.0-stage → 1.0.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/LICENSE +21 -0
- package/README.md +105 -2
- package/build/api/accounts.d.ts +111 -0
- package/build/api/accounts.js +1 -0
- package/build/api/analytics.d.ts +67 -0
- package/build/api/analytics.js +1 -0
- package/build/api/earn.d.ts +113 -0
- package/build/api/earn.js +1 -0
- package/build/api/exchange.d.ts +51 -0
- package/build/api/exchange.js +1 -0
- package/build/api/limit-orders.d.ts +62 -0
- package/build/api/limit-orders.js +1 -0
- package/build/api/transactions.d.ts +85 -0
- package/build/api/transactions.js +32 -0
- package/build/bin/login.d.ts +1 -0
- package/build/bin/login.js +26 -0
- package/build/browser.d.ts +19 -0
- package/build/browser.js +21 -0
- package/build/client.d.ts +138 -0
- package/build/client.js +294 -0
- package/build/index.d.ts +10 -0
- package/build/index.js +5 -0
- package/build/telegram/auth.d.ts +57 -0
- package/build/telegram/auth.js +164 -0
- package/build/telegram/file-storage.d.ts +3 -0
- package/build/telegram/file-storage.js +33 -0
- package/build/transport.d.ts +40 -0
- package/build/transport.js +177 -0
- package/package.json +81 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 2BAD
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,106 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @2bad/walt
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@2bad/walt)
|
|
4
|
+
[](https://www.npmjs.com/package/@2bad/walt)
|
|
5
|
+
[](https://codecov.io/gh/2BAD/walt)
|
|
6
|
+
[](https://github.com/2BAD/walt/actions/workflows/build.yml)
|
|
7
|
+
|
|
8
|
+
Client for Walt, the crypto app in Telegram (ex @wallet).
|
|
9
|
+
|
|
10
|
+
> [!WARNING]
|
|
11
|
+
> This is an unofficial client. It is not affiliated with, endorsed by or supported by Walt or Telegram. It uses a
|
|
12
|
+
> private, undocumented API. Using it likely violates the Walt and Telegram terms of service and may get your account
|
|
13
|
+
> restricted or banned. The software is provided as is, without warranty of any kind. The authors accept no liability
|
|
14
|
+
> for any loss of funds, account access or data, or any other damage arising from its use. Use it at your own risk.
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npm install @2bad/walt
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
ESM only. Requires Node.js 26 or later.
|
|
23
|
+
|
|
24
|
+
## Quick start
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { TelegramTokenSource, WaltClient } from '@2bad/walt'
|
|
28
|
+
|
|
29
|
+
const source = new TelegramTokenSource({ session: 'SESSION_STRING', apiId: 12345, apiHash: 'API_HASH' })
|
|
30
|
+
const client = new WaltClient({ tokenProvider: (rejected) => source.token(rejected) })
|
|
31
|
+
|
|
32
|
+
const { entries, total, fiatCurrency } = await client.portfolio()
|
|
33
|
+
console.log(entries[0], total, fiatCurrency) // { currency: 'TON', amount: '120.5', fiatValue: 381.2 } 1250.4 USD
|
|
34
|
+
await source.disconnect()
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Examples
|
|
38
|
+
|
|
39
|
+
- [Connecting](examples/connecting.md): Telegram credentials, token storage, retries and pacing
|
|
40
|
+
- [Balances](examples/balances.md): accounts, portfolio, profit and loss, staked funds
|
|
41
|
+
- [Prices](examples/prices.md): coin rates, charts and past prices
|
|
42
|
+
- [Exchange](examples/exchange.md): available pairs, quotes, exchanges and limit orders
|
|
43
|
+
- [Transactions](examples/transactions.md): history, details and reading a transaction
|
|
44
|
+
- [Errors](examples/errors.md): `WaltRequestError`, `WaltAuthError` and what is retried
|
|
45
|
+
|
|
46
|
+
A runnable script is in [examples/portfolio.ts](examples/portfolio.ts).
|
|
47
|
+
|
|
48
|
+
## API
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
new TelegramTokenSource(options: TelegramTokenSourceOptions)
|
|
52
|
+
|
|
53
|
+
type TelegramTokenSource = {
|
|
54
|
+
token(rejected?: string): Promise<string>
|
|
55
|
+
disconnect(): Promise<void>
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
new WaltClient(options: WaltClientOptions)
|
|
59
|
+
|
|
60
|
+
type WaltClient = {
|
|
61
|
+
accounts(): Promise<AccountsResponse>
|
|
62
|
+
portfolio(): Promise<Portfolio>
|
|
63
|
+
pnl(): Promise<PnlResponse>
|
|
64
|
+
portfolioHistory(dateFrom: Date | string, resolution: '1d' | '1m'): Promise<PortfolioHistory>
|
|
65
|
+
frozenBalances<T = unknown>(): Promise<T[]>
|
|
66
|
+
|
|
67
|
+
earnCampaigns(): Promise<EarnCampaignsResponse>
|
|
68
|
+
earnCampaignTransactions(campaignId: number | string, limit?: number, after?: EarnTransactionsPage): Promise<EarnTransactionsPage>
|
|
69
|
+
allEarnCampaignTransactions(campaignId: number | string, limit?: number): AsyncGenerator<EarnTransaction>
|
|
70
|
+
earnRate(from: string, to: string): Promise<EarnRate>
|
|
71
|
+
|
|
72
|
+
coins(fiatCurrency: FiatCurrency): Promise<Coin[]>
|
|
73
|
+
coinDetails(currency: string, fiatCurrency: FiatCurrency): Promise<CoinDetails>
|
|
74
|
+
charts(currency: string, fiatCurrency: FiatCurrency): Promise<Charts>
|
|
75
|
+
priceForFiatAtTime(crypto: string, fiat: FiatCurrency, amount: number | string, time: Date | string | number): Promise<PriceAtTime>
|
|
76
|
+
localCurrency(): Promise<FiatCurrency>
|
|
77
|
+
|
|
78
|
+
availableExchanges(): Promise<AvailableExchanges>
|
|
79
|
+
quote(fromCurrency: string, toCurrency: string, fromAmount: number): Promise<ExchangeQuote>
|
|
80
|
+
createExchange(request: ExchangeRequest): Promise<Exchange> // moves real money, never retried
|
|
81
|
+
|
|
82
|
+
limitOrders(options?: { status?: string[]; limit?: number }): Promise<LimitOrder[]>
|
|
83
|
+
limitOrder(id: string): Promise<LimitOrder>
|
|
84
|
+
limitOrderQuote(baseCurrency: string, side: 'BUY' | 'SELL', priceLimit: number | string, size: { amount: number | string } | { quantity: number | string }): Promise<LimitOrderQuote>
|
|
85
|
+
limitOrderBounds(baseCurrency: string): Promise<LimitOrderBounds>
|
|
86
|
+
limitOrderTokens(): Promise<LimitOrderToken[]>
|
|
87
|
+
|
|
88
|
+
transactions(limit?: number, cursor?: string): Promise<TransactionsPage>
|
|
89
|
+
accountTransactions(currency: string, limit?: number, cursor?: string): Promise<TransactionsPage>
|
|
90
|
+
allTransactions(limit?: number): AsyncGenerator<Transaction>
|
|
91
|
+
allAccountTransactions(currency: string, limit?: number): AsyncGenerator<Transaction>
|
|
92
|
+
transactionDetails(id: number | string, gateway?: TransactionGateway): Promise<TransactionDetails>
|
|
93
|
+
detailsFor(transactions: AsyncIterable<Transaction> | Iterable<Transaction>): AsyncGenerator<TransactionDetails>
|
|
94
|
+
unconfirmedTransactions<T = unknown>(limit?: number): Promise<{ transactions: T[]; size: number }>
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function normalizeTransaction(details: TransactionDetails): NormalizedTransaction
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Response fields keep the API's `snake_case`. Amounts are decimal strings, except in the exchange responses.
|
|
101
|
+
|
|
102
|
+
The API publishes no schemas. Every type was derived from real responses and is loose where a value has not been seen.
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
MIT
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
export type FiatCurrency = 'USD' | 'EUR' | 'RUB' | 'GBP' | 'UAH' | 'KZT' | 'BYN' | 'KRW' | 'ILS' | 'IDR' | 'AED' | 'GEL' | 'TWD' | 'TRY' | 'HKD' | 'INR' | 'CAD' | 'AMD' | 'AUD' | 'PLN' | 'COP' | 'BRL' | 'CHF' | 'MXN' | 'ARS' | 'SGD' | 'SAR' | 'MDL' | 'JPY' | 'RON' | 'SEK' | 'AZN' | 'RSD' | 'NOK' | 'MYR' | 'BGN' | 'EGP' | 'GTQ' | 'CLP' | 'NZD' | 'BDT' | 'KGS' | 'THB' | 'UZS' | 'UYU' | 'VND' | 'UGX' | 'KES' | 'ZAR' | 'VES' | 'ETB' | 'NGN' | 'LKR' | 'PHP' | 'PKR' | 'TJS' | 'CNY' | 'MZN' | 'SDG' | 'ZMW';
|
|
2
|
+
export type PriceAtTime = {
|
|
3
|
+
rate: string;
|
|
4
|
+
fiat_amount: string;
|
|
5
|
+
currency_from: string;
|
|
6
|
+
currency_to: string;
|
|
7
|
+
amount_from: string;
|
|
8
|
+
time: string;
|
|
9
|
+
};
|
|
10
|
+
export type AccountAddress = {
|
|
11
|
+
/** Null until the account `is_created`. */
|
|
12
|
+
address: string | null;
|
|
13
|
+
network: string;
|
|
14
|
+
network_code: string;
|
|
15
|
+
wallet_to_replace: boolean;
|
|
16
|
+
};
|
|
17
|
+
export type AccountAction = {
|
|
18
|
+
is_enabled: boolean;
|
|
19
|
+
is_popular: boolean;
|
|
20
|
+
scheduled_at: unknown;
|
|
21
|
+
};
|
|
22
|
+
export type AccountActions = {
|
|
23
|
+
deposit: AccountAction;
|
|
24
|
+
withdraw_inner: AccountAction;
|
|
25
|
+
withdraw_outer: AccountAction;
|
|
26
|
+
exchange: AccountAction;
|
|
27
|
+
p2p: AccountAction;
|
|
28
|
+
purchase: AccountAction;
|
|
29
|
+
};
|
|
30
|
+
export type Account = {
|
|
31
|
+
currency: string;
|
|
32
|
+
account_type: string;
|
|
33
|
+
/** For example `onchain`, `stock` or `etf`. */
|
|
34
|
+
category: string;
|
|
35
|
+
description: string | null;
|
|
36
|
+
market_cap: string | null;
|
|
37
|
+
rate: string;
|
|
38
|
+
absolute_rate_change: string;
|
|
39
|
+
percent_rate_change: string;
|
|
40
|
+
balance_hold: string;
|
|
41
|
+
available_balance: string;
|
|
42
|
+
available_balance_usd_amount: string;
|
|
43
|
+
available_balance_fiat_amount: string;
|
|
44
|
+
available_balance_fiat_currency: string;
|
|
45
|
+
addresses: AccountAddress[];
|
|
46
|
+
actions: AccountActions;
|
|
47
|
+
is_created: boolean;
|
|
48
|
+
is_always_on_main: boolean;
|
|
49
|
+
is_new_currency: boolean;
|
|
50
|
+
has_transactions: boolean;
|
|
51
|
+
};
|
|
52
|
+
export type AccountsResponse = {
|
|
53
|
+
available_balance_total_fiat_amount: string;
|
|
54
|
+
available_balance_total_fiat_currency: string;
|
|
55
|
+
accounts: Account[];
|
|
56
|
+
};
|
|
57
|
+
export type Coin = {
|
|
58
|
+
currency: string;
|
|
59
|
+
fiat_currency: string;
|
|
60
|
+
networks: string[];
|
|
61
|
+
category: string;
|
|
62
|
+
rate: string;
|
|
63
|
+
rate_change_24h_percent: string;
|
|
64
|
+
volume24h: string | null;
|
|
65
|
+
};
|
|
66
|
+
export type TradingHoursPeriod = {
|
|
67
|
+
mode: string;
|
|
68
|
+
start_at: string;
|
|
69
|
+
end_at: string;
|
|
70
|
+
};
|
|
71
|
+
export type TradingHoursState = TradingHoursPeriod & {
|
|
72
|
+
next_mode: string;
|
|
73
|
+
schedule: TradingHoursPeriod[];
|
|
74
|
+
};
|
|
75
|
+
export type CoinDetails = {
|
|
76
|
+
currency: string;
|
|
77
|
+
fiat_currency: string;
|
|
78
|
+
category: string;
|
|
79
|
+
description: string;
|
|
80
|
+
networks: string[];
|
|
81
|
+
rate: string;
|
|
82
|
+
rate_change_24h_percent: string;
|
|
83
|
+
rate_change_24h_absolute: string;
|
|
84
|
+
volume24h: string | null;
|
|
85
|
+
volume24h_change_24h_percent: string | null;
|
|
86
|
+
market_cap: string | null;
|
|
87
|
+
market_cap_change_24h_percent: string | null;
|
|
88
|
+
total_supply: string | null;
|
|
89
|
+
circulating_supply: string | null;
|
|
90
|
+
chart_preview_rate_24h: {
|
|
91
|
+
timestamp: number;
|
|
92
|
+
value: string;
|
|
93
|
+
}[];
|
|
94
|
+
trading_hours_state: TradingHoursState | null;
|
|
95
|
+
mira_summary: {
|
|
96
|
+
summary: string;
|
|
97
|
+
bot_url: string;
|
|
98
|
+
updated_at: string;
|
|
99
|
+
} | null;
|
|
100
|
+
};
|
|
101
|
+
export type ChartPoint = {
|
|
102
|
+
rate: string;
|
|
103
|
+
timestamp: number;
|
|
104
|
+
};
|
|
105
|
+
export type Charts = {
|
|
106
|
+
day: ChartPoint[];
|
|
107
|
+
week: ChartPoint[];
|
|
108
|
+
month: ChartPoint[];
|
|
109
|
+
year: ChartPoint[];
|
|
110
|
+
all: ChartPoint[];
|
|
111
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export type PnlPosition = {
|
|
2
|
+
currency: string;
|
|
3
|
+
fiat_currency: string;
|
|
4
|
+
/** Cost basis, not current value; add `absolute_all_time` for that. */
|
|
5
|
+
current_value_in_fiat: string;
|
|
6
|
+
absolute_24h: string;
|
|
7
|
+
percentage_24h: string;
|
|
8
|
+
absolute_all_time: string;
|
|
9
|
+
percentage_all_time: string;
|
|
10
|
+
account_type: string;
|
|
11
|
+
earn_campaign_name: string | null;
|
|
12
|
+
};
|
|
13
|
+
export type PnlTotals = {
|
|
14
|
+
fiat_currency: string;
|
|
15
|
+
/** Cost basis, not current value; add `absolute_all_time` for that. */
|
|
16
|
+
current_value_in_fiat: string;
|
|
17
|
+
absolute_24h: string;
|
|
18
|
+
percentage_24h: string;
|
|
19
|
+
absolute_all_time: string;
|
|
20
|
+
percentage_all_time: string;
|
|
21
|
+
};
|
|
22
|
+
export type PnlResponse = {
|
|
23
|
+
positions: PnlPosition[];
|
|
24
|
+
total: PnlTotals;
|
|
25
|
+
};
|
|
26
|
+
export type PortfolioFlows = {
|
|
27
|
+
total: string;
|
|
28
|
+
crypto_transfer: string;
|
|
29
|
+
transfer: string;
|
|
30
|
+
p2p: string;
|
|
31
|
+
on_ramp: string;
|
|
32
|
+
off_ramp: string;
|
|
33
|
+
earn: string;
|
|
34
|
+
gift: string;
|
|
35
|
+
wpay: string;
|
|
36
|
+
trading_agent: string;
|
|
37
|
+
other: string;
|
|
38
|
+
};
|
|
39
|
+
/** Fiat amounts over one period. */
|
|
40
|
+
export type PortfolioPeriod = {
|
|
41
|
+
date_from: string;
|
|
42
|
+
date_to: string;
|
|
43
|
+
open_balance_fiat: string;
|
|
44
|
+
close_amount_fiat: string;
|
|
45
|
+
total_pnl: string;
|
|
46
|
+
total_pnl_percent: string | null;
|
|
47
|
+
realized_pnl_details: {
|
|
48
|
+
total: string;
|
|
49
|
+
total_percent: string | null;
|
|
50
|
+
spot: string;
|
|
51
|
+
perps: string;
|
|
52
|
+
earns: string;
|
|
53
|
+
};
|
|
54
|
+
unrealized_pnl_details: {
|
|
55
|
+
total: string;
|
|
56
|
+
total_percent: string | null;
|
|
57
|
+
};
|
|
58
|
+
deposits_details: PortfolioFlows;
|
|
59
|
+
withdrawals_details: PortfolioFlows;
|
|
60
|
+
};
|
|
61
|
+
export type PortfolioHistory = {
|
|
62
|
+
fiat_currency: string;
|
|
63
|
+
chart: {
|
|
64
|
+
data_points: PortfolioPeriod[];
|
|
65
|
+
};
|
|
66
|
+
total_period_details: PortfolioPeriod;
|
|
67
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
export type EarnAccount = {
|
|
2
|
+
account_id: number;
|
|
3
|
+
/** Units staked in this campaign, absent from `accounts()`. */
|
|
4
|
+
balance: string;
|
|
5
|
+
paid_out_amount: string;
|
|
6
|
+
currency: string;
|
|
7
|
+
created_at: string;
|
|
8
|
+
max_withdraw_amount: unknown;
|
|
9
|
+
pending_withdraw_deadline_at: unknown;
|
|
10
|
+
};
|
|
11
|
+
export type EarnAccessPolicy = {
|
|
12
|
+
access_to_deposit: boolean;
|
|
13
|
+
access_to_withdrawal: boolean;
|
|
14
|
+
access_to_full_withdrawal: boolean;
|
|
15
|
+
deposit_restriction_reason: unknown;
|
|
16
|
+
};
|
|
17
|
+
export type EarnBonus = {
|
|
18
|
+
account_id: number | null;
|
|
19
|
+
name: string;
|
|
20
|
+
status: string;
|
|
21
|
+
apy: string;
|
|
22
|
+
combined_apy: string;
|
|
23
|
+
max_amount: string;
|
|
24
|
+
paid_out_amount: string;
|
|
25
|
+
duration: number | null;
|
|
26
|
+
end_at: string | null;
|
|
27
|
+
};
|
|
28
|
+
export type EarnInterestRate = {
|
|
29
|
+
rate: string;
|
|
30
|
+
interest_type: string;
|
|
31
|
+
combined_rate: string;
|
|
32
|
+
effective_rate: string;
|
|
33
|
+
bonus_rate: string | null;
|
|
34
|
+
};
|
|
35
|
+
export type EarnPayoutPool = {
|
|
36
|
+
total: string;
|
|
37
|
+
available: string;
|
|
38
|
+
};
|
|
39
|
+
export type EarnAmount = {
|
|
40
|
+
amount: string;
|
|
41
|
+
currency: string;
|
|
42
|
+
};
|
|
43
|
+
export type EarnCampaign = {
|
|
44
|
+
campaign_id: number;
|
|
45
|
+
/** Matches `PnlPosition.earn_campaign_name`. */
|
|
46
|
+
name: string;
|
|
47
|
+
status: string;
|
|
48
|
+
/** Null unless the campaign was joined. */
|
|
49
|
+
account: EarnAccount | null;
|
|
50
|
+
apy_type: string;
|
|
51
|
+
current_apy: string;
|
|
52
|
+
effective_apy: string | null;
|
|
53
|
+
interest_rate: EarnInterestRate;
|
|
54
|
+
bonus: EarnBonus | null;
|
|
55
|
+
access_policy: EarnAccessPolicy;
|
|
56
|
+
payout_pool: EarnPayoutPool | null;
|
|
57
|
+
total_earned: EarnAmount | null;
|
|
58
|
+
payout_type: string;
|
|
59
|
+
payout_account_type: string;
|
|
60
|
+
payout_interval: number;
|
|
61
|
+
payout_account: unknown;
|
|
62
|
+
input_currency: string;
|
|
63
|
+
deposit_currency: string;
|
|
64
|
+
payout_currency: string;
|
|
65
|
+
deposit_withdraw_currency: string;
|
|
66
|
+
payout_withdraw_currency: string;
|
|
67
|
+
min_amount: string;
|
|
68
|
+
max_amount: string | null;
|
|
69
|
+
min_deposit_amount: string;
|
|
70
|
+
min_withdraw_amount: string | null;
|
|
71
|
+
last_24hours_paid_out_amount: string | null;
|
|
72
|
+
start_at: string;
|
|
73
|
+
end_at: string | null;
|
|
74
|
+
terms_and_conditions: boolean;
|
|
75
|
+
is_deposit_limit_exceeded: boolean;
|
|
76
|
+
};
|
|
77
|
+
export type EarnCampaignsResponse = {
|
|
78
|
+
campaigns: EarnCampaign[];
|
|
79
|
+
required_kyc_level: string;
|
|
80
|
+
ab_tests: Record<string, unknown>;
|
|
81
|
+
tooltip_campaign_id: number | null;
|
|
82
|
+
total_participants: number;
|
|
83
|
+
};
|
|
84
|
+
export type EarnTransaction = {
|
|
85
|
+
id: number;
|
|
86
|
+
transaction_type: string;
|
|
87
|
+
direction: string;
|
|
88
|
+
status: string;
|
|
89
|
+
source: string;
|
|
90
|
+
amount: string;
|
|
91
|
+
currency: string;
|
|
92
|
+
date: string;
|
|
93
|
+
transfer_id: string;
|
|
94
|
+
idempotency_key: string;
|
|
95
|
+
deadline_at: unknown;
|
|
96
|
+
pending_reason: unknown;
|
|
97
|
+
};
|
|
98
|
+
export type EarnTransactionsPage = {
|
|
99
|
+
transactions: EarnTransaction[];
|
|
100
|
+
deposit_acc_next_from: number | null;
|
|
101
|
+
payout_acc_next_from: number | null;
|
|
102
|
+
transfer_request_next_before_datetime: string | null;
|
|
103
|
+
};
|
|
104
|
+
export type EarnDepegInfo = {
|
|
105
|
+
depeg_state: string;
|
|
106
|
+
depeg: number;
|
|
107
|
+
currency: string;
|
|
108
|
+
reference_currency: string;
|
|
109
|
+
};
|
|
110
|
+
export type EarnRate = {
|
|
111
|
+
rate: string;
|
|
112
|
+
depeg_info: EarnDepegInfo | null;
|
|
113
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { FiatCurrency } from "./accounts.js";
|
|
2
|
+
/** Each exchangeable currency mapped to its counterparts. Pairs appear in both directions. */
|
|
3
|
+
export type AvailableExchanges = Record<string, string[]>;
|
|
4
|
+
/**
|
|
5
|
+
* Amounts are numbers, not decimal strings. `min_amount` and `max_amount` bound `from_amount`;
|
|
6
|
+
* `max_amount` is the balance when selling and the platform limit when buying.
|
|
7
|
+
*/
|
|
8
|
+
export type ExchangeQuote = {
|
|
9
|
+
from_amount: number;
|
|
10
|
+
from_currency: string;
|
|
11
|
+
to_amount: number;
|
|
12
|
+
to_currency: string;
|
|
13
|
+
rate: number;
|
|
14
|
+
min_amount: number;
|
|
15
|
+
max_amount: number;
|
|
16
|
+
};
|
|
17
|
+
export type ExchangeRequest = {
|
|
18
|
+
from_currency: string;
|
|
19
|
+
to_currency: string;
|
|
20
|
+
from_amount: number;
|
|
21
|
+
local_currency: FiatCurrency;
|
|
22
|
+
/** Set when `from_amount` is the whole balance. */
|
|
23
|
+
max_amount?: boolean;
|
|
24
|
+
};
|
|
25
|
+
/** `ttl` is in seconds. */
|
|
26
|
+
export type Exchange = {
|
|
27
|
+
uid: string;
|
|
28
|
+
transfer_id: string;
|
|
29
|
+
ttl: number;
|
|
30
|
+
from_amount: number;
|
|
31
|
+
from_balance_after: number;
|
|
32
|
+
from_currency: string;
|
|
33
|
+
to_amount: number;
|
|
34
|
+
to_balance_after: number;
|
|
35
|
+
to_currency: string;
|
|
36
|
+
from_fiat_amount: number;
|
|
37
|
+
from_fiat_currency: string;
|
|
38
|
+
to_fiat_amount: number;
|
|
39
|
+
to_fiat_currency: string;
|
|
40
|
+
rate: number;
|
|
41
|
+
fee_amount: number;
|
|
42
|
+
fee_currency: string;
|
|
43
|
+
fee_fiat_amount: number;
|
|
44
|
+
fee_fiat_currency: string;
|
|
45
|
+
new_rates: boolean;
|
|
46
|
+
non_promo_fee_amount: unknown;
|
|
47
|
+
non_promo_fee_currency: unknown;
|
|
48
|
+
promo_fee: unknown;
|
|
49
|
+
max_amount: boolean;
|
|
50
|
+
price_deviation_percent: string;
|
|
51
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export type LimitOrder = {
|
|
2
|
+
id: string;
|
|
3
|
+
client_order_id: string;
|
|
4
|
+
base_currency: string;
|
|
5
|
+
side: string;
|
|
6
|
+
/** `LIMIT`, or `TP` and `SL` for take-profit and stop-loss orders. */
|
|
7
|
+
type: string;
|
|
8
|
+
price_limit: string;
|
|
9
|
+
quantity: string;
|
|
10
|
+
multiplier: string;
|
|
11
|
+
spv_price_limit: string;
|
|
12
|
+
spv_quantity: string;
|
|
13
|
+
fee: string;
|
|
14
|
+
fee_currency: string;
|
|
15
|
+
total: string;
|
|
16
|
+
/** For example `OPEN`, `CANCELLING`, `CANCELLED` or `FILLED`. */
|
|
17
|
+
status: string;
|
|
18
|
+
created_at: string;
|
|
19
|
+
updated_at: string;
|
|
20
|
+
/** Only on filled orders. */
|
|
21
|
+
executed_at?: string;
|
|
22
|
+
/** Only on filled orders. */
|
|
23
|
+
execution?: {
|
|
24
|
+
filled_quantity: string;
|
|
25
|
+
filled_quote_amount: string;
|
|
26
|
+
price: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export type LimitOrderQuote = {
|
|
30
|
+
base_currency: string;
|
|
31
|
+
side: string;
|
|
32
|
+
price_limit: string;
|
|
33
|
+
quantity: string;
|
|
34
|
+
multiplier: string;
|
|
35
|
+
spv_price_limit: string;
|
|
36
|
+
spv_quantity: string;
|
|
37
|
+
notional: string;
|
|
38
|
+
fee: string;
|
|
39
|
+
fee_currency: string;
|
|
40
|
+
total: string;
|
|
41
|
+
fee_discount: {
|
|
42
|
+
kind: string;
|
|
43
|
+
regular_amount: string;
|
|
44
|
+
reason: string;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
export type LimitOrderBounds = {
|
|
48
|
+
base_currency: string;
|
|
49
|
+
price: string;
|
|
50
|
+
max_price_limit: string;
|
|
51
|
+
take_profit_min_price: string;
|
|
52
|
+
stop_loss_max_price: string;
|
|
53
|
+
price_decimals: number;
|
|
54
|
+
updated_at: string;
|
|
55
|
+
};
|
|
56
|
+
export type LimitOrderToken = {
|
|
57
|
+
code: string;
|
|
58
|
+
/** Smallest order, in USDT. */
|
|
59
|
+
min_limit: string;
|
|
60
|
+
max_limit: string;
|
|
61
|
+
quantity_decimals: number;
|
|
62
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export type TransactionGateway = 'card' | 'purchase' | 'internal' | 'btc' | 'manual' | 'crypto_exchange' | 'tg_transfer' | 'binance' | 'top_up' | 'withdraw_onchain' | 'fireblocks' | 'single_use' | 'multi_use' | 'part_multi_use' | 'p2p_order' | 'p2p_order_inactive_offer' | 'p2p_offer' | 'p2p_refund' | 'p2p_security_deposit' | 'p2p_security_deposit_seizure' | 'wpay_payment' | 'wpay_payout' | 'payouts' | 'bonus_any' | 'onboarding_incentive' | 'giveaway' | 'earn' | 'earn_reward' | 'earn_v2' | 'earn_v2_reward' | 'earn_v2_bonus' | 'earn_v2_crypto_exchange' | 'forced_transfer' | 'tg_transfer_onchain' | 'onramp' | 'offramp' | 'xstocks_dividends' | 'perps' | 'perps_pnl' | 'perps_fee' | 'perps_liquidation_fee' | 'perps_fundings' | 'perps_open_hold_shortfall' | 'perps_margin' | 'perps_bbook_insurance' | 'perps_bbook_reserve' | 'perps_resize_position' | 'unconfirmed_deposit' | 'loyalty_incentive' | 'compensation' | 'tg_stars_purchase' | 'ipo' | 'ipo_allocation' | 'loyalty_payout' | 'crypto_card_cashback' | 'affiliate_payout' | 'limit_swap' | 'payment_link' | 'bot_banking';
|
|
2
|
+
export type Transaction = {
|
|
3
|
+
id: number;
|
|
4
|
+
type: string;
|
|
5
|
+
created_at: string;
|
|
6
|
+
amount: string;
|
|
7
|
+
currency: string;
|
|
8
|
+
status: string;
|
|
9
|
+
gateway: string;
|
|
10
|
+
is_blocked: boolean;
|
|
11
|
+
username: string | null;
|
|
12
|
+
tg_id: number | null;
|
|
13
|
+
input_addresses: string | null;
|
|
14
|
+
recipient_wallet_address: string | null;
|
|
15
|
+
photo_url: string | null;
|
|
16
|
+
pair_transaction_currency: string | null;
|
|
17
|
+
network: string | null;
|
|
18
|
+
block_reason: string | null;
|
|
19
|
+
crypto_tx_id: string | null;
|
|
20
|
+
gateway_details: unknown;
|
|
21
|
+
};
|
|
22
|
+
export type TransactionsPage = {
|
|
23
|
+
transactions: Transaction[];
|
|
24
|
+
limit: number;
|
|
25
|
+
size: number;
|
|
26
|
+
next_cursor: string | null;
|
|
27
|
+
};
|
|
28
|
+
export type TransactionDetails = {
|
|
29
|
+
id: number;
|
|
30
|
+
type: string;
|
|
31
|
+
created_at: string;
|
|
32
|
+
status: string;
|
|
33
|
+
gateway: string;
|
|
34
|
+
crypto_amount: string;
|
|
35
|
+
crypto_currency: string;
|
|
36
|
+
/** Null when the transaction was never priced. */
|
|
37
|
+
local_fiat_amount: string | null;
|
|
38
|
+
local_fiat_amount_now: string;
|
|
39
|
+
local_currency: string;
|
|
40
|
+
fee_amount: string | null;
|
|
41
|
+
fee_currency: string | null;
|
|
42
|
+
exchange_rate: string | null;
|
|
43
|
+
pair_transaction_amount: string | null;
|
|
44
|
+
pair_transaction_currency: string | null;
|
|
45
|
+
username: string | null;
|
|
46
|
+
tg_id: number | null;
|
|
47
|
+
transfer_id: string | null;
|
|
48
|
+
tg_transfer_status: string | null;
|
|
49
|
+
payment_link_id: string | null;
|
|
50
|
+
mention: string | null;
|
|
51
|
+
comment: string | null;
|
|
52
|
+
input_addresses: string | null;
|
|
53
|
+
recipient_wallet_address: string | null;
|
|
54
|
+
network: string | null;
|
|
55
|
+
crypto_tx_id: string | null;
|
|
56
|
+
/** Block explorer url for `crypto_tx_id`. */
|
|
57
|
+
transaction_link: string | null;
|
|
58
|
+
photo_url: string | null;
|
|
59
|
+
gateway_details: unknown;
|
|
60
|
+
is_blocked: boolean;
|
|
61
|
+
is_cancellable: boolean;
|
|
62
|
+
block_reason: string | null;
|
|
63
|
+
};
|
|
64
|
+
export type TransactionLeg = {
|
|
65
|
+
currency: string;
|
|
66
|
+
amount: string;
|
|
67
|
+
};
|
|
68
|
+
export type NormalizedTransaction = {
|
|
69
|
+
id: number;
|
|
70
|
+
createdAt: string;
|
|
71
|
+
gateway: string;
|
|
72
|
+
status: string;
|
|
73
|
+
received: TransactionLeg | null;
|
|
74
|
+
sent: TransactionLeg | null;
|
|
75
|
+
/** Already deducted from the legs; reporting only. */
|
|
76
|
+
fee: TransactionLeg | null;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Splits a `transactionDetails()` record into what entered the wallet, what left it, and the fee.
|
|
80
|
+
* A `deposit` of USDT paired with BTC is a sale of BTC. Listing rows lack `pair_transaction_amount`,
|
|
81
|
+
* so they cannot be normalised.
|
|
82
|
+
*
|
|
83
|
+
* @param details - A `transactionDetails()` record.
|
|
84
|
+
*/
|
|
85
|
+
export declare const normalizeTransaction: (details: TransactionDetails) => NormalizedTransaction;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// source/api/transactions.ts
|
|
2
|
+
/**
|
|
3
|
+
* Splits a `transactionDetails()` record into what entered the wallet, what left it, and the fee.
|
|
4
|
+
* A `deposit` of USDT paired with BTC is a sale of BTC. Listing rows lack `pair_transaction_amount`,
|
|
5
|
+
* so they cannot be normalised.
|
|
6
|
+
*
|
|
7
|
+
* @param details - A `transactionDetails()` record.
|
|
8
|
+
*/
|
|
9
|
+
const normalizeTransaction = (details) => {
|
|
10
|
+
const main = {
|
|
11
|
+
currency: details.crypto_currency,
|
|
12
|
+
amount: details.crypto_amount
|
|
13
|
+
};
|
|
14
|
+
const pair = details.pair_transaction_currency !== null && details.pair_transaction_amount !== null && details.pair_transaction_currency !== details.crypto_currency ? {
|
|
15
|
+
currency: details.pair_transaction_currency,
|
|
16
|
+
amount: details.pair_transaction_amount
|
|
17
|
+
} : null;
|
|
18
|
+
const inbound = details.type === "deposit";
|
|
19
|
+
return {
|
|
20
|
+
id: details.id,
|
|
21
|
+
createdAt: details.created_at,
|
|
22
|
+
gateway: details.gateway,
|
|
23
|
+
status: details.status,
|
|
24
|
+
received: inbound ? main : pair,
|
|
25
|
+
sent: inbound ? pair : main,
|
|
26
|
+
fee: details.fee_currency !== null && details.fee_amount !== null && Number(details.fee_amount) > 0 ? {
|
|
27
|
+
currency: details.fee_currency,
|
|
28
|
+
amount: details.fee_amount
|
|
29
|
+
} : null
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export { normalizeTransaction };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|