Unverified Commit ea3c150e authored by Joseph Mark's avatar Joseph Mark Committed by GitHub
Browse files

fix: seed reference wrapper (#583)



* Decrypt and sign without seed crossing bridge

- decrypt the seed in rust and return a raw pointer as i64
- from ios return int64_t
- from android return double using Double.longBitsToDouble
- in typescript use number
- sign messages by passing the seed reference and converting back to a
String pointer in rust

* Comment new functions in native.ts

* Remove debug code

* lint

* lint fixes

* safe typescript wrapper for seed reference

* remove package-lock.json from .gitignore

* add missing type

* initialize dataRef

* comments and names

* lint

* use seed ref as hooks

* Add signing functions to seedRefHooks

* Hook to SeedRef class instead of bridge functions

* fix SeedRefHooks

* SeedRefHooks an obj
Co-authored-by: default avatarHanwen Cheng <heawen.cheng@gmail.com>
parent fae7a7eb
Pipeline #86251 failed with stages
in 3 minutes and 47 seconds
......@@ -158,31 +158,63 @@ export function schnorrkelVerify(
return EthkeyBridge.schnorrkelVerify(seed, message, signature);
}
// Decrypt data and return a reference to the result
export function decryptDataRef(
data: string,
password: string
): Promise<number> {
return EthkeyBridge.decryptDataRef(data, password);
}
export class SeedRef {
private dataRef: number;
private valid: boolean;
// Clean up the memory allocation made by decryptDataRef
export function destroyDataRef(dataRef: number): Promise<number> {
return EthkeyBridge.destroyDataRef(dataRef);
}
constructor() {
this.dataRef = 0;
this.valid = false;
}
// Use a reference returned by decryptDataRef to sign a message
export function brainWalletSignWithRef(
seedRef: number,
message: string
): Promise<string> {
return EthkeyBridge.brainWalletSignWithRef(seedRef, message);
}
isValid(): boolean {
return this.valid;
}
// Use a reference returned by decryptDataRef to sign a message
export function substrateSignWithRef(
seedRef: number,
message: string
): Promise<string> {
return EthkeyBridge.substrateSignWithRef(seedRef, message);
// Decrypt a seed and store the reference. Must be called before signing.
tryCreate(encryptedSeed: string, password: string): Promise<SeedRef> {
if (this.valid) {
// Seed reference was already created.
throw new Error('cannot create a seed reference when one already exists');
}
return EthkeyBridge.decryptDataRef(encryptedSeed, password).then(
(dataRef: number) => {
this.dataRef = dataRef;
this.valid = true;
return this;
}
);
}
// Destroy the decrypted seed. Must be called before this leaves scope or
// memory will leak.
tryDestroy(): Promise<SeedRef> {
if (!this.valid) {
// Seed reference was never created or was already destroyed.
throw new Error('cannot destroy an invalid seed reference');
}
return EthkeyBridge.destroyDataRef(this.dataRef).then(() => {
this.valid = false;
return this;
});
}
// Use the seed reference to sign a message. Will throw an error if
// `tryDestroy` has already been called or if `tryCreate` failed.
tryBrainWalletSign(message: string): Promise<string> {
if (!this.valid) {
// Seed reference was never created or was already destroyed.
throw new Error('cannot sign with an invalid seed reference');
}
return EthkeyBridge.brainWalletSignWithRef(this.dataRef, message);
}
// Use a reference returned by decryptDataRef to sign a message
trySubstrateSign(message: string): Promise<string> {
if (!this.valid) {
// Seed reference was never created or was already destroyed.
throw new Error('cannot sign with an invalid seed reference');
}
return EthkeyBridge.substrateSignWithRef(this.dataRef, message);
}
}
import { useState } from 'react';
import { SeedRef } from 'utils/native';
type IsValidFunc = () => boolean;
type TryCreateFunc = (encryptedSeed: string, password: string) => Promise<void>;
type TryDestroyFunc = () => Promise<void>;
type TrySignFunc = (message: string) => Promise<string>;
type SeedRefHooks = {
isValid: IsValidFunc;
create: TryCreateFunc;
destroy: TryDestroyFunc;
brainWalletSign: TrySignFunc;
substrateSign: TrySignFunc;
};
export function useSeedRef(): SeedRefHooks {
const [seedRef, setSeedRef] = useState<SeedRef>(new SeedRef());
const isValid: IsValidFunc = function () {
return seedRef.isValid();
};
// Decrypt a seed and store the reference. Must be called before signing.
const create: TryCreateFunc = function (
encryptedSeed: string,
password: string
) {
return seedRef.tryCreate(encryptedSeed, password).then(createdRef => {
setSeedRef(createdRef);
});
};
// Destroy the decrypted seed. Must be called before this leaves scope or
// memory will leak.
const destroy: TryDestroyFunc = function () {
return seedRef.tryDestroy().then(destroyedRef => {
setSeedRef(destroyedRef);
});
};
// Use the seed reference to sign a message. Will throw an error if
// `tryDestroy` has already been called or if `tryCreate` failed.
const brainWalletSign: TrySignFunc = function (message: string) {
return seedRef.tryBrainWalletSign(message);
};
// Use the seed reference to sign a message. Will throw an error if
// `tryDestroy` has already been called or if `tryCreate` failed.
const substrateSign: TrySignFunc = function (message: string) {
return seedRef.trySubstrateSign(message);
};
return { brainWalletSign, create, destroy, isValid, substrateSign };
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment