@lombard.finance/sdk 3.1.0 → 3.4.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 (76) hide show
  1. package/README.md +60 -1
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.js +73 -62
  4. package/dist/index2.cjs +62 -52
  5. package/dist/index2.cjs.map +1 -1
  6. package/dist/index2.js +8361 -12041
  7. package/dist/index2.js.map +1 -1
  8. package/package.json +35 -33
  9. package/src/api-functions/generateDepositBtcAddress/generateDepositBtcAddress.ts +4 -4
  10. package/src/api-functions/getDepositBtcAddress/getDepositBtcAddress.stories.tsx +8 -0
  11. package/src/api-functions/getDepositBtcAddress/getDepositBtcAddress.ts +3 -3
  12. package/src/api-functions/getDepositsByAddress/getDepositsByAddress.ts +8 -7
  13. package/src/api-functions/getUnstakesByAddress/getUnstakesByAddress.ts +5 -5
  14. package/src/api-functions/getUserStakeAndBakeSignature/getUserStakeAndBakeSignature.stories.tsx +8 -0
  15. package/src/bridge/abi/CCIP_BRIDGE_ADAPTER_ABI.json +704 -0
  16. package/src/bridge/abi/OFT_BRIDGE_ADAPTER_ABI.json +912 -0
  17. package/src/bridge/index.ts +11 -0
  18. package/src/bridge/lib/bridge.stories.tsx +89 -0
  19. package/src/bridge/lib/bridge.ts +101 -0
  20. package/src/bridge/lib/ccip-bridge.stories.tsx +90 -0
  21. package/src/bridge/lib/ccip-bridge.ts +163 -0
  22. package/src/bridge/lib/config.ts +338 -0
  23. package/src/bridge/lib/oft-bridge.stories.tsx +89 -0
  24. package/src/bridge/lib/oft-bridge.ts +211 -0
  25. package/src/common/api-config.ts +8 -2
  26. package/src/common/blockchain-identifier.ts +32 -5
  27. package/src/common/chains.ts +13 -1
  28. package/src/common/contract-info.ts +8 -0
  29. package/src/contract-functions/approveLBTC/approveLBTC.stories.tsx +1 -1
  30. package/src/contract-functions/approveLBTC/approveLBTC.ts +3 -2
  31. package/src/contract-functions/claimLBTC/claimLBTC.ts +3 -2
  32. package/src/contract-functions/getBasculeDepositStatus/getBasculeDepositStatus.ts +10 -4
  33. package/src/contract-functions/getLBTCMintingFee/getLBTCMintingFee.tsx +14 -11
  34. package/src/contract-functions/getLBTCTotalSupply/getLBTCTotalSupply.ts +13 -9
  35. package/src/contract-functions/getPermitNonce/getPermitNonce.ts +16 -10
  36. package/src/contract-functions/getShareValue/getShareValue.stories.tsx +1 -1
  37. package/src/contract-functions/getShareValue/getShareValue.ts +1 -1
  38. package/src/contract-functions/getSharesByAddress/getSharesByAddress.stories.tsx +1 -1
  39. package/src/contract-functions/getSharesByAddress/getSharesByAddress.ts +1 -1
  40. package/src/contract-functions/getStakeAndBakeFee/getStakeAndBakeFee.stories.tsx +14 -1
  41. package/src/contract-functions/getStakeAndBakeFee/getStakeAndBakeFee.tsx +5 -1
  42. package/src/contract-functions/signNetworkFee/signNetworkFee.ts +3 -2
  43. package/src/contract-functions/signStakeAndBake/signStakeAndBake.stories.tsx +2 -1
  44. package/src/contract-functions/signStakeAndBake/signStakeAndBake.ts +8 -3
  45. package/src/contract-functions/unstakeLBTC/unstakeLBTC.ts +3 -2
  46. package/src/index.ts +26 -28
  47. package/src/metrics/get-lbtc-stats.stories.tsx +51 -0
  48. package/src/metrics/get-lbtc-stats.ts +38 -0
  49. package/src/rewards/lib/claim-reward.stories.tsx +1 -0
  50. package/src/rewards/lib/claim-reward.ts +5 -0
  51. package/src/rewards/lib/get-reward-signing-data.stories.tsx +1 -0
  52. package/src/rewards/lib/get-reward-signing-data.ts +4 -0
  53. package/src/tokens/abi/LBTC_ABI.json +1760 -1760
  54. package/src/tokens/abi/LBTC_ABI.ts +1761 -0
  55. package/src/tokens/lbtc-addresses.ts +1 -0
  56. package/src/tokens/token-addresses.ts +32 -0
  57. package/src/tokens/tokens.ts +59 -50
  58. package/src/utils/numbers.ts +3 -0
  59. package/src/vaults/index.ts +35 -176
  60. package/src/vaults/lib/config.ts +196 -0
  61. package/src/vaults/lib/metrics/get-vault-apy.stories.tsx +57 -0
  62. package/src/vaults/lib/metrics/get-vault-apy.ts +132 -0
  63. package/src/vaults/lib/{get-vault-points.stories.tsx → metrics/get-vault-points.stories.tsx} +8 -8
  64. package/src/vaults/lib/{get-vault-points.ts → metrics/get-vault-points.ts} +1 -1
  65. package/src/vaults/lib/metrics/get-vault-tvl.stories.tsx +57 -0
  66. package/src/vaults/lib/metrics/get-vault-tvl.ts +119 -0
  67. package/src/vaults/lib/{cancel-withdraw.stories.tsx → ops/cancel-withdraw.stories.tsx} +9 -9
  68. package/src/vaults/lib/{deposit.stories.tsx → ops/deposit.stories.tsx} +9 -9
  69. package/src/vaults/lib/{deposit.ts → ops/deposit.ts} +10 -10
  70. package/src/vaults/lib/{get-vault-deposits.stories.tsx → ops/get-vault-deposits.stories.tsx} +9 -9
  71. package/src/vaults/lib/{get-vault-deposits.ts → ops/get-vault-deposits.ts} +5 -5
  72. package/src/vaults/lib/{get-vault-withdrawals.stories.tsx → ops/get-vault-withdrawals.stories.tsx} +9 -9
  73. package/src/vaults/lib/{get-vault-withdrawals.ts → ops/get-vault-withdrawals.ts} +5 -5
  74. package/src/vaults/lib/{withdraw.stories.tsx → ops/withdraw.stories.tsx} +9 -9
  75. package/src/vaults/lib/{withdraw.ts → ops/withdraw.ts} +12 -12
  76. package/src/tokens/lbtc-contract.ts +0 -89
