Skip to content

Commit 0a400a7

Browse files
authored
Merge pull request #346 from 0xsequence/Fix/webgl-google-login
Fixed "SequenceNativeReceiver object missing"
2 parents 2db07ce + c8aa2fb commit 0a400a7

File tree

3 files changed

+171
-167
lines changed

3 files changed

+171
-167
lines changed

Assets/WebGLTemplates/SequenceReact/src/App.tsx

Lines changed: 166 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -13,64 +13,64 @@ let walletWindow: Window | null = null;
1313
let authInput: AuthInput | null = null;
1414

1515
interface AuthInput {
16-
url: string;
17-
action: string;
18-
payload: string;
16+
url: string;
17+
action: string;
18+
payload: string;
1919
}
2020

2121
function App() {
22-
const {
23-
unityProvider,
24-
addEventListener,
25-
removeEventListener,
26-
sendMessage,
27-
isLoaded,
28-
loadingProgression,
29-
} = useUnityContext({
30-
loaderUrl: "Build/<ReplaceWithDirectoryName>.loader.js",
31-
dataUrl: "Build/<ReplaceWithDirectoryName>.data",
32-
frameworkUrl: "Build/<ReplaceWithDirectoryName>.framework.js",
33-
codeUrl: "Build/<ReplaceWithDirectoryName>.wasm",
34-
});
35-
36-
const loadingPercentage = Math.round(loadingProgression * 100);
37-
38-
const handleSequenceWalletAuth = useCallback((...parameters: ReactUnityEventParameter[]): ReactUnityEventParameter => {
39-
const inputJson = parameters[0] as string;
40-
authInput = JSON.parse(inputJson) as AuthInput;
41-
42-
const sessionId = generateId();
43-
walletWindow = window.open(
44-
`${authInput?.url}?dappOrigin=${window.location.origin}&sessionId=${sessionId}`,
45-
"Wallet",
46-
'width=600,height=600,left=300,top=300');
47-
48-
return '';
49-
}, []);
50-
51-
const [messageToSend, setMessageToSend] = useState<{ functionName: string; value: string; } | undefined>(undefined);
52-
53-
useEffect(() => {
54-
if (messageToSend) {
55-
const message = messageToSend;
56-
setMessageToSend(undefined);
57-
sendMessage("SequenceNativeReceiver", message.functionName, message.value);
58-
}
59-
}, [messageToSend]);
60-
61-
useEffect(() => {
62-
addEventListener("GoogleSignIn", handleGoogleSignIn);
63-
addEventListener("OpenWalletApp", handleSequenceWalletAuth);
64-
window.addEventListener("message", handleMessage);
65-
window.addEventListener("resize", handleResize);
66-
handleResize()
67-
return () => {
68-
removeEventListener("GoogleSignIn", handleGoogleSignIn);
69-
removeEventListener("OpenWalletApp", handleSequenceWalletAuth);
70-
window.removeEventListener("message", handleMessage);
71-
window.removeEventListener("resize", handleResize);
72-
};
73-
}, []);
22+
const {
23+
unityProvider,
24+
addEventListener,
25+
removeEventListener,
26+
sendMessage,
27+
isLoaded,
28+
loadingProgression,
29+
} = useUnityContext({
30+
loaderUrl: "Build/<ReplaceWithDirectoryName>.loader.js",
31+
dataUrl: "Build/<ReplaceWithDirectoryName>.data",
32+
frameworkUrl: "Build/<ReplaceWithDirectoryName>.framework.js",
33+
codeUrl: "Build/<ReplaceWithDirectoryName>.wasm",
34+
});
35+
36+
const loadingPercentage = Math.round(loadingProgression * 100);
37+
38+
const handleSequenceWalletAuth = useCallback((...parameters: ReactUnityEventParameter[]): ReactUnityEventParameter => {
39+
const inputJson = parameters[0] as string;
40+
authInput = JSON.parse(inputJson) as AuthInput;
41+
42+
const sessionId = generateId();
43+
walletWindow = window.open(
44+
`${authInput?.url}?dappOrigin=${window.location.origin}&sessionId=${sessionId}`,
45+
"Wallet",
46+
'width=600,height=600,left=300,top=300');
47+
48+
return '';
49+
}, []);
50+
51+
const [messageToSend, setMessageToSend] = useState<{ gameObject: string; functionName: string; value: string; } | undefined>(undefined);
52+
53+
useEffect(() => {
54+
if (messageToSend) {
55+
const message = messageToSend;
56+
setMessageToSend(undefined);
57+
sendMessage(message.gameObject, message.functionName, message.value);
58+
}
59+
}, [messageToSend]);
60+
61+
useEffect(() => {
62+
addEventListener("GoogleSignIn", handleGoogleSignIn);
63+
addEventListener("OpenWalletApp", handleSequenceWalletAuth);
64+
window.addEventListener("message", handleMessage);
65+
window.addEventListener("resize", handleResize);
66+
handleResize()
67+
return () => {
68+
removeEventListener("GoogleSignIn", handleGoogleSignIn);
69+
removeEventListener("OpenWalletApp", handleSequenceWalletAuth);
70+
window.removeEventListener("message", handleMessage);
71+
window.removeEventListener("resize", handleResize);
72+
};
73+
}, []);
7474

7575
const handleGoogleSignIn = useCallback((...parameters: ReactUnityEventParameter[]): ReactUnityEventParameter => {
7676
const googleClientId = parameters[0] as string;
@@ -83,6 +83,7 @@ function App() {
8383

8484
const handleGoogleLogin = async (tokenResponse: CredentialResponse) => {
8585
setMessageToSend({
86+
gameObject: "WebBrowserMessageReceiver",
8687
functionName: "OnGoogleSignIn",
8788
value: tokenResponse.credential!,
8889
});
@@ -94,130 +95,131 @@ function App() {
9495
const [nonce, setNonce] = useState("");
9596
const [showLogin, setShowLogin] = useState(false);
9697

97-
const handleMessage = async (event: MessageEvent) => {
98-
if (!walletWindow) {
99-
return;
100-
}
98+
const handleMessage = async (event: MessageEvent) => {
99+
if (!walletWindow) {
100+
return;
101+
}
101102

102-
switch (event.data.type) {
103-
case "WALLET_OPENED":
104-
postMessageToWallet({
105-
id: generateId(),
106-
type: 'INIT',
107-
sessionId: 'mcyc0abl-8q11zpb',
108-
});
103+
switch (event.data.type) {
104+
case "WALLET_OPENED":
105+
postMessageToWallet({
106+
id: generateId(),
107+
type: 'INIT',
108+
sessionId: 'mcyc0abl-8q11zpb',
109+
});
110+
111+
console.log(authInput)
112+
postMessageToWallet({
113+
id: generateId(),
114+
type: 'REQUEST',
115+
action: authInput?.action,
116+
payload: authInput?.payload
117+
});
118+
119+
console.log('sent init message')
120+
break;
121+
case "RESPONSE":
122+
let data = event.data;
123+
if (data.payload) {
124+
const parsedPayload = JSON.stringify(data.payload, (_, v) => {
125+
if (typeof v === 'bigint') {
126+
return {_isBigInt: true, data: v.toString()};
127+
} else if (v instanceof Uint8Array) {
128+
return {_isUint8Array: true, data: bytesToHex(v)};
129+
} else {
130+
return v;
131+
}
132+
});
133+
134+
data = {...data, payload: btoa(parsedPayload)};
135+
}
136+
137+
console.log(data);
138+
139+
setMessageToSend({
140+
gameObject: "SequenceNativeReceiver",
141+
functionName: "HandleResponse",
142+
value: JSON.stringify(data)
143+
});
144+
145+
walletWindow.close();
146+
break;
147+
}
148+
}
109149

110-
console.log(authInput)
111-
postMessageToWallet({
112-
id: generateId(),
113-
type: 'REQUEST',
114-
action: authInput?.action,
115-
payload: authInput?.payload
116-
});
150+
function bytesToHex(bytes: Uint8Array): string {
151+
return '0x' + Array.from(bytes)
152+
.map(b => b.toString(16).padStart(2, "0"))
153+
.join("");
154+
}
117155

118-
console.log('sent init message')
119-
break;
120-
case "RESPONSE":
121-
let data = event.data;
122-
if (data.payload) {
123-
const parsedPayload = JSON.stringify(data.payload, (_, v) => {
124-
if (typeof v === 'bigint') {
125-
return {_isBigInt: true, data: v.toString()};
126-
} else if (v instanceof Uint8Array) {
127-
return {_isUint8Array: true, data: bytesToHex(v)};
128-
} else {
129-
return v;
156+
const postMessageToWallet = (message: any) => {
157+
try {
158+
if (!walletWindow) {
159+
throw new Error("Unable to find wallet");
130160
}
131-
});
132161

133-
data = {...data, payload: btoa(parsedPayload)};
162+
const walletOrigin = new URL(authInput?.url || '').origin;
163+
walletWindow.postMessage(message, walletOrigin);
164+
} catch (e) {
165+
console.error(e);
134166
}
167+
}
135168

136-
console.log(data);
169+
const handleResize = () => {
170+
const container = document.querySelector('.container') as any;
137171

138-
setMessageToSend({
139-
functionName: "HandleResponse",
140-
value: JSON.stringify(data)
141-
});
172+
let w = window.innerWidth * 0.98;
173+
let h = window.innerHeight * 0.98;
142174

143-
walletWindow.close();
144-
break;
145-
}
146-
}
147-
148-
function bytesToHex(bytes: Uint8Array): string {
149-
return '0x' + Array.from(bytes)
150-
.map(b => b.toString(16).padStart(2, "0"))
151-
.join("");
152-
}
153-
154-
const postMessageToWallet = (message: any) => {
155-
try {
156-
if (!walletWindow) {
157-
throw new Error("Unable to find wallet");
158-
}
159-
160-
const walletOrigin = new URL(authInput?.url || '').origin;
161-
walletWindow.postMessage(message, walletOrigin);
162-
} catch (e) {
163-
console.error(e);
164-
}
165-
}
175+
const r = 600 / 960;
176+
if (w * r > window.innerHeight) {
177+
w = Math.min(w, Math.ceil(h / r));
178+
}
166179

167-
const handleResize = () => {
168-
const container = document.querySelector('.container') as any;
180+
h = Math.floor(w * r);
169181

170-
let w = window.innerWidth * 0.98;
171-
let h = window.innerHeight * 0.98;
182+
container.style.width = w + "px";
183+
container.style.height = h + "px";
184+
}
172185

173-
const r = 600 / 960;
174-
if (w * r > window.innerHeight) {
175-
w = Math.min(w, Math.ceil(h / r));
186+
const generateId = (): string => {
187+
return `${Date.now().toString(36)}-${Math.random()
188+
.toString(36)
189+
.substring(2, 9)}`;
176190
}
177191

178-
h = Math.floor(w * r);
179-
180-
container.style.width = w + "px";
181-
container.style.height = h + "px";
182-
}
183-
184-
const generateId = (): string => {
185-
return `${Date.now().toString(36)}-${Math.random()
186-
.toString(36)
187-
.substring(2, 9)}`;
188-
}
189-
190-
return (
191-
<div className="outer-container">
192-
<div className="container">
193-
{isLoaded === false && (
194-
<div className="loading-overlay">
195-
<p>Loading... ({loadingPercentage}%)</p>
196-
</div>
197-
)}
198-
<Unity className="unity" unityProvider={unityProvider} />
192+
return (
193+
<div className="outer-container">
194+
<div className="container">
195+
{isLoaded === false && (
196+
<div className="loading-overlay">
197+
<p>Loading... ({loadingPercentage}%)</p>
198+
</div>
199+
)}
200+
<Unity className="unity" unityProvider={unityProvider} />
201+
</div>
202+
{showLogin && (
203+
<div className="login-outer-container">
204+
<div className="login-container">
205+
<h2 className="login-title">Login with Google</h2>
206+
<div>
207+
<GoogleOAuthProvider clientId={googleClientIdState}>
208+
<GoogleLogin
209+
onSuccess={(response) => {
210+
handleGoogleLogin(response);
211+
}}
212+
shape="circle"
213+
width={230}
214+
nonce={nonce}
215+
/>
216+
</GoogleOAuthProvider>
217+
</div>
218+
</div>
219+
</div>
220+
)}
199221
</div>
200-
{showLogin && (
201-
<div className="login-outer-container">
202-
<div className="login-container">
203-
<h2 className="login-title">Login with Google</h2>
204-
<div>
205-
<GoogleOAuthProvider clientId={googleClientIdState}>
206-
<GoogleLogin
207-
onSuccess={(response) => {
208-
handleGoogleLogin(response);
209-
}}
210-
shape="circle"
211-
width={230}
212-
nonce={nonce}
213-
/>
214-
</GoogleOAuthProvider>
215-
</div>
216-
</div>
217-
</div>
218-
)}
219-
</div>
220-
);
222+
);
221223
}
222224

223225
export default App;

0 commit comments

Comments
 (0)