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.
Files changed (58) hide show
  1. package/README.md +36 -0
  2. package/dist/api/auth.d.ts +27 -0
  3. package/dist/api/auth.js +38 -0
  4. package/dist/api/config.d.ts +37 -0
  5. package/dist/api/config.js +40 -0
  6. package/dist/api/developer.d.ts +12 -0
  7. package/dist/api/developer.js +15 -0
  8. package/dist/api/exchange.d.ts +35 -0
  9. package/dist/api/exchange.js +27 -0
  10. package/dist/api/fetch_api.d.ts +1 -0
  11. package/dist/api/fetch_api.js +122 -0
  12. package/dist/api/fiat_accounts.d.ts +32 -0
  13. package/dist/api/fiat_accounts.js +51 -0
  14. package/dist/api/index.d.ts +12 -0
  15. package/dist/api/index.js +17 -0
  16. package/dist/api/issuing.d.ts +31 -0
  17. package/dist/api/issuing.js +68 -0
  18. package/dist/api/kyc.d.ts +6 -0
  19. package/dist/api/kyc.js +9 -0
  20. package/dist/api/list.d.ts +10 -0
  21. package/dist/api/list.js +13 -0
  22. package/dist/api/orders.d.ts +12 -0
  23. package/dist/api/orders.js +34 -0
  24. package/dist/api/types.d.ts +945 -0
  25. package/dist/api/types.js +2 -0
  26. package/dist/api/user.d.ts +18 -0
  27. package/dist/api/user.js +21 -0
  28. package/dist/api/wallets.d.ts +18 -0
  29. package/dist/api/wallets.js +42 -0
  30. package/dist/constants.d.ts +149 -0
  31. package/dist/constants.js +172 -0
  32. package/dist/index.d.ts +5 -0
  33. package/dist/index.js +22 -0
  34. package/dist/utils/apiClientFactory.d.ts +13 -0
  35. package/dist/utils/apiClientFactory.js +132 -0
  36. package/dist/utils/storage.d.ts +3 -0
  37. package/dist/utils/storage.js +30 -0
  38. package/dist/utils/tokensFactory.d.ts +12 -0
  39. package/dist/utils/tokensFactory.js +53 -0
  40. package/package.json +35 -0
  41. package/src/api/auth.ts +50 -0
  42. package/src/api/developer.ts +18 -0
  43. package/src/api/exchange.ts +32 -0
  44. package/src/api/fiat_accounts.ts +69 -0
  45. package/src/api/index.ts +16 -0
  46. package/src/api/issuing.ts +66 -0
  47. package/src/api/kyc.ts +10 -0
  48. package/src/api/list.ts +18 -0
  49. package/src/api/orders.ts +32 -0
  50. package/src/api/types.ts +1141 -0
  51. package/src/api/user.ts +24 -0
  52. package/src/api/wallets.ts +39 -0
  53. package/src/constants.ts +180 -0
  54. package/src/index.ts +7 -0
  55. package/src/utils/apiClientFactory.ts +154 -0
  56. package/src/utils/storage.ts +29 -0
  57. package/src/utils/tokensFactory.ts +50 -0
  58. package/tsconfig.json +15 -0
@@ -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
+ };
@@ -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,7 @@
1
+ export * from './api';
2
+ export * from './utils/apiClientFactory';
3
+ export * from './utils/tokensFactory';
4
+ export * from './constants';
5
+
6
+ // Also export types if you have any
7
+ export * from './api/types';
@@ -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
+ }