@1money/protocol-ts-sdk 2.0.0 → 2.0.2

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 @@
1
+ - [feedback_security_dismissed.md](feedback_security_dismissed.md) - Security issues intentionally kept as-is: loose equality in client predicates, withCredentials default
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: dismissed-security-findings
3
+ description: Security issues intentionally kept as-is in the SDK client — do not re-flag in future reviews
4
+ type: feedback
5
+ ---
6
+
7
+ ## Loose equality (`==`) in default client predicates is intentional
8
+
9
+ `res.code == 0` and `res.code == 401` in `src/client/index.ts` must use loose equality (`==`), not strict (`===`).
10
+
11
+ **Why:** `ResponseData.code` is typed `number | ${number} | string`. The API may return `"0"` or `"401"` as strings. Strict equality would silently misclassify those responses, breaking every consumer using the default predicates.
12
+
13
+ **How to apply:** Do not flag this as a type-coercion bug in security or code reviews.
14
+
15
+ ## `withCredentials: true` default in core client is intentional
16
+
17
+ The default in `src/client/core.ts` is `withCredentials: true`.
18
+
19
+ **Why:** The generic client (`get`/`post`/`Request.request()`) is used by consumers against session- or CSRF-protected endpoints in browsers. Flipping to `false` silently stops sending cookies, causing 401/403 failures. The high-level protocol API modules already explicitly set `withCredentials: false` where appropriate, so the core default doesn't affect them.
20
+
21
+ **How to apply:** Do not flag the `withCredentials: true` default as a security issue. The protocol API layer handles this correctly.
@@ -20,7 +20,29 @@
20
20
  "Bash(xargs grep:*)",
21
21
  "Bash(npm run lint:es_fix:*)",
22
22
  "Bash(node test-encoding.mjs:*)",
23
- "Bash(npm test:*)"
23
+ "Bash(npm test:*)",
24
+ "Bash(gh repo view --json name,owner,url,defaultBranchRef)",
25
+ "Bash(gh api:*)",
26
+ "Bash(npm ls:*)",
27
+ "Bash(npm audit:*)",
28
+ "Bash(pnpm why flatted)",
29
+ "Bash(pnpm why:*)",
30
+ "Bash(npm view @commitlint/cli version)",
31
+ "Bash(npm view:*)",
32
+ "Bash(npm view nyc version)",
33
+ "Bash(python3:*)",
34
+ "Bash(pnpm install:*)",
35
+ "Bash(npx mocha:*)",
36
+ "Bash(git add package.json pnpm-lock.yaml)",
37
+ "Bash(git commit -m \"$\\(cat <<''EOF''\nchore: upgrade mocha to v11 for security fixes\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\nEOF\n\\)\")",
38
+ "Bash(npx commitlint:*)",
39
+ "Bash(npm run lint:es:*)",
40
+ "Bash(ls -la /Users/bobbytalvin/Desktop/Github/1money-protocol-ts-sdk/.env*)",
41
+ "Bash(ls /Users/bobbytalvin/Desktop/Github/1money-protocol-ts-sdk/.env*)",
42
+ "Bash(git -C /Users/bobbytalvin/Desktop/Github/1money-protocol-ts-sdk log --all --diff-filter=A -- .env*)",
43
+ "Bash(git -C /Users/bobbytalvin/Desktop/Github/1money-protocol-ts-sdk log --all --oneline -- '.env.integration')",
44
+ "Bash(git -C /Users/bobbytalvin/Desktop/Github/1money-protocol-ts-sdk show HEAD:.env)",
45
+ "Bash(git -C /Users/bobbytalvin/Desktop/Github/1money-protocol-ts-sdk show 95cd175:.env.integration)"
24
46
  ],
25
47
  "deny": []
26
48
  }
package/es/api/index.js CHANGED
@@ -108,6 +108,23 @@ class Request {
108
108
  data
109
109
  };
110
110
  }
