Skip to content

Instantly share code, notes, and snippets.

@nsjames
Created July 17, 2019 10:13
Show Gist options
  • Save nsjames/a30bd7f462654b8467ee91dd9ae06635 to your computer and use it in GitHub Desktop.
Save nsjames/a30bd7f462654b8467ee91dd9ae06635 to your computer and use it in GitHub Desktop.
// @ts-ignore
import BlockchainLoginToken from "../models/tokens/BlockchainLoginToken";
require('isomorphic-fetch');
// @ts-ignore
import Eos from 'eosjs';
const EOS_NODES:any = {
'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906':'https://nodes.get-scatter.com'
};
const eosReferences:any = {};
export const getEosReference = (chainId:string) => {
if(!EOS_NODES.hasOwnProperty(chainId)) return null;
if(!eosReferences.hasOwnProperty(chainId)) {
eosReferences[chainId] = Eos({httpEndpoint: EOS_NODES[chainId], chainId});
}
return eosReferences[chainId];
}
const getEOSIOPublicKeys = async (account:string, chainId:string) => {
if(!EOS_NODES.hasOwnProperty(chainId)) return false;
return fetch(`${EOS_NODES[chainId]}/v1/chain/get_account`, {
method:'POST',
body:JSON.stringify({ account_name:account })
}).then(res => res.json()).then(res => {
return res.permissions.reduce((acc:Array<string>, perm:any) => {
perm.required_auth.keys.map((x:any) => acc.push(x.key));
return acc;
}, []).reduce((acc:Array<string>, key:string) => {
if(!acc.includes(key)) acc.push(key);
return acc;
}, [])
}).catch(() => null)
}
export const getPublicKeys = async (account:string, network:string) => {
const [blockchain, chainId] = network.split(':');
switch(blockchain){
case 'eos': return getEOSIOPublicKeys(account, chainId);
default: return false;
}
}
// @ts-ignore
import ecc from 'eosjs-ecc';
import BlockchainLoginToken from "../models/tokens/BlockchainLoginToken";
import {getEosReference, getPublicKeys} from "./Blockchains";
class BlockchainLoginToken {
id:string;
account:string;
network:string;
token:string;
ipHash:string;
expires:number;
}
/***
* Verifies EOSIO signatures from unbroadcasted on-chain proofs (hardware capable).
* @param token
* @param proof
*/
const verifyEOSIOSignature = async (token:BlockchainLoginToken, proof:any) => {
try {
// Gets all the public keys associated with this account from the blockchain in an array ([key, key])
const publicKeys = await getPublicKeys(token.account, token.network);
const [blockchain, chainId] = token.network.split(':');
const eos = getEosReference(chainId);
// Loading ABI into cache
try { eos.fc.abiCache.abi('scatterproof') }
catch(error) { await eos.contract('scatterproof') }
const abi = eos.fc.abiCache.abi('scatterproof');
const signingFromData = abi.fromBuffer('prove', proof.transaction.actions[0].data);
if(!signingFromData.hasOwnProperty('signing')) return console.error('Invalid transaction: ', proof);
if(signingFromData.signing !== token.token) return console.error('Invalid nonce: ', signingFromData.signing, token);
const buffer = Buffer.concat([
Buffer.from(chainId, 'hex'),
eos.fc.toBuffer("transaction", proof.transaction),
Buffer.from(new Uint8Array(32))
]);
const recoveredKey = ecc.recover(proof.signature, buffer);
return publicKeys.some((x:any) => x === recoveredKey);
} catch(e){
return false;
}
}
#include <eosiolib/eosio.hpp>
using namespace eosio;
CONTRACT scatterproof : contract {
public:
using contract::contract;
void prove(std::string signing){}
};
EOSIO_DISPATCH( scatterproof, (prove) )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment