@swapkit/helpers 1.0.0-rc.99 → 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.
@@ -1,17 +1,131 @@
1
+ import { SwapKitError } from "../modules/swapKitError";
1
2
  import { Chain } from "../types/chains";
2
3
  import { MemoType } from "../types/sdk";
3
4
 
4
- export type ThornameRegisterParam = {
5
- name: string;
6
- chain: string;
7
- address: string;
8
- owner?: string;
9
- preferredAsset?: string;
10
- expiryBlock?: string;
11
- };
12
-
13
5
  type WithChain<T extends {}> = T & { chain: Chain };
14
6
 
7
+ type WithAffiliate<T extends {}> = T & { affiliateAddress?: string; affiliateBasisPoints?: number };
8
+
9
+ function addAffiliate(memo: string, { affiliateAddress, affiliateBasisPoints }: WithAffiliate<{}>) {
10
+ const affiliatePart = affiliateAddress ? `:${affiliateAddress}:${affiliateBasisPoints || 0}` : "";
11
+
12
+ return `${memo}${affiliatePart}`;
13
+ }
14
+
15
+ function getPoolIdentifier({ chain, symbol }: { chain: Chain; symbol: string }) {
16
+ switch (chain) {
17
+ case Chain.Bitcoin:
18
+ case Chain.Dogecoin:
19
+ case Chain.Litecoin:
20
+ return chain.slice(0, 1).toLowerCase();
21
+ case Chain.BitcoinCash:
22
+ return "c";
23
+
24
+ default:
25
+ return `${chain}.${symbol}`;
26
+ }
27
+ }
28
+
29
+ export function getMemoForLeaveAndBond({
30
+ type,
31
+ address,
32
+ }: { type: MemoType.BOND | MemoType.LEAVE; address: string }) {
33
+ return `${type}:${address}`;
34
+ }
35
+
36
+ export function getMemoForUnbond({
37
+ address,
38
+ unbondAmount,
39
+ }: { address: string; unbondAmount: number }) {
40
+ return `${MemoType.UNBOND}:${address}:${unbondAmount}`;
41
+ }
42
+
43
+ export function getMemoForNameRegister({
44
+ name,
45
+ chain,
46
+ address,
47
+ owner,
48
+ }: { name: string; chain: string; address: string; owner?: string }) {
49
+ const baseMemo = `${MemoType.NAME_REGISTER}:${name}:${chain}:${address}`;
50
+ const ownerAssignmentOrChangePart = owner ? `:${owner}` : "";
51
+
52
+ return `${baseMemo}${ownerAssignmentOrChangePart}`;
53
+ }
54
+
55
+ export function getMemoForLoan(
56
+ memoType: MemoType.OPEN_LOAN | MemoType.CLOSE_LOAN,
57
+ {
58
+ asset,
59
+ address,
60
+ minAmount,
61
+ ...affiliate
62
+ }: WithAffiliate<{
63
+ address: string;
64
+ asset: string;
65
+ minAmount?: string;
66
+ }>,
67
+ ) {
68
+ const baseMemo = `${memoType}:${asset}:${address}`;
69
+ const minAmountPart = minAmount ? `:${minAmount}` : "";
70
+
71
+ return addAffiliate(`${baseMemo}${minAmountPart}`, affiliate);
72
+ }
73
+
74
+ export function getMemoForSaverDeposit({
75
+ chain,
76
+ symbol,
77
+ ...affiliate
78
+ }: WithAffiliate<{ chain: Chain; symbol: string }>) {
79
+ return addAffiliate(`${MemoType.DEPOSIT}:${chain}/${symbol}`, affiliate);
80
+ }
81
+
82
+ export function getMemoForDeposit({
83
+ chain,
84
+ symbol,
85
+ address,
86
+ }: { chain: Chain; symbol: string; address?: string }) {
87
+ const poolIdentifier = getPoolIdentifier({ chain, symbol });
88
+ const addressPart = address ? `:${address}` : "";
89
+
90
+ return `${MemoType.DEPOSIT}:${poolIdentifier}${addressPart}`;
91
+ }
92
+
93
+ export function getMemoForSaverWithdraw({
94
+ chain,
95
+ symbol,
96
+ basisPoints,
97
+ ...affiliate
98
+ }: WithAffiliate<{ chain: Chain; symbol: string; basisPoints: number }>) {
99
+ return addAffiliate(`${MemoType.WITHDRAW}:${chain}/${symbol}:${basisPoints}`, affiliate);
100
+ }
101
+
102
+ export function getMemoForWithdraw({
103
+ chain,
104
+ symbol,
105
+ ticker,
106
+ basisPoints,
107
+ targetAsset,
108
+ ...affiliate
109
+ }: WithAffiliate<{
110
+ chain: Chain;
111
+ symbol: string;
112
+ ticker: string;
113
+ basisPoints: number;
114
+ targetAsset?: string;
115
+ }>) {
116
+ const shortenedSymbol =
117
+ chain === "ETH" && ticker !== "ETH" ? `${ticker}-${symbol.slice(-3)}` : symbol;
118
+ const targetPart = targetAsset ? `:${targetAsset}` : "";
119
+
120
+ return addAffiliate(
121
+ `${MemoType.WITHDRAW}:${chain}.${shortenedSymbol}:${basisPoints}${targetPart}`,
122
+ affiliate,
123
+ );
124
+ }
125
+
126
+ /**
127
+ * @deprecated - Use separate functions per each memo type like getMemoForDeposit, getMemoForWithdraw, etc.
128
+ */
15
129
  export type MemoOptions<T extends MemoType> = {
16
130
  [MemoType.BOND]: { address: string };
17
131
  [MemoType.LEAVE]: { address: string };
@@ -26,68 +140,65 @@ export type MemoOptions<T extends MemoType> = {
26
140
  targetAssetString?: string;
27
141
  singleSide?: boolean;
28
142
  }>;
29
- [MemoType.THORNAME_REGISTER]: Omit<ThornameRegisterParam, "preferredAsset" | "expiryBlock">;
143
+ [MemoType.NAME_REGISTER]: { name: string; chain: string; address: string };
30
144
  }[T];
