@pear-protocol/core-sdk 0.0.1

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.
@@ -0,0 +1,50 @@
1
+ import { HttpTypes } from '@pear-protocol/types';
2
+ import { HttpClient } from '../http.js';
3
+ import { ClientHeaders } from '../types.js';
4
+
5
+ declare class Auth {
6
+ private client;
7
+ constructor(client: HttpClient);
8
+ me(headers?: ClientHeaders): Promise<{
9
+ id: string;
10
+ role: "basic" | "pro";
11
+ }>;
12
+ login(body: HttpTypes.LoginRequest, headers?: ClientHeaders): Promise<{
13
+ user: {
14
+ id: string;
15
+ role: "basic" | "pro";
16
+ };
17
+ }>;
18
+ refreshSession(headers?: ClientHeaders): Promise<void>;
19
+ refreshToken(body: HttpTypes.RefreshTokenRequest, headers?: ClientHeaders): Promise<{
20
+ accessToken: string;
21
+ refreshToken: string;
22
+ tokenType: "Bearer";
23
+ expiresIn: number;
24
+ }>;
25
+ logout(headers?: ClientHeaders): Promise<void>;
26
+ requestNonce(body: HttpTypes.RequestNonceRequest, headers?: ClientHeaders): Promise<{
27
+ nonce: string;
28
+ expiresAt: number;
29
+ }>;
30
+ register(body: HttpTypes.EmailRegisterRequest, headers?: ClientHeaders): Promise<{
31
+ user: {
32
+ id: string;
33
+ role: "basic" | "pro";
34
+ };
35
+ }>;
36
+ linkEmail(body: HttpTypes.LinkEmailRequest, headers?: ClientHeaders): Promise<{
37
+ user: {
38
+ id: string;
39
+ role: "basic" | "pro";
40
+ };
41
+ }>;
42
+ linkWallet(body: HttpTypes.LinkWalletRequest, headers?: ClientHeaders): Promise<{
43
+ user: {
44
+ id: string;
45
+ role: "basic" | "pro";
46
+ };
47
+ }>;
48
+ }
49
+
50
+ export { Auth };
@@ -0,0 +1,68 @@
1
+ class Auth {
2
+ client;
3
+ constructor(client) {
4
+ this.client = client;
5
+ }
6
+ async me(headers) {
7
+ return await this.client.fetch(`/auth/me`, {
8
+ method: "GET",
9
+ headers
10
+ });
11
+ }
12
+ async login(body, headers) {
13
+ return await this.client.fetch(`/auth/login`, {
14
+ method: "POST",
15
+ headers,
16
+ body
17
+ });
18
+ }
19
+ async refreshSession(headers) {
20
+ return await this.client.fetch(`/auth/refresh`, {
21
+ method: "POST",
22
+ headers
23
+ });
24
+ }
25
+ async refreshToken(body, headers) {
26
+ return await this.client.fetch(`/auth/refresh/token`, {
27
+ method: "POST",
28
+ headers,
29
+ body
30
+ });
31
+ }
32
+ async logout(headers) {
33
+ return await this.client.fetch(`/auth/logout`, {
34
+ method: "POST",
35
+ headers
36
+ });
37
+ }
38
+ async requestNonce(body, headers) {
39
+ return await this.client.fetch(`/auth/nonce`, {
40
+ method: "POST",
41
+ headers,
42
+ body
43
+ });
44
+ }
45
+ async register(body, headers) {
46
+ return await this.client.fetch(`/auth/register`, {
47
+ method: "POST",
48
+ headers,
49
+ body
50
+ });
51
+ }
52
+ async linkEmail(body, headers) {
53
+ return await this.client.fetch(`/auth/link/email`, {
54
+ method: "POST",
55
+ headers,
56
+ body
57
+ });
58
+ }
59
+ async linkWallet(body, headers) {
60
+ return await this.client.fetch(`/auth/link/wallet`, {
61
+ method: "POST",
62
+ headers,
63
+ body
64
+ });
65
+ }
66
+ }
67
+
68
+ export { Auth };
package/dist/http.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ import { AuthMode, Logger, RequestMiddleware, ResponseMiddleware, FetchInput, FetchArgs } from './types.js';
2
+
3
+ declare class HttpClient {
4
+ private baseUrl;
5
+ private logger;
6
+ private authMode;
7
+ private requestMiddlewares;
8
+ private responseMiddlewares;
9
+ constructor(baseUrl: string, authMode?: AuthMode, logger?: Logger, debug?: boolean);
10
+ /**
11
+ * Add a request middleware that runs before the request is sent.
12
+ * Middlewares are executed in order.
13
+ */
14
+ useRequest(middleware: RequestMiddleware): void;
15
+ /**
16
+ * Add a response middleware that runs after the response is received.
17
+ * Middlewares are executed in order.
18
+ * The retry function allows retrying the request.
19
+ */
20
+ useResponse(middleware: ResponseMiddleware): void;
21
+ fetch<T>(input: FetchInput, init?: FetchArgs): Promise<T>;
22
+ private createDefaultHeaders;
23
+ private mergeHeaders;
24
+ private normalizeInput;
25
+ private logRequest;
26
+ }
27
+
28
+ export { HttpClient };
package/dist/http.js ADDED
@@ -0,0 +1,134 @@
1
+ import { stringify } from 'qs';
2
+ import { getBaseUrl, normalizeRequest, normalizeResponseData } from './utils';
3
+
4
+ class HttpClient {
5
+ baseUrl;
6
+ logger;
7
+ authMode;
8
+ requestMiddlewares = [];
9
+ responseMiddlewares = [];
10
+ constructor(baseUrl, authMode = "session", logger, debug) {
11
+ this.baseUrl = getBaseUrl(baseUrl);
12
+ this.authMode = authMode;
13
+ const defaultLogger = logger || {
14
+ error: console.error,
15
+ warn: console.warn,
16
+ info: console.info,
17
+ debug: console.debug
18
+ };
19
+ this.logger = {
20
+ ...defaultLogger,
21
+ debug: debug ? defaultLogger.debug : () => {
22
+ }
23
+ };
24
+ }
25
+ /**
26
+ * Add a request middleware that runs before the request is sent.
27
+ * Middlewares are executed in order.
28
+ */
29
+ useRequest(middleware) {
30
+ this.requestMiddlewares.push(middleware);
31
+ }
32
+ /**
33
+ * Add a response middleware that runs after the response is received.
34
+ * Middlewares are executed in order.
35
+ * The retry function allows retrying the request.
36
+ */
37
+ useResponse(middleware) {
38
+ this.responseMiddlewares.push(middleware);
39
+ }
40
+ async fetch(input, init) {
41
+ const defaultHeaders = this.createDefaultHeaders();
42
+ const headers = this.mergeHeaders(defaultHeaders, init);
43
+ const normalizedInput = this.normalizeInput(input, init);
44
+ this.logRequest(normalizedInput, headers);
45
+ const request = new Request(normalizedInput, normalizeRequest(init, headers, this.authMode));
46
+ const executeRequest = async () => {
47
+ let currentIndex = 0;
48
+ const next = async () => {
49
+ if (currentIndex < this.requestMiddlewares.length) {
50
+ const middleware = this.requestMiddlewares[currentIndex++];
51
+ if (middleware) {
52
+ return middleware(request, next);
53
+ }
54
+ }
55
+ return await fetch(request);
56
+ };
57
+ return next();
58
+ };
59
+ let response = await executeRequest();
60
+ const executeResponse = async (resp) => {
61
+ let currentIndex = 0;
62
+ const processMiddlewares = async () => {
63
+ if (currentIndex < this.responseMiddlewares.length) {
64
+ const middleware = this.responseMiddlewares[currentIndex++];
65
+ if (middleware) {
66
+ return middleware(
67
+ resp,
68
+ async () => {
69
+ const newResponse = await executeRequest();
70
+ return executeResponse(newResponse);
71
+ },
72
+ request
73
+ );
74
+ }
75
+ }
76
+ return resp;
77
+ };
78
+ return processMiddlewares();
79
+ };
80
+ response = await executeResponse(response);
81
+ this.logger.debug(`Received response with status ${response.status}
82
+ `);
83
+ return await normalizeResponseData(response, headers);
84
+ }
85
+ createDefaultHeaders() {
86
+ return new Headers({
87
+ "content-type": "application/json",
88
+ accept: "application/json"
89
+ });
90
+ }
91
+ mergeHeaders(defaultHeaders, init) {
92
+ const headers = new Headers(defaultHeaders);
93
+ const customHeaders = {
94
+ ...init?.headers
95
+ };
96
+ Object.entries(customHeaders).forEach(([key, value]) => {
97
+ if (value === null) {
98
+ headers.delete(key);
99
+ } else {
100
+ headers.set(key, value);
101
+ }
102
+ });
103
+ return headers;
104
+ }
105
+ normalizeInput(input, init) {
106
+ let normalizedInput = input;
107
+ if (input instanceof URL || typeof input === "string") {
108
+ const baseUrl = new URL(this.baseUrl);
109
+ const fullPath = `${baseUrl.pathname.replace(/\/$/, "")}/${input.toString().replace(/^\//, "")}`;
110
+ normalizedInput = new URL(fullPath, baseUrl.origin);
111
+ if (init?.query) {
112
+ const params = Object.fromEntries(normalizedInput.searchParams.entries());
113
+ const stringifiedQuery = stringify({ ...params, ...init.query }, { skipNulls: true, arrayFormat: "repeat" });
114
+ normalizedInput.search = stringifiedQuery;
115
+ }
116
+ }
117
+ return normalizedInput;
118
+ }
119
+ logRequest(normalizedInput, headers) {
120
+ const headersObj = {};
121
+ headers.forEach((value, key) => {
122
+ headersObj[key] = value;
123
+ });
124
+ this.logger.debug(
125
+ "Performing request to:\n",
126
+ `URL: ${normalizedInput.toString()}
127
+ `,
128
+ `Headers: ${JSON.stringify(headersObj, null, 2)}
129
+ `
130
+ );
131
+ }
132
+ }
133
+
134
+ export { HttpClient };
@@ -0,0 +1,16 @@
1
+ import { Auth } from './auth/index.js';
2
+ import { Info } from './info/index.js';
3
+ import { Trade } from './trade/index.js';
4
+ import { SDKConfig } from './types.js';
5
+ export { HttpTypes } from '@pear-protocol/types';
6
+ export * from '@pear-protocol/utils';
7
+ import './http.js';
8
+
9
+ declare class PearSDK {
10
+ auth: Auth;
11
+ trade: Trade;
12
+ info: Info;
13
+ constructor(config: SDKConfig);
14
+ }
15
+
16
+ export { PearSDK as default };
package/dist/index.js ADDED
@@ -0,0 +1,52 @@
1
+ import { Auth } from './auth';
2
+ import { HttpClient } from './http';
3
+ import { Info } from './info';
4
+ import { Trade } from './trade';
5
+ import { FetchError } from './utils';
6
+ export * from '@pear-protocol/utils';
7
+
8
+ class PearSDK {
9
+ auth;
10
+ trade;
11
+ info;
12
+ constructor(config) {
13
+ const authMode = config.auth?.type ?? "session";
14
+ const apiClient = new HttpClient(config.apiUrl, authMode, config.logger, config.debug);
15
+ const authClient = new HttpClient(config.authUrl, authMode, config.logger, config.debug);
16
+ this.auth = new Auth(authClient);
17
+ this.trade = new Trade(apiClient);
18
+ this.info = new Info(apiClient);
19
+ if (authMode === "bearer" && config.auth?.token) {
20
+ const getToken = config.auth.token;
21
+ apiClient.useRequest(async (request, next) => {
22
+ const token = getToken();
23
+ if (token) {
24
+ request.headers.set("Authorization", `Bearer ${token}`);
25
+ }
26
+ return next();
27
+ });
28
+ if (config.onAuthError) {
29
+ const onAuthError = config.onAuthError;
30
+ apiClient.useResponse(async (response) => {
31
+ if (response.status === 401) {
32
+ onAuthError();
33
+ throw new FetchError("Unauthorized. Token may be expired or revoked.", "Unauthorized", 401);
34
+ }
35
+ return response;
36
+ });
37
+ }
38
+ }
39
+ if (config.getTradeAccountId) {
40
+ const getTradeAccountId = config.getTradeAccountId;
41
+ apiClient.useRequest(async (request, next) => {
42
+ const tradeAccountId = getTradeAccountId();
43
+ if (tradeAccountId) {
44
+ request.headers.set("x-trade-account-id", tradeAccountId);
45
+ }
46
+ return next();
47
+ });
48
+ }
49
+ }
50
+ }
51
+
52
+ export { PearSDK as default };