<h1 align="center" style="margin-top: 30px;">JSI-RN-Wallet-Core</h1>

<h3 align="center">Wallet Core wrapper implementation for react-native</h3>

<br/>

# Installation

```
yarn add jsi-rn-wallet-core
```

# Supported currencies

- Ethereum
- Cosmos

# Usage

Import package once as early as possible, it installs global types, and on android it installs bindings in a safe way.

Afterwards, you can access a global `WalletCore` variable anywhere in your code.

```ts
import 'jsi-rn-wallet-core';
```

# API

```typescript
const { mnemonic, seed } = WalletCore.createWallet(128, '');
```

Creates a new wallet.

** SAMPLE METHOD **
Meant only to test creating a wallet, not meant to be used production

- `strength` _number_ - Strength of the secret seed. Possible options are 128 or 256.
- `passphrase` _string (optional)_ - Used to scramble the seed
- **Returns**
  - `mnemonic` _string_ - the recovery phrase of the wallet
  - `seed` _string_ - hex seed of the wallet. Can also be used to import.

<br />

```typescript
const { mnemonic, seed } = WalletCore.importWalletFromMnemonic({
  mnemonic:
    'ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal',
  passphrase: '',
  promptTitle: 'Unlock your device',
  promptSubtitle: 'Please authenticate to unlock your wallet',
  useBiometrics: true,
});
```

Import a wallet from a mnemonic recovery phrase. This will also load the wallet into local memory so that it can be used for creating addresses and/or signing transactions. The loaded wallet seed will also be securely stored on the device so it can be loaded (will require user authentication via passcode/biometrics).

- `params` object - contains the possible params
  - `mnemonic` _string_ - Recovery phrase
  - `passphrase` _string (optional)_ - The passphrase used when creating the wallet (if applicable)
  - `promptTitle` _string (optional)_ - The title for the native dialog when requesting biometric authentication
  - `promptSubtitle` _string (optional)_ - The subtitle for the native dialog when requesting biometric authentication
  - `useBiometrics` _boolean (optional) (default: false)_ - Lock the seed behind biometric authentication
- **Returns**
  - `mnemonic` _string_ - the recovery phrase of the wallet
  - `seed` _string_ - hex seed of the wallet. Can also be used to import.

<br />

```typescript
const { mnemonic, seed } = WalletCore.importWalletFromEntropy({
  entropy: '<ENTROPY_STRING>',
  passphrase: '',
  promptTitle: 'Unlock your device',
  promptSubtitle: 'Please authenticate to unlock your wallet',
  useBiometrics: true,
});
```

Import a wallet from a entropy string seed. This will also load the wallet into local memory so that it can be used for creating addresses and/or signing transactions. The loaded wallet seed will also be securely stored on the device so it can be loaded (will require user authentication via passcode/biometrics).

- `params` object - contains the possible params
  - `entropy` _string_ - Recovery phrase
  - `passphrase` _string (optional)_ - The passphrase used when creating the wallet (if applicable)
  - `promptTitle` _string (optional)_ - The title for the native dialog when requesting biometric authentication
  - `promptSubtitle` _string (optional)_ - The subtitle for the native dialog when requesting biometric authentication
  - `useBiometrics` _boolean (optional) (default: false)_ - Lock the seed behind biometric authentication
- **Returns**
  - `mnemonic` _string_ - the recovery phrase of the wallet
  - `seed` _string_ - hex seed of the wallet. Can also be used to import.

<br />

```typescript
const { mnemonic, seed } = WalletCore.loadWalletFromStorage({
  passphrase: '',
  promptTitle: 'Unlock Wallet',
  promptSubtitle: 'Please authenticate to use your wallet',
  useBiometrics: true,
});
```

Load a wallet into memory from a stored seed.

- `params` object - contains the possible params
  - `passphrase` _string (optional)_ - The passphrase used when creating the wallet (if applicable)
  - `promptTitle` _string (optional)_ - The title for the native dialog when requesting biometric authentication
  - `promptSubtitle` _string (optional)_ - The subtitle for the native dialog when requesting biometric authentication
  - `useBiometrics` _boolean (optional) (default: false)_ - Lock the seed behind biometric authentication, if you imported a wallet with the `useBiometrics` flag, you need to set it here too in order to be able to load it
- **Returns**
  - `mnemonic` _string_ - the recovery phrase of the wallet
  - `seed` _string_ - hex seed of the wallet. Can also be used to import.

<br />

```typescript
const address = WalletCore.getAddressForCoin('ethereum');
```

Generate and retrieve the default address for a coin. The address is generated using the default derivation path of a coin.

- `coin` _string_ - The coin type
- **Returns**
  - `address` _string_ - The public key of the address

<br />

```typescript
const { address, privateKey } = WalletCore.getAccount(
  'ethereum',
  "m/44'/60'/1'/0/0"
);
```