31
145
 
146
+ /**
147
+ * @deprecated - Use separate functions per each memo type like getMemoForDeposit, getMemoForWithdraw, etc.
148
+ */
32
149
  export const getMemoFor = <T extends MemoType>(memoType: T, options: MemoOptions<T>) => {
33
150
  switch (memoType) {
34
151
  case MemoType.LEAVE:
35
152
  case MemoType.BOND: {
36
153
  const { address } = options as MemoOptions<MemoType.BOND>;
37
- return `${memoType}:${address}`;
154
+ return getMemoForLeaveAndBond({ type: memoType, address });
38
155
  }
39
156
 
40
157
  case MemoType.UNBOND: {
41
158
  const { address, unbondAmount } = options as MemoOptions<MemoType.UNBOND>;
42
- return `${memoType}:${address}:${unbondAmount}`;
159
+ return getMemoForUnbond({ address, unbondAmount });
43
160
  }
44
161
 
45
- case MemoType.THORNAME_REGISTER: {
46
- const { name, chain, address, owner } = options as MemoOptions<MemoType.THORNAME_REGISTER>;
47
- return `${memoType}:${name}:${chain}:${address}${owner ? `:${owner}` : ""}`;
162
+ case MemoType.NAME_REGISTER: {
163
+ return getMemoForNameRegister(options as MemoOptions<MemoType.NAME_REGISTER>);
164
+ }
165
+
166
+ case MemoType.OPEN_LOAN:
167
+ case MemoType.CLOSE_LOAN: {
168
+ return getMemoForLoan(memoType, options as MemoOptions<MemoType.OPEN_LOAN>);
48
169
  }
49
170
 
50
171
  case MemoType.DEPOSIT: {
51
172
  const { chain, symbol, address, singleSide } = options as MemoOptions<MemoType.DEPOSIT>;
52
173
 
53
- const getPoolIdentifier = (chain: Chain, symbol: string): string => {
54
- switch (chain) {
55
- case Chain.Litecoin:
56
- return "l";
57
- case Chain.Dogecoin:
58
- return "d";
59
- case Chain.BitcoinCash:
60
- return "c";
61
- default:
62
- return `${chain}.${symbol}`;
63
- }
64
- };
65
-
66
- return singleSide
67
- ? `${memoType}:${chain}/${symbol}`
68
- : `${memoType}:${getPoolIdentifier(chain, symbol)}:${address || ""}`;
174
+ if (singleSide) {
175
+ return getMemoForSaverDeposit({ chain, symbol });
176
+ }
177
+
178
+ return getMemoForDeposit({ chain, symbol, address });
69
179
  }
70
180
 
71
181
  case MemoType.WITHDRAW: {
72
- const { chain, ticker, symbol, basisPoints, targetAssetString, singleSide } =
73
- options as MemoOptions<MemoType.WITHDRAW>;
182
+ const {
183
+ chain,
184
+ ticker,
185
+ symbol,
186
+ basisPoints,
187
+ targetAssetString: targetAsset,
188
+ singleSide,
189
+ } = options as MemoOptions<MemoType.WITHDRAW>;
74
190
 
75
- const shortenedSymbol =
76
- chain === "ETH" && ticker !== "ETH" ? `${ticker}-${symbol.slice(-3)}` : symbol;
77
- const target = !singleSide && targetAssetString ? `:${targetAssetString}` : "";
78
- const assetDivider = singleSide ? "/" : ".";
79
-
80
- return `${memoType}:${chain}${assetDivider}${shortenedSymbol}:${basisPoints}${target}`;
81
- }
82
-
83
- case MemoType.OPEN_LOAN:
84
- case MemoType.CLOSE_LOAN: {
85
- const { asset, address } = options as MemoOptions<MemoType.OPEN_LOAN>;
191
+ if (singleSide) {
192
+ return getMemoForSaverWithdraw({ chain, symbol, basisPoints });
193
+ }
86
194
 
87
- return `${memoType}:${asset}:${address}`; //:${minAmount ? `${minAmount}` : ''}:t:0`;
195
+ return getMemoForWithdraw({ chain, ticker, symbol, basisPoints, targetAsset });
88
196
  }
89
197
 
90
198
  default:
91
- return "";
199
+ throw new SwapKitError({
200
+ errorKey: "helpers_invalid_memo_type",
201
+ info: { memoType },
202
+ });
92
203
  }
93
204
  };
@@ -1,17 +1,26 @@
1
1
  import { type ErrorKeys, SwapKitError } from "../modules/swapKitError";
2
+ import { Chain } from "../types";
2
3
  import type { DerivationPathArray } from "../types/derivationPath";
3
4
 
4
5
  // 10 rune for register, 1 rune per year
5
6
  // MINIMUM_REGISTRATION_FEE = 11
6
7
  export function getTHORNameCost(numberOfYears: number) {
7
- if (numberOfYears < 0) throw new Error("Invalid number of years");
8
+ if (numberOfYears < 0)
9
+ throw new SwapKitError({
10
+ errorKey: "helpers_invalid_number_of_years",
11
+ info: { numberOfYears },
12
+ });
8
13
  return 10 + numberOfYears;
9
14
  }
10
15
 
11
16
  // 10 CACAO for register
12
17
  // 1.0512 CACAO per year
13
18
  export function getMAYANameCost(numberOfYears: number) {
14
- if (numberOfYears < 0) throw new Error("Invalid number of year");
19
+ if (numberOfYears < 0)
20
+ throw new SwapKitError({
21
+ errorKey: "helpers_invalid_number_of_years",
22
+ info: { numberOfYears },
23
+ });
15
24
  // round to max 10 decimals
16
25
  return Math.round((10 + numberOfYears * 1.0512) * 1e10) / 1e10;
17
26
  }
@@ -35,3 +44,19 @@ export function wrapWithThrow<T>(fn: () => T, errorKey?: ErrorKeys) {
35
44
  return console.error(error);
36
45
  }
37
46
  }
