squarefi-bff-api-module 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/README.md +36 -0
- package/dist/api/auth.d.ts +27 -0
- package/dist/api/auth.js +38 -0
- package/dist/api/config.d.ts +37 -0
- package/dist/api/config.js +40 -0
- package/dist/api/developer.d.ts +12 -0
- package/dist/api/developer.js +15 -0
- package/dist/api/exchange.d.ts +35 -0
- package/dist/api/exchange.js +27 -0
- package/dist/api/fetch_api.d.ts +1 -0
- package/dist/api/fetch_api.js +122 -0
- package/dist/api/fiat_accounts.d.ts +32 -0
- package/dist/api/fiat_accounts.js +51 -0
- package/dist/api/index.d.ts +12 -0
- package/dist/api/index.js +17 -0
- package/dist/api/issuing.d.ts +31 -0
- package/dist/api/issuing.js +68 -0
- package/dist/api/kyc.d.ts +6 -0
- package/dist/api/kyc.js +9 -0
- package/dist/api/list.d.ts +10 -0
- package/dist/api/list.js +13 -0
- package/dist/api/orders.d.ts +12 -0
- package/dist/api/orders.js +34 -0
- package/dist/api/types.d.ts +945 -0
- package/dist/api/types.js +2 -0
- package/dist/api/user.d.ts +18 -0
- package/dist/api/user.js +21 -0
- package/dist/api/wallets.d.ts +18 -0
- package/dist/api/wallets.js +42 -0
- package/dist/constants.d.ts +149 -0
- package/dist/constants.js +172 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +22 -0
- package/dist/utils/apiClientFactory.d.ts +13 -0
- package/dist/utils/apiClientFactory.js +132 -0
- package/dist/utils/storage.d.ts +3 -0
- package/dist/utils/storage.js +30 -0
- package/dist/utils/tokensFactory.d.ts +12 -0
- package/dist/utils/tokensFactory.js +53 -0
- package/package.json +35 -0
- package/src/api/auth.ts +50 -0
- package/src/api/developer.ts +18 -0
- package/src/api/exchange.ts +32 -0
- package/src/api/fiat_accounts.ts +69 -0
- package/src/api/index.ts +16 -0
- package/src/api/issuing.ts +66 -0
- package/src/api/kyc.ts +10 -0
- package/src/api/list.ts +18 -0
- package/src/api/orders.ts +32 -0
- package/src/api/types.ts +1141 -0
- package/src/api/user.ts +24 -0
- package/src/api/wallets.ts +39 -0
- package/src/constants.ts +180 -0
- package/src/index.ts +7 -0
- package/src/utils/apiClientFactory.ts +154 -0
- package/src/utils/storage.ts +29 -0
- package/src/utils/tokensFactory.ts +50 -0
- package/tsconfig.json +15 -0
package/src/api/user.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { API } from './types';
|
|
2
|
+
|
|
3
|
+
import { apiClientV2 } from '.';
|
|
4
|
+
|
|
5
|
+
export const user = {
|
|
6
|
+
get: () => apiClientV2.getRequest<API.User.User>('/user'),
|
|
7
|
+
userData: {
|
|
8
|
+
get: () => apiClientV2.getRequest<API.User.UserData.UserData>('/user/user-data'),
|
|
9
|
+
update: (data: API.User.UserData.UpdateUserData.Request) =>
|
|
10
|
+
apiClientV2.patchRequest<API.User.UserData.UpdateUserData.Response>('/user/user-data', { data }),
|
|
11
|
+
},
|
|
12
|
+
update: {
|
|
13
|
+
phone: {
|
|
14
|
+
request: (data: API.User.UpdateUser.Phone.RequestOTP.Request) =>
|
|
15
|
+
apiClientV2.patchRequest('/user/phone', { data }),
|
|
16
|
+
confirm: (data: API.User.UpdateUser.Phone.Confirm.Request) => apiClientV2.postRequest('/user/phone', { data }),
|
|
17
|
+
},
|
|
18
|
+
email: {
|
|
19
|
+
request: (data: API.User.UpdateUser.Email.RequestOTP.Request) =>
|
|
20
|
+
apiClientV2.patchRequest('/user/email', { data }),
|
|
21
|
+
confirm: (data: API.User.UpdateUser.Email.Confirm.Request) => apiClientV2.postRequest('/user/email', { data }),
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { API } from './types';
|
|
2
|
+
|
|
3
|
+
import { apiClientV2 } from '.';
|
|
4
|
+
|
|
5
|
+
import { defaultPaginationParams, WalletTypeValues } from '../constants';
|
|
6
|
+
|
|
7
|
+
export const wallets = {
|
|
8
|
+
create: (type: WalletTypeValues) => apiClientV2.postRequest('/wallets', { data: { type } }).then(({ data }) => data),
|
|
9
|
+
getAll: () => apiClientV2.getRequest<API.Wallets.WalletsList.Response>('/wallets').then(({ data }) => data),
|
|
10
|
+
getByUuid: (uuid: string) => apiClientV2.getRequest<API.Wallets.Wallet>(`/wallets/${uuid}`).then(({ data }) => data),
|
|
11
|
+
addresses: {
|
|
12
|
+
create: ({ wallet_uuid, chain, label }: API.Wallets.WalletChain.Create.Request) =>
|
|
13
|
+
apiClientV2
|
|
14
|
+
.postRequest<API.Wallets.WalletChain.Create.Response>(`/wallets/${wallet_uuid}/addresses/${chain}`, {
|
|
15
|
+
data: { label },
|
|
16
|
+
})
|
|
17
|
+
.then(({ data }) => data),
|
|
18
|
+
get: {
|
|
19
|
+
byWalletUuid: {
|
|
20
|
+
byChainId: (wallet_uuid: string, chain_id: number) =>
|
|
21
|
+
apiClientV2
|
|
22
|
+
.getRequest<API.Wallets.WalletChain.WalletChain>(`/wallets/${wallet_uuid}/addresses/${chain_id}`)
|
|
23
|
+
.then(({ data }) => data),
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
transactions: {
|
|
28
|
+
getByWalletUuid: async (
|
|
29
|
+
wallet_uuid: string,
|
|
30
|
+
limit = defaultPaginationParams.limit,
|
|
31
|
+
offset = defaultPaginationParams.offset
|
|
32
|
+
) =>
|
|
33
|
+
apiClientV2
|
|
34
|
+
.getRequest<API.Wallets.WalletTransactions.TransactionList.Response>(`/wallets/${wallet_uuid}/transactions`, {
|
|
35
|
+
params: { limit, offset },
|
|
36
|
+
})
|
|
37
|
+
.then(({ data }) => data),
|
|
38
|
+
},
|
|
39
|
+
};
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
export type ValueWithLabel = {
|
|
2
|
+
value: string;
|
|
3
|
+
label: string;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export type WalletType = {
|
|
7
|
+
[key: string]: ValueWithLabel;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const falsyValues = ['false', '0', '', 'FALSE', false, null, undefined, NaN, 0];
|
|
11
|
+
|
|
12
|
+
export enum AppEnviroment {
|
|
13
|
+
WEB = 'web',
|
|
14
|
+
TELEGRAM = 'telegram',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export enum CardFormFactor {
|
|
18
|
+
VIRTUAL = 'VIRTUAL',
|
|
19
|
+
PHYSICAL = 'PHYSICAL',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export enum CardType {
|
|
23
|
+
CREDIT = 'CREDIT',
|
|
24
|
+
DEBIT = 'DEBIT',
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export enum CardTransactionType {
|
|
28
|
+
AUTHORIZATION = 'AUTHORIZATION',
|
|
29
|
+
CLEARING = 'CLEARING',
|
|
30
|
+
REFUND = 'REFUND',
|
|
31
|
+
REVERSAL = 'REVERSAL',
|
|
32
|
+
ORIGINAL_CREDIT = 'ORIGINAL_CREDIT',
|
|
33
|
+
FEE = 'FEE',
|
|
34
|
+
DEPOSIT = 'DEPOSIT',
|
|
35
|
+
WITHDRAWAL = 'WITHDRAWAL',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export enum WalletTransactionType {
|
|
39
|
+
DEPOSIT = 'deposit',
|
|
40
|
+
WITHDRAWAL = 'withdrawal',
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export enum WalletTransactionMethod {
|
|
44
|
+
P2P = 'p2p',
|
|
45
|
+
CRYPTO = 'crypto',
|
|
46
|
+
BANK_TRANSFER = 'bank_transfer',
|
|
47
|
+
EXCHANGE = 'exchange',
|
|
48
|
+
SBP = 'sbp',
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export enum WalletTransactionRecordType {
|
|
52
|
+
CARD_PROVIDER_DEPOSIT = 'CARD_PROVIDER_DEPOSIT',
|
|
53
|
+
CARD_PROVIDER_REFUND = 'CARD_PROVIDER_REFUND',
|
|
54
|
+
DEPOSIT = 'DEPOSIT',
|
|
55
|
+
DEPOSIT_CRYPTO_EXTERNAL = 'DEPOSIT_CRYPTO_EXTERNAL',
|
|
56
|
+
DEPOSIT_CRYPTO_INTERNAL = 'DEPOSIT_CRYPTO_INTERNAL',
|
|
57
|
+
EXCHANGE_CRYPTO_INTERNAL = 'EXCHANGE_CRYPTO_INTERNAL',
|
|
58
|
+
EXT_EXCHANGE = 'EXT_EXCHANGE',
|
|
59
|
+
FEE = 'FEE',
|
|
60
|
+
NETWORK_FEE = 'NETWORK_FEE',
|
|
61
|
+
REFUND = 'REFUND',
|
|
62
|
+
WITHDRAWAL = 'WITHDRAWAL',
|
|
63
|
+
WITHDRAWAL_CRYPTO_EXTERNAL = 'WITHDRAWAL_CRYPTO_EXTERNAL',
|
|
64
|
+
WITHDRAWAL_CRYPTO_INTERNAL = 'WITHDRAWAL_CRYPTO_INTERNAL',
|
|
65
|
+
WHOLESALE_CARD_DEPOSIT = 'WHOLESALE_CARD_DEPOSIT',
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export enum RequestStatus {
|
|
69
|
+
NONE = 'none',
|
|
70
|
+
PENDING = 'pending',
|
|
71
|
+
FULLFILLED = 'fulfilled',
|
|
72
|
+
REJECTED = 'rejected',
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export enum RequestLoadingType {
|
|
76
|
+
NORMAL = 'normal',
|
|
77
|
+
TRANSPARENT = 'transparent',
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export enum ResponseStatus {
|
|
81
|
+
BAD_REQUEST = 400,
|
|
82
|
+
UNAUTHORIZED = 401,
|
|
83
|
+
FORBIDDEN = 403,
|
|
84
|
+
NOT_FOUND = 404,
|
|
85
|
+
VERIFICATION_EXPIRED = 419,
|
|
86
|
+
UNPROCESSABLE_ENTITY = 422,
|
|
87
|
+
USER_BLOCKED = 423,
|
|
88
|
+
SERVER_ERROR = 500,
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export enum WalletTypeValues {
|
|
92
|
+
BUSINESS = 'business',
|
|
93
|
+
PERSONAL = 'personal',
|
|
94
|
+
P2P = 'trading',
|
|
95
|
+
ESCROW = 'escrow',
|
|
96
|
+
MERCHANT = 'merchant',
|
|
97
|
+
EXCHANGE = 'exchange',
|
|
98
|
+
STAKING = 'staking',
|
|
99
|
+
VAULT = 'vault',
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export const walletType: WalletType = {
|
|
103
|
+
personal: { value: WalletTypeValues.PERSONAL, label: 'Personal' },
|
|
104
|
+
p2p: { value: 'p2p', label: 'P2P' },
|
|
105
|
+
escrow: { value: WalletTypeValues.ESCROW, label: 'Escrow' },
|
|
106
|
+
merchant: { value: WalletTypeValues.MERCHANT, label: 'Merchant' },
|
|
107
|
+
exchange: { value: WalletTypeValues.EXCHANGE, label: 'Exchange' },
|
|
108
|
+
staking: { value: WalletTypeValues.STAKING, label: 'Staking' },
|
|
109
|
+
vault: { value: WalletTypeValues.VAULT, label: 'Vault' },
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export const defaultPaginationParams = {
|
|
113
|
+
limit: 10,
|
|
114
|
+
offset: 0,
|
|
115
|
+
isLastPage: true,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export enum KYCStatuses {
|
|
119
|
+
APPROVED = 'APPROVED',
|
|
120
|
+
DECLINED = 'DECLINED',
|
|
121
|
+
PENDING = 'PENDING',
|
|
122
|
+
HOLD = 'HOLD',
|
|
123
|
+
DOUBLE = 'DOUBLE',
|
|
124
|
+
SOFT_REJECT = 'SOFT_REJECT',
|
|
125
|
+
REJECT = 'REJECT',
|
|
126
|
+
UNVERIFIED = 'UNVERIFIED',
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export enum OrderStatuses {
|
|
130
|
+
NEW = 'NEW',
|
|
131
|
+
PENDING = 'PENDING',
|
|
132
|
+
CANCELED = 'CANCELED',
|
|
133
|
+
COMPLETE = 'COMPLETE',
|
|
134
|
+
ERROR = 'ERROR',
|
|
135
|
+
FAILED = 'FAILED',
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export enum CardStatus {
|
|
139
|
+
ACTIVE = 'ACTIVE',
|
|
140
|
+
FROZEN = 'FROZEN',
|
|
141
|
+
BLOCKED = 'BLOCKED',
|
|
142
|
+
INACTIVE = 'INACTIVE',
|
|
143
|
+
CANCELED = 'CANCELED',
|
|
144
|
+
CLOSED = 'CLOSED',
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export enum FiatAccountStatus {
|
|
148
|
+
ACTIVE = 'ACTIVE',
|
|
149
|
+
BLOCKED = 'BLOCKED',
|
|
150
|
+
INACTIVE = 'INACTIVE',
|
|
151
|
+
CANCELED = 'CANCELED',
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export enum SubAccountType {
|
|
155
|
+
PREPAID = 'prepaid',
|
|
156
|
+
BALANCE = 'balance',
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export enum CurrencyType {
|
|
160
|
+
TOKEN = 'token',
|
|
161
|
+
NATIVE = 'native',
|
|
162
|
+
FIAT = 'fiat',
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export enum OrderType {
|
|
166
|
+
DEPOSIT_FIAT_SEPA = 'DEPOSIT_FIAT_SEPA',
|
|
167
|
+
DEPOSIT_FIAT_SWIFT = 'DEPOSIT_FIAT_SWIFT',
|
|
168
|
+
WITHDRAWAL_FIAT_SEPA = 'WITHDRAWAL_FIAT_SEPA',
|
|
169
|
+
TRANSFER_CARD_PREPAID = 'TRANSFER_CARD_PREPAID',
|
|
170
|
+
TRANSFER_CARD_SUBACCOUNT = 'TRANSFER_CARD_SUBACCOUNT',
|
|
171
|
+
WITHDRAWAL_CRYPTO = 'WITHDRAWAL_CRYPTO',
|
|
172
|
+
EXCHANGE_CRYPTO_INTERNAL = 'EXCHANGE_CRYPTO_INTERNAL',
|
|
173
|
+
TRANSFER_CARD_WHOLESALE = 'TRANSFER_CARD_WHOLESALE',
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export enum APIKeyRole {
|
|
177
|
+
READ_ONLY = 'READ_ONLY',
|
|
178
|
+
DEVELOPER = 'DEVELOPER',
|
|
179
|
+
PRODUCTION = 'PRODUCTION',
|
|
180
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { isTMA } from '@telegram-apps/sdk-react';
|
|
3
|
+
import axios, { AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
|
|
4
|
+
|
|
5
|
+
import { telegramSignUpPath, telegramSignInPath, refreshTokenPath } from '../api/auth';
|
|
6
|
+
|
|
7
|
+
import { AppEnviroment, ResponseStatus } from '../constants';
|
|
8
|
+
import { getFromLocalStorage } from '../utils/storage';
|
|
9
|
+
import { deleteTokens, refreshTokens } from '../utils/tokensFactory';
|
|
10
|
+
|
|
11
|
+
// eslint-disable-next-line no-constant-condition
|
|
12
|
+
|
|
13
|
+
type CreateApiClientOptions = {
|
|
14
|
+
baseURL: string;
|
|
15
|
+
tenantId: string;
|
|
16
|
+
isBearerToken?: boolean;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const createApiClient = ({ baseURL, isBearerToken, tenantId }: CreateApiClientOptions) => {
|
|
20
|
+
type RequestQueueItem = {
|
|
21
|
+
resolve: Function;
|
|
22
|
+
reject: Function;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const instance = axios.create({
|
|
26
|
+
baseURL,
|
|
27
|
+
timeout: 60000,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
instance.interceptors.request.use((config) => {
|
|
31
|
+
const access_token = getFromLocalStorage('access_token');
|
|
32
|
+
|
|
33
|
+
const modifiedHeaders = {
|
|
34
|
+
...config.headers,
|
|
35
|
+
'App-Enviroment': isTMA() ? AppEnviroment.TELEGRAM : AppEnviroment.WEB,
|
|
36
|
+
'Content-Type': 'application/json',
|
|
37
|
+
'Access-Control-Allow-Origin': '*',
|
|
38
|
+
'x-tenant-id': tenantId,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
if (access_token) {
|
|
42
|
+
const authHeader = isBearerToken ? `Bearer ${access_token}` : access_token;
|
|
43
|
+
modifiedHeaders.Authorization = authHeader;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return { ...config, headers: modifiedHeaders } as unknown as InternalAxiosRequestConfig;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
let isTokenRefreshing = false;
|
|
50
|
+
let requestQueue: RequestQueueItem[] = [];
|
|
51
|
+
|
|
52
|
+
instance.interceptors.response.use(
|
|
53
|
+
(response) => response,
|
|
54
|
+
(error) => {
|
|
55
|
+
if (typeof window === 'undefined') {
|
|
56
|
+
return Promise.reject(error);
|
|
57
|
+
}
|
|
58
|
+
if (error?.response?.status === ResponseStatus.UNAUTHORIZED) {
|
|
59
|
+
const { response, config: failedRequest } = error;
|
|
60
|
+
const refreshToken = getFromLocalStorage('refresh_token');
|
|
61
|
+
const isRetryRequest = failedRequest.headers['X-Retry-Request'];
|
|
62
|
+
|
|
63
|
+
const isRefreshTokenRequest = response?.config?.url.includes(refreshTokenPath);
|
|
64
|
+
const isTelegramSignInRequest = response?.config?.url.includes(telegramSignInPath);
|
|
65
|
+
const isTelegramSignUpRequest = response?.config?.url.includes(telegramSignUpPath);
|
|
66
|
+
const isRefreshNotRequired = !refreshToken && !isTMA();
|
|
67
|
+
const isLogoutNeccesary =
|
|
68
|
+
isRefreshNotRequired ||
|
|
69
|
+
isTelegramSignInRequest ||
|
|
70
|
+
isTelegramSignUpRequest ||
|
|
71
|
+
isRefreshTokenRequest ||
|
|
72
|
+
isRetryRequest;
|
|
73
|
+
|
|
74
|
+
const isRefreshAvailable = (!isTokenRefreshing && typeof refreshToken === 'string') || isTMA();
|
|
75
|
+
|
|
76
|
+
if (isLogoutNeccesary) {
|
|
77
|
+
if (typeof window !== 'undefined') {
|
|
78
|
+
// navigate('/auth/logout');
|
|
79
|
+
deleteTokens();
|
|
80
|
+
}
|
|
81
|
+
requestQueue = [];
|
|
82
|
+
return Promise.reject(response);
|
|
83
|
+
}
|
|
84
|
+
if (isRefreshAvailable) {
|
|
85
|
+
refreshTokens()
|
|
86
|
+
.then((data) => {
|
|
87
|
+
if (data?.access_token) {
|
|
88
|
+
requestQueue.forEach((request) => request.resolve());
|
|
89
|
+
requestQueue = [];
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
.catch((tokenRefreshError) => {
|
|
93
|
+
if (typeof window !== 'undefined') {
|
|
94
|
+
// navigate('/auth/logout');
|
|
95
|
+
deleteTokens();
|
|
96
|
+
}
|
|
97
|
+
requestQueue = [];
|
|
98
|
+
return Promise.reject(tokenRefreshError);
|
|
99
|
+
})
|
|
100
|
+
.finally(() => {
|
|
101
|
+
isTokenRefreshing = false;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
return new Promise((res, rej) => {
|
|
105
|
+
requestQueue.push({
|
|
106
|
+
resolve: () => {
|
|
107
|
+
failedRequest.headers['X-Retry-Request'] = 'true';
|
|
108
|
+
return res(instance(failedRequest));
|
|
109
|
+
},
|
|
110
|
+
reject: () => rej(instance(failedRequest)),
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
console.error('Axios error', error);
|
|
116
|
+
|
|
117
|
+
return Promise.reject(error);
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
const patchRequest = async <T>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> => {
|
|
122
|
+
const { data = {}, ...restConfig } = config ?? {};
|
|
123
|
+
|
|
124
|
+
const res = await instance.patch(url, data, restConfig);
|
|
125
|
+
|
|
126
|
+
return res;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const postRequest = async <T>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> => {
|
|
130
|
+
const { data = {}, ...restConfig } = config ?? {};
|
|
131
|
+
|
|
132
|
+
const res = await instance.post(url, data, restConfig);
|
|
133
|
+
|
|
134
|
+
return res;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const deleteRequest = async (url: string, config?: AxiosRequestConfig) => {
|
|
138
|
+
const { data = {}, ...restConfig } = config ?? {};
|
|
139
|
+
|
|
140
|
+
const res = await instance.delete(url, { data, ...restConfig });
|
|
141
|
+
|
|
142
|
+
return res;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const getRequest = async <T>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> => {
|
|
146
|
+
const { params = {}, ...restConfig } = config ?? {};
|
|
147
|
+
|
|
148
|
+
const res = await instance.get(url, { params, ...restConfig });
|
|
149
|
+
|
|
150
|
+
return res;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
return { patchRequest, postRequest, deleteRequest, getRequest };
|
|
154
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const getFromLocalStorage = (key: string) => {
|
|
2
|
+
if (typeof window === 'undefined') {
|
|
3
|
+
// eslint-disable-next-line no-console
|
|
4
|
+
console.error('call getFromLocalStorage in server side');
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return localStorage.getItem(key);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const setToLocalStorage = (key: string, value: string) => {
|
|
12
|
+
if (typeof window === 'undefined') {
|
|
13
|
+
// eslint-disable-next-line no-console
|
|
14
|
+
console.error('call setToLocalStorage in server side');
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
localStorage.setItem(key, value);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const deleteFromLocalStorage = (key: string) => {
|
|
22
|
+
if (typeof window === 'undefined') {
|
|
23
|
+
// eslint-disable-next-line no-console
|
|
24
|
+
console.error('call deleteFromLocalStorage in server side');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
localStorage.removeItem(key);
|
|
29
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { initData, isTMA } from '@telegram-apps/sdk-react';
|
|
2
|
+
|
|
3
|
+
import { deleteFromLocalStorage, getFromLocalStorage, setToLocalStorage } from './storage';
|
|
4
|
+
|
|
5
|
+
import { auth } from '../api/auth';
|
|
6
|
+
|
|
7
|
+
type SetTokensProps = {
|
|
8
|
+
access_token: string;
|
|
9
|
+
refresh_token?: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function setTokens({ access_token, refresh_token }: SetTokensProps) {
|
|
13
|
+
access_token && setToLocalStorage('access_token', access_token);
|
|
14
|
+
refresh_token && setToLocalStorage('refresh_token', refresh_token);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function deleteTokens() {
|
|
18
|
+
deleteFromLocalStorage('access_token');
|
|
19
|
+
deleteFromLocalStorage('refresh_token');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function refreshTokens() {
|
|
23
|
+
const refreshToken = getFromLocalStorage('refresh_token');
|
|
24
|
+
|
|
25
|
+
if (!refreshToken && !isTMA()) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const refreshHandler = () =>
|
|
30
|
+
isTMA()
|
|
31
|
+
? auth.signin.telegram({
|
|
32
|
+
tg_id: initData.user()?.id as number,
|
|
33
|
+
hash: initData.hash() as string,
|
|
34
|
+
init_data_raw: initData.raw() as string,
|
|
35
|
+
})
|
|
36
|
+
: auth.refresh.refresh_token(refreshToken as string);
|
|
37
|
+
|
|
38
|
+
const { data } = await refreshHandler();
|
|
39
|
+
|
|
40
|
+
setTokens(data);
|
|
41
|
+
|
|
42
|
+
return data;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function getTokens() {
|
|
46
|
+
return {
|
|
47
|
+
access_token: getFromLocalStorage('access_token'),
|
|
48
|
+
refresh_token: getFromLocalStorage('refresh_token'),
|
|
49
|
+
};
|
|
50
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es6",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"declaration": true,
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"moduleResolution": "node"
|
|
12
|
+
},
|
|
13
|
+
"include": ["src"],
|
|
14
|
+
"exclude": ["node_modules", "dist", "**/__tests__/*"]
|
|
15
|
+
}
|