Generate an address using a custom derivation path.

- `coin` _string_ - The coin type
- `derivationPath` _string_ - Derivation path to be used when generating the address
- **Returns**
  - `address` _string_ - The correspoding public address
  - `publicKey` _string_ - The public key

<br />

```typescript
const transactionHash = WalletCore.signTransactionForCoin(
  'ethereum',
  JSON.stringify({
    chainID: '0x01',
    amount: '0x0348bca5a16000',
    nonce: '0x00',
    toAddress: '0xC37054b3b48C3317082E7ba872d7753D13da4986',
    privateKeyDerivationPath: "m/44'/60'/1'/0/0", // optional - otherwise default address is used
  })
);
```

Generate and retrieve the default address for a coin. The address is generated using the default derivation path of a coin.

- `coinType` _string_ - The coin type
- `input` _string_ the payload to be signed, stringified JSON or raw byte protobuf
- **Returns** `transactionHash` _string_ - the hash of the signed data

<br />

```typescript
const transactionHash = WalletCore.signData(
  'ethereum',
  'XXXXX',
  "m/44'/60'/1'/0/0"
);
```

Generic sign function for any raw data byta array.

- `coinType` _string_ - The coin type
- `payload` _string_ - raw bytes to sign
- `derivationPath` _string (optional)_ - Derivation path to use to get private key
- **Returns** `transactionHash` _string_ - the hash of the signed data

<br />

```typescript
const mnemonic = WalletCore.getCurrentWalletMnemonic();
```

Gets the current loaded wallet mnemonic.

<br />

```typescript
const biometricsState = WalletCore.getBiometricsState();
```

Get device's biometrics state

- **Returns** biometrics state enum
  - `available`: device supports biometrics and is ready to authenticate
  - `available_locked`: device supports biometrics but is locked (e.g. too many failed attempts should trigger this state) (iOS only)
  - `unavailable`: device does not support biometrics or supports them but they are not enabled

<br />

```typescript
WalletCore.deleteWallet({
  promptTitle: 'Unlock wallet',
  promptSubtitle: 'Please unlock your wallet',
  useBiometrics: true,
});
```

Cleanup any previously loaded wallet from persistent storage and memory.

- `params` object - contains the possible params
  - `promptTitle` _string (optional)_ - The title for the native dialog when requesting biometric authentication
  - `promptSubtitle` _string (optional)_ - The subtitle for the native dialog when requesting biometric authentication
  - `useBiometrics` _boolean (optional) (default: false)_ - If you imported a wallet with the `useBiometrics` flag, you need to set it here too in order to be able to load it

<br />

```typescript
WalletCore.cleanup();
```

Cleanup any previously loaded wallet from memory **and also deletes any stored seed**.

<br />

```typescript
WalletCore.transferEntropyToBiometricsStorage();
```

Transfers any seed stored without biometric security to require biometric authentication.

<br />

```typescript
WalletCore.transferEntropyToNormalStorage();
```

Transfers any seed stored with biometric security to **NOT** require biometric authentication.

# Android Instructions

Once you add this library to your Android project you might get some errors, you need to modify the android compilation process a bit.

The underlaying C++ wallet-core library depends on the C++ STL, this might cause some Android error not being able to select a c++\_shared library.

On the apps build.gradle (`android/app/build.gradle`), you can force the gradle build process to just pick one.

```
packagingOptions {
  pickFirst 'lib/x86/libc++_shared.so'
  pickFirst 'lib/x86_64/libc++_shared.so'
  pickFirst 'lib/armeabi-v7a/libc++_shared.so'
  pickFirst 'lib/arm64-v8a/libc++_shared.so'
  pickFirst 'lib/x86/libTrustWalletCore.so'
  pickFirst 'lib/x86_64/libTrustWalletCore.so'
  pickFirst 'lib/armeabi-v7a/libTrustWalletCore.so'
  pickFirst 'lib/arm64-v8a/libTrustWalletCore.so'
}
```

## Updating Wallet-Core embedded .AAR

```
brew install boost
brew install cmake

git clone git@github.com:trustwallet/wallet-core.git
cd wallet-core

You need to modify the build gradle file to add prefab functionality (exposes C++ symbols to Android C++ builds)
It is also necessary to modify the CMakeLists to expose the generated symbols
There is a patch file in the /scripts directory in this repo with the changes you need to make

Then generate the .AAR file (from the `android` folder) with:

./bootstrap.sh # Generates all the protobuf classes and what not
BOOST_INCLUDEDIR=/opt/homebrew/Cellar/boost/1.78.0_1/include ./gradlew build

Then place the generated aar on this repo under android/libs/

You can then try to compile the example app
cd example && yarn android
```

## Contributing

See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.

## License

MIT