47
+
48
+ export const getChainIdentifier = (chain: Chain) => {
49
+ switch (chain) {
50
+ case Chain.THORChain:
51
+ return `${chain}.RUNE`;
52
+
53
+ case Chain.Cosmos:
54
+ return `${chain}.ATOM`;
55
+
56
+ case Chain.BinanceSmartChain:
57
+ return `${chain}`;
58
+
59
+ default:
60
+ return `${chain}.${chain}`;
61
+ }
62
+ };
@@ -1,3 +1,4 @@
1
+ import { SwapKitError } from "../modules/swapKitError";
1
2
  import { Chain } from "../types/chains";
2
3
 
3
4
  // Backward compatibility
@@ -12,9 +13,13 @@ export function validateIdentifier(identifier = "") {
12
13
  const [synthChain] = uppercasedIdentifier.split("/") as [Chain, string];
13
14
  if (supportedChains.includes(synthChain)) return true;
14
15
 
15
- throw new Error(
16
- `Invalid identifier: ${identifier}. Expected format: <Chain>.<Ticker> or <Chain>.<Ticker>-<ContractAddress>`,
17
- );
16
+ throw new SwapKitError({
17
+ errorKey: "helpers_invalid_identifier",
18
+ info: {
19
+ message: `Invalid identifier: ${identifier}. Expected format: <Chain>.<Ticker> or <Chain>.<Ticker>-<ContractAddress>`,
20
+ identifier,
21
+ },
22
+ });
18
23
  }
