Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c9c77ca
feat: create release/2.0.0 branch
a0979470582 Jun 14, 2024
9fbce45
chore: update core sdk to 2.0
a0979470582 Jun 14, 2024
72cc150
Merge pull request #62 from CoolBitX-Technology/chore/update_core_sdk…
a0979470582 Jun 14, 2024
6a38ad8
feat: integrate nfc transport
a0979470582 Jun 16, 2024
658f300
Merge pull request #63 from CoolBitX-Technology/feat/integrate_nfc_tr…
a0979470582 Jun 17, 2024
b7bf574
feat: add master key slice
gundomlegend Jun 21, 2024
3ca922b
feat: add derive master key page
gundomlegend Jun 21, 2024
7d36c87
chore: rename to create master key
gundomlegend Jun 24, 2024
895629a
Merge pull request #64 from CoolBitX-Technology/feat/add-generate-mas…
gundomlegend Jun 25, 2024
c213643
chore: add NFC AIDs 'CoolWalletLITE' and 'BackupApplet' for NFC
tp26610 Jun 25, 2024
5935782
style: add comment to AIDs
tp26610 Jun 25, 2024
044f22b
chore(ios): add NFC capability
tp26610 Jun 25, 2024
9062e65
chore: update Podfile to use latest react-native-nfc-manager
tp26610 Jun 25, 2024
47b9d9a
chore: use cocoapods from Gemfile
tp26610 Jun 25, 2024
7b08ba1
chore: update entitlements & info lists
gundomlegend Jun 25, 2024
d14a547
Merge pull request #65 from CoolBitX-Technology/chore/add-ios-nfc-con…
tp26610 Jun 25, 2024
3257bac
fix: cannot get card info issue
gundomlegend Jun 25, 2024
19fd4d2
Merge pull request #66 from CoolBitX-Technology/fix/nfc-get-card-info…
gundomlegend Jun 25, 2024
c737ec8
Merge branch 'main' into chore/merge-dev-take1
gundomlegend Jun 28, 2024
9e120df
Merge pull request #68 from CoolBitX-Technology/chore/merge-dev-take1
gundomlegend Jun 28, 2024
29b17d1
fix: 更新修正 setSeed 長度錯誤問題
gundomlegend Jul 1, 2024
75f8c23
feat: 還原流程增加 nfc 連線流程
gundomlegend Jul 1, 2024
e4cc2de
feat: 還原地址增加 nfc 連線流程
gundomlegend Jul 1, 2024
5e3c96e
Merge pull request #69 from CoolBitX-Technology/fix/set_seed_issue
gundomlegend Jul 1, 2024
532cc0d
feat: test createSeedByCard function and complete it.
a0979470582 Jul 5, 2024
eff52e8
Merge pull request #71 from CoolBitX-Technology/feature/create_seed_b…
a0979470582 Jul 19, 2024
2ca99c9
feat: add NFC flow in EIP1559CoinTransferContainer
tp26610 Aug 7, 2024
bd86a07
chore: update evm sdk to 2.0.0
tp26610 Aug 7, 2024
5c5d252
feat: add returnType prop in DemoSignView
tp26610 Aug 7, 2024
c0cb5d9
Merge pull request #76 from CoolBitX-Technology/feature/coin-transfer…
tp26610 Aug 7, 2024
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
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ v18.16.0

> **Note**: Make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding.

## Step 0: Install dependencies

### Install node_modules

```bash
yarn install
```

## Step 1: Start the Metro Server

