@swapkit/helpers 3.0.0-beta.12 → 3.0.0-beta.14

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 (64) hide show
  1. package/dist/api/index.cjs +2 -2
  2. package/dist/api/index.cjs.map +6 -6
  3. package/dist/api/index.js +2 -2
  4. package/dist/api/index.js.map +6 -6
  5. package/dist/{chunk-hk0jx7rp.js → chunk-7shcm26h.js} +3 -3
  6. package/dist/{chunk-hk0jx7rp.js.map → chunk-7shcm26h.js.map} +1 -1
  7. package/dist/chunk-8fdws4se.js +4 -0
  8. package/dist/chunk-8fdws4se.js.map +10 -0
  9. package/dist/{chunk-k2m9hvag.js → chunk-b8hashv0.js} +3 -3
  10. package/dist/{chunk-k2m9hvag.js.map → chunk-b8hashv0.js.map} +1 -1
  11. package/dist/{chunk-c4ndre32.js → chunk-bf0ph1bk.js} +3 -3
  12. package/dist/{chunk-c4ndre32.js.map → chunk-bf0ph1bk.js.map} +1 -1
  13. package/dist/{chunk-4mz4n5jc.js → chunk-bh986mnf.js} +3 -3
  14. package/dist/{chunk-4mz4n5jc.js.map → chunk-bh986mnf.js.map} +1 -1
  15. package/dist/{chunk-hbnf5tky.js → chunk-dzypg9sp.js} +3 -3
  16. package/dist/{chunk-hbnf5tky.js.map → chunk-dzypg9sp.js.map} +1 -1
  17. package/dist/{chunk-mt3sdnfg.js → chunk-ghdhtvtt.js} +3 -3
  18. package/dist/{chunk-mt3sdnfg.js.map → chunk-ghdhtvtt.js.map} +1 -1
  19. package/dist/{chunk-3ts9cha8.js → chunk-jhmhh7ax.js} +3 -3
  20. package/dist/{chunk-3ts9cha8.js.map → chunk-jhmhh7ax.js.map} +1 -1
  21. package/dist/{chunk-frkpmajq.js → chunk-nm1av1e6.js} +3 -3
  22. package/dist/{chunk-frkpmajq.js.map → chunk-nm1av1e6.js.map} +1 -1
  23. package/dist/{chunk-4edjz16h.js → chunk-rarep8vg.js} +3 -3
  24. package/dist/{chunk-4edjz16h.js.map → chunk-rarep8vg.js.map} +1 -1
  25. package/dist/{chunk-2vqx8ecy.js → chunk-rr043vwc.js} +3 -3
  26. package/dist/{chunk-2vqx8ecy.js.map → chunk-rr043vwc.js.map} +1 -1
  27. package/dist/{chunk-ganzk321.js → chunk-s82pm7xc.js} +2 -2
  28. package/dist/{chunk-ganzk321.js.map → chunk-s82pm7xc.js.map} +1 -1
  29. package/dist/chunk-sb9hymk1.js +3 -0
  30. package/dist/chunk-sb9hymk1.js.map +10 -0
  31. package/dist/{chunk-prm0g9b0.js → chunk-tn4e7zrk.js} +3 -3
  32. package/dist/{chunk-prm0g9b0.js.map → chunk-tn4e7zrk.js.map} +1 -1
  33. package/dist/{chunk-zv69dnwn.js → chunk-vadspc46.js} +3 -3
  34. package/dist/{chunk-zv69dnwn.js.map → chunk-vadspc46.js.map} +1 -1
  35. package/dist/{chunk-qpz3c078.js → chunk-vgg88vt8.js} +3 -3
  36. package/dist/{chunk-qpz3c078.js.map → chunk-vgg88vt8.js.map} +1 -1
  37. package/dist/{chunk-qkreqkaa.js → chunk-wssz50sc.js} +3 -3
  38. package/dist/{chunk-qkreqkaa.js.map → chunk-wssz50sc.js.map} +1 -1
  39. package/dist/contracts/index.js +1 -1
  40. package/dist/index.cjs +3 -3
  41. package/dist/index.cjs.map +15 -16
  42. package/dist/index.js +3 -3
  43. package/dist/index.js.map +15 -16
  44. package/dist/tokens/index.js +2 -2
  45. package/dist/tokens/index.js.map +2 -2
  46. package/package.json +2 -2
  47. package/src/api/midgard/endpoints.ts +6 -47
  48. package/src/api/swapkitApi/endpoints.ts +9 -26
  49. package/src/api/swapkitApi/types.ts +1 -1
  50. package/src/api/thornode/endpoints.ts +8 -26
  51. package/src/modules/__tests__/assetValue.test.ts +42 -0
  52. package/src/modules/__tests__/swapKitNumber.test.ts +4 -5
  53. package/src/modules/assetValue.ts +12 -28
  54. package/src/modules/bigIntArithmetics.ts +12 -1
  55. package/src/modules/requestClient.ts +36 -22
  56. package/src/modules/swapKitConfig.ts +1 -29
  57. package/src/modules/swapKitError.ts +294 -105
  58. package/src/types/chains.ts +45 -37
  59. package/src/types/derivationPath.ts +1 -0
  60. package/src/types/wallet.ts +2 -0
  61. package/src/utils/asset.ts +3 -2
  62. package/src/utils/memo.ts +5 -11
  63. package/src/utils/others.ts +1 -2
  64. package/src/utils/wallets.ts +5 -2