19
24
 
20
25
  export function validateTNS(name: string) {
@@ -1,5 +1,11 @@
1
1
  import type { BrowserProvider } from "ethers";
2
- import { ChainId, WalletOption } from "../types";
2
+ import { SwapKitError } from "../modules/swapKitError";
3
+ import {
4
+ ChainId,
5
+ type EIP6963AnnounceProviderEvent,
6
+ type EIP6963Provider,
7
+ WalletOption,
8
+ } from "../types";
3
9
 
4
10
  export type EthereumWindowProvider = BrowserProvider & {
5
11
  __XDEFI?: boolean;
@@ -8,6 +14,7 @@ export type EthereumWindowProvider = BrowserProvider & {
8
14
  isMetaMask?: boolean;
9
15
  isOkxWallet?: boolean;
10
16
  isTrust?: boolean;
17
+ isTalisman?: boolean;
11
18
  on: (event: string, callback?: () => void) => void;
12
19
  overrideIsMetaMask?: boolean;
13
20
  request: <T = unknown>(args: { method: string; params?: unknown[] }) => Promise<T>;
@@ -79,13 +86,18 @@ export const wrapMethodWithNetworkSwitch = <T extends (...args: Todo[]) => Todo>
79
86
  try {
80
87
  await switchEVMWalletNetwork(provider, chainId);
81
88
  } catch (error) {
82
- throw new Error(`Failed to switch network: ${error}`);
89
+ throw new SwapKitError({
90
+ errorKey: "helpers_failed_to_switch_network",
91
+ info: { error },
92
+ });
83
93
  }
84
94
  return func(...args);
85
95
  }) as unknown as T;
86
96
 
87
97
  const providerRequest = ({ provider, params, method }: ProviderRequestParams) => {
88
- if (!provider?.send) throw new Error("Provider not found");
98
+ if (!provider?.send) {
99
+ throw new SwapKitError("helpers_not_found_provider");
100
+ }
89
101
 
90
102
  const providerParams = params ? (Array.isArray(params) ? params : [params]) : [];
91
103
  return provider.send(method, providerParams);
@@ -142,7 +154,7 @@ export const isDetected = (walletOption: WalletOption) => {
142
154
  return listWeb3EVMWallets().includes(walletOption);
143
155
  };
144
156
 
145
- const listWeb3EVMWallets = () => {
157
+ export const listWeb3EVMWallets = () => {
146
158
  const metamaskEnabled = window?.ethereum && !window.ethereum?.isBraveWallet;
147
159
  // @ts-ignore that should be implemented in xdefi and hooked up via swapkit core
148
160
  const xdefiEnabled = window?.xfi || window?.ethereum?.__XDEFI;
@@ -164,6 +176,24 @@ const listWeb3EVMWallets = () => {
164
176
  return wallets;
165
177
  };
166
178
 
179
+ export function getEIP6963Wallets() {
180
+ const providers: EIP6963Provider[] = [];
181
+
182
+ function onAnnouncement(event: EIP6963AnnounceProviderEvent) {
183
+ if (providers.map((p) => p.info.uuid).includes(event.detail.info.uuid)) return;
184
+ providers.push(event.detail);
185
+ }
186
+
187
+ window.addEventListener("eip6963:announceProvider", onAnnouncement);
188
+ window.dispatchEvent(new Event("eip6963:requestProvider"));
189
+
190
+ function removeEIP6963EventListener() {
191
+ window.removeEventListener("eip6963:announceProvider", onAnnouncement);
192
+ }
193
+
194
+ return { providers, removeEIP6963EventListener };
195
+ }
196
+
167
197
  export const okxMobileEnabled = () => {
168
198
  const ua = navigator.userAgent;
169
199
  const isIOS = /iphone|ipad|ipod|ios/i.test(ua);