Skip to content
Merged
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
41 changes: 0 additions & 41 deletions .github/copilot-instructions.md

This file was deleted.

4 changes: 3 additions & 1 deletion DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Agents must:
- use existing theme tokens, styles, spacing, radius, typography, and colors from code where available
- use existing navigation, card, button, list, modal, sheet, form, and warning patterns
- build new UI from existing primitives where possible
- if an SVG is provided as input for a UI element, use that SVG in implementation unless a requirement explicitly says otherwise
- avoid hardcoding one-off values unless there is no existing token or component pattern
- keep feature-specific flow and copy decisions inside the relevant requirement spec
- treat this document as design guidance, not business logic
Expand Down Expand Up @@ -586,6 +587,7 @@ Rules:
- do not put long multi-step flows inside a bottom sheet unless existing Keeper patterns already do this
- use full screens for complex tasks
- keep CTA placement predictable
- keep modal CTA text short and action-specific to prevent button text overflow

# UI content and wording

Expand Down Expand Up @@ -745,4 +747,4 @@ This DESIGN.md provides:
When there is conflict:
- product behavior follows the feature spec
- implementation values follow the codebase
- visual judgment follows this DESIGN.md
- visual judgment follows this DESIGN.md
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ android {
applicationId "io.hexawallet.keeper"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 594
versionName "2.5.11"
versionCode 596
versionName "2.5.12"
missingDimensionStrategy 'react-native-camera', 'general'
missingDimensionStrategy 'store', 'play'
multiDexEnabled true
Expand Down
2 changes: 1 addition & 1 deletion ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3959,7 +3959,7 @@ SPEC CHECKSUMS:
glog: 5683914934d5b6e4240e497e0f4a3b42d1854183
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
hermes-engine: c35a887d0a1856e5c339a78517f0fb3357a135b5
hermes-engine: aa404dd2f865314cd211641ddff59d06039dbcf1
HtmlToPdf: 6a9c28f54ec810d1d120a698a9b3c83e2bdb1672
libportal-ios: d9aa55474e2d5be8e38e96345dd37be34fda45b4
libportal-react-native: 91b6bec36f7e92a0bcc4e9d51d6ce3ee7c163728
Expand Down
16 changes: 8 additions & 8 deletions ios/hexa_keeper.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 594;
CURRENT_PROJECT_VERSION = 596;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = Y5TCB759QL;
ENABLE_BITCODE = NO;
Expand Down Expand Up @@ -851,7 +851,7 @@
"$(inherited)",
"\"$(SRCROOT)\"",
);
MARKETING_VERSION = 2.5.11;
MARKETING_VERSION = 2.5.12;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
Expand Down Expand Up @@ -879,7 +879,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 594;
CURRENT_PROJECT_VERSION = 596;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = Y5TCB759QL;
HEADER_SEARCH_PATHS = (
Expand Down Expand Up @@ -980,7 +980,7 @@
"$(inherited)",
"\"$(SRCROOT)\"",
);
MARKETING_VERSION = 2.5.11;
MARKETING_VERSION = 2.5.12;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
Expand Down Expand Up @@ -1150,7 +1150,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 594;
CURRENT_PROJECT_VERSION = 596;
DEVELOPMENT_TEAM = Y5TCB759QL;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = Y5TCB759QL;
ENABLE_BITCODE = NO;
Expand Down Expand Up @@ -1253,7 +1253,7 @@
"$(PROJECT_DIR)",
"\"$(SRCROOT)\"",
);
MARKETING_VERSION = 2.5.11;
MARKETING_VERSION = 2.5.12;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
Expand Down Expand Up @@ -1281,7 +1281,7 @@
CODE_SIGN_ENTITLEMENTS = hexa_keeper_dev.entitlements;
CODE_SIGN_IDENTITY = "Apple Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CURRENT_PROJECT_VERSION = 594;
CURRENT_PROJECT_VERSION = 596;
DEVELOPMENT_TEAM = Y5TCB759QL;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = Y5TCB759QL;
HEADER_SEARCH_PATHS = (
Expand Down Expand Up @@ -1383,7 +1383,7 @@
"$(PROJECT_DIR)",
"\"$(SRCROOT)\"",
);
MARKETING_VERSION = 2.5.11;
MARKETING_VERSION = 2.5.12;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
Expand Down
2 changes: 1 addition & 1 deletion ios/hexa_keeper/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>594</string>
<string>596</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>itms-apps</string>
Expand Down
2 changes: 1 addition & 1 deletion ios/hexa_keeperTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>594</string>
<string>596</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion ios/hexa_keeper_dev-Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>594</string>
<string>596</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>itms-apps</string>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hexa_keeper",
"version": "2.5.11",
"version": "2.5.12",
"private": true,
"scripts": {
"ios": "npx react-native run-ios --scheme=hexa_keeper_dev --simulator 'iPhone 16' ",
Expand Down
38 changes: 38 additions & 0 deletions patches/react-native-tcp-socket+6.4.1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
diff --git a/node_modules/react-native-tcp-socket/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java b/node_modules/react-native-tcp-socket/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java
index e0f719f..6908996 100644
--- a/node_modules/react-native-tcp-socket/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java
+++ b/node_modules/react-native-tcp-socket/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java
@@ -51,7 +51,6 @@ class TcpSocketClient extends TcpSocket {
// Get the addresses
final String localAddress = options.hasKey("localAddress") ? options.getString("localAddress") : "0.0.0.0";
final InetAddress localInetAddress = InetAddress.getByName(localAddress);
- final InetAddress remoteInetAddress = InetAddress.getByName(address);
if (network != null)
network.bindSocket(socket);
// setReuseAddress
@@ -66,7 +65,8 @@ class TcpSocketClient extends TcpSocket {
// bind
socket.bind(new InetSocketAddress(localInetAddress, localPort));
final int connectTimeout = options.hasKey("connectTimeout") ? options.getInt("connectTimeout") : 0;
- socket.connect(new InetSocketAddress(remoteInetAddress, port), connectTimeout);
+ // Keep the original hostname to let TLS stacks build SNI/peer identity correctly.
+ socket.connect(new InetSocketAddress(address, port), connectTimeout);
if (socket instanceof SSLSocket) ((SSLSocket) socket).startHandshake();
startListening();
}
@@ -74,7 +74,14 @@ class TcpSocketClient extends TcpSocket {
public void startTLS(Context context, ReadableMap tlsOptions) throws IOException, GeneralSecurityException {
if (socket instanceof SSLSocket) return;
SSLSocketFactory ssf = getSSLSocketFactory(context, tlsOptions);
- SSLSocket sslSocket = (SSLSocket) ssf.createSocket(socket, socket.getInetAddress().getHostAddress(), socket.getPort(), true);
+ String peerHost = socket.getInetAddress().getHostName();
+ if (tlsOptions.hasKey("host")) {
+ String host = tlsOptions.getString("host");
+ if (host != null && !host.isEmpty()) {
+ peerHost = host;
+ }
+ }
+ SSLSocket sslSocket = (SSLSocket) ssf.createSocket(socket, peerHost, socket.getPort(), true);
sslSocket.setUseClientMode(true);
sslSocket.startHandshake();
socket = sslSocket;
1 change: 0 additions & 1 deletion src/components/KeeperModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,6 @@ const getStyles = (subTitleWidth) =>
alignSelf: 'flex-start',
borderBottomWidth: 0,
backgroundColor: 'transparent',
width: '90%',
marginTop: wp(5),
},
bodyContainer: {
Expand Down
15 changes: 13 additions & 2 deletions src/components/KeeperQRCode.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import QRCode from 'react-native-qrcode-svg';
import React from 'react';
import { StyleSheet } from 'react-native';
import React, { useEffect, useState } from 'react';
import { Platform, StyleSheet } from 'react-native';

import { Box, useColorMode } from '@gluestack-ui/themed-native-base';
import { useSelector } from 'react-redux';
Expand All @@ -23,13 +23,24 @@ function KeeperQRCode({
const { colorMode } = useColorMode();
const themeMode = useSelector((state: any) => state?.settings?.themeMode);
const privateTheme = themeMode === 'PRIVATE' || themeMode === 'PRIVATE_LIGHT';

// Workaround for react-native-svg not painting on initial mount with Fabric (new architecture) on iOS.
// Toggling the key forces a remount of the QRCode SVG after the first frame.
const [renderKey, setRenderKey] = useState(0);
useEffect(() => {
if (Platform.OS === 'ios') {
requestAnimationFrame(() => setRenderKey(1));
}
}, []);

return (
<Box
style={[styles.qrWrapper, { width: size + 20, height: size + 20 }]}
borderColor={`${colorMode}.headerWhite`}
>
{qrData && (
<QRCode
key={renderKey}
value={qrData}
{...(logoBackgroundColor ? { logoBackgroundColor } : {})}
size={size}
Expand Down
4 changes: 2 additions & 2 deletions src/context/Localization/language/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@
"skipWarningBody": "Unexpected software issues, app updates, device loss, or damaged app data can make wallet recovery fail without your Recovery Key.",
"skipWarningBox": "Your Keeper backup and hot wallets may not be recoverable.",
"skipWarningInfoBox": "Backing up takes less than a minute and can save your funds and data.",
"backUpRecoveryKey": "Back Up Recovery Key",
"continueWithoutBackup": "Continue Without Backup",
"backUpRecoveryKey": "Backup Now",
"continueWithoutBackup": "Skip Backup",
"skipWarningFooter": "You can back up your Recovery Key anytime from Settings.",
"recoveryKeyNotBackedUp": "Recovery Key not backed up"
},
Expand Down
14 changes: 13 additions & 1 deletion src/context/Localization/language/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,19 @@
"securityTipDesc": "Recreate the multisig on more coordinators. Receive a small amount and send a part of it. Check the balances are appropriately reflected across all the coordinators after each step.",
"backupModalTitle": "Confirm your Recovery Key",
"backupModalSubTitle": "To make sure your Recovery Key is not lost, you need to confirm it.",
"backupModalDesc": "Keeper keeps a protected copy of your Keeper data, encrypted using your Recovery Key, to help with app recovery. Keeper cannot read this data."
"backupModalDesc": "Keeper keeps a protected copy of your Keeper data, encrypted using your Recovery Key, to help with app recovery. Keeper cannot read this data.",
"educationSheetTitle": "Protect Your Recovery Key",
"educationSheetBody": "Your Recovery Key helps restore your Keeper backup and hot wallets if you change devices or need to recover the app.\n\nOnly you control this key. Keeper cannot recover it for you.",
"backUpNow": "Back Up Now",
"skipForNow": "Skip for Now",
"skipWarningTitle": "Continue Without Backup?",
"skipWarningBody": "Unexpected software issues, app updates, device loss, or damaged app data can make wallet recovery fail without your Recovery Key.",
"skipWarningBox": "Your Keeper backup and hot wallets may not be recoverable.",
"skipWarningInfoBox": "Backing up takes less than a minute and can save your funds and data.",
"backUpRecoveryKey": "Backup Now",
"continueWithoutBackup": "Skip Backup",
"skipWarningFooter": "You can back up your Recovery Key anytime from Settings.",
"recoveryKeyNotBackedUp": "Recovery Key not backed up"
},
"transactions": {
"Fees": "Fees",
Expand Down
1 change: 0 additions & 1 deletion src/screens/AppSettings/Node/NodeSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { hp, wp } from 'src/constants/responsive';
import { LocalizationContext } from 'src/context/Localization/LocContext';
import { useAppDispatch } from 'src/store/hooks';
import { NodeDetail } from 'src/services/wallets/interfaces';
import KeeperHeader from 'src/components/KeeperHeader';
import ScreenWrapper from 'src/components/ScreenWrapper';
import KeeperModal from 'src/components/KeeperModal';
import useToastMessage from 'src/hooks/useToastMessage';
Expand Down
Loading
Loading