@lombard.finance/sdk 0.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 (68) hide show
  1. package/README.md +32 -0
  2. package/dist/index.js +12574 -0
  3. package/dist/index.js.map +1 -0
  4. package/package.json +55 -0
  5. package/src/btcSdk/utils/getOutputScript.ts +54 -0
  6. package/src/common/const.ts +3 -0
  7. package/src/common/types/internalTypes.ts +8 -0
  8. package/src/common/types/types.ts +13 -0
  9. package/src/common/utils/convertSatoshi.ts +21 -0
  10. package/src/common/utils/getErrorMessage.ts +35 -0
  11. package/src/common/utils/isValidChain.ts +5 -0
  12. package/src/index.ts +5 -0
  13. package/src/provider/Provider.ts +174 -0
  14. package/src/provider/ReadProvider.ts +120 -0
  15. package/src/provider/index.ts +2 -0
  16. package/src/provider/rpcUrlConfig.ts +8 -0
  17. package/src/provider/types.ts +58 -0
  18. package/src/provider/utils/getMaxPriorityFeePerGas.ts +25 -0
  19. package/src/sdk/apiConfig.ts +20 -0
  20. package/src/sdk/generateDepositBtcAddress/generateDepositBtcAddress.stories.tsx +52 -0
  21. package/src/sdk/generateDepositBtcAddress/generateDepositBtcAddress.ts +64 -0
  22. package/src/sdk/generateDepositBtcAddress/index.ts +1 -0
  23. package/src/sdk/getDepositBtcAddress/getDepositBtcAddress.stories.tsx +53 -0
  24. package/src/sdk/getDepositBtcAddress/getDepositBtcAddress.ts +101 -0
  25. package/src/sdk/getDepositBtcAddress/index.ts +1 -0
  26. package/src/sdk/getDepositsByAddress/getDepositsByAddress.stories.tsx +49 -0
  27. package/src/sdk/getDepositsByAddress/getDepositsByAddress.ts +146 -0
  28. package/src/sdk/getDepositsByAddress/index.ts +1 -0
  29. package/src/sdk/index.ts +3 -0
  30. package/src/sdk/internalTypes.ts +5 -0
  31. package/src/sdk/utils/getCainIdByName.ts +21 -0
  32. package/src/sdk/utils/getChainNameById.ts +17 -0
  33. package/src/stories/components/Button/Button.tsx +43 -0
  34. package/src/stories/components/Button/index.ts +1 -0
  35. package/src/stories/components/CodeBlock/CodeBlock.tsx +24 -0
  36. package/src/stories/components/CodeBlock/CodeBlockStyles.css +3 -0
  37. package/src/stories/components/CodeBlock/index.ts +1 -0
  38. package/src/stories/components/Spinner/Spinner.tsx +25 -0
  39. package/src/stories/components/Spinner/index.ts +1 -0
  40. package/src/stories/const.ts +1 -0
  41. package/src/stories/hooks/useConnect.ts +47 -0
  42. package/src/stories/hooks/useQuery.ts +56 -0
  43. package/src/stories/utils/connectInjectedWallet.ts +12 -0
  44. package/src/stories/utils/fromCamelCase.ts +16 -0
  45. package/src/stories/utils/getMetaTitle.ts +7 -0
  46. package/src/stories/utils/getWalletInfo.ts +31 -0
  47. package/src/vite-env.d.ts +1 -0
  48. package/src/web3Sdk/abi/IERC20.json +222 -0
  49. package/src/web3Sdk/abi/LBTC.json +1400 -0
  50. package/src/web3Sdk/abi/index.ts +4 -0
  51. package/src/web3Sdk/approveLBTC/approveLBTC.stories.tsx +77 -0
  52. package/src/web3Sdk/approveLBTC/approveLBTC.ts +48 -0
  53. package/src/web3Sdk/approveLBTC/index.ts +1 -0
  54. package/src/web3Sdk/claimLBTC/claimLBTC.stories.tsx +77 -0
  55. package/src/web3Sdk/claimLBTC/claimLBTC.ts +62 -0
  56. package/src/web3Sdk/claimLBTC/index.ts +1 -0
  57. package/src/web3Sdk/index.ts +4 -0
  58. package/src/web3Sdk/internalTypes.ts +19 -0
  59. package/src/web3Sdk/lbtcAddressConfig.ts +16 -0
  60. package/src/web3Sdk/signLbtcDestionationAddr/index.ts +1 -0
  61. package/src/web3Sdk/signLbtcDestionationAddr/signLbtcDestionationAddr.stories.tsx +97 -0
  62. package/src/web3Sdk/signLbtcDestionationAddr/signLbtcDestionationAddr.ts +25 -0
  63. package/src/web3Sdk/unstakeLBTC/index.ts +1 -0
  64. package/src/web3Sdk/unstakeLBTC/unstakeLBTC.stories.tsx +77 -0
  65. package/src/web3Sdk/unstakeLBTC/unstakeLBTC.ts +51 -0
  66. package/src/web3Sdk/utils/getGasMultiplier.ts +19 -0
  67. package/src/web3Sdk/utils/getLbtcTokenContract.ts +28 -0
  68. package/src/web3Sdk/utils/getTokenABI.ts +12 -0
