Skip to content

Commit 60738d2

Browse files
authored
Merge pull request #61 from functionland/blockchain-blox-commands
Added wifiRemoveallMethod
2 parents dfff5ed + fd879f4 commit 60738d2

File tree

9 files changed

+572
-309
lines changed

9 files changed

+572
-309
lines changed

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ repositories {
6262
dependencies {
6363
//noinspection GradleDynamicVersion
6464
implementation "com.facebook.react:react-native:+" // From node_modules
65-
implementation 'com.github.functionland:fula-build-aar:1.2.1' // From jitpack.io
65+
implementation 'com.github.functionland:fula-build-aar:1.9.0' // From jitpack.io
6666
implementation 'com.github.functionland:wnfs-build-aar:v1.4.1' // From jitpack.io
6767
implementation 'commons-io:commons-io:20030203.000550'
6868
// implementation files('mobile.aar')

android/src/main/java/land/fx/fula/FulaModule.java

Lines changed: 85 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public void initialize() {
6767
SharedPreferenceHelper sharedPref;
6868
SecretKey secretKeyGlobal;
6969
String identityEncryptedGlobal;
70-
static String PRIVATE_KEY_STORE_ID = "PRIVATE_KEY";
70+
static String PRIVATE_KEY_STORE_PEERID = "PRIVATE_KEY";
7171

7272
public static class Client implements land.fx.wnfslib.Datastore {
7373

@@ -133,6 +133,15 @@ private byte[] toByte(@NonNull String input) {
133133
return input.getBytes(StandardCharsets.UTF_8);
134134
}
135135

136+
private byte[] decToByte(@NonNull String input) {
137+
String[] parts = input.split(",");
138+
byte[] output = new byte[parts.length];
139+
for (int i = 0; i < parts.length; i++) {
140+
output[i] = Byte.parseByte(parts[i]);
141+
}
142+
return output;
143+
}
144+
136145
@NonNull
137146
@Contract("_ -> new")
138147
public String toString(byte[] input) {
@@ -422,30 +431,48 @@ private boolean retryFailedActionsInternal(int timeout) throws Exception {
422431
}
423432

424433
@NonNull
425-
private byte[] createPeerIdentity(byte[] privateKey) throws GeneralSecurityException, IOException {
434+
private byte[] createPeerIdentity(byte[] identity) throws GeneralSecurityException, IOException {
426435
try {
427436
// 1: First: create public key from provided private key
428437
// 2: Should read the local keychain store (if it is key-value, key is public key above,
429438
// 3: if found, decrypt using the private key
430439
// 4: If not found or decryption not successful, generate an identity
431440
// 5: then encrypt and store in keychain
432-
String encryptedKey = sharedPref.getValue(PRIVATE_KEY_STORE_ID);
433-
SecretKey secretKey = Cryptography.generateKey(privateKey);
441+
byte[] libp2pId;
442+
String encryptedLibp2pId = sharedPref.getValue(PRIVATE_KEY_STORE_PEERID);
443+
byte[] encryptionPair;
444+
SecretKey encryptionSecretKey;
445+
try {
446+
encryptionSecretKey = Cryptography.generateKey(identity);
447+
Log.d("ReactNative", "encryptionSecretKey generated from privateKey");
448+
} catch (Exception e) {
449+
Log.d("ReactNative", "Failed to generate key for encryption: " + e.getMessage());
450+
throw new GeneralSecurityException("Failed to generate key encryption", e);
451+
}
452+
453+
if (encryptedLibp2pId == null || !encryptedLibp2pId.startsWith("FULA_ENC_V3:")) {
454+
Log.d("ReactNative", "encryptedLibp2pId is not correct. creating new one " + encryptedLibp2pId);
434455

435-
if (encryptedKey == null || !encryptedKey.startsWith("FULA_ENC_V2:")) {
436-
byte[] autoGeneratedIdentity;
437456
try {
438-
autoGeneratedIdentity = Fulamobile.generateEd25519Key();
457+
libp2pId = Fulamobile.generateEd25519KeyFromString(toString(identity));
439458
} catch (Exception e) {
440-
Log.d("ReactNative", "Failed to generate key: " + e.getMessage());
441-
throw new GeneralSecurityException("Failed to generate key", e);
459+
Log.d("ReactNative", "Failed to generate libp2pId: " + e.getMessage());
460+
throw new GeneralSecurityException("Failed to generate libp2pId", e);
442461
}
443-
encryptedKey = "FULA_ENC_V2:" + Cryptography.encryptMsg(StaticHelper.bytesToBase64(autoGeneratedIdentity), secretKey);
444-
sharedPref.add(PRIVATE_KEY_STORE_ID, encryptedKey);
462+
encryptedLibp2pId = "FULA_ENC_V3:" + Cryptography.encryptMsg(StaticHelper.bytesToBase64(libp2pId), encryptionSecretKey);
463+
sharedPref.add(PRIVATE_KEY_STORE_PEERID, encryptedLibp2pId);
464+
} else {
465+
Log.d("ReactNative", "encryptedLibp2pId is correct. decrypting " + encryptedLibp2pId);
445466
}
446467

447-
String decryptedKey = Cryptography.decryptMsg(encryptedKey.replace("FULA_ENC_V2:", ""), secretKey);
448-
return StaticHelper.base64ToBytes(decryptedKey);
468+
try {
469+
String decryptedLibp2pId = Cryptography.decryptMsg(encryptedLibp2pId.replace("FULA_ENC_V3:", ""), encryptionSecretKey);
470+
471+
return StaticHelper.base64ToBytes(decryptedLibp2pId);
472+
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) {
473+
Log.d("ReactNative", "createPeerIdentity decryptMsg failed with Error: " + e.getMessage());
474+
throw (e);
475+
}
449476

450477
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) {
451478
Log.d("ReactNative", "createPeerIdentity failed with Error: " + e.getMessage());
@@ -478,8 +505,8 @@ private boolean encrypt_and_store_config() throws Exception {
478505
String cid_encrypted = Cryptography.encryptMsg(this.rootConfig.getCid(), this.secretKeyGlobal);
479506
String private_ref_encrypted = Cryptography.encryptMsg(this.rootConfig.getPrivate_ref(), this.secretKeyGlobal);
480507

481-
sharedPref.add("FULA_ENC_V2:cid_encrypted_" + this.identityEncryptedGlobal, cid_encrypted);
482-
sharedPref.add("FULA_ENC_V2:private_ref_encrypted_" + this.identityEncryptedGlobal, private_ref_encrypted);
508+
sharedPref.add("FULA_ENC_V3:cid_encrypted_" + this.identityEncryptedGlobal, cid_encrypted);
509+
sharedPref.add("FULA_ENC_V3:private_ref_encrypted_" + this.identityEncryptedGlobal, private_ref_encrypted);
483510
return true;
484511
} else {
485512
return false;
@@ -496,14 +523,15 @@ private boolean logoutInternal(byte[] identity, String storePath) throws Excepti
496523
this.fula.flush();
497524
}
498525
SecretKey secretKey = Cryptography.generateKey(identity);
526+
499527
String identity_encrypted = Cryptography.encryptMsg(Arrays.toString(identity), secretKey);
500-
sharedPref.remove("FULA_ENC_V2:cid_encrypted_"+ identity_encrypted);
501-
sharedPref.remove("FULA_ENC_V2:private_ref_encrypted_"+identity_encrypted);
528+
sharedPref.remove("FULA_ENC_V3:cid_encrypted_"+ identity_encrypted);
529+
sharedPref.remove("FULA_ENC_V3:private_ref_encrypted_"+identity_encrypted);
502530

503531
//TODO: Should also remove peerid @Mahdi
504532

505-
sharedPref.remove("FULA_ENC_V2:cid_encrypted_"+ identity_encrypted);
506-
sharedPref.remove("FULA_ENC_V2:private_ref_encrypted_"+ identity_encrypted);
533+
sharedPref.remove("FULA_ENC_V3:cid_encrypted_"+ identity_encrypted);
534+
sharedPref.remove("FULA_ENC_V3:private_ref_encrypted_"+ identity_encrypted);
507535

508536
this.rootConfig = null;
509537
this.secretKeyGlobal = null;
@@ -591,8 +619,8 @@ private String[] initInternal(byte[] identity, String storePath, String bloxAddr
591619
Log.d("ReactNative", "this.rootCid is empty.");
592620
//Load from keystore
593621

594-
String cid_encrypted_fetched = sharedPref.getValue("FULA_ENC_V2:cid_encrypted_"+ identity_encrypted);
595-
String private_ref_encrypted_fetched = sharedPref.getValue("FULA_ENC_V2:private_ref_encrypted_"+identity_encrypted);
622+
String cid_encrypted_fetched = sharedPref.getValue("FULA_ENC_V3:cid_encrypted_"+ identity_encrypted);
623+
String private_ref_encrypted_fetched = sharedPref.getValue("FULA_ENC_V3:private_ref_encrypted_"+identity_encrypted);
596624
Log.d("ReactNative", "Here1");
597625
String cid = "";
598626
String private_ref = "";
@@ -1301,6 +1329,10 @@ public void removeStoredReplication(String seedString, String uploader, long poo
13011329
});
13021330
}
13031331

1332+
////////////////////////////////////////////////////////////////
1333+
///////////////// Blox Hardware Methods ////////////////////////
1334+
////////////////////////////////////////////////////////////////
1335+
13041336
@ReactMethod
13051337
public void bloxFreeSpace(Promise promise) {
13061338
ThreadUtils.runOnExecutor(() -> {
@@ -1317,4 +1349,36 @@ public void bloxFreeSpace(Promise promise) {
13171349
});
13181350
}
13191351

1352+
@ReactMethod
1353+
public void wifiRemoveall(Promise promise) {
1354+
ThreadUtils.runOnExecutor(() -> {
1355+
Log.d("ReactNative", "wifiRemoveall");
1356+
try {
1357+
byte[] result = this.fula.wifiRemoveall();
1358+
String resultString = toString(result);
1359+
Log.d("ReactNative", "result string="+resultString);
1360+
promise.resolve(resultString);
1361+
} catch (Exception e) {
1362+
Log.d("ReactNative", e.getMessage());
1363+
promise.reject(e);
1364+
}
1365+
});
1366+
}
1367+
1368+
@ReactMethod
1369+
public void reboot(Promise promise) {
1370+
ThreadUtils.runOnExecutor(() -> {
1371+
Log.d("ReactNative", "reboot");
1372+
try {
1373+
byte[] result = this.fula.reboot();
1374+
String resultString = toString(result);
1375+
Log.d("ReactNative", "result string="+resultString);
1376+
promise.resolve(resultString);
1377+
} catch (Exception e) {
1378+
Log.d("ReactNative", e.getMessage());
1379+
promise.reject(e);
1380+
}
1381+
});
1382+
}
1383+
13201384
}

example/src/App.tsx

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { StyleSheet, Text, View, Button, TextInput } from 'react-native';
33

4-
import { fula, blockchain, chainApi } from '@functionland/react-native-fula';
4+
import { fula, blockchain, chainApi, fxblox } from '@functionland/react-native-fula';
55

66
const App = () => {
77
const [key, setKey] = React.useState<string>('');
@@ -31,15 +31,15 @@ const App = () => {
3131
console.log(err.message, err.code);
3232
});
3333
};
34-
//Key for peerId: 12D3KooWQGQo81K99HfbwuwhvbP4MYfo13fo7U6SAdkAnxoNBdPE
34+
//Key for peerId: 12D3KooWDPZGpr4Jeq144R2KhezH7UHgHqyMXySh8tA5jzUyu2P8
3535
const privateKey = [
3636
183, 7, 117, 9, 159, 132, 170, 235, 215, 34, 145, 181, 60, 207, 4, 27, 27,
3737
17, 17, 167, 100, 89, 157, 218, 73, 200, 183, 145, 104, 151, 204, 142, 241,
3838
94, 225, 7, 153, 168, 239, 94, 7, 187, 123, 158, 149, 149, 227, 170, 32, 54,
3939
203, 243, 211, 78, 120, 114, 199, 1, 197, 134, 6, 91, 87, 152,
4040
];
4141
const privateKeyString = "\\test";
42-
const bloxAddr = '/dns/relay.dev.fx.land/tcp/4001/p2p/12D3KooWDRrBaAfPwsGJivBoUw5fE7ZpDiyfUjqgiURq2DEcL835/p2p-circuit/p2p/12D3KooWD69C5yX91nPe3tz6HRiuw7Pia4xsxE9xv2CghoyK6MPK';
42+
const bloxAddr = '/dns/relay.dev.fx.land/tcp/4001/p2p/12D3KooWDRrBaAfPwsGJivBoUw5fE7ZpDiyfUjqgiURq2DEcL835/p2p-circuit/p2p/12D3KooWQR2XygKM7jhBduhvz2GDJdGEbZL8SZhkeBuXYPn2kRt6';
4343
const newClient = async () => {
4444
try {
4545
return fula.newClient(
@@ -419,6 +419,70 @@ const App = () => {
419419
}}
420420
color={inprogress ? 'green' : 'blue'}
421421
/>
422+
423+
<Button
424+
title={inprogress ? 'Getting...' : 'Remove all Wifis'}
425+
onPress={async () => {
426+
try {
427+
if (initComplete) {
428+
fula.checkConnection().then((r) => {
429+
console.log('connection check');
430+
console.log(r);
431+
if (r) {
432+
console.log(
433+
'initialization is completed. send remove wifis command'
434+
);
435+
fxblox
436+
.wifiRemoveall()
437+
.then((res) => {
438+
console.log('wifiRemoveall received');
439+
console.log(res);
440+
})
441+
.catch((e) => {
442+
console.log('wifiRemoveall failed');
443+
console.log(e);
444+
});
445+
}
446+
});
447+
} else {
448+
console.log('wait for init to complete');
449+
}
450+
} catch (e) {}
451+
}}
452+
color={inprogress ? 'green' : 'blue'}
453+
/>
454+
455+
<Button
456+
title={inprogress ? 'Getting...' : 'Reboot'}
457+
onPress={async () => {
458+
try {
459+
if (initComplete) {
460+
fula.checkConnection().then((r) => {
461+
console.log('connection check');
462+
console.log(r);
463+
if (r) {
464+
console.log(
465+
'initialization is completed. send reboot command'
466+
);
467+
fxblox
468+
.reboot()
469+
.then((res) => {
470+
console.log('reboot received');
471+
console.log(res);
472+
})
473+
.catch((e) => {
474+
console.log('reboot failed');
475+
console.log(e);
476+
});
477+
}
478+
});
479+
} else {
480+
console.log('wait for init to complete');
481+
}
482+
} catch (e) {}
483+
}}
484+
color={inprogress ? 'green' : 'blue'}
485+
/>
422486
</View>
423487
</View>
424488
);

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@functionland/react-native-fula",
3-
"version": "1.2.4",
3+
"version": "1.9.0",
44
"description": "This package is a bridge to use the Fula libp2p protocols in the react-native which is using wnfs",
55
"main": "lib/commonjs/index",
66
"module": "lib/module/index",

src/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * as fula from './protocols/fula';
22
export * as blockchain from './protocols/blockchain';
3-
export * as chainApi from './protocols/chain-api';
3+
export * as chainApi from './protocols/chain-api';
4+
export * as fxblox from './protocols/fxblox';

src/interfaces/fulaNativeModule.ts

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ interface FulaNativeModule {
1919
autoFlush: boolean, //set to false always unless you know what you are doing. This is to write actions to disk explicitly after each write
2020
useRelay: boolean | null, // if true it forces the use of relay
2121
refresh: boolean // if true it forces to refresh the fula object
22-
) => Promise<string>;
22+
) => Promise<string>;
2323
isReady: (filesystemCheck: boolean) => Promise<boolean>;
2424
logout: (identity: string, storePath: string) => Promise<boolean>;
2525
checkFailedActions: (retry: boolean, timeout: number) => Promise<boolean>;
@@ -47,7 +47,7 @@ interface FulaNativeModule {
4747

4848
shutdown: () => Promise<void>;
4949

50-
//Blockchain related functions
50+
//Blockchain related functions
5151
createAccount: (seed: string) => Promise<string>;
5252
checkAccountExists: (account: string) => Promise<string>;
5353
createPool: (seed: string, poolName: string) => Promise<string>;
@@ -56,14 +56,47 @@ interface FulaNativeModule {
5656
leavePool: (seed: string, poolID: number) => Promise<string>;
5757
cancelPoolJoin: (seed: string, poolID: number) => Promise<string>;
5858
listPoolJoinRequests: (poolID: number) => Promise<string>;
59-
votePoolJoinRequest: (seed: string, poolID: number, account: string, accept: boolean) => Promise<string>;
60-
newReplicationRequest: (seed: string, poolID: number, replicationFactor: number, cid: string) => Promise<string>;
61-
newStoreRequest: (seed: string, poolID: number, uploader: string, cid: string) => Promise<string>;
59+
votePoolJoinRequest: (
60+
seed: string,
61+
poolID: number,
62+
account: string,
63+
accept: boolean
64+
) => Promise<string>;
65+
newReplicationRequest: (
66+
seed: string,
67+
poolID: number,
68+
replicationFactor: number,
69+
cid: string
70+
) => Promise<string>;
71+
newStoreRequest: (
72+
seed: string,
73+
poolID: number,
74+
uploader: string,
75+
cid: string
76+
) => Promise<string>;
6277
listAvailableReplicationRequests: (poolID: number) => Promise<string>;
63-
removeReplicationRequest: (seed: string, poolID: number, cid: string) => Promise<string>;
64-
removeStorer: (seed: string, storer: string, poolID: number, cid: string) => Promise<string>;
65-
removeStoredReplication: (seed: string, uploader: string, poolID: number, cid: string) => Promise<string>;
78+
removeReplicationRequest: (
79+
seed: string,
80+
poolID: number,
81+
cid: string
82+
) => Promise<string>;
83+
removeStorer: (
84+
seed: string,
85+
storer: string,
86+
poolID: number,
87+
cid: string
88+
) => Promise<string>;
89+
removeStoredReplication: (
90+
seed: string,
91+
uploader: string,
92+
poolID: number,
93+
cid: string
94+
) => Promise<string>;
95+
96+
//Hardware
6697
bloxFreeSpace: () => Promise<string>;
98+
wifiRemoveall: () => Promise<string>;
99+
reboot: () => Promise<string>;
67100
}
68101

69102
const LINKING_ERROR =

0 commit comments

Comments
 (0)