b5-api-client 0.0.25 → 0.0.27
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/P2PMarketplaceAPIClient.d.ts +13 -3
- package/dist/P2PMarketplaceAPIClient.js +91 -59
- package/dist/auth/FirebaseLoginService.d.ts +9 -0
- package/dist/auth/FirebaseLoginService.js +178 -46
- package/dist/auth/LoginService.d.ts +2 -0
- package/dist/types.d.ts +41 -1
- package/package.json +1 -1
- package/src/P2PMarketplaceAPIClient.ts +103 -58
- package/src/auth/FirebaseLoginService.ts +219 -49
- package/src/auth/LoginService.ts +2 -0
- package/src/types.ts +56 -1
|
@@ -17,5 +17,7 @@ export interface FirebaseLoginServiceConfig {
|
|
|
17
17
|
url: string;
|
|
18
18
|
handleCodeInApp: boolean;
|
|
19
19
|
};
|
|
20
|
+
emailVerificationUrl?: string;
|
|
21
|
+
emailVerificationContinueUrl?: string;
|
|
20
22
|
}
|
|
21
23
|
export declare function createLoginService(config: LoginServiceConfig): LoginService;
|
package/dist/types.d.ts
CHANGED
|
@@ -53,13 +53,17 @@ export interface UsersResponse {
|
|
|
53
53
|
users: KioscoinUser[];
|
|
54
54
|
}
|
|
55
55
|
export interface UserSettings {
|
|
56
|
-
preferredTokenCode?: string;
|
|
56
|
+
preferredTokenCode?: string | null;
|
|
57
57
|
paymentMethods: PaymentMethod[];
|
|
58
|
+
hasVerified?: boolean;
|
|
58
59
|
}
|
|
59
60
|
export interface UpdateUserSettingsRequest {
|
|
60
61
|
userId: string;
|
|
61
62
|
settings: UserSettings;
|
|
62
63
|
}
|
|
64
|
+
export interface VerifyEmailRequest {
|
|
65
|
+
loginId: string;
|
|
66
|
+
}
|
|
63
67
|
export interface PaymentMethod {
|
|
64
68
|
type: string;
|
|
65
69
|
alias?: string;
|
|
@@ -339,3 +343,39 @@ export interface KioscoinOperationResponse {
|
|
|
339
343
|
error?: OperationError;
|
|
340
344
|
order?: Order;
|
|
341
345
|
}
|
|
346
|
+
export type MessageContentType = 'TEXT' | 'ACTION' | 'EVENT' | 'NOTIFICATION';
|
|
347
|
+
export interface MessageContentBase {
|
|
348
|
+
type: MessageContentType;
|
|
349
|
+
}
|
|
350
|
+
export interface MessageContentText extends MessageContentBase {
|
|
351
|
+
type: 'TEXT';
|
|
352
|
+
text: string;
|
|
353
|
+
}
|
|
354
|
+
export interface MessageContentAction extends MessageContentBase {
|
|
355
|
+
type: 'ACTION';
|
|
356
|
+
content: string;
|
|
357
|
+
}
|
|
358
|
+
export interface MessageContentEvent extends MessageContentBase {
|
|
359
|
+
type: 'EVENT';
|
|
360
|
+
event: OrderEvent;
|
|
361
|
+
}
|
|
362
|
+
export interface MessageContentNotification extends MessageContentBase {
|
|
363
|
+
type: 'NOTIFICATION';
|
|
364
|
+
notification: NotificationDto;
|
|
365
|
+
}
|
|
366
|
+
export type MessageContent = MessageContentText | MessageContentAction | MessageContentEvent | MessageContentNotification;
|
|
367
|
+
export interface Message {
|
|
368
|
+
sender: string;
|
|
369
|
+
timestamp: number;
|
|
370
|
+
content: MessageContent;
|
|
371
|
+
}
|
|
372
|
+
export interface NotificationDto {
|
|
373
|
+
id: string;
|
|
374
|
+
userId: string;
|
|
375
|
+
message: Message;
|
|
376
|
+
createdAt: string;
|
|
377
|
+
readAt?: string | null;
|
|
378
|
+
}
|
|
379
|
+
export interface NotificationsResponse {
|
|
380
|
+
notifications: NotificationDto[];
|
|
381
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
|
-
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
2
|
-
import { CreateOrderRequest, CreateUserRequest, Order,
|
|
1
|
+
import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
2
|
+
import { CreateOrderRequest, CreateUserRequest, Order, OrderResponse, TakeOrderRequest, TestEventParams, UpdateOrderRequest, TransactionStatusResponse, RateUserRequest, OrderEventsResponse, PushNotificationsRegisterRequest, ConfigResponse, DashboardMetricsResponse, KioscoinUser, UsersResponse, PaymentMethod, GetOrdersParams, CreateDisputeRequest, DisputesResponse, OrderOffersResponse, TransactionRequest, KioscoinOperationResponse, UpdateUserSettingsRequest, NotificationsResponse, VerifyEmailRequest } from './types';
|
|
3
3
|
import { isPlainObject, camelCase, snakeCase, transform } from 'lodash';
|
|
4
4
|
|
|
5
|
+
interface RequestConfigWithRetry extends AxiosRequestConfig {
|
|
6
|
+
_retry?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface AuthTokenProvider {
|
|
10
|
+
getToken(): Promise<string | null>;
|
|
11
|
+
refreshToken(): Promise<string | null>;
|
|
12
|
+
onRefreshFailure?(error: unknown): void;
|
|
13
|
+
}
|
|
14
|
+
|
|
5
15
|
class P2PMarketplaceAPIClient {
|
|
6
16
|
private readonly client: AxiosInstance;
|
|
7
17
|
private readonly defaultHeaders: Record<string, string>;
|
|
18
|
+
private authTokenProvider?: AuthTokenProvider;
|
|
19
|
+
private refreshTokenPromise?: Promise<string | null>;
|
|
8
20
|
|
|
9
21
|
constructor(baseURL: string, timeout: number = 30000) {
|
|
10
22
|
this.client = axios.create({
|
|
@@ -18,11 +30,28 @@ class P2PMarketplaceAPIClient {
|
|
|
18
30
|
};
|
|
19
31
|
|
|
20
32
|
// Add a request interceptor to transform request data to snake_case
|
|
21
|
-
this.client.interceptors.request.use((config) => {
|
|
33
|
+
this.client.interceptors.request.use(async (config) => {
|
|
22
34
|
if (config.data) {
|
|
23
35
|
config.data = toSnakeCase(config.data);
|
|
24
36
|
}
|
|
25
|
-
|
|
37
|
+
const provider = this.authTokenProvider;
|
|
38
|
+
if (!provider) {
|
|
39
|
+
return config;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return provider
|
|
43
|
+
.getToken()
|
|
44
|
+
.then((token) => {
|
|
45
|
+
if (token) {
|
|
46
|
+
config.headers = config.headers ?? {};
|
|
47
|
+
config.headers['Authorization'] = `Bearer ${token}`;
|
|
48
|
+
}
|
|
49
|
+
return config;
|
|
50
|
+
})
|
|
51
|
+
.catch((error) => {
|
|
52
|
+
console.warn('[P2PMarketplaceAPIClient] Failed to obtain auth token before request:', error);
|
|
53
|
+
return config;
|
|
54
|
+
});
|
|
26
55
|
}, (error) => {
|
|
27
56
|
return Promise.reject(error);
|
|
28
57
|
});
|
|
@@ -33,11 +62,42 @@ class P2PMarketplaceAPIClient {
|
|
|
33
62
|
response.data = toCamelCase(response.data);
|
|
34
63
|
}
|
|
35
64
|
return response;
|
|
36
|
-
}, (error) => {
|
|
37
|
-
|
|
65
|
+
}, async (error: AxiosError) => {
|
|
66
|
+
const { response, config } = error;
|
|
67
|
+
if (!this.authTokenProvider || response?.status !== 401 || !config) {
|
|
68
|
+
return Promise.reject(error);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const originalRequest = config as RequestConfigWithRetry;
|
|
72
|
+
if (originalRequest._retry) {
|
|
73
|
+
return Promise.reject(error);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
originalRequest._retry = true;
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
const newToken = await this.getRefreshedToken();
|
|
80
|
+
if (!newToken) {
|
|
81
|
+
return Promise.reject(error);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
originalRequest.headers = originalRequest.headers ?? {};
|
|
85
|
+
originalRequest.headers['Authorization'] = `Bearer ${newToken}`;
|
|
86
|
+
return this.client(originalRequest);
|
|
87
|
+
} catch (refreshError) {
|
|
88
|
+
if (this.authTokenProvider?.onRefreshFailure) {
|
|
89
|
+
this.authTokenProvider.onRefreshFailure(refreshError);
|
|
90
|
+
}
|
|
91
|
+
return Promise.reject(error);
|
|
92
|
+
}
|
|
38
93
|
});
|
|
39
94
|
}
|
|
40
95
|
|
|
96
|
+
setAuthTokenProvider(provider?: AuthTokenProvider) {
|
|
97
|
+
this.authTokenProvider = provider;
|
|
98
|
+
this.refreshTokenPromise = undefined;
|
|
99
|
+
}
|
|
100
|
+
|
|
41
101
|
private mergeHeaders(customHeaders?: Record<string, string>): Record<string, string> {
|
|
42
102
|
return { ...this.defaultHeaders, ...customHeaders };
|
|
43
103
|
}
|
|
@@ -48,6 +108,28 @@ class P2PMarketplaceAPIClient {
|
|
|
48
108
|
};
|
|
49
109
|
}
|
|
50
110
|
|
|
111
|
+
private async getRefreshedToken(): Promise<string | null> {
|
|
112
|
+
if (!this.authTokenProvider) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!this.refreshTokenPromise) {
|
|
117
|
+
this.refreshTokenPromise = this.authTokenProvider
|
|
118
|
+
.refreshToken()
|
|
119
|
+
.catch((error) => {
|
|
120
|
+
if (this.authTokenProvider?.onRefreshFailure) {
|
|
121
|
+
this.authTokenProvider.onRefreshFailure(error);
|
|
122
|
+
}
|
|
123
|
+
throw error;
|
|
124
|
+
})
|
|
125
|
+
.finally(() => {
|
|
126
|
+
this.refreshTokenPromise = undefined;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return this.refreshTokenPromise;
|
|
131
|
+
}
|
|
132
|
+
|
|
51
133
|
async get<T>(url: string, headers?: Record<string, string>): Promise<T> {
|
|
52
134
|
const config = this.createConfig(headers);
|
|
53
135
|
try {
|
|
@@ -142,11 +224,26 @@ class P2PMarketplaceAPIClient {
|
|
|
142
224
|
return this.post<UsersResponse>(url, request, headers);
|
|
143
225
|
}
|
|
144
226
|
|
|
227
|
+
public async verifyUserEmail(request: VerifyEmailRequest, headers?: Record<string, string>): Promise<UsersResponse> {
|
|
228
|
+
const url = '/api/users/verify_email';
|
|
229
|
+
return this.post<UsersResponse>(url, request, headers);
|
|
230
|
+
}
|
|
231
|
+
|
|
145
232
|
public async registerPushToken(registerRequest: PushNotificationsRegisterRequest, headers?: Record<string, string>): Promise<any> {
|
|
146
233
|
const url = `/api/notifications/register-push`;
|
|
147
234
|
return this.post<PushNotificationsRegisterRequest>(url, registerRequest, headers);
|
|
148
235
|
}
|
|
149
236
|
|
|
237
|
+
public async listNotifications(limit: number = 10, offset: number = 0, headers?: Record<string, string>): Promise<NotificationsResponse> {
|
|
238
|
+
const url = `/api/notifications?limit=${limit}&offset=${offset}`;
|
|
239
|
+
return this.get<NotificationsResponse>(url, headers);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
public async markNotificationAsRead(notificationId: string, headers?: Record<string, string>): Promise<NotificationsResponse> {
|
|
243
|
+
const url = `/api/notifications/${notificationId}/read`;
|
|
244
|
+
return this.post<any>(url, {}, headers);
|
|
245
|
+
}
|
|
246
|
+
|
|
150
247
|
public async getConfig<T>(): Promise<ConfigResponse<T>> {
|
|
151
248
|
const url = '/api/configuration';
|
|
152
249
|
return await this.get<ConfigResponse<T>>(url);
|
|
@@ -173,58 +270,6 @@ class P2PMarketplaceAPIClient {
|
|
|
173
270
|
}
|
|
174
271
|
|
|
175
272
|
|
|
176
|
-
|
|
177
|
-
public async testLockFunds(order: Order, testParams?: TestEventParams, headers?: Record<string, string>) {
|
|
178
|
-
const orderEvent: OrderLockedEvent = {
|
|
179
|
-
type: "LOCKED",
|
|
180
|
-
orderId: order.id ?? "",
|
|
181
|
-
buyerAddress: order.buyerAddress ?? "",
|
|
182
|
-
amount: order.amount?.toString() ?? "0",
|
|
183
|
-
transaction: {
|
|
184
|
-
hash: "0x976d8c61b958e286d907a2e1c5ffde8c9316800ab4de1396a54927a39dc533a2",
|
|
185
|
-
},
|
|
186
|
-
tokenContractAddress: "0xee5e8291b551603a19ef41eea69ae49592ed14f8",
|
|
187
|
-
buyerHash:
|
|
188
|
-
"02809d5cc2ec09a7503ef77358654a5bfc958e08c04ecb33f412884c0933be68",
|
|
189
|
-
sellerAddress: "0x2A4E89D18C2742FEDC65444d339cC5fAF3dE4dF1",
|
|
190
|
-
sellerHash:
|
|
191
|
-
"4b3560738b8e3cb8a0a30ac664b12de2ace977c62ade94bc08a37fe5b93bf34b",
|
|
192
|
-
fee: "30000000000000000",
|
|
193
|
-
timestamp: new Date().toISOString(),
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
const url = "api/events/simulate/lock"
|
|
197
|
-
try {
|
|
198
|
-
await this.post<undefined>(url, orderEvent, headers);
|
|
199
|
-
} catch (error) {
|
|
200
|
-
console.error("Error locking funds:", error);
|
|
201
|
-
throw new Error("Failed to lock funds");
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
public async testReleaseFunds(order: Order, testParams?: TestEventParams, headers?: Record<string, string>) {
|
|
206
|
-
const releaseOrderEvent: OrderReleasedEvent = {
|
|
207
|
-
type: "RELEASED",
|
|
208
|
-
orderId: order.id ?? "",
|
|
209
|
-
buyerAddress: order.buyerAddress ?? "",
|
|
210
|
-
amount: order.amount?.toString() ?? "0",
|
|
211
|
-
transaction: {
|
|
212
|
-
hash: "0xeab4797bf0e13dff0bda481503a544698127c5f97dd826c465ebdb41bcfec3f5",
|
|
213
|
-
},
|
|
214
|
-
tokenContractAddress: "0xee5e8291b551603a19ef41eea69ae49592ed14f8",
|
|
215
|
-
adminAction: true,
|
|
216
|
-
timestamp: new Date().toISOString(),
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
const url = "api/events/simulate/release"
|
|
220
|
-
try {
|
|
221
|
-
await this.post<undefined>(url, releaseOrderEvent, headers);
|
|
222
|
-
} catch (error) {
|
|
223
|
-
console.error("Error releasing funds:", error);
|
|
224
|
-
throw new Error("Failed to release funds");
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
273
|
public async releaseFunds(order: Order, testParams?: TestEventParams, headers?: Record<string, string>): Promise<string> {
|
|
229
274
|
const body = {
|
|
230
275
|
orderId: order.id ?? "",
|