@@ -0,0 +1,4 @@
1
+ import IERC20 from './IERC20.json';
2
+ import LBTCABI from './LBTC.json';
3
+
4
+ export { IERC20, LBTCABI };
@@ -0,0 +1,77 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { defaultEnv } from '../../common/const';
3
+ import { Button } from '../../stories/components/Button';
4
+ import { CodeBlock } from '../../stories/components/CodeBlock';
5
+ import { useConnect } from '../../stories/hooks/useConnect';
6
+ import useQuery from '../../stories/hooks/useQuery';
7
+ import { approveLBTC, IApproveLBTCParams } from './approveLBTC';
8
+
9
+ const meta = {
10
+ title: 'Web3SDK/approveLBTC',
11
+ component: StoryView,
12
+ tags: ['autodocs'],
13
+ } satisfies Meta<typeof StoryView>;
14
+
15
+ export default meta;
16
+
17
+ type Story = StoryObj<typeof meta>;
18
+
19
+ export const WithParams: Story = {
20
+ args: {
21
+ amount: 0.00001,
22
+ spender: '',
23
+ env: defaultEnv,
24
+ },
25
+ };
26
+
27
+ type ClaimLBTCProps = Pick<IApproveLBTCParams, 'spender' | 'amount' | 'env'>;
28
+
29
+ export function StoryView(props: ClaimLBTCProps) {
30
+ const {
31
+ data: connectData,
32
+ error: connectError,
33
+ isLoading: isConnectLoading,
34
+ connect,
35
+ } = useConnect();
36
+
37
+ const request = async () => {
38
+ if (!connectData) {
39
+ return;
40
+ }
41
+
42
+ return approveLBTC({ ...connectData, ...props });
43
+ };
44
+
45
+ const { data, error, isLoading, refetch } = useQuery(request, [], false);
46
+
47
+ const formattedConnectData = connectData && {
48
+ account: connectData.account,
49
+ chainId: connectData.chainId,
50
+ };
51
+
52
+ return (
53
+ <>
54
+ <div className="mb-4">
55
+ <Button
56
+ onClick={connect}
57
+ disabled={isConnectLoading}
58
+ isLoading={isConnectLoading}
59
+ >
60
+ Connect
61
+ </Button>
62
+
63
+ <CodeBlock text={connectError || formattedConnectData} />
64
+ </div>
65
+
66
+ <Button
67
+ onClick={refetch}
68
+ disabled={isLoading || !connectData}
69
+ isLoading={isLoading}
70
+ >
71
+ Approve LBTC
72
+ </Button>
73
+
74
+ <CodeBlock text={error || data} />
75
+ </>
76
+ );
77
+ }
@@ -0,0 +1,48 @@
1
+ import { IEnvParam } from '../../common/types/internalTypes';
2
+ import { toSatoshi } from '../../common/utils/convertSatoshi';
3
+ import { IWeb3SendResult, Provider } from '../../provider';
4
+ import { IProviderBasedParams } from '../internalTypes';
5
+ import { getGasMultiplier } from '../utils/getGasMultiplier';
6
+ import { getLbtcTokenContract } from '../utils/getLbtcTokenContract';
7
+
8
+ export interface IApproveLBTCParams extends IProviderBasedParams, IEnvParam {
9
+ /**
10
+ * Spender address
11
+ */
12
+ spender: string;
13
+ /**
14
+ * The amount of LBTC to approve
15
+ */
16
+ amount: number;
17
+ }
18
+
19
+ /**
20
+ * Approves the transfer of a specified amount of LBTC tokens.
21
+ *
22
+ * @param {IApproveLBTCParams} params
23
+ *
24
+ * @returns {Promise<IWeb3SendResult>} transaction promise
25
+ */
26
+ export function approveLBTC({
27
+ spender,
28
+ amount,
29
+ env,
30
+ ...providerParams
31
+ }: IApproveLBTCParams): Promise<IWeb3SendResult> {
32
+ const provider = new Provider(providerParams);
33
+ const tokenContract = getLbtcTokenContract(provider, env);
34
+ const amountSat = toSatoshi(amount);
35
+
36
+ const tx = tokenContract.methods.approve(spender, amountSat);
37
+
38
+ return provider.sendTransactionAsync(
39
+ provider.account,
40
+ tokenContract.options.address,
41
+ {
42
+ data: tx.encodeABI(),
43
+ estimate: true,
44
+ estimateFee: true,
45
+ gasLimitMultiplier: getGasMultiplier(provider.chainId),
46
+ },
47
+ );
48
+ }
@@ -0,0 +1 @@
1
+ export * from './approveLBTC';
@@ -0,0 +1,77 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { defaultEnv } from '../../common/const';
3
+ import { Button } from '../../stories/components/Button';
4
+ import { CodeBlock } from '../../stories/components/CodeBlock';
5
+ import { useConnect } from '../../stories/hooks/useConnect';
6
+ import useQuery from '../../stories/hooks/useQuery';
7
+ import { claimLBTC, IClaimLBTCParams } from './claimLBTC';
8
+
9
+ const meta = {
10
+ title: 'Web3SDK/claimLBTC',
11
+ component: StoryView,
12
+ tags: ['autodocs'],
13
+ } satisfies Meta<typeof StoryView>;
14
+
15
+ export default meta;
16
+
17
+ type Story = StoryObj<typeof meta>;
18
+
19
+ export const WithParams: Story = {
20
+ args: {
21
+ proofSignature: '',
22
+ data: '',
23
+ env: defaultEnv,
24
+ },
25
+ };
26
+
27
+ type ClaimLBTCProps = Pick<IClaimLBTCParams, 'data' | 'env' | 'proofSignature'>;
28
+
29
+ export function StoryView(props: ClaimLBTCProps) {
30
+ const {
31
+ data: connectData,
32
+ error: connectError,
33
+ isLoading: isConnectLoading,
34
+ connect,
35
+ } = useConnect();
36
+
37
+ const request = async () => {
38
+ if (!connectData) {
39
+ return;
40
+ }
41
+
42
+ return claimLBTC({ ...connectData, ...props });
43
+ };
44
+
45
+ const { data, error, isLoading, refetch } = useQuery(request, [], false);
46
+
47
+ const formattedConnectData = connectData && {
48
+ account: connectData.account,
49
+ chainId: connectData.chainId,
50
+ };
51
+
52
+ return (
53
+ <>
54
+ <div className="mb-4">
55
+ <Button
56
+ onClick={connect}
57
+ disabled={isConnectLoading}
58
+ isLoading={isConnectLoading}
59
+ >
60
+ Connect
61
+ </Button>
62
+
63
+ <CodeBlock text={connectError || formattedConnectData} />
64
+ </div>
65
+
66
+ <Button
67
+ onClick={refetch}
68
+ disabled={isLoading || !connectData}
69
+ isLoading={isLoading}
70
+ >
71
+ Claim LBTC
72
+ </Button>
73
+
74
+ <CodeBlock text={error || data} />
75
+ </>
76
+ );
77
+ }
@@ -0,0 +1,62 @@
1
+ import { IEnvParam } from '../../common/types/internalTypes';
2
+ import { getErrorMessage } from '../../common/utils/getErrorMessage';
3
+ import { IWeb3SendResult, Provider } from '../../provider';
4
+ import { IProviderBasedParams } from '../internalTypes';
5
+ import { getGasMultiplier } from '../utils/getGasMultiplier';
6
+ import { getLbtcTokenContract } from '../utils/getLbtcTokenContract';
7
+
8
+ const INSUFFICIENT_FUNDS_PARTIAL_ERROR = 'insufficient funds';
9
+ const INSUFFICIENT_FUNDS_ERROR = 'Insufficient funds for transfer';
10
+
11
+ export interface IClaimLBTCParams extends IProviderBasedParams, IEnvParam {
12
+ /**
13
+ * Raw payload from deposit notarization.
14
+ */
15
+ data: string;
16
+ /**
17
+ * Signature from deposit notarization.
18
+ */
19
+ proofSignature: string;
20
+ }
21
+
22
+ /**
23
+ * Claims LBTC.
24
+ *
25
+ * @param {IClaimLBTCParams} params - The parameters for claiming LBTC.
26
+ *
27
+ * @returns {Promise<IWeb3SendResult>} transaction promise
28
+ */
29
+ export async function claimLBTC({
30
+ data,
31
+ proofSignature,
32
+ env,
33
+ ...providerParams
34
+ }: IClaimLBTCParams): Promise<IWeb3SendResult> {
35
+ const provider = new Provider(providerParams);
36
+ const tokenContract = getLbtcTokenContract(provider, env);
37
+
38
+ const tx = tokenContract.methods.mint(data, proofSignature);
39
+
40
+ try {
41
+ const result = await provider.sendTransactionAsync(
42
+ provider.account,
43
+ tokenContract.options.address,
44
+ {
45
+ data: tx.encodeABI(),
46
+ estimate: true,
47
+ estimateFee: true,
48
+ gasLimitMultiplier: getGasMultiplier(provider.chainId),
49
+ },
50
+ );
51
+
52
+ return result;
53
+ } catch (error) {
54
+ const errorMessage = getErrorMessage(error);
55
+
56
+ if (errorMessage.includes(INSUFFICIENT_FUNDS_PARTIAL_ERROR)) {
57
+ throw new Error(INSUFFICIENT_FUNDS_ERROR);
58
+ }
59
+
60
+ throw new Error(errorMessage);
61
+ }
62
+ }
@@ -0,0 +1 @@
1
+ export * from './claimLBTC';
@@ -0,0 +1,4 @@
1
+ export * from './approveLBTC';
2
+ export * from './claimLBTC';
3
+ export * from './signLbtcDestionationAddr';
4
+ export * from './unstakeLBTC';
@@ -0,0 +1,19 @@
1
+ import Web3 from 'web3';
2
+ import { TChainId } from '../common/types/types';
3
+
4
+ export interface IProviderBasedParams {
5
+ /**
6
+ * The web3 instance with write access.
7
+ *
8
+ * {@inheritDoc Web3}
9
+ */
10
+ web3: Web3;
11
+ /**
12
+ * Current chain ID
13
+ */
14
+ chainId: TChainId;
15
+ /**
16
+ * Current account address
17
+ */
18
+ account: string;
19
+ }
@@ -0,0 +1,16 @@
1
+ import { defaultEnv } from '../common/const';
2
+ import { OChainId, TChainId, TEnv } from '../common/types/types';
3
+
4
+ type LbtcTokenConfig = Partial<Record<TChainId, string>>;
5
+
6
+ const testnetConfig: LbtcTokenConfig = {
7
+ [OChainId.holesky]: '0xED7bfd5C1790576105Af4649817f6d35A75CD818',
8
+ };
9
+
10
+ const mainnetConfig: LbtcTokenConfig = {
11
+ [OChainId.ethereum]: '0x8236a87084f8b84306f72007f36f2618a5634494',
12
+ };
13
+
14
+ export function getLbtcAddressConfig(env: TEnv = defaultEnv): LbtcTokenConfig {
15
+ return env === 'prod' ? mainnetConfig : testnetConfig;
16
+ }
@@ -0,0 +1 @@
1
+ export * from './signLbtcDestionationAddr';
@@ -0,0 +1,97 @@
1
+ import type { Meta } from '@storybook/react';
2
+ import Web3, { FMT_BYTES, FMT_NUMBER } from 'web3';
3
+ import { OChainId, TChainId } from '../../common/types/types';
4
+ import { Button } from '../../stories/components/Button';
5
+ import { CodeBlock } from '../../stories/components/CodeBlock';
6
+ import { useConnect } from '../../stories/hooks/useConnect';
7
+ import useQuery from '../../stories/hooks/useQuery';
8
+ import { fromCamelCase } from '../../stories/utils/fromCamelCase';
9
+ import { signLbtcDestionationAddr } from './signLbtcDestionationAddr';
10
+
11
+ const { name } = signLbtcDestionationAddr;
12
+ const nameWithWhitespaces = fromCamelCase(name);
13
+
14
+ const meta = {
15
+ title: 'Web3SDK/signLbtcDestionationAddr',
16
+ component: StoryView,
17
+ tags: ['autodocs'],
18
+ } satisfies Meta<typeof StoryView>;
19
+
20
+ export default meta;
21
+
22
+ export function StoryView() {
23
+ const {
24
+ data: connectData,
25
+ error: connectError,
26
+ isLoading: isConnectLoading,
27
+ connect,
28
+ } = useConnect();
29
+
30
+ const request = async () => {
31
+ if (!connectData) {
32
+ return;
33
+ }
34
+
35
+ return signLbtcDestionationAddr(connectData);
36
+ };
37
+
38
+ const { data, error, isLoading, refetch } = useQuery(request, [], false);
39
+
40
+ const formattedConnectData = connectData && {
41
+ account: connectData.account,
42
+ chainId: connectData.chainId,
43
+ };
44
+
45
+ return (
46
+ <>
47
+ <p>
48
+ This method is used to get the signature of the Liquid BTC destination
49
+ address. The signature is used for generating the deposit address.
50
+ </p>
51
+
52
+ <div className="mb-4">
53
+ <Button
54
+ onClick={connect}
55
+ disabled={isConnectLoading}
56
+ isLoading={isConnectLoading}
57
+ >
58
+ Connect
59
+ </Button>
60
+
61
+ <CodeBlock text={connectError || formattedConnectData} />
62
+ </div>
63
+
64
+ <Button
65
+ onClick={refetch}
66
+ disabled={isLoading || !connectData}
67
+ isLoading={isLoading}
68
+ >
69
+ {nameWithWhitespaces}
70
+ </Button>
71
+
72
+ <CodeBlock text={error || data} />
73
+ </>
74
+ );
75
+ }
76
+
77
+ async function getWalletInfo(web3: Web3) {
78
+ const [account] = await web3.eth.getAccounts();
79
+
80
+ if (!account) {
81
+ throw new Error('No account found');
82
+ }
83
+
84
+ const chainId = await web3.eth.getChainId({
85
+ bytes: FMT_BYTES.HEX,
86
+ number: FMT_NUMBER.NUMBER,
87
+ });
88
+
89
+ return {
90
+ account,
91
+ chainId,
92
+ };
93
+ }
94
+
95
+ function isValidChain(chainId: number): chainId is TChainId {
96
+ return Object.values(OChainId).includes(chainId as TChainId);
97
+ }
@@ -0,0 +1,25 @@
1
+ import { Provider } from '../../provider';
2
+ import { IProviderBasedParams } from '../internalTypes';
3
+
4
+ export type SignLbtcDestionationAddrParams = IProviderBasedParams;
5
+
6
+ /**
7
+ * Signs the destination address for the LBTC in active chain
8
+ * in the current account. Signing is necessary for the
9
+ * generation of the deposit address.
10
+ *
11
+ * @param {SignLbtcDestionationAddrParams} params - The parameters for signing the destination address.
12
+ *
13
+ * @returns {Promise<string>} The signature of the message.
14
+ */
15
+ export async function signLbtcDestionationAddr({
16
+ web3,
17
+ chainId,
18
+ account,
19
+ }: SignLbtcDestionationAddrParams): Promise<string> {
20
+ const provider = new Provider({ web3, chainId, account });
21
+
22
+ const message = `destination chain id is ${chainId}`;
23
+
24
+ return provider.signMessage(message);
25
+ }
@@ -0,0 +1 @@
1
+ export * from './unstakeLBTC';
@@ -0,0 +1,77 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { defaultEnv } from '../../common/const';
3
+ import { Button } from '../../stories/components/Button';
4
+ import { CodeBlock } from '../../stories/components/CodeBlock';
5
+ import { useConnect } from '../../stories/hooks/useConnect';
6
+ import useQuery from '../../stories/hooks/useQuery';
7
+ import { IUnstakeLBTCParams, unstakeLBTC } from './unstakeLBTC';
8
+
9
+ const meta = {
10
+ title: 'Web3SDK/unstakeLBTC',
11
+ component: StoryView,
12
+ tags: ['autodocs'],
13
+ } satisfies Meta<typeof StoryView>;
14
+
15
+ export default meta;
16
+
17
+ type Story = StoryObj<typeof meta>;
18
+
19
+ export const WithParams: Story = {
20
+ args: {
21
+ amount: 0.00001,
22
+ btcAddress: '',
23
+ env: defaultEnv,
24
+ },
25
+ };
26
+
27
+ type ClaimLBTCProps = Pick<IUnstakeLBTCParams, 'btcAddress' | 'env' | 'amount'>;
28
+
29
+ export function StoryView(props: ClaimLBTCProps) {
30
+ const {
31
+ data: connectData,
32
+ error: connectError,
33
+ isLoading: isConnectLoading,
34
+ connect,
35
+ } = useConnect();
36
+
37
+ const request = async () => {
38
+ if (!connectData) {
39
+ return;
40
+ }
41
+
42
+ return unstakeLBTC({ ...connectData, ...props });
43
+ };
44
+
45
+ const { data, error, isLoading, refetch } = useQuery(request, [], false);
46
+
47
+ const formattedConnectData = connectData && {
48
+ account: connectData.account,
49
+ chainId: connectData.chainId,
50
+ };
51
+
52
+ return (
53
+ <>
54
+ <div className="mb-4">
55
+ <Button
56
+ onClick={connect}
57
+ disabled={isConnectLoading}
58
+ isLoading={isConnectLoading}
59
+ >
60
+ Connect
61
+ </Button>
62
+
63
+ <CodeBlock text={connectError || formattedConnectData} />
64
+ </div>
65
+
66
+ <Button
67
+ onClick={refetch}
68
+ disabled={isLoading || !connectData}
69
+ isLoading={isLoading}
70
+ >
71
+ Unstake LBTC
72
+ </Button>
73
+
74
+ <CodeBlock text={error || data} />
75
+ </>
76
+ );
77
+ }
@@ -0,0 +1,51 @@
1
+ import { getOutputScript } from '../../btcSdk/utils/getOutputScript';
2
+ import { IEnvParam } from '../../common/types/internalTypes';
3
+ import { toSatoshi } from '../../common/utils/convertSatoshi';
4
+ import { IWeb3SendResult, Provider } from '../../provider';
5
+ import { IProviderBasedParams } from '../internalTypes';
6
+ import { getGasMultiplier } from '../utils/getGasMultiplier';
7
+ import { getLbtcTokenContract } from '../utils/getLbtcTokenContract';
8
+
9
+ export interface IUnstakeLBTCParams extends IProviderBasedParams, IEnvParam {
10
+ /**
11
+ * The BTC address to send the BTC to.
12
+ */
13
+ btcAddress: string;
14
+ /**
15
+ * The amount of LBTC to unstake.
16
+ */
17
+ amount: number;
18
+ }
19
+
20
+ /**
21
+ * Unstakes LBTC to the specified BTC address.
22
+ *
23
+ * @param {IUnstakeLBTCParams} params
24
+ *
25
+ * @returns {Promise<IWeb3SendResult>} transaction promise
26
+ */
27
+ export function unstakeLBTC({
28
+ btcAddress,
29
+ amount,
30
+ env,
31
+ ...providerParams
32
+ }: IUnstakeLBTCParams): Promise<IWeb3SendResult> {
33
+ const provider = new Provider(providerParams);
34
+ const tokenContract = getLbtcTokenContract(provider, env);
35
+ const outputScript = getOutputScript(btcAddress, env);
36
+
37
+ const amountSat = toSatoshi(amount);
38
+
39
+ const tx = tokenContract.methods.burn(outputScript, amountSat);
40
+
41
+ return provider.sendTransactionAsync(
42
+ provider.account,
43
+ tokenContract.options.address,
44
+ {
45
+ data: tx.encodeABI(),
46
+ estimate: true,
47
+ estimateFee: true,
48
+ gasLimitMultiplier: getGasMultiplier(provider.chainId),
49
+ },
50
+ );
51
+ }
@@ -0,0 +1,19 @@
1
+ import { OChainId } from '../../common/types/types';
2
+
3
+ /**
4
+ * Returns the gas multiplier for the given chain ID.
5
+ *
6
+ * @param chainId - Chain ID.
7
+ *
8
+ * @returns Gas multiplier.
9
+ */
10
+ export function getGasMultiplier(chainId: number): number {
11
+ switch (chainId) {
12
+ case OChainId.ethereum:
13
+ return 1.3;
14
+ case OChainId.holesky:
15
+ return 1.5;
16
+ default:
17
+ return 1.3;
18
+ }
19
+ }
@@ -0,0 +1,28 @@
1
+ import { TChainId, TEnv } from '../../common/types/types';
2
+ import { Provider } from '../../provider';
3
+ import { getLbtcAddressConfig } from '../lbtcAddressConfig';
4
+ import { getTokenABI } from './getTokenABI';
5
+
6
+ export function getLbtcTokenContract(provider: Provider, env?: TEnv) {
7
+ const lbtcAddressConfig = getLbtcAddressConfig(env);
8
+
9
+ const tokenAddress = lbtcAddressConfig[provider.chainId as TChainId];
10
+
11
+ if (!tokenAddress) {
12
+ throw new Error(
13
+ `Token address for chain ${provider.chainId} is not defined`,
14
+ );
15
+ }
16
+
17
+ const abi = getTokenABI('LBTC');
18
+
19
+ const contract = provider.createContract(abi, tokenAddress);
20
+
21
+ if (!contract.options.address) {
22
+ contract.options.address = tokenAddress;
23
+ }
24
+
25
+ return contract as typeof contract & {
26
+ options: typeof contract.options & { address: string };
27
+ };
28
+ }
@@ -0,0 +1,12 @@
1
+ import { IERC20, LBTCABI } from '../abi';
2
+
3
+ type Token = 'LBTC' | 'ERC20';
4
+
5
+ export function getTokenABI(token: Token) {
6
+ switch (token) {
7
+ case 'LBTC':
8
+ return LBTCABI;
9
+ default:
10
+ return IERC20;
11
+ }
12
+ }