@@ -1,3 +1,3 @@
1
- import{a as w}from"../chunk-hbnf5tky.js";import{b as C}from"../chunk-qpz3c078.js";import{c as p}from"../chunk-qkreqkaa.js";import{d as m}from"../chunk-zv69dnwn.js";import{e as x}from"../chunk-3ts9cha8.js";import{f}from"../chunk-prm0g9b0.js";import{g as l}from"../chunk-mt3sdnfg.js";import{h as L}from"../chunk-4edjz16h.js";import{i as e}from"../chunk-c4ndre32.js";import{j as V}from"../chunk-frkpmajq.js";import{k as t}from"../chunk-4mz4n5jc.js";import{l as a}from"../chunk-k2m9hvag.js";import{m as i}from"../chunk-2vqx8ecy.js";import{n as o}from"../chunk-hk0jx7rp.js";import{p as T}from"../chunk-ganzk321.js";var s={};T(s,{UniswapV3List:()=>C,UniswapV2List:()=>w,TraderjoeV2List:()=>V,ThorchainList:()=>e,SushiswapList:()=>L,PangolinList:()=>l,PancakeswapList:()=>f,OpenOceanV2List:()=>x,OneInchList:()=>m,MayaList:()=>p,JupiterList:()=>o,ChainflipList:()=>i,CaviarV1List:()=>a,CamelotV3List:()=>t});function B(O){for(let c of Object.values(s)){let r=c.tokens.find((P)=>P.identifier===O);if(r?.logoURI)return r.logoURI}return}export{s as tokenLists,B as getTokenIcon};
1
+ import{e as w}from"../chunk-dzypg9sp.js";import{f as C}from"../chunk-vgg88vt8.js";import{g as p}from"../chunk-wssz50sc.js";import{h as m}from"../chunk-vadspc46.js";import{i as x}from"../chunk-jhmhh7ax.js";import{j as f}from"../chunk-tn4e7zrk.js";import{k as l}from"../chunk-ghdhtvtt.js";import{l as L}from"../chunk-rarep8vg.js";import{m as e}from"../chunk-bf0ph1bk.js";import{n as V}from"../chunk-nm1av1e6.js";import{o as t}from"../chunk-bh986mnf.js";import{p as a}from"../chunk-b8hashv0.js";import{q as i}from"../chunk-rr043vwc.js";import{r as o}from"../chunk-7shcm26h.js";import{t as T}from"../chunk-s82pm7xc.js";var s={};T(s,{UniswapV3List:()=>C,UniswapV2List:()=>w,TraderjoeV2List:()=>V,ThorchainList:()=>e,SushiswapList:()=>L,PangolinList:()=>l,PancakeswapList:()=>f,OpenOceanV2List:()=>x,OneInchList:()=>m,MayaList:()=>p,JupiterList:()=>o,ChainflipList:()=>i,CaviarV1List:()=>a,CamelotV3List:()=>t});function B(O){for(let c of Object.values(s)){let r=c.tokens.find((P)=>P.identifier===O);if(r?.logoURI)return r.logoURI}return}export{s as tokenLists,B as getTokenIcon};
2
2
 
3
- //# debugId=4914D9B24FD3F03364756E2164756E21
3
+ //# debugId=3A5B936F2C5A6EC964756E2164756E21
@@ -4,7 +4,7 @@
4
4
  "sourcesContent": [
5
5
  "import * as tokenLists from \"./lists\";\n\nexport function getTokenIcon(identifier: string): string | undefined {\n // Search through all lists for a matching token\n for (const list of Object.values(tokenLists)) {\n const token = list.tokens.find((token) => token.identifier === identifier);\n if (token?.logoURI) {\n return token.logoURI;\n }\n }\n\n return undefined;\n}\n\nexport { tokenLists };\n"
6
6
  ],
