Skip to content

Instantly share code, notes, and snippets.

@theblockstalk
Last active July 21, 2022 14:50
Show Gist options
  • Save theblockstalk/7cbb2623cffbdf13cf31fed26903b1fd to your computer and use it in GitHub Desktop.
Save theblockstalk/7cbb2623cffbdf13cf31fed26903b1fd to your computer and use it in GitHub Desktop.
Example showing flow for constructor dependency injection
// This is in the RN app. It shows the Client logic (CreateAccount), the RN Authenticator implementation and the service that calls the blockchain.
import { User as UserSdk, Authenticator, AuthenticatorLevel } from 'tonomy-id-sdk';
class RNAuthenticator implements Authenticator {
createPermission(level: AuthenticatorLevel, privateKey: string, challenge: string) {
// stores the key in keychain with the challenge
return 'publicKey';
}
// signs data with a private key
signData(level: AuthenticatorLevel, dataToSign: string | Uint8[], challenge: string) {
// check the key
// sign with the private key
}
}
// React component example (not using react for readability)
// just shows the logic
class CreateAccount {
user: UserSdk;
constructor(authenticator: Authenticator) {
this.user = new UserSdk(new RNAuthenticator());
}
// User presses create account button, and that calls this function in the client
createAccount(masterPassword: string) {
this.user.createAccount(masterPassword);
}
}
// this shows part of the SDK library with Authenticator interpace, and a User class library.
enum AuthenticatorLevel { Password, PIN, Fingerprint, Local };
interface Authenticator {
// creates a new secure key and returns the public key
createPermission(level: AuthenticatorLevel, privateKey: string, challenge: string): string
// to ensure the most forward compatibility, we send all arguments as properties of an object which can then more easily be depreciated and upgraded over time. a version property can also be added
createPermission(options: any): string
// signs data with a private key
signData(level: AuthenticatorLevel, dataToSign: string | Uint8[], challenge: string): string
// retrieve a public key from a stored private key
getKey(level: AuthenticatorLevel): string
}
class User {
authenticator: Authenticator;
id: IDSmartContract;
constructor(_authenticator: Authenticator) {
this.authenticator = _authenticator;
this.id = new IDSmartContract();
}
createAccount(accountName: string, masterPassword: string) {
const { privateKey, salt } = this.generatePrivateKeyFromPassword(masterPassword);
const passwordPublicKey = this.authenticator.createPermission(AuthenticatorLevel.Password, privateKey, masterPassword);
this.id.create(accountName, passwordPublicKey, salt);
}
signTx(accountName: string, masterPassword: string) {
const { privateKey, salt } = this.generatePrivateKeyFromPassword(masterPassword);
const passwordPublicKey = this.authenticator.createPermission(AuthenticatorLevel.Password, privateKey, masterPassword);
this.id.create(accountName, passwordPublicKey, salt);
}
generatePrivateKeyFromPassword(password: string) {
// creates a key based on secure (hashing) key generation algorithm like Argon2 or Scrypt
return {
privateKey: 'xxxx',
salt: 'yyyy'
}
}
}
// wrapper class that has js interface to call the smart contract
class IDSmartContract {
// calls the ID smart contract create() function to create the account
create(accountName: string, passwordPublicKey: string, salt: string) {
// creates the new account with the public key and account name,
// and stores the salt on chain for later user to re-derive the private key with the password
}
}
export default User;
export { Authenticator, AuthenticatorLevel };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment