Skip to content

Commit

Permalink
[native/web] make findUserIdentities RPC available to native and web
Browse files Browse the repository at this point in the history
Summary:
Implements `FindUserIdentities` RPC for web and native

Depends on D11999

Test Plan:
On both web/native successfully called the `FindUserIdentities` rpc on
1. ethereum user
2. username user
3. user with farcaster id
4. non-existent user (resulting in no entry in the identities result)

Reviewers: kamil, bartek

Reviewed By: bartek

Subscribers: inka, ashoat, tomek

Differential Revision: https://phab.comm.dev/D12000
  • Loading branch information
wyilio committed May 16, 2024
1 parent fdf6492 commit fb67cd1
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 0 deletions.
32 changes: 32 additions & 0 deletions lib/types/identity-service-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ export interface IdentityServiceClient {
) => Promise<$ReadOnlyArray<FarcasterUser>>;
+linkFarcasterAccount: (farcasterID: string) => Promise<void>;
+unlinkFarcasterAccount: () => Promise<void>;
+findUserIdentities: (userIDs: $ReadOnlyArray<string>) => Promise<Identities>;
}

export type IdentityServiceAuthLayer = {
Expand Down Expand Up @@ -230,6 +231,37 @@ export type UsersRawDeviceLists = {
+[userID: string]: RawDeviceList,
};

// User Identity types

export type EthereumIdentity = {
walletAddress: string,
siweMessage: string,
siweSignature: string,
};
export type Identity = {
+username: string,
+ethIdentity: ?EthereumIdentity,
+farcasterID: ?string,
};
export type Identities = {
+[userID: string]: Identity,
};
export const ethereumIdentityValidator: TInterface<EthereumIdentity> =
tShape<EthereumIdentity>({
walletAddress: t.String,
siweMessage: t.String,
siweSignature: t.String,
});
export const identityValidator: TInterface<Identity> = tShape<Identity>({
username: t.String,
ethIdentity: t.maybe(ethereumIdentityValidator),
farcasterID: t.maybe(t.String),
});
export const identitiesValidator: TDict<Identities> = t.dict(
t.String,
identityValidator,
);

export type SignedDeviceList = {
// JSON-stringified RawDeviceList
+rawDeviceList: string,
Expand Down
16 changes: 16 additions & 0 deletions native/identity-service/identity-service-context-provider.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
type UserDevicesOlmOutboundKeys,
type UsersSignedDeviceLists,
usersSignedDeviceListsValidator,
identitiesValidator,
} from 'lib/types/identity-service-types.js';
import { getContentSigningKey } from 'lib/utils/crypto-utils.js';
import { assertWithValidator } from 'lib/utils/validation-utils.js';
Expand Down Expand Up @@ -615,6 +616,21 @@ function IdentityServiceContextProvider(props: Props): React.Node {
} = await getAuthMetadata();
return commRustModule.unlinkFarcasterAccount(userID, deviceID, token);
},
findUserIdentities: async (userIDs: $ReadOnlyArray<string>) => {
const {
deviceID,
userID,
accessToken: token,
} = await getAuthMetadata();
const result = await commRustModule.findUserIdentities(
userID,
deviceID,
token,
userIDs,
);
const identities = JSON.parse(result);
return assertWithValidator(identities, identitiesValidator);
},
}),
[getAuthMetadata],
);
Expand Down
28 changes: 28 additions & 0 deletions web/grpc/identity-service-client-wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import {
farcasterUsersValidator,
type UsersSignedDeviceLists,
usersSignedDeviceListsValidator,
type Identities,
identitiesValidator,
} from 'lib/types/identity-service-types.js';
import { getMessageForException } from 'lib/utils/errors.js';
import { assertWithValidator } from 'lib/utils/validation-utils.js';
Expand Down Expand Up @@ -615,6 +617,32 @@ class IdentityServiceClientWrapper implements IdentityServiceClient {
}
await client.unlinkFarcasterAccount(new Empty());
};

findUserIdentities: (userIDs: $ReadOnlyArray<string>) => Promise<Identities> =
async userIDs => {
const client = this.authClient;
if (!client) {
throw new Error('Identity service client is not initialized');
}
const request = new IdentityAuthStructs.UserIdentitiesRequest();
request.setUserIdsList([...userIDs]);
const response = await client.findUserIdentities(request);
const identityObjects = response.toObject()?.identitiesMap;

let identities: Identities = {};
identityObjects.forEach(([userID, identityObject]) => {
identities = {
...identities,
[userID]: {
ethIdentity: identityObject.ethIdentity,
username: identityObject.username,
farcasterID: identityObject.farcasterId,
},
};
});

return assertWithValidator(identities, identitiesValidator);
};
}

function authNewDeviceKeyUpload(
Expand Down
1 change: 1 addition & 0 deletions web/grpc/identity-service-context-provider.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ function IdentityServiceContextProvider(props: Props): React.Node {
getFarcasterUsers: proxyMethodToWorker('getFarcasterUsers'),
linkFarcasterAccount: proxyMethodToWorker('linkFarcasterAccount'),
unlinkFarcasterAccount: proxyMethodToWorker('unlinkFarcasterAccount'),
findUserIdentities: proxyMethodToWorker('findUserIdentities'),
};
}, [proxyMethodToWorker]);

Expand Down

0 comments on commit fb67cd1

Please sign in to comment.