Browse Source

Avoid signing transaction repeatedly while in development

develop
Ezerous 6 years ago
parent
commit
d55e3de987
  1. 1
      app/package.json
  2. 30
      app/src/utils/EthereumIdentityProvider.js
  3. 64
      app/src/utils/ethereumIdentityProvider.js
  4. 24
      app/src/utils/levelUtils.js
  5. 3
      app/src/utils/orbitUtils.js

1
app/package.json

@ -14,6 +14,7 @@
"drizzle": "1.4.0", "drizzle": "1.4.0",
"history": "4.9.0", "history": "4.9.0",
"ipfs": "0.35.0", "ipfs": "0.35.0",
"level": "5.0.1",
"lodash.isequal": "4.5.0", "lodash.isequal": "4.5.0",
"orbit-db": "0.21.0-rc.1", "orbit-db": "0.21.0-rc.1",
"orbit-db-identity-provider": "0.1.0", "orbit-db-identity-provider": "0.1.0",

30
app/src/utils/EthereumIdentityProvider.js

@ -1,30 +0,0 @@
import { web3 } from '../redux/sagas/drizzleUtilsSaga';
class EthereumIdentityProvider {
constructor (options = {}) { // Orbit's Identity Id (equals user's Ethereum address)
this.id = options.id; // web3.eth.getAccounts())[0]
}
static get type () { return 'ethereum'; }
async getId () { return this.id; }
async signIdentity (data) {
while(true){ //Insist (e.g. if user dismisses dialog)
try{
return await web3.eth.personal.sign(data, this.id,""); //Password not required for MetaMask
}
catch (e) {
console.error("Failed to sign data.");
}
}
}
static async verifyIdentity (identity) {
// Verify that identity was signed by the ID
return web3.eth.accounts.recover(identity.publicKey + identity.signatures.id,
identity.signatures.publicKey) === identity.id;
}
}
export default EthereumIdentityProvider;

64
app/src/utils/ethereumIdentityProvider.js

@ -0,0 +1,64 @@
import { web3 } from '../redux/sagas/drizzleUtilsSaga';
import { getIdentitySignaturePubKey, storeIdentitySignaturePubKey } from './levelUtils';
class EthereumIdentityProvider {
constructor (options = {}) { // Orbit's Identity Id (equals user's Ethereum address)
this.id = options.id; // web3.eth.getAccounts())[0]
}
static get type () { return 'ethereum'; }
async getId () { return this.id; }
async signIdentity (data) {
if(process.env.NODE_ENV==='development') {
console.debug("Attempting to find stored Orbit identity data...");
const signaturePubKey = await getIdentitySignaturePubKey(data);
if (signaturePubKey) {
if (EthereumIdentityProvider.verifyIdentityInfo({
id: this.id,
pubKeySignId: data,
signaturePubKey
})) {
console.debug("Found and verified stored Orbit identity data!");
return signaturePubKey;
}
console.debug("Stored Orbit identity data couldn't be verified.");
}
else
console.debug("No stored Orbit identity data were found.");
}
while(true){ //Insist (e.g. if user dismisses dialog)
try{
const signaturePubKey = await web3.eth.personal.sign(data, this.id,"");
if(process.env.NODE_ENV==='development')
storeIdentitySignaturePubKey(data, signaturePubKey)
.then(()=>{
console.debug("Successfully stored current Orbit identity data.");
})
.catch(()=>{
console.warn("Couldn't store current Orbit identity data...");
});
return signaturePubKey; //Password not required for MetaMask
}
catch (e) {
console.error("Failed to sign data.");
}
}
}
static async verifyIdentity (identity) {
// Verify that identity was signed by the ID
return web3.eth.accounts.recover(identity.publicKey + identity.signatures.id,
identity.signatures.publicKey) === identity.id;
}
static async verifyIdentityInfo (identityInfo) {
// Verify that identity was signed by the ID
return web3.eth.accounts.recover(identityInfo.pubKeySignId,
identityInfo.signaturePubKey) === identityInfo.id;
}
}
export default EthereumIdentityProvider;

24
app/src/utils/levelUtils.js

@ -0,0 +1,24 @@
import level from 'level'
/* Used in development only to store the identity.signatures.publicKey so developers don't have to
repeatedly sign theOrbitDB creation transaction in MetaMask when React development server reloads
the app */
const apellaDB = level('./apella/identities');
async function storeIdentitySignaturePubKey(key, signaturePubKey){
await apellaDB.put(key, signaturePubKey);
}
// If it exists, it returns the identity.signatures.publicKey for the given key (key is the
// concatenation of identity.publicKey + identity.signatures.id
async function getIdentitySignaturePubKey(key){
try{
return await apellaDB.get(key);
} catch (err) {
if (err && err.notFound)
return null; // Not found
throw err;
}
}
export { storeIdentitySignaturePubKey ,getIdentitySignaturePubKey };

3
app/src/utils/orbitUtils.js

@ -4,7 +4,7 @@ import IPFS from 'ipfs';
import store from '../redux/store'; import store from '../redux/store';
import { DATABASES_LOADED, IPFS_INITIALIZED, updateDatabases } from '../redux/actions/orbitActions'; import { DATABASES_LOADED, IPFS_INITIALIZED, updateDatabases } from '../redux/actions/orbitActions';
import ipfsOptions from '../config/ipfsOptions'; import ipfsOptions from '../config/ipfsOptions';
import EthereumIdentityProvider from './EthereumIdentityProvider'; import EthereumIdentityProvider from './ethereumIdentityProvider';
function initIPFS() { function initIPFS() {
Identities.addIdentityProvider(EthereumIdentityProvider); Identities.addIdentityProvider(EthereumIdentityProvider);
@ -99,7 +99,6 @@ async function createDBs(identityId){
return { orbitdb, topicsDB, postsDB }; return { orbitdb, topicsDB, postsDB };
} }
export { export {
initIPFS, initIPFS,
createDatabases, createDatabases,

Loading…
Cancel
Save