Skip to content

Commit 37701ad

Browse files
committed
feat: changes
1 parent 0aa819c commit 37701ad

File tree

7 files changed

+225
-25
lines changed

7 files changed

+225
-25
lines changed

infrastructure/eid-wallet/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"clsx": "^2.1.1",
3535
"dotenv": "^16.5.0",
3636
"flag-icons": "^7.3.2",
37+
"graphql-request": "^6.1.0",
3738
"import": "^0.0.6",
3839
"svelte-loading-spinners": "^0.3.6",
3940
"tailwind-merge": "^3.0.2",

infrastructure/eid-wallet/src/lib/global/controllers/evault.ts

Lines changed: 191 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,142 @@
11
import type { Store } from "@tauri-apps/plugin-store";
2+
import { GraphQLClient } from "graphql-request";
3+
import axios from "axios";
4+
import { PUBLIC_REGISTRY_URL } from "$env/static/public";
5+
import { UserController } from "./user";
6+
7+
const STORE_META_ENVELOPE = `
8+
mutation StoreMetaEnvelope($input: MetaEnvelopeInput!) {
9+
storeMetaEnvelope(input: $input) {
10+
metaEnvelope {
11+
id
12+
ontology
13+
parsed
14+
}
15+
}
16+
}
17+
`;
18+
19+
interface MetaEnvelopeResponse {
20+
storeMetaEnvelope: {
21+
metaEnvelope: {
22+
id: string;
23+
ontology: string;
24+
parsed: any;
25+
};
26+
};
27+
}
28+
29+
interface UserProfile {
30+
username: string;
31+
displayName: string;
32+
bio: string | null;
33+
avatarUrl: string | null;
34+
bannerUrl: string | null;
35+
ename: string;
36+
isVerified: boolean;
37+
isPrivate: boolean;
38+
createdAt: string;
39+
updatedAt: string;
40+
isArchived: boolean;
41+
}
242