First, you will need to start **Metro**, the JavaScript _bundler_ that ships _with_ React Native.
Expand Down
4 changes: 4 additions & 0 deletions ios/CoolWalletAppDemo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
5DCACB8F33CDC322A6C60F78 /* libPods-CoolWalletAppDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CoolWalletAppDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = CoolWalletAppDemo/LaunchScreen.storyboard; sourceTree = "<group>"; };
89C6BE57DB24E9ADA2F236DE /* Pods-CoolWalletAppDemo-CoolWalletAppDemoTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoolWalletAppDemo-CoolWalletAppDemoTests.release.xcconfig"; path = "Target Support Files/Pods-CoolWalletAppDemo-CoolWalletAppDemoTests/Pods-CoolWalletAppDemo-CoolWalletAppDemoTests.release.xcconfig"; sourceTree = "<group>"; };
CCB436F82C2A639400BC0ECD /* CoolWalletAppDemo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = CoolWalletAppDemo.entitlements; path = CoolWalletAppDemo/CoolWalletAppDemo.entitlements; sourceTree = "<group>"; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -86,6 +87,7 @@
13B07FAE1A68108700A75B9A /* CoolWalletAppDemo */ = {
isa = PBXGroup;
children = (
CCB436F82C2A639400BC0ECD /* CoolWalletAppDemo.entitlements */,
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.mm */,
13B07FB51A68108700A75B9A /* Images.xcassets */,
Expand Down Expand Up @@ -485,6 +487,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = CoolWalletAppDemo/CoolWalletAppDemo.entitlements;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 87HB2LFXY3;
ENABLE_BITCODE = NO;
Expand Down Expand Up @@ -513,6 +516,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = CoolWalletAppDemo/CoolWalletAppDemo.entitlements;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 87HB2LFXY3;
INFOPLIST_FILE = CoolWalletAppDemo/Info.plist;
Expand Down
11 changes: 11 additions & 0 deletions ios/CoolWalletAppDemo/CoolWalletAppDemo.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>NDEF</string>
<string>TAG</string>
</array>
</dict>
</plist>
7 changes: 7 additions & 0 deletions ios/CoolWalletAppDemo/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,12 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
<string>436F6F6C57616C6C65744C495445</string>
<string>4261636B75704170706C6574</string>
</array>
<key>NFCReaderUsageDescription</key>
<string>We need to use NFC</string>
</dict>
</plist>
6 changes: 6 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,8 @@ PODS:
- React-Core
- react-native-get-random-values (1.11.0):
- React-Core
- react-native-nfc-manager (3.14.14):
- React-Core
- react-native-pager-view (6.3.1):
- RCT-Folly (= 2021.07.22.00)
- React-Core
Expand Down Expand Up @@ -573,6 +575,7 @@ DEPENDENCIES:
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
- react-native-ble-plx (from `../node_modules/react-native-ble-plx`)
- react-native-get-random-values (from `../node_modules/react-native-get-random-values`)
- react-native-nfc-manager (from `../node_modules/react-native-nfc-manager`)
- react-native-pager-view (from `../node_modules/react-native-pager-view`)
- react-native-randombytes (from `../node_modules/react-native-randombytes`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
Expand Down Expand Up @@ -670,6 +673,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-ble-plx"
react-native-get-random-values:
:path: "../node_modules/react-native-get-random-values"
react-native-nfc-manager:
:path: "../node_modules/react-native-nfc-manager"
react-native-pager-view:
:path: "../node_modules/react-native-pager-view"
react-native-randombytes:
Expand Down Expand Up @@ -768,6 +773,7 @@ SPEC CHECKSUMS:
React-logger: da1ebe05ae06eb6db4b162202faeafac4b435e77
react-native-ble-plx: f10240444452dfb2d2a13a0e4f58d7783e92d76e
react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06
react-native-nfc-manager: ead2cd1d1eaab139cc8b2dc5fbfe575eaa45efc4
react-native-pager-view: 712081434052f3af89ef00e8a353a7d351e62eeb
react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846
react-native-safe-area-context: 399a5859f6acbdf67f671c69b53113f535f3b5b0
Expand Down
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"ios:install-pods": "bundle install && cd ios && bundle exec pod install",
"lint": "eslint .",
"start": "react-native start",
"test": "jest",
"adbremote": "adb reverse tcp:8081 tcp:8081",
"patch:rn-nodeify": "npx rn-nodeify --install --hack",
"patch:jetify": "npx jetify",
"postinstall": "yarn patch:rn-nodeify && yarn patch:jetify && react-native setup-ios-permissions && pod-install"
"postinstall": "yarn patch:rn-nodeify && yarn patch:jetify && react-native setup-ios-permissions && yarn ios:install-pods"
},
"reactNativePermissionsIOS": [
"BluetoothPeripheral",
Expand All @@ -20,8 +21,10 @@
"LocationWhenInUse"
],
"dependencies": {
"@coolwallet/core": "^1.1.18",
"@coolwallet/evm": "^1.0.27",
"@coolwallet/core": "2.0.0-beta.7",
"@coolwallet/evm": "^2.0.0-beta.0",
"@coolwallet/transport-jre-http": "2.0.0-beta.1",
"@coolwallet/transport-react-native-nfc": "1.0.0-beta.3",
"@react-native-async-storage/async-storage": "^1.19.2",
"@react-native-clipboard/clipboard": "1.11.2",
"@react-navigation/material-top-tabs": "^6.6.3",
Expand Down Expand Up @@ -76,7 +79,6 @@
"string_decoder": "^0.10.31",
"styled-components": "^6.0.7",
"timers-browserify": "^1.4.2",
"transport-jre-http": "^1.1.2",
"tty-browserify": "^0.0.0",
"url": "^0.10.3",
"util": "^0.10.4",
Expand Down
10 changes: 8 additions & 2 deletions src/DemoAppNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import { RefreshAppKeyPairContainer } from '@src/features/cardPairing/RefreshApp
import { GeneratePairingPasswordContainer } from '@src/features/cardPairing/GeneratePairingPasswordContainer';
import { GetCardInfoContainer } from '@src/features/cardPairing/GetCardInfoContainer';
import { HttpScanContainer } from '@src/features/httpScan/HttpScanContainer';
import NFCScanContainer from "@src/features/nfc/NFCScanContainer";
import NFCScanContainer from '@src/features/nfcScan/NFCScanContainer';
import { GenerateMasterKeyContainer } from '@src/features/cardPairing/GenerateMasterKeyContainer';
import { FirmwareUpgradeContainer } from '@src/features/cardPairing/FirmwareUpgradeContainer';

export type DemoAppParamList = {
[RouteName.DEMO_HOME]: undefined;
[RouteName.BLUETOOTH_SCAN]: undefined;
Expand All @@ -41,6 +41,7 @@ export type DemoAppParamList = {
[RouteName.SIGN_TYPED_DATA]: undefined;
[RouteName.SEND_HEX]: undefined;
[RouteName.NFC_SCAN]: undefined;
[RouteName.CREATE_MASTER_KEY]: undefined;
};

export type RootNavigationProp = NavigationProp<DemoAppParamList>;
Expand Down Expand Up @@ -95,6 +96,11 @@ export function DemoAppNavigator() {
component={RecoverWalletContainer}
options={{ headerBackTitleVisible: false }}
/>
<Stack.Screen
name={RouteName.CREATE_MASTER_KEY}
component={GenerateMasterKeyContainer}
options={{ headerBackTitleVisible: false }}
/>
<Stack.Screen
name={RouteName.RECOVER_ADDRESS}
component={RecoverAddressContainer}
Expand Down
24 changes: 17 additions & 7 deletions src/features/ble/RNApduManager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Transport, apdu, config } from '@coolwallet/core';
import { Transport, config, info, setting, wallet } from '@coolwallet/core';
import { AppKeyPair } from '@src/features/ble/utils/StorageUtils';
import { SDKError } from '@coolwallet/core/lib/error';
import { RNApduError } from '@src/features/ble/RNApduError';
Expand Down Expand Up @@ -56,7 +56,7 @@ export class RNApduManager implements ApduManager {

async getCardInfo(): Promise<CardInfo> {
try {
return await apdu.info.getCardInfo(this.getTransport());
return await info.getCardInfo(this.getTransport());
} catch (e) {
throw RNApduError.parseError(e as Error);
}
Expand All @@ -67,7 +67,7 @@ export class RNApduManager implements ApduManager {
const { publicKey } = appKeyPair;
const sePublicKey = await this.getSEPublicKey();
try {
return await apdu.pair.register(this.getTransport(), publicKey, password, name, sePublicKey);
return await wallet.client.register(this.getTransport(), publicKey, password, name, sePublicKey);
} catch (e) {
throw RNApduError.parseError(e as Error);
}
Expand All @@ -77,7 +77,7 @@ export class RNApduManager implements ApduManager {
const appKeyPair = this.getAppKeyPair();
const { privateKey } = appKeyPair;
try {
return await apdu.pair.getPairedApps(this.getTransport(), appId, privateKey);
return await wallet.client.getPairedApps(this.getTransport(), appId, privateKey);
} catch (e) {
throw RNApduError.parseError(e as Error);
}
Expand All @@ -87,15 +87,15 @@ export class RNApduManager implements ApduManager {
const appKeyPair = this.getAppKeyPair();
const { privateKey } = appKeyPair;
try {
return await apdu.pair.removePairedDevice(this.getTransport(), appId, privateKey, pairedAppId);
return await wallet.client.removePairedDevice(this.getTransport(), appId, privateKey, pairedAppId);
} catch (e) {
throw RNApduError.parseError(e as Error);
}
}

async resetDevice(): Promise<boolean> {
try {
const status = await apdu.general.resetCard(this.getTransport());
const status = await setting.card.resetCard(this.getTransport());
return status;
} catch (e) {
throw RNApduError.parseError(e as Error);
Expand All @@ -106,7 +106,7 @@ export class RNApduManager implements ApduManager {
const appKeyPair = this.getAppKeyPair();
const { privateKey } = appKeyPair;
try {
return await apdu.pair.getPairingPassword(this.getTransport(), appId, privateKey);
return await wallet.client.getPairingPassword(this.getTransport(), appId, privateKey);
} catch (e) {
throw RNApduError.parseError(e as Error);
}
Expand Down Expand Up @@ -158,4 +158,14 @@ export class RNApduManager implements ApduManager {
throw RNApduError.parseError(e as Error);
}
}

async createSeedByCard(appId: string, strength: 12 | 18 | 24) {
const appKeyPair = this.getAppKeyPair();
const { privateKey } = appKeyPair;
try {
return await wallet.secret.creation.createSeedByCard(this.getTransport(), appId, privateKey, strength);
} catch (e) {
throw RNApduError.parseError(e as Error);
}
}
}
5 changes: 3 additions & 2 deletions src/features/ble/RNBleTransport.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Transport as CWTransport, device as CWDevice } from '@coolwallet/core';
import { device as CWDevice } from '@coolwallet/core';
import { BleTransport } from '@coolwallet/core/lib/transport';
import { RNBleError } from '@src/features/ble/RNBleError';
import { BleErrorCode, Device as BluetoothDevice, Characteristic } from 'react-native-ble-plx';

Expand All @@ -9,7 +10,7 @@ export interface CWServiceCharacteristics {
response?: Characteristic;
}

export class RNBleTransport extends CWTransport {
export class RNBleTransport extends BleTransport {
private characteristics?: CWServiceCharacteristics | null;

constructor(device: BluetoothDevice) {
Expand Down
35 changes: 35 additions & 0 deletions src/features/cardPairing/GenerateMasterKeyContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { RNApduManager } from '@src/features/ble/RNApduManager';
import { useConnectCardUseCase } from '@src/features/cardPairing/hooks/useConnectCardUseCase';
import { DemoView } from '@src/features/components/DemoView';
import { useLogUseCase } from '@src/features/home/usecases/useLogUseCase';
import { useAppId } from '@src/features/store/account/AccountActionHooks';
import { useCardId } from '@src/features/store/device/DeviceActionHooks';

const STRENGTH = 12;
export function GenerateMasterKeyContainer() {
const cardId = useCardId();
const appId = useAppId(cardId);
const { log, addLog } = useLogUseCase();
const { connect, disconnect } = useConnectCardUseCase();

const generateMasterKey = async () => {
await connect();

addLog(`createSeedByCard start...`);
const result = await RNApduManager.getInstance().createSeedByCard(appId, STRENGTH);
addLog(`createSeedByCard is successful. result=${result}`);

disconnect();
};

return (
<DemoView
btnText="Generate"
onPressBtn={generateMasterKey}
log={log}
showCopy={false}
showTextBox={false}
showInput={false}
/>
);
}
31 changes: 18 additions & 13 deletions src/features/cardPairing/GeneratePairingPasswordContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { RNApduError } from '@src/features/ble/RNApduError';
import { RNApduManager } from '@src/features/ble/RNApduManager';
import { useConnectCardUseCase } from '@src/features/cardPairing/hooks/useConnectCardUseCase';
import { DemoView } from '@src/features/components/DemoView';
import { useInitApduEffect } from '@src/features/home/usecases/useCardPairingUseCase';
import { useLogUseCase } from '@src/features/home/usecases/useLogUseCase';
Expand All @@ -17,23 +18,27 @@ export function GeneratePairingPasswordContainer() {
const isBtnDisable = !cardId || !isConnected || !defaultPairPassword;
const [isRefreshing, setIsRefereshing] = useState(false);

const { connect, disconnect } = useConnectCardUseCase();

useInitApduEffect();

const generatePairPassword = async () => {
if (!appId || isBtnDisable) return;
setIsRefereshing(true);
addLog('GENERATING....');
RNApduManager.getInstance()
.getPairPassword(appId)
.then((newPassword) => {
setPairPassword(newPassword);
addLog('GENERATED SUCCESS, PLEASE COPY NEW PAIR PASSWORD AND GO TO REFRESH APP KEY PAIR');
})
.catch((e) => {
const error = e as RNApduError;
addLog('GENERATED FAILED >>> ERROR=' + error);
})
.finally(() => setIsRefereshing(false));

try {
setIsRefereshing(true);
await connect();
addLog('GENERATING....');
const newPairedPassword = await RNApduManager.getInstance().getPairPassword(appId);
setPairPassword(newPairedPassword);
addLog('GENERATED SUCCESS, PLEASE COPY NEW PAIR PASSWORD AND GO TO REFRESH APP KEY PAIR');
await disconnect();
} catch(e) {
const error = e as RNApduError;
addLog('GENERATED FAILED >>> ERROR=' + error);
} finally {
setIsRefereshing(false);
}
};

return (
Expand Down
10 changes: 9 additions & 1 deletion src/features/cardPairing/GetCardInfoContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { RNApduError } from '@src/features/ble/RNApduError';
import { useConnectCardUseCase } from '@src/features/cardPairing/hooks/useConnectCardUseCase';
import { useGetCardInfoUseCase } from '@src/features/cardPairing/usecases/useGetCardInfoUseCase';
import { BlueButton } from '@src/features/components/BlueButton';
import { LogBox } from '@src/features/components/LogBox';
Expand Down Expand Up @@ -35,7 +36,11 @@ export function GetCardInfoContainer(): JSX.Element {
const isBtnDisable = !isConnected || isQuerying;
const { log, addLog, resetLog } = useLogUseCase();

const onClick = () => {
const { connect, disconnect } = useConnectCardUseCase();

const onClick = async () => {
await connect();

resetLog();
addLog('QUERYING....');
getCardInfo()
Expand Down Expand Up @@ -66,6 +71,9 @@ export function GetCardInfoContainer(): JSX.Element {
.catch((e) => {
const error = e as RNApduError;
addLog('QUERIED FAILED >>> ERROR=' + error);
})
.finally(() => {
disconnect();
});
};
return (
Expand Down
Loading