7
- "mappings": "28BAEO,IAAS,JAAY,JAAC,HAAwC,JAEnE,GAAW,AAAQ,EAAO,EAAO,JAAU,HAAG,JAC5C,DAAM,HAAQ,EAAK,OAAO,KAAK,CAAC,IAAU,EAAM,aAAe,CAAU,EACzE,GAAI,GAAO,QACT,OAAO,EAAM,QAIjB",
8
- "debugId": "4914D9B24FD3F03364756E2164756E21",
7
+ "mappings": "g9BAEO,IAAS,JAAY,JAAC,HAAwC,JAEnE,GAAW,AAAQ,EAAO,EAAO,JAAU,HAAG,JAC5C,DAAM,HAAQ,EAAK,OAAO,KAAK,CAAC,IAAU,EAAM,aAAe,CAAU,EACzE,GAAI,GAAO,QACT,OAAO,EAAM,QAIjB",
8
+ "debugId": "3A5B936F2C5A6EC964756E2164756E21",
9
9
  "names": []
10
10
  }
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "description": "SwapKit - Helpers",
10
10
  "devDependencies": {
11
- "@swapkit/toolboxes": "1.0.0-beta.17"
11
+ "@swapkit/toolboxes": "1.0.0-beta.19"
12
12
  },
13
13
  "exports": {
14
14
  ".": {
@@ -55,5 +55,5 @@
55
55
  "type-check:go": "tsgo"
56
56
  },
57
57
  "type": "module",
58
- "version": "3.0.0-beta.12"
58
+ "version": "3.0.0-beta.14"
59
59
  }
@@ -1,45 +1,8 @@
1
- import {
2
- AssetValue,
3
- BaseDecimal,
4
- Chain,
5
- RequestClient,
6
- SKConfig,
7
- StagenetChain,
8
- SwapKitNumber,
9
- } from "@swapkit/helpers";
1
+ import { AssetValue, BaseDecimal, Chain, RequestClient, SwapKitNumber } from "@swapkit/helpers";
10
2
  import type { MemberDetailsMayachain, MemberDetailsThorchain, THORNameDetails } from "./types";
11
3
 
12
- // Create extended RequestClient instances for each API
13
- const getMidgardRequestClient = () => {
14
- const apiHeaders = SKConfig.get("apiHeaders");
15
- return RequestClient.extend({
16
- headers: apiHeaders.midgard || {},
17
- });
18
- };
19
-
20
4
  function getMidgardBaseUrl(isThorchain = true) {
21
- const { isStagenet } = SKConfig.get("envs");
22
- const midgardUrls = SKConfig.get("midgardUrls");
23
-
24
- if (isThorchain) {
25
- const chain = isStagenet ? StagenetChain.THORChain : Chain.THORChain;
26
- // Use the configured URL if available, otherwise use defaults
27
- if (midgardUrls[chain]) {
28
- return midgardUrls[chain];
29
- }
30
- // Default URLs based on environment
31
- return isStagenet
32
- ? "https://stagenet-midgard.ninerealms.com"
33
- : "https://midgard.ninerealms.com";
34
- }
35
-
36
- const chain = isStagenet ? StagenetChain.Maya : Chain.Maya;
37
- // Use the configured URL if available, otherwise use defaults
38
- if (midgardUrls[chain]) {
39
- return midgardUrls[chain];
40
- }
41
- // Default URLs based on environment
42
- return isStagenet ? "https://stagenet-midgard.mayachain.info" : "https://midgard.mayachain.info";
5
+ return isThorchain ? "https://midgard.ninerealms.com" : "https://midgard.mayachain.info";
43
6
  }
44
7
 
