@swapkit/helpers 1.0.0-rc.98 → 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.
- package/dist/index.js +2 -2440
- package/dist/index.js.map +24 -23
- package/package.json +7 -14
- package/src/helpers/__tests__/asset.test.ts +40 -8
- package/src/helpers/__tests__/memo.test.ts +55 -74
- package/src/helpers/__tests__/others.test.ts +5 -3
- package/src/helpers/asset.ts +80 -26
- package/src/helpers/derivationPath.ts +5 -4
- package/src/helpers/memo.ts +157 -46
- package/src/helpers/others.ts +27 -2
- package/src/helpers/validators.ts +8 -3
- package/src/helpers/web3wallets.ts +34 -4
- package/src/modules/__tests__/assetValue.test.ts +183 -114
- package/src/modules/assetValue.ts +143 -101
- package/src/modules/bigIntArithmetics.ts +2 -6
- package/src/modules/requestClient.ts +22 -12
- package/src/modules/swapKitError.ts +78 -21
- package/src/types/chains.ts +12 -18
- package/src/types/commonTypes.ts +4 -0
- package/src/types/derivationPath.ts +4 -2
- package/src/types/errors/apiV1.ts +0 -0
- package/src/types/index.ts +2 -0
- package/src/types/network.ts +5 -3
- package/src/types/quotes.ts +391 -0
- package/src/types/radix.ts +14 -0
- package/src/types/sdk.ts +87 -5
- package/src/types/tokens.ts +18 -14
- package/src/types/wallet.ts +44 -19
package/src/helpers/memo.ts
CHANGED
|
@@ -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.
|
|
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
|
|
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
|
|
159
|
+
return getMemoForUnbond({ address, unbondAmount });
|
|
43
160
|
}
|
|
44
161
|
|
|
45
|
-
case MemoType.
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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 {
|
|
73
|
-
|
|
182
|
+
const {
|
|
183
|
+
chain,
|
|
184
|
+
ticker,
|
|
185
|
+
symbol,
|
|
186
|
+
basisPoints,
|
|
187
|
+
targetAssetString: targetAsset,
|
|
188
|
+
singleSide,
|
|
189
|
+
} = options as MemoOptions<MemoType.WITHDRAW>;
|
|
74
190
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
|
195
|
+
return getMemoForWithdraw({ chain, ticker, symbol, basisPoints, targetAsset });
|
|
88
196
|
}
|
|
89
197
|
|
|
90
198
|
default:
|
|
91
|
-
|
|
199
|
+
throw new SwapKitError({
|
|
200
|
+
errorKey: "helpers_invalid_memo_type",
|
|
201
|
+
info: { memoType },
|
|
202
|
+
});
|
|
92
203
|
}
|
|
93
204
|
};
|
package/src/helpers/others.ts
CHANGED
|
@@ -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)
|
|
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)
|
|
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
|
|
16
|
-
|
|
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 {
|
|
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
|
|
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)
|
|
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);
|