@swapkit/helpers 1.0.0-rc.10 → 1.0.0-rc.100
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 +2452 -0
- package/dist/index.js.map +30 -0
- package/package.json +24 -37
- package/src/helpers/__tests__/asset.test.ts +149 -105
- package/src/helpers/__tests__/memo.test.ts +52 -40
- package/src/helpers/__tests__/others.test.ts +42 -37
- package/src/helpers/__tests__/validators.test.ts +24 -0
- package/src/helpers/asset.ts +130 -94
- package/src/helpers/derivationPath.ts +53 -0
- package/src/helpers/liquidity.ts +50 -43
- package/src/helpers/memo.ts +31 -28
- package/src/helpers/others.ts +30 -13
- package/src/helpers/validators.ts +15 -6
- package/src/helpers/web3wallets.ts +177 -0
- package/src/index.ts +14 -9
- package/src/modules/__tests__/assetValue.test.ts +414 -117
- package/src/modules/__tests__/bigIntArithmetics.test.ts +30 -0
- package/src/modules/__tests__/swapKitNumber.test.ts +306 -183
- package/src/modules/assetValue.ts +218 -152
- package/src/modules/bigIntArithmetics.ts +214 -165
- package/src/modules/requestClient.ts +39 -0
- package/src/modules/swapKitError.ts +33 -5
- package/src/modules/swapKitNumber.ts +8 -1
- package/src/types/abis/erc20.ts +99 -0
- package/src/types/abis/mayaEvmVaults.ts +331 -0
- package/src/types/abis/tcEthVault.ts +496 -0
- package/src/types/chains.ts +220 -0
- package/src/types/commonTypes.ts +119 -0
- package/src/types/derivationPath.ts +56 -0
- package/src/types/errors/apiV1.ts +0 -0
- package/src/types/index.ts +10 -0
- package/src/types/network.ts +43 -0
- package/src/types/sdk.ts +44 -0
- package/src/types/tokens.ts +30 -0
- package/src/types/wallet.ts +47 -0
- package/LICENSE +0 -201
- package/dist/index.cjs +0 -1
- package/dist/index.d.ts +0 -355
- package/dist/index.es.js +0 -1064
- package/src/helpers/request.ts +0 -16
package/src/helpers/asset.ts
CHANGED
|
@@ -1,55 +1,65 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { BaseDecimal, Chain, ChainToRPC,
|
|
1
|
+
import { RequestClient } from "../modules/requestClient.ts";
|
|
2
|
+
import { BaseDecimal, Chain, ChainToRPC, type EVMChain, EVMChains } from "../types/chains.ts";
|
|
3
|
+
import type { TokenNames } from "../types/tokens.ts";
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
const getDecimalMethodHex = "0x313ce567";
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
export type CommonAssetString =
|
|
8
|
+
| `${Chain.Maya}.MAYA`
|
|
9
|
+
| `${Chain.Ethereum}.THOR`
|
|
10
|
+
| `${Chain.Ethereum}.vTHOR`
|
|
11
|
+
| `${Chain.Kujira}.USK`
|
|
12
|
+
| Chain;
|
|
9
13
|
|
|
10
14
|
const getContractDecimals = async ({ chain, to }: { chain: EVMChain; to: string }) => {
|
|
11
15
|
try {
|
|
12
16
|
const { result } = await RequestClient.post<{ result: string }>(ChainToRPC[chain], {
|
|
13
|
-
headers: {
|
|
17
|
+
headers: {
|
|
18
|
+
accept: "*/*",
|
|
19
|
+
"content-type": "application/json",
|
|
20
|
+
"cache-control": "no-cache",
|
|
21
|
+
},
|
|
14
22
|
body: JSON.stringify({
|
|
15
23
|
id: 44,
|
|
16
|
-
jsonrpc:
|
|
17
|
-
method:
|
|
18
|
-
params: [{ to: to.toLowerCase(), data: getDecimalMethodHex },
|
|
24
|
+
jsonrpc: "2.0",
|
|
25
|
+
method: "eth_call",
|
|
26
|
+
params: [{ to: to.toLowerCase(), data: getDecimalMethodHex }, "latest"],
|
|
19
27
|
}),
|
|
20
28
|
});
|
|
21
29
|
|
|
22
|
-
return parseInt(BigInt(result).toString());
|
|
30
|
+
return Number.parseInt(BigInt(result || BaseDecimal[chain]).toString());
|
|
23
31
|
} catch (error) {
|
|
24
32
|
console.error(error);
|
|
25
33
|
return BaseDecimal[chain];
|
|
26
34
|
}
|
|
27
35
|
};
|
|
28
36
|
|
|
29
|
-
const getETHAssetDecimal =
|
|
37
|
+
const getETHAssetDecimal = (symbol: string) => {
|
|
30
38
|
if (symbol === Chain.Ethereum) return BaseDecimal.ETH;
|
|
31
|
-
const
|
|
39
|
+
const splitSymbol = symbol.split("-");
|
|
40
|
+
const address = splitSymbol.length === 1 ? undefined : splitSymbol[splitSymbol.length - 1];
|
|
32
41
|
|
|
33
|
-
return address?.startsWith(
|
|
42
|
+
return address?.startsWith("0x")
|
|
34
43
|
? getContractDecimals({ chain: Chain.Ethereum, to: address })
|
|
35
44
|
: BaseDecimal.ETH;
|
|
36
45
|
};
|
|
37
46
|
|
|
38
|
-
const getAVAXAssetDecimal =
|
|
39
|
-
const
|
|
47
|
+
const getAVAXAssetDecimal = (symbol: string) => {
|
|
48
|
+
const splitSymbol = symbol.split("-");
|
|
49
|
+
const address = splitSymbol.length === 1 ? undefined : splitSymbol[splitSymbol.length - 1];
|
|
40
50
|
|
|
41
|
-
return address?.startsWith(
|
|
51
|
+
return address?.startsWith("0x")
|
|
42
52
|
? getContractDecimals({ chain: Chain.Avalanche, to: address.toLowerCase() })
|
|
43
53
|
: BaseDecimal.AVAX;
|
|
44
54
|
};
|
|
45
55
|
|
|
46
|
-
const getBSCAssetDecimal =
|
|
56
|
+
const getBSCAssetDecimal = (symbol: string) => {
|
|
47
57
|
if (symbol === Chain.BinanceSmartChain) return BaseDecimal.BSC;
|
|
48
58
|
|
|
49
59
|
return BaseDecimal.BSC;
|
|
50
60
|
};
|
|
51
61
|
|
|
52
|
-
export const getDecimal =
|
|
62
|
+
export const getDecimal = ({ chain, symbol }: { chain: Chain; symbol: string }) => {
|
|
53
63
|
switch (chain) {
|
|
54
64
|
case Chain.Ethereum:
|
|
55
65
|
return getETHAssetDecimal(symbol);
|
|
@@ -62,41 +72,26 @@ export const getDecimal = async ({ chain, symbol }: { chain: Chain; symbol: stri
|
|
|
62
72
|
}
|
|
63
73
|
};
|
|
64
74
|
|
|
65
|
-
export const gasFeeMultiplier: Record<FeeOption, number> = {
|
|
66
|
-
[FeeOption.Average]: 1.2,
|
|
67
|
-
[FeeOption.Fast]: 1.5,
|
|
68
|
-
[FeeOption.Fastest]: 2,
|
|
69
|
-
};
|
|
70
|
-
|
|
71
75
|
export const isGasAsset = ({ chain, symbol }: { chain: Chain; symbol: string }) => {
|
|
72
76
|
switch (chain) {
|
|
73
|
-
case Chain.Bitcoin:
|
|
74
|
-
case Chain.BitcoinCash:
|
|
75
|
-
case Chain.Litecoin:
|
|
76
|
-
case Chain.Dogecoin:
|
|
77
|
-
case Chain.Binance:
|
|
78
|
-
case Chain.Ethereum:
|
|
79
|
-
case Chain.Avalanche:
|
|
80
|
-
return symbol === chain;
|
|
81
|
-
|
|
82
77
|
case Chain.Arbitrum:
|
|
83
78
|
case Chain.Optimism:
|
|
84
|
-
return
|
|
85
|
-
|
|
79
|
+
return symbol === "ETH";
|
|
86
80
|
case Chain.Maya:
|
|
87
|
-
return symbol ===
|
|
88
|
-
|
|
81
|
+
return symbol === "CACAO";
|
|
89
82
|
case Chain.Kujira:
|
|
90
|
-
return symbol ===
|
|
91
|
-
|
|
83
|
+
return symbol === "KUJI";
|
|
92
84
|
case Chain.Cosmos:
|
|
93
|
-
return symbol ===
|
|
85
|
+
return symbol === "ATOM";
|
|
94
86
|
case Chain.Polygon:
|
|
95
|
-
return symbol ===
|
|
87
|
+
return symbol === "MATIC";
|
|
96
88
|
case Chain.BinanceSmartChain:
|
|
97
|
-
return symbol ===
|
|
89
|
+
return symbol === "BNB";
|
|
98
90
|
case Chain.THORChain:
|
|
99
|
-
return symbol ===
|
|
91
|
+
return symbol === "RUNE";
|
|
92
|
+
|
|
93
|
+
default:
|
|
94
|
+
return symbol === chain;
|
|
100
95
|
}
|
|
101
96
|
};
|
|
102
97
|
|
|
@@ -104,86 +99,127 @@ export const getCommonAssetInfo = (
|
|
|
104
99
|
assetString: CommonAssetString,
|
|
105
100
|
): { identifier: string; decimal: number } => {
|
|
106
101
|
switch (assetString) {
|
|
107
|
-
case
|
|
108
|
-
return { identifier:
|
|
109
|
-
case
|
|
110
|
-
return { identifier:
|
|
111
|
-
|
|
102
|
+
case `${Chain.Ethereum}.THOR`:
|
|
103
|
+
return { identifier: "ETH.THOR-0xa5f2211b9b8170f694421f2046281775e8468044", decimal: 18 };
|
|
104
|
+
case `${Chain.Ethereum}.vTHOR`:
|
|
105
|
+
return { identifier: "ETH.vTHOR-0x815c23eca83261b6ec689b60cc4a58b54bc24d8d", decimal: 18 };
|
|
106
|
+
case Chain.Arbitrum:
|
|
107
|
+
return { identifier: `${Chain.Arbitrum}.ETH`, decimal: BaseDecimal[assetString] };
|
|
108
|
+
case Chain.Optimism:
|
|
109
|
+
return { identifier: `${Chain.Optimism}.ETH`, decimal: BaseDecimal[assetString] };
|
|
112
110
|
case Chain.Cosmos:
|
|
113
|
-
return { identifier:
|
|
111
|
+
return { identifier: "GAIA.ATOM", decimal: BaseDecimal[assetString] };
|
|
114
112
|
case Chain.THORChain:
|
|
115
|
-
return { identifier:
|
|
113
|
+
return { identifier: "THOR.RUNE", decimal: BaseDecimal[assetString] };
|
|
116
114
|
case Chain.BinanceSmartChain:
|
|
117
|
-
return { identifier:
|
|
115
|
+
return { identifier: "BSC.BNB", decimal: BaseDecimal[assetString] };
|
|
118
116
|
case Chain.Maya:
|
|
119
|
-
return { identifier:
|
|
120
|
-
case
|
|
121
|
-
return { identifier:
|
|
117
|
+
return { identifier: "MAYA.CACAO", decimal: BaseDecimal.MAYA };
|
|
118
|
+
case `${Chain.Maya}.MAYA`:
|
|
119
|
+
return { identifier: "MAYA.MAYA", decimal: 4 };
|
|
122
120
|
|
|
123
|
-
case Chain.Kujira
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
case Chain.Litecoin:
|
|
128
|
-
case Chain.Dogecoin:
|
|
129
|
-
case Chain.Binance:
|
|
130
|
-
case Chain.Avalanche:
|
|
131
|
-
case Chain.Polygon:
|
|
132
|
-
case Chain.Bitcoin:
|
|
133
|
-
case Chain.Ethereum:
|
|
121
|
+
case `${Chain.Kujira}.USK`:
|
|
122
|
+
return { identifier: `${Chain.Kujira}.USK`, decimal: 6 };
|
|
123
|
+
|
|
124
|
+
default:
|
|
134
125
|
return { identifier: `${assetString}.${assetString}`, decimal: BaseDecimal[assetString] };
|
|
135
126
|
}
|
|
136
127
|
};
|
|
137
128
|
|
|
129
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: TODO: Refactor
|
|
138
130
|
export const getAssetType = ({ chain, symbol }: { chain: Chain; symbol: string }) => {
|
|
139
|
-
if (symbol.includes(
|
|
131
|
+
if (symbol.includes("/")) return "Synth";
|
|
140
132
|
|
|
141
133
|
switch (chain) {
|
|
142
|
-
case Chain.Bitcoin:
|
|
143
|
-
case Chain.BitcoinCash:
|
|
144
|
-
case Chain.Dogecoin:
|
|
145
|
-
case Chain.Litecoin:
|
|
146
|
-
case Chain.Maya:
|
|
147
|
-
case Chain.THORChain:
|
|
148
|
-
return 'Native';
|
|
149
|
-
|
|
150
134
|
case Chain.Cosmos:
|
|
151
|
-
return symbol ===
|
|
135
|
+
return symbol === "ATOM" ? "Native" : Chain.Cosmos;
|
|
152
136
|
case Chain.Kujira:
|
|
153
|
-
return symbol === Chain.Kujira ?
|
|
137
|
+
return symbol === Chain.Kujira ? "Native" : Chain.Kujira;
|
|
154
138
|
case Chain.Binance:
|
|
155
|
-
return symbol === Chain.Binance ?
|
|
139
|
+
return symbol === Chain.Binance ? "Native" : "BEP2";
|
|
156
140
|
case Chain.BinanceSmartChain:
|
|
157
|
-
return symbol === Chain.Binance ?
|
|
141
|
+
return symbol === Chain.Binance ? "Native" : "BEP20";
|
|
158
142
|
case Chain.Ethereum:
|
|
159
|
-
return symbol === Chain.Ethereum ?
|
|
143
|
+
return symbol === Chain.Ethereum ? "Native" : "ERC20";
|
|
160
144
|
case Chain.Avalanche:
|
|
161
|
-
return symbol === Chain.Avalanche ?
|
|
145
|
+
return symbol === Chain.Avalanche ? "Native" : Chain.Avalanche;
|
|
162
146
|
case Chain.Polygon:
|
|
163
|
-
return symbol === Chain.Polygon ?
|
|
147
|
+
return symbol === Chain.Polygon ? "Native" : "POLYGON";
|
|
164
148
|
|
|
165
149
|
case Chain.Arbitrum:
|
|
166
|
-
return [Chain.Ethereum, Chain.Arbitrum].includes(symbol as Chain) ?
|
|
150
|
+
return [Chain.Ethereum, Chain.Arbitrum].includes(symbol as Chain) ? "Native" : "ARBITRUM";
|
|
167
151
|
case Chain.Optimism:
|
|
168
|
-
return [Chain.Ethereum, Chain.Optimism].includes(symbol as Chain) ?
|
|
152
|
+
return [Chain.Ethereum, Chain.Optimism].includes(symbol as Chain) ? "Native" : "OPTIMISM";
|
|
153
|
+
|
|
154
|
+
default:
|
|
155
|
+
return "Native";
|
|
169
156
|
}
|
|
170
157
|
};
|
|
171
158
|
|
|
172
159
|
export const assetFromString = (assetString: string) => {
|
|
173
|
-
const [chain, ...symbolArray] = assetString.split(
|
|
174
|
-
const synth = assetString.includes(
|
|
175
|
-
const symbol = symbolArray.join(
|
|
176
|
-
const
|
|
160
|
+
const [chain, ...symbolArray] = assetString.split(".") as [Chain, ...(string | undefined)[]];
|
|
161
|
+
const synth = assetString.includes("/");
|
|
162
|
+
const symbol = symbolArray.join(".");
|
|
163
|
+
const splitSymbol = symbol?.split("-");
|
|
164
|
+
const ticker = splitSymbol?.length
|
|
165
|
+
? splitSymbol.length === 1
|
|
166
|
+
? splitSymbol[0]
|
|
167
|
+
: splitSymbol.slice(0, -1).join("-")
|
|
168
|
+
: undefined;
|
|
177
169
|
|
|
178
170
|
return { chain, symbol, ticker, synth };
|
|
179
171
|
};
|
|
180
172
|
|
|
181
173
|
const potentialScamRegex = new RegExp(
|
|
182
174
|
/(.)\1{6}|\.ORG|\.NET|\.FINANCE|\.COM|WWW|HTTP|\\\\|\/\/|[\s$%:[\]]/,
|
|
183
|
-
|
|
175
|
+
"gmi",
|
|
184
176
|
);
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
);
|
|
177
|
+
|
|
178
|
+
const evmAssetHasAddress = (assetString: string) => {
|
|
179
|
+
const [chain, symbol] = assetString.split(".") as [EVMChain, string];
|
|
180
|
+
if (!EVMChains.includes(chain as EVMChain)) return true;
|
|
181
|
+
const splitSymbol = symbol.split("-");
|
|
182
|
+
const address = splitSymbol.length === 1 ? undefined : splitSymbol[splitSymbol.length - 1];
|
|
183
|
+
|
|
184
|
+
return isGasAsset({ chain: chain as Chain, symbol }) || !!address;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
export const filterAssets = (
|
|
188
|
+
tokens: {
|
|
189
|
+
value: string;
|
|
190
|
+
decimal: number;
|
|
191
|
+
chain: Chain;
|
|
192
|
+
symbol: string;
|
|
193
|
+
}[],
|
|
194
|
+
) =>
|
|
195
|
+
tokens.filter(({ chain, value, symbol }) => {
|
|
196
|
+
const assetString = `${chain}.${symbol}`;
|
|
197
|
+
|
|
198
|
+
return (
|
|
199
|
+
!potentialScamRegex.test(assetString) && evmAssetHasAddress(assetString) && value !== "0"
|
|
200
|
+
);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
export async function findAssetBy(
|
|
204
|
+
params: { chain: EVMChain; contract: string } | { identifier: `${Chain}.${string}` },
|
|
205
|
+
) {
|
|
206
|
+
const tokenPackages = await import("@swapkit/tokens");
|
|
207
|
+
|
|
208
|
+
for (const tokenList of Object.values(tokenPackages)) {
|
|
209
|
+
for (const { identifier, chain: tokenChain, ...rest } of tokenList.tokens) {
|
|
210
|
+
if ("identifier" in params && identifier === params.identifier) {
|
|
211
|
+
return identifier as TokenNames;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (
|
|
215
|
+
"address" in rest &&
|
|
216
|
+
"chain" in params &&
|
|
217
|
+
tokenChain === params.chain &&
|
|
218
|
+
rest.address.toLowerCase() === params.contract.toLowerCase()
|
|
219
|
+
)
|
|
220
|
+
return identifier as TokenNames;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Chain,
|
|
3
|
+
type DerivationPathArray,
|
|
4
|
+
type EVMChain,
|
|
5
|
+
EVMChains,
|
|
6
|
+
NetworkDerivationPath,
|
|
7
|
+
} from "../types";
|
|
8
|
+
|
|
9
|
+
type Params = {
|
|
10
|
+
chain: Chain;
|
|
11
|
+
index: number;
|
|
12
|
+
addressIndex?: number;
|
|
13
|
+
type?: "legacy" | "ledgerLive" | "nativeSegwitMiddleAccount" | "segwit";
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const updatedLastIndex = (path: DerivationPathArray, index: number) => [
|
|
17
|
+
...path.slice(0, path.length - 1),
|
|
18
|
+
index,
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export function getDerivationPathFor({ chain, index, addressIndex = 0, type }: Params) {
|
|
22
|
+
if (EVMChains.includes(chain as EVMChain)) {
|
|
23
|
+
if (type === "legacy") return [44, 60, 0, index];
|
|
24
|
+
if (type === "ledgerLive") return [44, 60, index, 0, addressIndex];
|
|
25
|
+
return updatedLastIndex(NetworkDerivationPath[chain], index);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if ([Chain.Bitcoin, Chain.Litecoin].includes(chain)) {
|
|
29
|
+
const chainId = chain === Chain.Bitcoin ? 0 : 2;
|
|
30
|
+
|
|
31
|
+
if (type === "nativeSegwitMiddleAccount") return [84, chainId, index, 0, addressIndex];
|
|
32
|
+
if (type === "segwit") return [49, chainId, 0, 0, index];
|
|
33
|
+
if (type === "legacy") return [44, chainId, 0, 0, index];
|
|
34
|
+
return updatedLastIndex(NetworkDerivationPath[chain], index);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return updatedLastIndex(NetworkDerivationPath[chain], index);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function getWalletFormatFor(path: string) {
|
|
41
|
+
const [_, purpose, chainId] = path.split("/").map((p) => Number.parseInt(p, 10));
|
|
42
|
+
|
|
43
|
+
if (chainId === 145) "cashaddr";
|
|
44
|
+
|
|
45
|
+
switch (purpose) {
|
|
46
|
+
case 44:
|
|
47
|
+
return "legacy";
|
|
48
|
+
case 49:
|
|
49
|
+
return "p2sh";
|
|
50
|
+
default:
|
|
51
|
+
return "bech32";
|
|
52
|
+
}
|
|
53
|
+
}
|
package/src/helpers/liquidity.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SwapKitNumber } from "../index.ts";
|
|
2
|
+
import { BaseDecimal } from "../types/chains.ts";
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
type ShareParams<T = {}> = T & {
|
|
4
|
+
type ShareParams<T extends {}> = T & {
|
|
6
5
|
liquidityUnits: string;
|
|
7
6
|
poolUnits: string;
|
|
8
7
|
};
|
|
9
8
|
|
|
10
|
-
type PoolParams
|
|
9
|
+
type PoolParams = {
|
|
11
10
|
runeAmount: string;
|
|
12
11
|
assetAmount: string;
|
|
13
12
|
runeDepth: string;
|
|
@@ -25,11 +24,11 @@ type PoolParams<T = {}> = T & {
|
|
|
25
24
|
* share = (s * A * (2 * T^2 - 2 * T * s + s^2))/T^3
|
|
26
25
|
* (part1 * (part2 - part3 + part4)) / part5
|
|
27
26
|
*/
|
|
28
|
-
export
|
|
27
|
+
export function getAsymmetricRuneShare({
|
|
29
28
|
liquidityUnits,
|
|
30
29
|
poolUnits,
|
|
31
30
|
runeDepth,
|
|
32
|
-
}: ShareParams<{ runeDepth: string }>)
|
|
31
|
+
}: ShareParams<{ runeDepth: string }>) {
|
|
33
32
|
const s = toTCSwapKitNumber(liquidityUnits);
|
|
34
33
|
const T = toTCSwapKitNumber(poolUnits);
|
|
35
34
|
const A = toTCSwapKitNumber(runeDepth);
|
|
@@ -43,13 +42,13 @@ export const getAsymmetricRuneShare = ({
|
|
|
43
42
|
const numerator = part1.mul(part2.sub(part3).add(part4));
|
|
44
43
|
|
|
45
44
|
return numerator.div(part5);
|
|
46
|
-
}
|
|
45
|
+
}
|
|
47
46
|
|
|
48
|
-
export
|
|
47
|
+
export function getAsymmetricAssetShare({
|
|
49
48
|
liquidityUnits,
|
|
50
49
|
poolUnits,
|
|
51
50
|
assetDepth,
|
|
52
|
-
}: ShareParams<{ assetDepth: string }>)
|
|
51
|
+
}: ShareParams<{ assetDepth: string }>) {
|
|
53
52
|
const s = toTCSwapKitNumber(liquidityUnits);
|
|
54
53
|
const T = toTCSwapKitNumber(poolUnits);
|
|
55
54
|
const A = toTCSwapKitNumber(assetDepth);
|
|
@@ -62,28 +61,31 @@ export const getAsymmetricAssetShare = ({
|
|
|
62
61
|
const part5 = T.mul(T).mul(T);
|
|
63
62
|
|
|
64
63
|
return numerator.div(part5);
|
|
65
|
-
}
|
|
64
|
+
}
|
|
66
65
|
|
|
67
|
-
export
|
|
66
|
+
export function getAsymmetricRuneWithdrawAmount({
|
|
68
67
|
percent,
|
|
69
68
|
runeDepth,
|
|
70
69
|
liquidityUnits,
|
|
71
70
|
poolUnits,
|
|
72
|
-
}: ShareParams<{ percent: number; runeDepth: string }>)
|
|
73
|
-
getAsymmetricRuneShare({ runeDepth, liquidityUnits, poolUnits }).mul(percent);
|
|
71
|
+
}: ShareParams<{ percent: number; runeDepth: string }>) {
|
|
72
|
+
return getAsymmetricRuneShare({ runeDepth, liquidityUnits, poolUnits }).mul(percent);
|
|
73
|
+
}
|
|
74
74
|
|
|
75
|
-
export
|
|
75
|
+
export function getAsymmetricAssetWithdrawAmount({
|
|
76
76
|
percent,
|
|
77
77
|
assetDepth,
|
|
78
78
|
liquidityUnits,
|
|
79
79
|
poolUnits,
|
|
80
|
-
}: ShareParams<{ percent: number; assetDepth: string }>)
|
|
81
|
-
getAsymmetricAssetShare({ assetDepth, liquidityUnits, poolUnits }).mul(percent);
|
|
80
|
+
}: ShareParams<{ percent: number; assetDepth: string }>) {
|
|
81
|
+
return getAsymmetricAssetShare({ assetDepth, liquidityUnits, poolUnits }).mul(percent);
|
|
82
|
+
}
|
|
82
83
|
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
function toTCSwapKitNumber(value: string) {
|
|
85
|
+
return SwapKitNumber.fromBigInt(BigInt(value), BaseDecimal.THOR);
|
|
86
|
+
}
|
|
85
87
|
|
|
86
|
-
export
|
|
88
|
+
export function getSymmetricPoolShare({
|
|
87
89
|
liquidityUnits,
|
|
88
90
|
poolUnits,
|
|
89
91
|
runeDepth,
|
|
@@ -91,12 +93,14 @@ export const getSymmetricPoolShare = ({
|
|
|
91
93
|
}: ShareParams<{
|
|
92
94
|
runeDepth: string;
|
|
93
95
|
assetDepth: string;
|
|
94
|
-
}>)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
}>) {
|
|
97
|
+
return {
|
|
98
|
+
assetAmount: toTCSwapKitNumber(assetDepth).mul(liquidityUnits).div(poolUnits),
|
|
99
|
+
runeAmount: toTCSwapKitNumber(runeDepth).mul(liquidityUnits).div(poolUnits),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function getSymmetricWithdraw({
|
|
100
104
|
liquidityUnits,
|
|
101
105
|
poolUnits,
|
|
102
106
|
runeDepth,
|
|
@@ -106,14 +110,15 @@ export const getSymmetricWithdraw = ({
|
|
|
106
110
|
runeDepth: string;
|
|
107
111
|
assetDepth: string;
|
|
108
112
|
percent: number;
|
|
109
|
-
}>)
|
|
110
|
-
Object.fromEntries(
|
|
113
|
+
}>) {
|
|
114
|
+
return Object.fromEntries(
|
|
111
115
|
Object.entries(getSymmetricPoolShare({ liquidityUnits, poolUnits, runeDepth, assetDepth })).map(
|
|
112
116
|
([name, value]) => [name, value.mul(percent)],
|
|
113
117
|
),
|
|
114
118
|
);
|
|
119
|
+
}
|
|
115
120
|
|
|
116
|
-
export
|
|
121
|
+
export function getEstimatedPoolShare({
|
|
117
122
|
runeDepth,
|
|
118
123
|
poolUnits,
|
|
119
124
|
assetDepth,
|
|
@@ -125,12 +130,12 @@ export const getEstimatedPoolShare = ({
|
|
|
125
130
|
assetAmount: string;
|
|
126
131
|
runeDepth: string;
|
|
127
132
|
assetDepth: string;
|
|
128
|
-
}>)
|
|
129
|
-
const R =
|
|
130
|
-
const A =
|
|
131
|
-
const P =
|
|
132
|
-
const runeAddAmount =
|
|
133
|
-
const assetAddAmount =
|
|
133
|
+
}>) {
|
|
134
|
+
const R = new SwapKitNumber({ value: runeDepth, decimal: 8 });
|
|
135
|
+
const A = new SwapKitNumber({ value: assetDepth, decimal: 8 });
|
|
136
|
+
const P = new SwapKitNumber({ value: poolUnits, decimal: 8 });
|
|
137
|
+
const runeAddAmount = new SwapKitNumber({ value: runeAmount, decimal: 8 });
|
|
138
|
+
const assetAddAmount = new SwapKitNumber({ value: assetAmount, decimal: 8 });
|
|
134
139
|
|
|
135
140
|
// liquidityUnits = P * (r*A + a*R + 2*r*a) / (r*A + a*R + 2*R*A)
|
|
136
141
|
const rA = runeAddAmount.mul(A);
|
|
@@ -142,22 +147,24 @@ export const getEstimatedPoolShare = ({
|
|
|
142
147
|
const liquidityUnitsAfterAdd = numerator.div(denominator);
|
|
143
148
|
const estimatedLiquidityUnits = toTCSwapKitNumber(liquidityUnits).add(liquidityUnitsAfterAdd);
|
|
144
149
|
|
|
145
|
-
if (liquidityUnitsAfterAdd.
|
|
146
|
-
return estimatedLiquidityUnits.div(P).
|
|
150
|
+
if (liquidityUnitsAfterAdd.getBaseValue("number") === 0) {
|
|
151
|
+
return estimatedLiquidityUnits.div(P).getBaseValue("number");
|
|
147
152
|
}
|
|
148
153
|
|
|
149
154
|
// get pool units after add
|
|
150
155
|
const newPoolUnits = P.add(estimatedLiquidityUnits);
|
|
151
156
|
|
|
152
|
-
return estimatedLiquidityUnits.div(newPoolUnits).
|
|
153
|
-
}
|
|
157
|
+
return estimatedLiquidityUnits.div(newPoolUnits).getBaseValue("number");
|
|
158
|
+
}
|
|
154
159
|
|
|
155
|
-
export
|
|
160
|
+
export function getLiquiditySlippage({
|
|
156
161
|
runeAmount,
|
|
157
162
|
assetAmount,
|
|
158
163
|
runeDepth,
|
|
159
164
|
assetDepth,
|
|
160
|
-
}: PoolParams)
|
|
165
|
+
}: PoolParams) {
|
|
166
|
+
if (runeAmount === "0" || assetAmount === "0" || runeDepth === "0" || assetDepth === "0")
|
|
167
|
+
return 0;
|
|
161
168
|
// formula: (t * R - T * r)/ (T*r + R*T)
|
|
162
169
|
const R = toTCSwapKitNumber(runeDepth);
|
|
163
170
|
const T = toTCSwapKitNumber(assetDepth);
|
|
@@ -168,5 +175,5 @@ export const getLiquiditySlippage = ({
|
|
|
168
175
|
const denominator = T.mul(runeAddAmount).add(R.mul(T));
|
|
169
176
|
|
|
170
177
|
// set absolute value of percent, no negative allowed
|
|
171
|
-
return Math.abs(numerator.div(denominator).
|
|
172
|
-
}
|
|
178
|
+
return Math.abs(numerator.div(denominator).getBaseValue("number"));
|
|
179
|
+
}
|
package/src/helpers/memo.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { MemoType } from
|
|
1
|
+
import { Chain } from "../types/chains";
|
|
2
|
+
import { MemoType } from "../types/sdk";
|
|
3
3
|
|
|
4
4
|
export type ThornameRegisterParam = {
|
|
5
5
|
name: string;
|
|
@@ -10,25 +10,14 @@ export type ThornameRegisterParam = {
|
|
|
10
10
|
expiryBlock?: string;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
symbol,
|
|
15
|
-
ticker,
|
|
16
|
-
chain,
|
|
17
|
-
}: {
|
|
18
|
-
ticker: string;
|
|
19
|
-
symbol: string;
|
|
20
|
-
chain: string | Chain;
|
|
21
|
-
}) => (chain === 'ETH' && ticker !== 'ETH' ? `${ticker}-${symbol.slice(-3)}` : symbol);
|
|
22
|
-
|
|
23
|
-
type WithAddress<T = {}> = T & { address: string };
|
|
24
|
-
type WithChain<T = {}> = T & { chain: Chain };
|
|
13
|
+
type WithChain<T extends {}> = T & { chain: Chain };
|
|
25
14
|
|
|
26
15
|
export type MemoOptions<T extends MemoType> = {
|
|
27
|
-
[MemoType.BOND]:
|
|
28
|
-
[MemoType.LEAVE]:
|
|
29
|
-
[MemoType.CLOSE_LOAN]:
|
|
30
|
-
[MemoType.OPEN_LOAN]:
|
|
31
|
-
[MemoType.UNBOND]:
|
|
16
|
+
[MemoType.BOND]: { address: string };
|
|
17
|
+
[MemoType.LEAVE]: { address: string };
|
|
18
|
+
[MemoType.CLOSE_LOAN]: { address: string; asset: string; minAmount?: string };
|
|
19
|
+
[MemoType.OPEN_LOAN]: { address: string; asset: string; minAmount?: string };
|
|
20
|
+
[MemoType.UNBOND]: { address: string; unbondAmount: number };
|
|
32
21
|
[MemoType.DEPOSIT]: WithChain<{ symbol: string; address?: string; singleSide?: boolean }>;
|
|
33
22
|
[MemoType.WITHDRAW]: WithChain<{
|
|
34
23
|
ticker: string;
|
|
@@ -37,7 +26,7 @@ export type MemoOptions<T extends MemoType> = {
|
|
|
37
26
|
targetAssetString?: string;
|
|
38
27
|
singleSide?: boolean;
|
|
39
28
|
}>;
|
|
40
|
-
[MemoType.THORNAME_REGISTER]: Omit<ThornameRegisterParam,
|
|
29
|
+
[MemoType.THORNAME_REGISTER]: Omit<ThornameRegisterParam, "preferredAsset" | "expiryBlock">;
|
|
41
30
|
}[T];
|
|
42
31
|
|
|
43
32
|
export const getMemoFor = <T extends MemoType>(memoType: T, options: MemoOptions<T>) => {
|
|
@@ -50,29 +39,43 @@ export const getMemoFor = <T extends MemoType>(memoType: T, options: MemoOptions
|
|
|
50
39
|
|
|
51
40
|
case MemoType.UNBOND: {
|
|
52
41
|
const { address, unbondAmount } = options as MemoOptions<MemoType.UNBOND>;
|
|
53
|
-
return `${memoType}:${address}:${unbondAmount
|
|
42
|
+
return `${memoType}:${address}:${unbondAmount}`;
|
|
54
43
|
}
|
|
55
44
|
|
|
56
45
|
case MemoType.THORNAME_REGISTER: {
|
|
57
46
|
const { name, chain, address, owner } = options as MemoOptions<MemoType.THORNAME_REGISTER>;
|
|
58
|
-
return `${memoType}:${name}:${chain}:${address}${owner ? `:${owner}` :
|
|
47
|
+
return `${memoType}:${name}:${chain}:${address}${owner ? `:${owner}` : ""}`;
|
|
59
48
|
}
|
|
60
49
|
|
|
61
50
|
case MemoType.DEPOSIT: {
|
|
62
51
|
const { chain, symbol, address, singleSide } = options as MemoOptions<MemoType.DEPOSIT>;
|
|
63
52
|
|
|
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
|
+
|
|
64
66
|
return singleSide
|
|
65
|
-
? `${memoType}:${chain}/${symbol}
|
|
66
|
-
: `${memoType}:${chain
|
|
67
|
+
? `${memoType}:${chain}/${symbol}`
|
|
68
|
+
: `${memoType}:${getPoolIdentifier(chain, symbol)}:${address || ""}`;
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
case MemoType.WITHDRAW: {
|
|
70
72
|
const { chain, ticker, symbol, basisPoints, targetAssetString, singleSide } =
|
|
71
73
|
options as MemoOptions<MemoType.WITHDRAW>;
|
|
72
74
|
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
const
|
|
75
|
+
const shortenedSymbol =
|
|
76
|
+
chain === "ETH" && ticker !== "ETH" ? `${ticker}-${symbol.slice(-3)}` : symbol;
|
|
77
|
+
const target = !singleSide && targetAssetString ? `:${targetAssetString}` : "";
|
|
78
|
+
const assetDivider = singleSide ? "/" : ".";
|
|
76
79
|
|
|
77
80
|
return `${memoType}:${chain}${assetDivider}${shortenedSymbol}:${basisPoints}${target}`;
|
|
78
81
|
}
|
|
@@ -85,6 +88,6 @@ export const getMemoFor = <T extends MemoType>(memoType: T, options: MemoOptions
|
|
|
85
88
|
}
|
|
86
89
|
|
|
87
90
|
default:
|
|
88
|
-
return
|
|
91
|
+
return "";
|
|
89
92
|
}
|
|
90
93
|
};
|