mirror of
https://github.com/3lLobo/zkAuth.git
synced 2026-01-10 04:47:56 -05:00
las commit
This commit is contained in:
@@ -25,6 +25,9 @@ contract ZkSocialRecoveryWallet is IERC721Receiver {
|
||||
uint256 private thresholdForRecovery;
|
||||
|
||||
uint256 public currentRecoveryNumber;
|
||||
//to retrieve in frontend
|
||||
uint256 public numberTrustees;
|
||||
address[] public Trustees;
|
||||
|
||||
mapping(address => bool) Trustee;
|
||||
|
||||
@@ -104,37 +107,40 @@ contract ZkSocialRecoveryWallet is IERC721Receiver {
|
||||
constructor(
|
||||
address _hashCheckVerifier,
|
||||
uint256 _ownerPasswordHash,
|
||||
address[] memory _trustees,
|
||||
uint256[] memory _passwordHashes,
|
||||
uint256 _thresholdForRecovery,
|
||||
uint256 _root,
|
||||
address _otpVerifier
|
||||
) {
|
||||
require(_hashCheckVerifier != address(0), 'Zero address verifier');
|
||||
require(
|
||||
_trustees.length == _passwordHashes.length,
|
||||
'Trustees and hashes length diff'
|
||||
);
|
||||
require(
|
||||
_trustees.length >= _thresholdForRecovery,
|
||||
'Threshold is greater than number of trustees'
|
||||
);
|
||||
|
||||
hashCheckVerifier = _hashCheckVerifier;
|
||||
owner = msg.sender;
|
||||
ownerPasswordHash = _ownerPasswordHash;
|
||||
|
||||
thresholdForRecovery = _thresholdForRecovery;
|
||||
otpVerifierAddress = _otpVerifier;
|
||||
otpVerifier = new ZkOtpValidator(_root, _otpVerifier);
|
||||
}
|
||||
|
||||
for (uint256 i = 0; i < _trustees.length; i++) {
|
||||
// To set trustees after deployment
|
||||
function setTrustees(address[] memory _trustees) external isOwner {
|
||||
for (uint256 i = 0; i < _trustees.length; i++) {
|
||||
require(!Trustee[_trustees[i]], 'Duplicate trustee in list');
|
||||
Trustee[_trustees[i]] = true;
|
||||
trusteeToPasswordHash[_trustees[i]] = _passwordHashes[i];
|
||||
}
|
||||
|
||||
thresholdForRecovery = _thresholdForRecovery;
|
||||
|
||||
otpVerifierAddress = _otpVerifier;
|
||||
|
||||
otpVerifier = new ZkOtpValidator(_root, _otpVerifier);
|
||||
Trustees = _trustees;
|
||||
numberTrustees = _trustees.length;
|
||||
}
|
||||
|
||||
// Set trustees password after deployment
|
||||
function setTrusteesPasswords(uint256[] memory _passwordHashes) external isOwner {
|
||||
require(
|
||||
Trustees.length == _passwordHashes.length,
|
||||
'Trustees and hashes length diff'
|
||||
);
|
||||
for (uint256 i = 0; i < Trustees.length; i++) {
|
||||
trusteeToPasswordHash[Trustees[i]] = _passwordHashes[i];
|
||||
}
|
||||
}
|
||||
|
||||
function startRecovery(
|
||||
|
||||
@@ -15,18 +15,13 @@ contract ZkWalletFactory {
|
||||
|
||||
function deployWallet(
|
||||
uint256 _ownerPasswordHash,
|
||||
address[] memory _trustees,
|
||||
uint256[] memory _passwordHashes,
|
||||
uint256 _thresholdForRecovery,
|
||||
address _otpVerifier,
|
||||
uint256 _root
|
||||
|
||||
) external returns (address walletAddress) {
|
||||
ZkSocialRecoveryWallet wallet = new ZkSocialRecoveryWallet(
|
||||
hashCheckVerifier,
|
||||
_ownerPasswordHash,
|
||||
_trustees,
|
||||
_passwordHashes,
|
||||
_thresholdForRecovery,
|
||||
_root,
|
||||
_otpVerifier
|
||||
|
||||
@@ -29,32 +29,44 @@ import type {
|
||||
|
||||
export interface ZkSocialRecoveryWalletInterface extends utils.Interface {
|
||||
functions: {
|
||||
"Trustees(uint256)": FunctionFragment;
|
||||
"cancelRecovery(uint256[2],uint256[2][2],uint256[2],uint256[1],uint256)": FunctionFragment;
|
||||
"currentRecoveryNumber()": FunctionFragment;
|
||||
"executeRecoveryChange(uint256[2],uint256[2][2],uint256[2],uint256[1],uint256)": FunctionFragment;
|
||||
"executeTxn(uint256[2],uint256[2][2],uint256[2],uint256[2],address,uint256)": FunctionFragment;
|
||||
"isRecoveryOn()": FunctionFragment;
|
||||
"numberTrustees()": FunctionFragment;
|
||||
"onERC721Received(address,address,uint256,bytes)": FunctionFragment;
|
||||
"otpVerifierAddress()": FunctionFragment;
|
||||
"owner()": FunctionFragment;
|
||||
"setTrustees(address[])": FunctionFragment;
|
||||
"setTrusteesPasswords(uint256[])": FunctionFragment;
|
||||
"startRecovery(uint256[2],uint256[2][2],uint256[2],uint256[1],address)": FunctionFragment;
|
||||
"voteInRecovery(uint256[2],uint256[2][2],uint256[2],uint256[1],uint256)": FunctionFragment;
|
||||
};
|
||||
|
||||
getFunction(
|
||||
nameOrSignatureOrTopic:
|
||||
| "Trustees"
|
||||
| "cancelRecovery"
|
||||
| "currentRecoveryNumber"
|
||||
| "executeRecoveryChange"
|
||||
| "executeTxn"
|
||||
| "isRecoveryOn"
|
||||
| "numberTrustees"
|
||||
| "onERC721Received"
|
||||
| "otpVerifierAddress"
|
||||
| "owner"
|
||||
| "setTrustees"
|
||||
| "setTrusteesPasswords"
|
||||
| "startRecovery"
|
||||
| "voteInRecovery"
|
||||
): FunctionFragment;
|
||||
|
||||
encodeFunctionData(
|
||||
functionFragment: "Trustees",
|
||||
values: [PromiseOrValue<BigNumberish>]
|
||||
): string;
|
||||
encodeFunctionData(
|
||||
functionFragment: "cancelRecovery",
|
||||
values: [
|
||||
@@ -103,6 +115,10 @@ export interface ZkSocialRecoveryWalletInterface extends utils.Interface {
|
||||
functionFragment: "isRecoveryOn",
|
||||
values?: undefined
|
||||
): string;
|
||||
encodeFunctionData(
|
||||
functionFragment: "numberTrustees",
|
||||
values?: undefined
|
||||
): string;
|
||||
encodeFunctionData(
|
||||
functionFragment: "onERC721Received",
|
||||
values: [
|
||||
@@ -117,6 +133,14 @@ export interface ZkSocialRecoveryWalletInterface extends utils.Interface {
|
||||
values?: undefined
|
||||
): string;
|
||||
encodeFunctionData(functionFragment: "owner", values?: undefined): string;
|
||||
encodeFunctionData(
|
||||
functionFragment: "setTrustees",
|
||||
values: [PromiseOrValue<string>[]]
|
||||
): string;
|
||||
encodeFunctionData(
|
||||
functionFragment: "setTrusteesPasswords",
|
||||
values: [PromiseOrValue<BigNumberish>[]]
|
||||
): string;
|
||||
encodeFunctionData(
|
||||
functionFragment: "startRecovery",
|
||||
values: [
|
||||
@@ -144,6 +168,7 @@ export interface ZkSocialRecoveryWalletInterface extends utils.Interface {
|
||||
]
|
||||
): string;
|
||||
|
||||
decodeFunctionResult(functionFragment: "Trustees", data: BytesLike): Result;
|
||||
decodeFunctionResult(
|
||||
functionFragment: "cancelRecovery",
|
||||
data: BytesLike
|
||||
@@ -161,6 +186,10 @@ export interface ZkSocialRecoveryWalletInterface extends utils.Interface {
|
||||
functionFragment: "isRecoveryOn",
|
||||
data: BytesLike
|
||||
): Result;
|
||||
decodeFunctionResult(
|
||||
functionFragment: "numberTrustees",
|
||||
data: BytesLike
|
||||
): Result;
|
||||
decodeFunctionResult(
|
||||
functionFragment: "onERC721Received",
|
||||
data: BytesLike
|
||||
@@ -170,6 +199,14 @@ export interface ZkSocialRecoveryWalletInterface extends utils.Interface {
|
||||
data: BytesLike
|
||||
): Result;
|
||||
decodeFunctionResult(functionFragment: "owner", data: BytesLike): Result;
|
||||
decodeFunctionResult(
|
||||
functionFragment: "setTrustees",
|
||||
data: BytesLike
|
||||
): Result;
|
||||
decodeFunctionResult(
|
||||
functionFragment: "setTrusteesPasswords",
|
||||
data: BytesLike
|
||||
): Result;
|
||||
decodeFunctionResult(
|
||||
functionFragment: "startRecovery",
|
||||
data: BytesLike
|
||||
@@ -268,6 +305,11 @@ export interface ZkSocialRecoveryWallet extends BaseContract {
|
||||
removeListener: OnEvent<this>;
|
||||
|
||||
functions: {
|
||||
Trustees(
|
||||
arg0: PromiseOrValue<BigNumberish>,
|
||||
overrides?: CallOverrides
|
||||
): Promise<[string]>;
|
||||
|
||||
cancelRecovery(
|
||||
a: [PromiseOrValue<BigNumberish>, PromiseOrValue<BigNumberish>],
|
||||
b: [
|
||||
@@ -309,6 +351,8 @@ export interface ZkSocialRecoveryWallet extends BaseContract {
|
||||
|
||||
isRecoveryOn(overrides?: CallOverrides): Promise<[boolean]>;
|
||||
|
||||
numberTrustees(overrides?: CallOverrides): Promise<[BigNumber]>;
|
||||
|
||||
onERC721Received(
|
||||
arg0: PromiseOrValue<string>,
|
||||
arg1: PromiseOrValue<string>,
|
||||
@@ -321,6 +365,16 @@ export interface ZkSocialRecoveryWallet extends BaseContract {
|
||||
|
||||
owner(overrides?: CallOverrides): Promise<[string]>;
|
||||
|
||||
setTrustees(
|
||||
_trustees: PromiseOrValue<string>[],
|
||||
overrides?: Overrides & { from?: PromiseOrValue<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
setTrusteesPasswords(
|
||||
_passwordHashes: PromiseOrValue<BigNumberish>[],
|
||||
overrides?: Overrides & { from?: PromiseOrValue<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
startRecovery(
|
||||
a: [PromiseOrValue<BigNumberish>, PromiseOrValue<BigNumberish>],
|
||||
b: [
|
||||
@@ -346,6 +400,11 @@ export interface ZkSocialRecoveryWallet extends BaseContract {
|
||||
): Promise<ContractTransaction>;
|
||||
};
|
||||
|
||||
Trustees(
|
||||
arg0: PromiseOrValue<BigNumberish>,
|
||||
overrides?: CallOverrides
|
||||
): Promise<string>;
|
||||
|
||||
cancelRecovery(
|
||||
a: [PromiseOrValue<BigNumberish>, PromiseOrValue<BigNumberish>],
|
||||
b: [
|
||||
@@ -387,6 +446,8 @@ export interface ZkSocialRecoveryWallet extends BaseContract {
|
||||
|
||||
isRecoveryOn(overrides?: CallOverrides): Promise<boolean>;
|
||||
|
||||
numberTrustees(overrides?: CallOverrides): Promise<BigNumber>;
|
||||
|
||||
onERC721Received(
|
||||
arg0: PromiseOrValue<string>,
|
||||
arg1: PromiseOrValue<string>,
|
||||
@@ -399,6 +460,16 @@ export interface ZkSocialRecoveryWallet extends BaseContract {
|
||||
|
||||
owner(overrides?: CallOverrides): Promise<string>;
|
||||
|
||||
setTrustees(
|
||||
_trustees: PromiseOrValue<string>[],
|
||||
overrides?: Overrides & { from?: PromiseOrValue<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
setTrusteesPasswords(
|
||||
_passwordHashes: PromiseOrValue<BigNumberish>[],
|
||||
overrides?: Overrides & { from?: PromiseOrValue<string> }
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
startRecovery(
|
||||
a: [PromiseOrValue<BigNumberish>, PromiseOrValue<BigNumberish>],
|
||||
b: [
|
||||
@@ -424,6 +495,11 @@ export interface ZkSocialRecoveryWallet extends BaseContract {
|
||||
): Promise<ContractTransaction>;
|
||||
|
||||
callStatic: {
|
||||
Trustees(
|
||||
arg0: PromiseOrValue<BigNumberish>,
|
||||
overrides?: CallOverrides
|
||||
): Promise<string>;
|
||||
|
||||
cancelRecovery(
|
||||
a: [PromiseOrValue<BigNumberish>, PromiseOrValue<BigNumberish>],
|
||||
b: [
|
||||
@@ -465,6 +541,8 @@ export interface ZkSocialRecoveryWallet extends BaseContract {
|
||||
|
||||
isRecoveryOn(overrides?: CallOverrides): Promise<boolean>;
|
||||
|
||||
numberTrustees(overrides?: CallOverrides): Promise<BigNumber>;
|
||||
|
||||
onERC721Received(
|
||||
arg0: PromiseOrValue<string>,
|
||||
arg1: PromiseOrValue<string>,
|
||||
@@ -477,6 +555,16 @@ export interface ZkSocialRecoveryWallet extends BaseContract {
|
||||
|
||||
owner(overrides?: CallOverrides): Promise<string>;
|
||||
|
||||
setTrustees(
|
||||
_trustees: PromiseOrValue<string>[],
|
||||
overrides?: CallOverrides
|
||||
): Promise<void>;
|
||||
|
||||
setTrusteesPasswords(
|
||||
_passwordHashes: PromiseOrValue<BigNumberish>[],
|
||||
overrides?: CallOverrides
|
||||
): Promise<void>;
|
||||
|
||||
startRecovery(
|
||||
a: [PromiseOrValue<BigNumberish>, PromiseOrValue<BigNumberish>],
|
||||
b: [
|
||||
@@ -545,6 +633,11 @@ export interface ZkSocialRecoveryWallet extends BaseContract {
|
||||
};
|
||||
|
||||
estimateGas: {
|
||||
Trustees(
|
||||
arg0: PromiseOrValue<BigNumberish>,
|
||||
overrides?: CallOverrides
|
||||
): Promise<BigNumber>;
|
||||
|
||||
cancelRecovery(
|
||||
a: [PromiseOrValue<BigNumberish>, PromiseOrValue<BigNumberish>],
|
||||
b: [
|
||||
@@ -586,6 +679,8 @@ export interface ZkSocialRecoveryWallet extends BaseContract {
|
||||
|
||||
isRecoveryOn(overrides?: CallOverrides): Promise<BigNumber>;
|
||||
|
||||
numberTrustees(overrides?: CallOverrides): Promise<BigNumber>;
|
||||
|
||||
onERC721Received(
|
||||
arg0: PromiseOrValue<string>,
|
||||
arg1: PromiseOrValue<string>,
|
||||
@@ -598,6 +693,16 @@ export interface ZkSocialRecoveryWallet extends BaseContract {
|
||||
|
||||
owner(overrides?: CallOverrides): Promise<BigNumber>;
|
||||
|
||||
setTrustees(
|
||||
_trustees: PromiseOrValue<string>[],
|
||||
overrides?: Overrides & { from?: PromiseOrValue<string> }
|
||||
): Promise<BigNumber>;
|
||||
|
||||
setTrusteesPasswords(
|
||||
_passwordHashes: PromiseOrValue<BigNumberish>[],
|
||||
overrides?: Overrides & { from?: PromiseOrValue<string> }
|
||||
): Promise<BigNumber>;
|
||||
|
||||
startRecovery(
|
||||
a: [PromiseOrValue<BigNumberish>, PromiseOrValue<BigNumberish>],
|
||||
b: [
|
||||
@@ -624,6 +729,11 @@ export interface ZkSocialRecoveryWallet extends BaseContract {
|
||||
};
|
||||
|
||||
populateTransaction: {
|
||||
Trustees(
|
||||
arg0: PromiseOrValue<BigNumberish>,
|
||||
overrides?: CallOverrides
|
||||
): Promise<PopulatedTransaction>;
|
||||
|
||||
cancelRecovery(
|
||||
a: [PromiseOrValue<BigNumberish>, PromiseOrValue<BigNumberish>],
|
||||
b: [
|
||||
@@ -667,6 +777,8 @@ export interface ZkSocialRecoveryWallet extends BaseContract {
|
||||
|
||||
isRecoveryOn(overrides?: CallOverrides): Promise<PopulatedTransaction>;
|
||||
|
||||
numberTrustees(overrides?: CallOverrides): Promise<PopulatedTransaction>;
|
||||
|
||||
onERC721Received(
|
||||
arg0: PromiseOrValue<string>,
|
||||
arg1: PromiseOrValue<string>,
|
||||
@@ -681,6 +793,16 @@ export interface ZkSocialRecoveryWallet extends BaseContract {
|
||||
|
||||
owner(overrides?: CallOverrides): Promise<PopulatedTransaction>;
|
||||
|
||||
setTrustees(
|
||||
_trustees: PromiseOrValue<string>[],
|
||||
overrides?: Overrides & { from?: PromiseOrValue<string> }
|
||||
): Promise<PopulatedTransaction>;
|
||||
|
||||
setTrusteesPasswords(
|
||||
_passwordHashes: PromiseOrValue<BigNumberish>[],
|
||||
overrides?: Overrides & { from?: PromiseOrValue<string> }
|
||||
): Promise<PopulatedTransaction>;
|
||||
|
||||
startRecovery(
|
||||
a: [PromiseOrValue<BigNumberish>, PromiseOrValue<BigNumberish>],
|
||||
b: [
|
||||
|
||||
@@ -29,7 +29,7 @@ import type {
|
||||
|
||||
export interface ZkWalletFactoryInterface extends utils.Interface {
|
||||
functions: {
|
||||
"deployWallet(uint256,address[],uint256[],uint256,address,uint256)": FunctionFragment;
|
||||
"deployWallet(uint256,uint256,address,uint256)": FunctionFragment;
|
||||
"getUserWalletAddress(address)": FunctionFragment;
|
||||
"hashCheckVerifier()": FunctionFragment;
|
||||
"userAddressToWalletAddress(address)": FunctionFragment;
|
||||
@@ -47,8 +47,6 @@ export interface ZkWalletFactoryInterface extends utils.Interface {
|
||||
functionFragment: "deployWallet",
|
||||
values: [
|
||||
PromiseOrValue<BigNumberish>,
|
||||
PromiseOrValue<string>[],
|
||||
PromiseOrValue<BigNumberish>[],
|
||||
PromiseOrValue<BigNumberish>,
|
||||
PromiseOrValue<string>,
|
||||
PromiseOrValue<BigNumberish>
|
||||
@@ -127,8 +125,6 @@ export interface ZkWalletFactory extends BaseContract {
|
||||
functions: {
|
||||
deployWallet(
|
||||
_ownerPasswordHash: PromiseOrValue<BigNumberish>,
|
||||
_trustees: PromiseOrValue<string>[],
|
||||
_passwordHashes: PromiseOrValue<BigNumberish>[],
|
||||
_thresholdForRecovery: PromiseOrValue<BigNumberish>,
|
||||
_otpVerifier: PromiseOrValue<string>,
|
||||
_root: PromiseOrValue<BigNumberish>,
|
||||
@@ -150,8 +146,6 @@ export interface ZkWalletFactory extends BaseContract {
|
||||
|
||||
deployWallet(
|
||||
_ownerPasswordHash: PromiseOrValue<BigNumberish>,
|
||||
_trustees: PromiseOrValue<string>[],
|
||||
_passwordHashes: PromiseOrValue<BigNumberish>[],
|
||||
_thresholdForRecovery: PromiseOrValue<BigNumberish>,
|
||||
_otpVerifier: PromiseOrValue<string>,
|
||||
_root: PromiseOrValue<BigNumberish>,
|
||||
@@ -173,8 +167,6 @@ export interface ZkWalletFactory extends BaseContract {
|
||||
callStatic: {
|
||||
deployWallet(
|
||||
_ownerPasswordHash: PromiseOrValue<BigNumberish>,
|
||||
_trustees: PromiseOrValue<string>[],
|
||||
_passwordHashes: PromiseOrValue<BigNumberish>[],
|
||||
_thresholdForRecovery: PromiseOrValue<BigNumberish>,
|
||||
_otpVerifier: PromiseOrValue<string>,
|
||||
_root: PromiseOrValue<BigNumberish>,
|
||||
@@ -202,8 +194,6 @@ export interface ZkWalletFactory extends BaseContract {
|
||||
estimateGas: {
|
||||
deployWallet(
|
||||
_ownerPasswordHash: PromiseOrValue<BigNumberish>,
|
||||
_trustees: PromiseOrValue<string>[],
|
||||
_passwordHashes: PromiseOrValue<BigNumberish>[],
|
||||
_thresholdForRecovery: PromiseOrValue<BigNumberish>,
|
||||
_otpVerifier: PromiseOrValue<string>,
|
||||
_root: PromiseOrValue<BigNumberish>,
|
||||
@@ -226,8 +216,6 @@ export interface ZkWalletFactory extends BaseContract {
|
||||
populateTransaction: {
|
||||
deployWallet(
|
||||
_ownerPasswordHash: PromiseOrValue<BigNumberish>,
|
||||
_trustees: PromiseOrValue<string>[],
|
||||
_passwordHashes: PromiseOrValue<BigNumberish>[],
|
||||
_thresholdForRecovery: PromiseOrValue<BigNumberish>,
|
||||
_otpVerifier: PromiseOrValue<string>,
|
||||
_root: PromiseOrValue<BigNumberish>,
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,33 +0,0 @@
|
||||
/* global BigInt */
|
||||
|
||||
import { generateWitness } from './generate_witness';
|
||||
import { groth16 } from 'snarkjs';
|
||||
|
||||
export async function generateCalldata(input, circuit_name) {
|
||||
let generateWitnessSuccess = true;
|
||||
|
||||
let witness = await generateWitness(input, circuit_name).then()
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
generateWitnessSuccess = false;
|
||||
});
|
||||
|
||||
//console.log(witness);
|
||||
|
||||
if (!generateWitnessSuccess) { return; }
|
||||
|
||||
const { proof, publicSignals } = await groth16.prove(`${circuit_name}_circuit_final.zkey`, witness);
|
||||
|
||||
const calldata = await groth16.exportSolidityCallData(proof, publicSignals);
|
||||
|
||||
const argv = calldata.replace(/["[\]\s]/g, "").split(',').map(x => BigInt(x).toString());
|
||||
|
||||
//console.log(argv);
|
||||
|
||||
const a = [argv[0], argv[1]];
|
||||
const b = [[argv[2], argv[3]], [argv[4], argv[5]]];
|
||||
const c = [argv[6], argv[7]];
|
||||
const Input = argv.slice(8);
|
||||
|
||||
return [a, b, c, Input];
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import wc from "./witness_calculator";
|
||||
|
||||
export async function generateWitness (input, circuit_name) {
|
||||
const response = await fetch(`${circuit_name}_circuit.wasm`);
|
||||
const buffer = await response.arrayBuffer();
|
||||
//console.log(buffer);
|
||||
let buff;
|
||||
|
||||
await wc(buffer).then(async witnessCalculator => {
|
||||
buff = await witnessCalculator.calculateWTNSBin(input, 0);
|
||||
});
|
||||
return buff;
|
||||
}
|
||||
@@ -1,289 +0,0 @@
|
||||
/* global BigInt */
|
||||
module.exports = async function builder(code, options) {
|
||||
|
||||
options = options || {};
|
||||
|
||||
const wasmModule = await WebAssembly.compile(code);
|
||||
|
||||
let wc;
|
||||
|
||||
|
||||
const instance = await WebAssembly.instantiate(wasmModule, {
|
||||
runtime: {
|
||||
exceptionHandler : function(code) {
|
||||
let errStr;
|
||||
if (code === 1) {
|
||||
errStr= "Signal not found. ";
|
||||
} else if (code === 2) {
|
||||
errStr= "Too many signals set. ";
|
||||
} else if (code === 3) {
|
||||
errStr= "Signal already set. ";
|
||||
} else if (code === 4) {
|
||||
errStr= "Assert Failed. ";
|
||||
} else if (code === 5) {
|
||||
errStr= "Not enough memory. ";
|
||||
} else {
|
||||
errStr= "Unknown error\n";
|
||||
}
|
||||
// get error message from wasm
|
||||
errStr += getMessage();
|
||||
throw new Error(errStr);
|
||||
},
|
||||
showSharedRWMemory: function() {
|
||||
printSharedRWMemory ();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
const sanityCheck =
|
||||
options
|
||||
// options &&
|
||||
// (
|
||||
// options.sanityCheck ||
|
||||
// options.logGetSignal ||
|
||||
// options.logSetSignal ||
|
||||
// options.logStartComponent ||
|
||||
// options.logFinishComponent
|
||||
// );
|
||||
|
||||
|
||||
wc = new WitnessCalculator(instance, sanityCheck);
|
||||
return wc;
|
||||
|
||||
function getMessage() {
|
||||
var message = "";
|
||||
var c = instance.exports.getMessageChar();
|
||||
while ( c !== 0 ) {
|
||||
message += String.fromCharCode(c);
|
||||
c = instance.exports.getMessageChar();
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
function printSharedRWMemory () {
|
||||
const shared_rw_memory_size = instance.exports.getFieldNumLen32();
|
||||
const arr = new Uint32Array(shared_rw_memory_size);
|
||||
for (let j=0; j<shared_rw_memory_size; j++) {
|
||||
arr[shared_rw_memory_size-1-j] = instance.exports.readSharedRWMemory(j);
|
||||
}
|
||||
console.log(fromArray32(arr));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class WitnessCalculator {
|
||||
constructor(instance, sanityCheck) {
|
||||
this.instance = instance;
|
||||
|
||||
this.version = this.instance.exports.getVersion();
|
||||
this.n32 = this.instance.exports.getFieldNumLen32();
|
||||
|
||||
this.instance.exports.getRawPrime();
|
||||
const arr = new Array(this.n32);
|
||||
for (let i=0; i<this.n32; i++) {
|
||||
arr[this.n32-1-i] = this.instance.exports.readSharedRWMemory(i);
|
||||
}
|
||||
this.prime = fromArray32(arr);
|
||||
|
||||
this.witnessSize = this.instance.exports.getWitnessSize();
|
||||
|
||||
this.sanityCheck = sanityCheck;
|
||||
}
|
||||
|
||||
circom_version() {
|
||||
return this.instance.exports.getVersion();
|
||||
}
|
||||
|
||||
async _doCalculateWitness(input, sanityCheck) {
|
||||
//input is assumed to be a map from signals to arrays of bigints
|
||||
this.instance.exports.init((this.sanityCheck || sanityCheck) ? 1 : 0);
|
||||
const keys = Object.keys(input);
|
||||
var input_counter = 0;
|
||||
keys.forEach( (k) => {
|
||||
const h = fnvHash(k);
|
||||
const hMSB = parseInt(h.slice(0,8), 16);
|
||||
const hLSB = parseInt(h.slice(8,16), 16);
|
||||
const fArr = flatArray(input[k]);
|
||||
for (let i=0; i<fArr.length; i++) {
|
||||
const arrFr = toArray32(fArr[i],this.n32)
|
||||
for (let j=0; j<this.n32; j++) {
|
||||
this.instance.exports.writeSharedRWMemory(j,arrFr[this.n32-1-j]);
|
||||
}
|
||||
try {
|
||||
this.instance.exports.setInputSignal(hMSB, hLSB,i);
|
||||
input_counter++;
|
||||
} catch (err) {
|
||||
// console.log(`After adding signal ${i} of ${k}`)
|
||||
throw new Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
if (input_counter < this.instance.exports.getInputSize()) {
|
||||
throw new Error(`Not all inputs have been set. Only ${input_counter} out of ${this.instance.exports.getInputSize()}`);
|
||||
}
|
||||
}
|
||||
|
||||
async calculateWitness(input, sanityCheck) {
|
||||
|
||||
const w = [];
|
||||
|
||||
await this._doCalculateWitness(input, sanityCheck);
|
||||
|
||||
for (let i=0; i<this.witnessSize; i++) {
|
||||
this.instance.exports.getWitness(i);
|
||||
const arr = new Uint32Array(this.n32);
|
||||
for (let j=0; j<this.n32; j++) {
|
||||
arr[this.n32-1-j] = this.instance.exports.readSharedRWMemory(j);
|
||||
}
|
||||
w.push(fromArray32(arr));
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
async calculateBinWitness(input, sanityCheck) {
|
||||
|
||||
const buff32 = new Uint32Array(this.witnessSize*this.n32);
|
||||
const buff = new Uint8Array( buff32.buffer);
|
||||
await this._doCalculateWitness(input, sanityCheck);
|
||||
|
||||
for (let i=0; i<this.witnessSize; i++) {
|
||||
this.instance.exports.getWitness(i);
|
||||
const pos = i*this.n32;
|
||||
for (let j=0; j<this.n32; j++) {
|
||||
buff32[pos+j] = this.instance.exports.readSharedRWMemory(j);
|
||||
}
|
||||
}
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
|
||||
async calculateWTNSBin(input, sanityCheck) {
|
||||
|
||||
const buff32 = new Uint32Array(this.witnessSize*this.n32+this.n32+11);
|
||||
const buff = new Uint8Array( buff32.buffer);
|
||||
await this._doCalculateWitness(input, sanityCheck);
|
||||
|
||||
//"wtns"
|
||||
buff[0] = "w".charCodeAt(0)
|
||||
buff[1] = "t".charCodeAt(0)
|
||||
buff[2] = "n".charCodeAt(0)
|
||||
buff[3] = "s".charCodeAt(0)
|
||||
|
||||
//version 2
|
||||
buff32[1] = 2;
|
||||
|
||||
//number of sections: 2
|
||||
buff32[2] = 2;
|
||||
|
||||
//id section 1
|
||||
buff32[3] = 1;
|
||||
|
||||
const n8 = this.n32*4;
|
||||
//id section 1 length in 64bytes
|
||||
const idSection1length = 8 + n8;
|
||||
const idSection1lengthHex = idSection1length.toString(16);
|
||||
buff32[4] = parseInt(idSection1lengthHex.slice(0,8), 16);
|
||||
buff32[5] = parseInt(idSection1lengthHex.slice(8,16), 16);
|
||||
|
||||
//this.n32
|
||||
buff32[6] = n8;
|
||||
|
||||
//prime number
|
||||
this.instance.exports.getRawPrime();
|
||||
|
||||
var pos = 7;
|
||||
for (let j=0; j<this.n32; j++) {
|
||||
buff32[pos+j] = this.instance.exports.readSharedRWMemory(j);
|
||||
}
|
||||
pos += this.n32;
|
||||
|
||||
// witness size
|
||||
buff32[pos] = this.witnessSize;
|
||||
pos++;
|
||||
|
||||
//id section 2
|
||||
buff32[pos] = 2;
|
||||
pos++;
|
||||
|
||||
// section 2 length
|
||||
const idSection2length = n8*this.witnessSize;
|
||||
const idSection2lengthHex = idSection2length.toString(16);
|
||||
buff32[pos] = parseInt(idSection2lengthHex.slice(0,8), 16);
|
||||
buff32[pos+1] = parseInt(idSection2lengthHex.slice(8,16), 16);
|
||||
|
||||
pos += 2;
|
||||
for (let i=0; i<this.witnessSize; i++) {
|
||||
this.instance.exports.getWitness(i);
|
||||
for (let j=0; j<this.n32; j++) {
|
||||
buff32[pos+j] = this.instance.exports.readSharedRWMemory(j);
|
||||
}
|
||||
pos += this.n32;
|
||||
}
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function toArray32(s,size) {
|
||||
const res = []; //new Uint32Array(size); //has no unshift
|
||||
let rem = BigInt(s);
|
||||
const radix = BigInt(0x100000000);
|
||||
while (rem) {
|
||||
res.unshift( Number(rem % radix));
|
||||
rem = rem / radix;
|
||||
}
|
||||
if (size) {
|
||||
var i = size - res.length;
|
||||
while (i>0) {
|
||||
res.unshift(0);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function fromArray32(arr) { //returns a BigInt
|
||||
var res = BigInt(0);
|
||||
const radix = BigInt(0x100000000);
|
||||
for (let i = 0; i<arr.length; i++) {
|
||||
res = res*radix + BigInt(arr[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function flatArray(a) {
|
||||
var res = [];
|
||||
fillArray(res, a);
|
||||
return res;
|
||||
|
||||
function fillArray(res, a) {
|
||||
if (Array.isArray(a)) {
|
||||
for (let i=0; i<a.length; i++) {
|
||||
fillArray(res, a[i]);
|
||||
}
|
||||
} else {
|
||||
res.push(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fnvHash(str) {
|
||||
const uint64_max = BigInt(2) ** BigInt(64);
|
||||
let hash = BigInt("0xCBF29CE484222325");
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
hash ^= BigInt(str[i].charCodeAt());
|
||||
hash *= BigInt(0x100000001B3);
|
||||
hash %= uint64_max;
|
||||
}
|
||||
let shash = hash.toString(16);
|
||||
let n = 16 - shash.length;
|
||||
shash = '0'.repeat(n).concat(shash);
|
||||
return shash;
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
import { ModalSetSocial } from './'
|
||||
|
||||
const BoxSocialRecovery = () => {
|
||||
interface BoxSocialProps {
|
||||
numberTrustees: string
|
||||
}
|
||||
|
||||
const BoxSocialRecovery = (props: BoxSocialProps) => {
|
||||
return (
|
||||
<div
|
||||
className="grid grid-cols-12 col-span-4 w-full p-6 rounded-lg border shadow-md
|
||||
@@ -11,13 +15,17 @@ const BoxSocialRecovery = () => {
|
||||
<div className="text-sm text-gray-600 dark:text-gray-400 mb-3">
|
||||
Social Recovery
|
||||
</div>
|
||||
<div className="text-2xl mb-5">Enabled</div>
|
||||
<ModalSetSocial />
|
||||
{props.numberTrustees != '0' ? (
|
||||
<div className="text-2xl mb-5">Enabled</div>
|
||||
) : (
|
||||
<div className="text-2xl mb-5">Disabled</div>
|
||||
)}
|
||||
<ModalSetSocial enabled={props.numberTrustees == '0'} />
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col col-span-4 items-center justify-center">
|
||||
<div className="text-[6rem] text-gray-900 dark:text-gray-200 leading-none -mt-4">
|
||||
3
|
||||
{props.numberTrustees}
|
||||
</div>
|
||||
<div className="text-xs text-center text-gray-600 dark:text-gray-400">
|
||||
Recovery accounts
|
||||
|
||||
@@ -85,7 +85,7 @@ const ModalChangePassword = () => {
|
||||
className="w-3/4 px-2 py-2 button-unsaturated"
|
||||
onClick={(e) => onSubmit(e)}
|
||||
>
|
||||
Set Accounts
|
||||
Reset Password
|
||||
</button>
|
||||
<Transition.Root show={open} as={Fragment}>
|
||||
<Dialog as="div" className="relative z-10" onClose={setOpen}>
|
||||
|
||||
@@ -10,7 +10,9 @@ import { useTheme } from 'next-themes'
|
||||
import { PlusIcon } from '@heroicons/react/24/solid'
|
||||
import { PasswordTOTPBox, PasswordZKBox } from '.'
|
||||
|
||||
interface ModalSetSocialProps {}
|
||||
interface ModalSetSocialProps {
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
const ModalSetSocial = (props: ModalSetSocialProps) => {
|
||||
const [open, setOpen] = useState(false)
|
||||
@@ -193,12 +195,16 @@ const ModalSetSocial = (props: ModalSetSocialProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
className="w-3/4 px-2 py-2 button-unsaturated"
|
||||
onClick={(e) => onSubmit(e)}
|
||||
>
|
||||
Set Accounts
|
||||
</button>
|
||||
{props.enabled ? (
|
||||
<button
|
||||
className="w-3/4 px-2 py-2 button-unsaturated"
|
||||
onClick={(e) => onSubmit(e)}
|
||||
>
|
||||
Set Accounts
|
||||
</button>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
<Transition.Root show={open} as={Fragment}>
|
||||
<Dialog as="div" className="relative z-10" onClose={setOpen}>
|
||||
<Transition.Child
|
||||
@@ -354,7 +360,7 @@ const ModalSetSocial = (props: ModalSetSocialProps) => {
|
||||
id="password"
|
||||
className="w-full mt-3 flex flex-row gap-3 justify-center"
|
||||
>
|
||||
{false ? (
|
||||
{true ? (
|
||||
<PasswordTOTPBox
|
||||
setOpen={setOpen}
|
||||
allVerified={allVerified}
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
} from '@heroicons/react/24/outline'
|
||||
import { ethers } from 'ethers'
|
||||
import { useResolveName } from '@usedapp/core'
|
||||
import PasswordTOTPBox from './PasswordTOTPBox'
|
||||
|
||||
interface ModalTxDetailsProps {}
|
||||
|
||||
@@ -123,6 +124,11 @@ const ModalTxDetails = (props: ModalTxDetailsProps) => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{/* // TODO FLORIAN */}
|
||||
<PasswordTOTPBox setOpen={setOpen} allVerified={false} />
|
||||
</div>
|
||||
|
||||
<div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
import { ethers } from "ethers";
|
||||
import address from '../artifacts/address.json';
|
||||
import ZkWallet from '../artifacts/ZkSocialRecoveryWallet.json';
|
||||
import ZkWalletFactory from '../artifacts/ZkWalletFactory.json';
|
||||
import { generateCalldata } from '../circuit_js/generate_calldata.js';
|
||||
|
||||
let factory: ethers.Contract;
|
||||
let zkWallet: ethers.Contract;
|
||||
|
||||
export async function connectContract(addr: string) {
|
||||
const { ethereum } = window;
|
||||
|
||||
let provider = new ethers.providers.Web3Provider(ethereum);
|
||||
let signer = provider.getSigner();
|
||||
console.log('signer: ', await signer.getAddress());
|
||||
|
||||
zkWallet = new ethers.Contract(addr, ZkWallet.abi, signer);
|
||||
|
||||
console.log("Connect to ZkWalletAddress Contract:", addr);
|
||||
}
|
||||
|
||||
export async function connectZkWalletFactory() {
|
||||
const { ethereum } = window;
|
||||
|
||||
let provider = new ethers.providers.Web3Provider(ethereum);
|
||||
let signer = provider.getSigner();
|
||||
console.log('signer: ', await signer.getAddress());
|
||||
|
||||
factory = new ethers.Contract(address['ZkWalletFactory'], ZkWalletFactory.abi, signer);
|
||||
|
||||
console.log("Connect to ZkWalletFactory Contract:", ZkWalletFactory);
|
||||
}
|
||||
|
||||
export async function deployZkWallet(ownerPasswordHash: BigInt, trustees: string[], passwordHashes: BigInt[], thresholdForRecovery: number, root: BigInt) {
|
||||
await connectZkWalletFactory();
|
||||
|
||||
let txn = await factory.deployWallet(address["HashCheckVerfier"], ownerPasswordHash, trustees, passwordHashes, thresholdForRecovery, root, address["OtpMerkleTreeVerifier"]);
|
||||
let rc = await txn.wait()
|
||||
|
||||
let newWalletAddress = txn.events[0].args.walletAddress;
|
||||
|
||||
localStorage.setItem("ZkWalletAddress", newWalletAddress);
|
||||
|
||||
return newWalletAddress;
|
||||
}
|
||||
|
||||
export async function hashCheckGenerateCalldata(input: Object) {
|
||||
if (localStorage.getItem('ZkWalletAddress')) {
|
||||
console.log(localStorage.getItem('ZkWalletAddress'));
|
||||
await connectContract(localStorage.getItem('ZkWalletAddress')!);
|
||||
} else {
|
||||
throw new Error("No zkWallet contract address found. Deploy first.");
|
||||
}
|
||||
|
||||
let calldata = await generateCalldata(input, 'hash_check');
|
||||
return calldata;
|
||||
//a: calldata[0], b: calldata[1], c: calldata[2], Input: calldata[3]
|
||||
}
|
||||
|
||||
export async function otpVerificationGenerateCalldata(input: Object) {
|
||||
if (localStorage.getItem('ZkWalletAddress')) {
|
||||
console.log(localStorage.getItem('ZkWalletAddress'));
|
||||
await connectContract(localStorage.getItem('ZkWalletAddress')!);
|
||||
} else {
|
||||
throw new Error("No zkWallet contract address found. Deploy first.");
|
||||
}
|
||||
|
||||
let calldata = await generateCalldata(input, 'otp_verification');
|
||||
return calldata;
|
||||
//a: calldata[0], b: calldata[1], c: calldata[2], Input: calldata[3]
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ethers } from 'ethers'
|
||||
import { address } from '../../backend/config'
|
||||
import { generateCalldata } from './circuits/generate_calldata'
|
||||
import { buildPoseidon } from 'circomlibjs'
|
||||
|
||||
import zkWalletFactoryJson from '../../backend/artifacts/contracts/ZkWalletFactory.sol/ZkWalletFactory.json'
|
||||
|
||||
@@ -10,6 +11,7 @@ import ZkWalletJson from '../../backend/artifacts/contracts/ZkSocialRecoveryWall
|
||||
|
||||
let zkWalletFactory: ethers.Contract
|
||||
let ZkOtpValidator: ethers.Contract
|
||||
let ZkWallet: ethers.Contract
|
||||
|
||||
export async function connectTOTPVerifier(
|
||||
provider: ethers.providers.JsonRpcProvider,
|
||||
@@ -86,8 +88,6 @@ export async function deployZkWallet(
|
||||
|
||||
const zkWalletFactoryContract = await zkWalletFactory.deployWallet(
|
||||
0,
|
||||
[],
|
||||
[],
|
||||
0,
|
||||
otpVerifier,
|
||||
root
|
||||
@@ -96,6 +96,19 @@ export async function deployZkWallet(
|
||||
return zkWalletFactoryContract.address
|
||||
}
|
||||
|
||||
export function connectZkWallet(
|
||||
provider: ethers.providers.JsonRpcProvider,
|
||||
walletAddress: string
|
||||
) {
|
||||
let signer = provider.getSigner()
|
||||
|
||||
const iface = new ethers.utils.Interface(ZkWalletJson.abi)
|
||||
|
||||
ZkWallet = new ethers.Contract(walletAddress, iface, signer)
|
||||
console.log('Connect to ZkWallet Contract:', ZkWallet)
|
||||
return ZkWallet
|
||||
}
|
||||
|
||||
// export async function zkProof(input: Object) {
|
||||
|
||||
// let calldata = await generateCalldata(input);
|
||||
@@ -148,3 +161,29 @@ export async function zkTimestampProof(input: Object) {
|
||||
}
|
||||
return tx
|
||||
}
|
||||
|
||||
export async function setSocialRecovery(
|
||||
provider: ethers.providers.JsonRpcProvider,
|
||||
accounts: string[]
|
||||
) {
|
||||
const signer = provider.getSigner()
|
||||
const zkWalletContract = ZkWallet.connect(signer)
|
||||
await zkWalletContract.setTrustees(accounts)
|
||||
}
|
||||
|
||||
export async function initiateSocialRecovery(
|
||||
provider: ethers.providers.JsonRpcProvider,
|
||||
passwords: string[]
|
||||
) {
|
||||
const signer = provider.getSigner()
|
||||
const zkWalletContract = ZkWallet.connect(signer)
|
||||
let hashes: string[] = []
|
||||
|
||||
let poseidon = await buildPoseidon()
|
||||
for (let password in passwords) {
|
||||
const hash = poseidon.F.toObject(poseidon(password))
|
||||
hashes.push(hash)
|
||||
}
|
||||
|
||||
await zkWalletContract.setTrusteesPasswords(hashes)
|
||||
}
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import { useEthers } from '@usedapp/core'
|
||||
import { info } from 'console'
|
||||
import { ethers } from 'ethers'
|
||||
import { motion } from 'framer-motion'
|
||||
import type { NextPage } from 'next'
|
||||
import { useCallback, useEffect } from 'react'
|
||||
import { useTheme } from 'next-themes'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { ThreeDots } from 'react-loader-spinner'
|
||||
import {
|
||||
BoxApprovedTxs,
|
||||
BoxAuthSystem,
|
||||
BoxSocialRecovery,
|
||||
BoxPendingTransaction,
|
||||
} from '../components'
|
||||
import { connectFactory, connectZkWallet } from '../helpers/contracts'
|
||||
|
||||
const containerUpperBoxes = {
|
||||
hidden: {},
|
||||
@@ -64,7 +69,7 @@ const txBox = {
|
||||
}
|
||||
|
||||
const Dashboard: NextPage = () => {
|
||||
const { activate, library } = useEthers()
|
||||
const { activate, library, account } = useEthers()
|
||||
|
||||
// Set up provider if already connected
|
||||
const checkMetaMaskConnected = useCallback(async () => {
|
||||
@@ -83,44 +88,99 @@ const Dashboard: NextPage = () => {
|
||||
checkMetaMaskConnected()
|
||||
}, [checkMetaMaskConnected])
|
||||
|
||||
// Load blockchain info
|
||||
const router = useRouter()
|
||||
const [loadingBlock, setLoadingBlock] = useState(true)
|
||||
const [info, setInfo] = useState({
|
||||
trustees: [],
|
||||
numberTrustees: '0',
|
||||
})
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
if (library && account) {
|
||||
//load factory
|
||||
const zkWalletFactory = connectFactory(library)
|
||||
const walletAddress = await zkWalletFactory.userAddressToWalletAddress(
|
||||
account
|
||||
)
|
||||
if (walletAddress == ethers.constants.AddressZero) {
|
||||
router.push('./login')
|
||||
return
|
||||
}
|
||||
//load wallet
|
||||
const zkWallet = connectZkWallet(library, walletAddress)
|
||||
const numberTrustees = (await zkWallet.numberTrustees()).toString()
|
||||
const trustees = [] //await zkWallet.Trustees(1)
|
||||
setInfo({ ...info, numberTrustees: numberTrustees })
|
||||
setLoadingBlock(false)
|
||||
}
|
||||
}
|
||||
if (library && account) {
|
||||
loadData()
|
||||
}
|
||||
}, [library, account])
|
||||
|
||||
// Manage theme hydration
|
||||
const { theme } = useTheme()
|
||||
const [loaded, setLoaded] = useState(false)
|
||||
useEffect(() => {
|
||||
if (theme) {
|
||||
setLoaded(true)
|
||||
}
|
||||
})
|
||||
if (!loaded) return null
|
||||
|
||||
return (
|
||||
<div className="h-[calc(100vh-100px)] flex justify-center mt-10">
|
||||
<div className="w-[90%] max-w-6xl flex flex-col">
|
||||
<motion.div
|
||||
variants={containerUpperBoxes}
|
||||
initial="hidden"
|
||||
animate="show"
|
||||
className="w-full grid grid-cols-12 gap-4"
|
||||
>
|
||||
<motion.div variants={upperBox} className="col-span-4">
|
||||
<BoxAuthSystem />
|
||||
</motion.div>
|
||||
<motion.div variants={upperBox} className="col-span-4">
|
||||
<BoxSocialRecovery />
|
||||
</motion.div>
|
||||
<motion.div variants={upperBox} className="col-span-4">
|
||||
<BoxApprovedTxs />
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
variants={containerTxBoxes}
|
||||
initial="hidden"
|
||||
animate="show"
|
||||
className="w-full mt-10"
|
||||
>
|
||||
{' '}
|
||||
{loadingBlock ? (
|
||||
<div className="flex justify-center">
|
||||
<ThreeDots
|
||||
height="50"
|
||||
width="70"
|
||||
radius="9"
|
||||
color={theme == 'dark' ? '#ffffff' : '#3b83f6'}
|
||||
ariaLabel="three-dots-loading"
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-[90%] max-w-6xl flex flex-col">
|
||||
<motion.div
|
||||
variants={txTitle}
|
||||
className="text-2xl text-gray-800 dark:text-white mb-6"
|
||||
variants={containerUpperBoxes}
|
||||
initial="hidden"
|
||||
animate="show"
|
||||
className="w-full grid grid-cols-12 gap-4"
|
||||
>
|
||||
Pending transactions
|
||||
</motion.div>
|
||||
{[1, 2].map((key, tx) => (
|
||||
<motion.div variants={txBox} key={key} className="w-full mb-6">
|
||||
<BoxPendingTransaction />
|
||||
<motion.div variants={upperBox} className="col-span-4">
|
||||
<BoxAuthSystem />
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
<motion.div variants={upperBox} className="col-span-4">
|
||||
<BoxSocialRecovery numberTrustees={info['numberTrustees']} />
|
||||
</motion.div>
|
||||
<motion.div variants={upperBox} className="col-span-4">
|
||||
<BoxApprovedTxs />
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
<motion.div
|
||||
variants={containerTxBoxes}
|
||||
initial="hidden"
|
||||
animate="show"
|
||||
className="w-full mt-10"
|
||||
>
|
||||
<motion.div
|
||||
variants={txTitle}
|
||||
className="text-2xl text-gray-800 dark:text-white mb-6"
|
||||
>
|
||||
Pending transactions
|
||||
</motion.div>
|
||||
{[1, 2].map((key, tx) => (
|
||||
<motion.div variants={txBox} key={key} className="w-full mb-6">
|
||||
<BoxPendingTransaction />
|
||||
</motion.div>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user