Skip to content

Commit 1d4387f

Browse files
authored
feat: add OIDC accounts to recovery methods view (#74)
* feat: add getOidcAccounts add getOidcAccounts * feat: add oidc recovery card add oidc recovery card * chore: remove console logs remove console logs * refactor: use ByteVector instead of buffer use ByteVector instead of buffer * fix: get oidc accounts return type get oidc accounts return type * chore: bump circuits bump circuits * chore: update lock update lock * fix: nx project dependsOn nx project dependsOn * fix: add submodules submodules
1 parent d9b003d commit 1d4387f

File tree

15 files changed

+1584
-237
lines changed

15 files changed

+1584
-237
lines changed

.github/workflows/deploy-preview.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ jobs:
1818
output_urls: "${{ steps.preview_deploy.outputs.urls }}"
1919
steps:
2020
- uses: actions/checkout@v4 # v4
21+
with:
22+
submodules: 'recursive'
23+
fetch-depth: 0
2124

2225
- name: Setup pnpm
2326
uses: pnpm/action-setup@v4

examples/bank-demo/composables/useCart.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export interface CartData {
88
export const useCart = () => {
99
const cartData = useStorage<CartData>("cart-data", {
1010
amount: 0,
11-
priceOfEth: 1786.79
11+
priceOfEth: 1786.79,
1212
});
1313

1414
return cartData;

examples/bank-demo/composables/useHistory.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
import { useStorage } from "@vueuse/core";
22

3-
4-
53
export interface HistoryData {
6-
mainAccount: Array<{ icon: string; description: string; amount: string; time: string; value: number; }>;
7-
cryptoAccount: Array<{ icon: string; description: string; amount: string; time: string; transactionHash: string; valueEth: number; }>;
4+
mainAccount: Array<{ icon: string; description: string; amount: string; time: string; value: number }>;
5+
cryptoAccount: Array<{ icon: string; description: string; amount: string; time: string; transactionHash: string; valueEth: number }>;
86
}
97

108
export const useHistory = () => {
119
const history = useStorage<HistoryData>("history", {
1210
mainAccount: [
13-
{description: "OBA topup from J Doe", amount: "+ £2,000.00", time: "4 Oct, 13:32 - OBAGNSGT3OXBB4433", icon: "add", value: 2000},
11+
{ description: "OBA topup from J Doe", amount: "+ £2,000.00", time: "4 Oct, 13:32 - OBAGNSGT3OXBB4433", icon: "add", value: 2000 },
1412
],
15-
cryptoAccount: []
13+
cryptoAccount: [],
1614
});
1715

1816
return history;

examples/bank-demo/index.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
declare module "nuxt/schema" {
32
interface PublicRuntimeConfig {
43
aaveAddress: `0x${string}`;

examples/bank-demo/nuxt.config.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ export default defineNuxtConfig({
1515
app: {
1616
head: {
1717
bodyAttrs: {
18-
class: "bg-khaki"
19-
}
20-
}
18+
class: "bg-khaki",
19+
},
20+
},
2121
},
2222
runtimeConfig: {
2323
public: {
@@ -28,7 +28,7 @@ export default defineNuxtConfig({
2828
passkey: "0x455e8d86DC6728396f8d3B740Fc893F4E20b25Dc",
2929
accountFactory: "0x23b13d016E973C9915c6252271fF06cCA2098885",
3030
explorerUrl: "http://localhost:3010/",
31-
}
31+
},
3232
},
3333
$production: {
3434
runtimeConfig: {
@@ -47,8 +47,8 @@ export default defineNuxtConfig({
4747
passkey: "0xCeC63BD0f35e04F3Bef1128bA3A856A7BB4D88f1",
4848
accountFactory: "0x23b13d016E973C9915c6252271fF06cCA2098885",
4949
explorerUrl: "http://34.121.229.57:3010/",
50-
}
51-
}
50+
},
51+
},
5252
},
5353
vite: {
5454
css: {

examples/bank-demo/tailwind.config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export default {
2424
700: "#575757",
2525
800: "#3D3D3D",
2626
900: "#262626",
27-
950: "#1A1A1A"
27+
950: "#1A1A1A",
2828
},
2929
primary: {
3030
50: "#ECEDFE",
@@ -37,7 +37,7 @@ export default {
3737
700: "#0E14B4",
3838
800: "#090D76",
3939
900: "#05073D",
40-
950: "#02031C"
40+
950: "#02031C",
4141
},
4242
warning: {
4343
50: "#FFF9E5",

examples/demo-app/tests/create-account.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { test, expect, type Page } from "@playwright/test";
1+
import { expect, type Page, test } from "@playwright/test";
22

33
async function waitForServicesToLoad(page: Page): Promise<void> {
44
const maxRetryAttempts = 10;

packages/auth-server/components/account-recovery/google-flow/Step2.vue

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<div
3-
v-if="isLoading"
3+
v-if="addOidcAccountIsLoading"
44
class="flex flex-col items-center gap-4"
55
>
66
<common-spinner class="w-8 h-8" />
@@ -24,13 +24,13 @@ import type { OidcData } from "zksync-sso/client";
2424
2525
import { useRecoveryOidc } from "~/composables/useRecoveryOidc";
2626
27-
const { addOidcAccount, isLoading } = useRecoveryOidc();
27+
const { addOidcAccount, addOidcAccountIsLoading } = useRecoveryOidc();
2828
const oidcData = {
2929
oidcDigest: "0xdeadbeef",
30-
iss: "0xdeadbeef",
31-
aud: "0xdeadbeef",
30+
iss: "0x68747470733a2f2f6163636f756e74732e676f6f676c652e636f6d",
31+
aud: "0x7367696e2e617070732e676f6f676c6575736572636f6e74656e742e636f6d",
3232
} as OidcData;
3333
addOidcAccount(oidcData);
3434
35-
defineExpose({ isLoading });
35+
defineExpose({ addOidcAccountIsLoading });
3636
</script>
Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,43 @@
1-
import type { OidcData } from "zksync-sso/client";
1+
import type { Address, Hex } from "viem";
2+
import { OidcRecoveryModuleAbi } from "zksync-sso/abi";
3+
import { type OidcData, type ParsedOidcData, parseOidcData } from "zksync-sso/client";
24

35
export const useRecoveryOidc = () => {
4-
const { getClient, defaultChain } = useClientStore();
6+
const { getClient, getPublicClient, defaultChain } = useClientStore();
57
const paymasterAddress = contractsByChain[defaultChain!.id].accountPaymaster;
68

7-
const { inProgress: isLoading, error, execute: addOidcAccount } = useAsync(async (oidcData: OidcData) => {
9+
const getOidcAccountsInProgress = ref(false);
10+
const getOidcAccountsError = ref<Error | null>(null);
11+
const getOidcAccountsData = ref<readonly ParsedOidcData[] | null>(null);
12+
13+
async function getOidcAccounts(oidcAddress: Address) {
14+
getOidcAccountsInProgress.value = true;
15+
getOidcAccountsError.value = null;
16+
17+
try {
18+
const client = getPublicClient({ chainId: defaultChain.id });
19+
const data = await client.readContract({
20+
address: contractsByChain[defaultChain.id].recoveryOidc,
21+
abi: OidcRecoveryModuleAbi,
22+
functionName: "accountData",
23+
args: [oidcAddress],
24+
});
25+
const oidcData = {
26+
oidcDigest: data[0] as Hex,
27+
iss: data[1] as Hex,
28+
aud: data[2] as Hex,
29+
};
30+
getOidcAccountsData.value = [parseOidcData(oidcData)];
31+
return;
32+
} catch (err) {
33+
getOidcAccountsError.value = err as Error;
34+
return;
35+
} finally {
36+
getOidcAccountsInProgress.value = false;
37+
}
38+
}
39+
40+
const { inProgress: addOidcAccountIsLoading, error: addOidcAccountError, execute: addOidcAccount } = useAsync(async (oidcData: OidcData) => {
841
const client = getClient({ chainId: defaultChain.id });
942

1043
return await client.addOidcAccount({
@@ -16,8 +49,12 @@ export const useRecoveryOidc = () => {
1649
});
1750

1851
return {
52+
getOidcAccounts,
53+
getOidcAccountsInProgress,
54+
getOidcAccountsError,
55+
getOidcAccountsData,
1956
addOidcAccount,
20-
isLoading,
21-
error,
57+
addOidcAccountIsLoading,
58+
addOidcAccountError,
2259
};
2360
};

packages/auth-server/pages/dashboard/settings/index.vue

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<Card
2626
v-for="method in recoveryMethods"
2727
:key="method.address"
28-
:loading="getGuardiansInProgress && removeGuardianInProgress"
28+
:loading="getGuardiansInProgress && removeGuardianInProgress && getOidcAccountsInProgress"
2929
class="p-6"
3030
:class="{ 'border-yellow-400 bg-yellow-50 dark:bg-yellow-950 dark:border-yellow-600': method.pendingUrl }"
3131
>
@@ -42,14 +42,30 @@
4242
(Pending)
4343
</span>
4444
</div>
45-
<div class="flex items-center gap-3 text-gray-600 dark:text-gray-400">
45+
<div
46+
v-if="method.method === 'Guardian'"
47+
class="flex items-center gap-3 text-gray-600 dark:text-gray-400"
48+
>
4649
<WalletIcon class="w-5 h-5 flex-shrink-0" />
4750
<span class="font-mono text-sm">{{ isMobile ? shortenAddress(method.address) : method.address }}</span>
4851
<CopyToClipboard
4952
class="-ml-2"
5053
:text="method.address"
5154
/>
5255
</div>
56+
<div
57+
v-else-if="method.method === 'OIDC'"
58+
class="flex flex-col items-start gap-3 text-gray-600 dark:text-gray-400"
59+
>
60+
<div class="flex items-center gap-3">
61+
<ShieldCheckIcon class="w-5 h-5 flex-shrink-0" />
62+
<span class="font-mono text-sm">{{ method.iss }}</span>
63+
</div>
64+
<div class="flex items-center gap-3">
65+
<SparklesIcon class="w-5 h-5 flex-shrink-0" />
66+
<span class="font-mono text-sm">{{ method.digest }}</span>
67+
</div>
68+
</div>
5369
<p class="text-sm text-gray-500 dark:text-gray-500">
5470
Added on {{ method.addedOn.toLocaleDateString() }} {{ method.addedOn.toLocaleTimeString() }}
5571
</p>
@@ -79,6 +95,7 @@
7995
type="danger"
8096
class="text-sm lg:w-auto w-full"
8197
@click="removeGuardian(method.address)"
98+
v-if="method.method === 'Guardian'"
8299
>
83100
Remove
84101
</Button>
@@ -93,7 +110,7 @@
93110
</template>
94111

95112
<script setup lang="ts">
96-
import { WalletIcon } from "@heroicons/vue/24/solid";
113+
import { ShieldCheckIcon, SparklesIcon, WalletIcon } from "@heroicons/vue/24/solid";
97114
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core";
98115
99116
import AddRecoveryMethodModal from "~/components/account-recovery/AddRecoveryMethodModal.vue";
@@ -106,27 +123,38 @@ const breakpoints = useBreakpoints(breakpointsTailwind);
106123
const isMobile = breakpoints.smaller("lg");
107124
const { address: accountAddress } = useAccountStore();
108125
const { getGuardiansInProgress, getGuardians, getGuardiansData, removeGuardian, removeGuardianInProgress } = useRecoveryGuardian();
126+
const { getOidcAccounts, getOidcAccountsData, getOidcAccountsInProgress } = useRecoveryOidc();
109127
110128
const config = useRuntimeConfig();
111129
112130
const appUrl = config.public.appUrl;
113131
114-
const recoveryMethods = computed(() => (getGuardiansData.value ?? []).map((x) => ({
115-
method: "Guardian",
116-
address: x.addr,
117-
addedOn: new Date(),
118-
...(!x.isReady && { pendingUrl: `${appUrl}/recovery/guardian/confirm-guardian?accountAddress=${accountAddress}&guardianAddress=${x.addr}` }),
119-
})));
132+
const recoveryMethods = computed(() => [
133+
...(getGuardiansData.value ?? []).map((x) => ({
134+
method: "Guardian",
135+
address: x.addr,
136+
addedOn: new Date(),
137+
...(!x.isReady && { pendingUrl: `${appUrl}/recovery/guardian/confirm-guardian?accountAddress=${accountAddress}&guardianAddress=${x.addr}` }),
138+
})),
139+
...(getOidcAccountsData.value ?? []).map((x) => ({
140+
method: "OIDC",
141+
iss: x.iss,
142+
digest: x.oidcDigest,
143+
addedOn: new Date(),
144+
})),
145+
]);
120146
121147
const refreshGuardians = () => {
122148
if (accountAddress) {
123149
getGuardians(accountAddress);
150+
getOidcAccounts(accountAddress);
124151
}
125152
};
126153
127154
watchEffect(async () => {
128155
if (accountAddress) {
129156
await getGuardians(accountAddress);
157+
await getOidcAccounts(accountAddress);
130158
}
131159
});
132160
</script>

0 commit comments

Comments
 (0)