343
export class VaultController {
444
#store: Store;
5-
constructor(store: Store) {
45+
#client: GraphQLClient | null = null;
46+
#endpoint: string | null = null;
47+
#userController: UserController;
48+
49+
constructor(store: Store, userController: UserController) {
650
this.#store = store;
51+
this.#userController = userController;
52+
}
53+
54+
/**
55+
* Resolve eVault endpoint from registry
56+
*/
57+
private async resolveEndpoint(w3id: string): Promise<string> {
58+
try {
59+
const response = await axios.get(
60+
new URL(`resolve?w3id=${w3id}`, PUBLIC_REGISTRY_URL).toString()
61+
);
62+
return new URL("/graphql", response.data.uri).toString();
63+
} catch (error) {
64+
console.error("Error resolving eVault endpoint:", error);
65+
throw new Error("Failed to resolve eVault endpoint");
66+
}
67+
}
68+
69+
/**
70+
* Ensure we have a valid GraphQL client
71+
*/
72+
private async ensureClient(w3id: string): Promise<GraphQLClient> {
73+
if (!this.#endpoint || !this.#client) {
74+
this.#endpoint = await this.resolveEndpoint(w3id);
75+
this.#client = new GraphQLClient(this.#endpoint);
76+
}
77+
return this.#client;
78+
}
79+
80+
/**
81+
* Create UserProfile in eVault with retry mechanism
82+
*/
83+
private async createUserProfileInEVault(
84+
ename: string,
85+
displayName: string,
86+
w3id: string,
87+
maxRetries: number = 10
88+
): Promise<void> {
89+
console.log("attempting")
90+
const username = ename.replace('@', '');
91+
const now = new Date().toISOString();
92+
93+
const userProfile: UserProfile = {
94+
username,
95+
displayName,
96+
bio: null,
97+
avatarUrl: null,
98+
bannerUrl: null,
99+
ename,
100+
isVerified: false,
101+
isPrivate: false,
102+
createdAt: now,
103+
updatedAt: now,
104+
isArchived: false
105+
};
106+
107+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
108+
try {
109+
const client = await this.ensureClient(w3id);
110+
111+
console.log(`Attempting to create UserProfile in eVault (attempt ${attempt}/${maxRetries})`);
112+
113+
const response = await client.request<MetaEnvelopeResponse>(
114+
STORE_META_ENVELOPE,
115+
{
116+
input: {
117+
ontology: "550e8400-e29b-41d4-a716-446655440000",
118+
payload: userProfile,
119+
acl: ["*"],
120+
},
121+
}
122+
);
123+
124+
console.log("UserProfile created successfully in eVault:", response.storeMetaEnvelope.metaEnvelope.id);
125+
return;
126+
} catch (error) {
127+
console.error(`Failed to create UserProfile in eVault (attempt ${attempt}/${maxRetries}):`, error);
128+
129+
if (attempt === maxRetries) {
130+
console.error("Max retries reached, giving up on UserProfile creation");
131+
throw error;
132+
}
133+
134+
// Wait before retrying (exponential backoff)
135+
const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
136+
console.log(`Waiting ${delay}ms before retry...`);
137+
await new Promise(resolve => setTimeout(resolve, delay));
138+
}
139+
}
7140
}
8141

9142
set vault(
@@ -14,14 +147,59 @@ export class VaultController {
14147
) {
15148
if (vault instanceof Promise) {
16149
vault
17-
.then((resolvedUser) => {
18-
this.#store.set("vault", resolvedUser);
150+
.then(async (resolvedUser) => {
151+
if (resolvedUser?.ename) {
152+
this.#store.set("vault", resolvedUser);
153+
154+
// Get user data for display name
155+
const userData = await this.#userController.user;
156+
const displayName = userData?.name || resolvedUser.ename;
157+
158+
try {
159+
await this.createUserProfileInEVault(
160+
resolvedUser.ename,
161+
displayName,
162+
resolvedUser.ename
163+
);
164+
} catch (error) {
165+
console.error("Failed to create UserProfile in eVault:", error);
166+
// Don't throw here to avoid breaking the vault setting
167+
}
168+
}
19169
})
20170
.catch((error) => {
21171
console.error("Failed to set vault:", error);
22172
});
23173
} else {
24-
this.#store.set("vault", vault);
174+
if (vault?.ename) {
175+
this.#store.set("vault", vault);
176+
177+
// Get user data for display name and create UserProfile
178+
(async () => {
179+
try {
180+
const userData = await this.#userController.user;
181+
const displayName = userData?.name || vault.ename;
182+
183+
await this.createUserProfileInEVault(
184+
vault.ename,
185+
displayName,
186+
vault.ename
187+
);
188+
} catch (error) {
189+
console.error("Failed to get user data or create UserProfile:", error);
190+
// Fallback to using ename as display name
191+
try {
192+
await this.createUserProfileInEVault(
193+
vault.ename,
194+
vault.ename,
195+
vault.ename
196+
);
197+
} catch (fallbackError) {
198+
console.error("Failed to create UserProfile in eVault (fallback):", fallbackError);
199+
}
200+
}
201+
})();
202+
}
25203
}
26204
}
27205

@@ -39,4 +217,13 @@ export class VaultController {
39217
return undefined;
40218
});
41219
}
220+
221+
// Getters for internal properties
222+
get client() {
223+
return this.#client;
224+
}
225+
226+
get endpoint() {
227+
return this.#endpoint;
228+
}
42229
}

infrastructure/eid-wallet/src/lib/global/state.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export class GlobalState {
3030
this.#store = store;
3131
this.securityController = new SecurityController(store);
3232
this.userController = new UserController(store);
33-
this.vaultController = new VaultController(store);
33+
this.vaultController = new VaultController(store, this.userController);
3434
}
3535

3636
/**

platforms/blabsy-w3ds-auth-api/src/controllers/WebhookController.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export class WebhookController {
9393
adapter.addToLockedIds(id);
9494

9595
const mapping = Object.values(adapter.mapping).find(
96-
(m) => m.schemaId === schemaId
96+
(m) => m.schemaId === schemaId,
9797
);
9898
if (!mapping) throw new Error();
9999
const tableName = mapping.tableName + "s";
@@ -133,8 +133,15 @@ export class WebhookController {
133133
collection = this.db.collection(tableName);
134134
}
135135

136-
const docRef = collection.doc();
136+
let docRef = collection.doc();
137+
137138
const mappedData = await this.mapDataToFirebase(tableName, data);
139+
if (tableName === "users") {
140+
docRef = collection.doc(data.ename);
141+
} else {
142+
// Use auto-generated ID for other tables
143+
docRef = collection.doc();
144+
}
138145
await docRef.set(mappedData);
139146

140147
adapter.addToLockedIds(docRef.id);
@@ -155,7 +162,7 @@ export class WebhookController {
155162

156163
if (!docSnapshot.exists) {
157164
console.warn(
158-
`Document with ID '${localId}' does not exist in '${tableName}'. Skipping update.`
165+
`Document with ID '${localId}' does not exist in '${tableName}'. Skipping update.`,
159166
);
160167
return;
161168
}
@@ -211,7 +218,7 @@ export class WebhookController {
211218

212219
private async mapTweetData(
213220
data: any,
214-
now: Timestamp
221+
now: Timestamp,
215222
): Promise<Partial<Tweet>> {
216223
let createdBy = data.createdBy;
217224
if (createdBy.includes("(") && createdBy.includes(")")) {
@@ -264,7 +271,7 @@ export class WebhookController {
264271
name: data.name,
265272
participants:
266273
data.participants.map(
267-
(p: string) => p.split("(")[1].split(")")[0]
274+
(p: string) => p.split("(")[1].split(")")[0],
268275
) || [],
269276
createdAt: data.createdAt
270277
? Timestamp.fromDate(new Date(data.createdAt))
@@ -274,7 +281,7 @@ export class WebhookController {
274281
? {
275282
...data.lastMessage,
276283
timestamp: Timestamp.fromDate(
277-
new Date(data.lastMessage.timestamp)
284+
new Date(data.lastMessage.timestamp),
278285
),
279286
}
280287
: null,

platforms/blabsy/src/lib/context/auth-context.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export function AuthContextProvider({
5757
useEffect(() => {
5858
const manageUser = async (authUser: AuthUser): Promise<void> => {
5959
const { uid, displayName, photoURL } = authUser;
60+
console.log(uid);
6061

6162
const userSnapshot = await getDoc(doc(usersCollection, uid));
6263

@@ -88,7 +89,7 @@ export function AuthContextProvider({
8889
website: null,
8990
location: null,
9091
photoURL: photoURL ?? '/assets/twitter-avatar.jpg',
91-
username: randomUsername,
92+
username: uid.split('@')[1],
9293
verified: false,
9394
following: [],
9495
followers: [],

0 commit comments

Comments
 (0)