7 changed files with 469 additions and 60 deletions
			
			
		@ -0,0 +1,65 @@ | 
				
			|||||
 | 
					import { IIdentifier } from "@veramo/core"; | 
				
			||||
 | 
					import { DEFAULT_DID_PROVIDER_NAME } from "../veramo/setup"; | 
				
			||||
 | 
					import { getRandomBytesSync } from "ethereum-cryptography/random"; | 
				
			||||
 | 
					import { entropyToMnemonic } from "ethereum-cryptography/bip39"; | 
				
			||||
 | 
					import { wordlist } from "ethereum-cryptography/bip39/wordlists/english"; | 
				
			||||
 | 
					import { HDNode } from "@ethersproject/hdnode"; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** | 
				
			||||
 | 
					 * | 
				
			||||
 | 
					 * | 
				
			||||
 | 
					 * @param {string} address | 
				
			||||
 | 
					 * @param {string} publicHex | 
				
			||||
 | 
					 * @param {string} privateHex | 
				
			||||
 | 
					 * @param {string} derivationPath | 
				
			||||
 | 
					 * @return {*}  {Omit<IIdentifier, 'provider'>} | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					export const newIdentifier = ( | 
				
			||||
 | 
					  address: string, | 
				
			||||
 | 
					  publicHex: string, | 
				
			||||
 | 
					  privateHex: string, | 
				
			||||
 | 
					  derivationPath: string | 
				
			||||
 | 
					): Omit<IIdentifier, keyof "provider"> => { | 
				
			||||
 | 
					  return { | 
				
			||||
 | 
					    did: DEFAULT_DID_PROVIDER_NAME + ":" + address, | 
				
			||||
 | 
					    keys: [ | 
				
			||||
 | 
					      { | 
				
			||||
 | 
					        kid: publicHex, | 
				
			||||
 | 
					        kms: "local", | 
				
			||||
 | 
					        meta: { derivationPath: derivationPath }, | 
				
			||||
 | 
					        privateKeyHex: privateHex, | 
				
			||||
 | 
					        publicKeyHex: publicHex, | 
				
			||||
 | 
					        type: "Secp256k1", | 
				
			||||
 | 
					      }, | 
				
			||||
 | 
					    ], | 
				
			||||
 | 
					    provider: DEFAULT_DID_PROVIDER_NAME, | 
				
			||||
 | 
					    services: [], | 
				
			||||
 | 
					  }; | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export const deriveAddress = ( | 
				
			||||
 | 
					  mnemonic: string | 
				
			||||
 | 
					): [string, string, string, string] => { | 
				
			||||
 | 
					  const UPORT_ROOT_DERIVATION_PATH = "m/7696500'/0'/0'/0'"; | 
				
			||||
 | 
					  mnemonic = mnemonic.trim().toLowerCase(); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  const hdnode: HDNode = HDNode.fromMnemonic(mnemonic); | 
				
			||||
 | 
					  const rootNode: HDNode = hdnode.derivePath(UPORT_ROOT_DERIVATION_PATH); | 
				
			||||
 | 
					  const privateHex = rootNode.privateKey.substring(2); // original starts with '0x'
 | 
				
			||||
 | 
					  const publicHex = rootNode.publicKey.substring(2); // original starts with '0x'
 | 
				
			||||
 | 
					  const address = rootNode.address; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  return [address, privateHex, publicHex, UPORT_ROOT_DERIVATION_PATH]; | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** | 
				
			||||
 | 
					 * | 
				
			||||
 | 
					 * | 
				
			||||
 | 
					 * @return {*}  {string} | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					export const createIdentifier = (): string => { | 
				
			||||
 | 
					  const entropy: Uint8Array = getRandomBytesSync(32); | 
				
			||||
 | 
					  const mnemonic = entropyToMnemonic(entropy, wordlist); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  return mnemonic; | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,100 @@ | 
				
			|||||
 | 
					/* import * as R from "ramda"; | 
				
			||||
 | 
					import { configureStore, createSlice } from "@reduxjs/toolkit"; | 
				
			||||
 | 
					import { IIdentifier } from "@veramo/core"; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import { Contact } from "../entity/contact"; | 
				
			||||
 | 
					import { Settings } from "../entity/settings"; | 
				
			||||
 | 
					import * as utility from "../utility/utility"; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const MAX_LOG_LENGTH = 2000000; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export const DEFAULT_ENDORSER_API_SERVER = "https://endorser.ch:3000"; | 
				
			||||
 | 
					export const DEFAULT_ENDORSER_VIEW_SERVER = "https://endorser.ch"; | 
				
			||||
 | 
					export const LOCAL_ENDORSER_API_SERVER = "http://127.0.0.1:3000"; | 
				
			||||
 | 
					export const LOCAL_ENDORSER_VIEW_SERVER = "http://127.0.0.1:3001"; | 
				
			||||
 | 
					export const TEST_ENDORSER_API_SERVER = "https://test.endorser.ch:8000"; | 
				
			||||
 | 
					export const TEST_ENDORSER_VIEW_SERVER = "https://test.endorser.ch:8080"; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					// for contents set in reducers
 | 
				
			||||
 | 
					interface Payload<T> { | 
				
			||||
 | 
					  type: string; | 
				
			||||
 | 
					  payload: T; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					interface LogMsg { | 
				
			||||
 | 
					  log: boolean; | 
				
			||||
 | 
					  msg: string; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export const appSlice = createSlice({ | 
				
			||||
 | 
					  name: "app", | 
				
			||||
 | 
					  initialState: { | 
				
			||||
 | 
					    // This is nullable because it is cached state from the DB...
 | 
				
			||||
 | 
					    // it'll be null if we haven't even loaded from the DB yet.
 | 
				
			||||
 | 
					    settings: null as Settings, | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    // This is nullable because it is cached state from the DB...
 | 
				
			||||
 | 
					    // it'll be null if we haven't even loaded from the DB yet.
 | 
				
			||||
 | 
					    identifiers: null as Array<IIdentifier> | null, | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    // This is nullable because it is cached state from the DB...
 | 
				
			||||
 | 
					    // it'll be null if we haven't even loaded from the DB yet.
 | 
				
			||||
 | 
					    contacts: null as Array<Contact> | null, | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    viewServer: DEFAULT_ENDORSER_VIEW_SERVER, | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    logMessage: "", | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    advancedMode: false, | 
				
			||||
 | 
					    testMode: false, | 
				
			||||
 | 
					  }, | 
				
			||||
 | 
					  reducers: { | 
				
			||||
 | 
					    addIdentifier: (state, contents: Payload<IIdentifier>) => { | 
				
			||||
 | 
					      state.identifiers = state.identifiers.concat([contents.payload]); | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    addLog: (state, contents: Payload<LogMsg>) => { | 
				
			||||
 | 
					      if (state.logMessage.length > MAX_LOG_LENGTH) { | 
				
			||||
 | 
					        state.logMessage = | 
				
			||||
 | 
					          "<truncated>\n..." + | 
				
			||||
 | 
					          state.logMessage.substring( | 
				
			||||
 | 
					            state.logMessage.length - MAX_LOG_LENGTH / 2 | 
				
			||||
 | 
					          ); | 
				
			||||
 | 
					      } | 
				
			||||
 | 
					      if (contents.payload.log) { | 
				
			||||
 | 
					        console.log(contents.payload.msg); | 
				
			||||
 | 
					        state.logMessage += "\n" + contents.payload.msg; | 
				
			||||
 | 
					      } | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    setAdvancedMode: (state, contents: Payload<boolean>) => { | 
				
			||||
 | 
					      state.advancedMode = contents.payload; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    setContacts: (state, contents: Payload<Array<Contact>>) => { | 
				
			||||
 | 
					      state.contacts = contents.payload; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    setContact: (state, contents: Payload<Contact>) => { | 
				
			||||
 | 
					      const index = R.findIndex( | 
				
			||||
 | 
					        (c) => c.did === contents.payload.did, | 
				
			||||
 | 
					        state.contacts | 
				
			||||
 | 
					      ); | 
				
			||||
 | 
					      state.contacts[index] = contents.payload; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    setHomeScreen: (state, contents: Payload<string>) => { | 
				
			||||
 | 
					      state.settings.homeScreen = contents.payload; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    setIdentifiers: (state, contents: Payload<Array<IIdentifier>>) => { | 
				
			||||
 | 
					      state.identifiers = contents.payload; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    setSettings: (state, contents: Payload<Settings>) => { | 
				
			||||
 | 
					      state.settings = contents.payload; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    setTestMode: (state, contents: Payload<boolean>) => { | 
				
			||||
 | 
					      state.testMode = contents.payload; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    setViewServer: (state, contents: Payload<string>) => { | 
				
			||||
 | 
					      state.viewServer = contents.payload; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					  }, | 
				
			||||
 | 
					}); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export const appStore = configureStore({ reducer: appSlice.reducer }); | 
				
			||||
 | 
					 */ | 
				
			||||
@ -0,0 +1,151 @@ | 
				
			|||||
 | 
					// Created from the setup in https://veramo.io/docs/guides/react_native
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					// Core interfaces
 | 
				
			||||
 | 
					/* import { | 
				
			||||
 | 
					  createAgent, | 
				
			||||
 | 
					  IDIDManager, | 
				
			||||
 | 
					  IResolver, | 
				
			||||
 | 
					  IDataStore, | 
				
			||||
 | 
					  IKeyManager, | 
				
			||||
 | 
					} from "@veramo/core"; | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					// Core identity manager plugin
 | 
				
			||||
 | 
					//import { DIDManager } from "@veramo/did-manager";
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					// Ethr did identity provider
 | 
				
			||||
 | 
					//import { EthrDIDProvider } from "@veramo/did-provider-ethr";
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					// Core key manager plugin
 | 
				
			||||
 | 
					//import { KeyManager } from "@veramo/key-manager";
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					// Custom key management system for RN
 | 
				
			||||
 | 
					//import { KeyManagementSystem } from '@veramo/kms-local-react-native'
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					// Custom resolver
 | 
				
			||||
 | 
					// Custom resolvers
 | 
				
			||||
 | 
					//import { DIDResolverPlugin } from "@veramo/did-resolver";
 | 
				
			||||
 | 
					/* import { Resolver } from "did-resolver"; | 
				
			||||
 | 
					import { getResolver as ethrDidResolver } from "ethr-did-resolver"; | 
				
			||||
 | 
					import { getResolver as webDidResolver } from "web-did-resolver"; | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					// for VCs and VPs https://veramo.io/docs/api/credential-w3c
 | 
				
			||||
 | 
					//import { CredentialIssuer } from '@veramo/credential-w3c'
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					// Storage plugin using TypeOrm
 | 
				
			||||
 | 
					/* import { | 
				
			||||
 | 
					  Entities, | 
				
			||||
 | 
					  KeyStore, | 
				
			||||
 | 
					  DIDStore, | 
				
			||||
 | 
					  IDataStoreORM, | 
				
			||||
 | 
					} from "@veramo/data-store"; | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					// TypeORM is installed with @veramo/typeorm
 | 
				
			||||
 | 
					//import { createConnection } from 'typeorm'
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					//import * as R from "ramda";
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/* | 
				
			||||
 | 
					import { Contact } from '../entity/contact' | 
				
			||||
 | 
					import { Settings } from '../entity/settings' | 
				
			||||
 | 
					import { PrivateData } from '../entity/privateData' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import { Initial1616938713828 }          from '../migration/1616938713828-initial' | 
				
			||||
 | 
					import { SettingsContacts1616967972293 } from '../migration/1616967972293-settings-contacts' | 
				
			||||
 | 
					import { EncryptedSeed1637856484788 }    from '../migration/1637856484788-EncryptedSeed' | 
				
			||||
 | 
					import { HomeScreenConfig1639947962124 } from '../migration/1639947962124-HomeScreenConfig' | 
				
			||||
 | 
					import { HandlePublicKeys1652142819353 } from '../migration/1652142819353-HandlePublicKeys' | 
				
			||||
 | 
					import { LastClaimsSeen1656811846836 }   from '../migration/1656811846836-LastClaimsSeen' | 
				
			||||
 | 
					import { ContactRegistered1662256903367 }from '../migration/1662256903367-ContactRegistered' | 
				
			||||
 | 
					import { PrivateData1663080623479 }      from '../migration/1663080623479-PrivateData' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const ALL_ENTITIES = Entities.concat([Contact, Settings, PrivateData]) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					// Create react native DB connection configured by ormconfig.js
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export const dbConnection = createConnection({ | 
				
			||||
 | 
					  database: 'endorser-mobile.sqlite', | 
				
			||||
 | 
					  entities: ALL_ENTITIES, | 
				
			||||
 | 
					  location: 'default', | 
				
			||||
 | 
					  logging: ['error', 'info', 'warn'], | 
				
			||||
 | 
					  migrations: [ Initial1616938713828, SettingsContacts1616967972293, EncryptedSeed1637856484788, HomeScreenConfig1639947962124, HandlePublicKeys1652142819353, LastClaimsSeen1656811846836, ContactRegistered1662256903367, PrivateData1663080623479 ], | 
				
			||||
 | 
					  migrationsRun: true, | 
				
			||||
 | 
					  type: 'react-native', | 
				
			||||
 | 
					}) | 
				
			||||
 | 
					*/ | 
				
			||||
 | 
					function didProviderName(netName: string) { | 
				
			||||
 | 
					  return "did:ethr" + (netName === "mainnet" ? "" : ":" + netName); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					//const NETWORK_NAMES = ["mainnet", "rinkeby"];
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const DEFAULT_DID_PROVIDER_NETWORK_NAME = "mainnet"; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export const DEFAULT_DID_PROVIDER_NAME = didProviderName( | 
				
			||||
 | 
					  DEFAULT_DID_PROVIDER_NETWORK_NAME | 
				
			||||
 | 
					); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export const HANDY_APP = false; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					// this is used as the object in RegisterAction claims
 | 
				
			||||
 | 
					export const SERVICE_ID = "endorser.ch"; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					//const INFURA_PROJECT_ID = "INFURA_PROJECT_ID";
 | 
				
			||||
 | 
					/* | 
				
			||||
 | 
					const providers = {} | 
				
			||||
 | 
					NETWORK_NAMES.forEach((networkName) => { | 
				
			||||
 | 
					  providers[didProviderName(networkName)] = new EthrDIDProvider({ | 
				
			||||
 | 
					    defaultKms: 'local', | 
				
			||||
 | 
					    network: networkName, | 
				
			||||
 | 
					    rpcUrl: 'https://' + networkName + '.infura.io/v3/' + INFURA_PROJECT_ID, | 
				
			||||
 | 
					    gas: 1000001, | 
				
			||||
 | 
					    ttl: 60 * 60 * 24 * 30 * 12 + 1, | 
				
			||||
 | 
					  }) | 
				
			||||
 | 
					}) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const didManager = new DIDManager({ | 
				
			||||
 | 
					  store: new DIDStore(dbConnection), | 
				
			||||
 | 
					  defaultProvider: DEFAULT_DID_PROVIDER_NAME, | 
				
			||||
 | 
					  providers: providers, | 
				
			||||
 | 
					}) | 
				
			||||
 | 
					*/ | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/* const basicDidResolvers = NETWORK_NAMES.map((networkName) => [ | 
				
			||||
 | 
					  networkName, | 
				
			||||
 | 
					  new Resolver({ | 
				
			||||
 | 
					    ethr: ethrDidResolver({ | 
				
			||||
 | 
					      networks: [ | 
				
			||||
 | 
					        { | 
				
			||||
 | 
					          name: networkName, | 
				
			||||
 | 
					          rpcUrl: | 
				
			||||
 | 
					            "https://" + networkName + ".infura.io/v3/" + INFURA_PROJECT_ID, | 
				
			||||
 | 
					        }, | 
				
			||||
 | 
					      ], | 
				
			||||
 | 
					    }).ethr, | 
				
			||||
 | 
					    web: webDidResolver().web, | 
				
			||||
 | 
					  }), | 
				
			||||
 | 
					]); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const basicResolverMap = R.fromPairs(basicDidResolvers) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export const DEFAULT_BASIC_RESOLVER = basicResolverMap[DEFAULT_DID_PROVIDER_NETWORK_NAME] | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const agentDidResolvers = NETWORK_NAMES.map((networkName) => { | 
				
			||||
 | 
					  return new DIDResolverPlugin({ | 
				
			||||
 | 
					    resolver: basicResolverMap[networkName], | 
				
			||||
 | 
					  }) | 
				
			||||
 | 
					}) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					let allPlugins = [ | 
				
			||||
 | 
					  new CredentialIssuer(), | 
				
			||||
 | 
					  new KeyManager({ | 
				
			||||
 | 
					    store: new KeyStore(dbConnection), | 
				
			||||
 | 
					    kms: { | 
				
			||||
 | 
					      local: new KeyManagementSystem(), | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					  }), | 
				
			||||
 | 
					  didManager, | 
				
			||||
 | 
					].concat(agentDidResolvers) | 
				
			||||
 | 
					*/ | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					//export const agent = createAgent<IDIDManager & IKeyManager & IDataStore & IDataStoreORM & IResolver>({ plugins: allPlugins })
 | 
				
			||||
					Loading…
					
					
				
		Reference in new issue