diff --git a/package-lock.json b/package-lock.json
index 62257683..d322bcb6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,9 +14,14 @@
"@emotion/styled": "^11.11.0",
"@fontsource/poppins": "^5.0.8",
"@ls-lint/ls-lint": "^2.2.2",
+ "@noble/hashes": "^1.3.3",
"@reduxjs/toolkit": "^1.9.7",
+ "@scure/base": "^1.1.5",
+ "@scure/bip32": "^1.3.3",
+ "@scure/btc-signer": "^1.2.1",
"@trivago/prettier-plugin-sort-imports": "^4.2.1",
"@types/chrome": "^0.0.248",
+ "bitcoinjs-lib": "^6.1.5",
"concurrently": "^8.2.2",
"decimal.js": "^10.4.3",
"dotenv": "^16.3.1",
@@ -27,6 +32,7 @@
"eslint-plugin-react": "^7.33.2",
"ethers": "5.7.2",
"formik": "^2.4.5",
+ "micro-packed": "^0.5.1",
"prettier": "^3.0.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
@@ -2538,6 +2544,28 @@
"ls-lint": "bin/cli.js"
}
},
+ "node_modules/@noble/curves": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz",
+ "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==",
+ "dependencies": {
+ "@noble/hashes": "1.3.3"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/@noble/hashes": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz",
+ "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==",
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"license": "MIT",
@@ -2630,6 +2658,41 @@
"darwin"
]
},
+ "node_modules/@scure/base": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.5.tgz",
+ "integrity": "sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==",
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/@scure/bip32": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.3.tgz",
+ "integrity": "sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ==",
+ "dependencies": {
+ "@noble/curves": "~1.3.0",
+ "@noble/hashes": "~1.3.2",
+ "@scure/base": "~1.1.4"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/@scure/btc-signer": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@scure/btc-signer/-/btc-signer-1.2.1.tgz",
+ "integrity": "sha512-/Zle18/aWhYDBuBeXGDGJTdo0/LKpQhU8ETBJeWABCQkbk0QHCFCinidTiz9hdQFfh0HtasPGq5p6EodVCfEew==",
+ "dependencies": {
+ "@noble/curves": "~1.3.0",
+ "@noble/hashes": "~1.3.3",
+ "@scure/base": "~1.1.5",
+ "micro-packed": "~0.5.1"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/@sinclair/typebox": {
"version": "0.27.8",
"license": "MIT"
@@ -3443,10 +3506,44 @@
"version": "1.0.2",
"license": "MIT"
},
+ "node_modules/base-x": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz",
+ "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw=="
+ },
"node_modules/bech32": {
"version": "1.1.4",
"license": "MIT"
},
+ "node_modules/bip174": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/bip174/-/bip174-2.1.1.tgz",
+ "integrity": "sha512-mdFV5+/v0XyNYXjBS6CQPLo9ekCx4gtKZFnJm5PMto7Fs9hTTDpkkzOB7/FtluRI6JbUUAu+snTYfJRgHLZbZQ==",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/bitcoinjs-lib": {
+ "version": "6.1.5",
+ "resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-6.1.5.tgz",
+ "integrity": "sha512-yuf6xs9QX/E8LWE2aMJPNd0IxGofwfuVOiYdNUESkc+2bHHVKjhJd8qewqapeoolh9fihzHGoDCB5Vkr57RZCQ==",
+ "dependencies": {
+ "@noble/hashes": "^1.2.0",
+ "bech32": "^2.0.0",
+ "bip174": "^2.1.1",
+ "bs58check": "^3.0.1",
+ "typeforce": "^1.11.3",
+ "varuint-bitcoin": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/bitcoinjs-lib/node_modules/bech32": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz",
+ "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg=="
+ },
"node_modules/bn.js": {
"version": "5.2.1",
"license": "MIT"
@@ -3504,6 +3601,23 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/bs58": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz",
+ "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==",
+ "dependencies": {
+ "base-x": "^4.0.0"
+ }
+ },
+ "node_modules/bs58check": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-3.0.1.tgz",
+ "integrity": "sha512-hjuuJvoWEybo7Hn/0xOrczQKKEKD63WguEjlhLExYs2wUBcebDC1jDNK17eEAD2lYfw82d5ASC1d7K3SWszjaQ==",
+ "dependencies": {
+ "@noble/hashes": "^1.2.0",
+ "bs58": "^5.0.0"
+ }
+ },
"node_modules/cac": {
"version": "6.7.14",
"license": "MIT",
@@ -5452,6 +5566,17 @@
"node": ">= 8"
}
},
+ "node_modules/micro-packed": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/micro-packed/-/micro-packed-0.5.1.tgz",
+ "integrity": "sha512-VjBHcsMAVfivjCZPnqAEEkcihPBbNd39KLEMH76ksL3ORKSZE04gkrtsAmXtaTor67PmTO5h0Rq9+j3PA4zNrw==",
+ "dependencies": {
+ "@scure/base": "~1.1.5"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/micromatch": {
"version": "4.0.5",
"license": "MIT",
@@ -6333,6 +6458,25 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
"node_modules/safe-regex-test": {
"version": "1.0.0",
"license": "MIT",
@@ -6803,6 +6947,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/typeforce": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz",
+ "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g=="
+ },
"node_modules/typescript": {
"version": "5.3.2",
"license": "Apache-2.0",
@@ -6917,6 +7066,14 @@
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
+ "node_modules/varuint-bitcoin": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz",
+ "integrity": "sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw==",
+ "dependencies": {
+ "safe-buffer": "^5.1.1"
+ }
+ },
"node_modules/vite": {
"version": "4.5.0",
"dev": true,
diff --git a/package.json b/package.json
index 4e21eddd..605dc358 100644
--- a/package.json
+++ b/package.json
@@ -24,9 +24,14 @@
"@emotion/styled": "^11.11.0",
"@fontsource/poppins": "^5.0.8",
"@ls-lint/ls-lint": "^2.2.2",
+ "@noble/hashes": "^1.3.3",
"@reduxjs/toolkit": "^1.9.7",
+ "@scure/base": "^1.1.5",
+ "@scure/bip32": "^1.3.3",
+ "@scure/btc-signer": "^1.2.1",
"@trivago/prettier-plugin-sort-imports": "^4.2.1",
"@types/chrome": "^0.0.248",
+ "bitcoinjs-lib": "^6.1.5",
"concurrently": "^8.2.2",
"decimal.js": "^10.4.3",
"dotenv": "^16.3.1",
@@ -37,6 +42,7 @@
"eslint-plugin-react": "^7.33.2",
"ethers": "5.7.2",
"formik": "^2.4.5",
+ "micro-packed": "^0.5.1",
"prettier": "^3.0.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
diff --git a/src/app/app.tsx b/src/app/app.tsx
index 308339b6..b7c2b576 100644
--- a/src/app/app.tsx
+++ b/src/app/app.tsx
@@ -2,6 +2,7 @@ import { Route } from 'react-router-dom';
import { AppLayout } from '@components/app.layout';
import { MyVaults } from '@pages/my-vaults/my-vaults';
+import { ProofOfReservePage } from '@pages/proof-of-reserve/proof-of-reserve-page';
import { BalanceContextProvider } from '@providers/balance-context-provider';
import { About } from './pages/about/about';
@@ -18,6 +19,7 @@ export function App(): React.JSX.Element {
} />
} />
} />
+ } />
diff --git a/src/app/components/mint-unmint/components/lock-screen/lock-screen.tsx b/src/app/components/mint-unmint/components/lock-screen/lock-screen.tsx
index 44c974ad..6edac5b3 100644
--- a/src/app/components/mint-unmint/components/lock-screen/lock-screen.tsx
+++ b/src/app/components/mint-unmint/components/lock-screen/lock-screen.tsx
@@ -1,25 +1,39 @@
-import { useContext, useEffect, useState } from 'react';
+import { useEffect, useState } from 'react';
import { useDispatch } from 'react-redux';
-import { Button, VStack } from '@chakra-ui/react';
+import { Button, VStack, useToast } from '@chakra-ui/react';
import { VaultCard } from '@components/vault/vault-card';
+import { UseBitcoinReturnType } from '@hooks/use-bitcoin';
+import { UseEthereumReturnType } from '@hooks/use-ethereum';
+import { UseSignPSBTReturnType } from '@hooks/use-psbt';
import { useVaults } from '@hooks/use-vaults';
+import { BitcoinError } from '@models/error-types';
import { Vault } from '@models/vault';
-import { BlockchainContext } from '@providers/blockchain-context-provider';
import { mintUnmintActions } from '@store/slices/mintunmint/mintunmint.actions';
import { LockScreenProtocolFee } from './components/protocol-fee';
interface LockScreenProps {
+ bitcoinHandler: UseBitcoinReturnType;
+ ethereumHandler: UseEthereumReturnType;
+ psbtHandler: UseSignPSBTReturnType;
currentStep: [number, string];
}
-export function LockScreen({ currentStep }: LockScreenProps): React.JSX.Element {
+export function LockScreen({
+ currentStep,
+ bitcoinHandler,
+ psbtHandler,
+ ethereumHandler,
+}: LockScreenProps): React.JSX.Element {
+ const toast = useToast();
const dispatch = useDispatch();
+
const { readyVaults } = useVaults();
- const blockchainContext = useContext(BlockchainContext);
- const bitcoin = blockchainContext?.bitcoin;
- const ethereum = blockchainContext?.ethereum;
+
+ const { bitcoinPrice } = bitcoinHandler;
+ const { getProtocolFee } = ethereumHandler;
+ const { handleSignFundingTransaction } = psbtHandler;
const [isSubmitting, setIsSubmitting] = useState(false);
const [protocolFeePercentage, setProtocolFeePercentage] = useState(undefined);
@@ -28,21 +42,31 @@ export function LockScreen({ currentStep }: LockScreenProps): React.JSX.Element
useEffect(() => {
const fetchProtocolFeePercentage = async () => {
- const currentProtocolFeePercentage = await ethereum?.getProtocolFee();
+ const currentProtocolFeePercentage = await getProtocolFee();
setProtocolFeePercentage(currentProtocolFeePercentage);
};
fetchProtocolFeePercentage();
- }, [ethereum]);
+ }, [getProtocolFee]);
async function handleClick(currentVault?: Vault) {
if (!currentVault) return;
try {
setIsSubmitting(true);
- await bitcoin?.fetchBitcoinContractOfferAndSendToUserWallet(currentVault);
+ await handleSignFundingTransaction(currentVault.collateral, currentVault.uuid);
+ setTimeout(() => {
+ dispatch(mintUnmintActions.setMintStep([2, currentVault.uuid]));
+ setIsSubmitting(false);
+ }, 3000);
} catch (error) {
setIsSubmitting(false);
- throw new Error('Error locking vault');
+ toast({
+ title: 'Failed to sign transaction',
+ description: error instanceof BitcoinError ? error.message : '',
+ status: 'error',
+ duration: 9000,
+ isClosable: true,
+ });
}
}
@@ -51,7 +75,7 @@ export function LockScreen({ currentStep }: LockScreenProps): React.JSX.Element