@tcswap/plugins 4.2.15
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/chainflip/index.cjs +4 -0
- package/dist/chainflip/index.cjs.map +11 -0
- package/dist/chainflip/index.js +4 -0
- package/dist/chainflip/index.js.map +11 -0
- package/dist/chunk-vzvcxw96.js +5 -0
- package/dist/chunk-vzvcxw96.js.map +10 -0
- package/dist/chunk-zweecvg1.js +4 -0
- package/dist/chunk-zweecvg1.js.map +10 -0
- package/dist/evm/index.cjs +4 -0
- package/dist/evm/index.cjs.map +10 -0
- package/dist/evm/index.js +4 -0
- package/dist/evm/index.js.map +10 -0
- package/dist/garden/index.cjs +4 -0
- package/dist/garden/index.cjs.map +10 -0
- package/dist/garden/index.js +4 -0
- package/dist/garden/index.js.map +10 -0
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +10 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +10 -0
- package/dist/near/index.cjs +4 -0
- package/dist/near/index.cjs.map +11 -0
- package/dist/near/index.js +4 -0
- package/dist/near/index.js.map +11 -0
- package/dist/radix/index.cjs +4 -0
- package/dist/radix/index.cjs.map +10 -0
- package/dist/radix/index.js +4 -0
- package/dist/radix/index.js.map +10 -0
- package/dist/solana/index.cjs +4 -0
- package/dist/solana/index.cjs.map +10 -0
- package/dist/solana/index.js +4 -0
- package/dist/solana/index.js.map +10 -0
- package/dist/thorchain/index.cjs +4 -0
- package/dist/thorchain/index.cjs.map +11 -0
- package/dist/thorchain/index.js +4 -0
- package/dist/thorchain/index.js.map +11 -0
- package/dist/types/chainflip/broker.d.ts +23 -0
- package/dist/types/chainflip/broker.d.ts.map +1 -0
- package/dist/types/chainflip/index.d.ts +4 -0
- package/dist/types/chainflip/index.d.ts.map +1 -0
- package/dist/types/chainflip/plugin.d.ts +13 -0
- package/dist/types/chainflip/plugin.d.ts.map +1 -0
- package/dist/types/chainflip/types.d.ts +41 -0
- package/dist/types/chainflip/types.d.ts.map +1 -0
- package/dist/types/evm/index.d.ts +21 -0
- package/dist/types/evm/index.d.ts.map +1 -0
- package/dist/types/garden/index.d.ts +2 -0
- package/dist/types/garden/index.d.ts.map +1 -0
- package/dist/types/garden/plugin.d.ts +21 -0
- package/dist/types/garden/plugin.d.ts.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/near/index.d.ts +3 -0
- package/dist/types/near/index.d.ts.map +1 -0
- package/dist/types/near/nearNames.d.ts +3 -0
- package/dist/types/near/nearNames.d.ts.map +1 -0
- package/dist/types/near/plugin.d.ts +22 -0
- package/dist/types/near/plugin.d.ts.map +1 -0
- package/dist/types/near/types.d.ts +12 -0
- package/dist/types/near/types.d.ts.map +1 -0
- package/dist/types/radix/index.d.ts +13 -0
- package/dist/types/radix/index.d.ts.map +1 -0
- package/dist/types/solana/index.d.ts +2 -0
- package/dist/types/solana/index.d.ts.map +1 -0
- package/dist/types/solana/plugin.d.ts +13 -0
- package/dist/types/solana/plugin.d.ts.map +1 -0
- package/dist/types/thorchain/index.d.ts +4 -0
- package/dist/types/thorchain/index.d.ts.map +1 -0
- package/dist/types/thorchain/plugin.d.ts +110 -0
- package/dist/types/thorchain/plugin.d.ts.map +1 -0
- package/dist/types/thorchain/shared.d.ts +21 -0
- package/dist/types/thorchain/shared.d.ts.map +1 -0
- package/dist/types/thorchain/types.d.ts +64 -0
- package/dist/types/thorchain/types.d.ts.map +1 -0
- package/dist/types/types.d.ts +19 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/utils.d.ts +20 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/package.json +88 -0
- package/src/chainflip/broker.ts +116 -0
- package/src/chainflip/index.ts +3 -0
- package/src/chainflip/plugin.ts +56 -0
- package/src/chainflip/types.ts +37 -0
- package/src/evm/index.ts +49 -0
- package/src/garden/index.ts +1 -0
- package/src/garden/plugin.ts +50 -0
- package/src/index.ts +41 -0
- package/src/near/index.ts +2 -0
- package/src/near/nearNames.ts +37 -0
- package/src/near/plugin.ts +214 -0
- package/src/near/types.ts +9 -0
- package/src/radix/index.ts +28 -0
- package/src/solana/index.ts +1 -0
- package/src/solana/plugin.ts +30 -0
- package/src/thorchain/index.ts +3 -0
- package/src/thorchain/plugin.ts +491 -0
- package/src/thorchain/shared.ts +17 -0
- package/src/thorchain/types.ts +59 -0
- package/src/types.ts +26 -0
- package/src/utils.ts +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,mBAAmB,mBAAmB,CAAC;AACvC,mBAAmB,mBAAmB,CAAC;AAEvC,MAAM,MAAM,YAAY,GAAG,OAAO,eAAe,GAC/C,OAAO,eAAe,GACtB,OAAO,WAAW,GAClB,OAAO,YAAY,GACnB,OAAO,SAAS,GAChB,OAAO,UAAU,CAAC;AAEpB,MAAM,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC;AAE5C,MAAM,MAAM,mBAAmB,GAAG;IAAE,SAAS,EAAE,CAAC,CAAC,SAAS,KAAK,EAAE,KAAK,EAAE,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modifications © 2025 Horizontal Systems.
|
|
3
|
+
*/
|
|
4
|
+
import type { ApproveMode, ApproveReturnType, ProviderName } from "@tcswap/helpers";
|
|
5
|
+
import { type AssetValue } from "@tcswap/helpers";
|
|
6
|
+
import type { SwapKitPluginParams } from "./types";
|
|
7
|
+
export declare function createPlugin<const Name extends string, T extends (params: SwapKitPluginParams) => Record<string, unknown>, K extends {
|
|
8
|
+
supportedUSwapProviders?: readonly ProviderName[];
|
|
9
|
+
}>({ name, properties, methods }: {
|
|
10
|
+
name: Name;
|
|
11
|
+
properties?: K;
|
|
12
|
+
methods: T;
|
|
13
|
+
}): { [key in Name]: (pluginParams: SwapKitPluginParams) => K & ReturnType<T>; };
|
|
14
|
+
export declare function approve<T extends ApproveMode>({ approveMode, getWallet }: {
|
|
15
|
+
approveMode: T;
|
|
16
|
+
} & SwapKitPluginParams): ({ assetValue, spenderAddress }: {
|
|
17
|
+
spenderAddress: string;
|
|
18
|
+
assetValue: AssetValue;
|
|
19
|
+
}) => Promise<string> | Promise<boolean> | ApproveReturnType<T>;
|
|
20
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAY,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC9F,OAAO,EAAE,KAAK,UAAU,EAAyB,MAAM,iBAAiB,CAAC;AACzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,wBAAgB,YAAY,CAC1B,KAAK,CAAC,IAAI,SAAS,MAAM,EACzB,CAAC,SAAS,CAAC,MAAM,EAAE,mBAAmB,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClE,CAAC,SAAS;IAAE,uBAAuB,CAAC,EAAE,SAAS,YAAY,EAAE,CAAA;CAAE,EAC/D,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE,CAAC,CAAA;CAAE,GAK5C,GAAG,GAAG,IAAI,IAAI,kBAJb,mBAAmB,KACO,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAGZ,CAC9D;AAED,wBAAgB,OAAO,CAAC,CAAC,SAAS,WAAW,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE;IAAE,WAAW,EAAE,CAAC,CAAA;CAAE,GAAG,mBAAmB,IACzF,gCAAgC;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,+DAwB3G"}
|
package/package.json
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": "swapkit-oss",
|
|
3
|
+
"dependencies": {
|
|
4
|
+
"@near-js/utils": "~2.5.0",
|
|
5
|
+
"@polkadot/keyring": "~13.5.7",
|
|
6
|
+
"@polkadot/util": "~13.5.7",
|
|
7
|
+
"@solana/web3.js": "~1.98.0",
|
|
8
|
+
"@tcswap/helpers": "4.5.15",
|
|
9
|
+
"@tcswap/toolboxes": "4.3.15",
|
|
10
|
+
"ts-pattern": "^5.9.0"
|
|
11
|
+
},
|
|
12
|
+
"description": "USwap Plugin - Chainflip",
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@near-js/utils": "2.5.0",
|
|
15
|
+
"@polkadot/keyring": "13.5.7",
|
|
16
|
+
"@polkadot/util": "13.5.7",
|
|
17
|
+
"@solana/web3.js": "1.98.4",
|
|
18
|
+
"ts-pattern": "5.9.0"
|
|
19
|
+
},
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"bun": "./src/index.ts",
|
|
23
|
+
"default": "./dist/index.js",
|
|
24
|
+
"require": "./dist/index.cjs",
|
|
25
|
+
"types": "./dist/types/index.d.ts"
|
|
26
|
+
},
|
|
27
|
+
"./chainflip": {
|
|
28
|
+
"bun": "./src/chainflip/index.ts",
|
|
29
|
+
"default": "./dist/chainflip/index.js",
|
|
30
|
+
"require": "./dist/chainflip/index.cjs",
|
|
31
|
+
"types": "./dist/types/chainflip/index.d.ts"
|
|
32
|
+
},
|
|
33
|
+
"./evm": {
|
|
34
|
+
"bun": "./src/evm/index.ts",
|
|
35
|
+
"default": "./dist/evm/index.js",
|
|
36
|
+
"require": "./dist/evm/index.cjs",
|
|
37
|
+
"types": "./dist/types/evm/index.d.ts"
|
|
38
|
+
},
|
|
39
|
+
"./garden": {
|
|
40
|
+
"bun": "./src/garden/index.ts",
|
|
41
|
+
"default": "./dist/garden/index.js",
|
|
42
|
+
"require": "./dist/garden/index.cjs",
|
|
43
|
+
"types": "./dist/types/garden/index.d.ts"
|
|
44
|
+
},
|
|
45
|
+
"./near": {
|
|
46
|
+
"bun": "./src/near/index.ts",
|
|
47
|
+
"default": "./dist/near/index.js",
|
|
48
|
+
"require": "./dist/near/index.cjs",
|
|
49
|
+
"types": "./dist/types/near/index.d.ts"
|
|
50
|
+
},
|
|
51
|
+
"./radix": {
|
|
52
|
+
"bun": "./src/radix/index.ts",
|
|
53
|
+
"default": "./dist/radix/index.js",
|
|
54
|
+
"require": "./dist/radix/index.cjs",
|
|
55
|
+
"types": "./dist/types/radix/index.d.ts"
|
|
56
|
+
},
|
|
57
|
+
"./solana": {
|
|
58
|
+
"bun": "./src/solana/index.ts",
|
|
59
|
+
"default": "./dist/solana/index.js",
|
|
60
|
+
"require": "./dist/solana/index.cjs",
|
|
61
|
+
"types": "./dist/types/solana/index.d.ts"
|
|
62
|
+
},
|
|
63
|
+
"./thorchain": {
|
|
64
|
+
"bun": "./src/thorchain/index.ts",
|
|
65
|
+
"default": "./dist/thorchain/index.js",
|
|
66
|
+
"require": "./dist/thorchain/index.cjs",
|
|
67
|
+
"types": "./dist/types/thorchain/index.d.ts"
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"files": ["dist/", "src/"],
|
|
71
|
+
"homepage": "https://github.com/thorchain/TCSwap",
|
|
72
|
+
"license": "Apache-2.0",
|
|
73
|
+
"name": "@tcswap/plugins",
|
|
74
|
+
"repository": {
|
|
75
|
+
"directory": "packages/plugins",
|
|
76
|
+
"type": "git",
|
|
77
|
+
"url": "git+https://github.com/thorchain/TCSwap.git"
|
|
78
|
+
},
|
|
79
|
+
"scripts": {
|
|
80
|
+
"build": "bun run ./build.ts",
|
|
81
|
+
"build:clean": "rm -rf dist && bun run ./build.ts",
|
|
82
|
+
"clean": "rm -rf dist node_modules *.tsbuildinfo",
|
|
83
|
+
"type-check": "bun tsc --noEmit",
|
|
84
|
+
"type-check:go": "tsgo"
|
|
85
|
+
},
|
|
86
|
+
"type": "module",
|
|
87
|
+
"version": "4.2.15"
|
|
88
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modifications © 2025 Horizontal Systems.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { decodeAddress } from "@polkadot/keyring";
|
|
6
|
+
import { isHex, u8aToHex } from "@polkadot/util";
|
|
7
|
+
import { AssetValue, Chain, USwapError, wrapWithThrow } from "@tcswap/helpers";
|
|
8
|
+
import type { getEvmToolbox } from "@tcswap/toolboxes/evm";
|
|
9
|
+
import type { getSubstrateToolbox } from "@tcswap/toolboxes/substrate";
|
|
10
|
+
|
|
11
|
+
import type { WithdrawFeeResponse } from "./types";
|
|
12
|
+
|
|
13
|
+
type ChainflipToolbox = Awaited<ReturnType<typeof getSubstrateToolbox<typeof Chain.Chainflip>>>;
|
|
14
|
+
|
|
15
|
+
export const assetIdentifierToChainflipTicker = new Map<string, string>([
|
|
16
|
+
["ARB.ETH", "ArbEth"],
|
|
17
|
+
["ARB.USDC-0XAF88D065E77C8CC2239327C5EDB3A432268E5831", "ArbUsdc"],
|
|
18
|
+
["BTC.BTC", "Btc"],
|
|
19
|
+
["DOT.DOT", "Dot"],
|
|
20
|
+
["ETH.ETH", "Eth"],
|
|
21
|
+
["ETH.FLIP-0X826180541412D574CF1336D22C0C0A287822678A", "Flip"],
|
|
22
|
+
["ETH.USDC-0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48", "Usdc"],
|
|
23
|
+
["ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7", "Usdt"],
|
|
24
|
+
["SOL.SOL", "Sol"],
|
|
25
|
+
["SOL.USDC-EPJFWDD5AUFQSSQEM2QN1XZYBAPC8G4WEGGKZWYTDT1V", "SolUsdc"],
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
const registerAsBroker = (toolbox: ChainflipToolbox) => () => {
|
|
29
|
+
const extrinsic = toolbox.api.tx.swapping?.registerAsBroker?.();
|
|
30
|
+
|
|
31
|
+
if (!extrinsic) {
|
|
32
|
+
throw new USwapError("chainflip_broker_register");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return toolbox.signAndBroadcast({ address: toolbox.getAddress(), tx: extrinsic });
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const withdrawFee =
|
|
39
|
+
(toolbox: ChainflipToolbox) =>
|
|
40
|
+
({ feeAsset, recipient }: { feeAsset: AssetValue; recipient: string }) => {
|
|
41
|
+
const isFeeChainPolkadot = feeAsset.chain === Chain.Polkadot;
|
|
42
|
+
|
|
43
|
+
const recipientAddress = wrapWithThrow(() => {
|
|
44
|
+
return isFeeChainPolkadot ? toolbox.encodeAddress(toolbox.decodeAddress(recipient), "hex") : recipient;
|
|
45
|
+
}, "chainflip_broker_recipient_error");
|
|
46
|
+
|
|
47
|
+
return new Promise<WithdrawFeeResponse>((resolve) => {
|
|
48
|
+
const extrinsic = toolbox.api.tx?.swapping?.withdraw?.(feeAsset.ticker.toLowerCase(), {
|
|
49
|
+
[feeAsset.chain.toLowerCase()]: recipientAddress,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
if (!extrinsic) {
|
|
53
|
+
throw new USwapError("chainflip_broker_withdraw");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
toolbox.signAndBroadcast({
|
|
57
|
+
callback: (result) => {
|
|
58
|
+
if (!result.status?.isFinalized) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const withdrawEvent = result.events.find((event) => event.event.method === "WithdrawalRequested");
|
|
63
|
+
|
|
64
|
+
if (!withdrawEvent) {
|
|
65
|
+
throw new USwapError("chainflip_channel_error", "Could not find 'WithdrawalRequested' event");
|
|
66
|
+
}
|
|
67
|
+
const {
|
|
68
|
+
event: {
|
|
69
|
+
data: { egressId, egressAsset, egressAmount, egressFee, destinationAddress },
|
|
70
|
+
},
|
|
71
|
+
} = withdrawEvent.toHuman() as any;
|
|
72
|
+
resolve({ destinationAddress, egressAmount, egressAsset, egressFee, egressId });
|
|
73
|
+
},
|
|
74
|
+
tx: extrinsic,
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const fundStateChainAccount =
|
|
80
|
+
(chainflipToolbox: ChainflipToolbox) =>
|
|
81
|
+
async ({
|
|
82
|
+
evmToolbox,
|
|
83
|
+
stateChainAccount,
|
|
84
|
+
assetValue,
|
|
85
|
+
}: {
|
|
86
|
+
evmToolbox: Awaited<ReturnType<typeof getEvmToolbox>>;
|
|
87
|
+
stateChainAccount: string;
|
|
88
|
+
assetValue: AssetValue;
|
|
89
|
+
}) => {
|
|
90
|
+
const { chainflipGateway } = await import("@tcswap/helpers/contracts");
|
|
91
|
+
|
|
92
|
+
const flipAssetValue = AssetValue.from({ asset: "ETH.FLIP" });
|
|
93
|
+
|
|
94
|
+
if (!assetValue.eqAsset(flipAssetValue)) {
|
|
95
|
+
throw new USwapError("chainflip_broker_fund_only_flip_supported");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (!chainflipToolbox.validateAddress(stateChainAccount)) {
|
|
99
|
+
throw new USwapError("chainflip_broker_fund_invalid_address");
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const hexAddress = isHex(stateChainAccount) ? stateChainAccount : u8aToHex(decodeAddress(stateChainAccount));
|
|
103
|
+
|
|
104
|
+
return evmToolbox.call<string>({
|
|
105
|
+
abi: chainflipGateway,
|
|
106
|
+
contractAddress: "0x6995ab7c4d7f4b03f467cf4c8e920427d9621dbd",
|
|
107
|
+
funcName: "fundStateChainAccount",
|
|
108
|
+
funcParams: [hexAddress, assetValue.getBaseValue("string")],
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export const ChainflipBroker = (chainflipToolbox: ChainflipToolbox) => ({
|
|
113
|
+
fundStateChainAccount: fundStateChainAccount(chainflipToolbox),
|
|
114
|
+
registerAsBroker: registerAsBroker(chainflipToolbox),
|
|
115
|
+
withdrawFee: withdrawFee(chainflipToolbox),
|
|
116
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modifications © 2025 Horizontal Systems.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { AssetValue, type Chain, ProviderName, USwapError } from "@tcswap/helpers";
|
|
6
|
+
import { USwapApi } from "@tcswap/helpers/api";
|
|
7
|
+
import { createPlugin } from "../utils";
|
|
8
|
+
import type { RequestSwapDepositAddressParams } from "./types";
|
|
9
|
+
|
|
10
|
+
export const ChainflipPlugin = createPlugin({
|
|
11
|
+
methods: ({ getWallet }) => ({
|
|
12
|
+
swap: async function chainflipSwap(swapParams: RequestSwapDepositAddressParams) {
|
|
13
|
+
if (!(swapParams?.route?.buyAsset && swapParams.route.meta?.chainflip)) {
|
|
14
|
+
throw new USwapError("core_swap_invalid_params", { ...swapParams });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
route: {
|
|
19
|
+
buyAsset: buyAssetString,
|
|
20
|
+
sellAsset: sellAssetString,
|
|
21
|
+
sellAmount,
|
|
22
|
+
meta: { chainflip },
|
|
23
|
+
},
|
|
24
|
+
maxBoostFeeBps = 0,
|
|
25
|
+
} = swapParams;
|
|
26
|
+
|
|
27
|
+
if (!(sellAssetString && buyAssetString)) {
|
|
28
|
+
throw new USwapError("core_swap_asset_not_recognized");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const sellAsset = await AssetValue.from({ asset: sellAssetString, asyncTokenLookup: true, value: sellAmount });
|
|
32
|
+
|
|
33
|
+
const wallet = getWallet(sellAsset.chain as Exclude<Chain, Chain.Radix>);
|
|
34
|
+
|
|
35
|
+
if (!wallet || !("transfer" in wallet)) {
|
|
36
|
+
throw new USwapError("core_wallet_connection_not_found");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const { depositAddress } = await USwapApi.getChainflipDepositChannel({
|
|
40
|
+
...chainflip,
|
|
41
|
+
maxBoostFeeBps: maxBoostFeeBps || chainflip.maxBoostFeeBps,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const tx = await wallet.transfer({
|
|
45
|
+
assetValue: sellAsset,
|
|
46
|
+
isProgramDerivedAddress: true,
|
|
47
|
+
recipient: depositAddress,
|
|
48
|
+
sender: wallet.address,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
return tx;
|
|
52
|
+
},
|
|
53
|
+
}),
|
|
54
|
+
name: "chainflip",
|
|
55
|
+
properties: { supportedUSwapProviders: [ProviderName.CHAINFLIP, ProviderName.CHAINFLIP_STREAMING] as const },
|
|
56
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { AssetValue, SwapParams } from "@tcswap/helpers";
|
|
2
|
+
import type { QuoteResponseRoute } from "@tcswap/helpers/api";
|
|
3
|
+
|
|
4
|
+
export type WithdrawFeeResponse = {
|
|
5
|
+
egressId: string;
|
|
6
|
+
egressAsset: string;
|
|
7
|
+
egressAmount: string;
|
|
8
|
+
egressFee: string;
|
|
9
|
+
destinationAddress: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type DepositChannelRequest = {
|
|
13
|
+
brokerCommissionBPS: number;
|
|
14
|
+
ccmMetadata: ccmMetadata | null;
|
|
15
|
+
maxBoostFeeBps?: number;
|
|
16
|
+
affiliateFees?: AffiliateBroker[];
|
|
17
|
+
refundParameters?: SwapRefundParameters;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type ccmMetadata = { message: string; gasBudget: string; cfParameters: string };
|
|
21
|
+
|
|
22
|
+
export type SwapDepositResponse = {
|
|
23
|
+
depositChannelId: string;
|
|
24
|
+
depositAddress: string;
|
|
25
|
+
srcChainExpiryBlock: number;
|
|
26
|
+
sellAsset: AssetValue;
|
|
27
|
+
buyAsset: AssetValue;
|
|
28
|
+
recipient: string;
|
|
29
|
+
brokerCommissionBPS: number;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type AffiliateBroker = { brokerAddress: string; basisPoints: number };
|
|
33
|
+
|
|
34
|
+
export type SwapRefundParameters = { retryDuration: number; refundAddress: string; minPrice: string };
|
|
35
|
+
|
|
36
|
+
export type RequestSwapDepositAddressParams = Partial<SwapParams<"chainflip", QuoteResponseRoute>> &
|
|
37
|
+
Partial<DepositChannelRequest>;
|
package/src/evm/index.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modifications © 2025 Horizontal Systems.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
ApproveMode,
|
|
7
|
+
AssetValue,
|
|
8
|
+
type EVMChain,
|
|
9
|
+
EVMChains,
|
|
10
|
+
ProviderName,
|
|
11
|
+
type SwapParams,
|
|
12
|
+
USwapError,
|
|
13
|
+
} from "@tcswap/helpers";
|
|
14
|
+
import type { EVMTransaction, QuoteResponseRoute } from "@tcswap/helpers/api";
|
|
15
|
+
import { approve, createPlugin } from "../utils";
|
|
16
|
+
|
|
17
|
+
export const EVMPlugin = createPlugin({
|
|
18
|
+
methods: ({ getWallet }) => ({
|
|
19
|
+
approveAssetValue: approve({ approveMode: ApproveMode.Approve, getWallet }),
|
|
20
|
+
isAssetValueApproved: approve({ approveMode: ApproveMode.CheckOnly, getWallet }),
|
|
21
|
+
swap: async function evmSwap({ route: { tx, sellAsset }, feeOptionKey }: SwapParams<"evm", QuoteResponseRoute>) {
|
|
22
|
+
const assetValue = await AssetValue.from({ asset: sellAsset, asyncTokenLookup: true });
|
|
23
|
+
const evmChain = assetValue.chain as EVMChain;
|
|
24
|
+
const wallet = getWallet(evmChain);
|
|
25
|
+
|
|
26
|
+
if (!(EVMChains.includes(evmChain) && tx)) {
|
|
27
|
+
throw new USwapError("core_swap_invalid_params");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const { from, to, data, value } = tx as EVMTransaction;
|
|
31
|
+
return wallet.sendTransaction({ data, feeOptionKey, from, to, value: BigInt(value) });
|
|
32
|
+
},
|
|
33
|
+
}),
|
|
34
|
+
name: "evm",
|
|
35
|
+
properties: {
|
|
36
|
+
supportedUSwapProviders: [
|
|
37
|
+
ProviderName.CAMELOT_V3,
|
|
38
|
+
ProviderName.OPENOCEAN_V2,
|
|
39
|
+
ProviderName.OKX,
|
|
40
|
+
ProviderName.ONEINCH,
|
|
41
|
+
ProviderName.PANCAKESWAP,
|
|
42
|
+
ProviderName.PANGOLIN_V1,
|
|
43
|
+
ProviderName.SUSHISWAP_V2,
|
|
44
|
+
ProviderName.TRADERJOE_V2,
|
|
45
|
+
ProviderName.UNISWAP_V2,
|
|
46
|
+
ProviderName.UNISWAP_V3,
|
|
47
|
+
] as const,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { GardenPlugin } from "./plugin";
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modifications © 2025 Horizontal Systems.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { VersionedTransaction } from "@solana/web3.js";
|
|
6
|
+
import { ApproveMode, AssetValue, Chain, EVMChains, ProviderName, type SwapParams, USwapError } from "@tcswap/helpers";
|
|
7
|
+
import type { EVMTransaction, QuoteResponseRoute } from "@tcswap/helpers/api";
|
|
8
|
+
import { match } from "ts-pattern";
|
|
9
|
+
import { approve, createPlugin } from "../utils";
|
|
10
|
+
|
|
11
|
+
export const GardenPlugin = createPlugin({
|
|
12
|
+
methods: ({ getWallet }) => ({
|
|
13
|
+
approveAssetValue: approve({ approveMode: ApproveMode.Approve, getWallet }),
|
|
14
|
+
isAssetValueApproved: approve({ approveMode: ApproveMode.CheckOnly, getWallet }),
|
|
15
|
+
swap: function gardenSwap({ route }: SwapParams<"garden", QuoteResponseRoute>) {
|
|
16
|
+
const { sellAsset, sellAmount, targetAddress, tx } = route;
|
|
17
|
+
|
|
18
|
+
const sellAssetValue = AssetValue.from({ asset: sellAsset, value: sellAmount });
|
|
19
|
+
|
|
20
|
+
return match(sellAssetValue.chain as Chain)
|
|
21
|
+
.returnType<Promise<string>>()
|
|
22
|
+
.with(...EVMChains, (chain) => {
|
|
23
|
+
const wallet = getWallet(chain);
|
|
24
|
+
|
|
25
|
+
const { from, to, data, value } = tx as EVMTransaction;
|
|
26
|
+
return wallet.sendTransaction({ data, from, to, value: BigInt(value) });
|
|
27
|
+
})
|
|
28
|
+
.with(Chain.Solana, async (chain) => {
|
|
29
|
+
const wallet = getWallet(chain);
|
|
30
|
+
const transaction = VersionedTransaction.deserialize(Buffer.from(tx as string, "base64"));
|
|
31
|
+
|
|
32
|
+
const signedTransaction = await wallet.signTransaction(transaction);
|
|
33
|
+
|
|
34
|
+
return wallet.broadcastTransaction(signedTransaction);
|
|
35
|
+
})
|
|
36
|
+
.otherwise(async (chain) => {
|
|
37
|
+
if (!targetAddress) {
|
|
38
|
+
throw new USwapError("plugin_garden_missing_data", { message: "Missing target address: " });
|
|
39
|
+
}
|
|
40
|
+
const wallet = getWallet(chain as Exclude<Chain, Chain.Radix>);
|
|
41
|
+
|
|
42
|
+
const txHash = await wallet.transfer({ assetValue: sellAssetValue, recipient: targetAddress });
|
|
43
|
+
|
|
44
|
+
return txHash;
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
}),
|
|
48
|
+
name: "garden",
|
|
49
|
+
properties: { supportedUSwapProviders: [ProviderName.GARDEN] as const },
|
|
50
|
+
});
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modifications © 2025 Horizontal Systems.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { PluginName, USwapPlugins } from "./types";
|
|
6
|
+
|
|
7
|
+
export * from "./types";
|
|
8
|
+
export * from "./utils";
|
|
9
|
+
|
|
10
|
+
export async function loadPlugin<P extends PluginName>(pluginName: P) {
|
|
11
|
+
const { match } = await import("ts-pattern");
|
|
12
|
+
|
|
13
|
+
const plugin = await match(pluginName as PluginName)
|
|
14
|
+
.with("chainflip", async () => {
|
|
15
|
+
const { ChainflipPlugin } = await import("./chainflip");
|
|
16
|
+
return ChainflipPlugin;
|
|
17
|
+
})
|
|
18
|
+
.with("thorchain", async () => {
|
|
19
|
+
const { ThorchainPlugin } = await import("./thorchain");
|
|
20
|
+
return ThorchainPlugin;
|
|
21
|
+
})
|
|
22
|
+
.with("radix", async () => {
|
|
23
|
+
const { RadixPlugin } = await import("./radix");
|
|
24
|
+
return RadixPlugin;
|
|
25
|
+
})
|
|
26
|
+
.with("evm", async () => {
|
|
27
|
+
const { EVMPlugin } = await import("./evm");
|
|
28
|
+
return EVMPlugin;
|
|
29
|
+
})
|
|
30
|
+
.with("solana", async () => {
|
|
31
|
+
const { SolanaPlugin } = await import("./solana");
|
|
32
|
+
return SolanaPlugin;
|
|
33
|
+
})
|
|
34
|
+
.with("near", async () => {
|
|
35
|
+
const { NearPlugin } = await import("./near");
|
|
36
|
+
return NearPlugin;
|
|
37
|
+
})
|
|
38
|
+
.exhaustive();
|
|
39
|
+
|
|
40
|
+
return plugin as unknown as USwapPlugins[P];
|
|
41
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { parseNearAmount } from "@near-js/utils";
|
|
2
|
+
|
|
3
|
+
const MINIMUM_NAME_LENGTH = 2;
|
|
4
|
+
const MAXIMUM_NAME_LENGTH = 64;
|
|
5
|
+
|
|
6
|
+
export function validateNearName(name: string): boolean {
|
|
7
|
+
if (name.length < MINIMUM_NAME_LENGTH || name.length > MAXIMUM_NAME_LENGTH) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Only lowercase letters, numbers, and hyphens
|
|
12
|
+
// Cannot start or end with hyphen
|
|
13
|
+
// No consecutive hyphens
|
|
14
|
+
return /^[a-z0-9]+(-[a-z0-9]+)*$/.test(name);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function calculateNearNameCost(name: string): string {
|
|
18
|
+
// Pricing based on name length
|
|
19
|
+
// These are suggested prices, the actual minimum is ~0.00182 NEAR
|
|
20
|
+
const length = name.length;
|
|
21
|
+
|
|
22
|
+
let costInNear: string;
|
|
23
|
+
if (length <= 2) {
|
|
24
|
+
costInNear = "50"; // 50 NEAR for 2-char names
|
|
25
|
+
} else if (length <= 3) {
|
|
26
|
+
costInNear = "20"; // 20 NEAR for 3-char names
|
|
27
|
+
} else if (length <= 4) {
|
|
28
|
+
costInNear = "5"; // 5 NEAR for 4-char names
|
|
29
|
+
} else if (length <= 5) {
|
|
30
|
+
costInNear = "1"; // 1 NEAR for 5-char names
|
|
31
|
+
} else {
|
|
32
|
+
costInNear = "0.1"; // 0.1 NEAR for 6+ characters
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Convert NEAR to yoctoNEAR
|
|
36
|
+
return parseNearAmount(costInNear) || "0";
|
|
37
|
+
}
|