mirror of
https://github.com/getwax/wax.git
synced 2026-01-09 15:18:02 -05:00
Integrate account salt endpoint
Update relayer class. Update react component flows.
This commit is contained in:
@@ -4,10 +4,11 @@ import { abi as safeAbi } from '../abi/Safe.json'
|
||||
import { abi as recoveryPluginAbi } from '../abi/SafeZkEmailRecoveryPlugin.json'
|
||||
import { safeZkSafeZkEmailRecoveryPlugin } from '../../contracts.base-sepolia.json'
|
||||
import { Button } from './Button'
|
||||
import { genAccountCode, getGuardianSalt, getRequestGuardianSubject } from '../utils/email'
|
||||
import { genAccountCode, getRequestGuardianSubject, templateIdx } from '../utils/email'
|
||||
import { readContract } from 'wagmi/actions'
|
||||
import { config } from '../providers/config'
|
||||
import { pad } from 'viem'
|
||||
import { relayer } from '../services/relayer'
|
||||
|
||||
export function ConfigureSafeModule() {
|
||||
const { address } = useAccount()
|
||||
@@ -66,14 +67,13 @@ export function ConfigureSafeModule() {
|
||||
}
|
||||
|
||||
const accountCode = await genAccountCode();
|
||||
const guardianSalt = await getGuardianSalt(guardianEmail, accountCode);
|
||||
const guardianSalt = await relayer.getAccountSalt(accountCode, guardianEmail);
|
||||
const guardianAddr = await readContract(config, {
|
||||
abi: recoveryPluginAbi,
|
||||
address: safeZkSafeZkEmailRecoveryPlugin as `0x${string}`,
|
||||
functionName: 'computeEmailAuthAddress',
|
||||
args: [guardianSalt]
|
||||
})
|
||||
const subject = getRequestGuardianSubject(address);
|
||||
// TODO Should this be something else?
|
||||
const previousOwnerInLinkedList = pad("0x1", {
|
||||
size: 20
|
||||
@@ -93,16 +93,23 @@ export function ConfigureSafeModule() {
|
||||
|
||||
console.debug('recovery configured');
|
||||
|
||||
accountCode;
|
||||
subject;
|
||||
const recoveryRelayerAddr = await readContract(config, {
|
||||
abi: recoveryPluginAbi,
|
||||
address: safeZkSafeZkEmailRecoveryPlugin as `0x${string}`,
|
||||
functionName: 'getRouterForSafe',
|
||||
args: [address]
|
||||
}) as string;
|
||||
|
||||
// const { requestId } = await relayer.acceptanceRequest(
|
||||
// emailRecoveryRelayer,
|
||||
// guardianEmail,
|
||||
// accountCode,
|
||||
// templateIdx,
|
||||
// subject,
|
||||
// );
|
||||
const subject = getRequestGuardianSubject(address);
|
||||
const { requestId } = await relayer.acceptanceRequest(
|
||||
recoveryRelayerAddr,
|
||||
guardianEmail,
|
||||
accountCode,
|
||||
templateIdx,
|
||||
subject,
|
||||
);
|
||||
|
||||
console.debug('req guard req id', requestId)
|
||||
|
||||
setRecoveryConfigured(true);
|
||||
}, [
|
||||
|
||||
@@ -12,7 +12,12 @@ import {
|
||||
simpleWalletImpl
|
||||
} from '../../contracts.base-sepolia.json'
|
||||
import { ethers } from 'ethers'
|
||||
import { genAccountCode, getRequestGuardianSubject, getRequestsRecoverySubject } from '../utils/email'
|
||||
import {
|
||||
genAccountCode,
|
||||
getRequestGuardianSubject,
|
||||
getRequestsRecoverySubject,
|
||||
templateIdx
|
||||
} from '../utils/email'
|
||||
|
||||
// TODO Pull from lib
|
||||
type HexStr = `0x${string}`;
|
||||
@@ -23,8 +28,6 @@ const storageKeys = {
|
||||
accountCode: 'accountCode',
|
||||
}
|
||||
|
||||
const templateIdx = 0
|
||||
|
||||
// TODO Switch back to Safe over SimpleWallet
|
||||
export function PerformRecovery() {
|
||||
const cfg = useConfig()
|
||||
|
||||
@@ -24,9 +24,8 @@ class Relayer {
|
||||
}
|
||||
|
||||
async requestStatus(requestId: number) {
|
||||
// TODO type res body
|
||||
const { data } = await axios({
|
||||
method: 'GET',
|
||||
method: 'POST',
|
||||
url: `${this.apiUrl}/requestStatus`,
|
||||
data: {
|
||||
request_id: requestId
|
||||
@@ -88,6 +87,18 @@ class Relayer {
|
||||
})
|
||||
return data;
|
||||
}
|
||||
|
||||
async getAccountSalt(accountCode: string, emailAddress: string) {
|
||||
const { data } = await axios<unknown, { data: string }>({
|
||||
method: "POST",
|
||||
url: `${this.apiUrl}/getAccountSalt`,
|
||||
data: {
|
||||
account_code: accountCode,
|
||||
email_addr: emailAddress,
|
||||
}
|
||||
})
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
||||
export const relayer = new Relayer(import.meta.env.VITE_RELAYER_URL);
|
||||
|
||||
@@ -1,25 +1,27 @@
|
||||
import { buildPoseidon, Poseidon } from "circomlibjs";
|
||||
import { buildPoseidon } from "circomlibjs";
|
||||
|
||||
export const templateIdx = 0
|
||||
|
||||
// From https://github.com/zkemail/email-wallet/blob/main/packages/frontend/src/components/RegisterUnclaim.tsx
|
||||
function padStringToBytes(str: string, len: number): Uint8Array {
|
||||
const bytes = new Uint8Array(len);
|
||||
const strBytes = (new TextEncoder).encode(str);
|
||||
bytes.set(strBytes);
|
||||
const empty = new Uint8Array(len - strBytes.length);
|
||||
bytes.set(empty, strBytes.length);
|
||||
return bytes;
|
||||
}
|
||||
// function padStringToBytes(str: string, len: number): Uint8Array {
|
||||
// const bytes = new Uint8Array(len);
|
||||
// const strBytes = (new TextEncoder).encode(str);
|
||||
// bytes.set(strBytes);
|
||||
// const empty = new Uint8Array(len - strBytes.length);
|
||||
// bytes.set(empty, strBytes.length);
|
||||
// return bytes;
|
||||
// }
|
||||
|
||||
function bytes2fields(bytes: Uint8Array, F: Poseidon['F']): bigint[] {
|
||||
const fields: bigint[] = [];
|
||||
for (let i = 0; i < bytes.length; i += 31) {
|
||||
const bytes32 = new Uint8Array(32);
|
||||
bytes32.set(bytes.slice(i, i + 31));
|
||||
const val = F.fromRprLE(bytes32, 0);
|
||||
fields.push(val);
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
// function bytes2fields(bytes: Uint8Array, F: Poseidon['F']): bigint[] {
|
||||
// const fields: bigint[] = [];
|
||||
// for (let i = 0; i < bytes.length; i += 31) {
|
||||
// const bytes32 = new Uint8Array(32);
|
||||
// bytes32.set(bytes.slice(i, i + 31));
|
||||
// const val = F.fromRprLE(bytes32, 0);
|
||||
// fields.push(val);
|
||||
// }
|
||||
// return fields;
|
||||
// }
|
||||
|
||||
export function bytesToHex(bytes: Uint8Array) {
|
||||
return [...bytes]
|
||||
@@ -28,22 +30,25 @@ export function bytesToHex(bytes: Uint8Array) {
|
||||
.join("");
|
||||
}
|
||||
|
||||
export async function genAccountCode(): Promise<Uint8Array> {
|
||||
export async function genAccountCode(): Promise<string> {
|
||||
const poseidon = await buildPoseidon();
|
||||
const accountCodeBytes: Uint8Array = poseidon.F.random();
|
||||
return accountCodeBytes;
|
||||
return bytesToHex(accountCodeBytes);
|
||||
}
|
||||
|
||||
export async function getGuardianSalt(guardianEmail: string, accountCode: Uint8Array) {
|
||||
const poseidon = await buildPoseidon();
|
||||
const emailField = bytes2fields(padStringToBytes(guardianEmail, 256), poseidon.F);
|
||||
const accountSaltBytes = poseidon([
|
||||
...emailField, accountCode, 0
|
||||
]);
|
||||
const accountSalt: `0x${string}` = `0x${bytesToHex(accountSaltBytes)}`
|
||||
return accountSalt;
|
||||
}
|
||||
// Use relayer.getAccountSalt instead
|
||||
// export async function getGuardianSalt(guardianEmail: string, accountCode: Uint8Array) {
|
||||
// const poseidon = await buildPoseidon();
|
||||
// const emailField = bytes2fields(padStringToBytes(guardianEmail, 256), poseidon.F);
|
||||
// const accountSaltBytes = poseidon([
|
||||
// ...emailField, accountCode, 0
|
||||
// ]);
|
||||
// const accountSalt: `0x${string}` = `0x${bytesToHex(accountSaltBytes)}`
|
||||
// return accountSalt;
|
||||
// }
|
||||
|
||||
// TODO Update both with safe module accept subject
|
||||
export const getRequestGuardianSubject = (acctAddr: string) => `Accept guardian request for ${acctAddr}`;
|
||||
export const getRequestsRecoverySubject = (acctAddr: string, newOwner: string) => `Set the new signer of ${acctAddr} to ${newOwner}`;
|
||||
export const getRequestGuardianSubject = (acctAddr: string) =>
|
||||
`Accept guardian request for ${acctAddr}`;
|
||||
export const getRequestsRecoverySubject = (acctAddr: string, newOwner: string) =>
|
||||
`Set the new signer of ${acctAddr} to ${newOwner}`;
|
||||
|
||||
Reference in New Issue
Block a user