diff --git a/config/wallet-config.json b/config/wallet-config.json index 13de87c9121..c012ed8134d 100644 --- a/config/wallet-config.json +++ b/config/wallet-config.json @@ -93,6 +93,18 @@ "recoverUninscribedTaprootUtxosFeatureEnabled": true, "runesEnabled": true, "swapsEnabled": true, + "sbtc": { + "enabled": true, + "contracts": { + "mainnet": { + "address": "SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token::sbtc-token" + }, + "testnet": { + "address": "SNGWPN3XDAQE673MXYXF81016M50NHF5X5PWWM70.sbtc-token::sbtc-token" + } + }, + "showPromoLinkOnNetworks": ["testnet", "sbtcTestnet"] + }, "tokensEnabledByDefault": [ "DOGGOTOTHEMOON", "RSICGENESISRUNE", @@ -108,6 +120,8 @@ "SM26NBC8SFHNW4P1Y4DFH27974P56WN86C92HPEHH.token-lqstx::lqstx", "SP1Y5YSTAHZ88XYK1VPDH24GY0HPX5J4JECTMY4A1.velar-token::velar", "SP4SZE494VC2YC5JYG7AYFQ44F5Q4PYV7DVMDPBG.ststx-token::ststx", - "SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.arkadiko-token::diko" + "SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.arkadiko-token::diko", + "SNGWPN3XDAQE673MXYXF81016M50NHF5X5PWWM70.sbtc-token::sbtc-token", + "SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token::sbtc-token" ] } diff --git a/config/wallet-config.schema.json b/config/wallet-config.schema.json index 4746578f4ff..5bfdfdffd55 100644 --- a/config/wallet-config.schema.json +++ b/config/wallet-config.schema.json @@ -149,6 +149,46 @@ "swapsEnabled": { "type": "boolean", "description": "Determines whether or not the swaps feature is enabled" + }, + "sbtc": { + "type": "object", + "description": "Configuration for SBTC", + "properties": { + "enabled": { + "type": "boolean", + "description": "Determines whether or not SBTC is enabled" + }, + "showPromoLinkOnNetworks": { + "type": "array", + "description": "Networks on which the promo link should be shown", + "items": { + "type": "string" + } + }, + "contracts": { + "type": "object", + "properties": { + "mainnet": { + "type": "object", + "properties": { + "address": { + "type": "string", + "description": "Mainnet contract address" + } + } + }, + "testnet": { + "type": "object", + "properties": { + "address": { + "type": "string", + "description": "Testnet contract address" + } + } + } + } + } + } } }, "$defs": { diff --git a/package.json b/package.json index 8b6ba09c010..183b92c9ce3 100644 --- a/package.json +++ b/package.json @@ -146,15 +146,15 @@ "@hirosystems/token-metadata-api-client": "1.2.0", "@hookform/resolvers": "3.9.1", "@leather.io/analytics": "2.0.1", - "@leather.io/bitcoin": "0.16.5", - "@leather.io/constants": "0.13.3", - "@leather.io/crypto": "1.6.12", - "@leather.io/models": "0.21.0", - "@leather.io/query": "2.23.0", - "@leather.io/stacks": "1.3.5", + "@leather.io/bitcoin": "0.17.0", + "@leather.io/constants": "0.13.5", + "@leather.io/crypto": "1.6.14", + "@leather.io/models": "0.22.0", + "@leather.io/query": "2.23.3", + "@leather.io/stacks": "1.4.0", "@leather.io/tokens": "0.12.1", - "@leather.io/ui": "1.37.0", - "@leather.io/utils": "0.19.1", + "@leather.io/ui": "1.39.0", + "@leather.io/utils": "0.20.0", "@ledgerhq/hw-transport-webusb": "6.27.19", "@noble/hashes": "1.5.0", "@noble/secp256k1": "2.1.0", @@ -268,7 +268,7 @@ "@btckit/types": "0.0.19", "@chromatic-com/storybook": "3.2.2", "@leather.io/eslint-config": "0.7.0", - "@leather.io/panda-preset": "0.5.2", + "@leather.io/panda-preset": "0.5.3", "@leather.io/prettier-config": "0.6.0", "@leather.io/rpc": "2.4.0", "@ls-lint/ls-lint": "2.2.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6b8e4bbf75f..ad9338c704f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,32 +48,32 @@ importers: specifier: 2.0.1 version: 2.0.1 '@leather.io/bitcoin': - specifier: 0.16.5 - version: 0.16.5(encoding@0.1.13) + specifier: 0.17.0 + version: 0.17.0(encoding@0.1.13) '@leather.io/constants': - specifier: 0.13.3 - version: 0.13.3 + specifier: 0.13.5 + version: 0.13.5 '@leather.io/crypto': - specifier: 1.6.12 - version: 1.6.12 + specifier: 1.6.14 + version: 1.6.14 '@leather.io/models': - specifier: 0.21.0 - version: 0.21.0 + specifier: 0.22.0 + version: 0.22.0 '@leather.io/query': - specifier: 2.23.0 - version: 2.23.0(encoding@0.1.13)(react@18.3.1) + specifier: 2.23.3 + version: 2.23.3(encoding@0.1.13)(react@18.3.1) '@leather.io/stacks': - specifier: 1.3.5 - version: 1.3.5(encoding@0.1.13) + specifier: 1.4.0 + version: 1.4.0(encoding@0.1.13) '@leather.io/tokens': specifier: 0.12.1 version: 0.12.1 '@leather.io/ui': - specifier: 1.37.0 - version: 1.37.0(@babel/core@7.26.0)(@babel/preset-env@7.26.0(@babel/core@7.26.0))(@emotion/is-prop-valid@1.3.1)(@types/react-dom@18.3.0)(@types/react@18.3.10)(encoding@0.1.13)(expo-modules-autolinking@1.11.1) + specifier: 1.39.0 + version: 1.39.0(@babel/core@7.26.0)(@babel/preset-env@7.26.0(@babel/core@7.26.0))(@emotion/is-prop-valid@1.3.1)(@types/react-dom@18.3.0)(@types/react@18.3.10)(encoding@0.1.13)(expo-modules-autolinking@1.11.1) '@leather.io/utils': - specifier: 0.19.1 - version: 0.19.1 + specifier: 0.20.0 + version: 0.20.0 '@ledgerhq/hw-transport-webusb': specifier: 6.27.19 version: 6.27.19 @@ -409,8 +409,8 @@ importers: specifier: 0.7.0 version: 0.7.0(typescript@5.4.5) '@leather.io/panda-preset': - specifier: 0.5.2 - version: 0.5.2(jsdom@22.1.0)(typescript@5.4.5) + specifier: 0.5.3 + version: 0.5.3(jsdom@22.1.0)(typescript@5.4.5) '@leather.io/prettier-config': specifier: 0.6.0 version: 0.6.0(@vue/compiler-sfc@3.5.13) @@ -3015,7 +3015,7 @@ packages: '@expo/bunyan@4.0.1': resolution: {integrity: sha512-+Lla7nYSiHZirgK+U/uYzsLv/X+HaJienbD5AKX1UQZHYfWaP+9uuQluRB4GrEVWF0GZ7vEVp/jzaOT9k/SQlg==} - engines: {'0': node >=0.10.0} + engines: {node: '>=0.10.0'} '@expo/cli@0.18.28': resolution: {integrity: sha512-fvbVPId6s6etindzP6Nzos/CS1NurMVy4JKozjebArHr63tBid5i/UY5Pp+4wTCAM20gB2SjRdwcwoL6HFC4Iw==} @@ -3275,79 +3275,49 @@ packages: '@leather.io/analytics@2.0.1': resolution: {integrity: sha512-C4fcEZZ9la+UMhqDqEZIIMDMmmedDuhhlnqb7HFlGVUg5/EKrBbS4Kvcp36sv/Uz02h+DuoubTsoJ/rFkqq6Bw==} - '@leather.io/bitcoin@0.16.5': - resolution: {integrity: sha512-YzNep7Mkb4Be3p0RF52y53yhbn9/7JOd5N45FE+52N2H8l3N2OgTk68rdCF7ZGPLIgYD8ws9dR/4rSc1lCAV8g==} - - '@leather.io/bitcoin@0.16.6': - resolution: {integrity: sha512-P5OmvUTsoHQDxWcjAOqGvnbHNCjd2/XWYsMUZCrxGXCaPAQdhShLfvilzSUIOnUS/MkwxOMB28f2hGgs8lfeJA==} - - '@leather.io/constants@0.13.3': - resolution: {integrity: sha512-kVMOb0QXDUspjlz8wycpCVrtu5IdJAiWgegRV9WdWcCdO1uiMAtqXsgd5K/CvafRw+/XYmYSLllDsC26rVBqQw==} - - '@leather.io/constants@0.13.4': - resolution: {integrity: sha512-Cot8qwwLWeIMr0LFHtzVkeJZ/a+MSMuNPhrXKm5Psaqb2jyjkq5RrlCLtm9/cjwmkBTZeokWubaQUzyPMlQK4w==} + '@leather.io/bitcoin@0.17.0': + resolution: {integrity: sha512-Nc4Bl2HWmxWvgIXbpa6Gs8EpqR1UJHDzXPu+R+2TIyOsjxFoGXoIQwLohxySnQa4i0UodrCXBrqDOqOTHtwbMQ==} '@leather.io/constants@0.13.5': resolution: {integrity: sha512-FOh/F/g8WepB8HfoTXsMB/BYcm/F6INPEpyEZc3ljzaN0mLwVLO1kwgMTFU9Pq7tQlITvyWiyGHcB7OYovLoUQ==} - '@leather.io/crypto@1.6.12': - resolution: {integrity: sha512-ZEhUVhdq/m2pIhi8PwvRKyjwYdcmXcRJBOLSO1RMSu8N93GTEqfvxkqTlu88c2ReNt5C62+TwWM6hbZkU2BV6Q==} - - '@leather.io/crypto@1.6.13': - resolution: {integrity: sha512-wSQctUprSg8slWi5A5KskrXRKOEDP3M9TxY+SqQa9M6CsSFR212YLu4K6ZsbG4yKnhDUelegeg2kwpdpyT1pXg==} + '@leather.io/crypto@1.6.14': + resolution: {integrity: sha512-D9Z0EgvXhdDSJdaQX+KCm2czqNCRDe3Kj7YJ3Hn1GiHet+wOy68sBJzG6yzESeC0Z7f1UBuDhmN9Edq5u1Zz2g==} '@leather.io/eslint-config@0.7.0': resolution: {integrity: sha512-4K7olfSC+mJnG90TSaLIlytp14yDprGXwe1+oP9TLQbuPFpJai3/+g5Bp/FeUC4NZ23UVbAlGXFCav2amBb77w==} - '@leather.io/models@0.20.0': - resolution: {integrity: sha512-plsF1fzBC32OukQtijoeQgaszDrh0dqkPJByiA/ygHT8Jay8dNYclvVznpKCSsOhdt6iywJzgLY3yIO4MiKTKg==} - - '@leather.io/models@0.21.0': - resolution: {integrity: sha512-cy/WToOVy0ZGHxza5kJL2aeKKnBXL4lSK/j3iig/rDWAgx5Vy7M8sCjFBbo4hlinskb8VgM5woGe7hIFjFZcmA==} - '@leather.io/models@0.22.0': resolution: {integrity: sha512-MmFmWdKN3T+L9euo+rq8JCr5Ku0mNulzVa0mYqXclB9vLa4NyhUsGHA3lWz8e05cMW9CsrPNg+eWpVg6AKTkeQ==} '@leather.io/models@0.24.1': resolution: {integrity: sha512-BRjiX7N/LUlg5MMe3r5mkjUGLGtGRSpd21LPgo0lhUUSO1cBMAdp7rLACGM9LFPw+/dnUw1yMpT2hURC3pe3Gg==} - '@leather.io/panda-preset@0.5.2': - resolution: {integrity: sha512-JxPGX7hEUKWLp4gYc2S5irK6QXVMFEGn2F7bXEv2cr8324DYa07i5iUF6/UVeRhrzVivcXEdd/6u0wlKc39Rcw==} + '@leather.io/panda-preset@0.5.3': + resolution: {integrity: sha512-3mhe83gNSOjHOh5q5wBuUZiyx1611FQDJE0iEEa1R7CC7+lt4HPf+nMn1oVgPBmil/qTgglsIv807SioVA/p9g==} '@leather.io/prettier-config@0.6.0': resolution: {integrity: sha512-QBKtLanfxFxXBlR58U/j8a6lBI0xzJzqqi36fXpGVp+9mJoEf6Ro6xrtFrixjW6seY6EOva4OApVnnPBsvOC/w==} - '@leather.io/query@2.23.0': - resolution: {integrity: sha512-1I4Vm2wDQWz4vK3fFFioh82sNrHKeSrDudRCUukoTH3wLREn/oLqIE24GDTGri4HcbxB60Qu+LcVTGl1XcU2QQ==} + '@leather.io/query@2.23.3': + resolution: {integrity: sha512-pKjZOlXScOHaNbJbCCSL6hTg6h6nmtVYGrn0FKqGAPbbeHjsGtHXInhdQeudqlVr5vZ4/5Yztkza8+r2qIJ+fQ==} peerDependencies: react: '*' - '@leather.io/rpc@2.1.18': - resolution: {integrity: sha512-KC5QvjR0O/9QDwD1liPXo+aV7yDIA82OFjrveG7JYzWNSn2PBkkX5NJ1KqE42BILX3tfBuV/rab6zN19KvRGbw==} - - '@leather.io/rpc@2.1.19': - resolution: {integrity: sha512-IUcXnmIuPyu5TK3x46ReSw+2/As2cWa6mzA+tofe/e59K9E5SMpEXZAg+WhvgPRFaXWaA3W8BzeH0BVEoRwEtw==} - '@leather.io/rpc@2.1.20': resolution: {integrity: sha512-BE56W5yzdOPdVWHo2G+ZrXsEt3Jki47/noMxy+9On0sNW5B90M+pULm65szp5/vzqJuY7xIrQJ1AOyG22cd82g==} '@leather.io/rpc@2.4.0': resolution: {integrity: sha512-S9PYtyOnZ9LJL8ZYsEPHUWmVkVL/E7oAfNLunFY7zVI0tJUl45OXJVCOjYRRKDKOqdx2pRpdqzeUSxRZvJdyVA==} - '@leather.io/stacks@1.3.5': - resolution: {integrity: sha512-yqOX6CTcg0Shj3A5ymYtho054PJ2xU+HlyRfwXca8yJ1U2chMSq7jTinJktgI+1liTHsqmtRnrgmufxWY41J7A==} + '@leather.io/stacks@1.4.0': + resolution: {integrity: sha512-vF3eQljr+dsfg8DhlEFgQKvr9NHn9CKwt8XT51kWnULTtZH6syrABiarHGwhtE/AZz9weg5n5q/+m8b4lN6bGw==} '@leather.io/tokens@0.12.1': resolution: {integrity: sha512-XoP9PT7uuzHIk9HFFkGTuMeG8KL94PVHQfdWtvb19qQC9YVMzwj+QSK45KUFYtXyfI+Ejsn7EFZmZ/C4vStDrg==} - '@leather.io/ui@1.37.0': - resolution: {integrity: sha512-ryylwG9m9hjA7MUhXcN0idCtXZYwfhLHd+4T+/vXCvXEaSpFro4DF+ih7msJGCv+B0R0y/PaQvu+KJDgLhrYrA==} - - '@leather.io/utils@0.19.1': - resolution: {integrity: sha512-bwD3/4Rt3UOL3pvettqNon+zqS5S8K6z3AoAEwkcYS77DI/q4kzH5T/3nOOGpcWda1/R453mqRCIObRxecIWFA==} - - '@leather.io/utils@0.19.2': - resolution: {integrity: sha512-oLEasUP5BDeDbrB9vxH0C0zrZWcG2bj12KHaI9illCtIqEe9pLM/5R5Ee6vVH1Ft+vCg/HI7WHNu79o0NHFdgQ==} + '@leather.io/ui@1.39.0': + resolution: {integrity: sha512-nxC0IilOvc4B6pwzIs+y9ofwr5SdyBOGgURqDWPz8Xqjvp8rptGgxrjQwCxMiwRLFR/BkXgCpDPfdzOx4UtyyA==} '@leather.io/utils@0.20.0': resolution: {integrity: sha512-Ot0oOYMku4oy3218W3Tt0ip0xjMyegOxFONqOyt/WSZe9xzTiXXUq0u3D8jwa851ZEOSCB7TgOO5RMzWK0lkLg==} @@ -3834,6 +3804,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-context@1.1.1': + resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-dialog@1.0.5': resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} peerDependencies: @@ -4265,6 +4244,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-slider@1.2.1': + resolution: {integrity: sha512-bEzQoDW0XP+h/oGbutF5VMWJPAl/UU8IJjr7h02SOHDIIIxq+cep8nItVNoBV+OMmahCdqdF38FTpmXoqQUGvw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-slot@1.0.2': resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} peerDependencies: @@ -7564,6 +7556,9 @@ packages: bitcoin-address-validation@2.2.1: resolution: {integrity: sha512-f6LXNpvRKlTbHWb37N9tHoAbYGbshzM8FPWvCtloh++hxZ0/dmkokvKNVLz6HkG82zVwo8w6Sq4JmfO2timzyg==} + bitcoin-address-validation@2.2.3: + resolution: {integrity: sha512-1uGCGl26Ye8JG5qcExtFLQfuib6qEZWNDo1ZlLlwp/z7ygUFby3IxolgEfgMGaC+LG9csbVASLcH8fRLv7DIOg==} + bitcoinjs-lib@6.1.5: resolution: {integrity: sha512-yuf6xs9QX/E8LWE2aMJPNd0IxGofwfuVOiYdNUESkc+2bHHVKjhJd8qewqapeoolh9fihzHGoDCB5Vkr57RZCQ==} engines: {node: '>=8.0.0'} @@ -14512,12 +14507,15 @@ packages: sudo-prompt@8.2.5: resolution: {integrity: sha512-rlBo3HU/1zAJUrkY6jNxDOC9eVYliG6nS4JA8u8KAshITd07tafMc/Br7xQwCSseXwJ2iCcHCE8SNWX3q8Z+kw==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. sudo-prompt@9.1.1: resolution: {integrity: sha512-es33J1g2HjMpyAhz8lOR+ICmXXAqTuKbuXuUWLhOLew20oN9oUCgCJx615U/v7aioZg7IX5lIh9x34vwneu4pA==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. sudo-prompt@9.2.1: resolution: {integrity: sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. sumchecker@3.0.1: resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==} @@ -19040,36 +19038,13 @@ snapshots: '@leather.io/analytics@2.0.1': {} - '@leather.io/bitcoin@0.16.5(encoding@0.1.13)': + '@leather.io/bitcoin@0.17.0(encoding@0.1.13)': dependencies: '@bitcoinerlab/secp256k1': 1.0.2 - '@leather.io/constants': 0.13.3 - '@leather.io/crypto': 1.6.12 - '@leather.io/models': 0.20.0 - '@leather.io/utils': 0.19.1 - '@noble/hashes': 1.5.0 - '@noble/secp256k1': 2.1.0 - '@scure/base': 1.1.9 - '@scure/bip32': 1.5.0 - '@scure/bip39': 1.4.0 - '@scure/btc-signer': 1.4.0 - '@stacks/common': 6.13.0 - '@stacks/transactions': 6.17.0(encoding@0.1.13) - bip32: 4.0.0 - bitcoinjs-lib: 6.1.5 - ecpair: 2.1.0 - just-memoize: 2.2.0 - varuint-bitcoin: 1.1.2 - transitivePeerDependencies: - - encoding - - '@leather.io/bitcoin@0.16.6(encoding@0.1.13)': - dependencies: - '@bitcoinerlab/secp256k1': 1.0.2 - '@leather.io/constants': 0.13.4 - '@leather.io/crypto': 1.6.13 - '@leather.io/models': 0.21.0 - '@leather.io/utils': 0.19.2 + '@leather.io/constants': 0.13.5 + '@leather.io/crypto': 1.6.14 + '@leather.io/models': 0.22.0 + '@leather.io/utils': 0.20.0 '@noble/hashes': 1.5.0 '@noble/secp256k1': 2.1.0 '@scure/base': 1.1.9 @@ -19078,7 +19053,9 @@ snapshots: '@scure/btc-signer': 1.4.0 '@stacks/common': 6.13.0 '@stacks/transactions': 6.17.0(encoding@0.1.13) + bignumber.js: 9.1.2 bip32: 4.0.0 + bitcoin-address-validation: 2.2.3 bitcoinjs-lib: 6.1.5 ecpair: 2.1.0 just-memoize: 2.2.0 @@ -19086,28 +19063,13 @@ snapshots: transitivePeerDependencies: - encoding - '@leather.io/constants@0.13.3': - dependencies: - '@leather.io/models': 0.20.0 - - '@leather.io/constants@0.13.4': - dependencies: - '@leather.io/models': 0.21.0 - '@leather.io/constants@0.13.5': dependencies: '@leather.io/models': 0.22.0 - '@leather.io/crypto@1.6.12': + '@leather.io/crypto@1.6.14': dependencies: - '@leather.io/utils': 0.19.1 - '@scure/bip32': 1.5.0 - '@scure/bip39': 1.4.0 - just-memoize: 2.2.0 - - '@leather.io/crypto@1.6.13': - dependencies: - '@leather.io/utils': 0.19.2 + '@leather.io/utils': 0.20.0 '@scure/bip32': 1.5.0 '@scure/bip39': 1.4.0 just-memoize: 2.2.0 @@ -19122,18 +19084,6 @@ snapshots: - supports-color - typescript - '@leather.io/models@0.20.0': - dependencies: - '@stacks/stacks-blockchain-api-types': 7.8.2 - bignumber.js: 9.1.2 - zod: 3.23.8 - - '@leather.io/models@0.21.0': - dependencies: - '@stacks/stacks-blockchain-api-types': 7.8.2 - bignumber.js: 9.1.2 - zod: 3.23.8 - '@leather.io/models@0.22.0': dependencies: '@stacks/stacks-blockchain-api-types': 7.8.2 @@ -19146,7 +19096,7 @@ snapshots: bignumber.js: 9.1.2 zod: 3.23.8 - '@leather.io/panda-preset@0.5.2(jsdom@22.1.0)(typescript@5.4.5)': + '@leather.io/panda-preset@0.5.3(jsdom@22.1.0)(typescript@5.4.5)': dependencies: '@pandacss/dev': 0.46.1(jsdom@22.1.0)(typescript@5.4.5) transitivePeerDependencies: @@ -19161,15 +19111,15 @@ snapshots: - '@vue/compiler-sfc' - supports-color - '@leather.io/query@2.23.0(encoding@0.1.13)(react@18.3.1)': + '@leather.io/query@2.23.3(encoding@0.1.13)(react@18.3.1)': dependencies: '@fungible-systems/zone-file': 2.0.0 '@hirosystems/token-metadata-api-client': 1.2.0(encoding@0.1.13) - '@leather.io/bitcoin': 0.16.6(encoding@0.1.13) - '@leather.io/constants': 0.13.4 - '@leather.io/models': 0.21.0 - '@leather.io/rpc': 2.1.19 - '@leather.io/utils': 0.19.2 + '@leather.io/bitcoin': 0.17.0(encoding@0.1.13) + '@leather.io/constants': 0.13.5 + '@leather.io/models': 0.22.0 + '@leather.io/rpc': 2.1.20 + '@leather.io/utils': 0.20.0 '@noble/hashes': 1.5.0 '@scure/base': 1.1.9 '@scure/bip32': 1.5.0 @@ -19194,16 +19144,6 @@ snapshots: - debug - encoding - '@leather.io/rpc@2.1.18': - dependencies: - '@leather.io/models': 0.20.0 - zod: 3.23.8 - - '@leather.io/rpc@2.1.19': - dependencies: - '@leather.io/models': 0.21.0 - zod: 3.23.8 - '@leather.io/rpc@2.1.20': dependencies: '@leather.io/models': 0.22.0 @@ -19217,21 +19157,25 @@ snapshots: transitivePeerDependencies: - encoding - '@leather.io/stacks@1.3.5(encoding@0.1.13)': + '@leather.io/stacks@1.4.0(encoding@0.1.13)': dependencies: - '@leather.io/crypto': 1.6.12 - '@leather.io/models': 0.20.0 - '@leather.io/utils': 0.19.1 + '@leather.io/constants': 0.13.5 + '@leather.io/crypto': 1.6.14 + '@leather.io/models': 0.22.0 + '@leather.io/utils': 0.20.0 '@noble/hashes': 1.5.0 '@scure/bip32': 1.5.0 '@stacks/encryption': 6.16.1 + '@stacks/network': 6.13.0(encoding@0.1.13) + '@stacks/stacks-blockchain-api-types': 7.8.2 '@stacks/transactions': 6.17.0(encoding@0.1.13) + bignumber.js: 9.1.2 transitivePeerDependencies: - encoding '@leather.io/tokens@0.12.1': {} - '@leather.io/ui@1.37.0(@babel/core@7.26.0)(@babel/preset-env@7.26.0(@babel/core@7.26.0))(@emotion/is-prop-valid@1.3.1)(@types/react-dom@18.3.0)(@types/react@18.3.10)(encoding@0.1.13)(expo-modules-autolinking@1.11.1)': + '@leather.io/ui@1.39.0(@babel/core@7.26.0)(@babel/preset-env@7.26.0(@babel/core@7.26.0))(@emotion/is-prop-valid@1.3.1)(@types/react-dom@18.3.0)(@types/react@18.3.10)(encoding@0.1.13)(expo-modules-autolinking@1.11.1)': dependencies: '@expo/vector-icons': 14.0.0 '@gorhom/bottom-sheet': 4.6.3(@types/react@18.3.10)(react-native-gesture-handler@2.16.1(react-native@0.74.1(@babel/core@7.26.0)(@babel/preset-env@7.26.0(@babel/core@7.26.0))(@types/react@18.3.10)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native-reanimated@3.10.1(@babel/core@7.26.0)(react-native@0.74.1(@babel/core@7.26.0)(@babel/preset-env@7.26.0(@babel/core@7.26.0))(@types/react@18.3.10)(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(react-native@0.74.1(@babel/core@7.26.0)(@babel/preset-env@7.26.0(@babel/core@7.26.0))(@types/react@18.3.10)(encoding@0.1.13)(react@18.2.0))(react@18.2.0) @@ -19243,6 +19187,7 @@ snapshots: '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@radix-ui/react-dropdown-menu': 2.0.6(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@radix-ui/react-select': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@radix-ui/react-slider': 1.2.1(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@radix-ui/react-switch': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@radix-ui/react-tabs': 1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@radix-ui/react-toast': 1.1.5(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -19289,20 +19234,6 @@ snapshots: - supports-color - utf-8-validate - '@leather.io/utils@0.19.1': - dependencies: - '@leather.io/constants': 0.13.3 - '@leather.io/models': 0.20.0 - '@leather.io/rpc': 2.1.18 - bignumber.js: 9.1.2 - - '@leather.io/utils@0.19.2': - dependencies: - '@leather.io/constants': 0.13.4 - '@leather.io/models': 0.21.0 - '@leather.io/rpc': 2.1.19 - bignumber.js: 9.1.2 - '@leather.io/utils@0.20.0': dependencies: '@leather.io/constants': 0.13.5 @@ -19897,6 +19828,18 @@ snapshots: '@types/react': 18.3.10 '@types/react-dom': 18.3.0 + '@radix-ui/react-collection@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.10)(react@18.2.0) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.10)(react@18.2.0) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.10)(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + optionalDependencies: + '@types/react': 18.3.10 + '@types/react-dom': 18.3.0 + '@radix-ui/react-collection@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.10)(react@18.3.1) @@ -19975,6 +19918,12 @@ snapshots: optionalDependencies: '@types/react': 18.3.10 + '@radix-ui/react-context@1.1.1(@types/react@18.3.10)(react@18.2.0)': + dependencies: + react: 18.2.0 + optionalDependencies: + '@types/react': 18.3.10 + '@radix-ui/react-dialog@1.0.5(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.25.4 @@ -20057,6 +20006,12 @@ snapshots: optionalDependencies: '@types/react': 18.3.10 + '@radix-ui/react-direction@1.1.0(@types/react@18.3.10)(react@18.2.0)': + dependencies: + react: 18.2.0 + optionalDependencies: + '@types/react': 18.3.10 + '@radix-ui/react-direction@1.1.0(@types/react@18.3.10)(react@18.3.1)': dependencies: react: 18.3.1 @@ -20690,6 +20645,25 @@ snapshots: '@types/react': 18.3.10 '@types/react-dom': 18.3.0 + '@radix-ui/react-slider@1.2.1(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@radix-ui/number': 1.1.0 + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.10)(react@18.2.0) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.10)(react@18.2.0) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.10)(react@18.2.0) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.10)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.10)(react@18.2.0) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.10)(react@18.2.0) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.10)(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + optionalDependencies: + '@types/react': 18.3.10 + '@types/react-dom': 18.3.0 + '@radix-ui/react-slot@1.0.2(@types/react@18.3.10)(react@18.2.0)': dependencies: '@babel/runtime': 7.26.0 @@ -25374,6 +25348,12 @@ snapshots: bech32: 2.0.0 sha256-uint8array: 0.10.7 + bitcoin-address-validation@2.2.3: + dependencies: + base58-js: 1.0.5 + bech32: 2.0.0 + sha256-uint8array: 0.10.7 + bitcoinjs-lib@6.1.5: dependencies: '@noble/hashes': 1.5.0 diff --git a/public/assets/illustrations/sbtc-earn-promo.svg b/public/assets/illustrations/sbtc-earn-promo.svg new file mode 100644 index 00000000000..60ef4c7e85e --- /dev/null +++ b/public/assets/illustrations/sbtc-earn-promo.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/app/common/hooks/use-calculate-sip10-fiat-value.ts b/src/app/common/hooks/use-calculate-sip10-fiat-value.ts new file mode 100644 index 00000000000..1c98f119cd4 --- /dev/null +++ b/src/app/common/hooks/use-calculate-sip10-fiat-value.ts @@ -0,0 +1,42 @@ +import { useMemo } from 'react'; + +import { type MarketData, createMarketData, createMarketPair } from '@leather.io/models'; +import { + useAlexCurrencyPriceAsMarketData, + useCryptoCurrencyMarketDataMeanAverage, +} from '@leather.io/query'; +import { createMoney } from '@leather.io/utils'; + +import { useConfigSbtc } from '@app/query/common/remote-config/remote-config.query'; + +import { getPrincipalFromContractId } from '../utils'; + +function castBitcoinMarketDataToSbtcMarketData(bitcoinMarketData: MarketData) { + return createMarketData( + createMarketPair('sBTC', 'USD'), + createMoney(bitcoinMarketData.price.amount.toNumber(), 'USD') + ); +} + +export function useSip10FiatMarketData() { + const priceAsMarketData = useAlexCurrencyPriceAsMarketData(); + const bitcoinMarketData = useCryptoCurrencyMarketDataMeanAverage('BTC'); + const { isSbtcContract } = useConfigSbtc(); + + return useMemo( + () => ({ + getTokenMarketData(principal: string, symbol: string) { + const lookupIdentifier = principal.includes('::') + ? getPrincipalFromContractId(principal) + : principal; + + if (isSbtcContract(lookupIdentifier)) { + return castBitcoinMarketDataToSbtcMarketData(bitcoinMarketData); + } + + return priceAsMarketData(lookupIdentifier, symbol); + }, + }), + [bitcoinMarketData, isSbtcContract, priceAsMarketData] + ); +} diff --git a/src/app/common/hooks/use-manage-tokens.ts b/src/app/common/hooks/use-manage-tokens.ts index de5bf4ff60e..d713afac8c6 100644 --- a/src/app/common/hooks/use-manage-tokens.ts +++ b/src/app/common/hooks/use-manage-tokens.ts @@ -1,5 +1,6 @@ import { useConfigTokensEnabledByDefault } from '@leather.io/query'; +import { useConfigSbtc } from '@app/query/common/remote-config/remote-config.query'; import { useCurrentAccountIndex } from '@app/store/accounts/account'; import { useUserAllTokens } from '@app/store/manage-tokens/manage-tokens.slice'; @@ -17,6 +18,7 @@ interface FilterTokensArgs { export function useManageTokens() { const configEnabledTokens = useConfigTokensEnabledByDefault(); + const { contractId: sbtcContractId } = useConfigSbtc(); const accountIndex = useCurrentAccountIndex(); const userTokensList = useUserAllTokens(); @@ -29,6 +31,14 @@ export function useManageTokens() { return token?.enabled ?? isEnabledByDefault; } + function sortTokens(tokens: any[]) { + return tokens.sort((a, b) => { + if (a.info.contractId === sbtcContractId) return -1; + if (b.info.contractId === sbtcContractId) return 1; + return 0; + }); + } + function filterTokens({ tokens, filter = 'all', @@ -37,7 +47,9 @@ export function useManageTokens() { }: FilterTokensArgs): T[] { if (filter === 'all') return tokens; - return tokens.filter(t => { + const sortedTokens = sortTokens(tokens); + + return sortedTokens.filter(t => { const tokenId = getTokenId(t); const tokenEnabled = isTokenEnabled({ tokenId, preEnabledTokensIds }); diff --git a/src/app/components/stacks-asset-avatar.tsx b/src/app/components/stacks-asset-avatar.tsx index 706602c3d75..a6d1d8a47b3 100644 --- a/src/app/components/stacks-asset-avatar.tsx +++ b/src/app/components/stacks-asset-avatar.tsx @@ -3,8 +3,8 @@ import { Box, BoxProps } from 'leather-styles/jsx'; import { Avatar, DynamicColorCircle, StxAvatarIcon, defaultFallbackDelay } from '@leather.io/ui'; interface StacksAssetAvatarProps extends BoxProps { - gradientString?: string; imageCanonicalUri?: string; + gradientString: string; isStx?: boolean; size?: string; } diff --git a/src/app/features/asset-list/stacks/sip10-token-asset-list/sip10-token-asset-item.tsx b/src/app/features/asset-list/stacks/sip10-token-asset-list/sip10-token-asset-item.tsx index e47654cd0f0..125485821af 100644 --- a/src/app/features/asset-list/stacks/sip10-token-asset-list/sip10-token-asset-item.tsx +++ b/src/app/features/asset-list/stacks/sip10-token-asset-list/sip10-token-asset-item.tsx @@ -37,13 +37,15 @@ export function Sip10TokenAssetItem({ const { contractId, imageCanonicalUri, name, symbol } = info; const icon = ( - - {name[0]} - + <> + + {name[0]} + + ); const captionLeft = symbol; diff --git a/src/app/features/asset-list/stacks/sip10-token-asset-list/sip10-token-asset-list.tsx b/src/app/features/asset-list/stacks/sip10-token-asset-list/sip10-token-asset-list.tsx index 044c93c755f..8f0a098cfaa 100644 --- a/src/app/features/asset-list/stacks/sip10-token-asset-list/sip10-token-asset-list.tsx +++ b/src/app/features/asset-list/stacks/sip10-token-asset-list/sip10-token-asset-list.tsx @@ -2,9 +2,9 @@ import { type Dispatch, type SetStateAction, useEffect } from 'react'; import { Stack } from 'leather-styles/jsx'; -import { type Sip10TokenAssetDetails, useAlexCurrencyPriceAsMarketData } from '@leather.io/query'; +import { type Sip10TokenAssetDetails } from '@leather.io/query'; -import { getPrincipalFromContractId } from '@app/common/utils'; +import { useSip10FiatMarketData } from '@app/common/hooks/use-calculate-sip10-fiat-value'; import type { AssetRightElementVariant } from '../../asset-list'; import { Sip10TokenAssetItem } from './sip10-token-asset-item'; @@ -25,7 +25,7 @@ export function Sip10TokenAssetList({ preEnabledTokensIds, setHasManageableTokens, }: Sip10TokenAssetListProps) { - const priceAsMarketData = useAlexCurrencyPriceAsMarketData(); + const { getTokenMarketData } = useSip10FiatMarketData(); useEffect(() => { if (tokens.length > 0 && setHasManageableTokens) { @@ -44,8 +44,8 @@ export function Sip10TokenAssetList({ key={token.info.name + token.info.contractId} info={token.info} isLoading={isLoading} - marketData={priceAsMarketData( - getPrincipalFromContractId(token.info.contractId), + marketData={getTokenMarketData( + token.info.contractId, token.balance.availableBalance.symbol )} onSelectAsset={onSelectAsset} diff --git a/src/app/features/sbtc-promo-card/sbtc-promo-card.tsx b/src/app/features/sbtc-promo-card/sbtc-promo-card.tsx new file mode 100644 index 00000000000..ccc398e9eb4 --- /dev/null +++ b/src/app/features/sbtc-promo-card/sbtc-promo-card.tsx @@ -0,0 +1,46 @@ +import { Box, styled } from 'leather-styles/jsx'; + +import { Flag, type FlagProps } from '@leather.io/ui'; + +import { useThemeSwitcher } from '@app/common/theme-provider'; +import { useConfigSbtc } from '@app/query/common/remote-config/remote-config.query'; + +interface SbtcPromoCardContentProps extends FlagProps {} + +function SbtcPromoCardLayout(props: SbtcPromoCardContentProps) { + const { theme } = useThemeSwitcher(); + const invertStyle = theme === 'light' ? '' : 'invert()'; + + return ( + + } + background="ink.background-secondary" + borderRadius={8} + {...props} + > + + + Earn rewards in BTC + + + Enroll your sBTC to unlock yields through the protocol. + + + + ); +} + +export function SbtcPromoCard(props: FlagProps) { + const { shouldDisplayPromoCard } = useConfigSbtc(); + if (!shouldDisplayPromoCard) return null; + return ; +} diff --git a/src/app/pages/home/home.tsx b/src/app/pages/home/home.tsx index ad1cd93b119..303ad935f1a 100644 --- a/src/app/pages/home/home.tsx +++ b/src/app/pages/home/home.tsx @@ -11,8 +11,10 @@ import { useTotalBalance } from '@app/common/hooks/balance/use-total-balance'; import { useOnMount } from '@app/common/hooks/use-on-mount'; import { useSwitchAccountSheet } from '@app/common/switch-account/use-switch-account-sheet-context'; import { whenPageMode } from '@app/common/utils'; +import { openInNewTab } from '@app/common/utils/open-in-new-tab'; import { ActivityList } from '@app/features/activity-list/activity-list'; import { FeedbackButton } from '@app/features/feedback-button/feedback-button'; +import { SbtcPromoCard } from '@app/features/sbtc-promo-card/sbtc-promo-card'; import { Assets } from '@app/pages/home/components/assets'; import { homePageModalRoutes } from '@app/routes/app-routes'; import { ModalBackgroundWrapper } from '@app/routes/components/modal-background-wrapper'; @@ -26,6 +28,8 @@ import { AccountCard } from '@app/ui/components/account/account.card'; import { AccountActions } from './components/account-actions'; import { HomeTabs } from './components/home-tabs'; +const leatherEarnUrl = 'https://earn.leather.io'; + export function Home() { const { decodedAuthRequest } = useOnboardingState(); const { toggleSwitchAccount } = useSwitchAccountSheet(); @@ -75,6 +79,7 @@ export function Home() { > + openInNewTab(leatherEarnUrl)} /> {whenPageMode({ full: , popup: null })} diff --git a/src/app/pages/send/send-crypto-asset-form/form/sip10/sip10-token-send-form.tsx b/src/app/pages/send/send-crypto-asset-form/form/sip10/sip10-token-send-form.tsx index da2a81f0a63..3c7fa17878c 100644 --- a/src/app/pages/send/send-crypto-asset-form/form/sip10/sip10-token-send-form.tsx +++ b/src/app/pages/send/send-crypto-asset-form/form/sip10/sip10-token-send-form.tsx @@ -1,10 +1,11 @@ import { useNavigate, useParams } from 'react-router-dom'; import type { CryptoAssetBalance, MarketData, Sip10CryptoAssetInfo } from '@leather.io/models'; -import { useAlexCurrencyPriceAsMarketData, useSip10Token } from '@leather.io/query'; +import { useSip10Token } from '@leather.io/query'; import { RouteUrls } from '@shared/route-urls'; +import { useSip10FiatMarketData } from '@app/common/hooks/use-calculate-sip10-fiat-value'; import { Content } from '@app/components/layout'; import { PageHeader } from '@app/features/container/headers/page.header'; import { useToast } from '@app/features/toasts/use-toast'; @@ -23,7 +24,7 @@ function Sip10TokenSendFormLoader({ children }: Sip10TokenSendFormLoaderProps) { const { contractId } = useParams(); const stxAddress = useCurrentStacksAccountAddress(); const token = useSip10Token(stxAddress, contractId ?? ''); - const priceAsMarketData = useAlexCurrencyPriceAsMarketData(); + const { getTokenMarketData } = useSip10FiatMarketData(); const toast = useToast(); const navigate = useNavigate(); @@ -37,7 +38,7 @@ function Sip10TokenSendFormLoader({ children }: Sip10TokenSendFormLoaderProps) { return children({ ...token, - marketData: priceAsMarketData(token.info.contractId, token.balance.availableBalance.symbol), + marketData: getTokenMarketData(token.info.contractId, token.balance.availableBalance.symbol), }); } diff --git a/src/app/pages/swap/hooks/use-bitflow-swappable-assets.tsx b/src/app/pages/swap/hooks/use-bitflow-swappable-assets.tsx index bbff32bded6..0c781dd1bf6 100644 --- a/src/app/pages/swap/hooks/use-bitflow-swappable-assets.tsx +++ b/src/app/pages/swap/hooks/use-bitflow-swappable-assets.tsx @@ -8,7 +8,6 @@ import type { Token } from 'bitflow-sdk'; import { createMarketData, createMarketPair } from '@leather.io/models'; import { type SwapAsset, - useAlexCurrencyPriceAsMarketData, useAlexSdkLatestPricesQuery, useStxAvailableUnlockedBalance, useTransferableSip10Tokens, @@ -20,6 +19,7 @@ import { isDefined, } from '@leather.io/utils'; +import { useSip10FiatMarketData } from '@app/common/hooks/use-calculate-sip10-fiat-value'; import { createGetBitflowAvailableTokensQueryOptions } from '@app/query/bitflow-sdk/bitflow-available-tokens.query'; import { sortSwapAssets } from '../swap.utils'; @@ -29,7 +29,7 @@ const USD_DECIMAL_PRECISION = 2; function useCreateSwapAsset(address: string) { const { data: prices } = useAlexSdkLatestPricesQuery(); - const priceAsMarketData = useAlexCurrencyPriceAsMarketData(); + const { getTokenMarketData } = useSip10FiatMarketData(); const availableUnlockedBalance = useStxAvailableUnlockedBalance(address); const sip10Tokens = useTransferableSip10Tokens(address); @@ -70,11 +70,11 @@ function useCreateSwapAsset(address: string) { ...swapAsset, balance: availableBalance ?? createMoney(0, token.symbol, token.tokenDecimals), marketData: availableBalance - ? priceAsMarketData(swapAsset.principal, availableBalance.symbol) - : priceAsMarketData(swapAsset.principal, token.symbol), + ? getTokenMarketData(swapAsset.principal, availableBalance.symbol) + : getTokenMarketData(swapAsset.principal, token.symbol), }; }, - [availableUnlockedBalance, priceAsMarketData, prices, sip10Tokens] + [availableUnlockedBalance, getTokenMarketData, prices, sip10Tokens] ); } diff --git a/src/app/query/common/remote-config/remote-config.query.ts b/src/app/query/common/remote-config/remote-config.query.ts index 894e9b2a8da..8e95c60394b 100644 --- a/src/app/query/common/remote-config/remote-config.query.ts +++ b/src/app/query/common/remote-config/remote-config.query.ts @@ -1,7 +1,11 @@ +import { useMemo } from 'react'; + import { useRemoteConfig } from '@leather.io/query'; +import { getPrincipalFromContractId } from '@leather.io/utils'; import { useWalletType } from '@app/common/use-wallet-type'; import { useHasCurrentBitcoinAccount } from '@app/store/accounts/blockchain/bitcoin/bitcoin.hooks'; +import { useCurrentNetwork } from '@app/store/networks/networks.selectors'; export { HiroMessage, @@ -35,3 +39,27 @@ export function useConfigBitcoinSendEnabled() { software: config?.bitcoinSendEnabled ?? true, }); } + +export function useConfigSbtc() { + const config = useRemoteConfig(); + const sbtc = config?.sbtc; + const network = useCurrentNetwork(); + + return useMemo(() => { + const displayPromoCardOnNetworks = (sbtc as any)?.showPromoLinkOnNetworks ?? []; + const contractIdMainnet = sbtc?.contracts.mainnet.address ?? ''; + const contractIdTestnet = sbtc?.contracts.testnet.address ?? ''; + + return { + contractId: network.chain.bitcoin.mode === 'mainnet' ? contractIdMainnet : contractIdTestnet, + isSbtcEnabled: sbtc?.enabled ?? false, + isSbtcContract(contract: string) { + return ( + contract === getPrincipalFromContractId(sbtc?.contracts.mainnet.address ?? '') || + contract === getPrincipalFromContractId(sbtc?.contracts.testnet.address ?? '') + ); + }, + shouldDisplayPromoCard: displayPromoCardOnNetworks.includes(network.id), + }; + }, [network.chain.bitcoin.mode, network.id, sbtc]); +} diff --git a/src/background/messaging/messaging-utils.ts b/src/background/messaging/messaging-utils.ts index c3daa8e5722..25019dab805 100644 --- a/src/background/messaging/messaging-utils.ts +++ b/src/background/messaging/messaging-utils.ts @@ -74,5 +74,5 @@ export async function triggerRequestWindowOpen(path: RouteUrls, urlParams: URLSe export async function triggerSwapWindowOpen(path: To, urlParams: URLSearchParams) { if (IS_TEST_ENV) return openRequestInFullPage(path, urlParams); - return popup({ url: `/swap.html#${path}?${urlParams.toString()}` }); + return popup({ url: `/popup.html#${path}?${urlParams.toString()}` }); } diff --git a/src/background/messaging/rpc-methods/supported-methods.ts b/src/background/messaging/rpc-methods/supported-methods.ts index 722214b166c..4f699dd7690 100644 --- a/src/background/messaging/rpc-methods/supported-methods.ts +++ b/src/background/messaging/rpc-methods/supported-methods.ts @@ -39,6 +39,10 @@ export function rpcSupportedMethods(message: SupportedMethodsRequest, port: chro docsUrl: 'https://leather.gitbook.io/developers/bitcoin/sign-transactions/partially-signed-bitcoin-transactions-psbts', }, + { + name: 'openSwap', + docsUrl: 'https://leather.gitbook.io/developers/bitcoin/swaps/open-swap', + }, ], }, })