openpgp.config.rejectCurves = new Set(); // pinched from https://stackoverflow.com/questions/16826200/javascript-silly-name-generator const name_parts = [ ["Runny", "Buttercup", "Dinky", "Stinky", "Crusty", "Greasy","Gidget", "Cheesypoof", "Lumpy", "Wacky", "Tiny", "Flunky", "Fluffy", "Zippy", "Doofus", "Gobsmacked", "Slimy", "Grimy", "Salamander", "Oily", "Burrito", "Bumpy", "Loopy", "Snotty", "Irving", "Egbert"], ["Waffer", "Lilly","Rugrat","Sand", "Fuzzy","Kitty", "Puppy", "Snuggles","Rubber", "Stinky", "Lulu", "Lala", "Sparkle", "Glitter", "Silver", "Golden", "Rainbow", "Cloud", "Rain", "Stormy", "Wink", "Sugar", "Twinkle", "Star", "Halo", "Angel"], ["Snicker", "Buffalo", "Gross", "Bubble", "Sheep", "Corset", "Toilet", "Lizard", "Waffle", "Kumquat", "Burger", "Chimp", "Liver", "Gorilla", "Rhino", "Emu", "Pizza", "Toad", "Gerbil", "Pickle", "Tofu", "Chicken", "Potato", "Hamster", "Lemur", "Vermin"], ["face", "dip", "nose", "brain", "head", "breath", "pants", "shorts", "lips", "mouth", "muffin", "butt", "bottom", "elbow", "honker", "toes", "buns", "spew", "kisser", "fanny", "squirt", "chunks", "brains", "wit", "juice", "shower"], ]; function generateName() { name = ''; for (let i = 0; i < name_parts.length; i++) { if (i > 0 && i < 3) { name += ' '; } const ii = Math.random() * name_parts[i].length; name += name_parts[i][Math.floor(ii)]; } return name; } async function createSessionKey(passphrase) { const name = generateName(); const k = await openpgp.generateKey({ curve: 'secp256k1', userIDs: [{name: name, email: 'none@example.com'}], passphrase: passphrase, format: 'armored', }); return k.privateKey; } async function toKeyPair(pk, passphrase) { let o = await openpgp.readPrivateKey({ armoredKey: pk, }); if (!passphrase) { passphrase = undefined; } if (passphrase !== undefined) { o = await openpgp.decryptKey({ privateKey: o, passphrase: passphrase, }); } const r = o.toPacketList().findPacket(openpgp.enums.packet.secretKey); return { 'publicKey': r.publicParams.Q, 'privateKey': r.privateParams.d, }; } function SessionWallet() { this.provider = null; this.wallet_key = null; this.wallet = null; this.wallet_address = null; //self.wallet_address = "0xeb3907ecad74a0013c259d5874ae7f22dcbcc95c"; } async function ethKeyFromPGPKey(pk, passphrase) { const k = await toKeyPair(pk, passphrase); const signKey = new ethers.SigningKey(k.privateKey); return new ethers.Wallet(signKey); } SessionWallet.prototype.applyKey = async function(pk, passphrase) { this.wallet = await ethKeyFromPGPKey(pk, passphrase); this.wallet_key = pk; this.wallet_address = this.wallet.address; console.log('wallet key applied', this.wallet_address); } SessionWallet.prototype.connect = async function(provider) { this.provider = provider; return this; } SessionWallet.prototype.getAddress = function() { return this.wallet_address; } SessionWallet.prototype.getNonce = async function() { return this.provider.send('eth_getTransactionCount', [this.wallet_address, 'latest']); } async function sessionwallet_create(id, passphrase) { const w = new SessionWallet(); if (window.localStorage.getItem('sessionKey_' + id) == null) { console.debug('creating new key'); const newPk = await createSessionKey(); const ethKey = await ethKeyFromPGPKey(newPk); const o = await openpgp.readKey({ armoredKey: newPk, }); let pl = o.toPacketList(); let u = pl.findPacket(openpgp.enums.packet.userID); let a = ethKey.address; if (a.substring(0, 2) == '0x') { a = a.substring(2); } const uNew = openpgp.UserIDPacket.fromObject({ name: u.name, email: a.toLowerCase() + '@defalsify.org', comment: "evm", }); const r = await openpgp.reformatKey({ privateKey: o, userIDs: [uNew], }); let pku = await openpgp.readKey({ armoredKey: r.privateKey, }); if (passphrase !== undefined) { console.debug('encrypting'); pku = await openpgp.encryptKey({ privateKey: pku, passphrase: passphrase, }); } window.localStorage.setItem('sessionKey_' + id, pku.armor()); pl = pku.toPacketList(); u = pl.findPacket(openpgp.enums.packet.userID); console.debug('added key', u.name, u.email); } const pksrc = window.localStorage.getItem('sessionKey_' + id); console.debug('src', pksrc); let pk = await openpgp.readKey({ armoredKey: pksrc, }); if (passphrase !== undefined) { pk = await openpgp.decryptKey({ privateKey: pk, passphrase: passphrase, }); } await w.applyKey(pk.armor()); // the key is decrypted at this point return w; } async function sessionwallet_importEth(id, passphrase) { const pk = window.localStorage.getItem('sessionKey_' + id); await ethers.Wallet.fromEncryptedJson(pk, passphrase); return pk; } async function sessionwallet_exportEth(id, passphrase, progress) { const pk = window.localStorage.getItem('sessionKey_' + id); const w = await ethKeyFromPGPKey(pk, passphrase); const we = await w.encrypt(passphrase, progress); return we; } async function sessionwallet_exportPgp(id, passphrase, progress) { const pk = window.localStorage.getItem('sessionKey_' + id); console.log(pk); return pk; }