45
8
  function getNameServiceBaseUrl(isThorchain = true) {
@@ -51,8 +14,7 @@ function getLiquidityPositionRaw<Chain extends Chain.THORChain | Chain.Maya>(bas
51
14
  return function getLiquidityPosition(
52
15
  address: string,
53
16
  ): Promise<Chain extends Chain.THORChain ? MemberDetailsThorchain : MemberDetailsMayachain> {
54
- const MidgardRequestClient = getMidgardRequestClient();
55
- return MidgardRequestClient.get<
17
+ return RequestClient.get<
56
18
  Chain extends Chain.THORChain ? MemberDetailsThorchain : MemberDetailsMayachain
57
19
  >(`${baseUrl}/v2/member/${address}`);
58
20
  };
@@ -60,22 +22,19 @@ function getLiquidityPositionRaw<Chain extends Chain.THORChain | Chain.Maya>(bas
60
22
 
61
23
  function getNameDetails(baseUrl: string) {
62
24
  return function getNameDetails(name: string) {
63
- const MidgardRequestClient = getMidgardRequestClient();
64
- return MidgardRequestClient.get<THORNameDetails>(`${baseUrl}/lookup/${name}`);
25
+ return RequestClient.get<THORNameDetails>(`${baseUrl}/lookup/${name}`);
65
26
  };
66
27
  }
67
28
 
68
29
  function getNamesByAddress(baseUrl: string) {
69
30
  return function getNamesByAddress(address: string) {
70
- const MidgardRequestClient = getMidgardRequestClient();
71
- return MidgardRequestClient.get<string[]>(`${baseUrl}/rlookup/${address}`);
31
+ return RequestClient.get<string[]>(`${baseUrl}/rlookup/${address}`);
72
32
  };
73
33
  }
74
34
 
75
35
  function getNamesByOwner(baseUrl: string) {
76
36
  return function getNamesByOwner(address: string) {
77
- const MidgardRequestClient = getMidgardRequestClient();
78
- return MidgardRequestClient.get<string[]>(`${baseUrl}/owner/${address}`);
37
+ return RequestClient.get<string[]>(`${baseUrl}/owner/${address}`);
79
38
  };
80
39
  }
81
40
 
@@ -9,14 +9,6 @@ import {
9
9
  isGasAsset,
10
10
  } from "@swapkit/helpers";
11
11
 
12
- // Create extended RequestClient for swapkitApi with custom headers
13
- const getSwapkitApiRequestClient = () => {
14
- const apiHeaders = SKConfig.get("apiHeaders");
15
- return RequestClient.extend({
16
- headers: apiHeaders.swapkitApi || {},
17
- });
18
- };
19
-
20
12
  import {
21
13
  type BalanceResponse,
22
14
  type BrokerDepositChannelParams,
@@ -37,13 +29,11 @@ import {
37
29
  } from "./types";
38
30
 
39
31
  export function getTrackerDetails(json: TrackerParams) {
40
- const SwapkitApiRequestClient = getSwapkitApiRequestClient();
41
- return SwapkitApiRequestClient.post<TrackerResponse>(getApiUrl("/track"), { json });
32
+ return RequestClient.post<TrackerResponse>(getApiUrl("/track"), { json });
42
33
  }
43
34
 
44
35
  export async function getSwapQuote(json: QuoteRequest) {
45
- const SwapkitApiRequestClient = getSwapkitApiRequestClient();
46
- const response = await SwapkitApiRequestClient.post<QuoteResponse>(getApiUrl("/quote"), { json });
36
+ const response = await RequestClient.post<QuoteResponse>(getApiUrl("/quote"), { json });
47
37
 
48
38
  if (response.error) {
49
39
  throw new SwapKitError("api_v2_server_error", { message: response.error });
@@ -57,9 +47,8 @@ export async function getSwapQuote(json: QuoteRequest) {
57
47
  }
58
48
 
59
49
  return parsedResponse.data;
60
- } catch (error) {
50
+ } catch (_error) {
61
51
  // throw new SwapKitError("api_v2_invalid_response", error);
62
- console.warn(error);
63
52
  return response;
64
53
  }
65
54
  }
@@ -69,30 +58,26 @@ export async function getChainBalance<T extends Chain>({
69
58
  address,
70
59
  scamFilter = true,
71
60
  }: { chain: T; address: string; scamFilter?: boolean }) {
72
- const SwapkitApiRequestClient = getSwapkitApiRequestClient();
73
61
  const url = getApiUrl(`/balance?chain=${chain}&address=${address}`);
74
- const balanceResponse = await SwapkitApiRequestClient.get<BalanceResponse>(url);
62
+ const balanceResponse = await RequestClient.get<BalanceResponse>(url);
75
63
  const balances = Array.isArray(balanceResponse) ? balanceResponse : [];
76
64
 
77
65
  return scamFilter ? filterAssets(balances) : balances;
78
66
  }
79
67
 
80
68
  export function getTokenListProviders() {
81
- const SwapkitApiRequestClient = getSwapkitApiRequestClient();
82
69
  const url = getApiUrl("/providers");
83
- return SwapkitApiRequestClient.get<TokenListProvidersResponse>(url);
70
+ return RequestClient.get<TokenListProvidersResponse>(url);
84
71
  }
85
72
 
86
73
  export function getTokenList(provider: ProviderName) {
87
- const SwapkitApiRequestClient = getSwapkitApiRequestClient();
88
74
  const url = getApiUrl(`/tokens?provider=${provider}`);
89
- return SwapkitApiRequestClient.get<TokensResponseV2>(url);
75
+ return RequestClient.get<TokensResponseV2>(url);
90
76
  }
91
77
 
92
78
  export async function getPrice(body: PriceRequest) {
93
- const SwapkitApiRequestClient = getSwapkitApiRequestClient();
94
79
  const url = getApiUrl("/price");
95
- const response = await SwapkitApiRequestClient.post<PriceResponse>(url, {
80
+ const response = await RequestClient.post<PriceResponse>(url, {
96
81
  json: body,
97
82
  });
98
83
 
@@ -110,9 +95,8 @@ export async function getPrice(body: PriceRequest) {
110
95
  }
111
96
 
112
97
  export async function getGasRate() {
113
- const SwapkitApiRequestClient = getSwapkitApiRequestClient();
114
98
  const url = getApiUrl("/gas");
115
- const response = await SwapkitApiRequestClient.get<GasResponse>(url);
99
+ const response = await RequestClient.get<GasResponse>(url);
116
100
 
117
101
  try {
118
102
  const parsedResponse = GasResponseSchema.safeParse(response);
@@ -133,10 +117,9 @@ export async function getChainflipDepositChannel(body: BrokerDepositChannelParam
133
117
  if (!destinationAddress) {
134
118
  throw new SwapKitError("chainflip_broker_invalid_params");
135
119
  }
136
- const SwapkitApiRequestClient = getSwapkitApiRequestClient();
137
120
  const url = SKConfig.get("integrations").chainflip?.brokerUrl || getApiUrl("/channel");
138
121
 
139
- const response = await SwapkitApiRequestClient.post<DepositChannelResponse>(url, { json: body });
122
+ const response = await RequestClient.post<DepositChannelResponse>(url, { json: body });
140
123
 
141
124
  try {
142
125
  const parsedResponse = DepositChannelResponseSchema.safeParse(response);
@@ -2,7 +2,6 @@ import {
2
2
  type AssetValue,
3
3
  Chain,
4
4
  ChainId,
5
- ErrorCode,
6
5
  FeeTypeEnum,
7
6
  ProviderName,
8
7
  WarningCodeEnum,
@@ -20,6 +19,7 @@ import {
20
19
  unknown,
21
20
  type z,
22
21
  } from "zod";
22
+ import { ErrorCode } from "../../types/quotes";
23
23
 
24
24
  export enum PriorityLabel {
25
25
  CHEAPEST = "CHEAPEST",
@@ -10,14 +10,6 @@ import type {
10
10
  THORNodeType,
11
11
  } from "./types";
12
12
 
13
- // Create extended RequestClient for thornode with custom headers
14
- const getThornodeRequestClient = () => {
15
- const apiHeaders = SKConfig.get("apiHeaders");
16
- return RequestClient.extend({
17
- headers: apiHeaders.thornode || {},
18
- });
19
- };
20
-
21
13
  function baseUrl(type?: THORNodeType) {
22
14
  const { isStagenet } = SKConfig.get("envs");
23
15
  const nodeUrls = SKConfig.get("nodeUrls");
@@ -43,28 +35,23 @@ function getNameServiceBaseUrl(type?: THORNodeType) {
43
35
  }
44
36
 
45
37
  export function getLastBlock<T extends THORNodeType = "thorchain">(type: T = "thorchain" as T) {
46
- const ThornodeRequestClient = getThornodeRequestClient();
47
- return ThornodeRequestClient.get<LastBlockItem<T>[]>(`${baseUrl(type)}/lastblock`);
38
+ return RequestClient.get<LastBlockItem<T>[]>(`${baseUrl(type)}/lastblock`);
48
39
  }
49
40
 
50
41
  export function getThorchainQueue(type?: THORNodeType) {
51
- const ThornodeRequestClient = getThornodeRequestClient();
52
- return ThornodeRequestClient.get(`${baseUrl(type)}/queue`);
42
+ return RequestClient.get(`${baseUrl(type)}/queue`);
53
43
  }
54
44
 
55
45
  export function getNodes(type?: THORNodeType) {
56
- const ThornodeRequestClient = getThornodeRequestClient();
57
- return ThornodeRequestClient.get<NodeItem[]>(`${baseUrl(type)}/nodes`);
46
+ return RequestClient.get<NodeItem[]>(`${baseUrl(type)}/nodes`);
58
47
  }
59
48
 
60
49
  export function getMimirInfo(type?: THORNodeType) {
61
- const ThornodeRequestClient = getThornodeRequestClient();
62
- return ThornodeRequestClient.get<MimirData>(`${baseUrl(type)}/mimir`);
50
+ return RequestClient.get<MimirData>(`${baseUrl(type)}/mimir`);
63
51
  }
64
52
 
65
53
  export function getInboundAddresses(type?: THORNodeType) {
66
- const ThornodeRequestClient = getThornodeRequestClient();
67
- return ThornodeRequestClient.get<InboundAddressesItem[]>(`${baseUrl(type)}/inbound_addresses`);
54
+ return RequestClient.get<InboundAddressesItem[]>(`${baseUrl(type)}/inbound_addresses`);
68
55
  }
69
56
 
70
57
  export async function getTHORNodeTNSDetails({
@@ -72,8 +59,7 @@ export async function getTHORNodeTNSDetails({
72
59
  name,
73
60
  }: { type?: THORNodeType; name: string }): Promise<THORNodeTNSDetails> {
74
61
  try {
75
- const ThornodeRequestClient = getThornodeRequestClient();
76
- const result = await ThornodeRequestClient.get<THORNodeTNSDetails>(
62
+ const result = await RequestClient.get<THORNodeTNSDetails>(
77
63
  `${getNameServiceBaseUrl(type)}/${name}`,
78
64
  );
79
65
  return result;
@@ -99,16 +85,12 @@ export async function getTNSPreferredAsset({ type, tns }: { type?: THORNodeType;
99
85
  }
100
86
 
101
87
  export function getRunePoolInfo(type?: THORNodeType) {
102
- const ThornodeRequestClient = getThornodeRequestClient();
103
- return ThornodeRequestClient.get<RunePoolInfo>(`${baseUrl(type)}/runepool`);
88
+ return RequestClient.get<RunePoolInfo>(`${baseUrl(type)}/runepool`);
104
89
  }
105
90
 
106
91
  export function getRunePoolProviderInfo({
107
92
  type,
108
93
  thorAddress,
109
94
  }: { type?: THORNodeType; thorAddress: string }) {
110
- const ThornodeRequestClient = getThornodeRequestClient();
111
- return ThornodeRequestClient.get<RunePoolProviderInfo>(
112
- `${baseUrl(type)}/rune_provider/${thorAddress}`,
113
- );
95
+ return RequestClient.get<RunePoolProviderInfo>(`${baseUrl(type)}/rune_provider/${thorAddress}`);
114
96
  }
@@ -794,6 +794,32 @@ describe("AssetValue", () => {
794
794
  type: "Native",
795
795
  }),
796
796
  );
797
+
798
+ const trxAsset = AssetValue.from({ chain: Chain.Tron });
799
+ expect(trxAsset).toEqual(
800
+ expect.objectContaining({
801
+ chain: Chain.Tron,
802
+ decimal: BaseDecimal.TRX,
803
+ isGasAsset: true,
804
+ isSynthetic: false,
805
+ symbol: "TRX",
806
+ ticker: "TRX",
807
+ type: "Native",
808
+ }),
809
+ );
810
+
811
+ const trxAssetFromString = AssetValue.from({ asset: "TRX.TRX" });
812
+ expect(trxAssetFromString).toEqual(
813
+ expect.objectContaining({
814
+ chain: Chain.Tron,
815
+ decimal: BaseDecimal.TRX,
816
+ isGasAsset: true,
817
+ isSynthetic: false,
818
+ symbol: "TRX",
819
+ ticker: "TRX",
820
+ type: "Native",
821
+ }),
822
+ );
797
823
  });
798
824
 
799
825
  test("keep SOL address casing", () => {
@@ -811,6 +837,22 @@ describe("AssetValue", () => {
811
837
  }),
812
838
  );
813
839
  });
840
+
841
+ test("TRC20 tokens are not marked as gas assets", () => {
842
+ const tronUsdt = AssetValue.from({
843
+ asset: "TRX.USDT-TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
844
+ });
845
+ expect(tronUsdt).toEqual(
846
+ expect.objectContaining({
847
+ address: "tr7nhqjekqxgtci8q8zy4pl8otszgjlj6t",
848
+ chain: Chain.Tron,
849
+ isGasAsset: false,
850
+ isSynthetic: false,
851
+ symbol: "USDT-tr7nhqjekqxgtci8q8zy4pl8otszgjlj6t",
852
+ ticker: "USDT",
853
+ }),
854
+ );
855
+ });
814
856
  });
815
857
  });
816
858
 
@@ -27,11 +27,11 @@ describe("SwapKitNumber", () => {
27
27
 
28
28
  const skNumber5 = new SwapKitNumber({ value: 0.1005, decimal: 3 });
29
29
  expect(skNumber5.getValue("string")).toBe("0.101");
30
- expect(skNumber5.getBaseValue("bigint")).toBe(100n);
30
+ expect(skNumber5.getBaseValue("bigint")).toBe(101n);
31
31
 
32
32
  const skNumber6 = new SwapKitNumber({ value: -0.1005, decimal: 3 });
33
33
  expect(skNumber6.getValue("string")).toBe("-0.101");
34
- expect(skNumber6.getBaseValue("bigint")).toBe(-100n);
34
+ expect(skNumber6.getBaseValue("bigint")).toBe(-101n);
35
35
  expect(skNumber6.decimal).toBe(3);
36
36
  expect(skNumber6.getValue("number")).toBe(-0.101);
37
37
  expect(skNumber6.decimalMultiplier).toBe(100000000n);
@@ -355,9 +355,8 @@ describe("SwapKitNumber", () => {
355
355
 
356
356
  const result = skNumber1.mul(skNumber2);
357
357
 
358
- // The exact result of 1.23 * 4.56 is 5.6088
359
358
  expect(result.getValue("string")).toBe("5.609");
360
- expect(result.getBaseValue("bigint")).toBe(5608n);
359
+ expect(result.getBaseValue("bigint")).toBe(5609n);
361
360
 
362
361
  const skNumber3 = new SwapKitNumber({ decimal: 2, value: 1.23 });
363
362
  const skNumber4 = new SwapKitNumber(-1.234567891);
@@ -367,7 +366,7 @@ describe("SwapKitNumber", () => {
367
366
  // The exact result of 1.23 * -1.234567891 is -1,518518505
368
367
  // If we round it to 2 decimal places, we should get 5.61
369
368
  expect(result2.getValue("string")).toBe("-1.52");
370
- expect(result2.getBaseValue("bigint")).toBe(-151n);
369
+ expect(result2.getBaseValue("bigint")).toBe(-152n);
371
370
  });
372
371
  });
373
372
 
@@ -1,3 +1,6 @@
1
+ import { getAddress } from "ethers";
2
+ import { match } from "ts-pattern";
3
+
1
4
  import {
2
5
  BaseDecimal,
3
6
  Chain,
@@ -19,7 +22,6 @@ import { warnOnce } from "../utils/others";
19
22
  import { type TokenListName, loadTokenLists } from "../utils/tokens";
20
23
  import { validateIdentifier } from "../utils/validators";
21
24
 
22
- import { getAddress } from "ethers";
23
25
  import type { NumberPrimitives } from "./bigIntArithmetics";
24
26
  import { BigIntArithmetics, formatBigIntToSafeValue } from "./bigIntArithmetics";
25
27
  import { SwapKitError } from "./swapKitError";
@@ -213,33 +215,15 @@ or by passing asyncTokenLookup: true to the from() function, which will make it
213
215
  export function getMinAmountByChain(chain: Chain) {
214
216
  const asset = AssetValue.from({ chain });
215
217
 
216
- switch (chain) {
217
- case Chain.Bitcoin:
218
- case Chain.Litecoin:
219
- case Chain.BitcoinCash:
220
- case Chain.Dash:
221
- return asset.set(0.00010001);
222
-
223
- case Chain.Dogecoin:
224
- return asset.set(1.00000001);
225
-
226
- case Chain.Avalanche:
227
- case Chain.Ethereum:
228
- case Chain.Arbitrum:
229
- case Chain.BinanceSmartChain:
230
- return asset.set(0.00000001);
231
-
232
- case Chain.THORChain:
233
- case Chain.Maya:
234
- return asset.set(0);
235
-
236
- case Chain.Cosmos:
237
- case Chain.Kujira:
238
- return asset.set(0.000001);
239
-
240
- default:
241
- return asset.set(0.00000001);
242
- }
218
+ return match(chain)
219
+ .with(Chain.Bitcoin, Chain.Litecoin, Chain.BitcoinCash, Chain.Dash, () => asset.set(0.00010001))
220
+ .with(Chain.Dogecoin, () => asset.set(1.00000001))
221
+ .with(Chain.Avalanche, Chain.Ethereum, Chain.Arbitrum, Chain.BinanceSmartChain, () =>
222
+ asset.set(0.00000001),
223
+ )
224
+ .with(Chain.THORChain, Chain.Maya, () => asset.set(0))
225
+ .with(Chain.Cosmos, Chain.Kujira, () => asset.set(0.000001))
226
+ .otherwise(() => asset.set(0.00000001));
243
227
  }
244
228
 
245
229
  async function createAssetValue(identifier: string, value: NumberPrimitives = 0) {
@@ -54,6 +54,17 @@ export function formatBigIntToSafeValue({
54
54
  );
55
55
  }
56
56
 
57
+ function divideBigIntWithRounding(n: bigint, d: bigint) {
58
+ if (d === 0n) {
59
+ throw new Error("Cannot divide by zero");
60
+ }
61
+ const half = d / 2n;
62
+ if ((n >= 0n && d >= 0n) || (n < 0n && d < 0n)) {
63
+ return (n + half) / d;
64
+ }
65
+ return (n - half) / d;
66
+ }
67
+
57
68
  export class BigIntArithmetics {
58
69
  decimalMultiplier: bigint = 10n ** 8n;
59
70
  bigIntValue = 0n;
@@ -153,7 +164,7 @@ export class BigIntArithmetics {
153
164
  getBaseValue<T extends AllowedNumberTypes>(type: T, decimal?: number): NumberPrimitivesType[T] {
154
165
  const divisor =
155
166
  this.decimalMultiplier / toMultiplier(decimal || this.decimal || BaseDecimal.THOR);
156
- const baseValue = this.bigIntValue / divisor;
167
+ const baseValue = divideBigIntWithRounding(this.bigIntValue, divisor);
157
168
 
158
169
  switch (type) {
159
170
  case "number":
@@ -1,8 +1,9 @@
1
1
  import { SKConfig } from "./swapKitConfig";
2
+ import { SwapKitError } from "./swapKitError";
2
3
 
3
4
  type Options = RequestInit & {
4
5
  /**
5
- * @deprecated Use onSuccess instead
6
+ * @deprecated Use onSuccess instead - will be removed in next major @MarkedV4
6
7
  */
7
8
  responseHandler?: (response: any) => any;
8
9
  json?: unknown;
@@ -24,40 +25,53 @@ export const RequestClient = {
24
25
  function fetchWithConfig(method: "GET" | "POST", extendOptions: Options = {}) {
25
26
  return async <T>(url: string, options: Options = {}): Promise<T> => {
26
27
  const { searchParams, json, body, headers: headersOptions } = { ...extendOptions, ...options };
27
- const { swapKit } = SKConfig.get("apiKeys");
28
28
 
29
- const isJson = json || url.endsWith(".json");
29
+ const isJson = !!json || url.endsWith(".json");
30
30
  const bodyToSend = isJson ? JSON.stringify(json) : body;
31
- const urlInstance = new URL(url);
32
-
33
- if (searchParams) {
34
- urlInstance.search = new URLSearchParams(searchParams).toString();
35
- }
36
-
37
- const headers = {
38
- ...headersOptions,
39
- ...(isJson ? { "Content-Type": "application/json" } : {}),
40
- ...(swapKit ? { "x-api-key": swapKit } : {}),
41
- };
42
31
 
43
32
  try {
44
- const response = await fetch(urlInstance.toString(), {
45
- ...options,
46
- method,
47
- body: bodyToSend,
48
- headers,
49
- });
33
+ const requestUrl = buildUrl(url, searchParams);
34
+ const headers = buildHeaders(isJson, headersOptions);
35
+
36
+ const response = await fetch(requestUrl, { ...options, method, body: bodyToSend, headers });
50
37
 
51
38
  if (!response.ok) {
52
39
  const message = await response.text();
53
- throw new Error(`${response.statusText}(${response.status}): ${message}`);
40
+ throw new SwapKitError("helpers_invalid_response", {
41
+ status: response.status,
42
+ statusText: response.statusText,
43
+ message,
44
+ });
54
45
  }
55
46
 
56
47
  const body = await response.json();
57
48
 
58
49
  return options.onSuccess?.(body) || options.responseHandler?.(body) || body;
59
50
  } catch (error) {
60
- return options.onError?.(error) || console.error(error);
51
+ if (options.onError) {
52
+ return options.onError(error);
53
+ }
54
+ throw error;
61
55
  }
62
56
  };
63
57
  }
58
+
59
+ function buildHeaders(isJson: boolean, headersOptions?: HeadersInit) {
60
+ const { swapKit } = SKConfig.get("apiKeys");
61
+
62
+ return {
63
+ ...headersOptions,
64
+ ...(isJson ? { "Content-Type": "application/json" } : {}),
65
+ ...(swapKit ? { "x-api-key": swapKit } : {}),
66
+ };
67
+ }
68
+
69
+ function buildUrl(url: string, searchParams?: Record<string, string>) {
70
+ const urlInstance = new URL(url);
71
+
72
+ if (searchParams) {
73
+ urlInstance.search = new URLSearchParams(searchParams).toString();
74
+ }
75
+
76
+ return urlInstance.toString();
77
+ }