@atomiqlabs/sdk 1.3.19 → 2.1.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.
Files changed (49) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +545 -501
  3. package/dist/SmartChainAssets.d.ts +73 -59
  4. package/dist/SmartChainAssets.js +75 -55
  5. package/dist/SwapperFactory.d.ts +49 -0
  6. package/dist/SwapperFactory.js +84 -0
  7. package/dist/Utils.d.ts +11 -0
  8. package/dist/Utils.js +37 -0
  9. package/dist/fs-storage/FileSystemStorageManager.d.ts +15 -0
  10. package/dist/fs-storage/FileSystemStorageManager.js +60 -0
  11. package/dist/fs-storage/index.d.ts +1 -0
  12. package/dist/fs-storage/index.js +17 -0
  13. package/dist/index.d.ts +5 -4
  14. package/dist/index.js +21 -20
  15. package/dist/storage/LocalStorageManager.d.ts +24 -0
  16. package/dist/storage/LocalStorageManager.js +68 -0
  17. package/package.json +31 -32
  18. package/src/SmartChainAssets.js +75 -0
  19. package/src/SmartChainAssets.ts +76 -62
  20. package/src/SwapperFactory.js +96 -0
  21. package/src/SwapperFactory.ts +171 -0
  22. package/src/Utils.js +37 -0
  23. package/src/Utils.ts +31 -0
  24. package/src/example/BrowserExample.js +199 -0
  25. package/src/example/BrowserExample.ts +141 -120
  26. package/src/example/NodeJSExample.js +206 -0
  27. package/src/example/NodeJSExample.ts +150 -120
  28. package/src/fs-storage/FileSystemStorageManager.ts +71 -0
  29. package/src/fs-storage/index.ts +1 -0
  30. package/src/index.js +21 -0
  31. package/src/index.ts +5 -4
  32. package/src/storage/LocalStorageManager.js +72 -0
  33. package/src/storage/LocalStorageManager.ts +81 -0
  34. package/dist/MultichainSwapper.d.ts +0 -46
  35. package/dist/MultichainSwapper.js +0 -83
  36. package/dist/chains/ChainInitializer.d.ts +0 -13
  37. package/dist/chains/ChainInitializer.js +0 -2
  38. package/dist/chains/solana/SolanaChainInitializer.d.ts +0 -41
  39. package/dist/chains/solana/SolanaChainInitializer.js +0 -60
  40. package/dist/chains/solana/SolanaChains.d.ts +0 -14
  41. package/dist/chains/solana/SolanaChains.js +0 -18
  42. package/dist/example/BrowserExample.d.ts +0 -1
  43. package/dist/example/BrowserExample.js +0 -104
  44. package/dist/example/NodeJSExample.d.ts +0 -1
  45. package/dist/example/NodeJSExample.js +0 -104
  46. package/src/MultichainSwapper.ts +0 -156
  47. package/src/chains/ChainInitializer.ts +0 -16
  48. package/src/chains/solana/SolanaChainInitializer.ts +0 -99
  49. package/src/chains/solana/SolanaChains.ts +0 -16
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LocalStorageManager = void 0;
4
+ /**
5
+ * StorageManager using browser's local storage API
6
+ */
7
+ class LocalStorageManager {
8
+ constructor(storageKey) {
9
+ this.rawData = null;
10
+ this.data = {};
11
+ this.storageKey = storageKey;
12
+ }
13
+ init() {
14
+ const completedTxt = window.localStorage.getItem(this.storageKey);
15
+ if (completedTxt != null) {
16
+ this.rawData = JSON.parse(completedTxt);
17
+ if (this.rawData == null)
18
+ this.rawData = {};
19
+ }
20
+ else {
21
+ this.rawData = {};
22
+ }
23
+ return Promise.resolve();
24
+ }
25
+ saveData(hash, object) {
26
+ this.data[hash] = object;
27
+ this.rawData[hash] = object.serialize();
28
+ return this.save();
29
+ }
30
+ saveDataArr(arr) {
31
+ arr.forEach(e => {
32
+ this.data[e.id] = e.object;
33
+ this.rawData[e.id] = e.object.serialize();
34
+ });
35
+ return this.save();
36
+ }
37
+ removeData(hash) {
38
+ if (this.rawData[hash] != null) {
39
+ if (this.data[hash] != null)
40
+ delete this.data[hash];
41
+ delete this.rawData[hash];
42
+ return this.save();
43
+ }
44
+ return Promise.resolve();
45
+ }
46
+ removeDataArr(hashArr) {
47
+ hashArr.forEach(hash => {
48
+ if (this.rawData[hash] != null) {
49
+ if (this.data[hash] != null)
50
+ delete this.data[hash];
51
+ delete this.rawData[hash];
52
+ }
53
+ });
54
+ return this.save();
55
+ }
56
+ loadData(type) {
57
+ return Promise.resolve(Object.keys(this.rawData).map(e => {
58
+ const deserialized = new type(this.rawData[e]);
59
+ this.data[e] = deserialized;
60
+ return deserialized;
61
+ }));
62
+ }
63
+ save() {
64
+ window.localStorage.setItem(this.storageKey, JSON.stringify(this.rawData));
65
+ return Promise.resolve();
66
+ }
67
+ }
68
+ exports.LocalStorageManager = LocalStorageManager;
package/package.json CHANGED
@@ -1,32 +1,31 @@
1
- {
2
- "name": "@atomiqlabs/sdk",
3
- "version": "1.3.19",
4
- "description": "atomiq labs SDK for cross-chain swaps between smart chains and bitcoin",
5
- "main": "./dist/index.js",
6
- "types:": "./dist/index.d.ts",
7
- "scripts": {
8
- "test": "echo \"Error: no test specified\" && exit 1"
9
- },
10
- "files": [
11
- "/dist",
12
- "/src"
13
- ],
14
- "keywords": [
15
- "Bitcoin",
16
- "Cross-chain",
17
- "Cryptocurrency",
18
- "Bridge",
19
- "Trustless"
20
- ],
21
- "author": "adambor",
22
- "license": "ISC",
23
- "dependencies": {
24
- "@atomiqlabs/base": "7.2.2",
25
- "@atomiqlabs/chain-solana": "7.3.8",
26
- "@atomiqlabs/sdk-lib": "10.3.12"
27
- },
28
- "devDependencies": {
29
- "@types/bn.js": "5.1.5",
30
- "typescript": "4.9.5"
31
- }
32
- }
1
+ {
2
+ "name": "@atomiqlabs/sdk",
3
+ "version": "2.1.0",
4
+ "description": "atomiq labs SDK for cross-chain swaps between smart chains and bitcoin",
5
+ "main": "./dist/index.js",
6
+ "types:": "./dist/index.d.ts",
7
+ "scripts": {
8
+ "test": "echo \"Error: no test specified\" && exit 1"
9
+ },
10
+ "files": [
11
+ "/dist",
12
+ "/src"
13
+ ],
14
+ "keywords": [
15
+ "Bitcoin",
16
+ "Cross-chain",
17
+ "Cryptocurrency",
18
+ "Bridge",
19
+ "Trustless"
20
+ ],
21
+ "author": "adambor",
22
+ "license": "ISC",
23
+ "dependencies": {
24
+ "@atomiqlabs/base": "^8.0.0",
25
+ "@atomiqlabs/sdk-lib": "^11.1.0"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "22.13.5",
29
+ "typescript": "4.9.5"
30
+ }
31
+ }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SmartChainAssets = void 0;
4
+ exports.SmartChainAssets = {
5
+ WBTC: {
6
+ pricing: {
7
+ binancePair: "WBTCBTC",
8
+ okxPair: null,
9
+ coinGeckoCoinId: "wrapped-bitcoin",
10
+ coinPaprikaCoinId: "wbtc-wrapped-bitcoin",
11
+ krakenPair: "WBTCXBT"
12
+ },
13
+ name: "Wrapped BTC (Wormhole)"
14
+ },
15
+ USDC: {
16
+ pricing: {
17
+ binancePair: "!BTCUSDC",
18
+ okxPair: "!BTC-USDC",
19
+ coinGeckoCoinId: "usd-coin",
20
+ coinPaprikaCoinId: "usdc-usd-coin",
21
+ krakenPair: "!XBTUSDC"
22
+ },
23
+ name: "USD Circle"
24
+ },
25
+ USDT: {
26
+ pricing: {
27
+ binancePair: "!BTCUSDT",
28
+ okxPair: "!BTC-USDT",
29
+ coinGeckoCoinId: "tether",
30
+ coinPaprikaCoinId: "usdt-tether",
31
+ krakenPair: "!XBTUSDT"
32
+ },
33
+ name: "Tether USD"
34
+ },
35
+ SOL: {
36
+ pricing: {
37
+ binancePair: "SOLBTC",
38
+ okxPair: "SOL-BTC",
39
+ coinGeckoCoinId: "solana",
40
+ coinPaprikaCoinId: "sol-solana",
41
+ krakenPair: "SOLXBT"
42
+ },
43
+ name: "Solana"
44
+ },
45
+ BONK: {
46
+ pricing: {
47
+ binancePair: "BONKUSDC;!BTCUSDC",
48
+ okxPair: "BONK-USDT;!BTC-USDT",
49
+ coinGeckoCoinId: "bonk",
50
+ coinPaprikaCoinId: "bonk-bonk",
51
+ krakenPair: "BONKUSD;!XXBTZUSD"
52
+ },
53
+ name: "Bonk"
54
+ },
55
+ ETH: {
56
+ pricing: {
57
+ binancePair: "ETHBTC",
58
+ okxPair: "ETH-BTC",
59
+ coinGeckoCoinId: "ethereum",
60
+ coinPaprikaCoinId: "eth-ethereum",
61
+ krakenPair: "XETHXXBT"
62
+ },
63
+ name: "Ethereum"
64
+ },
65
+ STRK: {
66
+ pricing: {
67
+ binancePair: "STRKUSDT;!BTCUSDT",
68
+ okxPair: "STRK-USDT;!BTC-USDT",
69
+ coinGeckoCoinId: "starknet",
70
+ coinPaprikaCoinId: "strk-starknet",
71
+ krakenPair: "STRKUSD;!XXBTZUSD"
72
+ },
73
+ name: "Starknet"
74
+ }
75
+ };
@@ -1,62 +1,76 @@
1
-
2
- export const SmartChainAssets = {
3
- WBTC: {
4
- pricing: {
5
- binancePair: "WBTCBTC",
6
- okxPair: null,
7
- coinGeckoCoinId: "wrapped-bitcoin",
8
- coinPaprikaCoinId: "wbtc-wrapped-bitcoin",
9
- krakenPair: "WBTCXBT"
10
- },
11
- name: "Wrapped BTC (Wormhole)"
12
- },
13
- USDC: {
14
- pricing: {
15
- binancePair: "!BTCUSDC",
16
- okxPair: "!BTC-USDC",
17
- coinGeckoCoinId: "usd-coin",
18
- coinPaprikaCoinId: "usdc-usd-coin",
19
- krakenPair: "!XBTUSDC"
20
- },
21
- name: "USD Circle"
22
- },
23
- USDT: {
24
- pricing: {
25
- binancePair: "!BTCUSDT",
26
- okxPair: "!BTC-USDT",
27
- coinGeckoCoinId: "tether",
28
- coinPaprikaCoinId: "usdt-tether",
29
- krakenPair: "!XBTUSDT"
30
- },
31
- name: "Tether USD"
32
- },
33
- SOL: {
34
- pricing: {
35
- binancePair: "SOLBTC",
36
- okxPair: "SOL-BTC",
37
- coinGeckoCoinId: "solana",
38
- coinPaprikaCoinId: "sol-solana",
39
- krakenPair: "SOLXBT"
40
- },
41
- name: "Solana"
42
- },
43
- BONK: {
44
- pricing: {
45
- binancePair: "BONKUSDC;!BTCUSDC",
46
- okxPair: "BONK-USDT;!BTC-USDT",
47
- coinGeckoCoinId: "bonk",
48
- coinPaprikaCoinId: "bonk-bonk",
49
- krakenPair: "BONKUSD;!XXBTZUSD"
50
- },
51
- name: "Bonk"
52
- }
53
- } as const;
54
-
55
- export type SmartChainAssetTickers = keyof typeof SmartChainAssets;
56
-
57
- export type AssetData = {
58
- [ticker in SmartChainAssetTickers]?: {
59
- address: string,
60
- decimals: number
61
- }
62
- };
1
+
2
+ export const SmartChainAssets = {
3
+ WBTC: {
4
+ pricing: {
5
+ binancePair: "WBTCBTC",
6
+ okxPair: null,
7
+ coinGeckoCoinId: "wrapped-bitcoin",
8
+ coinPaprikaCoinId: "wbtc-wrapped-bitcoin",
9
+ krakenPair: "WBTCXBT"
10
+ },
11
+ name: "Wrapped BTC (Wormhole)"
12
+ },
13
+ USDC: {
14
+ pricing: {
15
+ binancePair: "!BTCUSDC",
16
+ okxPair: "!BTC-USDC",
17
+ coinGeckoCoinId: "usd-coin",
18
+ coinPaprikaCoinId: "usdc-usd-coin",
19
+ krakenPair: "!XBTUSDC"
20
+ },
21
+ name: "USD Circle"
22
+ },
23
+ USDT: {
24
+ pricing: {
25
+ binancePair: "!BTCUSDT",
26
+ okxPair: "!BTC-USDT",
27
+ coinGeckoCoinId: "tether",
28
+ coinPaprikaCoinId: "usdt-tether",
29
+ krakenPair: "!XBTUSDT"
30
+ },
31
+ name: "Tether USD"
32
+ },
33
+ SOL: {
34
+ pricing: {
35
+ binancePair: "SOLBTC",
36
+ okxPair: "SOL-BTC",
37
+ coinGeckoCoinId: "solana",
38
+ coinPaprikaCoinId: "sol-solana",
39
+ krakenPair: "SOLXBT"
40
+ },
41
+ name: "Solana"
42
+ },
43
+ BONK: {
44
+ pricing: {
45
+ binancePair: "BONKUSDC;!BTCUSDC",
46
+ okxPair: "BONK-USDT;!BTC-USDT",
47
+ coinGeckoCoinId: "bonk",
48
+ coinPaprikaCoinId: "bonk-bonk",
49
+ krakenPair: "BONKUSD;!XXBTZUSD"
50
+ },
51
+ name: "Bonk"
52
+ },
53
+
54
+ ETH: {
55
+ pricing: {
56
+ binancePair: "ETHBTC",
57
+ okxPair: "ETH-BTC",
58
+ coinGeckoCoinId: "ethereum",
59
+ coinPaprikaCoinId: "eth-ethereum",
60
+ krakenPair: "XETHXXBT"
61
+ },
62
+ name: "Ethereum"
63
+ },
64
+ STRK: {
65
+ pricing: {
66
+ binancePair: "STRKUSDT;!BTCUSDT",
67
+ okxPair: "STRK-USDT;!BTC-USDT",
68
+ coinGeckoCoinId: "starknet",
69
+ coinPaprikaCoinId: "strk-starknet",
70
+ krakenPair: "STRKUSD;!XXBTZUSD"
71
+ },
72
+ name: "Starknet"
73
+ }
74
+ } as const;
75
+
76
+ export type SmartChainAssetTickers = keyof typeof SmartChainAssets;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.SwapperFactory = void 0;
15
+ var base_1 = require("@atomiqlabs/base");
16
+ var sdk_lib_1 = require("@atomiqlabs/sdk-lib");
17
+ var SmartChainAssets_1 = require("./SmartChainAssets");
18
+ var LocalStorageManager_1 = require("./storage/LocalStorageManager");
19
+ var SwapperFactory = /** @class */ (function () {
20
+ function SwapperFactory(initializers) {
21
+ var _this = this;
22
+ this.initializers = initializers;
23
+ this.Tokens = {
24
+ BITCOIN: sdk_lib_1.BitcoinTokens
25
+ };
26
+ this.TokenResolver = {};
27
+ this.initializers = initializers;
28
+ initializers.forEach(function (initializer) {
29
+ var addressMap = {};
30
+ _this.Tokens[initializer.chainId] = {};
31
+ for (var ticker in initializer.tokens) {
32
+ var assetData = initializer.tokens[ticker];
33
+ _this.Tokens[initializer.chainId][ticker] = addressMap[assetData.address] = {
34
+ chain: "SC",
35
+ chainId: initializer.chainId,
36
+ address: assetData.address,
37
+ name: SmartChainAssets_1.SmartChainAssets[ticker].name,
38
+ decimals: assetData.decimals,
39
+ displayDecimals: assetData.displayDecimals,
40
+ ticker: ticker
41
+ };
42
+ }
43
+ _this.TokenResolver[initializer.chainId] = {
44
+ getToken: function (address) { return addressMap[address]; }
45
+ };
46
+ });
47
+ }
48
+ SwapperFactory.prototype.newSwapper = function (options) {
49
+ var _this = this;
50
+ var _a, _b, _c, _d, _e, _f, _g;
51
+ (_a = options.bitcoinNetwork) !== null && _a !== void 0 ? _a : (options.bitcoinNetwork = base_1.BitcoinNetwork.MAINNET);
52
+ (_b = options.storagePrefix) !== null && _b !== void 0 ? _b : (options.storagePrefix = "atomiqsdk-" + options.bitcoinNetwork + "-");
53
+ (_c = options.defaultTrustedIntermediaryUrl) !== null && _c !== void 0 ? _c : (options.defaultTrustedIntermediaryUrl = options.bitcoinNetwork === base_1.BitcoinNetwork.MAINNET ?
54
+ "https://node3.gethopa.com:34100" :
55
+ "https://node3.gethopa.com:24100");
56
+ (_d = options.registryUrl) !== null && _d !== void 0 ? _d : (options.registryUrl = options.bitcoinNetwork === base_1.BitcoinNetwork.MAINNET ?
57
+ "https://api.github.com/repos/adambor/SolLightning-registry/contents/registry-mainnet.json?ref=main" :
58
+ "https://api.github.com/repos/adambor/SolLightning-registry/contents/registry.json?ref=main");
59
+ var mempoolApi = (_e = options.mempoolApi) !== null && _e !== void 0 ? _e : new sdk_lib_1.MempoolApi(options.bitcoinNetwork === base_1.BitcoinNetwork.TESTNET ?
60
+ [
61
+ "https://mempool.space/testnet/api/",
62
+ "https://mempool.fra.mempool.space/testnet/api/",
63
+ "https://mempool.va1.mempool.space/testnet/api/",
64
+ "https://mempool.tk7.mempool.space/testnet/api/"
65
+ ] :
66
+ [
67
+ "https://mempool.space/api/",
68
+ "https://mempool.fra.mempool.space/api/",
69
+ "https://mempool.va1.mempool.space/api/",
70
+ "https://mempool.tk7.mempool.space/api/"
71
+ ]);
72
+ var bitcoinRpc = new sdk_lib_1.MempoolBitcoinRpc(mempoolApi);
73
+ var pricingAssets = [];
74
+ Object.keys(SmartChainAssets_1.SmartChainAssets).forEach(function (ticker) {
75
+ var chains = {};
76
+ for (var _i = 0, _a = _this.initializers; _i < _a.length; _i++) {
77
+ var _b = _a[_i], tokens = _b.tokens, chainId = _b.chainId;
78
+ if (tokens[ticker] != null)
79
+ chains[chainId] = tokens[ticker];
80
+ }
81
+ var assetData = SmartChainAssets_1.SmartChainAssets[ticker];
82
+ pricingAssets.push(__assign(__assign({}, assetData.pricing), { chains: chains, ticker: ticker, name: assetData.name }));
83
+ });
84
+ (_f = options.chainStorageCtor) !== null && _f !== void 0 ? _f : (options.chainStorageCtor = function (name) { return new LocalStorageManager_1.LocalStorageManager(name); });
85
+ var chains = {};
86
+ for (var _i = 0, _h = this.initializers; _i < _h.length; _i++) {
87
+ var _j = _h[_i], initializer = _j.initializer, chainId = _j.chainId;
88
+ if (options.chains[chainId] == null)
89
+ continue;
90
+ chains[chainId] = initializer(options.chains[chainId], bitcoinRpc, options.bitcoinNetwork, options.chainStorageCtor);
91
+ }
92
+ return new sdk_lib_1.Swapper(bitcoinRpc, chains, sdk_lib_1.RedundantSwapPrice.createFromTokenMap((_g = options.pricingFeeDifferencePPM) !== null && _g !== void 0 ? _g : 10000n, pricingAssets), pricingAssets, options);
93
+ };
94
+ return SwapperFactory;
95
+ }());
96
+ exports.SwapperFactory = SwapperFactory;
@@ -0,0 +1,171 @@
1
+ import {
2
+ ChainData,
3
+ BitcoinNetwork,
4
+ BitcoinRpc,
5
+ BaseTokenType,
6
+ ChainType,
7
+ StorageObject,
8
+ IStorageManager
9
+ } from "@atomiqlabs/base";
10
+ import {
11
+ BitcoinTokens,
12
+ BtcToken,
13
+ MempoolApi,
14
+ MempoolBitcoinRpc, RedundantSwapPrice,
15
+ RedundantSwapPriceAssets, SCToken, Swapper,
16
+ SwapperOptions
17
+ } from "@atomiqlabs/sdk-lib";
18
+ import {SmartChainAssets} from "./SmartChainAssets";
19
+ import {LocalStorageManager} from "./storage/LocalStorageManager";
20
+
21
+ type ChainInitializer<O, C extends ChainType, T extends BaseTokenType> = {
22
+ chainId: ChainType["ChainId"],
23
+ chainType: ChainType,
24
+ initializer: (
25
+ options: O,
26
+ bitcoinRelay: BitcoinRpc<any>,
27
+ network: BitcoinNetwork,
28
+ storageCtor: <T extends StorageObject>(name: string) => IStorageManager<T>
29
+ ) => ChainData<C>,
30
+ tokens: T,
31
+ options: O
32
+ }
33
+
34
+ type TokensDict<T extends ChainInitializer<any, any, any>> = {
35
+ [K in T["chainId"]]: {
36
+ [val in keyof T["tokens"]]: SCToken<K>
37
+ }
38
+ };
39
+ type GetAllTokens<T extends readonly ChainInitializer<any, any, any>[]> =
40
+ (T extends readonly [infer First extends ChainInitializer<any, any, any>, ...infer Rest extends ChainInitializer<any, any, any>[]]
41
+ ? TokensDict<First> & GetAllTokens<Rest>
42
+ : unknown);
43
+
44
+ export type TokenResolverDict<T extends ChainInitializer<any, any, any>> = {[K in T["chainId"]]: {
45
+ getToken: (address: string) => SCToken<K>
46
+ }};
47
+ type GetAllTokenResolvers<T extends readonly ChainInitializer<any, any, any>[]> =
48
+ (T extends readonly [infer First extends ChainInitializer<any, any, any>, ...infer Rest extends ChainInitializer<any, any, any>[]]
49
+ ? TokenResolverDict<First> & GetAllTokenResolvers<Rest>
50
+ : unknown);
51
+
52
+ type OptionsDict<T extends ChainInitializer<any, any, any>> = {[K in T["chainId"]]: T["options"]};
53
+ type GetAllOptions<T extends readonly ChainInitializer<any, any, any>[]> =
54
+ (T extends readonly [infer First extends ChainInitializer<any, any, any>, ...infer Rest extends ChainInitializer<any, any, any>[]]
55
+ ? OptionsDict<First> & GetAllOptions<Rest>
56
+ : unknown);
57
+
58
+ type ChainTypeDict<T extends ChainInitializer<any, any, any>> = {[K in T["chainId"]]: T["chainType"]};
59
+ type ToMultichain<T extends readonly ChainInitializer<any, any, any>[]> =
60
+ (T extends readonly [infer First extends ChainInitializer<any, any, any>, ...infer Rest extends ChainInitializer<any, any, any>[]]
61
+ ? ChainTypeDict<First> & ToMultichain<Rest>
62
+ : {});
63
+
64
+ export type MultichainSwapperOptions<T extends readonly ChainInitializer<any, any, any>[]> = SwapperOptions & {
65
+ chains: GetAllOptions<T>
66
+ } & {
67
+ chainStorageCtor?: <T extends StorageObject>(name: string) => IStorageManager<T>,
68
+ pricingFeeDifferencePPM?: bigint,
69
+ mempoolApi?: MempoolApi
70
+ };
71
+
72
+ export class SwapperFactory<T extends readonly ChainInitializer<any, any, any>[]> {
73
+
74
+ Tokens: GetAllTokens<T> & {
75
+ BITCOIN: {
76
+ BTC: BtcToken<false>,
77
+ BTCLN: BtcToken<true>
78
+ }
79
+ } = {
80
+ BITCOIN: BitcoinTokens
81
+ } as any;
82
+ TokenResolver: GetAllTokenResolvers<T> = {} as any;
83
+
84
+ constructor(readonly initializers: T) {
85
+ this.initializers = initializers;
86
+ initializers.forEach(initializer => {
87
+ const addressMap: {[tokenAddress: string]: SCToken} = {};
88
+
89
+ this.Tokens[initializer.chainId] = {} as any;
90
+
91
+ for(let ticker in initializer.tokens) {
92
+ const assetData = initializer.tokens[ticker] as any;
93
+ this.Tokens[initializer.chainId][ticker] = addressMap[assetData.address] = {
94
+ chain: "SC",
95
+ chainId: initializer.chainId,
96
+ address: assetData.address,
97
+ name: SmartChainAssets[ticker].name,
98
+ decimals: assetData.decimals,
99
+ displayDecimals: assetData.displayDecimals,
100
+ ticker
101
+ } as any;
102
+ }
103
+
104
+ this.TokenResolver[initializer.chainId] = {
105
+ getToken: (address: string) => addressMap[address]
106
+ } as any;
107
+ });
108
+ }
109
+
110
+ newSwapper(options: MultichainSwapperOptions<T>) {
111
+ options.bitcoinNetwork ??= BitcoinNetwork.MAINNET as any;
112
+ options.storagePrefix ??= "atomiqsdk-"+options.bitcoinNetwork+"-";
113
+
114
+ options.defaultTrustedIntermediaryUrl ??= options.bitcoinNetwork===BitcoinNetwork.MAINNET ?
115
+ "https://node3.gethopa.com:34100" :
116
+ "https://node3.gethopa.com:24100";
117
+
118
+ options.registryUrl ??= options.bitcoinNetwork===BitcoinNetwork.MAINNET ?
119
+ "https://api.github.com/repos/adambor/SolLightning-registry/contents/registry-mainnet.json?ref=main" :
120
+ "https://api.github.com/repos/adambor/SolLightning-registry/contents/registry.json?ref=main";
121
+
122
+ const mempoolApi = options.mempoolApi ?? new MempoolApi(
123
+ options.bitcoinNetwork===BitcoinNetwork.TESTNET ?
124
+ [
125
+ "https://mempool.space/testnet/api/",
126
+ "https://mempool.fra.mempool.space/testnet/api/",
127
+ "https://mempool.va1.mempool.space/testnet/api/",
128
+ "https://mempool.tk7.mempool.space/testnet/api/"
129
+ ] :
130
+ [
131
+ "https://mempool.space/api/",
132
+ "https://mempool.fra.mempool.space/api/",
133
+ "https://mempool.va1.mempool.space/api/",
134
+ "https://mempool.tk7.mempool.space/api/"
135
+ ]
136
+ );
137
+ const bitcoinRpc = new MempoolBitcoinRpc(mempoolApi);
138
+
139
+ const pricingAssets: (RedundantSwapPriceAssets<ToMultichain<T>>[number] & {ticker: string, name: string})[] = [];
140
+ Object.keys(SmartChainAssets).forEach((ticker) => {
141
+ const chains: any = {};
142
+ for(let {tokens, chainId} of this.initializers) {
143
+ if(tokens[ticker]!=null) chains[chainId] = tokens[ticker];
144
+ }
145
+ const assetData = SmartChainAssets[ticker];
146
+ pricingAssets.push({
147
+ ...assetData.pricing,
148
+ chains,
149
+ ticker,
150
+ name: assetData.name
151
+ })
152
+ });
153
+
154
+ options.chainStorageCtor ??= (name: string) => new LocalStorageManager(name);
155
+
156
+ const chains: {[key in T[number]["chainId"]]: ChainData<any>} = {} as any;
157
+ for(let {initializer, chainId} of this.initializers) {
158
+ if(options.chains[chainId]==null) continue;
159
+ chains[chainId] = initializer(options.chains[chainId], bitcoinRpc, options.bitcoinNetwork, options.chainStorageCtor) as any;
160
+ }
161
+
162
+ return new Swapper<ToMultichain<T>>(
163
+ bitcoinRpc,
164
+ chains as any,
165
+ RedundantSwapPrice.createFromTokenMap<ToMultichain<T>>(options.pricingFeeDifferencePPM ?? 10000n, pricingAssets),
166
+ pricingAssets,
167
+ options
168
+ );
169
+ }
170
+
171
+ }
package/src/Utils.js ADDED
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.timeoutSignal = exports.fromHumanReadableString = exports.toHumanReadableString = void 0;
4
+ var sdk_lib_1 = require("@atomiqlabs/sdk-lib");
5
+ function toHumanReadableString(amount, currencySpec) {
6
+ if (amount == null)
7
+ return null;
8
+ return (0, sdk_lib_1.toDecimal)(amount, currencySpec.decimals, undefined, currencySpec.displayDecimals);
9
+ }
10
+ exports.toHumanReadableString = toHumanReadableString;
11
+ function fromHumanReadableString(amount, currencySpec) {
12
+ if (amount === "" || amount == null)
13
+ return null;
14
+ return (0, sdk_lib_1.fromDecimal)(amount, currencySpec.decimals);
15
+ }
16
+ exports.fromHumanReadableString = fromHumanReadableString;
17
+ /**
18
+ * Returns an abort signal that aborts after a specified timeout in milliseconds
19
+ *
20
+ * @param timeout Milliseconds to wait
21
+ * @param abortReason Abort with this abort reason
22
+ * @param abortSignal Abort signal to extend
23
+ */
24
+ function timeoutSignal(timeout, abortReason, abortSignal) {
25
+ if (timeout == null)
26
+ return abortSignal;
27
+ var abortController = new AbortController();
28
+ var timeoutHandle = setTimeout(function () { return abortController.abort(abortReason || new Error("Timed out")); }, timeout);
29
+ if (abortSignal != null) {
30
+ abortSignal.addEventListener("abort", function () {
31
+ clearTimeout(timeoutHandle);
32
+ abortController.abort(abortSignal.reason);
33
+ });
34
+ }
35
+ return abortController.signal;
36
+ }
37
+ exports.timeoutSignal = timeoutSignal;