@@ -0,0 +1,338 @@
1
+ import BigNumber from 'bignumber.js';
2
+ import { Abi } from 'viem';
3
+ import { ChainId } from '../../common/chains';
4
+ import { ContractInfo } from '../../common/contract-info';
5
+ import { unique } from '../../utils/array';
6
+ import CCIP_BRIDGE_ADAPTER_ABI from '../abi/CCIP_BRIDGE_ADAPTER_ABI.json';
7
+ import OFT_BRIDGE_ADAPTER_ABI from '../abi/OFT_BRIDGE_ADAPTER_ABI.json';
8
+
9
+ export const MIN_BRIDGE_AMOUNT = BigNumber(0.000001);
10
+
11
+ export enum BridgeType {
12
+ /** CCIP - (Chainlink) Cross-Chain Interoperability Protocol */
13
+ CCIP = 'CCIP',
14
+
15
+ /** OFT - (LayerZero) Omnichain Fungible Token */
16
+ OFT = 'OFT',
17
+ }
18
+
19
+ export const BRIDGE_EXPLORER_URL_MAP = {
20
+ [BridgeType.CCIP]: 'https://ccip.chain.link/tx/{txHash}',
21
+ [BridgeType.OFT]: 'https://layerzeroscan.com/tx/{txHash}',
22
+ };
23
+
24
+ export const CCIP_BRIDGE_CHAINS = [
25
+ // Mainnets:
26
+ ChainId.ethereum,
27
+ ChainId.base,
28
+ ChainId.binanceSmartChain,
29
+ ChainId.sonic,
30
+ // Testnets:
31
+ ChainId.baseSepoliaTestnet,
32
+ ChainId.holesky,
33
+ ];
34
+ export type CCIPBridgeChain = (typeof CCIP_BRIDGE_CHAINS)[number];
35
+
36
+ export const OFT_BRIDGE_CHAINS = [
37
+ // Mainnets:
38
+ ChainId.ethereum,
39
+ ChainId.berachain,
40
+ ChainId.corn,
41
+ ChainId.etherlink,
42
+ ChainId.swell,
43
+ // Testnets:
44
+ ChainId.berachainBartioTestnet,
45
+ ChainId.sepolia,
46
+ ];
47
+
48
+ export const BRIDGE_CHAINS = unique([
49
+ ...CCIP_BRIDGE_CHAINS,
50
+ ...OFT_BRIDGE_CHAINS,
51
+ ]);
52
+ export type BridgeChain = CCIPBridgeChain | OFTBridgeChain;
53
+
54
+ export const OFT_GAS_LIMIT = 90_000;
55
+ export const OFT_HI_GAS_LIMIT = 200_000;
56
+ export const OFT_HI_GAS_LIMIT_CHAINS = [
57
+ // Mainnets:
58
+ ChainId.berachain,
59
+ // Testnets:
60
+ ChainId.berachainBartioTestnet,
61
+ ];
62
+
63
+ export type OFTBridgeChain = (typeof OFT_BRIDGE_CHAINS)[number];
64
+
65
+ type BridgeIdentifier<Ch extends CCIPBridgeChain | OFTBridgeChain> =
66
+ `[from:${Ch}, to: ${Ch}]`;
67
+
68
+ const bridgeIdentifier = <Ch extends CCIPBridgeChain | OFTBridgeChain>([
69
+ from,
70
+ to,
71
+ ]: [from: Ch, to: Ch]): BridgeIdentifier<Ch> => `[from:${from}, to: ${to}]`;
72
+
73
+ type BridgeInfo = { type: BridgeType; contract: ContractInfo };
74
+
75
+ type CCIPBridgesConfig = [
76
+ BridgeIdentifier<CCIPBridgeChain>,
77
+ { type: BridgeType.CCIP; contract: ContractInfo },
78
+ ];
79
+
80
+ const CCIP_BRIDGES: CCIPBridgesConfig[] = [
81
+ // Mainnets:
82
+
83
+ [
84
+ bridgeIdentifier([ChainId.ethereum, ChainId.base]),
85
+ {
86
+ type: BridgeType.CCIP,
87
+ contract: {
88
+ address: '0xa869817b48b25eee986bdf4be04062e6fd2c418b',
89
+ abi: CCIP_BRIDGE_ADAPTER_ABI as Abi,
90
+ chainId: ChainId.ethereum,
91
+ },
92
+ },
93
+ ],
94
+ [
95
+ bridgeIdentifier([ChainId.ethereum, ChainId.binanceSmartChain]),
96
+ {
97
+ type: BridgeType.CCIP,
98
+ contract: {
99
+ address: '0xa869817b48b25eee986bdf4be04062e6fd2c418b',
100
+ abi: CCIP_BRIDGE_ADAPTER_ABI as Abi,
101
+ chainId: ChainId.ethereum,
102
+ },
103
+ },
104
+ ],
105
+
106
+ [
107
+ bridgeIdentifier([ChainId.base, ChainId.ethereum]),
108
+ {
109
+ type: BridgeType.CCIP,
110
+ contract: {
111
+ address: '0xa869817b48b25eee986bdf4be04062e6fd2c418b',
112
+ abi: CCIP_BRIDGE_ADAPTER_ABI as Abi,
113
+ chainId: ChainId.base,
114
+ },
115
+ },
116
+ ],
117
+ [
118
+ bridgeIdentifier([ChainId.base, ChainId.binanceSmartChain]),
119
+ {
120
+ type: BridgeType.CCIP,
121
+ contract: {
122
+ address: '0xa869817b48b25eee986bdf4be04062e6fd2c418b',
123
+ abi: CCIP_BRIDGE_ADAPTER_ABI as Abi,
124
+ chainId: ChainId.base,
125
+ },
126
+ },
127
+ ],
128
+
129
+ [
130
+ bridgeIdentifier([ChainId.binanceSmartChain, ChainId.ethereum]),
131
+ {
132
+ type: BridgeType.CCIP,
133
+ contract: {
134
+ address: '0xa869817b48b25eee986bdf4be04062e6fd2c418b',
135
+ abi: CCIP_BRIDGE_ADAPTER_ABI as Abi,
136
+ chainId: ChainId.binanceSmartChain,
137
+ },
138
+ },
139
+ ],
140
+ [
141
+ bridgeIdentifier([ChainId.binanceSmartChain, ChainId.base]),
142
+ {
143
+ type: BridgeType.CCIP,
144
+ contract: {
145
+ address: '0xa869817b48b25eee986bdf4be04062e6fd2c418b',
146
+ abi: CCIP_BRIDGE_ADAPTER_ABI as Abi,
147
+ chainId: ChainId.binanceSmartChain,
148
+ },
149
+ },
150
+ ],
151
+
152
+ [
153
+ bridgeIdentifier([ChainId.ethereum, ChainId.sonic]),
154
+ {
155
+ type: BridgeType.CCIP,
156
+ contract: {
157
+ address: '0xa869817b48b25eee986bdf4be04062e6fd2c418b',
158
+ abi: CCIP_BRIDGE_ADAPTER_ABI as Abi,
159
+ chainId: ChainId.ethereum,
160
+ },
161
+ },
162
+ ],
163
+
164
+ [
165
+ bridgeIdentifier([ChainId.sonic, ChainId.ethereum]),
166
+ {
167
+ type: BridgeType.CCIP,
168
+ contract: {
169
+ address: '0xa869817b48b25eee986bdf4be04062e6fd2c418b',
170
+ abi: CCIP_BRIDGE_ADAPTER_ABI as Abi,
171
+ chainId: ChainId.sonic,
172
+ },
173
+ },
174
+ ],
175
+
176
+ // Testnets:
177
+
178
+ [
179
+ bridgeIdentifier([ChainId.baseSepoliaTestnet, ChainId.holesky]),
180
+ {
181
+ type: BridgeType.CCIP,
182
+ contract: {
183
+ address: '0x38247C4c846D549CAAd2C6c0b6fec0c402b77a0F',
184
+ abi: CCIP_BRIDGE_ADAPTER_ABI as Abi,
185
+ chainId: ChainId.baseSepoliaTestnet,
186
+ },
187
+ },
188
+ ],
189
+
190
+ [
191
+ bridgeIdentifier([ChainId.holesky, ChainId.baseSepoliaTestnet]),
192
+ {
193
+ type: BridgeType.CCIP,
194
+ contract: {
195
+ address: '0x38247C4c846D549CAAd2C6c0b6fec0c402b77a0F',
196
+ abi: CCIP_BRIDGE_ADAPTER_ABI as Abi,
197
+ chainId: ChainId.holesky,
198
+ },
199
+ },
200
+ ],
201
+ ];
202
+
203
+ type OFTBridgeConfig = [
204
+ BridgeIdentifier<OFTBridgeChain>,
205
+ { type: BridgeType.OFT; contract: ContractInfo },
206
+ ];
207
+ const OFT_BRIDGES: OFTBridgeConfig[] = [
208
+ // Mainnets:
209
+
210
+ [
211
+ bridgeIdentifier([ChainId.ethereum, ChainId.berachain]),
212
+ {
213
+ type: BridgeType.OFT,
214
+ contract: {
215
+ address: '0x1290A6b480f7eF14925229fdB66f5680aD8F44AD',
216
+ abi: OFT_BRIDGE_ADAPTER_ABI as Abi,
217
+ chainId: ChainId.ethereum,
218
+ },
219
+ },
220
+ ],
221
+ [
222
+ bridgeIdentifier([ChainId.ethereum, ChainId.corn]),
223
+ {
224
+ type: BridgeType.OFT,
225
+ contract: {
226
+ address: '0x6bc15d7930839ec18a57f6f7df72ae1b439d077f',
227
+ abi: OFT_BRIDGE_ADAPTER_ABI as Abi,
228
+ chainId: ChainId.ethereum,
229
+ },
230
+ },
231
+ ],
232
+ [
233
+ bridgeIdentifier([ChainId.ethereum, ChainId.etherlink]),
234
+ {
235
+ type: BridgeType.OFT,
236
+ contract: {
237
+ address: '0x3a7647c1323144a16e7D0D71A581E3FE5BD95299',
238
+ abi: OFT_BRIDGE_ADAPTER_ABI as Abi,
239
+ chainId: ChainId.ethereum,
240
+ },
241
+ },
242
+ ],
243
+ [
244
+ bridgeIdentifier([ChainId.ethereum, ChainId.swell]),
245
+ {
246
+ type: BridgeType.OFT,
247
+ contract: {
248
+ address: '0x37E92d760a15231e652a2C502182a6b44c7510c0',
249
+ abi: OFT_BRIDGE_ADAPTER_ABI as Abi,
250
+ chainId: ChainId.ethereum,
251
+ },
252
+ },
253
+ ],
254
+
255
+ [
256
+ bridgeIdentifier([ChainId.berachain, ChainId.ethereum]),
257
+ {
258
+ type: BridgeType.OFT,
259
+ contract: {
260
+ address: '0x630e12D53D4E041b8C5451aD035Ea841E08391d7',
261
+ abi: OFT_BRIDGE_ADAPTER_ABI as Abi,
262
+ chainId: ChainId.berachain,
263
+ },
264
+ },
265
+ ],
266
+
267
+ [
268
+ bridgeIdentifier([ChainId.corn, ChainId.ethereum]),
269
+ {
270
+ type: BridgeType.OFT,
271
+ contract: {
272
+ address: '0xfc7B20D9B59A8A466f4fC3d34aA69a7D98e71d7A',
273
+ abi: OFT_BRIDGE_ADAPTER_ABI as Abi,
274
+ chainId: ChainId.corn,
275
+ },
276
+ },
277
+ ],
278
+
279
+ [
280
+ bridgeIdentifier([ChainId.etherlink, ChainId.ethereum]),
281
+ {
282
+ type: BridgeType.OFT,
283
+ contract: {
284
+ address: '0xC832183d4d5fc5831daaC892a93dBBfd798034E3',
285
+ abi: OFT_BRIDGE_ADAPTER_ABI as Abi,
286
+ chainId: ChainId.etherlink,
287
+ },
288
+ },
289
+ ],
290
+
291
+ [
292
+ bridgeIdentifier([ChainId.swell, ChainId.ethereum]),
293
+ {
294
+ type: BridgeType.OFT,
295
+ contract: {
296
+ address: '0x7B3784AD646C10A8Ddf42b47a4f4bd9aFD351E54',
297
+ abi: OFT_BRIDGE_ADAPTER_ABI as Abi,
298
+ chainId: ChainId.swell,
299
+ },
300
+ },
301
+ ],
302
+
303
+ // Testnets:
304
+
305
+ [
306
+ bridgeIdentifier([ChainId.berachainBartioTestnet, ChainId.sepolia]),
307
+ {
308
+ type: BridgeType.OFT,
309
+ contract: {
310
+ address: '0x1977013acaf27856ac8048C42EE2ed0134d53895',
311
+ abi: OFT_BRIDGE_ADAPTER_ABI as Abi,
312
+ chainId: ChainId.berachainBartioTestnet,
313
+ },
314
+ },
315
+ ],
316
+
317
+ [
318
+ bridgeIdentifier([ChainId.sepolia, ChainId.berachainBartioTestnet]),
319
+ {
320
+ type: BridgeType.OFT,
321
+ contract: {
322
+ address: '0xe3748bF0Ec0A76767539eE28610B3367e35fe2C2',
323
+ abi: OFT_BRIDGE_ADAPTER_ABI as Abi,
324
+ chainId: ChainId.sepolia,
325
+ },
326
+ },
327
+ ],
328
+ ];
329
+
330
+ export const BRIDGES = new Map<BridgeIdentifier<BridgeChain>, BridgeInfo>([
331
+ ...CCIP_BRIDGES,
332
+ ...OFT_BRIDGES,
333
+ ]);
334
+
335
+ /** Gets the bridge information */
336
+ export const getBridgeInfo = (from: BridgeChain, to: BridgeChain) => {
337
+ return BRIDGES.get(bridgeIdentifier([from, to]));
338
+ };
@@ -0,0 +1,89 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { ChainId } from '../../common/chains';
3
+ import { Button } from '../../stories/components/Button';
4
+ import { CodeBlock } from '../../stories/components/CodeBlock';
5
+ import { ConnectButton } from '../../stories/components/ConnectButton';
6
+ import {
7
+ functionType,
8
+ wagmiDecorator,
9
+ } from '../../stories/components/decorators';
10
+ import { ErrorBlock } from '../../stories/components/error-block';
11
+ import {
12
+ canPerformAction,
13
+ useConnection,
14
+ } from '../../stories/hooks/useConnection';
15
+ import useQuery from '../../stories/hooks/useQuery';
16
+ import { OFT_BRIDGE_CHAINS } from './config';
17
+ import { BridgeOFTParameters, bridgeOFT } from './oft-bridge';
18
+
19
+ const meta = {
20
+ title: 'bridge/bridgeOFT',
21
+ component: StoryView,
22
+ tags: ['autodocs'],
23
+ decorators: [wagmiDecorator, functionType('write')],
24
+ } satisfies Meta<typeof StoryView>;
25
+
26
+ export default meta;
27
+
28
+ type Story = StoryObj<typeof meta>;
29
+
30
+ export const WithParams: Story = {
31
+ args: {
32
+ to: ChainId.corn,
33
+ amount: '0.0001',
34
+ approve: true,
35
+ env: 'prod',
36
+ },
37
+ argTypes: {
38
+ to: {
39
+ mapping: ChainId,
40
+ options: OFT_BRIDGE_CHAINS.map(
41
+ ch => Object.entries(ChainId).find(([, v]) => v === ch)?.[0],
42
+ ),
43
+ control: { type: 'select' },
44
+ },
45
+ },
46
+ };
47
+
48
+ type Props = Omit<BridgeOFTParameters, 'account' | 'chainId' | 'provider'>;
49
+
50
+ export function StoryView(props: Props) {
51
+ const connection = useConnection();
52
+
53
+ const request = async () => {
54
+ if (!canPerformAction(connection)) {
55
+ return;
56
+ }
57
+
58
+ return bridgeOFT({
59
+ ...props,
60
+
61
+ account: connection.account.address,
62
+ chainId: connection.account.chainId,
63
+ provider: connection.provider,
64
+ });
65
+ };
66
+
67
+ const { data, error, isLoading, refetch } = useQuery(request, [], false);
68
+
69
+ return (
70
+ <>
71
+ <p>This method bridges funds between chains.</p>
72
+
73
+ <div className="mb-4">
74
+ <ConnectButton />
75
+ </div>
76
+
77
+ <Button
78
+ onClick={refetch}
79
+ disabled={isLoading || !canPerformAction(connection)}
80
+ isLoading={isLoading}
81
+ actionName={bridgeOFT.name}
82
+ />
83
+
84
+ <ErrorBlock>{error}</ErrorBlock>
85
+
86
+ <CodeBlock text={data} />
87
+ </>
88
+ );
89
+ }
@@ -0,0 +1,211 @@
1
+ import { Options } from '@layerzerolabs/lz-v2-utilities';
2
+ import BigNumber from 'bignumber.js';
3
+ import { Address, pad } from 'viem';
4
+ import { makePublicClient } from '../../clients/public-client';
5
+ import { makeWalletClient } from '../../clients/wallet-client';
6
+ import { ChainId } from '../../common/chains';
7
+ import { CommonWriteParameters } from '../../common/parameters';
8
+ import { approveLBTC } from '../../contract-functions';
9
+ import { Token } from '../../tokens/token-addresses';
10
+ import {
11
+ fromBaseDenomination,
12
+ getTokenInfo,
13
+ toBaseDenomination,
14
+ } from '../../tokens/tokens';
15
+ import { getErrorMessage } from '../../utils/err';
16
+ import toBigInt from '../../utils/numbers';
17
+ import {
18
+ BridgeType,
19
+ MIN_BRIDGE_AMOUNT,
20
+ OFTBridgeChain,
21
+ OFT_BRIDGE_CHAINS,
22
+ OFT_GAS_LIMIT,
23
+ OFT_HI_GAS_LIMIT,
24
+ OFT_HI_GAS_LIMIT_CHAINS,
25
+ getBridgeInfo,
26
+ } from './config';
27
+
28
+ const DESTINATION_ENDPOINT_ID_MAP: Record<OFTBridgeChain, number> = {
29
+ // Mainnets:
30
+ [ChainId.ethereum]: 30101,
31
+ [ChainId.berachain]: 30362,
32
+ [ChainId.corn]: 30331,
33
+ [ChainId.etherlink]: 30292,
34
+ [ChainId.swell]: 30335,
35
+ // Testnets:
36
+ [ChainId.sepolia]: 40161,
37
+ [ChainId.berachainBartioTestnet]: 40291,
38
+ };
39
+
40
+ export type BridgeOFTParameters = {
41
+ /** The destination chain id. */
42
+ to: OFTBridgeChain;
43
+ /** The LBTC amount. */
44
+ amount: BigNumber.Value;
45
+ /**
46
+ * A flag determining whether the amount should be approved within
47
+ * the execution of this function. If set to `false` it will
48
+ * throw an error when the deposit amount exceeds allowance.
49
+ */
50
+ approve?: boolean;
51
+ /** The destination address. If omitted the same as the account address. */
52
+ recipient?: Address;
53
+ } & CommonWriteParameters;
54
+ export async function bridgeOFT({
55
+ to,
56
+ amount: amountRaw,
57
+ approve,
58
+ recipient: optionalRecipient,
59
+ account,
60
+ chainId: from,
61
+ provider,
62
+ env,
63
+ rpcUrl,
64
+ }: BridgeOFTParameters) {
65
+ const amount = BigNumber(amountRaw);
66
+ const recipient = optionalRecipient || account;
67
+
68
+ const bridgeInfo = getBridgeInfo(from as OFTBridgeChain, to);
69
+ if (!bridgeInfo || bridgeInfo.type !== BridgeType.OFT) {
70
+ throw new Error(
71
+ `Unsupported bridge from ${from} to ${to}. Please switch to the supported chains: ${OFT_BRIDGE_CHAINS.join(', ')}`,
72
+ );
73
+ }
74
+
75
+ const bridgeContract = bridgeInfo.contract;
76
+
77
+ const lbtcContract = await getTokenInfo(Token.LBTC, from, env, rpcUrl);
78
+ if (!lbtcContract) {
79
+ throw new Error('Could not retrieve LBTC contract info.');
80
+ }
81
+
82
+ const publicClient = makePublicClient({ chainId: from, rpcUrl });
83
+ const walletClient = makeWalletClient({ provider, chainId: from });
84
+
85
+ const amountBase = toBigInt(
86
+ toBaseDenomination(amount, lbtcContract.decimals),
87
+ );
88
+
89
+ if (amount.isLessThan(MIN_BRIDGE_AMOUNT)) {
90
+ throw new Error(
91
+ `The amount is smaller than the minimum amount allowed: ${MIN_BRIDGE_AMOUNT.toFixed()}`,
92
+ );
93
+ }
94
+
95
+ const balanceRaw = await publicClient.readContract({
96
+ address: lbtcContract.address,
97
+ abi: lbtcContract.abi,
98
+ functionName: 'balanceOf',
99
+ args: [account],
100
+ });
101
+ const balance = fromBaseDenomination(
102
+ String(balanceRaw),
103
+ lbtcContract.decimals,
104
+ );
105
+
106
+ // check if amount exceeds balance
107
+ if (amount.isGreaterThan(balance)) {
108
+ throw new Error(
109
+ `The amount exceeds the account's balance. \nAmount: ${amount.toFixed()} \nBalance: ${balance.toFixed()}`,
110
+ );
111
+ }
112
+
113
+ const allowanceRaw = await publicClient.readContract({
114
+ address: lbtcContract.address,
115
+ abi: lbtcContract.abi,
116
+ functionName: 'allowance',
117
+ args: [account, bridgeContract.address],
118
+ });
119
+ const allowance = fromBaseDenomination(
120
+ String(allowanceRaw),
121
+ lbtcContract.decimals,
122
+ );
123
+
124
+ // check if amount exceeds allowance
125
+ if (amount.isGreaterThan(allowance)) {
126
+ const exceededMessage = `The amount exceeds allowance. \nAmount: ${amount.toFixed()} \nAllowance: ${allowance.toFixed()}`;
127
+ if (!approve) {
128
+ throw new Error(exceededMessage);
129
+ }
130
+
131
+ // try to approve new amount
132
+ console.info(exceededMessage);
133
+ try {
134
+ const txHash = await approveLBTC({
135
+ account,
136
+ spender: bridgeContract.address,
137
+ amount,
138
+ chainId: from,
139
+ provider,
140
+ rpcUrl,
141
+ env,
142
+ });
143
+ console.info(`Approve tx hash: ${txHash}`);
144
+ console.info(`Approved ${amountBase} for ${bridgeContract.address}`);
145
+ } catch (err) {
146
+ const msg = getErrorMessage(err);
147
+ throw new Error(
148
+ `Could not approve ${amountBase} for ${bridgeContract.address}. \nReason: ${msg}`,
149
+ );
150
+ }
151
+ }
152
+
153
+ const extraOptions = Options.newOptions().addExecutorLzReceiveOption(
154
+ (OFT_HI_GAS_LIMIT_CHAINS as number[]).includes(to)
155
+ ? OFT_HI_GAS_LIMIT
156
+ : OFT_GAS_LIMIT,
157
+ 0,
158
+ );
159
+
160
+ /** _sendParam */
161
+ const sendParam = [
162
+ /** dstEid - uint32 */
163
+ DESTINATION_ENDPOINT_ID_MAP[to],
164
+ /** to - bytes32 */
165
+ pad(recipient),
166
+ /** amountLD - uint256 */
167
+ amountBase,
168
+ /** minAmountLD - uint256 */
169
+ amountBase,
170
+ /** extraOptions - bytes */
171
+ extraOptions.toHex(),
172
+ /** composeMsg - bytes */
173
+ '0x',
174
+ /** oftCmd - bytes */
175
+ '0x',
176
+ ];
177
+
178
+ const { nativeFee, lzTokenFee } = (await publicClient.readContract({
179
+ abi: bridgeContract.abi,
180
+ address: bridgeContract.address,
181
+ account,
182
+ functionName: 'quoteSend',
183
+ args: [sendParam, false],
184
+ })) as { nativeFee: bigint; lzTokenFee: bigint };
185
+
186
+ const bridgeArgs = [
187
+ /** _sendParam */
188
+ sendParam,
189
+ /** _fee */
190
+ [
191
+ /** nativeFee - uint256 */
192
+ nativeFee,
193
+ /** lzTokenFee - uint256 */
194
+ lzTokenFee,
195
+ ],
196
+ /** address - address */
197
+ account,
198
+ ];
199
+
200
+ const { request } = await publicClient.simulateContract({
201
+ abi: bridgeContract.abi,
202
+ address: bridgeContract.address,
203
+ account,
204
+ functionName: 'send',
205
+ args: bridgeArgs,
206
+ value: nativeFee,
207
+ });
208
+
209
+ const txHash = await walletClient.writeContract(request);
210
+ return txHash;
211
+ }
@@ -1,5 +1,4 @@
1
- import { DEFAULT_ENV } from '@lombard.finance/sdk-common';
2
- import { Env } from '@lombard.finance/sdk-common';
1
+ import { DEFAULT_ENV, Env } from '@lombard.finance/sdk-common';
3
2
 
4
3
  interface IApiConfig {
5
4
  baseApiUrl: string;
@@ -21,8 +20,15 @@ const prodConfig: IApiConfig = {
21
20
  bffApiUrl: 'https://bff.prod.lombard.finance',
22
21
  };
23
22
 
23
+ const devConfig: IApiConfig = {
24
+ baseApiUrl: 'https://staging.prod.lombard.finance',
25
+ bffApiUrl: 'http://localhost:8001',
26
+ };
27
+
24
28
  export const getApiConfig = (env: Env = DEFAULT_ENV): IApiConfig => {
25
29
  switch (env) {
30
+ case Env.dev:
31
+ return devConfig;
26
32
  case Env.prod:
27
33
  return prodConfig;
28
34
  case Env.testnet: