diff --git a/src/components/PageContainer/PageContainer.tsx b/src/components/PageContainer/PageContainer.tsx
index 7d8f2675..7b9cd52d 100644
--- a/src/components/PageContainer/PageContainer.tsx
+++ b/src/components/PageContainer/PageContainer.tsx
@@ -40,11 +40,13 @@ export const PageContainer = ({
keyboardShouldPersistTaps="handled"
noVerticalPadding={noVerticalPadding}
>
- {!header || headerHeight ? children : null}
- {footerButton && }
- {bottom > 0 && !noBottomMargin && !noVerticalPadding && (
-
- )}
+
+ {!header || headerHeight ? children : null}
+ {footerButton && }
+ {bottom > 0 && !noBottomMargin && !noVerticalPadding && (
+
+ )}
+
{footerButton && (
{
onPress: handleSubmit(onSubmit)
}}
>
+
{
getFieldState={getFieldState}
currency={currency}
/>
+
);
};
diff --git a/src/screens/Pos/Pos.tsx b/src/screens/Pos/Pos.tsx
index 5021b122..e22bfef0 100644
--- a/src/screens/Pos/Pos.tsx
+++ b/src/screens/Pos/Pos.tsx
@@ -9,6 +9,7 @@ import {
useRef,
useState
} from "react";
+import { View } from "react-native";
import {
getFormattedUnit,
AsyncStorage,
@@ -134,7 +135,7 @@ export const Pos = () => {
const { unitDecimals, unitDecimalPower } = useMemo(() => {
const _unitDecimals =
currencies.find((c) => c.value === unit)?.decimals ?? DEFAULT_DECIMALS;
- const _unitDecimalPower = getUnitDecimalPower(unit);
+ const _unitDecimalPower = getUnitDecimalPower(unit || "USD");
return { unitDecimals: _unitDecimals, unitDecimalPower: _unitDecimalPower };
}, [unit]);
@@ -159,7 +160,7 @@ export const Pos = () => {
const requestInvoice = useCallback(async () => {
await postInvoice({
amount: decimalFiat,
- unit,
+ unit: unit || "USD",
description,
deviceName,
deviceType
@@ -212,20 +213,20 @@ export const Pos = () => {
const [decimalCount, setDecimalCount] = useState(0);
const [parts, springs, animateAmount] = useAnimateAmount({
- unit,
+ unit: unit || "USD",
initialParts: initialValue,
decimalCount
});
const [plusParts, plusSprings, animatePlusAmount, setPlusParts] =
useAnimateAmount({
- unit,
+ unit: unit || "USD",
mode: AnimationMode.Plus,
animationDelay: PLUS_ANIMATION_DELAY
});
const [totalParts, totalSprings, animateTotalAmount] = useAnimateAmount({
- unit,
+ unit: unit || "USD",
mode: AnimationMode.Plus
});
@@ -368,12 +369,12 @@ export const Pos = () => {
unitDecimals
]);
+ const [symbolsProps, symbolsApi] = useSymbolApi();
+
const [movingPlusProps, movingPlusApi] = useSpring(() => ({
from: { top: 0, scale: 1, color: colors.white, opacity: 1 }
}));
- const [symbolsProps, symbolsApi] = useSymbolApi();
-
const onPlus = useCallback(async () => {
const newPlusParts = parts.filter((p) => !p.remove);
const currentParts = newPlusParts.map((e) => e.text).join("");
@@ -388,7 +389,7 @@ export const Pos = () => {
},
delay: springAnimationDelay,
config: PLUS_ANIMATION_CONFIG
- }));
+ }) as any);
if (plusFiatAmount > 0) {
await movingPlusApi.start(() => ({
@@ -464,9 +465,9 @@ export const Pos = () => {
}, [handleKeyPress]);
const registerRef = useCallback(
- (index: number) => (ref: TouchableOpacity) =>
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
- (inputRef.current[index] = ref),
+ (index: number) => (ref: any) => {
+ inputRef.current[index] = ref;
+ },
[]
);
@@ -567,6 +568,7 @@ export const Pos = () => {
noPadding
noBottomMargin
>
+
{deviceNameModal}
{isAtm && (
@@ -620,7 +622,7 @@ export const Pos = () => {
{totalPartsComponents}
-
+
{
{rowValue.map((columnValue, columnIndex) => (
{
/>
+
) : (
diff --git a/src/screens/Pos/components/NumberInput/NumberInput.tsx b/src/screens/Pos/components/NumberInput/NumberInput.tsx
index 3ceedd0d..44bbd89f 100644
--- a/src/screens/Pos/components/NumberInput/NumberInput.tsx
+++ b/src/screens/Pos/components/NumberInput/NumberInput.tsx
@@ -21,7 +21,7 @@ type NumberInputProps = {
paddingBottom?: number;
};
-export const NumberInput = forwardRef(
+export const NumberInput = forwardRef(
(
{
value,
diff --git a/src/screens/QRScanner/QRScanner.tsx b/src/screens/QRScanner/QRScanner.tsx
index eed34542..a76d83aa 100644
--- a/src/screens/QRScanner/QRScanner.tsx
+++ b/src/screens/QRScanner/QRScanner.tsx
@@ -1,4 +1,5 @@
import { useCallback, useMemo, useState } from "react";
+import { View } from "react-native";
import { useWindowDimensions } from "react-native";
import { useLocation, useNavigate } from "@components/Router";
import { Image, Loader, PageContainer } from "@components";
@@ -99,6 +100,7 @@ export const QRScanner = () => {
/>
)}
+
{!isCameraLoading && !isLoading ? (
<>
@@ -132,6 +134,7 @@ export const QRScanner = () => {
) : (
)}
+
>
);
diff --git a/src/screens/Settings/Settings.tsx b/src/screens/Settings/Settings.tsx
index 7af8c9dd..73450845 100644
--- a/src/screens/Settings/Settings.tsx
+++ b/src/screens/Settings/Settings.tsx
@@ -1,4 +1,5 @@
import { useCallback, useContext, useEffect, useMemo, useState } from "react";
+import { View } from "react-native";
import {
SBPContext,
apiRootUrl,
@@ -272,6 +273,7 @@ export const Settings = () => {
left: { icon: faArrowLeft, onPress: -1 }
}}
>
+
{accountConfig ? (
!accountConfig.isAtm &&
@@ -459,6 +461,7 @@ export const Settings = () => {
{versionTag}
+
);
};
diff --git a/src/screens/SignatureLogin/SignatureLogin.tsx b/src/screens/SignatureLogin/SignatureLogin.tsx
index 31f3799e..7cff840b 100644
--- a/src/screens/SignatureLogin/SignatureLogin.tsx
+++ b/src/screens/SignatureLogin/SignatureLogin.tsx
@@ -1,4 +1,5 @@
import { useCallback, useContext, useRef, useState } from "react";
+import { View } from "react-native";
import { useTranslation } from "react-i18next";
import { SBPContext, apiRootUrl, platform } from "@config";
import { Controller, SubmitHandler, useForm } from "react-hook-form";
@@ -216,7 +217,13 @@ export const SignatureLogin = () => {
signature,
zPub,
words: words.join(" "),
- walletType: "local"
+ walletType: "local",
+ walletConfig: {
+ account: "local",
+ label: "Local Wallet",
+ type: "local",
+ zpub: zPub
+ }
});
} catch (e) {
if (isApiError(e)) {
@@ -296,7 +303,8 @@ export const SignatureLogin = () => {
signature: data.signature,
zPub: data.zPub,
words: data.words,
- walletType: data.walletType
+ walletType: data.walletType,
+ walletConfig: data.walletConfig
});
}
},
@@ -347,6 +355,7 @@ export const SignatureLogin = () => {
title: tRoot("common.login")
}}
>
+
{
+
);
};
diff --git a/src/screens/Signup/Signup.tsx b/src/screens/Signup/Signup.tsx
index 6332cc92..a95f761d 100644
--- a/src/screens/Signup/Signup.tsx
+++ b/src/screens/Signup/Signup.tsx
@@ -1,4 +1,5 @@
import { useCallback, useContext, useEffect, useMemo, useState } from "react";
+import { View } from "react-native";
import {
faArrowLeft,
faAt,
@@ -490,6 +491,7 @@ export const Signup = () => {
onPress: handleSubmit(onSubmit)
}}
>
+
{
/>
+
);
};
diff --git a/src/screens/Wallet/Wallet.tsx b/src/screens/Wallet/Wallet.tsx
index 5dd450f1..ceaca653 100644
--- a/src/screens/Wallet/Wallet.tsx
+++ b/src/screens/Wallet/Wallet.tsx
@@ -1,4 +1,5 @@
import { useCallback, useEffect, useMemo, useState } from "react";
+import { View } from "react-native";
import { useTranslation } from "react-i18next";
import {
Button,
@@ -214,7 +215,9 @@ export const Wallet = () => {
onClose={onSendModalClose}
zPub={zPub}
currentBalance={balance / 100000000}
- />
+ >
+ <>>
+
)}
{
}
: {})}
>
+
@@ -311,6 +315,7 @@ export const Wallet = () => {
})}
/>
+
>
);
diff --git a/src/screens/Wallet/components/SendModal/SendModal.tsx b/src/screens/Wallet/components/SendModal/SendModal.tsx
index e1399ad3..0857416a 100644
--- a/src/screens/Wallet/components/SendModal/SendModal.tsx
+++ b/src/screens/Wallet/components/SendModal/SendModal.tsx
@@ -42,7 +42,7 @@ import {
import { Controller, SubmitHandler, useForm } from "react-hook-form";
import { useToast } from "react-native-toast-notifications";
import { HardwareReadyFunctionParams } from "@components/ConnectWalletModal/ConnectWalletModal";
-import { PrepareTransactionParams } from "@utils/wallet/prepare-transaction";
+import { LocalPrepareTransactionParams } from "@utils/wallet/prepare-transaction";
import { Platform } from "react-native";
import { faBluetooth, faUsb } from "@fortawesome/free-brands-svg-icons";
import { WalletType } from "@components/PayoutConfig/PayoutConfig";
@@ -121,7 +121,8 @@ export const SendModal = ({
useForm({
mode: "onTouched",
defaultValues: {
- isMax: false
+ address: "",
+ feeRate: "1"
}
});
@@ -142,10 +143,9 @@ export const SendModal = ({
useEffect(() => {
(async () => {
setWallet({
- type:
- walletType ||
+ type: (walletType ||
(await AsyncStorage.getItem(keyStoreWalletType)) ||
- "local",
+ "local") as WalletType,
transport: (await AsyncStorage.getItem(keyStoreLedgerBluetoothId))
? "bluetooth"
: undefined
@@ -156,13 +156,13 @@ export const SendModal = ({
const askPassword = useAskPassword();
const awaitWalletTransaction = useCallback(
- async (params: Omit) => {
+ async (params: Omit) => {
return new Promise((resolver, reject) => {
try {
const walletType = wallet?.type;
if (walletType === "local") {
prepareTransaction({
- walletType,
+ walletType: walletType as string,
askWordsPassword: askPassword,
...params
})
@@ -173,14 +173,19 @@ export const SendModal = ({
() => async (walletReadyProps: HardwareReadyFunctionParams) => {
try {
const result = await prepareTransaction({
- walletType,
+ walletType: walletType as string,
...walletReadyProps,
...params
});
- resolver(result);
+ if (result) {
+ resolver(result);
+ } else {
+ reject(new Error("Transaction preparation failed"));
+ }
} catch (e) {
reject(e);
}
+ return { messageToSign: "Transaction prepared" };
}
);
}
@@ -316,7 +321,7 @@ export const SendModal = ({
isOpen={!!customWalletFunction}
customFunction={customWalletFunction}
onClose={onCloseBitboxModal}
- walletType={walletType}
+ walletType={walletType as WalletType}
/>
isMax ||
- (isValidBitcoinAmount(v) && parseFloat(v) <= currentBalance)
+ (v && isValidBitcoinAmount(v) && parseFloat(v) <= currentBalance)
}}
render={({
field: { onChange, onBlur, value = "" },
@@ -446,7 +451,7 @@ export const SendModal = ({
control={control}
rules={{
required: !isMax,
- validate: (v) => isMax || isValidFiatAmount(v)
+ validate: (v) => isMax || (v && isValidFiatAmount(v))
}}
render={({
field: { onChange, onBlur, value = "" },
@@ -490,7 +495,7 @@ export const SendModal = ({
{t("balance")} : {currentBalance} BTC (~{" "}
{accountCurrency
- ? getFormattedUnit(btcToFiat(currentBalance), accountCurrency)
+ ? getFormattedUnit(btcToFiat(currentBalance), accountCurrency, 2)
: ""}
)
@@ -539,16 +544,20 @@ export const SendModal = ({
required: true
}}
render={({ field: { onChange, value } }) => {
- return feesOptions.map((option, index) => (
-
- ));
+ return (
+ <>
+ {feesOptions.map((option, index) => (
+
+ ))}
+ >
+ );
}}
/>
@@ -579,8 +588,8 @@ const FeeOption = ({
const isMedium = useIsScreenSizeMin("medium");
const onPress = useCallback(() => {
- onSelect(option.label);
- }, [onSelect, option.label]);
+ onSelect(option.value);
+ }, [onSelect, option.value]);
return (
{
)} */}
+
{
{versionTag}
+
>
);
diff --git a/src/types/FieldsType.tsx b/src/types/FieldsType.tsx
index 8ebe8462..b3a3804d 100644
--- a/src/types/FieldsType.tsx
+++ b/src/types/FieldsType.tsx
@@ -10,12 +10,12 @@ export enum FieldsType {
}
export const FieldByType = {
- [FieldsType.Text]: (props) => ,
- [FieldsType.Multiline]: (props) => (
+ [FieldsType.Text]: (props: any) => ,
+ [FieldsType.Multiline]: (props: any) => (
),
- [FieldsType.Number]: (props) => ,
- [FieldsType.Email]: (props) => ,
- [FieldsType.Date]: (props) => ,
- [FieldsType.File]: (props) =>
+ [FieldsType.Number]: (props: any) => ,
+ [FieldsType.Email]: (props: any) => ,
+ [FieldsType.Date]: (props: any) => ,
+ [FieldsType.File]: (props: any) =>
};
diff --git a/src/types/styled-component-component-props.ts b/src/types/styled-component-component-props.ts
index 7edb274d..a65df58a 100644
--- a/src/types/styled-component-component-props.ts
+++ b/src/types/styled-component-component-props.ts
@@ -1,7 +1,7 @@
import { ComponentPropsWithRef } from "react";
-import { AnyStyledComponent } from "styled-components";
+import { IStyledComponent } from "styled-components";
-export type StyledComponentComponentProps =
- ComponentPropsWithRef & T extends AnyStyledComponent
+export type StyledComponentComponentProps> =
+ ComponentPropsWithRef & T extends IStyledComponent
? React.ComponentProps
: never;
\ No newline at end of file
diff --git a/src/utils/AsyncStorage/AsyncStorage.native.ts b/src/utils/AsyncStorage/AsyncStorage.native.ts
index a76d4fb8..067733af 100644
--- a/src/utils/AsyncStorage/AsyncStorage.native.ts
+++ b/src/utils/AsyncStorage/AsyncStorage.native.ts
@@ -9,7 +9,7 @@ const getItem = async (key: string, prompt?: Keychain.AuthenticationPrompt) => {
try {
const encryptedValue = await Keychain.getGenericPassword({
service: key,
- rules: SECURE_RULES,
+ // rules: SECURE_RULES // Commented out as rules is not a valid property,
authenticationPrompt: prompt
});
if (encryptedValue) return encryptedValue.password;
@@ -36,7 +36,7 @@ const setItem = async (
return await Keychain.setGenericPassword(key, value, {
service: key,
accessControl,
- rules: SECURE_RULES
+ // rules: SECURE_RULES // Commented out as rules is not a valid property
});
};
diff --git a/src/utils/AsyncStorage/AsyncStorage.ts b/src/utils/AsyncStorage/AsyncStorage.ts
index f76ed8cf..c19e009b 100644
--- a/src/utils/AsyncStorage/AsyncStorage.ts
+++ b/src/utils/AsyncStorage/AsyncStorage.ts
@@ -6,10 +6,10 @@ const textEncoder = new TextEncoder();
const textDecoder = new TextDecoder();
// Convert between binary and Base64
-const arrayBufferToBase64 = (buffer) =>
+const arrayBufferToBase64 = (buffer: ArrayBuffer) =>
btoa(String.fromCharCode(...new Uint8Array(buffer)));
-const base64ToArrayBuffer = (base64) =>
+const base64ToArrayBuffer = (base64: string) =>
Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)).buffer;
// eslint-disable-next-line @typescript-eslint/require-await
diff --git a/src/utils/Bitbox/api/account.ts b/src/utils/Bitbox/api/account.ts
index 43cb1563..3915a519 100644
--- a/src/utils/Bitbox/api/account.ts
+++ b/src/utils/Bitbox/api/account.ts
@@ -16,6 +16,11 @@
import { apiGet, apiPost } from "./request";
+// Mock types for missing imports
+type CoinCode = string;
+type Conversions = any;
+type CoinUnit = string;
+
export type AccountCode = string;
export type TKeystore = {
@@ -40,7 +45,7 @@ export interface IAccount {
}
export const getAccounts = (): Promise => {
- return apiGet("accounts");
+ return apiGet("accounts") as Promise;
};
export interface IReceiveAddress {
@@ -56,7 +61,7 @@ export interface ReceiveAddressList {
export const getReceiveAddressList = (
code: AccountCode
): Promise => {
- return apiGet(`account/${code}/receive-addresses`);
+ return apiGet(`account/${code}/receive-addresses`) as Promise;
};
export type ScriptType = "p2pkh" | "p2wpkh-p2sh" | "p2wpkh" | "p2tr";
@@ -90,7 +95,7 @@ export type TSigningConfigurationList = null | {
export const getInfo = (
code: AccountCode
): Promise => {
- return apiGet(`account/${code}/info`);
+ return apiGet(`account/${code}/info`) as Promise;
};
export type AddressSignResponse =
@@ -110,7 +115,7 @@ export const signAddress = (
msg: string,
code: AccountCode
): Promise => {
- return apiPost(`account/${code}/sign-address`, { format, msg, code });
+ return apiPost(`account/${code}/sign-address`, { format, msg, code }) as Promise;
};
export type FeeTargetCode = "custom" | "low" | "economy" | "normal" | "high";
@@ -147,7 +152,7 @@ export const proposeTx = (
accountCode: AccountCode,
txInput: TTxInput
): Promise => {
- return apiPost(`account/${accountCode}/tx-proposal`, txInput);
+ return apiPost(`account/${accountCode}/tx-proposal`, txInput) as Promise;
};
export type ISendTx =
@@ -163,5 +168,5 @@ export type ISendTx =
};
export const sendTx = (code: AccountCode): Promise => {
- return apiPost(`account/${code}/sendtx`);
+ return apiPost(`account/${code}/sendtx`) as Promise;
};
\ No newline at end of file
diff --git a/src/utils/Bitbox/api/bitbox02.ts b/src/utils/Bitbox/api/bitbox02.ts
index dc5279b3..4019c792 100644
--- a/src/utils/Bitbox/api/bitbox02.ts
+++ b/src/utils/Bitbox/api/bitbox02.ts
@@ -35,17 +35,17 @@ type DeviceInfoResponse = SuccessResponse & {
export const getDeviceInfo = (
deviceID: string
): Promise => {
- return apiGet(`devices/bitbox02/${deviceID}/info`);
+ return apiGet(`devices/bitbox02/${deviceID}/info`) as Promise;
};
export const checkSDCard = (deviceID: string): Promise => {
- return apiGet(`devices/bitbox02/${deviceID}/check-sdcard`);
+ return apiGet(`devices/bitbox02/${deviceID}/check-sdcard`) as Promise;
};
export const insertSDCard = (
deviceID: string
): Promise => {
- return apiPost(`devices/bitbox02/${deviceID}/insert-sdcard`);
+ return apiPost(`devices/bitbox02/${deviceID}/insert-sdcard`) as Promise;
};
export const setDeviceName = (
@@ -54,18 +54,18 @@ export const setDeviceName = (
): Promise => {
return apiPost(`devices/bitbox02/${deviceID}/set-device-name`, {
name: newDeviceName
- });
+ }) as Promise;
};
export const createBackup = (
deviceID: string,
method: "sdcard" | "recovery-words"
): Promise => {
- return apiPost(`devices/bitbox02/${deviceID}/backups/create`, method);
+ return apiPost(`devices/bitbox02/${deviceID}/backups/create`, method) as Promise;
};
export const upgradeDeviceFirmware = (deviceID: string): Promise => {
- return apiPost(`devices/bitbox02/${deviceID}/upgrade-firmware`);
+ return apiPost(`devices/bitbox02/${deviceID}/upgrade-firmware`) as Promise;
};
export type TStatus =
@@ -79,7 +79,7 @@ export type TStatus =
| "uninitialized";
export const getStatus = (deviceID: string): Promise => {
- return apiGet(`devices/bitbox02/${deviceID}/status`);
+ return apiGet(`devices/bitbox02/${deviceID}/status`) as Promise;
};
type TChannelHash = {
@@ -88,19 +88,19 @@ type TChannelHash = {
};
export const getChannelHash = (deviceID: string): Promise => {
- return apiGet(`devices/bitbox02/${deviceID}/channel-hash`);
+ return apiGet(`devices/bitbox02/${deviceID}/channel-hash`) as Promise;
};
export const verifyChannelHash = (
deviceID: string,
ok: boolean
): Promise => {
- return apiPost(`devices/bitbox02/${deviceID}/channel-hash-verify`, ok);
+ return apiPost(`devices/bitbox02/${deviceID}/channel-hash-verify`, ok) as Promise;
};
export const setPassword = (
deviceID: string,
seedLen: 16 | 32
): Promise => {
- return apiPost(`devices/bitbox02/${deviceID}/set-password`, seedLen);
+ return apiPost(`devices/bitbox02/${deviceID}/set-password`, seedLen) as Promise;
};
diff --git a/src/utils/Bitbox/api/bitbox02bootloader.ts b/src/utils/Bitbox/api/bitbox02bootloader.ts
index 203c1b62..12d868fe 100644
--- a/src/utils/Bitbox/api/bitbox02bootloader.ts
+++ b/src/utils/Bitbox/api/bitbox02bootloader.ts
@@ -27,11 +27,12 @@ export type TStatus = {
};
export const getStatus = (deviceID: string): Promise => {
- return apiGet(`devices/bitbox02-bootloader/${deviceID}/status`);
+ return apiGet(`devices/bitbox02-bootloader/${deviceID}/status`) as Promise;
};
export const useSyncStatus = () => {
- const { subscribeEndpoint } = useContext(SBPBitboxContext);
+ const context = useContext(SBPBitboxContext);
+ const subscribeEndpoint = (context as any).subscribeEndpoint;
return (deviceID: string) => (cb: TSubscriptionCallback) => {
return subscribeEndpoint(
@@ -53,13 +54,13 @@ export type TVersionInfo = {
};
export const getVersionInfo = (deviceID: string): Promise => {
- return apiGet(`devices/bitbox02-bootloader/${deviceID}/version-info`);
+ return apiGet(`devices/bitbox02-bootloader/${deviceID}/version-info`) as Promise;
};
export const upgradeFirmware = (deviceID: string): Promise => {
- return apiPost(`devices/bitbox02-bootloader/${deviceID}/upgrade-firmware`);
+ return apiPost(`devices/bitbox02-bootloader/${deviceID}/upgrade-firmware`) as Promise;
};
export const screenRotate = (deviceID: string): Promise => {
- return apiPost(`devices/bitbox02-bootloader/${deviceID}/screen-rotate`);
+ return apiPost(`devices/bitbox02-bootloader/${deviceID}/screen-rotate`) as Promise;
};
diff --git a/src/utils/Bitbox/api/devices.ts b/src/utils/Bitbox/api/devices.ts
index 5e2af74b..1bc64ce5 100644
--- a/src/utils/Bitbox/api/devices.ts
+++ b/src/utils/Bitbox/api/devices.ts
@@ -23,5 +23,5 @@ export type TDevices = {
};
export const getDeviceList = (): Promise => {
- return apiGet("devices/registered");
+ return apiGet("devices/registered") as Promise;
};
diff --git a/src/utils/Bitbox/api/event.ts b/src/utils/Bitbox/api/event.ts
index 991c65f0..0ba4eba4 100644
--- a/src/utils/Bitbox/api/event.ts
+++ b/src/utils/Bitbox/api/event.ts
@@ -15,7 +15,8 @@
* limitations under the License.
*/
-import { TUnsubscribe } from "./websocket";
+// Mock type for missing websocket import
+type TUnsubscribe = () => void;
import { TEvent } from "./transport-common";
export type { TEvent, TUnsubscribe };
diff --git a/src/utils/Bitbox/api/request.ts b/src/utils/Bitbox/api/request.ts
index 62f24d1e..0c360f87 100644
--- a/src/utils/Bitbox/api/request.ts
+++ b/src/utils/Bitbox/api/request.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-export const call: (query: string) => Promise = window?.bitboxAndroidSend;
+export const call: (query: string) => Promise = (window as any)?.bitboxAndroidSend;
export const apiGet = (endpoint: string) => {
return call(
diff --git a/src/utils/FS/FS.ts b/src/utils/FS/FS.ts
index 26dd3003..47f5e57f 100644
--- a/src/utils/FS/FS.ts
+++ b/src/utils/FS/FS.ts
@@ -2,7 +2,9 @@ const readFile = async (
_filepath: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_encodingOrOptions?: any
-): Promise => {};
+): Promise => {
+ return "";
+};
const FS = { readFile };
diff --git a/src/utils/Linking/Linking.ts b/src/utils/Linking/Linking.ts
index d3070422..f049f05e 100644
--- a/src/utils/Linking/Linking.ts
+++ b/src/utils/Linking/Linking.ts
@@ -5,5 +5,5 @@ export const Linking: Pick = {
window.location.href = url;
return new Promise(() => null);
},
- canOpenURL: (url: string) => true
+ canOpenURL: (url: string) => Promise.resolve(true)
};
diff --git a/src/utils/Printer/Printer.native.ts b/src/utils/Printer/Printer.native.ts
index c9833cad..9e731d6f 100644
--- a/src/utils/Printer/Printer.native.ts
+++ b/src/utils/Printer/Printer.native.ts
@@ -19,7 +19,13 @@ export const printLabelValue = async (label: string, value: string) => {
TOTAL_WIDTH - label.length - value.length
)}${THOUSAND_SPACE.repeat(thousandsSpaceNb)}${value}`;
await printText(text, {
- font: NyxFont.monospace
+ font: NyxFont.monospace,
+ textSize: 12,
+ underline: false,
+ textScaleX: 1.0,
+ textScaleY: 1.0,
+ align: 0,
+ color: 0x000000
});
} catch (e) {
console.error("error", e);
diff --git a/src/utils/Printer/Printer.ts b/src/utils/Printer/Printer.ts
index 9bb5a5d7..a6419b07 100644
--- a/src/utils/Printer/Printer.ts
+++ b/src/utils/Printer/Printer.ts
@@ -8,11 +8,11 @@ export enum PrinterAlignValue {
type PrinterType = (typeof PrinterNative)["Printer"];
-const printLabelValue: PrinterType["printLabelValue"] = () => {};
-const printText: PrinterType["printText"] = () => {};
-const printQrCode: PrinterType["printQrCode"] = () => {};
-const paperOut: PrinterType["paperOut"] = () => {};
-const printBitmap: PrinterType["printBitmap"] = () => {};
+const printLabelValue: PrinterType["printLabelValue"] = async () => {};
+const printText: PrinterType["printText"] = async () => 0;
+const printQrCode: PrinterType["printQrCode"] = async () => 0;
+const paperOut: PrinterType["paperOut"] = async () => 0;
+const printBitmap: PrinterType["printBitmap"] = async () => 0;
const Printer = {
printLabelValue,
diff --git a/src/utils/diffStrings.ts b/src/utils/diffStrings.ts
index 6eab7f86..df5af4eb 100644
--- a/src/utils/diffStrings.ts
+++ b/src/utils/diffStrings.ts
@@ -20,7 +20,7 @@ export const diffStrings = (
newIndex < newAmount.length &&
oldAmount[oldIndex] === newAmount[newIndex]
) {
- array.push({ text: oldAmount[oldIndex] });
+ array.push({ id: uuidv4(), text: oldAmount[oldIndex] });
oldIndex++;
newIndex++;
} else if (
@@ -28,26 +28,26 @@ export const diffStrings = (
newAmount[newIndex] === decimalSeparator
) {
if (oldIndex < oldAmount.length) {
- array.push({ text: oldAmount[oldIndex], remove: true });
+ array.push({ id: uuidv4(), text: oldAmount[oldIndex], remove: true });
oldIndex++;
}
if (newIndex < newAmount.length) {
- array.push({ text: newAmount[newIndex], add: true });
+ array.push({ id: uuidv4(), text: newAmount[newIndex], add: true });
newIndex++;
}
} else {
if (oldIndex < oldAmount.length) {
- array.push({ text: oldAmount[oldIndex], remove: true });
+ array.push({ id: uuidv4(), text: oldAmount[oldIndex], remove: true });
oldIndex++;
}
if (newIndex < newAmount.length) {
- array.push({ text: newAmount[newIndex], add: true });
+ array.push({ id: uuidv4(), text: newAmount[newIndex], add: true });
newIndex++;
}
}
}
} else {
- array.push({ text: oldStr, remove: true });
+ array.push({ id: uuidv4(), text: oldStr, remove: true });
}
return degroup(array);
diff --git a/src/utils/formattedUnitChanges.ts b/src/utils/formattedUnitChanges.ts
index 9d61ddc9..0ffb1d63 100644
--- a/src/utils/formattedUnitChanges.ts
+++ b/src/utils/formattedUnitChanges.ts
@@ -19,22 +19,23 @@ export const formattedUnitChanges = (
if (typeof add === "number") {
if (!rightPart || (leftPart === "0" && rightPart[0] === "0")) {
- array.push({ text: leftPart });
+ array.push({ id: uuidv4(), text: leftPart });
decimalSwitch = !rightPart;
} else {
if (leftPart === "0" && decimalCount === 0) {
- array.push({ text: "0", remove: true });
+ array.push({ id: uuidv4(), text: "0", remove: true });
} else {
- array.push({ text: leftPart });
+ array.push({ id: uuidv4(), text: leftPart });
}
if (decimalCount === 0) {
- array.push({ text: decimalSeparator, remove: true });
- array.push({ text: rightPart[0] });
+ array.push({ id: uuidv4(), text: decimalSeparator, remove: true });
+ array.push({ id: uuidv4(), text: rightPart[0] });
decimalSwitch = true;
}
}
array.push({
+ id: uuidv4(),
text: decimalSeparator,
add: decimalSwitch && decimalCount === 0
});
@@ -43,64 +44,64 @@ export const formattedUnitChanges = (
if (!rightPart) {
if (decimalCount === 2) {
- array.push({ text: firstChar, add: true });
+ array.push({ id: uuidv4(), text: firstChar, add: true });
} else {
- array.push({ text: "0", add: true });
+ array.push({ id: uuidv4(), text: "0", add: true });
}
} else {
if (rightPart[0] === "0" && leftPart === "0" && decimalCount !== 1) {
- array.push({ text: "0", remove: true });
+ array.push({ id: uuidv4(), text: "0", remove: true });
if (decimalCount === 2) {
- array.push({ text: firstChar, add: true });
- array.push({ text: "0" });
+ array.push({ id: uuidv4(), text: firstChar, add: true });
+ array.push({ id: uuidv4(), text: "0" });
}
}
if (decimalCount === 0) {
- array.push({ text: rightPart.slice(-1) });
+ array.push({ id: uuidv4(), text: rightPart.slice(-1) });
} else if (decimalCount === 1) {
- array.push({ text: rightPart[0] });
+ array.push({ id: uuidv4(), text: rightPart[0] });
if (firstChar === "0") {
- array.push({ text: "0", add: true });
+ array.push({ id: uuidv4(), text: "0", add: true });
} else {
if (decimalCount !== 1) {
- array.push({ text: "0", remove: true });
+ array.push({ id: uuidv4(), text: "0", remove: true });
}
- array.push({ text: firstChar, add: true });
+ array.push({ id: uuidv4(), text: firstChar, add: true });
}
}
}
if (decimalCount === 0) {
- array.push({ text: firstChar, add: true });
+ array.push({ id: uuidv4(), text: firstChar, add: true });
}
} else if (add === "delete") {
if (leftPart === "0") {
- array.push({ text: leftPart });
+ array.push({ id: uuidv4(), text: leftPart });
} else {
if (leftPart.length === 1) {
- array.push({ text: "0", add: true });
+ array.push({ id: uuidv4(), text: "0", add: true });
}
if (leftPart.length >= 1) {
- array.push({ text: leftPart.slice(0, -1) });
- array.push({ text: decimalSeparator, add: true });
+ array.push({ id: uuidv4(), text: leftPart.slice(0, -1) });
+ array.push({ id: uuidv4(), text: decimalSeparator, add: true });
decimalSwitch = true;
}
}
if (decimalCount === 2 && !rightPart) {
- array.push({ text: decimalSeparator, remove: true });
+ array.push({ id: uuidv4(), text: decimalSeparator, remove: true });
}
if (leftPart !== "0") {
- array.push({ text: leftPart[leftPart.length - 1] });
- array.push({ text: decimalSeparator, remove: decimalSwitch });
+ array.push({ id: uuidv4(), text: leftPart[leftPart.length - 1] });
+ array.push({ id: uuidv4(), text: decimalSeparator, remove: decimalSwitch });
} else {
- array.push({ text: decimalSeparator, add: decimalSwitch });
- array.push({ text: "0", add: true });
+ array.push({ id: uuidv4(), text: decimalSeparator, add: decimalSwitch });
+ array.push({ id: uuidv4(), text: "0", add: true });
}
- array.push({ text: rightPart[0] });
+ array.push({ id: uuidv4(), text: rightPart[0] });
if (decimalCount !== 1) {
- array.push({ text: rightPart[1], remove: true });
+ array.push({ id: uuidv4(), text: rightPart[1], remove: true });
}
} else if (add === "clear") {
const isRightPartDefined = rightPart !== undefined;
@@ -108,9 +109,10 @@ export const formattedUnitChanges = (
if (leftPart !== "0") {
if (!isRightPartDefined) {
- array.push({ text: "0" });
+ array.push({ id: uuidv4(), text: "0" });
}
array.push({
+ id: uuidv4(),
text: leftPart.slice(
isRightPartDefined ? 0 : 1,
isLastLeftPartCharZero ? -1 : undefined
@@ -119,7 +121,7 @@ export const formattedUnitChanges = (
});
}
if (isLastLeftPartCharZero) {
- array.push({ text: "0" });
+ array.push({ id: uuidv4(), text: "0" });
}
const isLastRightPartCharZero =
@@ -132,48 +134,49 @@ export const formattedUnitChanges = (
!isLastLeftPartCharZero &&
isRightPartDefined
) {
- array.push({ text: "0", add: leftPart !== "0" });
+ array.push({ id: uuidv4(), text: "0", add: leftPart !== "0" });
}
if (decimalCount === 2 && !rightPart) {
- array.push({ text: decimalSeparator, remove: true });
+ array.push({ id: uuidv4(), text: decimalSeparator, remove: true });
}
if (rightPart) {
array.push({
+ id: uuidv4(),
text: `${decimalSeparator}${rightPart.slice(0, isLastRightPartCharZero ? -1 : undefined)}`,
remove: true
});
}
if (isLastRightPartCharZero) {
- array.push({ text: "0" });
+ array.push({ id: uuidv4(), text: "0" });
}
} else if (add === "decimal") {
if (!rightPart) {
- array.push({ text: leftPart });
- array.push({ text: decimalSeparator, add: true });
+ array.push({ id: uuidv4(), text: leftPart });
+ array.push({ id: uuidv4(), text: decimalSeparator, add: true });
} else {
if (decimalCount === 0) {
- array.push({ text: leftPart, remove: leftPart === "0" });
- array.push({ text: decimalSeparator, remove: true });
+ array.push({ id: uuidv4(), text: leftPart, remove: leftPart === "0" });
+ array.push({ id: uuidv4(), text: decimalSeparator, remove: true });
if (rightPart === "00") {
- array.push({ text: "00" });
+ array.push({ id: uuidv4(), text: "00" });
}
const fullRight = rightPart.replace(/^0+/, "");
if (fullRight.length === 1) {
- array.push({ text: "0", remove: leftPart === "0" });
+ array.push({ id: uuidv4(), text: "0", remove: leftPart === "0" });
}
- array.push({ text: fullRight });
+ array.push({ id: uuidv4(), text: fullRight });
}
- array.push({ text: decimalSeparator, add: true });
+ array.push({ id: uuidv4(), text: decimalSeparator, add: true });
}
}
} else {
- array.push({ text: amount });
+ array.push({ id: uuidv4(), text: amount });
}
- return degroup(array).map((r) => ({ ...r, id: uuidv4() }));
+ return degroup(array);
};
const degroup = (array: StringPart[]) => {
@@ -184,6 +187,7 @@ const degroup = (array: StringPart[]) => {
if (elem.add || elem.remove) {
degroupArr.push(
...elem.text.split("").map((c) => ({
+ id: uuidv4(),
text: c,
add: elem.add,
remove: elem.remove
diff --git a/src/utils/getFormattedUnit.ts b/src/utils/getFormattedUnit.ts
index 1284b8b9..7569ccc1 100644
--- a/src/utils/getFormattedUnit.ts
+++ b/src/utils/getFormattedUnit.ts
@@ -23,7 +23,7 @@ export const getFormattedUnit = (
amount: number,
unit: string,
floating?: number,
- trailingDecimal?: boolean = false
+ trailingDecimal: boolean = false
) => {
let prefix = "";
if (amount > 0 && amount < 0.01 && unit !== "BTC") {
diff --git a/src/utils/measureText/measureText.native.ts b/src/utils/measureText/measureText.native.ts
index f839aefb..dcc4afe8 100644
--- a/src/utils/measureText/measureText.native.ts
+++ b/src/utils/measureText/measureText.native.ts
@@ -8,6 +8,6 @@ export const measureText = (
return RNTextSize.measure({
text,
fontSize,
- fontFamily
+ fontFamily: fontFamily as string
});
};
diff --git a/src/utils/measureText/measureText.tsx b/src/utils/measureText/measureText.tsx
index 51baeef5..d8654e01 100644
--- a/src/utils/measureText/measureText.tsx
+++ b/src/utils/measureText/measureText.tsx
@@ -5,7 +5,7 @@ const ctx = document.createElement("canvas").getContext("2d");
export type MeasureTextFont = {
fontSize: number;
- fontFamily: number;
+ fontFamily: string;
};
export const measureText = (
@@ -14,7 +14,11 @@ export const measureText = (
) => {
return new Promise<{ width: number }>((resolve) => {
const elem = document.createElement("div");
- ctx.font = `${fontSize}px ${fontFamily}`;
- resolve({ width: ctx?.measureText(text).width || 0 });
+ if (ctx) {
+ ctx.font = `${fontSize}px ${fontFamily}`;
+ resolve({ width: ctx.measureText(text).width || 0 });
+ } else {
+ resolve({ width: 0 });
+ }
});
};
diff --git a/src/utils/scaleDimensions.ts b/src/utils/scaleDimensions.ts
index d1bcfca1..af0a1bab 100644
--- a/src/utils/scaleDimensions.ts
+++ b/src/utils/scaleDimensions.ts
@@ -1,4 +1,4 @@
-export const scaleDimensions = (width, height, maxWidth, maxHeight) => {
+export const scaleDimensions = (width: number, height: number, maxWidth: number, maxHeight: number) => {
const widthRatio = maxWidth / width;
const heightRatio = maxHeight / height;
diff --git a/src/utils/wallet/bitbox02/prepare/prepare.android.ts b/src/utils/wallet/bitbox02/prepare/prepare.android.ts
index d4630915..491c39fb 100644
--- a/src/utils/wallet/bitbox02/prepare/prepare.android.ts
+++ b/src/utils/wallet/bitbox02/prepare/prepare.android.ts
@@ -1,13 +1,21 @@
import { getInfo } from "@utils/Bitbox/api/account";
-import { PrepareFunction } from "@utils/wallet/types";
+import { PrepareFunction, PrepareTransactionParams, PrepareTransactionReturn } from "@utils/wallet/types";
import { DEFAULT_SCRIPT_TYPE } from "@config";
-export const prepareTransaction: PrepareFunction = async ({ account }) => {
+export const prepareTransaction: PrepareFunction = async ({ account }: PrepareTransactionParams): Promise => {
+ if (!account) {
+ throw new Error("Account is required for Android BitBox02");
+ }
+
const accountInfo = await getInfo(account);
const masterFingerprint = accountInfo?.signingConfigurations.find(
(v) => v.bitcoinSimple.scriptType === DEFAULT_SCRIPT_TYPE
)?.bitcoinSimple.keyInfo.rootFingerprint;
+ if (!masterFingerprint) {
+ throw new Error("Master fingerprint not found");
+ }
+
return { masterFingerprint };
};
diff --git a/src/utils/wallet/bitbox02/prepare/prepare.ts b/src/utils/wallet/bitbox02/prepare/prepare.ts
index 4cfe1d39..85929d54 100644
--- a/src/utils/wallet/bitbox02/prepare/prepare.ts
+++ b/src/utils/wallet/bitbox02/prepare/prepare.ts
@@ -1,5 +1,7 @@
-import { PrepareFunction } from "@utils/wallet/types";
+import { PrepareFunction, PrepareTransactionParams, PrepareTransactionReturn } from "@utils/wallet/types";
-export const prepareTransaction: PrepareFunction = (
+export const prepareTransaction: PrepareFunction = async (
_params: PrepareTransactionParams
-): Promise => ({});
+): Promise => {
+ return { masterFingerprint: "" };
+};
diff --git a/src/utils/wallet/bitbox02/transaction/transaction.android.ts b/src/utils/wallet/bitbox02/transaction/transaction.android.ts
index bd66de6c..d1f5d022 100644
--- a/src/utils/wallet/bitbox02/transaction/transaction.android.ts
+++ b/src/utils/wallet/bitbox02/transaction/transaction.android.ts
@@ -1,5 +1,5 @@
import { TTxInput, proposeTx, sendTx } from "@utils/Bitbox/api/account";
-import { CreateFunction } from "@utils/wallet/types";
+import { CreateFunction, CreateTransactionParams, CreateTransactionReturn } from "@utils/wallet/types";
const txInputHashToString = (txInputHash: Uint8Array) => {
return Array.from(txInputHash)
@@ -12,11 +12,19 @@ export const createTransaction: CreateFunction = async ({
account,
psbt,
feeRate
-}) => {
+}: CreateTransactionParams): Promise => {
+ if (!account) {
+ throw new Error("Account is required for Android BitBox02");
+ }
+
const psbtOutput =
psbt.txOutputs[psbt.data.outputs.findIndex((v) => !v.bip32Derivation)];
const outputAddress = psbtOutput.address;
+ if (!outputAddress) {
+ throw new Error("Output address not found");
+ }
+
const outputValue = (Number(psbtOutput.value) / 100000000).toString();
const selectedUTXOs = psbt.txInputs.map(
@@ -41,5 +49,5 @@ export const createTransaction: CreateFunction = async ({
}
}
- return {};
+ return undefined;
};
diff --git a/src/utils/wallet/bitbox02/transaction/transaction.ts b/src/utils/wallet/bitbox02/transaction/transaction.ts
index e670f598..6540dbc8 100644
--- a/src/utils/wallet/bitbox02/transaction/transaction.ts
+++ b/src/utils/wallet/bitbox02/transaction/transaction.ts
@@ -1,7 +1,7 @@
-import { CreateFunction } from "@utils/wallet/types";
+import { CreateFunction, CreateTransactionParams, CreateTransactionReturn } from "@utils/wallet/types";
-export const createTransaction: CreateFunction = (
+export const createTransaction: CreateFunction = async (
_props: CreateTransactionParams
-) => {
- return { txHex: "" };
+): Promise => {
+ return { txHex: "", psbt: _props.psbt };
};
diff --git a/src/utils/wallet/ledger/prepare.ts b/src/utils/wallet/ledger/prepare.ts
index 07a890ee..1239c8bc 100644
--- a/src/utils/wallet/ledger/prepare.ts
+++ b/src/utils/wallet/ledger/prepare.ts
@@ -1,11 +1,15 @@
-import { PrepareFunction } from "@utils/wallet/types";
+import { PrepareFunction, PrepareTransactionParams, PrepareTransactionReturn } from "@utils/wallet/types";
import { AppClient } from "ledger-bitcoin";
export const prepareTransaction: PrepareFunction = async ({
hardwareWallet
-}) => {
+}: PrepareTransactionParams): Promise => {
+ if (!hardwareWallet) {
+ throw new Error("Hardware wallet is required for Ledger");
+ }
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
- const app = new AppClient(hardwareWallet._transport);
+ const app = new AppClient((hardwareWallet as any)._transport);
const masterFingerprint = await app.getMasterFingerprint();
diff --git a/src/utils/wallet/ledger/transaction.ts b/src/utils/wallet/ledger/transaction.ts
index 7861f7a5..c2c80168 100644
--- a/src/utils/wallet/ledger/transaction.ts
+++ b/src/utils/wallet/ledger/transaction.ts
@@ -1,4 +1,4 @@
-import { CreateFunction } from "@utils/wallet/types";
+import { CreateFunction, CreateTransactionParams, CreateTransactionReturn } from "@utils/wallet/types";
import AppClient, { DefaultWalletPolicy } from "ledger-bitcoin";
import * as bitcoin from "bitcoinjs-lib";
@@ -9,9 +9,13 @@ export const createTransaction: CreateFunction = async ({
psbt,
rootPath,
masterFingerprint
-}) => {
+}: CreateTransactionParams): Promise => {
+ if (!hardwareWallet) {
+ throw new Error("Hardware wallet is required for Ledger");
+ }
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
- const app = new AppClient(hardwareWallet._transport);
+ const app = new AppClient((hardwareWallet as any)._transport);
const xpub = await app.getExtendedPubkey(`${rootPath}`, false);
@@ -20,12 +24,12 @@ export const createTransaction: CreateFunction = async ({
`[${masterFingerprint}/${rootPath.replace("m/", "")}]${xpub}`
);
- const ledgerSignature = await app.signPsbt(psbt.toBase64(), signingPolicy);
+ const ledgerSignature = await app.signPsbt(psbt.toBase64(), signingPolicy, null);
const newTxIsSegwit = true;
for (let index = 0; index < ledgerSignature.length; index++) {
- const { pubkey, signature } = ledgerSignature[index][1];
+ const [inputIndex, { pubkey, signature }] = ledgerSignature[index];
const signer = {
network: NETWORK,
@@ -33,10 +37,10 @@ export const createTransaction: CreateFunction = async ({
sign: () => {
const encodedSignature = (() => {
if (newTxIsSegwit) {
- return Buffer.from(signature, "hex");
+ return Buffer.from(signature as unknown as string, "hex");
}
return Buffer.concat([
- Buffer.from(signature, "hex"),
+ Buffer.from(signature as unknown as string, "hex"),
Buffer.from("01", "hex") // SIGHASH_ALL
]);
})();
@@ -45,7 +49,7 @@ export const createTransaction: CreateFunction = async ({
}
};
- psbt.signInput(index, signer);
+ psbt.signInput(inputIndex, signer);
}
psbt.finalizeAllInputs();
diff --git a/src/utils/wallet/prepare-transaction.ts b/src/utils/wallet/prepare-transaction.ts
index ed949acf..536a5586 100644
--- a/src/utils/wallet/prepare-transaction.ts
+++ b/src/utils/wallet/prepare-transaction.ts
@@ -13,7 +13,7 @@ import {
} from "bitcoin-address-validation";
import axios from "axios";
import { HardwareReadyFunctionParams } from "@components/ConnectWalletModal/ConnectWalletModal";
-import { Wallet } from "./types";
+import { Wallet, PrepareTransactionParams as WalletPrepareTransactionParams, CreateTransactionParams as WalletCreateTransactionParams } from "./types";
import { Bip84Account } from "@types";
import { DEFAULT_NETWORK } from "@config";
import { AsyncStorage } from "@utils/AsyncStorage";
@@ -71,7 +71,7 @@ type OutputsTypes = {
const getAddressType: (
address: string
-) => InputAddressTypes | OutputAddressTypes = (address: string) => {
+) => InputAddressTypes | OutputAddressTypes | undefined = (address: string) => {
if (validate(address)) {
const addressInfo = getAddressInfo(address);
@@ -87,11 +87,12 @@ const getAddressType: (
case AddressType.p2tr:
return "P2TR";
}
- return addressInfo.type;
+ return addressInfo.type as any;
}
+ return undefined;
};
-export type PrepareTransactionParams = {
+export type LocalPrepareTransactionParams = {
zPub: string;
utxos: FormattedUtxo[];
receiveAddress: string;
@@ -113,26 +114,30 @@ export const prepareTransaction = async ({
account,
walletType,
askWordsPassword
-}: PrepareTransactionParams) => {
- let wallet: Wallet;
+}: LocalPrepareTransactionParams) => {
+ let wallet: Wallet | undefined;
let pathPrefix = "";
switch (walletType) {
case "local":
- wallet = local;
+ wallet = local as any;
break;
case "bitbox02":
- wallet = bitbox02;
+ wallet = bitbox02 as any;
break;
case "ledger":
- wallet = ledger;
+ wallet = ledger as any;
// pathPrefix = "m/";
break;
default:
- break;
+ throw new Error(`Unsupported wallet type: ${walletType}`);
+ }
+
+ if (!wallet) {
+ throw new Error("Wallet not initialized");
}
- let inputs: InputsTypes = {};
- let outputs: OutputsTypes = {};
+ let inputs: Partial = {};
+ let outputs: Partial = {};
const psbt = new Psbt({ network: DEFAULT_NETWORK });
@@ -150,32 +155,38 @@ export const prepareTransaction = async ({
account,
rootPath,
askWordsPassword
- });
+ } as any);
const receiveAddressType = getAddressType(receiveAddress);
- outputs = {
- ...outputs,
- [receiveAddressType]: (outputs[receiveAddressType] || 0) + 1
- };
-
- if (changeAddress) {
- const changeAddressType = getAddressType(changeAddress.address);
+ if (receiveAddressType) {
outputs = {
...outputs,
- [changeAddressType]: (outputs[changeAddressType] || 0) + 1
+ [receiveAddressType]: ((outputs as any)[receiveAddressType] || 0) + 1
};
}
+ if (changeAddress) {
+ const changeAddressType = getAddressType(changeAddress.address);
+ if (changeAddressType) {
+ outputs = {
+ ...outputs,
+ [changeAddressType]: ((outputs as any)[changeAddressType] || 0) + 1
+ };
+ }
+ }
+
const usedUtxos: FormattedUtxo[] = [];
let inputAmount = 0;
let finalFee = 0;
for (const utxo of utxos) {
const addressType = getAddressType(utxo.address);
- inputs = {
- ...inputs,
- [addressType]: (inputs[addressType] || 0) + 1
- };
+ if (addressType) {
+ inputs = {
+ ...inputs,
+ [addressType]: ((inputs as any)[addressType] || 0) + 1
+ };
+ }
const { data: rawTx } = await axios.get(
`https://mempool.space/api/tx/${utxo.txid}/hex`
@@ -261,19 +272,19 @@ export const prepareTransaction = async ({
};
// Inspired by https://gist.github.com/junderw/b43af3253ea5865ed52cb51c200ac19c
-const getByteCount = (inputs: InputsTypes, outputs: OutputsTypes) => {
+const getByteCount = (inputs: Partial, outputs: Partial) => {
let totalWeight = 0;
let hasWitness = false;
let inputCount = 0;
let outputCount = 0;
// assumes compressed pubkeys in all cases.
- function checkUInt53(n) {
+ function checkUInt53(n: number) {
if (n < 0 || n > Number.MAX_SAFE_INTEGER || n % 1 !== 0)
throw new RangeError("value out of range");
}
- function varIntLength(number) {
+ function varIntLength(number: number) {
checkUInt53(number);
return number < 0xfd
@@ -286,30 +297,36 @@ const getByteCount = (inputs: InputsTypes, outputs: OutputsTypes) => {
}
Object.keys(inputs).forEach(function (key) {
- checkUInt53(inputs[key]);
- if (key.slice(0, 8) === "MULTISIG") {
- // ex. "MULTISIG-P2SH:2-3" would mean 2 of 3 P2SH MULTISIG
- const keyParts = key.split(":");
- if (keyParts.length !== 2) throw new Error("invalid input: " + key);
- const newKey = keyParts[0];
- const mAndN = keyParts[1].split("-").map(function (item) {
- return parseInt(item);
- });
-
- totalWeight += types.inputs[newKey] * inputs[key];
- const multiplyer = newKey === "MULTISIG-P2SH" ? 4 : 1;
- totalWeight += (73 * mAndN[0] + 34 * mAndN[1]) * multiplyer * inputs[key];
- } else {
- totalWeight += types.inputs[key] * inputs[key];
+ const inputCountValue = inputs[key as keyof InputsTypes];
+ if (inputCountValue) {
+ checkUInt53(inputCountValue);
+ if (key.slice(0, 8) === "MULTISIG") {
+ // ex. "MULTISIG-P2SH:2-3" would mean 2 of 3 P2SH MULTISIG
+ const keyParts = key.split(":");
+ if (keyParts.length !== 2) throw new Error("invalid input: " + key);
+ const newKey = keyParts[0] as keyof typeof types.inputs;
+ const mAndN = keyParts[1].split("-").map(function (item) {
+ return parseInt(item);
+ });
+
+ totalWeight += types.inputs[newKey] * inputCountValue;
+ const multiplyer = newKey === "MULTISIG-P2SH" ? 4 : 1;
+ totalWeight += (73 * mAndN[0] + 34 * mAndN[1]) * multiplyer * inputCountValue;
+ } else {
+ totalWeight += types.inputs[key as keyof typeof types.inputs] * inputCountValue;
+ }
+ inputCount += inputCountValue;
+ if (key.indexOf("W") >= 0) hasWitness = true;
}
- inputCount += inputs[key];
- if (key.indexOf("W") >= 0) hasWitness = true;
});
Object.keys(outputs).forEach(function (key) {
- checkUInt53(outputs[key]);
- totalWeight += types.outputs[key] * outputs[key];
- outputCount += outputs[key];
+ const outputCountValue = outputs[key as keyof OutputsTypes];
+ if (outputCountValue) {
+ checkUInt53(outputCountValue);
+ totalWeight += types.outputs[key as keyof typeof types.outputs] * outputCountValue;
+ outputCount += outputCountValue;
+ }
});
if (hasWitness) totalWeight += 2;
diff --git a/src/utils/wallet/trezor/prepare.ts b/src/utils/wallet/trezor/prepare.ts
index 3d7b4f62..85929d54 100644
--- a/src/utils/wallet/trezor/prepare.ts
+++ b/src/utils/wallet/trezor/prepare.ts
@@ -1,3 +1,7 @@
-import { PrepareFunction } from "@utils/wallet/types";
+import { PrepareFunction, PrepareTransactionParams, PrepareTransactionReturn } from "@utils/wallet/types";
-export const prepareTransaction: PrepareFunction = async () => {};
+export const prepareTransaction: PrepareFunction = async (
+ _params: PrepareTransactionParams
+): Promise => {
+ return { masterFingerprint: "" };
+};
diff --git a/src/utils/wallet/trezor/transaction.ts b/src/utils/wallet/trezor/transaction.ts
index cb91e029..6958cc15 100644
--- a/src/utils/wallet/trezor/transaction.ts
+++ b/src/utils/wallet/trezor/transaction.ts
@@ -1,4 +1,4 @@
-import { CreateFunction } from "@utils/wallet/types";
+import { CreateFunction, CreateTransactionParams, CreateTransactionReturn } from "@utils/wallet/types";
import AppClient, { DefaultWalletPolicy } from "ledger-bitcoin";
import * as bitcoin from "bitcoinjs-lib";
@@ -9,9 +9,13 @@ export const createTransaction: CreateFunction = async ({
psbt,
rootPath,
masterFingerprint
-}) => {
+}: CreateTransactionParams): Promise => {
+ if (!hardwareWallet) {
+ throw new Error("Hardware wallet is required for Trezor");
+ }
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
- const app = new AppClient(hardwareWallet._transport);
+ const app = new AppClient((hardwareWallet as any)._transport);
const xpub = await app.getExtendedPubkey(`m/${rootPath}`, false);
@@ -20,12 +24,12 @@ export const createTransaction: CreateFunction = async ({
`[${masterFingerprint}/${rootPath}]${xpub}`
);
- const ledgerSignature = await app.signPsbt(psbt.toBase64(), signingPolicy);
+ const ledgerSignature = await app.signPsbt(psbt.toBase64(), signingPolicy, null);
const newTxIsSegwit = true;
for (let index = 0; index < ledgerSignature.length; index++) {
- const { pubkey, signature } = ledgerSignature[index][1];
+ const [inputIndex, { pubkey, signature }] = ledgerSignature[index];
const signer = {
network: NETWORK,
@@ -33,10 +37,10 @@ export const createTransaction: CreateFunction = async ({
sign: () => {
const encodedSignature = (() => {
if (newTxIsSegwit) {
- return Buffer.from(signature, "hex");
+ return Buffer.from(signature as unknown as string, "hex");
}
return Buffer.concat([
- Buffer.from(signature, "hex"),
+ Buffer.from(signature as unknown as string, "hex"),
Buffer.from("01", "hex") // SIGHASH_ALL
]);
})();
@@ -45,7 +49,7 @@ export const createTransaction: CreateFunction = async ({
}
};
- psbt.signInput(index, signer);
+ psbt.signInput(inputIndex, signer);
}
psbt.finalizeAllInputs();
diff --git a/src/utils/wallet/types.ts b/src/utils/wallet/types.ts
index d4c83e14..2603a9cd 100644
--- a/src/utils/wallet/types.ts
+++ b/src/utils/wallet/types.ts
@@ -6,7 +6,7 @@ import { Psbt } from "bitcoinjs-lib";
export type HardwareWallet = PairedBitBox | Btc;
-type PrepareTransactionParams = {
+export type PrepareTransactionParams = {
// ledger, bitbox-web
hardwareWallet?: HardwareWallet;
@@ -16,7 +16,7 @@ type PrepareTransactionParams = {
rootPath: string;
};
-type PrepareTransactionReturn = {
+export type PrepareTransactionReturn = {
masterFingerprint: string;
bip84Account?: Bip84PrivateAccount;
};
@@ -25,7 +25,7 @@ export type PrepareFunction = (
_params: PrepareTransactionParams
) => Promise;
-type CreateTransactionParams = {
+export type CreateTransactionParams = {
psbt: Psbt;
feeRate: number;
usedUtxos: FormattedUtxo[];