@lombard.finance/sdk 4.3.2 → 4.4.1
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/CHANGELOG.md +24 -0
- package/LICENSE +21 -0
- package/README.md +6 -6
- package/dist/api-functions/generateDepositBtcAddress/generateDepositBtcAddress.d.ts.map +1 -1
- package/dist/api-functions/getDepositBtcAddress/getDepositBtcAddress.d.ts.map +1 -1
- package/dist/api-functions/getDepositsByAddress/getDepositsByAddress.d.ts +13 -1
- package/dist/api-functions/getDepositsByAddress/getDepositsByAddress.d.ts.map +1 -1
- package/dist/api.cjs +1 -1
- package/dist/api.js +29 -29
- package/dist/bridge.cjs +1 -1
- package/dist/bridge.js +7 -7
- package/dist/btc.cjs +1 -1
- package/dist/btc.js +10 -10
- package/dist/chains/btc/actions/deposit/BtcDeposit.d.ts +7 -4
- package/dist/chains/btc/actions/deposit/BtcDeposit.d.ts.map +1 -1
- package/dist/chains/btc/actions/deposit/config/index.d.ts +16 -8
- package/dist/chains/btc/actions/deposit/config/index.d.ts.map +1 -1
- package/dist/chains/btc/actions/deposit/config/solana.d.ts +20 -0
- package/dist/chains/btc/actions/deposit/config/solana.d.ts.map +1 -0
- package/dist/chains/btc/actions/deposit/config/types.d.ts +4 -3
- package/dist/chains/btc/actions/deposit/config/types.d.ts.map +1 -1
- package/dist/chains/evm/EvmActions.d.ts +4 -4
- package/dist/chains/evm/actions/deposit/config/evm.d.ts +3 -3
- package/dist/chains/evm/actions/deposit/config/evm.d.ts.map +1 -1
- package/dist/chains/evm/actions/deposit/config/types.d.ts +1 -1
- package/dist/chains/evm/actions/deposit/config/types.d.ts.map +1 -1
- package/dist/chains/evm/actions/deposit/factory.d.ts +1 -1
- package/dist/chains/evm/actions/deposit/types.d.ts +1 -1
- package/dist/chains/evm/actions/deposit/types.d.ts.map +1 -1
- package/dist/chains/evm/actions/redeem/EvmRedeem.d.ts.map +1 -1
- package/dist/chains/evm/actions/unstake/EvmUnstake.d.ts.map +1 -1
- package/dist/chains/solana/SolanaActions.d.ts +10 -0
- package/dist/chains/solana/SolanaActions.d.ts.map +1 -1
- package/dist/chains/solana/actions/index.d.ts +1 -0
- package/dist/chains/solana/actions/index.d.ts.map +1 -1
- package/dist/chains/solana/actions/redeem/SolanaRedeem.d.ts +37 -0
- package/dist/chains/solana/actions/redeem/SolanaRedeem.d.ts.map +1 -0
- package/dist/chains/solana/actions/redeem/config/index.d.ts +8 -0
- package/dist/chains/solana/actions/redeem/config/index.d.ts.map +1 -0
- package/dist/chains/solana/actions/redeem/config/solana.d.ts +22 -0
- package/dist/chains/solana/actions/redeem/config/solana.d.ts.map +1 -0
- package/dist/chains/solana/actions/redeem/config/types.d.ts +35 -0
- package/dist/chains/solana/actions/redeem/config/types.d.ts.map +1 -0
- package/dist/chains/solana/actions/redeem/factory.d.ts +12 -0
- package/dist/chains/solana/actions/redeem/factory.d.ts.map +1 -0
- package/dist/chains/solana/actions/redeem/index.d.ts +9 -0
- package/dist/chains/solana/actions/redeem/index.d.ts.map +1 -0
- package/dist/chains/solana/actions/redeem/types.d.ts +52 -0
- package/dist/chains/solana/actions/redeem/types.d.ts.map +1 -0
- package/dist/chains/solana/utils.d.ts +15 -0
- package/dist/chains/solana/utils.d.ts.map +1 -0
- package/dist/chunks/BtcActions-BIBsbYIt.cjs +2 -0
- package/dist/chunks/BtcActions-BIBsbYIt.cjs.map +1 -0
- package/dist/chunks/{BtcActions-k-qs1uO0.js → BtcActions-Df41lbsb.js} +457 -414
- package/dist/chunks/BtcActions-Df41lbsb.js.map +1 -0
- package/dist/chunks/{EvmActions-B_dF42So.js → EvmActions-5lPqhRaM.js} +163 -173
- package/dist/chunks/EvmActions-5lPqhRaM.js.map +1 -0
- package/dist/chunks/EvmActions-BY_18gTg.cjs +2 -0
- package/dist/chunks/EvmActions-BY_18gTg.cjs.map +1 -0
- package/dist/chunks/ReferralsClient-Cmrjo9bN.cjs +2 -0
- package/dist/chunks/ReferralsClient-Cmrjo9bN.cjs.map +1 -0
- package/dist/chunks/{ReferralsClient-DbFWWtVi.js → ReferralsClient-DvEsA3II.js} +160 -160
- package/dist/chunks/ReferralsClient-DvEsA3II.js.map +1 -0
- package/dist/chunks/{api-config-CtcP3TVl.js → api-config-Dm6dR85f.js} +6 -6
- package/dist/chunks/{api-config-CtcP3TVl.js.map → api-config-Dm6dR85f.js.map} +1 -1
- package/dist/chunks/{approveLBTC-CZiZmdcX.cjs → approveLBTC-CUXEC3kw.cjs} +2 -2
- package/dist/chunks/{approveLBTC-CZiZmdcX.cjs.map → approveLBTC-CUXEC3kw.cjs.map} +1 -1
- package/dist/chunks/approveLBTC-Du2El1tW.js +26 -0
- package/dist/chunks/{approveLBTC-B5-ZWqct.js.map → approveLBTC-Du2El1tW.js.map} +1 -1
- package/dist/chunks/{array-Cev6kyLJ.js → array-DYttUPf5.js} +7 -7
- package/dist/chunks/{array-Cev6kyLJ.js.map → array-DYttUPf5.js.map} +1 -1
- package/dist/chunks/{blockchain-identifier-BzMQWh-C.cjs → blockchain-identifier-BTPGxLio.cjs} +2 -2
- package/dist/chunks/{blockchain-identifier-BzMQWh-C.cjs.map → blockchain-identifier-BTPGxLio.cjs.map} +1 -1
- package/dist/chunks/{blockchain-identifier-BmadkNtK.js → blockchain-identifier-CTVaEPpY.js} +24 -24
- package/dist/chunks/{blockchain-identifier-BmadkNtK.js.map → blockchain-identifier-CTVaEPpY.js.map} +1 -1
- package/dist/chunks/{bridge-CTsiodO1.js → bridge-DqGabhIY.js} +13 -13
- package/dist/chunks/{bridge-CTsiodO1.js.map → bridge-DqGabhIY.js.map} +1 -1
- package/dist/chunks/{bridge-BzRlY9pP.cjs → bridge-dWaKrMKm.cjs} +2 -2
- package/dist/chunks/{bridge-BzRlY9pP.cjs.map → bridge-dWaKrMKm.cjs.map} +1 -1
- package/dist/chunks/{config-hFKqUyg3.js → config-DghboRx0.js} +10 -10
- package/dist/chunks/{config-hFKqUyg3.js.map → config-DghboRx0.js.map} +1 -1
- package/dist/chunks/{config-l4ZaZw_g.cjs → config-DmCmanM_.cjs} +2 -2
- package/dist/chunks/{config-l4ZaZw_g.cjs.map → config-DmCmanM_.cjs.map} +1 -1
- package/dist/chunks/constants-D1FnS2Z8.js +6 -0
- package/dist/chunks/constants-D1FnS2Z8.js.map +1 -0
- package/dist/chunks/constants-ueShGH9R.cjs +2 -0
- package/dist/chunks/constants-ueShGH9R.cjs.map +1 -0
- package/dist/chunks/{defi-registry-BIRv_zkp.cjs → defi-registry-DDNavtO1.cjs} +2 -2
- package/dist/chunks/{defi-registry-BIRv_zkp.cjs.map → defi-registry-DDNavtO1.cjs.map} +1 -1
- package/dist/chunks/{defi-registry-wNFN3qyB.js → defi-registry-DxjjBQTV.js} +13 -13
- package/dist/chunks/{defi-registry-wNFN3qyB.js.map → defi-registry-DxjjBQTV.js.map} +1 -1
- package/dist/chunks/depositStatus-CFo5jW89.cjs +2 -0
- package/dist/chunks/depositStatus-CFo5jW89.cjs.map +1 -0
- package/dist/chunks/{depositStatus-DM7fRmbN.js → depositStatus-DTc01ZoZ.js} +63 -61
- package/dist/chunks/depositStatus-DTc01ZoZ.js.map +1 -0
- package/dist/chunks/events-6PV6NP-o.cjs +2 -0
- package/dist/chunks/events-6PV6NP-o.cjs.map +1 -0
- package/dist/chunks/{events-DdV_xi-2.js → events-BvRwXePq.js} +414 -303
- package/dist/chunks/events-BvRwXePq.js.map +1 -0
- package/dist/chunks/evm-by-btc-address-CZvE15lx.js +39 -0
- package/dist/chunks/{evm-by-btc-address-CwLiENtM.js.map → evm-by-btc-address-CZvE15lx.js.map} +1 -1
- package/dist/chunks/fee-requirements-CCNsxAvJ.js +14 -0
- package/dist/chunks/{fee-requirements-x8-8mpJ7.js.map → fee-requirements-CCNsxAvJ.js.map} +1 -1
- package/dist/chunks/get-exchange-ratio-B-xzYND1.js +20 -0
- package/dist/chunks/{get-exchange-ratio-NtnkG1kZ.js.map → get-exchange-ratio-B-xzYND1.js.map} +1 -1
- package/dist/chunks/{get-exchange-ratio-C-7DadfD.cjs → get-exchange-ratio-BEhD4gLB.cjs} +2 -2
- package/dist/chunks/{get-exchange-ratio-C-7DadfD.cjs.map → get-exchange-ratio-BEhD4gLB.cjs.map} +1 -1
- package/dist/chunks/{get-positions-summary-DkZZYbGP.cjs → get-positions-summary-Dh1QPLYO.cjs} +2 -2
- package/dist/chunks/{get-positions-summary-DkZZYbGP.cjs.map → get-positions-summary-Dh1QPLYO.cjs.map} +1 -1
- package/dist/chunks/{get-positions-summary-B_MmGHLv.js → get-positions-summary-iYshN1RQ.js} +28 -28
- package/dist/chunks/{get-positions-summary-B_MmGHLv.js.map → get-positions-summary-iYshN1RQ.js.map} +1 -1
- package/dist/chunks/{get-vault-tvl-YAXePAW3.js → get-vault-tvl-Ct_Zkg7C.js} +41 -41
- package/dist/chunks/{get-vault-tvl-YAXePAW3.js.map → get-vault-tvl-Ct_Zkg7C.js.map} +1 -1
- package/dist/chunks/{get-vault-tvl-DmTUbOY7.cjs → get-vault-tvl-D_tQIDAs.cjs} +2 -2
- package/dist/chunks/{get-vault-tvl-DmTUbOY7.cjs.map → get-vault-tvl-D_tQIDAs.cjs.map} +1 -1
- package/dist/chunks/{get-vault-withdrawals-CWcYy_sH.cjs → get-vault-withdrawals-8ALlEiAC.cjs} +2 -2
- package/dist/chunks/{get-vault-withdrawals-CWcYy_sH.cjs.map → get-vault-withdrawals-8ALlEiAC.cjs.map} +1 -1
- package/dist/chunks/get-vault-withdrawals-jk7Sv4S4.js +161 -0
- package/dist/chunks/{get-vault-withdrawals-BrpZlt6s.js.map → get-vault-withdrawals-jk7Sv4S4.js.map} +1 -1
- package/dist/chunks/{getSharesByAddress-BEgOf1C0.cjs → getSharesByAddress-D8hehnP1.cjs} +2 -2
- package/dist/chunks/{getSharesByAddress-BEgOf1C0.cjs.map → getSharesByAddress-D8hehnP1.cjs.map} +1 -1
- package/dist/chunks/{getSharesByAddress-BiruCDp6.js → getSharesByAddress-_tBaIBsw.js} +38 -38
- package/dist/chunks/{getSharesByAddress-BiruCDp6.js.map → getSharesByAddress-_tBaIBsw.js.map} +1 -1
- package/dist/chunks/getUserStakeAndBakeSignature-CSEyzgMc.cjs +2 -0
- package/dist/chunks/getUserStakeAndBakeSignature-CSEyzgMc.cjs.map +1 -0
- package/dist/chunks/getUserStakeAndBakeSignature-Su-k10ap.js +125 -0
- package/dist/chunks/getUserStakeAndBakeSignature-Su-k10ap.js.map +1 -0
- package/dist/chunks/lbtc-addresses-D8MYCdsx.js +10 -0
- package/dist/chunks/{lbtc-addresses-BLRmtR3c.js.map → lbtc-addresses-D8MYCdsx.js.map} +1 -1
- package/dist/chunks/{lbtc-addresses-xyTYV7hx.cjs → lbtc-addresses-Kil252DX.cjs} +2 -2
- package/dist/chunks/{lbtc-addresses-xyTYV7hx.cjs.map → lbtc-addresses-Kil252DX.cjs.map} +1 -1
- package/dist/chunks/numbers-CclN2Ohk.js +15 -0
- package/dist/chunks/{numbers-CM-lcmt4.js.map → numbers-CclN2Ohk.js.map} +1 -1
- package/dist/chunks/parameters-C_16L5ft.js +11 -0
- package/dist/chunks/{parameters-CDV-6Hk5.js.map → parameters-C_16L5ft.js.map} +1 -1
- package/dist/chunks/satoshi-CSoJBXc6.js +19 -0
- package/dist/chunks/{satoshi-Ch6y8aYG.js.map → satoshi-CSoJBXc6.js.map} +1 -1
- package/dist/chunks/{statusConstants-DFxMrVob.js → statusConstants-C4YNx2q0.js} +1134 -1113
- package/dist/chunks/statusConstants-C4YNx2q0.js.map +1 -0
- package/dist/chunks/statusConstants-DlM2oPfW.cjs +2 -0
- package/dist/chunks/statusConstants-DlM2oPfW.cjs.map +1 -0
- package/dist/chunks/{storeNetworkFeeSignature-BZGL2Zn_.js → storeNetworkFeeSignature-BODIpq3Y.js} +26 -26
- package/dist/chunks/{storeNetworkFeeSignature-BZGL2Zn_.js.map → storeNetworkFeeSignature-BODIpq3Y.js.map} +1 -1
- package/dist/chunks/{storeNetworkFeeSignature-D7yo6lDV.cjs → storeNetworkFeeSignature-Buk4091C.cjs} +2 -2
- package/dist/chunks/{storeNetworkFeeSignature-D7yo6lDV.cjs.map → storeNetworkFeeSignature-Buk4091C.cjs.map} +1 -1
- package/dist/chunks/time-Sa5gggPG.js +24 -0
- package/dist/chunks/{time-QPeEEEnQ.js.map → time-Sa5gggPG.js.map} +1 -1
- package/dist/chunks/{token-addresses-FKpA3uc4.js → token-addresses-D0v5cR1j.js} +174 -163
- package/dist/chunks/{token-addresses-FKpA3uc4.js.map → token-addresses-D0v5cR1j.js.map} +1 -1
- package/dist/chunks/{token-addresses-DRBecUa7.cjs → token-addresses-nzvTOi24.cjs} +2 -2
- package/dist/chunks/{token-addresses-DRBecUa7.cjs.map → token-addresses-nzvTOi24.cjs.map} +1 -1
- package/dist/chunks/{tokens-D_HeVB5p.cjs → tokens-BkvA0Gp1.cjs} +2 -2
- package/dist/chunks/{tokens-D_HeVB5p.cjs.map → tokens-BkvA0Gp1.cjs.map} +1 -1
- package/dist/chunks/{tokens-C6qZHzph.js → tokens-DgC1hfkm.js} +18 -18
- package/dist/chunks/{tokens-C6qZHzph.js.map → tokens-DgC1hfkm.js.map} +1 -1
- package/dist/chunks/{unstakeLBTC-H0zdYQa6.cjs → unstakeLBTC-CmoCaGX9.cjs} +2 -2
- package/dist/chunks/{unstakeLBTC-H0zdYQa6.cjs.map → unstakeLBTC-CmoCaGX9.cjs.map} +1 -1
- package/dist/chunks/{unstakeLBTC-DAIR9NO_.js → unstakeLBTC-DtvVbpbU.js} +50 -50
- package/dist/chunks/{unstakeLBTC-DAIR9NO_.js.map → unstakeLBTC-DtvVbpbU.js.map} +1 -1
- package/dist/chunks/{withdraw-hHueI2p7.js → withdraw-DgjuaUN3.js} +45 -45
- package/dist/chunks/{withdraw-hHueI2p7.js.map → withdraw-DgjuaUN3.js.map} +1 -1
- package/dist/chunks/{withdraw-C1fMFSwy.cjs → withdraw-i0AueZ_C.cjs} +2 -2
- package/dist/chunks/{withdraw-C1fMFSwy.cjs.map → withdraw-i0AueZ_C.cjs.map} +1 -1
- package/dist/common/constants.d.ts +1 -0
- package/dist/common/constants.d.ts.map +1 -1
- package/dist/contracts.cjs +1 -1
- package/dist/contracts.js +16 -16
- package/dist/core/assets/catalog.d.ts.map +1 -1
- package/dist/core.cjs +1 -1
- package/dist/core.js +85 -85
- package/dist/debug.js +4 -4
- package/dist/defi.cjs +1 -1
- package/dist/defi.js +10 -10
- package/dist/evm.cjs +1 -1
- package/dist/evm.js +34 -34
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +287 -283
- package/dist/index.js.map +1 -1
- package/dist/metrics.cjs +1 -1
- package/dist/metrics.js +6 -6
- package/dist/shared/deposits/depositStatus.d.ts +9 -5
- package/dist/shared/deposits/depositStatus.d.ts.map +1 -1
- package/dist/stories/arg-types.d.ts +1 -0
- package/dist/stories/arg-types.d.ts.map +1 -1
- package/dist/tokens/token-addresses.d.ts +2 -2
- package/dist/tokens/token-addresses.d.ts.map +1 -1
- package/dist/utils/chain.d.ts +7 -0
- package/dist/utils/chain.d.ts.map +1 -1
- package/dist/utils.cjs +1 -1
- package/dist/utils.js +76 -76
- package/dist/vaults.cjs +1 -1
- package/dist/vaults.js +14 -14
- package/package.json +19 -6
- package/dist/chunks/BtcActions-XbVRQEcM.cjs +0 -2
- package/dist/chunks/BtcActions-XbVRQEcM.cjs.map +0 -1
- package/dist/chunks/BtcActions-k-qs1uO0.js.map +0 -1
- package/dist/chunks/EvmActions-BVzQ3fLK.cjs +0 -2
- package/dist/chunks/EvmActions-BVzQ3fLK.cjs.map +0 -1
- package/dist/chunks/EvmActions-B_dF42So.js.map +0 -1
- package/dist/chunks/ReferralsClient-BC-1wT1q.cjs +0 -2
- package/dist/chunks/ReferralsClient-BC-1wT1q.cjs.map +0 -1
- package/dist/chunks/ReferralsClient-DbFWWtVi.js.map +0 -1
- package/dist/chunks/approveLBTC-B5-ZWqct.js +0 -26
- package/dist/chunks/constants-BBK-JNcY.cjs +0 -2
- package/dist/chunks/constants-BBK-JNcY.cjs.map +0 -1
- package/dist/chunks/constants-CuT4axsy.js +0 -5
- package/dist/chunks/constants-CuT4axsy.js.map +0 -1
- package/dist/chunks/depositStatus-C3-EgT2a.cjs +0 -2
- package/dist/chunks/depositStatus-C3-EgT2a.cjs.map +0 -1
- package/dist/chunks/depositStatus-DM7fRmbN.js.map +0 -1
- package/dist/chunks/events-DdV_xi-2.js.map +0 -1
- package/dist/chunks/events-DqIJRzJo.cjs +0 -2
- package/dist/chunks/events-DqIJRzJo.cjs.map +0 -1
- package/dist/chunks/evm-by-btc-address-CwLiENtM.js +0 -39
- package/dist/chunks/fee-requirements-x8-8mpJ7.js +0 -14
- package/dist/chunks/get-exchange-ratio-NtnkG1kZ.js +0 -20
- package/dist/chunks/get-vault-withdrawals-BrpZlt6s.js +0 -161
- package/dist/chunks/getUserStakeAndBakeSignature-BxRq2cI1.cjs +0 -2
- package/dist/chunks/getUserStakeAndBakeSignature-BxRq2cI1.cjs.map +0 -1
- package/dist/chunks/getUserStakeAndBakeSignature-NGGblnJl.js +0 -120
- package/dist/chunks/getUserStakeAndBakeSignature-NGGblnJl.js.map +0 -1
- package/dist/chunks/lbtc-addresses-BLRmtR3c.js +0 -10
- package/dist/chunks/numbers-CM-lcmt4.js +0 -15
- package/dist/chunks/parameters-CDV-6Hk5.js +0 -11
- package/dist/chunks/satoshi-Ch6y8aYG.js +0 -19
- package/dist/chunks/statusConstants-BLiNBT6s.cjs +0 -2
- package/dist/chunks/statusConstants-BLiNBT6s.cjs.map +0 -1
- package/dist/chunks/statusConstants-DFxMrVob.js.map +0 -1
- package/dist/chunks/time-QPeEEEnQ.js +0 -24
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BtcActions-XbVRQEcM.cjs","sources":["../../src/chains/btc/client/mempool/error.ts","../../src/chains/btc/client/mempool/mempool.ts","../../src/chains/btc/client/getCurrentBlockHeight.ts","../../src/services/BtcService.ts","../../src/modules/btcModule.ts","../../src/shared/monitoring/depositMonitor.ts","../../src/utils/ensureNotSanctionedAddress.ts","../../src/chains/btc/actions/shared/BaseBtcAction.ts","../../src/chains/btc/actions/shared/tokenUtils.ts","../../src/shared/evm/switchChain.ts","../../src/chains/btc/actions/deposit/config/evm.ts","../../src/chains/btc/actions/deposit/config/index.ts","../../src/chains/btc/actions/deposit/BtcDeposit.ts","../../src/chains/btc/actions/stakeAndDeploy/config/evm.ts","../../src/chains/btc/actions/stakeAndDeploy/config/index.ts","../../src/chains/btc/actions/depositAndDeploy/config/evm.ts","../../src/chains/btc/actions/depositAndDeploy/config/index.ts","../../src/chains/btc/actions/depositAndDeploy/BtcDepositAndDeploy.ts","../../src/utils/chain.ts","../../src/chains/btc/actions/stake/config/evm.ts","../../src/chains/btc/actions/stake/config/solana.ts","../../src/chains/btc/actions/stake/config/starknet.ts","../../src/chains/btc/actions/stake/config/sui.ts","../../src/chains/btc/actions/stake/config/index.ts","../../src/chains/btc/actions/stake/BtcStake.ts","../../src/chains/btc/actions/stakeAndDeploy/BtcStakeAndDeploy.ts","../../src/chains/btc/BtcActions.ts"],"sourcesContent":["import { AxiosError } from 'axios';\n\nconst ADBLOCKER_ERROR_CODE = 'ERR_NETWORK';\n\nconst ADBLOCK_ERROR_MSG =\n 'This may be due to your Adblocker. Please disable any Adblocker and refresh the page to restore full functionality.';\n\n/**\n * Handles the error from the mempool.space API.\n * If the error is due to an adblocker, it throws an error with a message to disable the adblocker.\n *\n * @param error Error object.\n *\n * @throws Error with the error message.\n */\nexport function handleMempoolApiError(error: unknown): never {\n const { code, message } = error as AxiosError;\n\n if (code === ADBLOCKER_ERROR_CODE) {\n throw new Error(ADBLOCK_ERROR_MSG);\n }\n\n throw new Error(message);\n}\n","export type TNetworkMode = 'mainnet' | 'testnet';\n\ninterface IApiConfig {\n mempoolApiUrl: string;\n}\n\nconst stageConfig: IApiConfig = {\n mempoolApiUrl: 'https://mempool.space/signet',\n};\n\nconst prodConfig: IApiConfig = {\n mempoolApiUrl: 'https://mempool.space',\n};\n\n/**\n * Returns the configuration for the Bitcoin related APIs.\n *\n * @param mode - The network mode.\n *\n * @returns The configuration.\n */\nexport const getBtcApiConfig = (mode: TNetworkMode): IApiConfig =>\n mode === 'mainnet' ? prodConfig : stageConfig;\n","import axios from 'axios';\n\nimport { handleMempoolApiError } from './mempool/error';\nimport { getBtcApiConfig,TNetworkMode } from './mempool/mempool';\n\ninterface Response {\n height: number;\n hash: string;\n timestamp: string;\n}\n\n/**\n * Returns the current block height from the mempool.space API\n */\nexport async function getCurrentBlockHeight(\n mode: TNetworkMode,\n): Promise<number> {\n const { mempoolApiUrl } = getBtcApiConfig(mode);\n const timestamp = Math.floor(Date.now() / 1000);\n const url = `${mempoolApiUrl}/api/v1/mining/blocks/timestamp/${timestamp}`;\n\n try {\n const { data } = await axios.get<Response>(url);\n return data.height;\n } catch (error) {\n handleMempoolApiError(error);\n }\n}\n","/**\n * BTC Service\n *\n * Provides Bitcoin-specific operations via mempool API.\n *\n * @module services/BtcService\n */\n\nimport type {\n BtcNetworkMode,\n BtcService as IBtcService,\n} from '@lombard.finance/sdk-common';\n\nimport { getCurrentBlockHeight } from '../chains/btc/client/getCurrentBlockHeight';\n\n/**\n * BTC Service\n *\n * Implementation of the BtcService interface from sdk-common.\n * Provides Bitcoin blockchain operations.\n */\nexport class BtcService implements IBtcService {\n /**\n * Get current block height from mempool\n */\n async getCurrentBlockHeight(network: BtcNetworkMode): Promise<number> {\n return getCurrentBlockHeight(network);\n }\n}\n","/**\n * BTC Module\n *\n * Provides Bitcoin chain service for deposit monitoring and address operations.\n * Uses Service-First pattern: module is a thin factory that instantiates the service.\n *\n * @module modules/btcModule\n */\n\nimport type {\n BtcService as IBtcService,\n ChainModule,\n} from '@lombard.finance/sdk-common';\n\nimport { BtcService } from '../services/BtcService';\n\n/**\n * Create BTC module\n *\n * Built-in module that provides BtcService. Automatically included by createLombardSDK().\n *\n * @example\n * ```ts\n * const sdk = await createLombardSDK({\n * env: Env.prod,\n * providers: { evm: () => window.ethereum },\n * });\n * const stake = sdk.chain.btc.stake({ ... });\n * ```\n */\nexport function btcModule(): ChainModule<'btc', IBtcService> {\n return {\n id: 'btc',\n chain: 'btc',\n register() {\n return new BtcService();\n },\n };\n}\n\n// Re-export service class and interface type\nexport { BtcService };\nexport type { IBtcService as BtcServiceInterface };\n","/**\n * Deposit Monitor Utility\n *\n * Shared monitoring logic for tracking Bitcoin deposit confirmations\n * and minting status. Used by BtcStake, BtcDeposit, and BtcStakeAndDeploy actions.\n *\n * @module shared/monitoring/depositMonitor\n */\n\nimport { StepStatus } from '../../core';\nimport type { BtcService } from '../../modules/btcModule';\n\n/** Bitcoin network mode */\nexport type NetworkMode = 'mainnet' | 'testnet';\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Types\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Deposit information returned by fetch function\n */\nexport interface DepositInfo {\n /** Block height where deposit was confirmed */\n blockHeight?: number;\n /** Whether LBTC has been minted/claimed */\n isClaimed?: boolean;\n}\n\n/**\n * Progress information emitted during monitoring\n */\nexport interface MonitorProgress {\n /** Current confirmations */\n confirmations: number;\n /** Required confirmations for finality */\n requiredConfirmations: number;\n /** Whether deposit has enough confirmations */\n hasEnoughConfirmations: boolean;\n /** Whether LBTC has been claimed */\n isClaimed: boolean;\n /** Step statuses for UI */\n steps: {\n created: StepStatus;\n verifying: StepStatus;\n issuing: StepStatus;\n };\n}\n\n/**\n * Options for deposit monitoring\n */\nexport interface MonitorOptions {\n /** Function to fetch deposit information */\n fetchDeposit: () => Promise<DepositInfo | undefined>;\n /** Bitcoin network mode */\n network: NetworkMode;\n /** BTC service for block height queries */\n btcService: BtcService;\n /** Number of confirmations required (default: 6) */\n requiredConfirmations?: number;\n /** Callback for progress updates */\n onProgress?: (progress: MonitorProgress) => void;\n /** Callback when deposit is fully claimed */\n onComplete?: () => void;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Monitor Function\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Monitor a Bitcoin deposit for confirmations and minting\n *\n * This is a single-shot check. For continuous monitoring, call this\n * function repeatedly with a timer/interval.\n *\n * @param options - Monitoring options\n * @returns Progress information or undefined if deposit not found\n *\n * @example\n * ```typescript\n * const progress = await monitorDeposit({\n * fetchDeposit: async () => {\n * const deposits = await getDepositsByAddress({ address, env });\n * return deposits.find(d => d.depositAddress === myAddress);\n * },\n * network: 'mainnet',\n * btcService: ctx.btc,\n * onProgress: (p) => console.log(`${p.confirmations}/${p.requiredConfirmations}`),\n * onComplete: () => console.log('Deposit complete!'),\n * });\n * ```\n */\nexport async function monitorDeposit(\n options: MonitorOptions,\n): Promise<MonitorProgress | undefined> {\n const {\n fetchDeposit,\n network,\n btcService,\n requiredConfirmations = 6,\n onProgress,\n onComplete,\n } = options;\n\n // Fetch current deposit status\n const deposit = await fetchDeposit();\n if (!deposit) {\n return undefined;\n }\n\n const blockHeight = deposit.blockHeight;\n if (typeof blockHeight !== 'number') {\n return undefined;\n }\n\n // Get current block height and calculate confirmations\n const currentBlockHeight = await btcService.getCurrentBlockHeight(network);\n const confirmations = Math.max(0, currentBlockHeight - blockHeight);\n const hasEnoughConfirmations = confirmations >= requiredConfirmations;\n const isClaimed = deposit.isClaimed ?? false;\n\n // Build progress object\n const progress: MonitorProgress = {\n confirmations,\n requiredConfirmations,\n hasEnoughConfirmations,\n isClaimed,\n steps: {\n created: StepStatus.COMPLETE,\n verifying: hasEnoughConfirmations\n ? StepStatus.COMPLETE\n : StepStatus.PENDING,\n issuing: isClaimed ? StepStatus.COMPLETE : StepStatus.PENDING,\n },\n };\n\n // Emit callbacks\n onProgress?.(progress);\n if (isClaimed) {\n onComplete?.();\n }\n\n return progress;\n}\n\n/**\n * Create a polling monitor that checks deposit status at intervals\n *\n * @param options - Monitoring options\n * @param intervalMs - Polling interval in milliseconds (default: 30000)\n * @returns Stop function to cancel monitoring\n *\n * @example\n * ```typescript\n * const stop = createPollingMonitor({\n * fetchDeposit,\n * network: 'mainnet',\n * btcService: ctx.btc,\n * onProgress: updateUI,\n * onComplete: () => {\n * stop(); // Stop polling when complete\n * showSuccess();\n * },\n * }, 30000);\n *\n * // Later: stop monitoring\n * stop();\n * ```\n */\nexport function createPollingMonitor(\n options: MonitorOptions,\n intervalMs = 30000,\n): () => void {\n let stopped = false;\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const poll = async () => {\n if (stopped) return;\n\n try {\n const progress = await monitorDeposit(options);\n\n // Stop polling if claimed\n if (progress?.isClaimed) {\n stopped = true;\n return;\n }\n } catch (error) {\n // Continue polling on error\n console.warn('Deposit monitor poll failed:', error);\n }\n\n // Schedule next poll\n if (!stopped) {\n timeoutId = setTimeout(poll, intervalMs);\n }\n };\n\n // Start polling\n poll();\n\n // Return stop function\n return () => {\n stopped = true;\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n };\n}\n","import { SANCTIONED_ADDRESS } from '../api-functions/generateDepositBtcAddress/generateDepositBtcAddress';\nimport { LombardError, ValidationErrorCode } from '../shared/errors';\n\nexport function ensureNotSanctionedAddress(address: string): void {\n if (address === SANCTIONED_ADDRESS) {\n throw new LombardError(\n ValidationErrorCode.INVALID_PARAMETER,\n 'Destination address is under sanctions',\n );\n }\n}\n","/**\n * Base BTC Action Class\n *\n * Provides common functionality for all BTC actions:\n * - State management (amount, recipient, depositAddress, referralCode)\n * - Ensure methods for validation\n * - Bitcoin network helpers\n * - Deposit monitoring\n * - Bitcoin send operations\n * - Common validation and prepare patterns\n *\n * @module chains/btc/actions/shared/BaseBtcAction\n */\n\nimport { z } from 'zod';\n\nimport {\n ChainId,\n SolanaChain,\n StarknetChainId,\n SuiChain,\n} from '../../../../common/chains';\nimport { Chain, StepStatus } from '../../../../core';\nimport { BaseAction } from '../../../../shared/actions';\nimport type { BtcCoreContext } from '../../../../shared/context';\nimport { LombardError, ValidationErrorCode } from '../../../../shared/errors';\nimport type {\n MonitorProgress,\n NetworkMode,\n} from '../../../../shared/monitoring';\nimport { monitorDeposit } from '../../../../shared/monitoring';\nimport type { EventHandler } from '../../../../shared/monitoring/createEventEmitter';\nimport {\n btcStakeAmountSchema,\n referralCodeSchema,\n validatePrepareParams as zodValidate,\n} from '../../../../shared/validation';\nimport { ensureNotSanctionedAddress } from '../../../../utils/ensureNotSanctionedAddress';\nimport { toSatoshi } from '../../../../utils/satoshi';\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Types\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Common authorization state for BTC actions\n */\nexport interface BtcAuthorizationState {\n authorized: boolean;\n signature?: string;\n typedData?: unknown;\n [key: string]: unknown;\n}\n\n/**\n * Common params that all BTC actions share\n */\nexport interface BaseBtcParams {\n sourceChain?: typeof Chain.BITCOIN_MAINNET | typeof Chain.BITCOIN_SIGNET;\n destChain: Chain;\n}\n\n/**\n * Common prepare params\n */\nexport interface BasePrepareParams {\n amount: string;\n recipient: string;\n referralCode?: string;\n}\n\n/**\n * Progress step definitions\n */\nexport type StepDefinition = Record<string, StepStatus>;\n\n/**\n * Status configuration for template methods\n */\nexport interface StatusConfig<TStatus extends string> {\n idle: TStatus;\n ready: TStatus;\n addressReady: TStatus;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Base Class\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Base class for BTC actions\n *\n * Provides template methods for common patterns:\n * - prepare() with validation and resume\n * - generateDepositAddress()\n * - execute()\n * - monitorDeposit()\n *\n * Subclasses implement abstract methods to customize behavior.\n *\n * @example\n * ```typescript\n * class BtcStake extends BaseBtcAction<StakeEventMap, BtcActionStatus, BtcStakeParams> {\n * protected getAddressSchema() { return evmAddressSchema; }\n * protected getStatusConfig() { return { idle: BtcActionStatus.IDLE, ... }; }\n * protected getInitialSteps() { return { created: StepStatus.IDLE, ... }; }\n * }\n * ```\n */\nexport abstract class BaseBtcAction<\n TEventMap extends Record<string, EventHandler<unknown[]>>,\n TStatus extends string,\n TParams extends BaseBtcParams,\n> extends BaseAction<TEventMap, TStatus> {\n // ─────────────────────────────────────────────────────────────────────────\n // Common State\n // ─────────────────────────────────────────────────────────────────────────\n\n protected _amount?: string;\n protected _recipient?: string;\n protected _depositAddress?: string;\n protected _referralCode?: string;\n protected _chainId?: unknown;\n\n constructor(\n protected readonly ctx: BtcCoreContext,\n protected readonly params: TParams,\n initialStatus: TStatus,\n ) {\n super(initialStatus);\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Abstract Methods - Subclasses Must Implement\n // ─────────────────────────────────────────────────────────────────────────\n\n /** Get the address validation schema for this action */\n protected abstract getAddressSchema(): z.ZodType<string>;\n\n /** Get the status configuration for template methods */\n protected abstract getStatusConfig(): StatusConfig<TStatus>;\n\n /** Get the initial progress steps for this action */\n protected abstract getInitialSteps(): StepDefinition;\n\n /** Check if the action has been authorized */\n protected abstract isAuthorized(): boolean;\n\n /** Get the chain ID (after parsing in constructor) */\n protected abstract getChainId():\n | ChainId\n | SuiChain\n | SolanaChain\n | StarknetChainId;\n\n /**\n * Get API params for generateDepositAddress\n * Subclasses provide action-specific parameters\n */\n protected abstract getDepositAddressParams(captchaToken?: string): {\n address: string;\n chainId: ChainId | SuiChain | SolanaChain | StarknetChainId;\n signature: string;\n token: string;\n eip712Data?: string;\n signatureData?: string;\n pubKey?: string;\n partnerId?: string;\n referrerCode?: string;\n captchaToken?: string;\n };\n\n /**\n * Get the expected destination token (LBTC, BTCb, etc.)\n * Used for resuming from existing deposits before authorization is complete\n */\n protected abstract getExpectedToken(): string;\n\n // ─────────────────────────────────────────────────────────────────────────\n // Common Getters\n // ─────────────────────────────────────────────────────────────────────────\n\n /** Amount of BTC to stake/deposit */\n get amount(): string | undefined {\n return this._amount;\n }\n\n /** Recipient address on destination chain */\n get recipient(): string | undefined {\n return this._recipient;\n }\n\n /** Generated Bitcoin deposit address */\n get depositAddress(): string | undefined {\n return this._depositAddress;\n }\n\n /** Referral code (optional) */\n get referralCode(): string | undefined {\n return this._referralCode;\n }\n\n /** Bitcoin network mode for monitoring */\n protected get bitcoinNetwork(): NetworkMode {\n const source = this.params.sourceChain;\n return source === Chain.BITCOIN_MAINNET ? 'mainnet' : 'testnet';\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Common Validation\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Get the prepare schema (amount + recipient + referralCode)\n * Uses abstract getAddressSchema() for chain-specific validation\n */\n protected get prepareSchema() {\n return z.object({\n amount: btcStakeAmountSchema,\n recipient: this.getAddressSchema(),\n referralCode: referralCodeSchema,\n });\n }\n\n /**\n * Validate prepare params using Zod\n * Subclasses can override if they need custom validation\n */\n protected validatePrepareParams(\n params: BasePrepareParams,\n ): BasePrepareParams {\n return zodValidate(this.prepareSchema, params, {\n destChain: this.params.destChain,\n });\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Ensure Methods (throw if missing)\n // ─────────────────────────────────────────────────────────────────────────\n\n protected ensureRecipient(): string {\n if (!this._recipient) {\n throw LombardError.missingParameter('recipient');\n }\n return this._recipient;\n }\n\n protected ensureAmount(): string {\n if (!this._amount) {\n throw LombardError.missingParameter('amount');\n }\n return this._amount;\n }\n\n protected ensureDepositAddress(): string {\n if (!this._depositAddress) {\n throw new LombardError(\n ValidationErrorCode.INVALID_PARAMETER,\n 'Deposit address not generated. Call generateDepositAddress() first.',\n );\n }\n return this._depositAddress;\n }\n\n /**\n * Get error message for missing authorization\n * Subclasses can override to provide specific messages\n */\n protected getAuthRequiredMessage(): string {\n return 'Authorization required. Complete the authorization step first.';\n }\n\n protected ensureAuthorized(): void {\n if (!this.isAuthorized()) {\n throw new LombardError(\n ValidationErrorCode.INVALID_PARAMETER,\n this.getAuthRequiredMessage(),\n );\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Common Resume Logic\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Try to resume from an existing deposit address\n *\n * This method only stores the deposit address if found.\n * It does NOT update the status - the caller must do that\n * after performing any additional validation (e.g., fee authorization).\n *\n * @param recipient - The recipient address to check\n * @returns true if a deposit address was found, false otherwise\n */\n protected async resumeFromExistingDeposit(\n recipient: string,\n ): Promise<boolean> {\n try {\n const depositAddress = await this.ctx.api.getDepositAddress({\n address: recipient,\n chainId: this.getChainId(),\n token: this.getExpectedToken(),\n partnerId: this.ctx.partner.getPartnerId(),\n });\n\n if (!depositAddress) {\n return false;\n }\n\n this._depositAddress = depositAddress;\n // NOTE: Status is NOT updated here - caller must set appropriate status\n // after validating fee authorization (which may have expired)\n return true;\n } catch {\n return false;\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Common Generate Deposit Address\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Generate a Bitcoin deposit address\n *\n * Template method that:\n * 1. Validates status and authorization\n * 2. Calls API to generate address\n * 3. Updates state and emits progress\n *\n * Subclasses must implement getDepositAddressParams() to provide API params.\n */\n protected async generateDepositAddressImpl(\n captchaToken?: string,\n ): Promise<string> {\n const statusConfig = this.getStatusConfig();\n\n this.assertStatus(statusConfig.ready, 'generateDepositAddress');\n this.ensureAuthorized();\n\n if (this._depositAddress) {\n return this._depositAddress;\n }\n\n return this.act(async () => {\n const apiParams = this.getDepositAddressParams(captchaToken);\n\n const depositAddress =\n await this.ctx.api.generateDepositAddress(apiParams);\n\n ensureNotSanctionedAddress(depositAddress);\n this._depositAddress = depositAddress;\n\n // Emit progress with address ready\n const steps = this.getInitialSteps();\n const addressReadySteps = Object.fromEntries(\n Object.entries(steps).map(([key], index) => [\n key,\n index === 0 ? StepStatus.COMPLETE : StepStatus.IDLE,\n ]),\n );\n\n this.emitProgress({\n status: statusConfig.addressReady,\n steps: addressReadySteps,\n metadata: { depositAddress },\n });\n\n return depositAddress;\n }, statusConfig.addressReady);\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Common Execute Pattern\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Execute the action - generate address and optionally send BTC\n *\n * Template method that:\n * 1. Ensures deposit address exists\n * 2. Tries to send BTC if provider available\n * 3. Returns result\n */\n protected async executeImpl(): Promise<{\n depositAddress: string;\n txHash?: string;\n }> {\n const statusConfig = this.getStatusConfig();\n\n return this.act(async () => {\n this.assertStatus(statusConfig.addressReady, 'execute');\n\n if (!this._depositAddress) {\n await this.generateDepositAddressImpl();\n }\n\n const depositAddress = this.ensureDepositAddress();\n const txHash = await this.trySendBitcoin(depositAddress);\n\n return txHash ? { depositAddress, txHash } : { depositAddress };\n });\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Common Progress Emission\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Emit initial progress with action-specific steps\n */\n protected emitInitialProgress(): void {\n this.emitProgress({\n status: this.status,\n steps: this.getInitialSteps(),\n });\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Deposit Monitoring\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Monitor Bitcoin deposit progress\n */\n async monitorDeposit(): Promise<MonitorProgress | undefined> {\n const depositAddress = this._depositAddress;\n const recipient = this._recipient;\n\n if (!depositAddress || !recipient) {\n throw LombardError.missingParameter('depositAddress or recipient');\n }\n\n const progress = await monitorDeposit({\n network: this.bitcoinNetwork,\n btcService: this.ctx.btc,\n fetchDeposit: async () => {\n const deposits = await this.ctx.api.getDeposits(recipient);\n const ourDeposit = deposits.find(\n deposit => deposit.depositAddress === depositAddress,\n );\n\n if (!ourDeposit) {\n return undefined;\n }\n\n return {\n blockHeight: ourDeposit.blockHeight,\n isClaimed: ourDeposit.isClaimed,\n };\n },\n onProgress: p => {\n this.emitProgress({\n status: this.status,\n steps: p.steps,\n confirmations: p.confirmations,\n requiredConfirmations: p.requiredConfirmations,\n metadata: { isClaimed: p.isClaimed },\n });\n },\n onComplete: () => {\n this.emitCompleted();\n },\n });\n\n return progress;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Bitcoin Send (Optional)\n // ─────────────────────────────────────────────────────────────────────────\n\n protected async trySendBitcoin(\n depositAddress: string,\n ): Promise<string | undefined> {\n const amount = this._amount;\n if (!amount) return undefined;\n\n try {\n const btcProvider = await this.ctx.getProvider('bitcoin');\n if (!btcProvider) return undefined;\n\n const provider = btcProvider as {\n sendBitcoin?: (address: string, amountSats: number) => Promise<string>;\n };\n\n if (provider.sendBitcoin) {\n const amountSats = toSatoshi(amount).toNumber();\n return provider.sendBitcoin(depositAddress, amountSats);\n }\n } catch {\n // Fall back to manual send\n }\n\n return undefined;\n }\n}\n","/**\n * Token Utilities for BTC Actions\n *\n * Shared utilities for mapping asset IDs to tokens.\n *\n * ## Token Parameter Pattern for StakeAndBake/DepositAndDeploy\n *\n * The `token` parameter in authorization functions determines which DEFI_REGISTRY\n * entry is used, which affects the `amountStrategy`:\n *\n * | Action | Flow | Token Param | Strategy | Reason |\n * |---------------------|-------------------|---------------|-------------|----------------------------|\n * | BtcStakeAndDeploy | BTC → LBTC → Vault | AssetId.BTC | btcToLbtc | Apply BTC/LBTC ratio |\n * | BtcDepositAndDeploy | BTC → BTCb → Vault | Token.BTCb | identity | 1:1 ratio, no conversion |\n *\n * **Key Insight:**\n * - LBTC has a variable exchange rate with BTC (~1.00265 BTC = 1 LBTC)\n * - BTC.b is 1:1 with BTC (wrapped representation)\n *\n * For LBTC outputs, use the SOURCE asset (`'BTC'`) to trigger ratio conversion.\n * For BTC.b outputs, use the OUTPUT asset (`Token.BTCb`) since no conversion needed.\n *\n * @see DEFI_REGISTRY in defi/defi-registry.ts\n * @see signStakeAndBake for how amountStrategy is applied\n *\n * @module chains/btc/actions/shared/tokenUtils\n */\n\nimport { AssetId } from '../../../../core/assets';\nimport { Token } from '../../../../tokens/token-addresses';\n\n/**\n * Maps an AssetId to its corresponding Token value for API calls.\n *\n * **Note:** This function handles LBTC and BTCb. For BTC → LBTC flows that need\n * ratio conversion, use `AssetId.BTC` directly instead of this function.\n *\n * @param assetId - The asset ID to convert\n * @param defaultToken - The default token if assetId doesn't match known types (defaults to LBTC)\n * @returns The corresponding Token value\n *\n * @example\n * // For BTC.b outputs (1:1 with BTC)\n * assetIdToToken(AssetId.BTCb) // returns Token.BTCb\n *\n * @example\n * // For LBTC outputs from LBTC source (no ratio conversion)\n * assetIdToToken(AssetId.LBTC) // returns Token.LBTC\n *\n * @example\n * // For BTC → LBTC (needs ratio conversion)\n * // DON'T use assetIdToToken, use AssetId.BTC directly\n * token: AssetId.BTC // triggers btcToLbtc strategy\n */\nexport function assetIdToToken(\n assetId: AssetId,\n defaultToken: Token = Token.LBTC,\n): Token {\n switch (assetId) {\n case AssetId.LBTC:\n return Token.LBTC;\n case AssetId.BTCb:\n return Token.BTCb;\n default:\n return defaultToken;\n }\n}\n\n","/**\n * EVM Chain Switching Utility\n *\n * Helper to ensure wallet is on the correct chain before signing.\n * Uses EIP-3326 (wallet_switchEthereumChain) and EIP-3085 (wallet_addEthereumChain).\n *\n * @module shared/evm/switchChain\n */\n\nimport type { EIP1193Provider } from 'viem';\n\nimport { addChain, type ChainId } from '../../common/chains';\nimport { LombardError, ValidationErrorCode } from '../errors';\n\n/**\n * Request to switch wallet to the target chain\n * If chain is not available, attempts to add it first.\n *\n * @param provider - EIP-1193 provider\n * @param targetChainId - Chain ID to switch to\n * @throws LombardError if chain switching fails\n */\nexport async function requestChainSwitch(\n provider: EIP1193Provider,\n targetChainId: ChainId,\n): Promise<void> {\n try {\n await provider.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: `0x${targetChainId.toString(16)}` }],\n });\n } catch (error) {\n const err = error as { code?: number; message?: string };\n\n // 4902 = chain not added - try to add it automatically\n if (err.code === 4902) {\n try {\n await addChain({ provider, chainId: targetChainId });\n // After adding, try to switch again\n await provider.request({\n method: 'wallet_switchEthereumChain',\n params: [{ chainId: `0x${targetChainId.toString(16)}` }],\n });\n return;\n } catch (addError) {\n const addErr = addError as { code?: number; message?: string };\n\n // User rejected adding chain\n if (addErr.code === 4001) {\n throw new LombardError(\n ValidationErrorCode.INVALID_PARAMETER,\n 'User rejected adding chain to wallet.',\n );\n }\n\n throw new LombardError(\n ValidationErrorCode.INVALID_CHAIN,\n `Failed to add chain ${targetChainId} to wallet: ${addErr.message || 'Unknown error'}`,\n );\n }\n }\n\n // User rejected\n if (err.code === 4001) {\n throw new LombardError(\n ValidationErrorCode.INVALID_PARAMETER,\n 'User rejected chain switch request.',\n );\n }\n\n throw new LombardError(\n ValidationErrorCode.INVALID_CHAIN,\n `Failed to switch to chain ${targetChainId}: ${err.message || 'Unknown error'}`,\n );\n }\n}\n\n/**\n * Get current chain ID from wallet\n *\n * @param provider - EIP-1193 provider\n * @returns Current chain ID as number\n */\nexport async function getCurrentChainId(\n provider: EIP1193Provider,\n): Promise<number> {\n const chainIdHex = (await provider.request({\n method: 'eth_chainId',\n })) as string;\n return parseInt(chainIdHex, 16);\n}\n\n/**\n * Ensure wallet is on the correct chain, switching if necessary\n *\n * @param provider - EIP-1193 provider\n * @param targetChainId - Required chain ID\n * @throws LombardError if chain switching fails\n */\nexport async function ensureCorrectChain(\n provider: EIP1193Provider,\n targetChainId: ChainId,\n): Promise<void> {\n const currentChainId = await getCurrentChainId(provider);\n\n if (currentChainId !== targetChainId) {\n await requestChainSwitch(provider, targetChainId);\n }\n}\n","/**\n * EVM Chain Configuration for BTC Deposit\n *\n * BTC Deposit: BTC → BTC.b (wrapped BTC without yield)\n * For staking (BTC → LBTC), use BtcStake instead.\n *\n * Supported chains are derived from ASSET_CATALOG - single source of truth.\n *\n * Fee authorization is ONLY required for Ethereum mainnet.\n * Other chains use address confirmation signing.\n *\n * @module chains/btc/actions/deposit/config/evm\n */\n\nimport type { EvmService } from '@lombard.finance/sdk-common';\nimport { Env } from '@lombard.finance/sdk-common';\nimport type { EIP1193Provider } from 'viem';\n\nimport type { ChainId } from '../../../../../common/chains';\nimport {\n AssetId,\n Chain,\n getAllAssetChains,\n isEvmChain,\n} from '../../../../../core';\nimport { LombardError } from '../../../../../shared/errors';\nimport { ensureCorrectChain } from '../../../../../shared/evm/switchChain';\nimport { evmAddressSchema } from '../../../../../shared/validation';\nimport { Token } from '../../../../../tokens/token-addresses';\nimport { getTokenContractInfo } from '../../../../../tokens/tokens';\nimport { toSatoshi } from '../../../../../utils/satoshi';\nimport type { DepositChainConfig, DepositFeeAuthConfig } from './types';\n\n/**\n * Chains that require fee authorization (unsubsidized chains).\n * \n * Ethereum mainnet and Sepolia require EIP-712 network fee signing.\n * Other chains are subsidized by Lombard.\n */\nconst UNSUBSIDIZED_CHAINS = [Chain.ETHEREUM, Chain.SEPOLIA] as const;\n\n/**\n * Fee authorization config for unsubsidized chains\n *\n * BTC Deposit produces BTC.b, so we must use Token.BTCb for fee signatures.\n * This ensures the backend can distinguish between LBTC and BTC.b signatures.\n */\nconst feeAuthConfig: DepositFeeAuthConfig = {\n async getMintingFee(ctx, chainId) {\n const evm = ctx.capabilities.require('evm') as EvmService;\n // Fetch BTC.b minting fee (not LBTC!)\n return evm.getMintingFee(chainId as ChainId, Token.BTCb);\n },\n\n async restoreFeeSignature(ctx, chainId, address) {\n // Get BTC.b token address for this chain to distinguish from LBTC signatures\n const tokenInfo = await getTokenContractInfo(\n Token.BTCb,\n chainId as ChainId,\n ctx.env,\n );\n\n const result = await ctx.api.getFeeSignature({\n address,\n chainId: chainId as ChainId,\n tokenAddress: tokenInfo.address,\n });\n\n // Check if signature exists on server (API returns has_signature flag)\n if (!result.hasSignature) {\n return null;\n }\n\n // Check expiration - expirationDate is Unix timestamp in seconds\n // Convert to milliseconds for Date comparison\n if (result.expirationDate && new Date(Number(result.expirationDate) * 1000) < new Date()) {\n return null;\n }\n\n // Return hasSignature: true even if actual signature string is not returned by API\n // The server has the signature stored; we just need to know it's valid\n return {\n hasSignature: true,\n signature: result.signature, // May be undefined - that's OK\n typedData: result.typedData,\n };\n },\n\n async authorizeFee(ctx, { chainId, recipient, fee }) {\n const evm = ctx.capabilities.require('evm') as EvmService;\n const provider = await ctx.getProvider('evm');\n if (!provider) {\n throw LombardError.providerMissing(String(chainId), 'evm');\n }\n\n // Ensure wallet is on the correct chain before signing\n await ensureCorrectChain(provider as EIP1193Provider, chainId as ChainId);\n\n // getMintingFee returns BTC (e.g., \"0.00000032\"), but signNetworkFee expects satoshis\n const feeInSatoshis = toSatoshi(fee).toString();\n\n // Get BTC.b token info for this chain\n const tokenInfo = await getTokenContractInfo(\n Token.BTCb,\n chainId as ChainId,\n ctx.env,\n );\n\n // Sign the network fee with BTC.b token (not LBTC!)\n const result = await evm.signNetworkFee({\n fee: feeInSatoshis,\n account: recipient,\n chainId: chainId as ChainId,\n provider: provider as EIP1193Provider,\n token: Token.BTCb,\n });\n\n // Store the signature with token address to distinguish from LBTC signatures\n await ctx.api.storeFeeSignature({\n address: recipient,\n signature: result.signature,\n typedData: result.typedData,\n tokenAddress: tokenInfo.address,\n });\n\n return {\n signature: result.signature,\n typedData: result.typedData,\n };\n },\n};\n\n/**\n * EVM deposit configuration\n *\n * BTC Deposit produces BTC.b (wrapped BTC without yield).\n * Supported chains are derived from ASSET_CATALOG[AssetId.BTCb].deployments.\n */\nexport const evmDepositConfig: DepositChainConfig = {\n chainType: 'evm',\n\n routes: [\n {\n sourceChains: [Chain.BITCOIN_MAINNET],\n envs: [Env.prod],\n },\n {\n sourceChains: [Chain.BITCOIN_SIGNET],\n envs: [Env.stage, Env.dev, Env.testnet, Env.ibc],\n },\n ],\n\n // Derived from ASSET_CATALOG - all chains where BTC.b is deployed\n destChains: getAllAssetChains(AssetId.BTCb).filter(chain =>\n isEvmChain(chain),\n ),\n\n // BTC Deposit only produces BTC.b\n supportedAssetsOut: [AssetId.BTCb],\n\n addressSchema: evmAddressSchema,\n\n /**\n * Get fee auth config - unsubsidized chains require fee authorization\n * Other chains use address confirmation signing\n */\n getFeeAuthConfig(destChain: Chain): DepositFeeAuthConfig | null {\n return (UNSUBSIDIZED_CHAINS as readonly Chain[]).includes(destChain)\n ? feeAuthConfig\n : null;\n },\n\n /**\n * Sign destination address confirmation\n * Used for non-fee-auth chains (e.g., Avalanche, Katana)\n */\n async signDestination(ctx, recipient, chainId) {\n const evm = ctx.capabilities.require('evm') as EvmService;\n const provider = await ctx.getProvider('evm');\n if (!provider) {\n throw LombardError.providerMissing(String(chainId), 'evm');\n }\n\n // Ensure wallet is on the correct chain before signing\n await ensureCorrectChain(provider as EIP1193Provider, chainId as ChainId);\n\n const result = await evm.signLbtcDestination({\n address: recipient,\n chainId: chainId as ChainId,\n provider: provider as EIP1193Provider,\n });\n\n return {\n signature: result.signature,\n };\n },\n};\n","/**\n * BTC Deposit Chain Configuration Registry\n *\n * BTC Deposit: BTC → BTC.b (wrapped BTC without yield)\n *\n * @module chains/btc/actions/deposit/config\n */\n\nimport type { Env } from '@lombard.finance/sdk-common';\n\nimport type { AssetId, Chain } from '../../../../../core';\nimport { evmDepositConfig } from './evm';\n\nexport type {\n DepositChainConfig,\n DepositFeeAuthConfig,\n DepositRouteDefinition,\n FeeAuthResult,\n SignatureResult,\n StoredFeeSignature,\n} from './types';\n\n/**\n * All deposit configs (currently only EVM)\n */\nexport const depositConfig = evmDepositConfig;\n\n/**\n * Check if destination chain is supported\n */\nexport function isDestChainSupported(chain: Chain): boolean {\n return depositConfig.destChains.includes(chain);\n}\n\n/**\n * Check if assetOut is supported for BTC Deposit\n * BTC Deposit should only produce BTC.b\n */\nexport function isAssetOutSupported(assetOut: AssetId): boolean {\n return depositConfig.supportedAssetsOut.includes(assetOut);\n}\n\n/**\n * Check if route is available for given source chain and environment\n */\nexport function isRouteAvailable(\n sourceChain: Chain | undefined,\n env: Env,\n): boolean {\n if (!sourceChain) return true;\n return depositConfig.routes.some(\n route =>\n route.sourceChains.includes(sourceChain) && route.envs.includes(env),\n );\n}\n","/**\n * BTC Deposit Action\n *\n * Handles BTC deposit operations for custody without staking.\n * Currently supports EVM destination chains.\n *\n * Fee authorization is ONLY required for Ethereum mainnet.\n * Other chains use address confirmation signing.\n *\n * @module chains/btc/actions/deposit/BtcDeposit\n */\n\nimport type { z } from 'zod';\n\nimport type { ChainId } from '../../../../common/chains';\nimport { isValidChain } from '../../../../common/chains';\nimport { parseChainIdentifier, StepStatus } from '../../../../core';\nimport type { BtcCoreContext } from '../../../../shared/context';\nimport { LombardError, ValidationErrorCode } from '../../../../shared/errors';\nimport type { DepositEventMap } from '../../../../shared/events';\nimport type { MonitorProgress } from '../../../../shared/monitoring';\nimport { Token } from '../../../../tokens/token-addresses';\nimport {\n assetIdToToken,\n BaseBtcAction,\n type StatusConfig,\n type StepDefinition,\n} from '../shared';\nimport {\n depositConfig,\n type DepositFeeAuthConfig,\n isAssetOutSupported,\n isDestChainSupported,\n isRouteAvailable,\n} from './config';\nimport {\n BtcActionStatus,\n type BtcDeposit as IBtcDeposit,\n type BtcDepositParams,\n type BtcDepositPrepareParams,\n} from './types';\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Types\n// ═══════════════════════════════════════════════════════════════════════════\n\ninterface AuthorizationState {\n signature?: string;\n typedData?: string;\n authorized: boolean;\n /** Minting fee in BTC (e.g., \"0.00000032\") */\n mintingFee?: string;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// BtcDeposit Implementation\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * BTC Deposit Action\n *\n * Handles BTC deposit to custody with BTC.b minting on destination chain.\n * This is for custody without staking. For staking (BTC → LBTC), use BtcStake.\n *\n * @example\n * ```typescript\n * const deposit = new BtcDeposit(ctx, {\n * assetOut: AssetId.BTCb,\n * destChain: Chain.AVALANCHE,\n * });\n *\n * await deposit.prepare({ amount: '0.1', recipient: '0x...' });\n * await deposit.authorizeFee();\n * const address = await deposit.generateDepositAddress();\n * ```\n */\nexport class BtcDeposit\n extends BaseBtcAction<DepositEventMap, BtcActionStatus, BtcDepositParams>\n implements IBtcDeposit\n{\n private readonly chainId: ChainId;\n private readonly authState: AuthorizationState = { authorized: false };\n\n /** Fee auth config - null if not required for this destination */\n private feeAuthConfig: DepositFeeAuthConfig | null = null;\n\n constructor(ctx: BtcCoreContext, params: BtcDepositParams) {\n super(ctx, params, BtcActionStatus.IDLE);\n\n // Validate assetOut - BTC Deposit should only produce BTC.b\n if (!isAssetOutSupported(params.assetOut)) {\n throw new LombardError(\n ValidationErrorCode.INVALID_ASSET,\n `Asset ${params.assetOut} is not supported for BTC deposits. ` +\n `BTC Deposit produces BTC.b. For LBTC, use BtcStake instead.`,\n );\n }\n\n if (!isDestChainSupported(params.destChain)) {\n throw new LombardError(\n ValidationErrorCode.INVALID_CHAIN,\n `Destination chain ${params.destChain} is not supported for BTC deposits. ` +\n `BTC.b is currently available on Avalanche and Katana.`,\n );\n }\n\n if (!isRouteAvailable(params.sourceChain, ctx.env)) {\n throw LombardError.routeNotFound({\n assetOut: params.assetOut,\n sourceChain: params.sourceChain,\n destChain: params.destChain,\n env: ctx.env,\n });\n }\n\n const parsed = parseChainIdentifier(params.destChain);\n if (typeof parsed !== 'number' || !isValidChain(parsed)) {\n throw new LombardError(\n ValidationErrorCode.INVALID_CHAIN,\n `Unsupported EVM chain: ${params.destChain}`,\n );\n }\n\n this.chainId = parsed as ChainId;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Abstract Method Implementations\n // ─────────────────────────────────────────────────────────────────────────\n\n protected getAddressSchema(): z.ZodType<string> {\n return depositConfig.addressSchema;\n }\n\n protected getStatusConfig(): StatusConfig<BtcActionStatus> {\n return {\n idle: BtcActionStatus.IDLE,\n ready: BtcActionStatus.READY,\n addressReady: BtcActionStatus.ADDRESS_READY,\n };\n }\n\n protected getInitialSteps(): StepDefinition {\n return {\n created: StepStatus.IDLE,\n verifying: StepStatus.IDLE,\n issuing: StepStatus.IDLE,\n };\n }\n\n protected isAuthorized(): boolean {\n return this.authState.authorized;\n }\n\n protected getChainId(): ChainId {\n return this.chainId;\n }\n\n /**\n * Get the minting fee for this deposit (in BTC)\n * Available after prepare() when fee authorization is required\n */\n get mintingFee(): string | undefined {\n return this.authState.mintingFee;\n }\n\n protected getDepositAddressParams(captchaToken?: string) {\n const recipient = this.ensureRecipient();\n return {\n address: recipient,\n chainId: this.chainId,\n signature: this.authState.signature!, // Must be set before calling\n token: this.getExpectedToken(),\n eip712Data: this.authState.typedData,\n partnerId: this.ctx.partner.getPartnerId(),\n referrerCode: this._referralCode,\n captchaToken,\n };\n }\n\n /**\n * Override to ensure we have a signature before generating deposit address.\n * \n * When fee auth exists on server but signature isn't available locally,\n * we fall back to signing the destination address.\n */\n async generateDepositAddress(captchaToken?: string): Promise<string> {\n // If signature isn't available locally, sign the destination address as fallback\n if (!this.authState.signature) {\n const result = await depositConfig.signDestination(\n this.ctx,\n this.ensureRecipient(),\n this.chainId,\n );\n this.authState.signature = result.signature;\n this.authState.typedData = result.typedData;\n }\n\n return this.generateDepositAddressImpl(captchaToken);\n }\n\n /**\n * Get expected token for this action (BTCb by default for BTC Deposit)\n */\n protected getExpectedToken(): string {\n return assetIdToToken(this.params.assetOut, Token.BTCb);\n }\n\n protected getAuthRequiredMessage(): string {\n return this.feeAuthConfig\n ? 'Fee authorization required. Call authorizeFee() first.'\n : 'Address confirmation required. Call confirmAddress() first.';\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Public Methods\n // ─────────────────────────────────────────────────────────────────────────\n\n async prepare(params: BtcDepositPrepareParams): Promise<void> {\n this.assertStatus(BtcActionStatus.IDLE, 'prepare');\n\n return this.act(async () => {\n const validated = this.validatePrepareParams(params);\n\n this._amount = validated.amount;\n this._recipient = validated.recipient;\n this._referralCode = validated.referralCode;\n\n // Get fee auth config for this destination chain (needed for both resume and new flow)\n this.feeAuthConfig = depositConfig.getFeeAuthConfig(\n this.params.destChain,\n );\n\n // Check for existing deposit address (resume flow)\n const hasExistingDeposit = await this.resumeFromExistingDeposit(\n validated.recipient,\n );\n\n if (hasExistingDeposit) {\n // We have a deposit address, but we still need to validate fee authorization\n // The deposit address might have been created when fee auth was valid,\n // but the fee auth could have expired since then\n if (this.feeAuthConfig) {\n const stored = await this.feeAuthConfig.restoreFeeSignature(\n this.ctx,\n this.chainId,\n validated.recipient,\n );\n\n // Check hasSignature flag - the actual signature string may not be returned by API\n if (!stored?.hasSignature) {\n // Fee auth is required but expired/missing - need re-authorization\n // Fetch the minting fee for display purposes\n this.authState.mintingFee = await this.feeAuthConfig.getMintingFee(\n this.ctx,\n this.chainId,\n );\n this.updateStatus(BtcActionStatus.NEEDS_FEE_AUTHORIZATION);\n this.emitInitialProgress();\n return;\n }\n\n // Fee auth is still valid on server - store signature if available\n if (stored.signature) {\n this.authState.signature = stored.signature;\n this.authState.typedData = stored.typedData;\n }\n this.authState.authorized = true;\n }\n\n // Deposit address exists and fee auth is valid (or not required)\n // Now we can safely set the status to ADDRESS_READY\n this.updateStatus(BtcActionStatus.ADDRESS_READY);\n this.emitInitialProgress();\n return;\n }\n\n // No existing deposit - proceed with normal flow\n if (this.feeAuthConfig) {\n // Fee authorization required (Ethereum mainnet only)\n const stored = await this.feeAuthConfig.restoreFeeSignature(\n this.ctx,\n this.chainId,\n validated.recipient,\n );\n\n // Check hasSignature flag - the actual signature string may not be returned by API\n if (stored?.hasSignature) {\n // Fee auth already exists on server - store signature if available\n if (stored.signature) {\n this.authState.signature = stored.signature;\n this.authState.typedData = stored.typedData;\n }\n this.authState.authorized = true;\n this.updateStatus(BtcActionStatus.READY);\n this.emitInitialProgress();\n return;\n }\n\n // Fetch the minting fee for display purposes\n this.authState.mintingFee = await this.feeAuthConfig.getMintingFee(\n this.ctx,\n this.chainId,\n );\n this.updateStatus(BtcActionStatus.NEEDS_FEE_AUTHORIZATION);\n } else {\n this.updateStatus(BtcActionStatus.NEEDS_ADDRESS_CONFIRMATION);\n }\n\n this.emitInitialProgress();\n });\n }\n\n async authorizeFee(): Promise<void> {\n this.assertStatus(\n [BtcActionStatus.NEEDS_FEE_AUTHORIZATION, BtcActionStatus.READY],\n 'authorizeFee',\n );\n\n if (this.status === BtcActionStatus.READY) return;\n\n if (!this.feeAuthConfig) {\n throw new LombardError(\n ValidationErrorCode.INVALID_PARAMETER,\n 'Fee authorization is not required for this destination chain. Use confirmAddress() instead.',\n );\n }\n\n const recipient = this.ensureRecipient();\n\n // Use the minting fee that was fetched during prepare(), not the deposit amount\n if (!this.authState.mintingFee) {\n throw new LombardError(\n ValidationErrorCode.INVALID_STATE,\n 'Minting fee not available. Call prepare() first.',\n );\n }\n\n return this.act(async () => {\n const result = await this.feeAuthConfig!.authorizeFee(this.ctx, {\n chainId: this.chainId,\n recipient,\n fee: this.authState.mintingFee!,\n });\n\n this.authState.signature = result.signature;\n this.authState.typedData = result.typedData;\n this.authState.authorized = true;\n }, BtcActionStatus.READY);\n }\n\n async confirmAddress(): Promise<void> {\n this.assertStatus(\n [BtcActionStatus.NEEDS_ADDRESS_CONFIRMATION, BtcActionStatus.READY],\n 'confirmAddress',\n );\n\n if (this.status === BtcActionStatus.READY) return;\n\n if (this.feeAuthConfig) {\n throw new LombardError(\n ValidationErrorCode.INVALID_PARAMETER,\n 'This destination chain requires fee authorization. Use authorizeFee() instead.',\n );\n }\n\n const recipient = this.ensureRecipient();\n\n return this.act(async () => {\n const result = await depositConfig.signDestination(\n this.ctx,\n recipient,\n this.chainId,\n );\n\n this.authState.signature = result.signature;\n this.authState.typedData = result.typedData;\n this.authState.authorized = true;\n }, BtcActionStatus.READY);\n }\n\n async execute(): Promise<{ depositAddress: string; txHash?: string }> {\n return this.executeImpl();\n }\n\n async monitorDeposit(): Promise<MonitorProgress | undefined> {\n return super.monitorDeposit();\n }\n}\n","/**\n * EVM Chain Configuration for BTC StakeAndDeploy\n *\n * BTC StakeAndDeploy: BTC → LBTC → DeFi vault (Veda, Silo)\n *\n * Note: StakeAndDeploy is limited to chains that have both LBTC deployed\n * AND Veda/Silo vault support. This is a subset of all LBTC chains.\n *\n * @module chains/btc/actions/stakeAndDeploy/config/evm\n */\n\nimport type { EvmService } from '@lombard.finance/sdk-common';\nimport { Env } from '@lombard.finance/sdk-common';\nimport type { EIP1193Provider } from 'viem';\n\nimport { getUserStakeAndBakeSignature } from '../../../../../api-functions/getUserStakeAndBakeSignature';\nimport type { ChainId } from '../../../../../common/chains';\nimport { AssetId, Chain, evmChainIdToChain } from '../../../../../core';\nimport { LombardError } from '../../../../../shared/errors';\nimport { ensureCorrectChain } from '../../../../../shared/evm/switchChain';\nimport { evmAddressSchema } from '../../../../../shared/validation';\nimport { VEDA_VAULT_STAKE_AND_BAKE_CHAINS } from '../../../../../vaults/lib/config';\nimport { getSupportedProtocols } from '../../depositAndDeploy/config';\nimport type { StakeAndDeployChainConfig } from './types';\n\n// Convert chain IDs to Chain enum values (CAIP-2 format)\n// Uses VEDA_VAULT_STAKE_AND_BAKE_CHAINS as source of truth\nconst STAKE_AND_DEPLOY_DEST_CHAINS = VEDA_VAULT_STAKE_AND_BAKE_CHAINS.map(\n chainId => evmChainIdToChain(chainId),\n);\n\n/**\n * EVM stake and deploy configuration\n *\n * StakeAndDeploy produces LBTC then deploys to a vault.\n * Limited to chains with Veda/Silo vault support.\n */\nexport const evmStakeAndDeployConfig: StakeAndDeployChainConfig = {\n chainType: 'evm',\n\n routes: [\n {\n sourceChains: [Chain.BITCOIN_MAINNET],\n envs: [Env.prod],\n },\n {\n sourceChains: [Chain.BITCOIN_SIGNET],\n envs: [Env.stage, Env.dev, Env.testnet, Env.ibc],\n },\n ],\n\n // StakeAndDeploy requires vault support - uses VEDA_VAULT_STAKE_AND_BAKE_CHAINS as source of truth\n destChains: STAKE_AND_DEPLOY_DEST_CHAINS,\n\n // StakeAndDeploy produces LBTC (then deposits to vault)\n supportedAssetsOut: [AssetId.LBTC],\n\n supportedProtocols: getSupportedProtocols(AssetId.LBTC),\n\n addressSchema: evmAddressSchema,\n\n async getStakeAndBakeFee(ctx, chainId, protocol) {\n const evm = ctx.capabilities.require('evm') as EvmService;\n return evm.getStakeAndBakeFee(chainId as ChainId, protocol);\n },\n\n async authorizeStakeAndBake(\n ctx,\n { chainId, recipient, amount, vaultKey, token },\n ) {\n const evm = ctx.capabilities.require('evm') as EvmService;\n const provider = await ctx.getProvider('evm');\n if (!provider) {\n throw LombardError.providerMissing(String(chainId), 'evm');\n }\n\n // Ensure wallet is on the correct chain before signing\n await ensureCorrectChain(provider as EIP1193Provider, chainId as ChainId);\n\n const result = await evm.signStakeAndBake({\n value: amount,\n account: recipient,\n chainId: chainId as ChainId,\n provider: provider as EIP1193Provider,\n vaultKey,\n token,\n });\n\n // Store signature via API\n await ctx.api.storeStakeAndBakeSignature({\n signature: result.signature,\n typedData: result.typedData,\n });\n\n return {\n signature: result.signature,\n typedData: result.typedData,\n };\n },\n\n async restoreStakeAndBakeSignature(ctx, chainId, recipient) {\n try {\n const result = await getUserStakeAndBakeSignature({\n userDestinationAddress: recipient,\n chainId: chainId as ChainId,\n env: ctx.env,\n });\n\n // Check if signature exists by looking at metadata, not just the signature string.\n // The API may return metadata (expiration, amount, nonce) even if the raw\n // signature string is not included in the response.\n // If we have an expiration date, that means a valid signature exists on the server.\n const hasSignatureData = result.signature || result.expirationDate;\n if (!hasSignatureData) {\n return null;\n }\n\n // Check expiration - expirationDate is Unix timestamp in seconds\n // Convert to milliseconds for Date comparison\n if (result.expirationDate) {\n const expirationMs = Number(result.expirationDate) * 1000;\n if (expirationMs < Date.now()) {\n // Signature has expired\n return null;\n }\n }\n\n return {\n hasSignature: true,\n signature: result.signature,\n depositAmount: result.depositAmount,\n expirationDate: result.expirationDate,\n };\n } catch {\n // API error (e.g., signature not found, network error)\n // Return null to indicate no valid signature exists\n return null;\n }\n },\n};\n","/**\n * BTC StakeAndDeploy Chain Configuration Registry\n *\n * BTC StakeAndDeploy: BTC → LBTC → DeFi vault\n * Uses DEFI_REGISTRY as the single source of truth for protocol validation.\n *\n * @module chains/btc/actions/stakeAndDeploy/config\n */\n\nimport type { Env } from '@lombard.finance/sdk-common';\n\nimport type { AssetId, Chain } from '../../../../../core';\nimport { DEFI_REGISTRY,DefiProtocol } from '../../../../../defi';\nimport { Token } from '../../../../../tokens/token-addresses';\nimport { evmStakeAndDeployConfig } from './evm';\n\nexport type {\n StakeAndBakeAuthResult,\n StakeAndDeployChainConfig,\n StakeAndDeployRouteDefinition,\n} from './types';\n\n/**\n * Config (currently EVM only)\n */\nexport const stakeAndDeployConfig = evmStakeAndDeployConfig;\n\n/**\n * Check if destination chain is supported\n */\nexport function isDestChainSupported(chain: Chain): boolean {\n return stakeAndDeployConfig.destChains.includes(chain);\n}\n\n/**\n * Check if assetOut is supported\n * StakeAndDeploy should only produce LBTC\n */\nexport function isAssetOutSupported(assetOut: AssetId): boolean {\n return stakeAndDeployConfig.supportedAssetsOut.includes(assetOut);\n}\n\n/**\n * Check if route is available\n */\nexport function isRouteAvailable(\n sourceChain: Chain | undefined,\n env: Env,\n): boolean {\n if (!sourceChain) return true;\n return stakeAndDeployConfig.routes.some(\n route =>\n route.sourceChains.includes(sourceChain) && route.envs.includes(env),\n );\n}\n\n/**\n * Check if protocol is supported for stake and deploy\n * Uses DEFI_REGISTRY as the single source of truth\n */\nexport function isProtocolSupported(protocol: string): boolean {\n // Check if protocol exists in DEFI_REGISTRY\n return protocol in DEFI_REGISTRY;\n}\n\n/**\n * Get the vault key for a protocol\n * Returns the protocol key if valid, throws if not supported\n *\n * @param protocol - Protocol identifier from DefiProtocol\n * @returns The vault key for API calls\n * @throws If protocol is not in DEFI_REGISTRY\n */\nexport function getVaultKey(protocol: string): string {\n if (!isProtocolSupported(protocol)) {\n const supportedProtocols = Object.keys(DEFI_REGISTRY).join(', ');\n throw new Error(\n `Unsupported protocol: ${protocol}. ` +\n `Supported protocols: ${supportedProtocols}`,\n );\n }\n // Protocol keys in DEFI_REGISTRY match DefiProtocol values\n return protocol;\n}\n\n/**\n * Get list of supported protocols for StakeAndDeploy\n * This returns protocols that support LBTC or BTC (for StakeAndDeploy from BTC)\n * \n * TODO: Update this to match against asset and chain\n */\nexport function getSupportedProtocols(assetId: AssetId): DefiProtocol[] {\n return Object.entries(DEFI_REGISTRY)\n .filter(([_, tokenMap]) => assetId in tokenMap)\n .map(([protocol]) => protocol as DefiProtocol);\n}\n\n/**\n * Check if a protocol supports a specific chain for stake and deploy\n */\nexport function isProtocolChainSupported(\n protocol: string,\n chainId: number,\n env: Env,\n): boolean {\n const protocolRegistry = DEFI_REGISTRY[protocol as DefiProtocol];\n if (!protocolRegistry) return false;\n\n // Check LBTC token first, then BTC\n const lbtcRegistry =\n protocolRegistry[Token.LBTC as keyof typeof protocolRegistry];\n const btcRegistry = protocolRegistry['BTC' as keyof typeof protocolRegistry];\n\n const tokenRegistry = lbtcRegistry || btcRegistry;\n if (!tokenRegistry) return false;\n\n const envRegistry = tokenRegistry[env];\n if (!envRegistry) return false;\n\n return chainId in envRegistry;\n}\n","/**\n * EVM Chain Configuration for BTC DepositAndDeploy\n *\n * BTC DepositAndDeploy: BTC → BTC.b → DeFi vault (Silo)\n *\n * Note: DepositAndDeploy is for protocols that accept BTC.b (wrapped BTC)\n * rather than LBTC. Currently, this is Silo on Avalanche.\n *\n * @module chains/btc/actions/depositAndDeploy/config/evm\n */\n\nimport type { EvmService } from '@lombard.finance/sdk-common';\nimport { Env } from '@lombard.finance/sdk-common';\nimport type { EIP1193Provider } from 'viem';\n\nimport type { ChainId } from '../../../../../common/chains';\nimport { AssetId, Chain } from '../../../../../core';\nimport { LombardError } from '../../../../../shared/errors';\nimport { ensureCorrectChain } from '../../../../../shared/evm/switchChain';\nimport { evmAddressSchema } from '../../../../../shared/validation';\nimport { getSupportedProtocols } from '../../stakeAndDeploy/config';\nimport type { DepositAndDeployChainConfig } from './types';\n\n// DepositAndDeploy requires BTC.b + Silo vault support\n// Currently only Avalanche is supported\nconst DEPOSIT_AND_DEPLOY_CHAINS = {\n mainnet: [Chain.AVALANCHE],\n testnet: [Chain.AVALANCHE_FUJI],\n};\n\n/**\n * EVM deposit and deploy configuration\n *\n * DepositAndDeploy produces BTC.b then deploys to a vault.\n * Currently limited to Silo on Avalanche.\n */\nexport const evmDepositAndDeployConfig: DepositAndDeployChainConfig = {\n chainType: 'evm',\n\n routes: [\n {\n sourceChains: [Chain.BITCOIN_MAINNET],\n envs: [Env.prod],\n },\n {\n sourceChains: [Chain.BITCOIN_SIGNET],\n envs: [Env.stage, Env.dev, Env.testnet, Env.ibc],\n },\n ],\n\n // DepositAndDeploy with BTC.b is available on Avalanche\n destChains: [\n ...DEPOSIT_AND_DEPLOY_CHAINS.mainnet,\n ...DEPOSIT_AND_DEPLOY_CHAINS.testnet,\n ],\n\n // DepositAndDeploy produces BTC.b (then deposits to vault)\n supportedAssetsOut: [AssetId.BTCb],\n\n supportedProtocols: getSupportedProtocols(AssetId.BTCb),\n\n addressSchema: evmAddressSchema,\n\n async getDepositAndDeployFee(ctx, chainId, vaultKey) {\n const evm = ctx.capabilities.require('evm') as EvmService;\n // Silo uses the same fee mechanism as stake and bake\n return evm.getStakeAndBakeFee(chainId as ChainId, vaultKey);\n },\n\n async authorizeDepositAndDeploy(\n ctx,\n { chainId, recipient, amount, vaultKey, token },\n ) {\n const evm = ctx.capabilities.require('evm') as EvmService;\n const provider = await ctx.getProvider('evm');\n if (!provider) {\n throw LombardError.providerMissing(String(chainId), 'evm');\n }\n\n // Ensure wallet is on the correct chain before signing\n await ensureCorrectChain(provider as EIP1193Provider, chainId as ChainId);\n\n // Silo uses the approve flow (on-chain approval), not permit\n const result = await evm.signStakeAndBake({\n value: amount,\n account: recipient,\n chainId: chainId as ChainId,\n provider: provider as EIP1193Provider,\n vaultKey,\n token,\n });\n\n // Store signature via API (even for approve flow, we need to track it)\n await ctx.api.storeStakeAndBakeSignature({\n signature: result.signature,\n typedData: result.typedData,\n });\n\n return {\n signature: result.signature,\n typedData: result.typedData,\n // approvalTxHash may not be present in the result for all flows\n approvalTxHash: (result as { approvalTxHash?: string }).approvalTxHash,\n };\n },\n};\n","/**\n * BTC DepositAndDeploy Configuration\n *\n * Exports configuration for BTC → BTC.b → Vault operations.\n * Uses DEFI_REGISTRY as the single source of truth for protocol validation.\n *\n * @module chains/btc/actions/depositAndDeploy/config\n */\n\nimport type { Env } from '@lombard.finance/sdk-common';\n\nimport type { AssetId, Chain } from '../../../../../core';\nimport { DEFI_REGISTRY,DefiProtocol } from '../../../../../defi';\nimport { evmDepositAndDeployConfig } from './evm';\nimport type { DepositAndDeployChainConfig } from './types';\n\nexport type {\n DepositAndDeployAuthResult,\n DepositAndDeployChainConfig,\n DepositAndDeployRouteDefinition,\n} from './types';\n\n/**\n * The default config for DepositAndDeploy\n * Currently only EVM (Avalanche + Silo) is supported\n */\nexport const depositAndDeployConfig: DepositAndDeployChainConfig =\n evmDepositAndDeployConfig;\n\n/**\n * Check if a destination chain is supported for deposit and deploy\n */\nexport function isDestChainSupported(destChain: Chain): boolean {\n return depositAndDeployConfig.destChains.includes(destChain);\n}\n\n/**\n * Check if assetOut is supported for DepositAndDeploy\n * DepositAndDeploy should only produce BTC.b\n */\nexport function isAssetOutSupported(assetOut: AssetId): boolean {\n return depositAndDeployConfig.supportedAssetsOut.includes(assetOut);\n}\n\n/**\n * Check if a protocol is supported for deposit and deploy\n * Uses DEFI_REGISTRY as the single source of truth\n */\nexport function isProtocolSupported(protocol: string): boolean {\n // Check if protocol exists in DEFI_REGISTRY\n return protocol in DEFI_REGISTRY;\n}\n\n/**\n * Get the vault key for a protocol\n * Returns the protocol key if valid, throws if not supported\n *\n * @param protocol - Protocol identifier from DefiProtocol\n * @returns The vault key for API calls\n * @throws If protocol is not in DEFI_REGISTRY\n */\nexport function getVaultKey(protocol: string): string {\n if (!isProtocolSupported(protocol)) {\n const supportedProtocols = Object.keys(DEFI_REGISTRY).join(', ');\n throw new Error(\n `Unsupported protocol: ${protocol}. ` +\n `Supported protocols: ${supportedProtocols}`,\n );\n }\n // Protocol keys in DEFI_REGISTRY match DefiProtocol values\n return protocol;\n}\n\n/**\n * Get list of supported protocols for DepositAndDeploy\n * This returns protocols that support BTC.b (for DepositAndDeploy)\n */\nexport function getSupportedProtocols(assetId: AssetId): DefiProtocol[] {\n return Object.entries(DEFI_REGISTRY)\n .filter(([_, tokenMap]) => assetId in tokenMap)\n .map(([protocol]) => protocol as DefiProtocol);\n}\n/**\n * Check if a route is available for a given source chain and environment\n */\nexport function isRouteAvailable(sourceChain: Chain, env: Env): boolean {\n return depositAndDeployConfig.routes.some(\n route =>\n route.sourceChains.includes(sourceChain) && route.envs.includes(env),\n );\n}\n\n/**\n * Check if a protocol supports a specific chain for deposit and deploy\n */\nexport function isProtocolChainSupported(\n protocol: string,\n chainId: number,\n env: Env,\n): boolean {\n const protocolRegistry = DEFI_REGISTRY[protocol as DefiProtocol];\n if (!protocolRegistry) return false;\n\n // Check BTCb token (used by DepositAndDeploy)\n const btcbRegistry =\n protocolRegistry['BTCb' as keyof typeof protocolRegistry];\n if (!btcbRegistry) return false;\n\n const envRegistry = btcbRegistry[env];\n if (!envRegistry) return false;\n\n return chainId in envRegistry;\n}\n","/**\n * BTC DepositAndDeploy Action\n *\n * Handles BTC → BTC.b → Vault deposit in a single atomic operation.\n * Similar to StakeAndDeploy but produces BTC.b instead of LBTC.\n * Used for protocols like Silo on Avalanche that accept BTC.b.\n *\n * @module chains/btc/actions/depositAndDeploy/BtcDepositAndDeploy\n */\n\nimport type { z } from 'zod';\n\nimport type { ChainId } from '../../../../common/chains';\nimport { isValidChain } from '../../../../common/chains';\nimport { Chain, parseChainIdentifier,StepStatus } from '../../../../core';\nimport type { BtcCoreContext } from '../../../../shared/context';\nimport { LombardError, ValidationErrorCode } from '../../../../shared/errors';\nimport type { DepositAndDeployEventMap } from '../../../../shared/events';\nimport {\n monitorDeposit,\n type MonitorProgress,\n} from '../../../../shared/monitoring';\nimport { Token } from '../../../../tokens/token-addresses';\nimport { ensureNotSanctionedAddress } from '../../../../utils/ensureNotSanctionedAddress';\nimport { toSatoshi } from '../../../../utils/satoshi';\nimport {\n assetIdToToken,\n BaseBtcAction,\n type StatusConfig,\n type StepDefinition,\n} from '../shared';\nimport {\n depositAndDeployConfig,\n getVaultKey,\n isAssetOutSupported,\n isDestChainSupported,\n isProtocolSupported,\n isRouteAvailable,\n} from './config';\nimport {\n BtcActionStatus,\n type BtcDepositAndDeploy as IBtcDepositAndDeploy,\n type BtcDepositAndDeployParams,\n type BtcDepositAndDeployPrepareParams,\n} from './types';\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Types\n// ═══════════════════════════════════════════════════════════════════════════\n\ninterface AuthState {\n fee?: string;\n signature?: string;\n typedData?: string;\n approvalTxHash?: string;\n authorized: boolean;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// BtcDepositAndDeploy Implementation\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * BTC DepositAndDeploy Action\n *\n * Combines deposit (BTC → BTC.b) and vault deployment in a single atomic operation.\n *\n * @example\n * ```typescript\n * const depositAndDeploy = new BtcDepositAndDeploy(ctx, {\n * assetOut: AssetId.BTCb,\n * destChain: Chain.AVALANCHE,\n * protocol: DeployProtocol.Silo,\n * });\n *\n * await depositAndDeploy.prepare({ amount: '0.1', recipient: '0x...' });\n * await depositAndDeploy.authorizeDeposit();\n * const address = await depositAndDeploy.generateDepositAddress();\n * ```\n */\nexport class BtcDepositAndDeploy\n extends BaseBtcAction<\n DepositAndDeployEventMap,\n BtcActionStatus,\n BtcDepositAndDeployParams\n >\n implements IBtcDepositAndDeploy\n{\n private readonly chainId: ChainId;\n private readonly authState: AuthState = { authorized: false };\n\n constructor(ctx: BtcCoreContext, params: BtcDepositAndDeployParams) {\n super(ctx, params, BtcActionStatus.IDLE);\n\n // Validate assetOut - DepositAndDeploy should only produce BTC.b\n if (!isAssetOutSupported(params.assetOut)) {\n throw new LombardError(\n ValidationErrorCode.INVALID_ASSET,\n `Asset ${params.assetOut} is not supported for deposit and deploy. ` +\n `DepositAndDeploy produces BTC.b which is then deployed to a vault like Silo.`,\n );\n }\n\n if (!isDestChainSupported(params.destChain)) {\n throw new LombardError(\n ValidationErrorCode.INVALID_CHAIN,\n `Destination chain ${params.destChain} is not supported for deposit and deploy. ` +\n `Supported chains: Avalanche, Avalanche Fuji`,\n );\n }\n\n if (!isProtocolSupported(params.protocol)) {\n throw new LombardError(\n ValidationErrorCode.INVALID_PARAMETER,\n `Protocol ${params.protocol} is not supported for deposit and deploy. ` +\n `DepositAndDeploy with BTC.b only supports Silo protocol.`,\n );\n }\n\n const sourceChain = params.sourceChain ?? Chain.BITCOIN_MAINNET;\n if (!isRouteAvailable(sourceChain, ctx.env)) {\n throw LombardError.routeNotFound({\n assetOut: params.assetOut,\n sourceChain,\n destChain: params.destChain,\n env: ctx.env,\n });\n }\n\n const parsed = parseChainIdentifier(params.destChain);\n if (typeof parsed !== 'number' || !isValidChain(parsed)) {\n throw new LombardError(\n ValidationErrorCode.INVALID_CHAIN,\n `Unsupported EVM chain: ${params.destChain}`,\n );\n }\n\n this.chainId = parsed as ChainId;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Abstract Method Implementations\n // ─────────────────────────────────────────────────────────────────────────\n\n protected getAddressSchema(): z.ZodType<string> {\n return depositAndDeployConfig.addressSchema;\n }\n\n protected getStatusConfig(): StatusConfig<BtcActionStatus> {\n return {\n idle: BtcActionStatus.IDLE,\n ready: BtcActionStatus.READY,\n addressReady: BtcActionStatus.ADDRESS_READY,\n };\n }\n\n protected getInitialSteps(): StepDefinition {\n return {\n created: StepStatus.IDLE,\n verifying: StepStatus.IDLE,\n wrapping: StepStatus.IDLE,\n depositing: StepStatus.IDLE,\n };\n }\n\n protected isAuthorized(): boolean {\n return this.authState.authorized;\n }\n\n protected getChainId(): ChainId {\n return this.chainId;\n }\n\n protected getDepositAddressParams(captchaToken?: string) {\n const recipient = this.ensureRecipient();\n return {\n address: recipient,\n chainId: this.chainId,\n signature: this.authState.signature!,\n token: this.getExpectedToken(),\n // Deposit and deploy uses signatureData (maps to sb_signature_data), not eip712Data\n signatureData: this.authState.typedData,\n partnerId: this.ctx.partner.getPartnerId(),\n referrerCode: this._referralCode,\n captchaToken,\n };\n }\n\n /**\n * Get expected token for this action (BTCb by default for DepositAndDeploy)\n */\n protected getExpectedToken(): string {\n return assetIdToToken(this.params.assetOut, Token.BTCb);\n }\n\n protected getAuthRequiredMessage(): string {\n return 'Deposit authorization required. Call authorizeDeposit() first.';\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Public Getters\n // ─────────────────────────────────────────────────────────────────────────\n\n /** Get deposit and deploy fee (available after prepare()) */\n get fee(): string | undefined {\n return this.authState.fee;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Public Methods\n // ─────────────────────────────────────────────────────────────────────────\n\n async prepare(params: BtcDepositAndDeployPrepareParams): Promise<void> {\n this.assertStatus(BtcActionStatus.IDLE, 'prepare');\n\n return this.act(async () => {\n const validated = this.validatePrepareParams(params);\n\n this._amount = validated.amount;\n this._recipient = validated.recipient;\n this._referralCode = validated.referralCode;\n\n // Get fee for deposit and deploy (uses config's getVaultKey for validation)\n this.authState.fee = await depositAndDeployConfig.getDepositAndDeployFee(\n this.ctx,\n this.chainId,\n getVaultKey(this.params.protocol),\n );\n\n this.updateStatus(BtcActionStatus.NEEDS_DEPLOY_AUTHORIZATION);\n this.emitInitialProgress();\n }, BtcActionStatus.NEEDS_DEPLOY_AUTHORIZATION);\n }\n\n async authorizeDeposit(): Promise<void> {\n this.assertStatus(\n [BtcActionStatus.NEEDS_DEPLOY_AUTHORIZATION, BtcActionStatus.READY],\n 'authorizeDeposit',\n );\n\n if (this.status === BtcActionStatus.READY) return;\n\n const recipient = this.ensureRecipient();\n const amount = this.ensureAmount();\n\n return this.act(async () => {\n const amountSats = toSatoshi(amount);\n\n // For BTC → BTC.b deposit and deploy, use the output token (BTCb).\n // Unlike LBTC which has a variable ratio with BTC, BTC.b is 1:1 with BTC\n // so no ratio conversion is needed (amountStrategy: 'identity').\n // Using assetIdToToken ensures we use the correct token for the permit.\n const outputToken = assetIdToToken(this.params.assetOut, Token.BTCb);\n\n const result = await depositAndDeployConfig.authorizeDepositAndDeploy(\n this.ctx,\n {\n chainId: this.chainId,\n recipient,\n amount: amountSats.toString(),\n vaultKey: getVaultKey(this.params.protocol),\n token: outputToken,\n },\n );\n\n this.authState.signature = result.signature;\n this.authState.typedData = result.typedData;\n this.authState.authorized = true;\n }, BtcActionStatus.READY);\n }\n\n async generateDepositAddress(captchaToken?: string): Promise<string> {\n this.assertStatus(BtcActionStatus.READY, 'generateDepositAddress');\n this.ensureAuthorized();\n\n if (this._depositAddress) {\n return this._depositAddress;\n }\n\n return this.act(async () => {\n const apiParams = this.getDepositAddressParams(captchaToken);\n const depositAddress =\n await this.ctx.api.generateDepositAddress(apiParams);\n\n ensureNotSanctionedAddress(depositAddress);\n this._depositAddress = depositAddress;\n\n this.emitProgress({\n status: BtcActionStatus.ADDRESS_READY,\n steps: {\n created: StepStatus.COMPLETE,\n verifying: StepStatus.IDLE,\n wrapping: StepStatus.IDLE,\n depositing: StepStatus.IDLE,\n },\n metadata: { depositAddress },\n });\n\n return depositAddress;\n }, BtcActionStatus.ADDRESS_READY);\n }\n\n async execute(): Promise<{ depositAddress: string; txHash?: string }> {\n return this.act(async () => {\n this.assertStatus(BtcActionStatus.ADDRESS_READY, 'execute');\n\n if (!this._depositAddress) {\n await this.generateDepositAddress();\n }\n\n const depositAddress = this.ensureDepositAddress();\n const txHash = await this.trySendBitcoin(depositAddress);\n\n return txHash ? { depositAddress, txHash } : { depositAddress };\n });\n }\n\n // Custom monitorDeposit with different step names\n async monitorDeposit(): Promise<MonitorProgress | undefined> {\n const depositAddress = this._depositAddress;\n const recipient = this._recipient;\n\n if (!depositAddress || !recipient) {\n throw LombardError.missingParameter('depositAddress or recipient');\n }\n\n const progress = await monitorDeposit({\n network: this.bitcoinNetwork,\n btcService: this.ctx.btc,\n fetchDeposit: async () => {\n const deposits = await this.ctx.api.getDeposits(recipient);\n const ourDeposit = deposits.find(\n deposit => deposit.depositAddress === depositAddress,\n );\n\n if (!ourDeposit) {\n return undefined;\n }\n\n return {\n blockHeight: ourDeposit.blockHeight,\n isClaimed: ourDeposit.isClaimed,\n };\n },\n onProgress: p => {\n this.emitProgress({\n status: this.status,\n steps: {\n created: StepStatus.COMPLETE,\n verifying: p.hasEnoughConfirmations\n ? StepStatus.COMPLETE\n : StepStatus.PENDING,\n wrapping: p.isClaimed ? StepStatus.COMPLETE : StepStatus.PENDING,\n depositing: StepStatus.PENDING,\n },\n confirmations: p.confirmations,\n requiredConfirmations: p.requiredConfirmations,\n metadata: { isClaimed: p.isClaimed },\n });\n },\n onComplete: () => {\n this.emitCompleted();\n },\n });\n\n return progress;\n }\n}\n","/**\n * Chain Utility Functions\n *\n * Provides type-safe utilities for working with Chain enum values.\n * Handles parsing and validation of CAIP-2 chain identifiers.\n *\n * @module utils/chain\n */\n\nimport { CAIP2_SEPARATOR, Chain,CHAIN_PREFIXES } from '../core';\nimport { LombardError, ValidationErrorCode } from '../shared/errors';\n\n/** Helper to get prefix with separator */\nconst withSeparator = (prefix: string) => `${prefix}${CAIP2_SEPARATOR}`;\n\n/**\n * Parse EVM chain ID from Chain enum\n *\n * Extracts the numeric chain ID from an EVM chain identifier.\n *\n * @param chain - Chain enum value\n * @returns Numeric EVM chain ID\n * @throws {ValidationError} If chain is not an EVM chain\n *\n * @example\n * ```typescript\n * parseEvmChainId(Chain.ETHEREUM) // 1\n * parseEvmChainId(Chain.BASE) // 8453\n * parseEvmChainId(Chain.BITCOIN_MAINNET) // throws ValidationError\n * ```\n */\nexport function parseEvmChainId(chain: Chain): number {\n const chainStr = String(chain);\n const evmPrefix = withSeparator(CHAIN_PREFIXES.EIP155);\n const isEvm = chainStr.startsWith(evmPrefix);\n\n if (!isEvm) {\n throw new LombardError(\n ValidationErrorCode.INVALID_PARAMETER,\n `Not an EVM chain: ${chainStr}`,\n );\n }\n\n const chainId = Number.parseInt(chainStr.slice(evmPrefix.length), 10);\n\n if (Number.isNaN(chainId)) {\n throw new LombardError(\n ValidationErrorCode.INVALID_PARAMETER,\n `Invalid EVM chain ID: ${chainStr}`,\n );\n }\n\n return chainId;\n}\n\n/**\n * Check if chain is an EVM chain\n *\n * @param chain - Chain enum value\n * @returns True if chain is an EVM chain\n *\n * @example\n * ```typescript\n * isEvmChain(Chain.ETHEREUM) // true\n * isEvmChain(Chain.BITCOIN_MAINNET) // false\n * ```\n */\nexport function isEvmChain(chain: Chain): boolean {\n return String(chain).startsWith(withSeparator(CHAIN_PREFIXES.EIP155));\n}\n\n/**\n * Check if chain is a Bitcoin chain\n *\n * @param chain - Chain enum value\n * @returns True if chain is a Bitcoin chain\n *\n * @example\n * ```typescript\n * isBitcoinChain(Chain.BITCOIN_MAINNET) // true\n * isBitcoinChain(Chain.ETHEREUM) // false\n * ```\n */\nexport function isBitcoinChain(chain: Chain): boolean {\n return String(chain).startsWith(withSeparator(CHAIN_PREFIXES.BIP122));\n}\n\n/**\n * Check if chain is a Solana chain\n *\n * @param chain - Chain enum value\n * @returns True if chain is a Solana chain\n *\n * @example\n * ```typescript\n * isSolanaChain(Chain.SOLANA_MAINNET) // true\n * isSolanaChain(Chain.ETHEREUM) // false\n * ```\n */\nexport function isSolanaChain(chain: Chain): boolean {\n return String(chain).startsWith(withSeparator(CHAIN_PREFIXES.SOLANA));\n}\n\n/**\n * Check if chain is a Sui chain\n *\n * @param chain - Chain enum value\n * @returns True if chain is a Sui chain\n *\n * @example\n * ```typescript\n * isSuiChain(Chain.SUI_MAINNET) // true\n * isSuiChain(Chain.ETHEREUM) // false\n * ```\n */\nexport function isSuiChain(chain: Chain): boolean {\n return String(chain).startsWith(withSeparator(CHAIN_PREFIXES.SUI));\n}\n\n/**\n * Check if chain is a Starknet chain\n *\n * @param chain - Chain enum value\n * @returns True if chain is a Starknet chain\n *\n * @example\n * ```typescript\n * isStarknetChain(Chain.STARKNET_MAINNET) // true\n * isStarknetChain(Chain.ETHEREUM) // false\n * ```\n */\nexport function isStarknetChain(chain: Chain): boolean {\n return String(chain).startsWith(withSeparator(CHAIN_PREFIXES.STARKNET));\n}\n\n/**\n * Get chain namespace from Chain enum\n *\n * Returns the CAIP-2 namespace prefix (eip155, bip122, solana, etc.)\n *\n * @param chain - Chain enum value\n * @returns CAIP-2 namespace string\n *\n * @example\n * ```typescript\n * getChainNamespace(Chain.ETHEREUM) // 'eip155'\n * getChainNamespace(Chain.BITCOIN_MAINNET) // 'bip122'\n * ```\n */\nexport function getChainNamespace(chain: Chain): string {\n return String(chain).split(CAIP2_SEPARATOR)[0];\n}\n","/**\n * EVM Chain Configuration\n *\n * Handles all EVM-compatible destination chains (Ethereum, Base, Arbitrum, etc.)\n * Includes fee authorization for Ethereum mainnet and destination signing for others.\n *\n * Supported chains are derived from ASSET_CATALOG - single source of truth.\n *\n * @module chains/btc/actions/stake/config/evm\n */\n\nimport type { EvmService } from '@lombard.finance/sdk-common';\nimport { Env } from '@lombard.finance/sdk-common';\nimport type { EIP1193Provider } from 'viem';\n\nimport type { ChainId } from '../../../../../common/chains';\nimport { AssetId, Chain, getAllAssetChains } from '../../../../../core';\nimport { LombardError } from '../../../../../shared/errors';\nimport { ensureCorrectChain } from '../../../../../shared/evm/switchChain';\nimport { evmAddressSchema } from '../../../../../shared/validation';\nimport { Token } from '../../../../../tokens/token-addresses';\nimport { getTokenContractInfo } from '../../../../../tokens/tokens';\nimport { isEvmChain } from '../../../../../utils/chain';\nimport { toSatoshi } from '../../../../../utils/satoshi';\nimport type { ChainConfig, FeeAuthConfig } from './types';\n\n/**\n * Chains that require fee authorization (unsubsidized chains).\n * \n * These chains require users to sign a fee authorization message\n * before minting LBTC. On subsidized chains, Lombard covers the fees.\n */\nconst UNSUBSIDIZED_CHAINS = [Chain.ETHEREUM, Chain.SEPOLIA] as const;\n\n/**\n * Fee authorization config for unsubsidized chains.\n *\n * Ethereum mainnet and Sepolia require fee authorization.\n * All methods access EvmService via capabilities.\n *\n * BTC Stake produces LBTC, so we use Token.LBTC for fee signatures.\n * This ensures the backend can distinguish between LBTC and BTC.b signatures.\n */\nconst feeAuthConfig: FeeAuthConfig = {\n async getMintingFee(ctx, chainId) {\n const evm = ctx.capabilities.require('evm') as EvmService;\n return evm.getMintingFee(chainId as ChainId);\n },\n\n async restoreFeeSignature(ctx, chainId, address) {\n // Get LBTC token address for this chain to distinguish from BTC.b signatures\n const tokenInfo = await getTokenContractInfo(\n Token.LBTC,\n chainId as ChainId,\n ctx.env,\n );\n\n const result = await ctx.api.getFeeSignature({\n address,\n chainId: chainId as ChainId,\n tokenAddress: tokenInfo.address,\n });\n\n // Check if signature exists on server (API returns has_signature flag)\n if (!result.hasSignature) {\n return null;\n }\n\n // Check expiration - expirationDate is Unix timestamp in seconds\n // Convert to milliseconds for Date comparison\n if (result.expirationDate && new Date(Number(result.expirationDate) * 1000) < new Date()) {\n return null;\n }\n\n // Return hasSignature: true even if actual signature string is not returned by API\n // The server has the signature stored; we just need to know it's valid\n return {\n hasSignature: true,\n signature: result.signature, // May be undefined - that's OK\n typedData: result.typedData,\n };\n },\n\n async authorizeFee(ctx, { chainId, recipient, fee }) {\n const evm = ctx.capabilities.require('evm') as EvmService;\n const provider = await ctx.getProvider('evm');\n if (!provider) {\n throw LombardError.providerMissing(String(chainId), 'evm');\n }\n\n // Ensure wallet is on the correct chain before signing\n await ensureCorrectChain(provider as EIP1193Provider, chainId as ChainId);\n\n // getMintingFee returns BTC (e.g., \"0.00000032\"), but signNetworkFee expects satoshis\n const feeInSatoshis = toSatoshi(fee).toString();\n\n // Get LBTC token info for this chain\n const tokenInfo = await getTokenContractInfo(\n Token.LBTC,\n chainId as ChainId,\n ctx.env,\n );\n\n // Sign the network fee with LBTC token (explicitly specified)\n const result = await evm.signNetworkFee({\n fee: feeInSatoshis,\n account: recipient,\n chainId: chainId as ChainId,\n provider: provider as EIP1193Provider,\n token: Token.LBTC,\n });\n\n // Store the signature with token address to distinguish from BTC.b signatures\n await ctx.api.storeFeeSignature({\n address: recipient,\n signature: result.signature,\n typedData: result.typedData,\n tokenAddress: tokenInfo.address,\n });\n\n return {\n signature: result.signature,\n typedData: result.typedData,\n };\n },\n};\n\n/**\n * EVM chain configuration for BTC stake\n *\n * BTC Stake: BTC → LBTC (yield-bearing staked BTC)\n * Supports staking BTC to LBTC on any EVM-compatible chain.\n * Supported chains are derived from ASSET_CATALOG[AssetId.LBTC].deployments.\n */\nexport const evmConfig: ChainConfig = {\n chainType: 'evm',\n\n routes: [\n {\n sourceChains: [Chain.BITCOIN_MAINNET],\n envs: [Env.prod],\n },\n {\n sourceChains: [Chain.BITCOIN_SIGNET],\n envs: [Env.testnet, Env.stage, Env.dev, Env.ibc],\n },\n ],\n\n // Derived from ASSET_CATALOG - all EVM chains where LBTC is deployed\n // Note: This includes all chains across all environments\n // The `routes` config above filters by source chain + env\n destChains: getAllAssetChains(AssetId.LBTC).filter(chain => {\n return isEvmChain(chain);\n }),\n\n // BTC Stake only produces LBTC\n supportedAssetsOut: [AssetId.LBTC],\n\n addressSchema: evmAddressSchema,\n\n getFeeAuthConfig(destChain) {\n // Unsubsidized chains require fee authorization\n return (UNSUBSIDIZED_CHAINS as readonly Chain[]).includes(destChain)\n ? feeAuthConfig\n : null;\n },\n\n async getSignature(ctx, recipient, chainId) {\n const evm = ctx.capabilities.require('evm') as EvmService;\n const provider = await ctx.getProvider('evm');\n if (!provider) {\n throw LombardError.providerMissing(String(chainId), 'evm');\n }\n\n // Ensure wallet is on the correct chain before signing\n await ensureCorrectChain(provider as EIP1193Provider, chainId as ChainId);\n\n return evm.signLbtcDestination({\n chainId: chainId as ChainId,\n address: recipient,\n provider: provider as EIP1193Provider,\n });\n },\n};\n","/**\n * Solana Chain Configuration\n *\n * Handles Solana destination chains (mainnet and devnet).\n * Uses Solana wallet signing via the Solana SDK module.\n *\n * BTC Stake: BTC → LBTC (yield-bearing staked BTC)\n * Supported chains derived from ASSET_CATALOG.\n *\n * @module chains/btc/actions/stake/config/solana\n */\n\nimport type { SolanaService } from '@lombard.finance/sdk-common';\nimport { Env } from '@lombard.finance/sdk-common';\n\nimport { AssetId, Chain, getAllAssetChains } from '../../../../../core';\nimport { LombardError, ValidationErrorCode } from '../../../../../shared/errors';\nimport { solanaAddressSchema } from '../../../../../shared/validation';\nimport { isSolanaChain } from '../../../../../utils/chain';\nimport type { ChainConfig } from './types';\n\n/**\n * Map CAIP-2 Solana chain identifier to SolanaNetwork format.\n * \n * The Solana SDK's signLbtcDestination expects network names like 'devnet', 'mainnet-beta',\n * but the SDK uses CAIP-2 chain identifiers with genesis hash references.\n * \n * @param chainId - CAIP-2 chain identifier (e.g., 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1')\n * @returns SolanaNetwork format (e.g., 'devnet')\n */\nfunction chainToSolanaNetwork(chainId: string): string {\n // Map from CAIP-2 genesis hash references to SolanaNetwork names\n const CHAIN_TO_NETWORK: Record<string, string> = {\n // CAIP-2 format using genesis hash\n [Chain.SOLANA_MAINNET]: 'mainnet-beta',\n [Chain.SOLANA_DEVNET]: 'devnet',\n [Chain.SOLANA_TESTNET]: 'testnet',\n // Legacy format (solana:network-name)\n 'solana:mainnet-beta': 'mainnet-beta',\n 'solana:devnet': 'devnet',\n 'solana:testnet': 'testnet',\n };\n\n const network = CHAIN_TO_NETWORK[chainId];\n if (!network) {\n throw new LombardError(\n ValidationErrorCode.INVALID_CHAIN,\n `Unknown Solana chain: ${chainId}. Expected one of: ${Object.keys(CHAIN_TO_NETWORK).join(', ')}`,\n );\n }\n return network;\n}\n\n/**\n * Solana chain configuration for BTC stake\n *\n * Supports staking BTC to LBTC on Solana.\n * Requires the @lombard.finance/sdk-solana module to be installed.\n */\nexport const solanaConfig: ChainConfig = {\n chainType: 'solana',\n\n routes: [\n {\n sourceChains: [Chain.BITCOIN_MAINNET],\n envs: [Env.prod],\n },\n {\n sourceChains: [Chain.BITCOIN_SIGNET],\n envs: [Env.testnet, Env.stage, Env.dev, Env.ibc],\n },\n ],\n\n // Derived from ASSET_CATALOG - Solana chains where LBTC is deployed\n destChains: getAllAssetChains(AssetId.LBTC).filter(chain =>\n isSolanaChain(chain),\n ),\n\n // BTC Stake only produces LBTC\n supportedAssetsOut: [AssetId.LBTC],\n\n addressSchema: solanaAddressSchema,\n\n // Solana never requires fee authorization\n getFeeAuthConfig: () => null,\n\n async getSignature(ctx, _recipient, chainId) {\n const solana = ctx.capabilities.require('solana') as SolanaService;\n // Convert CAIP-2 chain ID to SolanaNetwork format (e.g., 'devnet')\n const network = chainToSolanaNetwork(chainId as string);\n const { signature } = await solana.signLbtcDestination({\n network,\n });\n\n return { signature };\n },\n};\n","/**\n * Starknet Chain Configuration\n *\n * Handles Starknet destination chains (mainnet and Sepolia).\n * Uses Starknet wallet signing via the Starknet SDK module.\n * Note: Starknet requires address padding and returns a public key.\n *\n * BTC Stake: BTC → LBTC (yield-bearing staked BTC)\n * Supported chains derived from ASSET_CATALOG.\n *\n * @module chains/btc/actions/stake/config/starknet\n */\n\nimport type { StarknetService } from '@lombard.finance/sdk-common';\nimport { Env } from '@lombard.finance/sdk-common';\nimport { pad } from 'viem';\n\nimport { AssetId, Chain, getAllAssetChains } from '../../../../../core';\nimport { starknetAddressSchema } from '../../../../../shared/validation';\nimport { isStarknetChain } from '../../../../../utils/chain';\nimport type { ChainConfig } from './types';\n\n/**\n * Starknet chain configuration for BTC stake\n *\n * Supports staking BTC to LBTC on Starknet.\n * Requires the @lombard.finance/sdk-starknet module to be installed.\n */\nexport const starknetConfig: ChainConfig = {\n chainType: 'starknet',\n\n routes: [\n {\n sourceChains: [Chain.BITCOIN_MAINNET],\n envs: [Env.prod],\n },\n {\n sourceChains: [Chain.BITCOIN_SIGNET],\n envs: [Env.testnet, Env.stage, Env.dev, Env.ibc],\n },\n ],\n\n // Derived from ASSET_CATALOG - Starknet chains where LBTC is deployed\n destChains: getAllAssetChains(AssetId.LBTC).filter(chain =>\n isStarknetChain(chain),\n ),\n\n // BTC Stake only produces LBTC\n supportedAssetsOut: [AssetId.LBTC],\n\n addressSchema: starknetAddressSchema,\n\n // Starknet never requires fee authorization\n getFeeAuthConfig: () => null,\n\n async getSignature(ctx, recipient, chainId) {\n const starknet = ctx.capabilities.require('starknet') as StarknetService;\n const { signature, pubKey } = await starknet.signLbtcDestination({\n chainId: chainId as string,\n });\n\n // Starknet addresses need to be padded to 32 bytes\n const paddedAddress = pad(recipient as `0x${string}`, { size: 32 });\n\n return { signature, pubKey, paddedAddress };\n },\n};\n","/**\n * Sui Chain Configuration\n *\n * Handles Sui destination chains (mainnet and testnet).\n * Uses Sui wallet signing via the Sui SDK module.\n *\n * BTC Stake: BTC → LBTC (yield-bearing staked BTC)\n * Supported chains derived from ASSET_CATALOG.\n *\n * @module chains/btc/actions/stake/config/sui\n */\n\nimport type { SuiService } from '@lombard.finance/sdk-common';\nimport { Env } from '@lombard.finance/sdk-common';\n\nimport { AssetId, Chain, getAllAssetChains } from '../../../../../core';\nimport { suiAddressSchema } from '../../../../../shared/validation';\nimport { isSuiChain } from '../../../../../utils/chain';\nimport type { ChainConfig } from './types';\n\n/**\n * Sui chain configuration for BTC stake\n *\n * Supports staking BTC to LBTC on Sui.\n * Requires the @lombard.finance/sdk-sui module to be installed.\n */\nexport const suiConfig: ChainConfig = {\n chainType: 'sui',\n\n routes: [\n {\n sourceChains: [Chain.BITCOIN_MAINNET],\n envs: [Env.prod],\n },\n {\n sourceChains: [Chain.BITCOIN_SIGNET],\n envs: [Env.testnet, Env.stage, Env.dev, Env.ibc],\n },\n ],\n\n // Derived from ASSET_CATALOG - Sui chains where LBTC is deployed\n destChains: getAllAssetChains(AssetId.LBTC).filter(chain =>\n isSuiChain(chain),\n ),\n\n // BTC Stake only produces LBTC\n supportedAssetsOut: [AssetId.LBTC],\n\n addressSchema: suiAddressSchema,\n\n // Sui never requires fee authorization\n getFeeAuthConfig: () => null,\n\n async getSignature(ctx, _recipient, chainId) {\n const sui = ctx.capabilities.require('sui') as SuiService;\n const { signature } = await sui.signLbtcDestination({\n chainId: chainId as string,\n });\n\n return { signature };\n },\n};\n","/**\n * Chain Configuration Registry\n *\n * Exports all chain configurations and provides registry lookup functions.\n *\n * BTC Stake: BTC → LBTC (yield-bearing staked BTC)\n *\n * @module chains/btc/actions/stake/config\n */\n\nimport type { Env } from '@lombard.finance/sdk-common';\n\nimport type { AssetId, Chain, ChainType } from '../../../../../core';\nimport { evmConfig } from './evm';\nimport { solanaConfig } from './solana';\nimport { starknetConfig } from './starknet';\nimport { suiConfig } from './sui';\nimport type { ChainConfig } from './types';\n\n// Re-export types\nexport type {\n ChainConfig,\n FeeAuthConfig,\n FeeAuthResult,\n RouteDefinition,\n SignatureResult,\n StoredFeeSignature,\n} from './types';\n\n// Re-export individual configs\nexport { evmConfig } from './evm';\nexport { solanaConfig } from './solana';\nexport { starknetConfig } from './starknet';\nexport { suiConfig } from './sui';\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Registry\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Registry of all chain configurations\n *\n * Add new chain types here to support additional destination chains.\n * The key must match the ChainType from the chain catalog.\n */\nexport const chainConfigs: Partial<Record<ChainType, ChainConfig>> = {\n evm: evmConfig,\n solana: solanaConfig,\n sui: suiConfig,\n starknet: starknetConfig,\n};\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Lookup Functions\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Get chain configuration by chain type\n *\n * @param chainType - The chain type from getChainType()\n * @returns ChainConfig or undefined if not supported\n */\nexport function getChainConfig(chainType: ChainType): ChainConfig | undefined {\n return chainConfigs[chainType];\n}\n\n/**\n * Check if a chain type is supported for BTC staking\n *\n * @param chainType - The chain type to check\n * @returns true if supported\n */\nexport function isChainTypeSupported(chainType: ChainType): boolean {\n return chainType in chainConfigs;\n}\n\n/**\n * Check if a specific route is available\n *\n * @param config - Chain configuration\n * @param sourceChain - Source chain (Bitcoin network)\n * @param env - Environment\n * @returns true if route is available\n */\nexport function isRouteAvailable(\n config: ChainConfig,\n sourceChain: Chain | undefined,\n env: Env,\n): boolean {\n if (!sourceChain) return true; // No source chain specified, allow all\n\n return config.routes.some(\n route =>\n route.sourceChains.includes(sourceChain) && route.envs.includes(env),\n );\n}\n\n/**\n * Check if a destination chain is supported by a config\n *\n * @param config - Chain configuration\n * @param destChain - Destination chain\n * @returns true if destination chain is supported\n */\nexport function isDestChainSupported(\n config: ChainConfig,\n destChain: Chain,\n): boolean {\n return config.destChains.includes(destChain);\n}\n\n/**\n * Check if an output asset is supported by a config\n *\n * @param config - Chain configuration\n * @param assetOut - Output asset\n * @returns true if output asset is supported\n */\nexport function isAssetOutSupported(\n config: ChainConfig,\n assetOut: AssetId,\n): boolean {\n return config.supportedAssetsOut.includes(assetOut);\n}\n","/**\n * BTC Stake Action\n *\n * A configuration-driven action that handles BTC → LBTC staking\n * to any supported destination chain. Chain-specific logic is delegated\n * to ChainConfig objects in the config/ folder.\n *\n * @module chains/btc/actions/stake/BtcStake\n */\n\nimport type { z } from 'zod';\n\nimport type {\n ChainId,\n SolanaChain,\n StarknetChainId,\n SuiChain,\n} from '../../../../common/chains';\nimport {\n getChainType,\n parseChainIdentifier,\n StepStatus,\n} from '../../../../core';\nimport { BtcActionStatus } from '../../../../shared/constants/statusConstants';\nimport type { BtcCoreContext } from '../../../../shared/context';\nimport { LombardError, ValidationErrorCode } from '../../../../shared/errors';\nimport type { StakeEventMap } from '../../../../shared/events';\nimport type { MonitorProgress } from '../../../../shared/monitoring';\nimport { Token } from '../../../../tokens/token-addresses';\nimport { ensureNotSanctionedAddress } from '../../../../utils/ensureNotSanctionedAddress';\nimport {\n assetIdToToken,\n BaseBtcAction,\n type StatusConfig,\n type StepDefinition,\n} from '../shared';\nimport {\n type ChainConfig,\n type FeeAuthConfig,\n getChainConfig,\n isAssetOutSupported,\n isDestChainSupported,\n isRouteAvailable,\n type SignatureResult,\n} from './config';\nimport type { BtcStake as IBtcStake,BtcStakeParams } from './types';\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Types\n// ═══════════════════════════════════════════════════════════════════════════\n\ntype AnyChainId = ChainId | SolanaChain | SuiChain | StarknetChainId;\n\ninterface AuthorizationState {\n mintingFee?: string;\n networkFee?: {\n signature: string;\n typedData?: string;\n };\n destinationSignature?: SignatureResult;\n authorized: boolean;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// BtcStake Implementation\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * BTC Stake Action\n *\n * Handles BTC → LBTC staking to any supported destination chain.\n * Uses configuration-driven design for chain-specific logic.\n *\n * @example\n * ```typescript\n * const stake = new BtcStake(ctx, {\n * assetOut: AssetId.LBTC,\n * destChain: Chain.ETHEREUM,\n * });\n *\n * await stake.prepare({ amount: '0.1', recipient: '0x...' });\n * await stake.authorize();\n * const address = await stake.generateDepositAddress();\n * ```\n */\nexport class BtcStake\n extends BaseBtcAction<StakeEventMap, BtcActionStatus, BtcStakeParams>\n implements IBtcStake\n{\n private readonly config: ChainConfig;\n private readonly chainId: AnyChainId;\n private readonly authState: AuthorizationState = { authorized: false };\n\n /** Fee auth config - null if not required for this destination */\n private feeAuthConfig: FeeAuthConfig | null = null;\n\n constructor(ctx: BtcCoreContext, params: BtcStakeParams) {\n super(ctx, params, BtcActionStatus.IDLE);\n\n const chainType = getChainType(params.destChain);\n const config = getChainConfig(chainType);\n\n if (!config) {\n throw new LombardError(\n ValidationErrorCode.INVALID_CHAIN,\n `Unsupported destination chain type: ${chainType} (${params.destChain})`,\n );\n }\n\n // Validate assetOut - BTC Stake should only produce LBTC\n if (!isAssetOutSupported(config, params.assetOut)) {\n throw new LombardError(\n ValidationErrorCode.INVALID_ASSET,\n `Asset ${params.assetOut} is not supported for BTC staking. ` +\n `BTC Stake produces LBTC. For BTC.b, use BtcDeposit instead.`,\n );\n }\n\n if (!isDestChainSupported(config, params.destChain)) {\n throw new LombardError(\n ValidationErrorCode.INVALID_CHAIN,\n `Destination chain ${params.destChain} is not supported for ${chainType}`,\n );\n }\n\n if (!isRouteAvailable(config, params.sourceChain, ctx.env)) {\n throw LombardError.routeNotFound({\n assetOut: params.assetOut,\n sourceChain: params.sourceChain,\n destChain: params.destChain,\n env: ctx.env,\n });\n }\n\n this.config = config;\n this.chainId = parseChainIdentifier(params.destChain);\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Abstract Method Implementations\n // ─────────────────────────────────────────────────────────────────────────\n\n protected getAddressSchema(): z.ZodType<string> {\n return this.config.addressSchema;\n }\n\n protected getStatusConfig(): StatusConfig<BtcActionStatus> {\n return {\n idle: BtcActionStatus.IDLE,\n ready: BtcActionStatus.READY,\n addressReady: BtcActionStatus.ADDRESS_READY,\n };\n }\n\n protected getInitialSteps(): StepDefinition {\n return {\n created: StepStatus.IDLE,\n verifying: StepStatus.IDLE,\n issuing: StepStatus.IDLE,\n };\n }\n\n protected isAuthorized(): boolean {\n return this.authState.authorized;\n }\n\n protected getChainId(): AnyChainId {\n return this.chainId;\n }\n\n protected getDepositAddressParams(captchaToken?: string) {\n const recipient = this.ensureRecipient();\n const signature = this.getActiveSignature();\n\n if (!signature) {\n throw new LombardError(\n ValidationErrorCode.INVALID_PARAMETER,\n 'Missing signature. Complete authorization first.',\n );\n }\n\n return {\n address: signature.paddedAddress ?? recipient,\n chainId: this.chainId,\n signature: signature.signature,\n token: this.getExpectedToken(),\n eip712Data: this.authState.networkFee?.typedData,\n pubKey: signature.pubKey,\n partnerId: this.ctx.partner.getPartnerId(),\n referrerCode: this._referralCode,\n captchaToken,\n };\n }\n\n /**\n * Get expected token for this action (LBTC by default for BTC Stake)\n */\n protected getExpectedToken(): string {\n return assetIdToToken(this.params.assetOut, Token.LBTC);\n }\n\n protected getAuthRequiredMessage(): string {\n return 'Authorization required. Call authorize() first.';\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Public Getters\n // ─────────────────────────────────────────────────────────────────────────\n\n /** Get minting fee (available after prepare() for fee-auth chains) */\n get mintingFee(): string | undefined {\n return this.authState.mintingFee;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Public Methods\n // ─────────────────────────────────────────────────────────────────────────\n\n async prepare(params: {\n amount: string;\n recipient: string;\n referralCode?: string;\n }): Promise<void> {\n this.assertStatus(BtcActionStatus.IDLE, 'prepare');\n\n return this.act(async () => {\n const validated = this.validatePrepareParams(params);\n\n this._amount = validated.amount;\n this._recipient = validated.recipient;\n this._referralCode = validated.referralCode;\n\n // Get fee auth config for this destination chain (needed for both resume and new flow)\n this.feeAuthConfig = this.config.getFeeAuthConfig(this.params.destChain);\n\n // Check for existing deposit (resume flow)\n const hasExistingDeposit = await this.resumeFromExistingDeposit(\n validated.recipient,\n );\n\n if (hasExistingDeposit) {\n // We have a deposit address, but we still need to validate fee authorization\n // The deposit address might have been created when fee auth was valid,\n // but the fee auth could have expired since then\n if (this.feeAuthConfig) {\n const stored = await this.feeAuthConfig.restoreFeeSignature(\n this.ctx,\n this.chainId,\n validated.recipient,\n );\n\n // Check hasSignature flag - the actual signature string may not be returned by API\n if (!stored?.hasSignature) {\n // Fee auth is required but expired/missing - need re-authorization\n this.authState.mintingFee = await this.feeAuthConfig.getMintingFee(\n this.ctx,\n this.chainId,\n );\n this.updateStatus(BtcActionStatus.NEEDS_FEE_AUTHORIZATION);\n this.emitInitialProgress();\n return;\n }\n\n // Fee auth is still valid on server - store signature if available\n if (stored.signature) {\n this.authState.networkFee = {\n signature: stored.signature,\n typedData: stored.typedData,\n };\n }\n this.authState.authorized = true;\n }\n\n // Deposit address exists and fee auth is valid (or not required)\n // Now we can safely set the status to ADDRESS_READY\n this.updateStatus(BtcActionStatus.ADDRESS_READY);\n this.emitInitialProgress();\n return;\n }\n\n // No existing deposit - proceed with normal flow\n if (this.feeAuthConfig) {\n // Fee authorization required - try to restore stored signature first\n const stored = await this.feeAuthConfig.restoreFeeSignature(\n this.ctx,\n this.chainId,\n validated.recipient,\n );\n\n // Check hasSignature flag - the actual signature string may not be returned by API\n if (stored?.hasSignature) {\n // Fee auth already exists on server - store signature if available\n if (stored.signature) {\n this.authState.networkFee = {\n signature: stored.signature,\n typedData: stored.typedData,\n };\n }\n this.authState.authorized = true;\n this.updateStatus(BtcActionStatus.READY);\n this.emitInitialProgress();\n return;\n }\n\n // Get minting fee for display\n this.authState.mintingFee = await this.feeAuthConfig.getMintingFee(\n this.ctx,\n this.chainId,\n );\n this.updateStatus(BtcActionStatus.NEEDS_FEE_AUTHORIZATION);\n } else {\n // No fee auth required - go to address confirmation\n this.updateStatus(BtcActionStatus.NEEDS_ADDRESS_CONFIRMATION);\n }\n\n this.emitInitialProgress();\n });\n }\n\n async authorize(): Promise<void> {\n this.assertStatus(\n [\n BtcActionStatus.NEEDS_FEE_AUTHORIZATION,\n BtcActionStatus.NEEDS_ADDRESS_CONFIRMATION,\n BtcActionStatus.READY,\n ],\n 'authorize',\n );\n\n if (this.status === BtcActionStatus.READY) return;\n\n const recipient = this.ensureRecipient();\n const needsFeeAuth = this.feeAuthConfig !== null;\n\n return this.act(async () => {\n if (needsFeeAuth) {\n // Fee authorization flow\n const fee = this.ensureMintingFee();\n const result = await this.feeAuthConfig!.authorizeFee(this.ctx, {\n chainId: this.chainId,\n recipient,\n fee,\n });\n this.authState.networkFee = {\n signature: result.signature,\n typedData: result.typedData,\n };\n } else {\n // Destination signature flow\n this.authState.destinationSignature = await this.config.getSignature(\n this.ctx,\n recipient,\n this.chainId,\n );\n }\n\n this.authState.authorized = true;\n }, BtcActionStatus.READY);\n }\n\n async generateDepositAddress(captchaToken?: string): Promise<string> {\n this.assertStatus(BtcActionStatus.READY, 'generateDepositAddress');\n this.ensureAuthorized();\n\n if (this._depositAddress) {\n return this._depositAddress;\n }\n\n // If no signature is available locally (fee auth exists on server but wasn't returned),\n // fall back to signing the destination address\n if (!this.getActiveSignature()) {\n const result = await this.config.getSignature(\n this.ctx,\n this.ensureRecipient(),\n this.chainId,\n );\n this.authState.destinationSignature = result;\n }\n\n return this.act(async () => {\n const apiParams = this.getDepositAddressParams(captchaToken);\n const depositAddress =\n await this.ctx.api.generateDepositAddress(apiParams);\n\n ensureNotSanctionedAddress(depositAddress);\n this._depositAddress = depositAddress;\n\n this.emitProgress({\n status: BtcActionStatus.ADDRESS_READY,\n steps: {\n created: StepStatus.COMPLETE,\n verifying: StepStatus.IDLE,\n issuing: StepStatus.IDLE,\n },\n metadata: { depositAddress },\n });\n\n return depositAddress;\n }, BtcActionStatus.ADDRESS_READY);\n }\n\n async execute(): Promise<{ depositAddress: string; txHash?: string }> {\n return this.executeImpl();\n }\n\n async monitorDeposit(): Promise<MonitorProgress | undefined> {\n return super.monitorDeposit();\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Private: Ensure Methods\n // ─────────────────────────────────────────────────────────────────────────\n\n private ensureMintingFee(): string {\n if (!this.authState.mintingFee) {\n throw new LombardError(\n ValidationErrorCode.INVALID_PARAMETER,\n 'Minting fee not fetched. Call prepare() first.',\n );\n }\n return this.authState.mintingFee;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Private: Signature Helpers\n // ─────────────────────────────────────────────────────────────────────────\n\n private getActiveSignature(): SignatureResult | undefined {\n if (this.authState.networkFee?.signature) {\n return { signature: this.authState.networkFee.signature };\n }\n return this.authState.destinationSignature;\n }\n}\n","/**\n * BTC StakeAndDeploy Action\n *\n * Handles BTC → LBTC → Vault deposit in a single atomic operation.\n * Also known as \"Stake and Bake\".\n *\n * @module chains/btc/actions/stakeAndDeploy/BtcStakeAndDeploy\n */\n\nimport type { z } from 'zod';\n\nimport type { ChainId } from '../../../../common/chains';\nimport { isValidChain } from '../../../../common/chains';\nimport { AssetId, parseChainIdentifier, StepStatus } from '../../../../core';\nimport type { BtcCoreContext } from '../../../../shared/context';\nimport { LombardError, ValidationErrorCode } from '../../../../shared/errors';\nimport type { StakeAndDeployEventMap } from '../../../../shared/events';\nimport {\n monitorDeposit,\n type MonitorProgress,\n} from '../../../../shared/monitoring';\nimport { Token } from '../../../../tokens/token-addresses';\nimport { ensureNotSanctionedAddress } from '../../../../utils/ensureNotSanctionedAddress';\nimport { toSatoshi } from '../../../../utils/satoshi';\nimport {\n assetIdToToken,\n BaseBtcAction,\n type StatusConfig,\n type StepDefinition,\n} from '../shared';\nimport {\n getVaultKey,\n isAssetOutSupported,\n isDestChainSupported,\n isProtocolSupported,\n isRouteAvailable,\n stakeAndDeployConfig,\n} from './config';\nimport {\n BtcActionStatus,\n type BtcStakeAndDeploy as IBtcStakeAndDeploy,\n type BtcStakeAndDeployParams,\n type BtcStakeAndDeployPrepareParams,\n} from './types';\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Types\n// ═══════════════════════════════════════════════════════════════════════════\n\ninterface AuthState {\n fee?: string;\n signature?: string;\n typedData?: string;\n authorized: boolean;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// BtcStakeAndDeploy Implementation\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * BTC StakeAndDeploy Action\n *\n * Combines staking and vault deployment in a single atomic operation.\n *\n * @example\n * ```typescript\n * const stakeAndDeploy = new BtcStakeAndDeploy(ctx, {\n * assetOut: AssetId.LBTC,\n * destChain: Chain.ETHEREUM,\n * protocol: DeployProtocol.Veda,\n * });\n *\n * await stakeAndDeploy.prepare({ amount: '0.1', recipient: '0x...' });\n * await stakeAndDeploy.authorizeDeposit();\n * const address = await stakeAndDeploy.generateDepositAddress();\n * ```\n */\nexport class BtcStakeAndDeploy\n extends BaseBtcAction<\n StakeAndDeployEventMap,\n BtcActionStatus,\n BtcStakeAndDeployParams\n >\n implements IBtcStakeAndDeploy\n{\n private readonly chainId: ChainId;\n private readonly authState: AuthState = { authorized: false };\n\n constructor(ctx: BtcCoreContext, params: BtcStakeAndDeployParams) {\n super(ctx, params, BtcActionStatus.IDLE);\n\n // Validate assetOut - StakeAndDeploy should only produce LBTC\n if (!isAssetOutSupported(params.assetOut)) {\n throw new LombardError(\n ValidationErrorCode.INVALID_ASSET,\n `Asset ${params.assetOut} is not supported for stake and deploy. ` +\n `StakeAndDeploy produces LBTC which is then deployed to a vault.`,\n );\n }\n\n if (!isDestChainSupported(params.destChain)) {\n throw new LombardError(\n ValidationErrorCode.INVALID_CHAIN,\n `Destination chain ${params.destChain} is not supported for stake and deploy`,\n );\n }\n\n if (!isProtocolSupported(params.protocol)) {\n throw new LombardError(\n ValidationErrorCode.INVALID_PARAMETER,\n `Protocol ${params.protocol} is not supported for stake and deploy`,\n );\n }\n\n if (!isRouteAvailable(params.sourceChain, ctx.env)) {\n throw LombardError.routeNotFound({\n assetOut: params.assetOut,\n sourceChain: params.sourceChain,\n destChain: params.destChain,\n env: ctx.env,\n });\n }\n\n const parsed = parseChainIdentifier(params.destChain);\n if (typeof parsed !== 'number' || !isValidChain(parsed)) {\n throw new LombardError(\n ValidationErrorCode.INVALID_CHAIN,\n `Unsupported EVM chain: ${params.destChain}`,\n );\n }\n\n this.chainId = parsed as ChainId;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Abstract Method Implementations\n // ─────────────────────────────────────────────────────────────────────────\n\n protected getAddressSchema(): z.ZodType<string> {\n return stakeAndDeployConfig.addressSchema;\n }\n\n protected getStatusConfig(): StatusConfig<BtcActionStatus> {\n return {\n idle: BtcActionStatus.IDLE,\n ready: BtcActionStatus.READY,\n addressReady: BtcActionStatus.ADDRESS_READY,\n };\n }\n\n protected getInitialSteps(): StepDefinition {\n return {\n created: StepStatus.IDLE,\n verifying: StepStatus.IDLE,\n issuing: StepStatus.IDLE,\n depositing: StepStatus.IDLE,\n };\n }\n\n protected isAuthorized(): boolean {\n return this.authState.authorized;\n }\n\n protected getChainId(): ChainId {\n return this.chainId;\n }\n\n protected getDepositAddressParams(captchaToken?: string) {\n const recipient = this.ensureRecipient();\n return {\n address: recipient,\n chainId: this.chainId,\n signature: this.authState.signature!,\n token: this.getExpectedToken(),\n // Stake and bake uses signatureData (maps to sb_signature_data), not eip712Data\n signatureData: this.authState.typedData,\n partnerId: this.ctx.partner.getPartnerId(),\n referrerCode: this._referralCode,\n captchaToken,\n };\n }\n\n /**\n * Get expected token for this action (LBTC by default for StakeAndDeploy)\n */\n protected getExpectedToken(): string {\n return assetIdToToken(this.params.assetOut, Token.LBTC);\n }\n\n protected getAuthRequiredMessage(): string {\n return 'Deposit authorization required. Call authorizeDeposit() first.';\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Public Getters\n // ─────────────────────────────────────────────────────────────────────────\n\n /** Get stake and bake fee (available after prepare()) */\n get fee(): string | undefined {\n return this.authState.fee;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Public Methods\n // ─────────────────────────────────────────────────────────────────────────\n\n async prepare(params: BtcStakeAndDeployPrepareParams): Promise<void> {\n this.assertStatus(BtcActionStatus.IDLE, 'prepare');\n\n return this.act(async () => {\n const validated = this.validatePrepareParams(params);\n\n this._amount = validated.amount;\n this._recipient = validated.recipient;\n this._referralCode = validated.referralCode;\n\n // Get fee for stake and bake\n this.authState.fee = await stakeAndDeployConfig.getStakeAndBakeFee(\n this.ctx,\n this.chainId,\n this.params.protocol,\n );\n\n // Check for existing deposit address (resume flow)\n const hasExistingDeposit = await this.resumeFromExistingDeposit(\n validated.recipient,\n );\n\n if (hasExistingDeposit) {\n // We have a deposit address - check if stake and bake signature is still valid\n const stored = await stakeAndDeployConfig.restoreStakeAndBakeSignature(\n this.ctx,\n this.chainId,\n validated.recipient,\n );\n\n if (stored?.hasSignature) {\n // Valid signature exists - skip authorization step\n if (stored.signature) {\n this.authState.signature = stored.signature;\n }\n this.authState.authorized = true;\n this.updateStatus(BtcActionStatus.ADDRESS_READY);\n this.emitInitialProgress();\n return;\n }\n\n // Deposit exists but signature expired/missing - need re-authorization\n this.updateStatus(BtcActionStatus.NEEDS_DEPLOY_AUTHORIZATION);\n this.emitInitialProgress();\n return;\n }\n\n // No existing deposit - check if there's a valid signature anyway\n // (signature was created but deposit address not yet generated)\n const existingSignature =\n await stakeAndDeployConfig.restoreStakeAndBakeSignature(\n this.ctx,\n this.chainId,\n validated.recipient,\n );\n\n if (existingSignature?.hasSignature) {\n // Valid signature exists - skip to READY state\n if (existingSignature.signature) {\n this.authState.signature = existingSignature.signature;\n }\n this.authState.authorized = true;\n this.updateStatus(BtcActionStatus.READY);\n this.emitInitialProgress();\n return;\n }\n\n // No existing signature - require authorization\n this.updateStatus(BtcActionStatus.NEEDS_DEPLOY_AUTHORIZATION);\n this.emitInitialProgress();\n });\n }\n\n async authorizeDeposit(): Promise<void> {\n this.assertStatus(\n [BtcActionStatus.NEEDS_DEPLOY_AUTHORIZATION, BtcActionStatus.READY],\n 'authorizeDeposit',\n );\n\n if (this.status === BtcActionStatus.READY) return;\n\n const recipient = this.ensureRecipient();\n const amount = this.ensureAmount();\n\n return this.act(async () => {\n const amountSats = toSatoshi(amount);\n\n // For BTC → LBTC stake and bake, use AssetId.BTC to trigger ratio conversion.\n // The DEFI_REGISTRY maps 'BTC' to { amountStrategy: 'btcToLbtc' } which divides\n // the BTC amount by BTCTokenRatio to get the correct LBTC amount for the signature.\n // This is critical because the backend expects the ratio-adjusted amount.\n //\n // Note: assetIn is optional but for BtcStakeAndDeploy, the source is always\n // native BTC since we're receiving deposits on the Bitcoin blockchain.\n const sourceToken = this.params.assetIn ?? AssetId.BTC;\n\n const result = await stakeAndDeployConfig.authorizeStakeAndBake(\n this.ctx,\n {\n chainId: this.chainId,\n recipient,\n amount: amountSats.toString(),\n vaultKey: getVaultKey(this.params.protocol),\n token: sourceToken,\n },\n );\n\n this.authState.signature = result.signature;\n this.authState.typedData = result.typedData;\n this.authState.authorized = true;\n }, BtcActionStatus.READY);\n }\n\n async generateDepositAddress(captchaToken?: string): Promise<string> {\n this.assertStatus(BtcActionStatus.READY, 'generateDepositAddress');\n this.ensureAuthorized();\n\n if (this._depositAddress) {\n return this._depositAddress;\n }\n\n return this.act(async () => {\n const apiParams = this.getDepositAddressParams(captchaToken);\n const depositAddress =\n await this.ctx.api.generateDepositAddress(apiParams);\n\n ensureNotSanctionedAddress(depositAddress);\n this._depositAddress = depositAddress;\n\n this.emitProgress({\n status: BtcActionStatus.ADDRESS_READY,\n steps: {\n created: StepStatus.COMPLETE,\n verifying: StepStatus.IDLE,\n issuing: StepStatus.IDLE,\n depositing: StepStatus.IDLE,\n },\n metadata: { depositAddress },\n });\n\n return depositAddress;\n }, BtcActionStatus.ADDRESS_READY);\n }\n\n async execute(): Promise<{ depositAddress: string; txHash?: string }> {\n return this.act(async () => {\n this.assertStatus(BtcActionStatus.ADDRESS_READY, 'execute');\n\n if (!this._depositAddress) {\n await this.generateDepositAddress();\n }\n\n const depositAddress = this.ensureDepositAddress();\n const txHash = await this.trySendBitcoin(depositAddress);\n\n return txHash ? { depositAddress, txHash } : { depositAddress };\n });\n }\n\n // Custom monitorDeposit with different step names\n async monitorDeposit(): Promise<MonitorProgress | undefined> {\n const depositAddress = this._depositAddress;\n const recipient = this._recipient;\n\n if (!depositAddress || !recipient) {\n throw LombardError.missingParameter('depositAddress or recipient');\n }\n\n const progress = await monitorDeposit({\n network: this.bitcoinNetwork,\n btcService: this.ctx.btc,\n fetchDeposit: async () => {\n const deposits = await this.ctx.api.getDeposits(recipient);\n const ourDeposit = deposits.find(\n deposit => deposit.depositAddress === depositAddress,\n );\n\n if (!ourDeposit) {\n return undefined;\n }\n\n return {\n blockHeight: ourDeposit.blockHeight,\n isClaimed: ourDeposit.isClaimed,\n };\n },\n onProgress: p => {\n this.emitProgress({\n status: this.status,\n steps: {\n created: StepStatus.COMPLETE,\n verifying: p.hasEnoughConfirmations\n ? StepStatus.COMPLETE\n : StepStatus.PENDING,\n issuing: p.isClaimed ? StepStatus.COMPLETE : StepStatus.PENDING,\n depositing: StepStatus.PENDING,\n },\n confirmations: p.confirmations,\n requiredConfirmations: p.requiredConfirmations,\n metadata: { isClaimed: p.isClaimed },\n });\n },\n onComplete: () => {\n this.emitCompleted();\n },\n });\n\n return progress;\n }\n}\n","/**\n * BTC Actions\n *\n * Provides factory methods for Bitcoin operations (stake, stakeAndDeploy, deposit).\n * This is the user-facing API for BTC operations.\n *\n * @example\n * ```typescript\n * import { createLombardSDK, Chain, AssetId, Env } from '@lombard.finance/sdk';\n *\n * const sdk = await createLombardSDK({\n * env: Env.prod,\n * providers: { evm: () => window.ethereum },\n * });\n *\n * const stake = sdk.chain.btc.stake({\n * assetOut: AssetId.LBTC,\n * destChain: Chain.ETHEREUM,\n * });\n *\n * await stake.prepare({ amount: '0.1', recipient: '0x...' });\n * await stake.authorize();\n * const address = await stake.generateDepositAddress();\n * ```\n *\n * @module chains/btc/BtcActions\n */\n\nimport type { LombardConfig } from '../../config/types';\nimport type { BtcCoreContext } from '../../shared/context';\nimport { createBtcCoreContext } from '../../shared/context';\nimport { BtcDeposit } from './actions/deposit/BtcDeposit';\nimport type {\n BtcDeposit as IBtcDeposit,\n BtcDepositParams,\n} from './actions/deposit/types';\nimport { BtcDepositAndDeploy } from './actions/depositAndDeploy/BtcDepositAndDeploy';\nimport type {\n BtcDepositAndDeploy as IBtcDepositAndDeploy,\n BtcDepositAndDeployParams,\n} from './actions/depositAndDeploy/types';\nimport { BtcStake } from './actions/stake/BtcStake';\nimport type {\n BtcStake as IBtcStake,\n BtcStakeParams,\n} from './actions/stake/types';\nimport { BtcStakeAndDeploy } from './actions/stakeAndDeploy/BtcStakeAndDeploy';\nimport type {\n BtcStakeAndDeploy as IBtcStakeAndDeploy,\n BtcStakeAndDeployParams,\n} from './actions/stakeAndDeploy/types';\n\n/**\n * BTC Actions\n *\n * User-facing class for Bitcoin operations.\n * Created via btcActions(config) factory function.\n */\nexport class BtcActions {\n private readonly ctx: BtcCoreContext;\n\n constructor(config: LombardConfig) {\n this.ctx = createBtcCoreContext(config);\n }\n\n /**\n * Stake BTC → LBTC\n *\n * Creates a stake operation for converting BTC to LBTC on a destination chain.\n * Supports all destination chains: EVM, Solana, Sui, and Starknet.\n *\n * @param params - Stake parameters\n * @returns BtcStake instance\n *\n * @example\n * ```typescript\n * const stake = btc.stake({\n * assetOut: AssetId.LBTC,\n * destChain: Chain.ETHEREUM,\n * });\n *\n * await stake.prepare({ amount: '0.1', recipient: '0x...' });\n * await stake.authorize();\n * const address = await stake.generateDepositAddress();\n * ```\n */\n stake(params: BtcStakeParams): IBtcStake {\n return new BtcStake(this.ctx, params);\n }\n\n /**\n * Stake and Deploy BTC → LBTC + auto-deploy (\"Stake and Bake\")\n *\n * Creates an atomic operation that:\n * 1. Converts BTC to LBTC\n * 2. Automatically deposits LBTC to the specified DeFi vault\n *\n * @param params - StakeAndDeploy parameters including protocol/vault\n * @returns BtcStakeAndDeploy instance\n *\n * @example\n * ```typescript\n * const action = btc.stakeAndDeploy({\n * assetOut: AssetId.LBTC,\n * destChain: Chain.ETHEREUM,\n * protocol: DeployProtocol.Veda,\n * });\n *\n * await action.prepare({ amount: '0.1', recipient: '0x...' });\n * await action.authorizeDeposit();\n * const address = await action.generateDepositAddress();\n * ```\n */\n stakeAndDeploy(params: BtcStakeAndDeployParams): IBtcStakeAndDeploy {\n return new BtcStakeAndDeploy(this.ctx, params);\n }\n\n /**\n * Deposit BTC for custody (BTC → BTC.b)\n *\n * Creates a deposit operation for custodying BTC with BTC.b minting.\n * This is for custody without staking. For staking (BTC → LBTC), use stake().\n *\n * @param params - Deposit parameters\n * @returns BtcDeposit instance\n *\n * @example\n * ```typescript\n * const deposit = btc.deposit({\n * assetOut: AssetId.BTCb,\n * destChain: Chain.AVALANCHE,\n * });\n *\n * await deposit.prepare({ amount: '0.1', recipient: '0x...' });\n * await deposit.authorizeFee();\n * const address = await deposit.generateDepositAddress();\n * ```\n */\n deposit(params: BtcDepositParams): IBtcDeposit {\n return new BtcDeposit(this.ctx, params);\n }\n\n /**\n * Deposit and Deploy BTC → BTC.b + auto-deploy to vault\n *\n * Creates an atomic operation that:\n * 1. Converts BTC to BTC.b (wrapped BTC)\n * 2. Automatically deposits BTC.b to the specified DeFi vault (e.g., Silo on Avalanche)\n *\n * This is similar to stakeAndDeploy but for protocols that accept BTC.b instead of LBTC.\n *\n * @param params - DepositAndDeploy parameters including protocol/vault\n * @returns BtcDepositAndDeploy instance\n *\n * @example\n * ```typescript\n * const action = btc.depositAndDeploy({\n * assetOut: AssetId.BTCb,\n * destChain: Chain.AVALANCHE,\n * protocol: DeployProtocol.Silo,\n * });\n *\n * await action.prepare({ amount: '0.1', recipient: '0x...' });\n * await action.authorizeDeposit();\n * const address = await action.generateDepositAddress();\n * ```\n */\n depositAndDeploy(params: BtcDepositAndDeployParams): IBtcDepositAndDeploy {\n return new BtcDepositAndDeploy(this.ctx, params);\n }\n}\n\n/**\n * Create BTC actions from config\n *\n * @internal This factory is for internal use. Use createLombardSDK() instead:\n *\n * @example\n * ```typescript\n * const sdk = await createLombardSDK({ env: Env.prod, providers: { ... } });\n * const stake = sdk.chain.btc.stake({ destChain: Chain.ETHEREUM, assetOut: AssetId.LBTC });\n * const deposit = sdk.chain.btc.deposit({ destChain: Chain.AVALANCHE, assetOut: AssetId.BTCb });\n * const stakeAndDeploy = sdk.chain.btc.stakeAndDeploy({\n * destChain: Chain.AVALANCHE,\n * assetOut: AssetId.BTCb,\n * protocol: DeployProtocol.Silo,\n * });\n * ```\n */\nexport function btcActions(config: LombardConfig): BtcActions {\n return new BtcActions(config);\n}\n"],"names":["ADBLOCKER_ERROR_CODE","ADBLOCK_ERROR_MSG","handleMempoolApiError","error","code","message","stageConfig","prodConfig","getBtcApiConfig","mode","getCurrentBlockHeight","mempoolApiUrl","timestamp","url","data","axios","BtcService","network","btcModule","monitorDeposit","options","fetchDeposit","btcService","requiredConfirmations","onProgress","onComplete","deposit","blockHeight","currentBlockHeight","confirmations","hasEnoughConfirmations","isClaimed","progress","StepStatus","ensureNotSanctionedAddress","address","SANCTIONED_ADDRESS","LombardError","ValidationErrorCode","BaseBtcAction","BaseAction","ctx","params","initialStatus","__publicField","Chain","z.object","btcStakeAmountSchema","referralCodeSchema","zodValidate","recipient","depositAddress","captchaToken","statusConfig","apiParams","steps","addressReadySteps","key","index","txHash","ourDeposit","p","amount","btcProvider","provider","amountSats","toSatoshi","assetIdToToken","assetId","defaultToken","Token","AssetId","requestChainSwitch","targetChainId","err","addChain","addError","addErr","getCurrentChainId","chainIdHex","ensureCorrectChain","UNSUBSIDIZED_CHAINS","feeAuthConfig","chainId","tokenInfo","getTokenContractInfo","result","fee","evm","feeInSatoshis","evmDepositConfig","Env","getAllAssetChains","chain","isEvmChain","evmAddressSchema","destChain","depositConfig","isDestChainSupported","isAssetOutSupported","assetOut","isRouteAvailable","sourceChain","env","route","BtcDeposit","BtcActionStatus","parsed","parseChainIdentifier","isValidChain","validated","stored","STAKE_AND_DEPLOY_DEST_CHAINS","VEDA_VAULT_STAKE_AND_BAKE_CHAINS","evmChainIdToChain","evmStakeAndDeployConfig","getSupportedProtocols","protocol","vaultKey","token","getUserStakeAndBakeSignature","stakeAndDeployConfig","isProtocolSupported","DEFI_REGISTRY","getVaultKey","supportedProtocols","_","tokenMap","DEPOSIT_AND_DEPLOY_CHAINS","evmDepositAndDeployConfig","depositAndDeployConfig","BtcDepositAndDeploy","outputToken","withSeparator","prefix","CAIP2_SEPARATOR","CHAIN_PREFIXES","isSolanaChain","isSuiChain","isStarknetChain","evmConfig","chainToSolanaNetwork","CHAIN_TO_NETWORK","solanaConfig","solanaAddressSchema","_recipient","solana","signature","starknetConfig","starknetAddressSchema","starknet","pubKey","paddedAddress","pad","suiConfig","suiAddressSchema","sui","chainConfigs","getChainConfig","chainType","config","BtcStake","getChainType","_a","needsFeeAuth","BtcStakeAndDeploy","existingSignature","sourceToken","BtcActions","createBtcCoreContext","btcActions"],"mappings":"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"}
|