Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
diff --git a/node_modules/@bitpay-labs/bitcore-wallet-client/ts_build/src/lib/tsskey.js b/node_modules/@bitpay-labs/bitcore-wallet-client/ts_build/src/lib/tsskey.js
index d073bca..cdeaea3 100644
index b21da63..5075941 100644
--- a/node_modules/@bitpay-labs/bitcore-wallet-client/ts_build/src/lib/tsskey.js
+++ b/node_modules/@bitpay-labs/bitcore-wallet-client/ts_build/src/lib/tsskey.js
@@ -118,17 +118,19 @@ class TssKeyGen extends events_1.EventEmitter {
Expand All @@ -23,3 +23,18 @@ index d073bca..cdeaea3 100644
__classPrivateFieldGet(this, _TssKeyGen_request, "f").setCredentials(__classPrivateFieldGet(this, _TssKeyGen_credentials, "f"));
__classPrivateFieldSet(this, _TssKeyGen_requestPrivateKey, crypto_wallet_core_1.BitcoreLib.PrivateKey.fromString(__classPrivateFieldGet(this, _TssKeyGen_credentials, "f").requestPrivKey), "f");
const baseXPrivKey = __classPrivateFieldGet(this, _TssKeyGen_key, "f").get(params.password).xPrivKey;
diff --git a/node_modules/@bitpay-labs/bitcore-wallet-client/ts_build/src/lib/tsssign.js b/node_modules/@bitpay-labs/bitcore-wallet-client/ts_build/src/lib/tsssign.js
index f8e7463..f096163 100644
--- a/node_modules/@bitpay-labs/bitcore-wallet-client/ts_build/src/lib/tsssign.js
+++ b/node_modules/@bitpay-labs/bitcore-wallet-client/ts_build/src/lib/tsssign.js
@@ -84,7 +84,9 @@ class TssSign extends events_1.EventEmitter {
}
async restoreSession(params) {
const { session } = params;
- const [id, sigSession] = session.split(':');
+ const lastColon = session.lastIndexOf(':');
+ const id = session.slice(0, lastColon);
+ const sigSession = session.slice(lastColon + 1);
this.id = id;
__classPrivateFieldSet(this, _TssSign_sign, await bitcore_tss_1.ECDSA.Sign.restore({
session: sigSession,
3 changes: 3 additions & 0 deletions src/navigation/wallet/WalletGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ const WalletGroup = ({Wallet, theme}: WalletProps) => {
/>
<Wallet.Screen
options={{
gestureEnabled: false,
headerLeft: () => null,
}}
name={WalletScreens.BACKUP_SHARED_KEY}
Expand Down Expand Up @@ -424,6 +425,8 @@ const WalletGroup = ({Wallet, theme}: WalletProps) => {
/>
<Wallet.Screen
options={{
gestureEnabled: false,
headerLeft: () => null,
headerTitle: () => (
<HeaderTitle>{t('Invite Co-Signers')}</HeaderTitle>
),
Expand Down
110 changes: 87 additions & 23 deletions src/navigation/wallet/components/TSSProgressTracker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,57 @@ const TSSProgressTracker: React.FC<TSSProgressTrackerProps> = ({
const [showSigningHelp, setShowSigningHelp] = useState(false);
const signingStartedAt = useRef<number | null>(null);

const copayerOpacities = useRef<Map<string, Animated.Value>>(
new Map(),
).current;
const [hiddenCopayerIds, setHiddenCopayerIds] = useState<Set<string>>(
new Set(),
);
const fadeAnimationDone = useRef(false);

useEffect(() => {
copayers.forEach(c => {
if (!copayerOpacities.has(c.id)) {
copayerOpacities.set(c.id, new Animated.Value(1));
}
});
}, [copayers, copayerOpacities]);

useEffect(() => {
if (status !== 'signature_generation') {
fadeAnimationDone.current = false;
setHiddenCopayerIds(new Set());
copayerOpacities.forEach(opacity => opacity.setValue(1));
}
}, [status, copayerOpacities]);

useEffect(() => {
if (status !== 'signature_generation') return;
if (fadeAnimationDone.current) return;
const signedCount = copayers.filter(c => c.signed).length;
const m = wallet?.tssMetadata?.m ?? copayers.length;
if (signedCount < m) return;

fadeAnimationDone.current = true;

const toFade = copayers.filter(c => !c.signed);
if (!toFade.length) return;

const animations = toFade
.map(c => copayerOpacities.get(c.id))
.filter((v): v is Animated.Value => !!v)
.map(opacity =>
Animated.timing(opacity, {
toValue: 0,
duration: 400,
useNativeDriver: true,
}),
);
Animated.parallel(animations).start(() => {
setHiddenCopayerIds(new Set(toFade.map(c => c.id)));
});
}, [status, copayers, copayerOpacities, wallet]);

useEffect(() => {
if (status === 'signature_generation') {
if (signingStartedAt.current === null) {
Expand Down Expand Up @@ -370,6 +421,10 @@ const TSSProgressTracker: React.FC<TSSProgressTrackerProps> = ({
return 'pending';
};

const creatorCopayerName = wallet?.copayers?.find(
c => c.id === txpCreatorId,
)?.name;

const steps = [
{
title: t('Proposal Created'),
Expand All @@ -392,13 +447,7 @@ const TSSProgressTracker: React.FC<TSSProgressTrackerProps> = ({
];

const handleClose = () => {
if (
status !== 'complete' &&
status !== 'broadcasting' &&
status !== 'signature_generation'
) {
setModalVisible(false);
}
setModalVisible(false);
};

useEffect(() => {
Expand Down Expand Up @@ -516,25 +565,40 @@ const TSSProgressTracker: React.FC<TSSProgressTrackerProps> = ({
</HelpBanner>
)}
{step.subtitle && (
<StepSubtitle>{step.subtitle}</StepSubtitle>
<StepSubtitle>
{index === 0 && creatorCopayerName
? `${step.subtitle} - ${t(
'Created by',
)}: ${creatorCopayerName}`
: step.subtitle}
</StepSubtitle>
)}

{showCopayers && (
{showCopayers && copayers.length > 0 && (
<CopayerList style={{marginTop: 8}}>
{copayers.map((copayer, idx) => (
<CopayerRow key={copayer.id || idx}>
<CopayerIndicator signed={copayer.signed}>
{copayer.signed ? (
<SuccessIcon width={12} height={12} />
) : (
<Loader size={16} spinning />
)}
</CopayerIndicator>
<CopayerName signed={copayer.signed}>
{copayer.name}
</CopayerName>
</CopayerRow>
))}
{copayers
.filter(c => !hiddenCopayerIds.has(c.id))
.map(copayer => (
<Animated.View
key={copayer.id}
style={{
opacity:
copayerOpacities.get(copayer.id) ?? 1,
}}>
<CopayerRow>
<CopayerIndicator signed={copayer.signed}>
{copayer.signed ? (
<SuccessIcon width={12} height={12} />
) : (
<Loader size={16} spinning />
)}
</CopayerIndicator>
<CopayerName signed={copayer.signed}>
{copayer.name}
</CopayerName>
</CopayerRow>
</Animated.View>
))}
</CopayerList>
)}
</StepContent>
Expand Down
3 changes: 3 additions & 0 deletions src/navigation/wallet/screens/InviteCosigners.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ import {useTheme} from 'styled-components/native';
import {useNavigation} from '@react-navigation/native';
import {TouchableOpacity} from '../../../components/base/TouchableOpacity';
import Back from '../../../components/back/Back';
import {useAndroidBackHandler} from 'react-navigation-backhandler';

const Container = styled.SafeAreaView`
flex: 1;
Expand Down Expand Up @@ -318,6 +319,8 @@ const InviteCosigners: React.FC<Props> = ({route}) => {
const {height: screenHeight} = useWindowDimensions();
const isSmallScreen = screenHeight < 700;

useAndroidBackHandler(() => true);

const {keyId} = route.params;
const key = useAppSelector(({WALLET}) => WALLET.keys[keyId]);
const tssSession = key?.tssSession;
Expand Down
7 changes: 7 additions & 0 deletions src/navigation/wallet/screens/JoinTSSWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {NativeStackScreenProps} from '@react-navigation/native-stack';
import {useTranslation} from 'react-i18next';
import QRCode from 'react-native-qrcode-svg';
import {useTheme} from 'styled-components/native';
import {useAndroidBackHandler} from 'react-navigation-backhandler';
import {WalletGroupParamList, WalletScreens} from '../WalletGroup';
import {useAppDispatch, useAppSelector} from '../../../utils/hooks';
import {
Expand Down Expand Up @@ -207,6 +208,9 @@ const JoinTSSWallet: React.FC<Props> = ({navigation, route}) => {
const [partyKey, setPartyKey] = useState<any>(null);
const [isLoading, setIsLoading] = useState(false);
const [currentStep, setCurrentStep] = useState(0);

useAndroidBackHandler(() => currentStep === 3);

// const [showInviteInput, setShowInviteInput] = useState(false);
const [showWaitingCopayers, setShowWaitingCopayers] = useState(false);
const [inviteCode, setInviteCode] = useState('');
Expand Down Expand Up @@ -473,9 +477,12 @@ const JoinTSSWallet: React.FC<Props> = ({navigation, route}) => {
useLayoutEffect(() => {
const showMenu = currentStep === 1 || currentStep === 2;
navigation.setOptions({
gestureEnabled: currentStep !== 3,
headerLeft:
currentStep === 2
? () => <HeaderBackButton onPress={() => setCurrentStep(1)} />
: currentStep === 3
? () => null
: undefined,
headerRight: showMenu
? () => <Settings onPress={() => setShowOptions(true)} />
Expand Down
5 changes: 4 additions & 1 deletion src/navigation/wallet/screens/TransactionProposalDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ const TransactionProposalDetails = () => {
);

const [showTSSProgressModal, setShowTSSProgressModal] = useState(false);
const [hasSwiped, setHasSwiped] = useState(false);
const [tssStatus, setTssStatus] = useState<TSSSigningStatus>(
'waiting_for_cosigners',
);
Expand Down Expand Up @@ -564,6 +565,7 @@ const TransactionProposalDetails = () => {
const onSwipeComplete = async () => {
try {
if (isTSSWallet(wallet)) {
setHasSwiped(true);
await joinTSSSigning();
return;
}
Expand Down Expand Up @@ -749,7 +751,7 @@ const TransactionProposalDetails = () => {
{isTSSWallet(wallet) ? (
<>
{(txp.creatorId === wallet.credentials.copayerId ||
txp.canBeRemoved) &&
Math.floor(Date.now() / 1000) - txp.createdOn > 10 * 60) &&
!key.isReadOnly && (
<Button
testID="txp-details-tss-delete-proposal-button"
Expand Down Expand Up @@ -800,6 +802,7 @@ const TransactionProposalDetails = () => {
isModalVisible={showTSSProgressModal}
onModalVisibilityChange={setShowTSSProgressModal}
txpCreatorId={transaction.creatorId}
hideTracker={!hasSwiped}
/>
)}

Expand Down
Loading
Loading