111
+ mergeSignals(...signals) {
112
+ const controller = new AbortController();
113
+ const onAbort = () => controller.abort();
114
+ const cleanups = [];
115
+ for (const signal of signals) {
116
+ if (signal.aborted) {
117
+ controller.abort();
118
+ break;
119
+ }
120
+ signal.addEventListener('abort', onAbort);
121
+ cleanups.push(() => signal.removeEventListener('abort', onAbort));
122
+ }
123
+ return {
124
+ signal: controller.signal,
125
+ cleanup: () => cleanups.forEach(fn => fn()),
126
+ };
127
+ }
111
128
  setting(config) {
112
129
  if (!config)
113
130
  return console.warn('[1Money SDK]: setting method required correct parameters!');
@@ -123,7 +140,6 @@ class Request {
123
140
  };
124
141
  options.headers['Accept'] = options.headers['Accept'] || '*/*';
125
142
  options.headers['X-Requested-With'] = options.headers['X-Requested-With'] || 'XMLHttpRequest';
126
- options.headers['X-Content-Type-Options'] = options.headers['X-Content-Type-Options'] || 'nosniff';
127
143
  const { onSuccess: initOnSuccess, onFailure: initOnFailure, onLogin: initOnLogin, onError: initOnError, onTimeout: initOnTimeout, isSuccess: initIsSuccess, isLogin: initIsLogin, timeout: initTimeout, } = this._config;
128
144
  const { onSuccess, onFailure, onLogin, onError, onTimeout, isSuccess, isLogin, timeout, } = options;
129
145
  const rules = {
@@ -208,18 +224,33 @@ class Request {
208
224
  let timer = null;
209
225
  let isTimeout = false;
210
226
  const _timeout = timeout ?? initTimeout;
227
+ const controller = new AbortController();
228
+ let signalCleanup = null;
229
+ if (options.signal) {
230
+ const merged = this.mergeSignals(options.signal, controller.signal);
231
+ options.signal = merged.signal;
232
+ signalCleanup = merged.cleanup;
233
+ }
234
+ else {
235
+ options.signal = controller.signal;
236
+ }
211
237
  // Cleanup function for timeout
212
238
  const cleanup = () => {
213
239
  if (timer !== null) {
214
240
  clearTimeout(timer);
215
241
  timer = null;
216
242
  }
243
+ if (signalCleanup) {
244
+ signalCleanup();
245
+ signalCleanup = null;
246
+ }
217
247
  };
218
248
  if (_timeout) {
219
249
  timer = setTimeout(async () => {
220
250
  try {
221
251
  isTimeout = true;
222
252
  cleanup();
253
+ controller.abort();
223
254
  let err = this.parseError('timeout');
224
255
  // @ts-ignore
225
256
  const res = await Promise.resolve(callbacks.timeout(err, options.headers ?? {}));
@@ -266,7 +297,7 @@ class Request {
266
297
  return;
267
298
  cleanup();
268
299
  const data = err.response?.data ?? {};
269
- console.error(`[1Money SDK]: Error(${err.status ?? 500}, ${err.code ?? 'UNKNOWN'}), Message: ${err.message}, Config: ${err.config?.method}, ${err.config?.baseURL ?? ''}, ${err.config?.url ?? ''}, ${JSON.stringify(err.config?.headers ?? {})}, Request: ${JSON.stringify(err.config?.data ?? {})}, Response: ${JSON.stringify(data)};`);
300
+ console.error(`[1Money SDK]: Error(${err.status ?? 500}, ${err.code ?? 'UNKNOWN'}), Message: ${err.message}, Config: ${err.config?.method}, ${err.config?.baseURL ?? ''}${err.config?.url ?? ''};`);
270
301
  const status = err.response?.status ?? 500;
271
302
  const headers = err.response?.headers ?? {};
272
303
  try {
@@ -87,22 +87,20 @@ export type ErrorRes = {
87
87
  };
88
88
  export type RestScopeName = ChainName['all'];
89
89
  export type RestScope = Readonly<[RestScopeName, RestScopeName?, RestScopeName?, RestScopeName?, RestScopeName?]>;
90
- type Tuple2Record<T extends readonly any[]> = {
91
- [Value in T[number]]: Value;
92
- };
93
90
  export interface PromiseWrapper<T, U, TSuc = ChainReturn<T, U>['success'], TFail = ChainReturn<T, U>['failure'], TErr = ChainReturn<T, U>['error'], TLogin = ChainReturn<T, U>['login'], TTime = ChainReturn<T, U>['timeout'], HadCall extends string = ''> {
94
91
  success<TRes = TSuc, Delete extends string = HadCall | 'success'>(onSuccess?: (res: ChainReturn<T, U>['success'], headers: AxiosResHeaders) => TRes): Omit<PromiseWrapper<T, U, TRes, TFail, TErr, TLogin, TTime, Delete>, ChainName['withoutS'] extends HadCall ? Delete | 'rest' : Delete> & Promise<TRes | TFail | TErr | TLogin | TTime>;
95
92
  failure<TRes = TFail, Delete extends string = HadCall | 'failure'>(onFailure?: (res: ChainReturn<T, U>['failure'], headers: AxiosResHeaders) => TRes): Omit<PromiseWrapper<T, U, TSuc, TRes, TErr, TLogin, TTime, Delete>, ChainName['withoutF'] extends HadCall ? Delete | 'rest' : Delete> & Promise<TSuc | TRes | TErr | TLogin | TTime>;
96
93
  error<TRes = TErr, Delete extends string = HadCall | 'error'>(onError?: (err: ChainReturn<T, U>['error'], headers: AxiosReqHeaders | AxiosResHeaders) => TRes): Omit<PromiseWrapper<T, U, TSuc, TFail, TRes, TLogin, TTime, Delete>, ChainName['withoutE'] extends HadCall ? Delete | 'rest' : Delete> & Promise<TSuc | TFail | TRes | TLogin | TTime>;
97
94
  login<TRes = TLogin, Delete extends string = HadCall | 'login'>(onLogin?: (res: ChainReturn<T, U>['login'], headers: AxiosResHeaders) => TRes): Omit<PromiseWrapper<T, U, TSuc, TFail, TErr, TRes, TTime, Delete>, ChainName['withoutL'] extends HadCall ? Delete | 'rest' : Delete> & Promise<TSuc | TFail | TErr | TRes | TTime>;
98
95
  timeout<TRes = TTime, Delete extends string = HadCall | 'timeout'>(onTimeout?: (err: ChainReturn<T, U>['timeout'], headers: AxiosReqHeaders) => TRes): Omit<PromiseWrapper<T, U, TSuc, TFail, TErr, TLogin, TRes, Delete>, ChainName['withoutT'] extends HadCall ? Delete | 'rest' : Delete> & Promise<TSuc | TFail | TErr | TLogin | TRes>;
99
- rest<TRes = TSuc | TFail | TErr | TLogin | TTime, TRestScope extends RestScope = ['success', 'failure', 'login', 'error', 'timeout'], TRestScopeName extends RestScopeName = Exclude<keyof Tuple2Record<TRestScope>, undefined>, THadCallWithNotInScope extends string = HadCall | Exclude<RestScopeName, TRestScopeName>, Delete extends string = HadCall | TRestScopeName | 'rest'>(onRest?: (val: ChainName['all'] extends THadCallWithNotInScope ? unknown : ChainName['withoutS'] extends THadCallWithNotInScope ? ChainReturn<T, U>['success'] : ChainName['withoutF'] extends THadCallWithNotInScope ? ChainReturn<T, U>['failure'] : ChainName['withoutE'] extends THadCallWithNotInScope ? ChainReturn<T, U>['error'] : ChainName['withoutL'] extends THadCallWithNotInScope ? ChainReturn<T, U>['login'] : ChainName['withoutT'] extends THadCallWithNotInScope ? ChainReturn<T, U>['timeout'] : ChainName['withoutSF'] extends THadCallWithNotInScope ? ChainReturn<T, U>['successOrFailure'] : ChainName['withoutSE'] extends THadCallWithNotInScope ? ChainReturn<T, U>['success' | 'error'] : ChainName['withoutSL'] extends THadCallWithNotInScope ? ChainReturn<T, U>['success' | 'login'] : ChainName['withoutST'] extends THadCallWithNotInScope ? ChainReturn<T, U>['success' | 'timeout'] : ChainName['withoutFE'] extends THadCallWithNotInScope ? ChainReturn<T, U>['failure' | 'error'] : ChainName['withoutFL'] extends THadCallWithNotInScope ? ChainReturn<T, U>['failure' | 'login'] : ChainName['withoutFT'] extends THadCallWithNotInScope ? ChainReturn<T, U>['failure' | 'timeout'] : ChainName['withoutEL'] extends THadCallWithNotInScope ? ChainReturn<T, U>['error' | 'login'] : ChainName['withoutET'] extends THadCallWithNotInScope ? ChainReturn<T, U>['error' | 'timeout'] : ChainName['withoutLT'] extends THadCallWithNotInScope ? ChainReturn<T, U>['login' | 'timeout'] : ChainName['withSF'] extends THadCallWithNotInScope ? ChainReturn<T, U>['error' | 'login' | 'timeout'] : ChainName['withSE'] extends THadCallWithNotInScope ? ChainReturn<T, U>['failure' | 'login' | 'timeout'] : ChainName['withSL'] extends THadCallWithNotInScope ? ChainReturn<T, U>['failure' | 'error' | 'timeout'] : ChainName['withST'] extends THadCallWithNotInScope ? ChainReturn<T, U>['failure' | 'error' | 'login'] : ChainName['withFE'] extends THadCallWithNotInScope ? ChainReturn<T, U>['success' | 'login' | 'timeout'] : ChainName['withFL'] extends THadCallWithNotInScope ? ChainReturn<T, U>['success' | 'error' | 'timeout'] : ChainName['withFT'] extends THadCallWithNotInScope ? ChainReturn<T, U>['success' | 'error' | 'login'] : ChainName['withEL'] extends THadCallWithNotInScope ? ChainReturn<T, U>['successOrFailure' | 'timeout'] : ChainName['withET'] extends THadCallWithNotInScope ? ChainReturn<T, U>['successOrFailure' | 'login'] : ChainName['withLT'] extends THadCallWithNotInScope ? ChainReturn<T, U>['successOrFailure' | 'error'] : ChainName['success'] extends THadCallWithNotInScope ? ChainReturn<T, U>['failure' | 'error' | 'login' | 'timeout'] : ChainName['failure'] extends THadCallWithNotInScope ? ChainReturn<T, U>['success' | 'error' | 'login' | 'timeout'] : ChainName['error'] extends THadCallWithNotInScope ? ChainReturn<T, U>['successOrFailure' | 'login' | 'timeout'] : ChainName['login'] extends THadCallWithNotInScope ? ChainReturn<T, U>['successOrFailure' | 'error' | 'timeout'] : ChainName['timeout'] extends THadCallWithNotInScope ? ChainReturn<T, U>['successOrFailure' | 'error' | 'login'] : ChainReturn<T, U>['all'], headers: AxiosReqHeaders | AxiosResHeaders) => TRes, scope?: TRestScope): Omit<PromiseWrapper<T, U, TSuc, TFail, TErr, TLogin, TTime, Delete>, Delete> & Promise<ChainName['all'] extends THadCallWithNotInScope ? TSuc | TFail | TErr | TLogin | TTime : ChainName['withoutS'] extends THadCallWithNotInScope ? TRes | TFail | TErr | TLogin | TTime : ChainName['withoutF'] extends THadCallWithNotInScope ? TSuc | TRes | TErr | TLogin | TTime : ChainName['withoutE'] extends THadCallWithNotInScope ? TSuc | TFail | TRes | TLogin | TTime : ChainName['withoutL'] extends THadCallWithNotInScope ? TSuc | TFail | TErr | TRes | TTime : ChainName['withoutT'] extends THadCallWithNotInScope ? TSuc | TFail | TErr | TLogin | TRes : ChainName['withoutSF'] extends THadCallWithNotInScope ? TRes | TErr | TLogin | TTime : ChainName['withoutSE'] extends THadCallWithNotInScope ? TRes | TFail | TLogin | TTime : ChainName['withoutSL'] extends THadCallWithNotInScope ? TRes | TFail | TErr | TTime : ChainName['withoutST'] extends THadCallWithNotInScope ? TRes | TFail | TErr | TLogin : ChainName['withoutFE'] extends THadCallWithNotInScope ? TSuc | TRes | TLogin | TTime : ChainName['withoutFL'] extends THadCallWithNotInScope ? TSuc | TRes | TErr | TTime : ChainName['withoutFT'] extends THadCallWithNotInScope ? TSuc | TRes | TErr | TLogin : ChainName['withoutEL'] extends THadCallWithNotInScope ? TSuc | TFail | TRes | TTime : ChainName['withoutET'] extends THadCallWithNotInScope ? TSuc | TFail | TRes | TLogin : ChainName['withoutLT'] extends THadCallWithNotInScope ? TSuc | TFail | TErr | TRes : ChainName['withSF'] extends THadCallWithNotInScope ? TSuc | TFail | TRes : ChainName['withSE'] extends THadCallWithNotInScope ? TSuc | TErr | TRes : ChainName['withSL'] extends THadCallWithNotInScope ? TSuc | TLogin | TRes : ChainName['withST'] extends THadCallWithNotInScope ? TSuc | TTime | TRes : ChainName['withFE'] extends THadCallWithNotInScope ? TFail | TErr | TRes : ChainName['withFL'] extends THadCallWithNotInScope ? TFail | TLogin | TRes : ChainName['withFT'] extends THadCallWithNotInScope ? TFail | TTime | TRes : ChainName['withEL'] extends THadCallWithNotInScope ? TErr | TLogin | TRes : ChainName['withET'] extends THadCallWithNotInScope ? TErr | TTime | TRes : ChainName['withLT'] extends THadCallWithNotInScope ? TLogin | TTime | TRes : ChainName['success'] extends THadCallWithNotInScope ? TSuc | TRes : ChainName['failure'] extends THadCallWithNotInScope ? TFail | TRes : ChainName['error'] extends THadCallWithNotInScope ? TErr | TRes : ChainName['login'] extends THadCallWithNotInScope ? TLogin | TRes : ChainName['timeout'] extends THadCallWithNotInScope ? TTime | TRes : TRes>;
96
+ rest<TRes = TSuc | TFail | TErr | TLogin | TTime, S1 extends Exclude<RestScopeName, HadCall> = Exclude<RestScopeName, HadCall>, S2 extends Exclude<RestScopeName, HadCall | S1> | undefined = undefined, S3 extends Exclude<RestScopeName, HadCall | S1 | Extract<S2, string>> | undefined = undefined, S4 extends Exclude<RestScopeName, HadCall | S1 | Extract<S2, string> | Extract<S3, string>> | undefined = undefined, S5 extends Exclude<RestScopeName, HadCall | S1 | Extract<S2, string> | Extract<S3, string> | Extract<S4, string>> | undefined = undefined, TRestScopeName extends RestScopeName = Extract<S1 | S2 | S3 | S4 | S5, RestScopeName>, THadCallWithNotInScope extends string = HadCall | Exclude<RestScopeName, TRestScopeName>, Delete extends string = HadCall | TRestScopeName | 'rest'>(onRest?: (val: ChainName['all'] extends THadCallWithNotInScope ? unknown : ChainName['withoutS'] extends THadCallWithNotInScope ? ChainReturn<T, U>['success'] : ChainName['withoutF'] extends THadCallWithNotInScope ? ChainReturn<T, U>['failure'] : ChainName['withoutE'] extends THadCallWithNotInScope ? ChainReturn<T, U>['error'] : ChainName['withoutL'] extends THadCallWithNotInScope ? ChainReturn<T, U>['login'] : ChainName['withoutT'] extends THadCallWithNotInScope ? ChainReturn<T, U>['timeout'] : ChainName['withoutSF'] extends THadCallWithNotInScope ? ChainReturn<T, U>['successOrFailure'] : ChainName['withoutSE'] extends THadCallWithNotInScope ? ChainReturn<T, U>['success' | 'error'] : ChainName['withoutSL'] extends THadCallWithNotInScope ? ChainReturn<T, U>['success' | 'login'] : ChainName['withoutST'] extends THadCallWithNotInScope ? ChainReturn<T, U>['success' | 'timeout'] : ChainName['withoutFE'] extends THadCallWithNotInScope ? ChainReturn<T, U>['failure' | 'error'] : ChainName['withoutFL'] extends THadCallWithNotInScope ? ChainReturn<T, U>['failure' | 'login'] : ChainName['withoutFT'] extends THadCallWithNotInScope ? ChainReturn<T, U>['failure' | 'timeout'] : ChainName['withoutEL'] extends THadCallWithNotInScope ? ChainReturn<T, U>['error' | 'login'] : ChainName['withoutET'] extends THadCallWithNotInScope ? ChainReturn<T, U>['error' | 'timeout'] : ChainName['withoutLT'] extends THadCallWithNotInScope ? ChainReturn<T, U>['login' | 'timeout'] : ChainName['withSF'] extends THadCallWithNotInScope ? ChainReturn<T, U>['error' | 'login' | 'timeout'] : ChainName['withSE'] extends THadCallWithNotInScope ? ChainReturn<T, U>['failure' | 'login' | 'timeout'] : ChainName['withSL'] extends THadCallWithNotInScope ? ChainReturn<T, U>['failure' | 'error' | 'timeout'] : ChainName['withST'] extends THadCallWithNotInScope ? ChainReturn<T, U>['failure' | 'error' | 'login'] : ChainName['withFE'] extends THadCallWithNotInScope ? ChainReturn<T, U>['success' | 'login' | 'timeout'] : ChainName['withFL'] extends THadCallWithNotInScope ? ChainReturn<T, U>['success' | 'error' | 'timeout'] : ChainName['withFT'] extends THadCallWithNotInScope ? ChainReturn<T, U>['success' | 'error' | 'login'] : ChainName['withEL'] extends THadCallWithNotInScope ? ChainReturn<T, U>['successOrFailure' | 'timeout'] : ChainName['withET'] extends THadCallWithNotInScope ? ChainReturn<T, U>['successOrFailure' | 'login'] : ChainName['withLT'] extends THadCallWithNotInScope ? ChainReturn<T, U>['successOrFailure' | 'error'] : ChainName['success'] extends THadCallWithNotInScope ? ChainReturn<T, U>['failure' | 'error' | 'login' | 'timeout'] : ChainName['failure'] extends THadCallWithNotInScope ? ChainReturn<T, U>['success' | 'error' | 'login' | 'timeout'] : ChainName['error'] extends THadCallWithNotInScope ? ChainReturn<T, U>['successOrFailure' | 'login' | 'timeout'] : ChainName['login'] extends THadCallWithNotInScope ? ChainReturn<T, U>['successOrFailure' | 'error' | 'timeout'] : ChainName['timeout'] extends THadCallWithNotInScope ? ChainReturn<T, U>['successOrFailure' | 'error' | 'login'] : ChainReturn<T, U>['all'], headers: AxiosReqHeaders | AxiosResHeaders) => TRes, scope?: Readonly<[S1, S2?, S3?, S4?, S5?]>): Omit<PromiseWrapper<T, U, TSuc, TFail, TErr, TLogin, TTime, Delete>, Delete> & Promise<ChainName['all'] extends THadCallWithNotInScope ? TSuc | TFail | TErr | TLogin | TTime : ChainName['withoutS'] extends THadCallWithNotInScope ? TRes | TFail | TErr | TLogin | TTime : ChainName['withoutF'] extends THadCallWithNotInScope ? TSuc | TRes | TErr | TLogin | TTime : ChainName['withoutE'] extends THadCallWithNotInScope ? TSuc | TFail | TRes | TLogin | TTime : ChainName['withoutL'] extends THadCallWithNotInScope ? TSuc | TFail | TErr | TRes | TTime : ChainName['withoutT'] extends THadCallWithNotInScope ? TSuc | TFail | TErr | TLogin | TRes : ChainName['withoutSF'] extends THadCallWithNotInScope ? TRes | TErr | TLogin | TTime : ChainName['withoutSE'] extends THadCallWithNotInScope ? TRes | TFail | TLogin | TTime : ChainName['withoutSL'] extends THadCallWithNotInScope ? TRes | TFail | TErr | TTime : ChainName['withoutST'] extends THadCallWithNotInScope ? TRes | TFail | TErr | TLogin : ChainName['withoutFE'] extends THadCallWithNotInScope ? TSuc | TRes | TLogin | TTime : ChainName['withoutFL'] extends THadCallWithNotInScope ? TSuc | TRes | TErr | TTime : ChainName['withoutFT'] extends THadCallWithNotInScope ? TSuc | TRes | TErr | TLogin : ChainName['withoutEL'] extends THadCallWithNotInScope ? TSuc | TFail | TRes | TTime : ChainName['withoutET'] extends THadCallWithNotInScope ? TSuc | TFail | TRes | TLogin : ChainName['withoutLT'] extends THadCallWithNotInScope ? TSuc | TFail | TErr | TRes : ChainName['withSF'] extends THadCallWithNotInScope ? TSuc | TFail | TRes : ChainName['withSE'] extends THadCallWithNotInScope ? TSuc | TErr | TRes : ChainName['withSL'] extends THadCallWithNotInScope ? TSuc | TLogin | TRes : ChainName['withST'] extends THadCallWithNotInScope ? TSuc | TTime | TRes : ChainName['withFE'] extends THadCallWithNotInScope ? TFail | TErr | TRes : ChainName['withFL'] extends THadCallWithNotInScope ? TFail | TLogin | TRes : ChainName['withFT'] extends THadCallWithNotInScope ? TFail | TTime | TRes : ChainName['withEL'] extends THadCallWithNotInScope ? TErr | TLogin | TRes : ChainName['withET'] extends THadCallWithNotInScope ? TErr | TTime | TRes : ChainName['withLT'] extends THadCallWithNotInScope ? TLogin | TTime | TRes : ChainName['success'] extends THadCallWithNotInScope ? TSuc | TRes : ChainName['failure'] extends THadCallWithNotInScope ? TFail | TRes : ChainName['error'] extends THadCallWithNotInScope ? TErr | TRes : ChainName['login'] extends THadCallWithNotInScope ? TLogin | TRes : ChainName['timeout'] extends THadCallWithNotInScope ? TTime | TRes : TRes>;
100
97
  }
101
98
  export declare class Request {
102
99
  private _config;
103
100
  axios: AxiosStatic;
104
101
  constructor(config?: InitConfig);
105
102
  private parseError;
103
+ private mergeSignals;
106
104
  setting(config: InitConfig): void;
107
105
  request<T, U = unknown>(options: Options<T, U>): PromiseWrapper<T, U> & Promise<CustomResponseData<T, U, WithFailureData<T>>>;
108
106
  }
@@ -108,6 +108,23 @@ class Request {
108
108
  data
109
109
  };
110
110
  }
111
+ mergeSignals(...signals) {
112
+ const controller = new AbortController();
113
+ const onAbort = () => controller.abort();
114
+ const cleanups = [];
115
+ for (const signal of signals) {
116
+ if (signal.aborted) {
117
+ controller.abort();
118
+ break;
119
+ }
120
+ signal.addEventListener('abort', onAbort);
121
+ cleanups.push(() => signal.removeEventListener('abort', onAbort));
122
+ }
123
+ return {
124
+ signal: controller.signal,
125
+ cleanup: () => cleanups.forEach(fn => fn()),
126
+ };
127
+ }
111
128
  setting(config) {
112
129
  if (!config)
113
130
  return console.warn('[1Money SDK]: setting method required correct parameters!');
@@ -123,7 +140,6 @@ class Request {
123
140
  };
124
141
  options.headers['Accept'] = options.headers['Accept'] || '*/*';
125
142
  options.headers['X-Requested-With'] = options.headers['X-Requested-With'] || 'XMLHttpRequest';
126
- options.headers['X-Content-Type-Options'] = options.headers['X-Content-Type-Options'] || 'nosniff';
127
143
  const { onSuccess: initOnSuccess, onFailure: initOnFailure, onLogin: initOnLogin, onError: initOnError, onTimeout: initOnTimeout, isSuccess: initIsSuccess, isLogin: initIsLogin, timeout: initTimeout, } = this._config;
128
144
  const { onSuccess, onFailure, onLogin, onError, onTimeout, isSuccess, isLogin, timeout, } = options;
129
145
  const rules = {
@@ -208,18 +224,33 @@ class Request {
208
224
  let timer = null;
209
225
  let isTimeout = false;
210
226
  const _timeout = timeout ?? initTimeout;
227
+ const controller = new AbortController();
228
+ let signalCleanup = null;
229
+ if (options.signal) {
230
+ const merged = this.mergeSignals(options.signal, controller.signal);
231
+ options.signal = merged.signal;
232
+ signalCleanup = merged.cleanup;
233
+ }
234
+ else {
235
+ options.signal = controller.signal;
236
+ }
211
237
  // Cleanup function for timeout
212
238
  const cleanup = () => {
213
239
  if (timer !== null) {
214
240
  clearTimeout(timer);
215
241
  timer = null;
216
242
  }
243
+ if (signalCleanup) {
244
+ signalCleanup();
245
+ signalCleanup = null;
246
+ }
217
247
  };
218
248
  if (_timeout) {
219
249
  timer = setTimeout(async () => {
220
250
  try {
221
251
  isTimeout = true;
222
252
  cleanup();
253
+ controller.abort();
223
254
  let err = this.parseError('timeout');
224
255
  // @ts-ignore
225
256
  const res = await Promise.resolve(callbacks.timeout(err, options.headers ?? {}));
@@ -266,7 +297,7 @@ class Request {
266
297
  return;
267
298
  cleanup();
268
299
  const data = err.response?.data ?? {};
269
- console.error(`[1Money SDK]: Error(${err.status ?? 500}, ${err.code ?? 'UNKNOWN'}), Message: ${err.message}, Config: ${err.config?.method}, ${err.config?.baseURL ?? ''}, ${err.config?.url ?? ''}, ${JSON.stringify(err.config?.headers ?? {})}, Request: ${JSON.stringify(err.config?.data ?? {})}, Response: ${JSON.stringify(data)};`);
300
+ console.error(`[1Money SDK]: Error(${err.status ?? 500}, ${err.code ?? 'UNKNOWN'}), Message: ${err.message}, Config: ${err.config?.method}, ${err.config?.baseURL ?? ''}${err.config?.url ?? ''};`);
270
301
  const status = err.response?.status ?? 500;
271
302
  const headers = err.response?.headers ?? {};
272
303
  try {
package/es/index.js CHANGED
@@ -889,8 +889,7 @@ function toHex(value) {
889
889
  }
890
890
  }
891
891
  catch (e) {
892
- console.error('[1Money SDK]: toHex error:', e);
893
- return '0x';
892
+ throw new Error(`[1Money SDK]: toHex conversion failed: ${e instanceof Error ? e.message : String(e)}`);
894
893
  }
895
894
  }function encodeRlpListHeader(length) {
896
895
  if (length < 56) {
@@ -1032,6 +1031,23 @@ class Request {
1032
1031
  data
1033
1032
  };
1034
1033
  }
1034
+ mergeSignals(...signals) {
1035
+ const controller = new AbortController();
1036
+ const onAbort = () => controller.abort();
1037
+ const cleanups = [];
1038
+ for (const signal of signals) {
1039
+ if (signal.aborted) {
1040
+ controller.abort();
1041
+ break;
1042
+ }
1043
+ signal.addEventListener('abort', onAbort);
1044
+ cleanups.push(() => signal.removeEventListener('abort', onAbort));
1045
+ }
1046
+ return {
1047
+ signal: controller.signal,
1048
+ cleanup: () => cleanups.forEach(fn => fn()),
1049
+ };
1050
+ }
1035
1051
  setting(config) {
1036
1052
  if (!config)
1037
1053
  return console.warn('[1Money SDK]: setting method required correct parameters!');
@@ -1047,7 +1063,6 @@ class Request {
1047
1063
  };
1048
1064
  options.headers['Accept'] = options.headers['Accept'] || '*/*';
1049
1065
  options.headers['X-Requested-With'] = options.headers['X-Requested-With'] || 'XMLHttpRequest';
1050
- options.headers['X-Content-Type-Options'] = options.headers['X-Content-Type-Options'] || 'nosniff';
1051
1066
  const { onSuccess: initOnSuccess, onFailure: initOnFailure, onLogin: initOnLogin, onError: initOnError, onTimeout: initOnTimeout, isSuccess: initIsSuccess, isLogin: initIsLogin, timeout: initTimeout, } = this._config;
1052
1067
  const { onSuccess, onFailure, onLogin, onError, onTimeout, isSuccess, isLogin, timeout, } = options;
1053
1068
  const rules = {
@@ -1132,18 +1147,33 @@ class Request {
1132
1147
  let timer = null;
1133
1148
  let isTimeout = false;
1134
1149
  const _timeout = timeout ?? initTimeout;
1150
+ const controller = new AbortController();
1151
+ let signalCleanup = null;
1152
+ if (options.signal) {
1153
+ const merged = this.mergeSignals(options.signal, controller.signal);
1154
+ options.signal = merged.signal;
1155
+ signalCleanup = merged.cleanup;
1156
+ }
1157
+ else {
1158
+ options.signal = controller.signal;
1159
+ }
1135
1160
  // Cleanup function for timeout
1136
1161
  const cleanup = () => {
1137
1162
  if (timer !== null) {
1138
1163
  clearTimeout(timer);
1139
1164
  timer = null;
1140
1165
  }
1166
+ if (signalCleanup) {
1167
+ signalCleanup();
1168
+ signalCleanup = null;
1169
+ }
1141
1170
  };
1142
1171
  if (_timeout) {
1143
1172
  timer = setTimeout(async () => {
1144
1173
  try {
1145
1174
  isTimeout = true;
1146
1175
  cleanup();
1176
+ controller.abort();
1147
1177
  let err = this.parseError('timeout');
1148
1178
  // @ts-ignore
1149
1179
  const res = await Promise.resolve(callbacks.timeout(err, options.headers ?? {}));
@@ -1190,7 +1220,7 @@ class Request {
1190
1220
  return;
1191
1221
  cleanup();
1192
1222
  const data = err.response?.data ?? {};
1193
- console.error(`[1Money SDK]: Error(${err.status ?? 500}, ${err.code ?? 'UNKNOWN'}), Message: ${err.message}, Config: ${err.config?.method}, ${err.config?.baseURL ?? ''}, ${err.config?.url ?? ''}, ${JSON.stringify(err.config?.headers ?? {})}, Request: ${JSON.stringify(err.config?.data ?? {})}, Response: ${JSON.stringify(data)};`);
1223
+ console.error(`[1Money SDK]: Error(${err.status ?? 500}, ${err.code ?? 'UNKNOWN'}), Message: ${err.message}, Config: ${err.config?.method}, ${err.config?.baseURL ?? ''}${err.config?.url ?? ''};`);
1194
1224
  const status = err.response?.status ?? 500;
1195
1225
  const headers = err.response?.headers ?? {};
1196
1226
  try {
package/es/utils/index.js CHANGED
@@ -889,8 +889,7 @@ function toHex(value) {
889
889
  }
890
890
  }
891
891
  catch (e) {
892
- console.error('[1Money SDK]: toHex error:', e);
893
- return '0x';
892
+ throw new Error(`[1Money SDK]: toHex conversion failed: ${e instanceof Error ? e.message : String(e)}`);
894
893
  }
895
894
  }function encodeRlpListHeader(length) {
896
895
  if (length < 56) {
@@ -0,0 +1,101 @@
1
+ import js from '@eslint/js';
2
+ import tseslint from 'typescript-eslint';
3
+ import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
4
+
5
+ export default tseslint.config(
6
+ // Global ignores (replaces .eslintignore)
7
+ {
8
+ ignores: [
9
+ 'build/',
10
+ 'configs/',
11
+ 'es/',
12
+ 'lib/',
13
+ 'dist/',
14
+ 'server/',
15
+ 'demo/',
16
+ 'node_modules/',
17
+ 'src/**/__test__/',
18
+ 'src/.umi',
19
+ '*.config.js',
20
+ '*.config.mjs',
21
+ '*.conf.js',
22
+ 'mocha.tsx.js',
23
+ 'commitlint.config.js',
24
+ ],
25
+ },
26
+
27
+ // Base configs
28
+ js.configs.recommended,
29
+ ...tseslint.configs.recommended,
30
+
31
+ // Main source config
32
+ {
33
+ files: ['src/**/*.{ts,tsx}'],
34
+ languageOptions: {
35
+ ecmaVersion: 2020,
36
+ sourceType: 'module',
37
+ globals: {
38
+ Atomics: 'readonly',
39
+ SharedArrayBuffer: 'readonly',
40
+ },
41
+ parserOptions: {
42
+ project: './tsconfig.json',
43
+ },
44
+ },
45
+ rules: {
46
+ // TypeScript
47
+ '@typescript-eslint/no-empty-interface': 'off',
48
+ '@typescript-eslint/no-empty-object-type': 'off',
49
+ '@typescript-eslint/restrict-plus-operands': 'warn',
50
+ '@typescript-eslint/array-type': 'off',
51
+ '@typescript-eslint/no-use-before-define': 'off',
52
+ '@typescript-eslint/consistent-type-assertions': 'warn',
53
+ '@typescript-eslint/no-inferrable-types': 'warn',
54
+ '@typescript-eslint/explicit-member-accessibility': 'warn',
55
+
56
+ '@typescript-eslint/no-explicit-any': 'off',
57
+ '@typescript-eslint/no-unused-vars': 'off',
58
+ '@typescript-eslint/no-unused-expressions': 'off',
59
+ '@typescript-eslint/ban-ts-comment': 'off',
60
+ '@typescript-eslint/no-unnecessary-type-constraint': 'off',
61
+
62
+ // Core ESLint
63
+ 'no-console': ['error', { allow: ['warn', 'error', 'info'] }],
64
+ 'prefer-spread': 'warn',
65
+ 'no-unused-vars': 'off',
66
+ },
67
+ },
68
+
69
+ // Integration tests override
70
+ {
71
+ files: ['src/__integration__/**/*.ts'],
72
+ rules: {
73
+ 'no-console': 'off',
74
+ '@typescript-eslint/no-inferrable-types': 'off',
75
+ },
76
+ },
77
+
78
+ // Prettier (must be last — disables conflicting rules + adds prettier plugin)
79
+ eslintPluginPrettierRecommended,
80
+
81
+ // Custom prettier options
82
+ {
83
+ files: ['src/**/*.{ts,tsx}'],
84
+ rules: {
85
+ 'prettier/prettier': [
86
+ 'warn',
87
+ {
88
+ printWidth: 50,
89
+ tabWidth: 2,
90
+ singleQuote: true,
91
+ jsxSingleQuote: true,
92
+ semi: true,
93
+ trailingComma: 'none',
94
+ endOfLine: 'auto',
95
+ arrowParens: 'avoid',
96
+ rangeEnd: 0,
97
+ },
98
+ ],
99
+ },
100
+ },
101
+ );
package/lib/api/index.js CHANGED
@@ -184,6 +184,33 @@ var Request = /** @class */ (function () {
184
184
  data: data
185
185
  };
186
186
  };
187
+ Request.prototype.mergeSignals = function () {
188
+ var signals = [];
189
+ for (var _i = 0; _i < arguments.length; _i++) {
190
+ signals[_i] = arguments[_i];
191
+ }
192
+ var controller = new AbortController();
193
+ var onAbort = function () { return controller.abort(); };
194
+ var cleanups = [];
195
+ var _loop_2 = function (signal) {
196
+ if (signal.aborted) {
197
+ controller.abort();
198
+ return "break";
199
+ }
200
+ signal.addEventListener('abort', onAbort);
201
+ cleanups.push(function () { return signal.removeEventListener('abort', onAbort); });
202
+ };
203
+ for (var _a = 0, signals_1 = signals; _a < signals_1.length; _a++) {
204
+ var signal = signals_1[_a];
205
+ var state_1 = _loop_2(signal);
206
+ if (state_1 === "break")
207
+ break;
208
+ }
209
+ return {
210
+ signal: controller.signal,
211
+ cleanup: function () { return cleanups.forEach(function (fn) { return fn(); }); },
212
+ };
213
+ };
187
214
  Request.prototype.setting = function (config) {
188
215
  if (!config)
189
216
  return console.warn('[1Money SDK]: setting method required correct parameters!');
@@ -196,7 +223,6 @@ var Request = /** @class */ (function () {
196
223
  options.headers = __assign(__assign(__assign({}, this.axios.defaults.headers.common), (options.method ? this.axios.defaults.headers[options.method] : {})), options.headers);
197
224
  options.headers['Accept'] = options.headers['Accept'] || '*/*';
198
225
  options.headers['X-Requested-With'] = options.headers['X-Requested-With'] || 'XMLHttpRequest';
199
- options.headers['X-Content-Type-Options'] = options.headers['X-Content-Type-Options'] || 'nosniff';
200
226
  var _a = this._config, initOnSuccess = _a.onSuccess, initOnFailure = _a.onFailure, initOnLogin = _a.onLogin, initOnError = _a.onError, initOnTimeout = _a.onTimeout, initIsSuccess = _a.isSuccess, initIsLogin = _a.isLogin, initTimeout = _a.timeout;
201
227
  var onSuccess = options.onSuccess, onFailure = options.onFailure, onLogin = options.onLogin, onError = options.onError, onTimeout = options.onTimeout, isSuccess = options.isSuccess, isLogin = options.isLogin, timeout = options.timeout;
202
228
  var rules = {
@@ -272,12 +298,26 @@ var Request = /** @class */ (function () {
272
298
  var timer = null;
273
299
  var isTimeout = false;
274
300
  var _timeout = timeout !== null && timeout !== void 0 ? timeout : initTimeout;
301
+ var controller = new AbortController();
302
+ var signalCleanup = null;
303
+ if (options.signal) {
304
+ var merged = _this.mergeSignals(options.signal, controller.signal);
305
+ options.signal = merged.signal;
306
+ signalCleanup = merged.cleanup;
307
+ }
308
+ else {
309
+ options.signal = controller.signal;
310
+ }
275
311
  // Cleanup function for timeout
276
312
  var cleanup = function () {
277
313
  if (timer !== null) {
278
314
  clearTimeout(timer);
279
315
  timer = null;
280
316
  }
317
+ if (signalCleanup) {
318
+ signalCleanup();
319
+ signalCleanup = null;
320
+ }
281
321
  };
282
322
  if (_timeout) {
283
323
  timer = setTimeout(function () { return __awaiter(_this, void 0, void 0, function () {
@@ -289,6 +329,7 @@ var Request = /** @class */ (function () {
289
329
  _c.trys.push([0, 2, , 3]);
290
330
  isTimeout = true;
291
331
  cleanup();
332
+ controller.abort();
292
333
  err = this.parseError('timeout');
293
334
  return [4 /*yield*/, Promise.resolve(callbacks.timeout(err, (_a = options.headers) !== null && _a !== void 0 ? _a : {}))];
294
335
  case 1:
@@ -355,34 +396,34 @@ var Request = /** @class */ (function () {
355
396
  });
356
397
  }); }).catch(function (err) { return __awaiter(_this, void 0, void 0, function () {
357
398
  var data, status, headers, res, doLogin, e_3;
358
- var _a, _b, _c, _d, _f, _g, _h, _j, _k, _l, _o, _p, _q, _r, _s, _t, _u, _v;
359
- return __generator(this, function (_w) {
360
- switch (_w.label) {
399
+ var _a, _b, _c, _d, _f, _g, _h, _j, _k, _l, _o, _p, _q, _r;
400
+ return __generator(this, function (_s) {
401
+ switch (_s.label) {
361
402
  case 0:
362
403
  if (isTimeout)
363
404
  return [2 /*return*/];
364
405
  cleanup();
365
406
  data = (_b = (_a = err.response) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : {};
366
- console.error("[1Money SDK]: Error(".concat((_c = err.status) !== null && _c !== void 0 ? _c : 500, ", ").concat((_d = err.code) !== null && _d !== void 0 ? _d : 'UNKNOWN', "), Message: ").concat(err.message, ", Config: ").concat((_f = err.config) === null || _f === void 0 ? void 0 : _f.method, ", ").concat((_h = (_g = err.config) === null || _g === void 0 ? void 0 : _g.baseURL) !== null && _h !== void 0 ? _h : '', ", ").concat((_k = (_j = err.config) === null || _j === void 0 ? void 0 : _j.url) !== null && _k !== void 0 ? _k : '', ", ").concat(JSON.stringify((_o = (_l = err.config) === null || _l === void 0 ? void 0 : _l.headers) !== null && _o !== void 0 ? _o : {}), ", Request: ").concat(JSON.stringify((_q = (_p = err.config) === null || _p === void 0 ? void 0 : _p.data) !== null && _q !== void 0 ? _q : {}), ", Response: ").concat(JSON.stringify(data), ";"));
367
- status = (_s = (_r = err.response) === null || _r === void 0 ? void 0 : _r.status) !== null && _s !== void 0 ? _s : 500;
368
- headers = (_u = (_t = err.response) === null || _t === void 0 ? void 0 : _t.headers) !== null && _u !== void 0 ? _u : {};
369
- _w.label = 1;
407
+ console.error("[1Money SDK]: Error(".concat((_c = err.status) !== null && _c !== void 0 ? _c : 500, ", ").concat((_d = err.code) !== null && _d !== void 0 ? _d : 'UNKNOWN', "), Message: ").concat(err.message, ", Config: ").concat((_f = err.config) === null || _f === void 0 ? void 0 : _f.method, ", ").concat((_h = (_g = err.config) === null || _g === void 0 ? void 0 : _g.baseURL) !== null && _h !== void 0 ? _h : '').concat((_k = (_j = err.config) === null || _j === void 0 ? void 0 : _j.url) !== null && _k !== void 0 ? _k : '', ";"));
408
+ status = (_o = (_l = err.response) === null || _l === void 0 ? void 0 : _l.status) !== null && _o !== void 0 ? _o : 500;
409
+ headers = (_q = (_p = err.response) === null || _p === void 0 ? void 0 : _p.headers) !== null && _q !== void 0 ? _q : {};
410
+ _s.label = 1;
370
411
  case 1:
371
- _w.trys.push([1, 5, , 6]);
412
+ _s.trys.push([1, 5, , 6]);
372
413
  res = data;
373
- doLogin = (_v = rules.login) === null || _v === void 0 ? void 0 : _v.call(rules, data, status, headers);
414
+ doLogin = (_r = rules.login) === null || _r === void 0 ? void 0 : _r.call(rules, data, status, headers);
374
415
  if (!doLogin) return [3 /*break*/, 3];
375
416
  return [4 /*yield*/, Promise.resolve(callbacks.login(res, headers))];
376
417
  case 2:
377
- res = _w.sent();
418
+ res = _s.sent();
378
419
  ResPromise._resolve(res);
379
420
  return [3 /*break*/, 4];
380
421
  case 3:
381
422
  errorHandler(err, headers);
382
- _w.label = 4;
423
+ _s.label = 4;
383
424
  case 4: return [3 /*break*/, 6];
384
425
  case 5:
385
- e_3 = _w.sent();
426
+ e_3 = _s.sent();
386
427
  errorHandler(e_3, headers);
387
428
  return [3 /*break*/, 6];
388
429
  case 6: return [2 /*return*/];