@swapkit/core 1.0.0-rc.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/LICENSE +201 -0
- package/dist/index-9e36735e.cjs +1 -0
- package/dist/index-cf1865cd.js +649 -0
- package/dist/index.cjs +2 -0
- package/dist/index.d.ts +214 -0
- package/dist/index.es-320ea117.js +13836 -0
- package/dist/index.es-66e7d15a.js +11436 -0
- package/dist/index.es-8503fb04-8503fb04.js +34669 -0
- package/dist/index.es-8503fb04-903b9173.cjs +1 -0
- package/dist/index.es-c82b553a.cjs +14 -0
- package/dist/index.es-e22f22e9.cjs +1 -0
- package/dist/index.es.js +3743 -0
- package/package.json +57 -0
- package/src/aggregator/contracts/avaxGeneric.ts +92 -0
- package/src/aggregator/contracts/avaxWoofi.ts +145 -0
- package/src/aggregator/contracts/bscGeneric.ts +106 -0
- package/src/aggregator/contracts/ethGeneric.ts +92 -0
- package/src/aggregator/contracts/index.ts +74 -0
- package/src/aggregator/contracts/pancakeV2.ts +145 -0
- package/src/aggregator/contracts/pangolin.ts +120 -0
- package/src/aggregator/contracts/sushiswap.ts +120 -0
- package/src/aggregator/contracts/traderJoe.ts +120 -0
- package/src/aggregator/contracts/uniswapV2.ts +120 -0
- package/src/aggregator/contracts/uniswapV2Leg.ts +128 -0
- package/src/aggregator/contracts/uniswapV3_100.ts +128 -0
- package/src/aggregator/contracts/uniswapV3_10000.ts +128 -0
- package/src/aggregator/contracts/uniswapV3_3000.ts +128 -0
- package/src/aggregator/contracts/uniswapV3_500.ts +128 -0
- package/src/aggregator/getSwapParams.ts +70 -0
- package/src/client/__tests__/helpers.test.ts +69 -0
- package/src/client/explorerUrls.ts +60 -0
- package/src/client/index.ts +690 -0
- package/src/client/thornode.ts +31 -0
- package/src/client/types.ts +101 -0
- package/src/index.ts +4 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { QuoteRoute } from '@swapkit/api';
|
|
2
|
+
|
|
3
|
+
import type { AGG_CONTRACT_ADDRESS } from './contracts/index.ts';
|
|
4
|
+
import { lowercasedGenericAbiMappings } from './contracts/index.ts';
|
|
5
|
+
|
|
6
|
+
type SwapInParams = {
|
|
7
|
+
calldata: QuoteRoute['calldata'];
|
|
8
|
+
recipient: string;
|
|
9
|
+
streamSwap?: boolean;
|
|
10
|
+
contractAddress: AGG_CONTRACT_ADDRESS;
|
|
11
|
+
toChecksumAddress: (address: string) => string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const getSwapInParams = ({
|
|
15
|
+
streamSwap,
|
|
16
|
+
contractAddress,
|
|
17
|
+
recipient,
|
|
18
|
+
toChecksumAddress,
|
|
19
|
+
calldata: {
|
|
20
|
+
amount,
|
|
21
|
+
amountOutMin = '',
|
|
22
|
+
data = '',
|
|
23
|
+
deadline,
|
|
24
|
+
memo,
|
|
25
|
+
router,
|
|
26
|
+
memoStreamingSwap,
|
|
27
|
+
tcMemo,
|
|
28
|
+
tcRouter,
|
|
29
|
+
tcVault,
|
|
30
|
+
vault,
|
|
31
|
+
token,
|
|
32
|
+
},
|
|
33
|
+
}: SwapInParams) => {
|
|
34
|
+
const isGeneric = !!lowercasedGenericAbiMappings[contractAddress.toLowerCase()];
|
|
35
|
+
|
|
36
|
+
if (isGeneric && !router) {
|
|
37
|
+
throw new Error('Router is required on calldata for swapIn with GenericContract');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Data structure for contract calls
|
|
42
|
+
* GENERIC: tcRouter, tcVault, tcMemo, token, amount, router, data, deadline
|
|
43
|
+
* ETH_UNISWAP: tcRouter, tcVault, tcMemo, token, amount, amountOutMin, deadline
|
|
44
|
+
* AVAX_PANGOLIN: tcRouter, tcVault, tcMemo, token, amount, amountOutMin, deadline
|
|
45
|
+
* AVAX_WOOFI: router, vault, memo, token, amount, amountOutMin, deadline
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
const baseMemo = tcMemo || memo;
|
|
49
|
+
const transactionMemo = streamSwap ? memoStreamingSwap || baseMemo : baseMemo;
|
|
50
|
+
|
|
51
|
+
if (!tcVault && !vault) throw new Error('TC Vault is required on calldata');
|
|
52
|
+
if (!tcRouter && !router) throw new Error('TC Router is required on calldata');
|
|
53
|
+
if (!transactionMemo) throw new Error('TC Memo is required on calldata');
|
|
54
|
+
if (!token) throw new Error('Token is required on calldata');
|
|
55
|
+
|
|
56
|
+
const baseParams = [
|
|
57
|
+
// v2 contracts don't have tcVault, tcRouter, tcMemo but vault, router, memo
|
|
58
|
+
toChecksumAddress((tcRouter || router) as string),
|
|
59
|
+
toChecksumAddress((tcVault || vault) as string),
|
|
60
|
+
transactionMemo.replace('{recipientAddress}', recipient),
|
|
61
|
+
toChecksumAddress(token),
|
|
62
|
+
amount,
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
const contractParams = isGeneric
|
|
66
|
+
? [toChecksumAddress(router as string), data, deadline]
|
|
67
|
+
: [amountOutMin, deadline];
|
|
68
|
+
|
|
69
|
+
return [...baseParams, ...contractParams];
|
|
70
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Chain, ChainToExplorerUrl } from '@swapkit/types';
|
|
2
|
+
import { describe, expect, test } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import { getExplorerAddressUrl, getExplorerTxUrl } from '../explorerUrls.ts';
|
|
5
|
+
|
|
6
|
+
describe('Explorer URLs', () => {
|
|
7
|
+
Object.values(Chain)
|
|
8
|
+
.filter((c) => ![Chain.Litecoin, Chain.Dogecoin, Chain.Cosmos].includes(c))
|
|
9
|
+
.forEach((chain) => {
|
|
10
|
+
test(`getExplorerTxUrl returns correct URL for ${chain}`, () => {
|
|
11
|
+
expect(getExplorerTxUrl({ chain, txHash: '0x12345' })).toBe(
|
|
12
|
+
`${ChainToExplorerUrl[chain]}/tx/0x12345`,
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
expect(getExplorerAddressUrl({ chain, address: 'asdfg' })).toBe(
|
|
16
|
+
`${ChainToExplorerUrl[chain]}/address/asdfg`,
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('getExplorerTxUrl throws Error for unsupported Chain', () => {
|
|
22
|
+
expect(() =>
|
|
23
|
+
getExplorerTxUrl({ chain: 'unsupported' as Chain, txHash: '0x12345' }),
|
|
24
|
+
).toThrowError('Unsupported chain: unsupported');
|
|
25
|
+
});
|
|
26
|
+
test('getExplorerAddressUrl throws Error for unsupported Chain', () => {
|
|
27
|
+
expect(() =>
|
|
28
|
+
getExplorerAddressUrl({ chain: 'unsupported' as Chain, address: 'asdfg' }),
|
|
29
|
+
).toThrowError('Unsupported chain: unsupported');
|
|
30
|
+
});
|
|
31
|
+
test('getExplorerTxUrl adds 0x for EVM like chains', () => {
|
|
32
|
+
expect(getExplorerTxUrl({ chain: Chain.Ethereum, txHash: '12345' })).toBe(
|
|
33
|
+
'https://etherscan.io/tx/0x12345',
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('getExplorerTxUrl returns correct URL for Litecoin', () => {
|
|
38
|
+
expect(getExplorerTxUrl({ chain: Chain.Litecoin, txHash: 'efghi' })).toBe(
|
|
39
|
+
'https://ltc.bitaps.com/efghi',
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
test('getExplorerAddressUrl returns correct URL for Litecoin', () => {
|
|
43
|
+
expect(getExplorerAddressUrl({ chain: Chain.Litecoin, address: '12345' })).toBe(
|
|
44
|
+
'https://ltc.bitaps.com/12345',
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('getExplorerTxUrl returns correct URL for Cosmos', () => {
|
|
49
|
+
expect(getExplorerTxUrl({ chain: Chain.Cosmos, txHash: 'pqrst' })).toBe(
|
|
50
|
+
'https://cosmos.bigdipper.live/transactions/pqrst',
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
test('getExplorerAddressUrl returns correct URL for Cosmos', () => {
|
|
54
|
+
expect(getExplorerAddressUrl({ chain: Chain.Cosmos, address: 'zabcd' })).toBe(
|
|
55
|
+
'https://cosmos.bigdipper.live/account/zabcd',
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('getExplorerTxUrl returns correct URL for Doge', () => {
|
|
60
|
+
expect(getExplorerTxUrl({ chain: Chain.Dogecoin, txHash: 'uvwxy' })).toBe(
|
|
61
|
+
'https://blockchair.com/dogecoin/transaction/uvwxy',
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
test('getExplorerAddressUrl returns correct URL for Doge', () => {
|
|
65
|
+
expect(getExplorerAddressUrl({ chain: Chain.Dogecoin, address: 'efghi' })).toBe(
|
|
66
|
+
'https://blockchair.com/dogecoin/address/efghi',
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Chain, ChainToExplorerUrl } from '@swapkit/types';
|
|
2
|
+
|
|
3
|
+
export const getExplorerTxUrl = ({ chain, txHash }: { txHash: string; chain: Chain }) => {
|
|
4
|
+
const baseUrl = ChainToExplorerUrl[chain];
|
|
5
|
+
|
|
6
|
+
switch (chain) {
|
|
7
|
+
case Chain.Binance:
|
|
8
|
+
case Chain.Bitcoin:
|
|
9
|
+
case Chain.BitcoinCash:
|
|
10
|
+
case Chain.Maya:
|
|
11
|
+
case Chain.THORChain:
|
|
12
|
+
return `${baseUrl}/tx/${txHash}`;
|
|
13
|
+
|
|
14
|
+
case Chain.Arbitrum:
|
|
15
|
+
case Chain.Avalanche:
|
|
16
|
+
case Chain.BinanceSmartChain:
|
|
17
|
+
case Chain.Ethereum:
|
|
18
|
+
case Chain.Optimism:
|
|
19
|
+
case Chain.Polygon:
|
|
20
|
+
return `${baseUrl}/tx/${txHash.startsWith('0x') ? txHash : `0x${txHash}`}`;
|
|
21
|
+
|
|
22
|
+
case Chain.Cosmos:
|
|
23
|
+
return `${baseUrl}/transactions/${txHash}`;
|
|
24
|
+
case Chain.Dogecoin:
|
|
25
|
+
return `${baseUrl}/transaction/${txHash.toLowerCase()}`;
|
|
26
|
+
case Chain.Litecoin:
|
|
27
|
+
return `${baseUrl}/${txHash}`;
|
|
28
|
+
|
|
29
|
+
default:
|
|
30
|
+
throw new Error(`Unsupported chain: ${chain}`);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const getExplorerAddressUrl = ({ chain, address }: { address: string; chain: Chain }) => {
|
|
35
|
+
const baseUrl = ChainToExplorerUrl[chain];
|
|
36
|
+
|
|
37
|
+
switch (chain) {
|
|
38
|
+
case Chain.Arbitrum:
|
|
39
|
+
case Chain.Avalanche:
|
|
40
|
+
case Chain.Binance:
|
|
41
|
+
case Chain.BinanceSmartChain:
|
|
42
|
+
case Chain.Bitcoin:
|
|
43
|
+
case Chain.BitcoinCash:
|
|
44
|
+
case Chain.Dogecoin:
|
|
45
|
+
case Chain.Ethereum:
|
|
46
|
+
case Chain.Maya:
|
|
47
|
+
case Chain.Optimism:
|
|
48
|
+
case Chain.Polygon:
|
|
49
|
+
case Chain.THORChain:
|
|
50
|
+
return `${baseUrl}/address/${address}`;
|
|
51
|
+
|
|
52
|
+
case Chain.Cosmos:
|
|
53
|
+
return `${baseUrl}/account/${address}`;
|
|
54
|
+
case Chain.Litecoin:
|
|
55
|
+
return `${baseUrl}/${address}`;
|
|
56
|
+
|
|
57
|
+
default:
|
|
58
|
+
throw new Error(`Unsupported chain: ${chain}`);
|
|
59
|
+
}
|
|
60
|
+
};
|