Skip to content

DRAFT: changes needed to get privy in react-native to work with the webapp. #12133

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 53 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
3646b39
trying to clean up auth and get it to work...
burtonator May 5, 2025
3c711f8
Merge branch 'master' into burton/privy-react-native-rpc
burtonator May 5, 2025
fa78c9d
... basic layout for the privy auth, but I need to think through some…
burtonator May 5, 2025
28d99d5
ok... it won't login yet but I think we can get the domain status...
burtonator May 5, 2025
e747d4f
... hook to sign messages now..
burtonator May 5, 2025
7c1267f
ok this should be all that we need now...
burtonator May 5, 2025
61ccc4e
...
burtonator May 5, 2025
301e289
...
burtonator May 5, 2025
b4a5bd6
record the signature now...
burtonator May 5, 2025
90c165f
more debug code...
burtonator May 5, 2025
e4c6928
...
burtonator May 6, 2025
5551f04
test of post message.
burtonator May 6, 2025
1168890
had a bug in my debug code...
burtonator May 6, 2025
bcc2de1
this shouldn't matter ...
burtonator May 6, 2025
f96cc82
ok v1 of the new sender/receiver RPC
burtonator May 6, 2025
3673584
wrong object sent.
burtonator May 6, 2025
c3a71a9
cleanup...
burtonator May 6, 2025
e97f322
implemented logout now...
burtonator May 6, 2025
5454855
request now works...
burtonator May 6, 2025
eec183d
cleanup...
burtonator May 6, 2025
034ba25
we should support mobile privy auth but I have to test first...
burtonator May 7, 2025
a9aea63
...
burtonator May 7, 2025
d86ba44
...
burtonator May 7, 2025
1ce55d6
more debug...
burtonator May 8, 2025
41b980f
null is an acceptable result..
burtonator May 8, 2025
75ff160
null is an acceptable result..
burtonator May 8, 2025
a9651d4
...
burtonator May 8, 2025
93a53a1
...
burtonator May 8, 2025
fd424a3
ok both sides of the event updater have been worked on...
burtonator May 8, 2025
2a11ca3
now we're giving it the event name...
burtonator May 8, 2025
8e40b0a
ok I think all the callbacks are in place...
burtonator May 8, 2025
56095a8
client side is done now...
burtonator May 8, 2025
aec25d3
changing this to a generic mobile debug component...
burtonator May 8, 2025
e83da9f
...
burtonator May 8, 2025
a66c20b
use request...
burtonator May 8, 2025
7691a92
request notifications.. not get..
burtonator May 8, 2025
dcb8529
ok we fixed permission prompting.
burtonator May 8, 2025
8827f40
trying to debug auth... it should work, but it's not...
burtonator May 12, 2025
41c72df
force logout on mobile...
burtonator May 12, 2025
cb777ac
trying to fix auth now...
burtonator May 12, 2025
4947d01
Fixing types...
burtonator May 12, 2025
14ac8ea
it requires one more load after signIn...
burtonator May 12, 2025
8853de6
Fixed bug with auth loop...
burtonator May 12, 2025
06c4eca
wrong logic...
burtonator May 12, 2025
1bfa206
cleanup
burtonator May 12, 2025
f3020cd
cleanup... also handle auth better.
burtonator May 13, 2025
048cb68
cleaning up this component because it was misnamed, and in the wrong …
burtonator May 13, 2025
d51bb20
...
burtonator May 13, 2025
aae3d36
new loading indicator screen...
burtonator May 13, 2025
c7ae5c4
cleanup...
burtonator May 13, 2025
6446605
perform logout if there's an error during auth...
burtonator May 14, 2025
4948109
more logging so I can debug the authentication process...
burtonator May 14, 2025
0c1cfcc
...
burtonator May 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 18 additions & 11 deletions packages/commonwealth/client/scripts/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import { ToastContainer } from 'react-toastify';
import { queryClient } from 'state/api/config';
import { DefaultPrivyProvider } from 'views/components/DefaultPrivyProvider/DefaultPrivyProvider';
import { DisableMavaOnMobile } from 'views/components/DisableMavaOnMobile';
import ForceMobileAuth from 'views/components/ForceMobileAuth';
import { PrivyMobileAuthStatusProvider } from 'views/components/PrivyMobile/PrivyMobileAuthStatusProvider';
import { PrivyMobileAuthenticator } from 'views/components/PrivyMobile/PrivyMobileAuthenticator';
import { ReactNativeBridgeUser } from 'views/components/ReactNativeBridge';
import { ReactNativeLogForwarder } from 'views/components/ReactNativeBridge/ReactNativeLogForwarder';
import { ReactNativeScrollToTopListener } from 'views/components/ReactNativeBridge/ReactNativeScrollToTopListener';
Expand All @@ -31,22 +32,28 @@ const App = () => {
<QueryClientProvider client={queryClient}>
<trpc.Provider client={trpcClient} queryClient={queryClient}>
<DisableMavaOnMobile />
<ReactNativeLogForwarder />
<FarcasterFrameProvider>
{/*@ts-expect-error StrictNullChecks*/}
<OpenFeatureProvider client={undefined}>
{isLoading ? (
<Splash />
) : (
<DefaultPrivyProvider>
<ForceMobileAuth>
<OnBoardingWrapperForMobile>
<ReactNativeBridgeUser />
<ReactNativeLogForwarder />
<ReactNativeScrollToTopListener />
<RouterProvider router={router()} />
</OnBoardingWrapperForMobile>
</ForceMobileAuth>
</DefaultPrivyProvider>
<>
<PrivyMobileAuthStatusProvider>
<PrivyMobileAuthenticator>
<DefaultPrivyProvider>
{/*<ForceMobileAuth>*/}
<OnBoardingWrapperForMobile>
<ReactNativeBridgeUser />
<ReactNativeScrollToTopListener />
<RouterProvider router={router()} />
</OnBoardingWrapperForMobile>
{/*</ForceMobileAuth>*/}
</DefaultPrivyProvider>
</PrivyMobileAuthenticator>
</PrivyMobileAuthStatusProvider>
</>
)}
<ToastContainer />
{import.meta.env.DEV && <ReactQueryDevtools />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ export class PrivyEthereumWebWalletController implements IWebWallet<string> {
public async enable(forceChainId?: string) {
// TODO: use https://docs.metamask.io/guide/rpc-api.html#other-rpc-methods to switch active
// chain according to currently active node, if one exists
console.log('Attempting to enable Metamask');
this._enabling = true;
try {
// default to ETH
Expand Down Expand Up @@ -188,6 +187,7 @@ export class PrivyEthereumWebWalletController implements IWebWallet<string> {
throw switchError;
}
}

// fetch active accounts
this._accounts = (
await this._web3.givenProvider.request({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { useCallback } from 'react';
import { useReactNativeWebView } from '../useReactNativeWebView';

type EvenSubscribeMessage = {
$id: string;
type: string;
variant: 'event-subscribe';
eventName: string;
};

type EventUpdateMessage<EventData> = {
$id: string;
type: string;
variant: 'event-update';
data: EventData;
};

export function useMobileRPCEventReceiver<EventData>(type: string) {
const reactNativeWebView = useReactNativeWebView();

return useCallback(
(eventName: string, listener: (update: EventData) => void) => {
const $id = '' + Math.random() * 100000;

const subscription: EvenSubscribeMessage = {
$id,
type: type,
eventName,
variant: 'event-subscribe',
};

if (!reactNativeWebView) {
return;
}

reactNativeWebView.postMessage(JSON.stringify(subscription));

function handler(message: MessageEvent<any>) {

Check failure on line 38 in packages/commonwealth/client/scripts/hooks/mobile/useMobileRPCEventReceiver.ts

View workflow job for this annotation

GitHub Actions / Lint (22)

Unexpected any. Specify a different type
const eventUpdateMessage = toEventUpdateMessage<EventData>(
type,
message.data,
);

if (eventUpdateMessage?.$id === $id) {
console.log('Got event update: ', eventUpdateMessage);
listener(eventUpdateMessage.data);
}
}

window.addEventListener('message', handler);
},
[reactNativeWebView, type],
);
}

function toEventUpdateMessage<EventData>(
type: string,
data: any,

Check failure on line 58 in packages/commonwealth/client/scripts/hooks/mobile/useMobileRPCEventReceiver.ts

View workflow job for this annotation

GitHub Actions / Lint (22)

Unexpected any. Specify a different type
): EventUpdateMessage<EventData> | null {
const obj = messageToObject(data);

if (obj && obj.type === type && obj.variant === 'event-update') {
return obj;
}

return null;
}

function messageToObject(message: string | any): any | null {

Check failure on line 69 in packages/commonwealth/client/scripts/hooks/mobile/useMobileRPCEventReceiver.ts

View workflow job for this annotation

GitHub Actions / Lint (22)

Unexpected any. Specify a different type

Check failure on line 69 in packages/commonwealth/client/scripts/hooks/mobile/useMobileRPCEventReceiver.ts

View workflow job for this annotation

GitHub Actions / Lint (22)

Unexpected any. Specify a different type
if (message === 'string') {
try {
return JSON.parse(message);
} catch (e) {
// this might be just a string sent with sendMessage
return null;
}
}

return typeof message === 'string' ? JSON.parse(message) : message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { useCallback } from 'react';

type ProtoError = {
message: string;
};

type ProtoRequestObject<Request> = {
$id: string;
type: string;
variant: 'request';
data: Request;
};

type ProtoResponseObjectSuccess<Response> = {
$id: string;
type: string;
variant: 'response';
data: Response;
error: null;
};

/**
* Wraps a response so that it includes the error OR data.
*/
type ProtoResponseObjectFailure = {
$id: string;
type: string;
variant: 'response';
data: null;
error: ProtoError;
};

type ProtoResponseObject<Response> =
| ProtoResponseObjectSuccess<Response>
| ProtoResponseObjectFailure;

type Opts = {
type: string;
};

export function useMobileRPCSender<Request, Response>(opts: Opts) {
return useCallback(
async (request: Request) => {
return new Promise<Response>((resolve, reject) => {
const $id = '' + Math.random() * 100000;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function handler(message: MessageEvent<any>) {
const protoResponse = toProtoResponse<Response>(
opts.type,
message.data,
);

if (protoResponse?.$id === $id) {
console.log('Got proto response: ', protoResponse);

if (protoResponse.error) {
reject(protoResponse.error);
} else {
resolve(protoResponse.data);
}
}
}

window.addEventListener('message', handler);

const protoRequest: ProtoRequestObject<Request> = {
$id,
type: opts.type,
variant: 'request',
data: request,
};

window.ReactNativeWebView!.postMessage(JSON.stringify(protoRequest));
});
},
[opts.type],
);
}

function toProtoResponse<Response>(
type: string,
data: any,

Check failure on line 83 in packages/commonwealth/client/scripts/hooks/mobile/useMobileRPCSender.ts

View workflow job for this annotation

GitHub Actions / Lint (22)

Unexpected any. Specify a different type
): ProtoResponseObject<Response> | null {
const obj = messageToObject(data);

if (obj && obj.type === type && obj.variant === 'response') {
return obj;
}

return null;
}

function messageToObject(message: string | any): any | null {

Check failure on line 94 in packages/commonwealth/client/scripts/hooks/mobile/useMobileRPCSender.ts

View workflow job for this annotation

GitHub Actions / Lint (22)

Unexpected any. Specify a different type

Check failure on line 94 in packages/commonwealth/client/scripts/hooks/mobile/useMobileRPCSender.ts

View workflow job for this annotation

GitHub Actions / Lint (22)

Unexpected any. Specify a different type
if (message === 'string') {
try {
return JSON.parse(message);
} catch (e) {
// this might be just a string sent with sendMessage
return null;
}
}

return typeof message === 'string' ? JSON.parse(message) : message;
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,26 @@

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function handler(message: MessageEvent<any>) {
console.log('FIXME execWithinMobileApp handler received message!');
const dataObj = messageToObject(message.data);

// FIXME: it's possible messageToObject could be throwing an error?

Check failure on line 78 in packages/commonwealth/client/scripts/hooks/useReactNativeWebView.ts

View workflow job for this annotation

GitHub Actions / Lint (22)

Unexpected 'FIXME' comment: 'FIXME: it's possible messageToObject...'

console.log(
'FIXME execWithinMobileApp: got message: ',
JSON.stringify(dataObj, null, 2),
);

if (dataObj.__requestID === __requestID) {
latch.resolve(dataObj as Output);
}
}

addEventListener('message', handler);
console.log(
'FIXME execWithinMobileApp adding event listener to listen for response message',
);

window.addEventListener('message', handler);

window.ReactNativeWebView!.postMessage(
JSON.stringify({
Expand All @@ -88,13 +100,17 @@
}),
);

console.log('FIXME execWithinMobileApp waiting fr resolution ');

// the event listener we just registered will keep listening until the
// latch is revolved and gets the response.
await latch.promise;
const output = await latch.promise;

console.log('FIXME execWithinMobileApp RESOLVED!!! ');

// now we have to remove the event listener before we return the latch and
// clean up after ourselves.
removeEventListener('message', handler);
window.removeEventListener('message', handler);

return latch.promise;
return output;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Navigate } from 'navigation/helpers';
import React, { lazy } from 'react';
import { Route } from 'react-router-dom';
import { DebugMobile } from 'views/components/DebugMobile/DebugMobile';
import { SignIn } from 'views/components/SignIn/SignIn';
import { withLayout } from 'views/Layout';
import { MobileSignIn } from 'views/modals/MobileSignIn/MobileSignIn';
Expand Down Expand Up @@ -145,6 +146,12 @@ const newProposalViewPage = lazy(
);

const CommonDomainRoutes = () => [
<Route
key="mobile-app-redirect"
path="/_internal/debug-mobile"
element={<DebugMobile />}
/>,

<Route
key="mobile-app-redirect"
path="/_internal/mobile-app-redirect"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ export interface PermissionResponse {
status: PermissionStatus;
}

/**
* @deprecated Not used any longer. We should remove.
*/
export class MobileNotifications {
/**
* @deprecated
*/
public static async getPermissionsAsync(): Promise<PermissionResponse> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const response = await execWithinMobileApp<any, any>({
Expand All @@ -44,6 +50,9 @@ export class MobileNotifications {
};
}

/**
* @deprecated
*/
public static async requestPermissionsAsync(): Promise<PermissionResponse> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const response = await execWithinMobileApp<any, any>({
Expand Down
Loading
Loading