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',
+ },
],
},
})