@@ -2,127 +2,221 @@ import {ReactUnityEventParameter} from "react-unity-webgl/distribution/types/rea
22import { Unity , useUnityContext } from "react-unity-webgl" ;
33import { useCallback , useEffect , useState } from "react" ;
44import {
5- GoogleOAuthProvider ,
6- GoogleLogin ,
7- CredentialResponse ,
5+ GoogleOAuthProvider ,
6+ GoogleLogin ,
7+ CredentialResponse ,
88} from "@react-oauth/google" ;
99
1010import "./App.css" ;
1111
12- function App ( ) {
13- const {
14- unityProvider,
15- addEventListener,
16- removeEventListener,
17- sendMessage,
18- isLoaded,
19- loadingProgression,
20- } = useUnityContext ( {
21- loaderUrl : "Build/<ReplaceWithDirectoryName>.loader.js" ,
22- dataUrl : "Build/<ReplaceWithDirectoryName>.data" ,
23- frameworkUrl : "Build/<ReplaceWithDirectoryName>.framework.js" ,
24- codeUrl : "Build/<ReplaceWithDirectoryName>.wasm" ,
25- } ) ;
12+ let walletWindow : Window | null = null ;
13+ let authInput : AuthInput | null = null ;
14+
15+ interface AuthInput {
16+ url : string ;
17+ action : string ;
18+ payload : string ;
19+ }
20+
21+ function App ( ) {
22+ const {
23+ unityProvider,
24+ addEventListener,
25+ removeEventListener,
26+ sendMessage,
27+ isLoaded,
28+ loadingProgression,
29+ } = useUnityContext ( {
30+ loaderUrl : "Build/webgl.loader.js" ,
31+ dataUrl : "Build/webgl.data.unityweb" ,
32+ frameworkUrl : "Build/webgl.framework.js.unityweb" ,
33+ codeUrl : "Build/webgl.wasm.unityweb" ,
34+ } ) ;
2635
2736 const loadingPercentage = Math . round ( loadingProgression * 100 ) ;
2837
29- const handleGoogleSignIn = useCallback ( ( ...parameters : ReactUnityEventParameter [ ] ) : ReactUnityEventParameter => {
30- const googleClientId = parameters [ 0 ] as string ;
31- const nonce = parameters [ 1 ] as string ;
32- setGoogleClientId ( googleClientId ) ;
33- setNonce ( nonce ) ;
34- setShowLogin ( true ) ;
35- return '' ;
36- } , [ ] ) ;
38+ const handleSequenceWalletAuth = useCallback ( ( ...parameters : ReactUnityEventParameter [ ] ) : ReactUnityEventParameter => {
39+ const inputJson = parameters [ 0 ] as string ;
40+ authInput = JSON . parse ( inputJson ) as AuthInput ;
3741
38- const [ googleClientIdState , setGoogleClientId ] = useState ( "" ) ;
39- const [ nonce , setNonce ] = useState ( "" ) ;
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' ) ;
4047
41- const [ messageToSend , setMessageToSend ] = useState <
42- | {
43- functionName : string ;
44- value : string ;
45- }
46- | undefined
47- > ( ) ;
48+ return '' ;
49+ } , [ ] ) ;
50+
51+ const [ messageToSend , setMessageToSend ] = useState < { functionName : string ; value : string ; } | undefined > ( undefined ) ;
4852
4953 useEffect ( ( ) => {
5054 if ( messageToSend ) {
5155 const message = messageToSend ;
5256 setMessageToSend ( undefined ) ;
53- sendMessage ( "WebBrowserMessageReceiver " , message . functionName , message . value ) ;
57+ sendMessage ( "SequenceNativeReceiver " , message . functionName , message . value ) ;
5458 }
5559 } , [ messageToSend ] ) ;
5660
5761 useEffect ( ( ) => {
5862 addEventListener ( "GoogleSignIn" , handleGoogleSignIn ) ;
63+ addEventListener ( "OpenWalletApp" , handleSequenceWalletAuth ) ;
64+ window . addEventListener ( "message" , handleMessage ) ;
5965 window . addEventListener ( "resize" , handleResize ) ;
6066 handleResize ( )
6167 return ( ) => {
6268 removeEventListener ( "GoogleSignIn" , handleGoogleSignIn ) ;
69+ removeEventListener ( "OpenWalletApp" , handleSequenceWalletAuth ) ;
70+ window . removeEventListener ( "message" , handleMessage ) ;
6371 window . removeEventListener ( "resize" , handleResize ) ;
6472 } ;
6573 } , [ ] ) ;
6674
67- const [ showLogin , setShowLogin ] = useState ( false ) ;
75+ const handleGoogleSignIn = useCallback ( ( ...parameters : ReactUnityEventParameter [ ] ) : ReactUnityEventParameter => {
76+ const googleClientId = parameters [ 0 ] as string ;
77+ const nonce = parameters [ 1 ] as string ;
78+ setGoogleClientId ( googleClientId ) ;
79+ setNonce ( nonce ) ;
80+ setShowLogin ( true ) ;
81+ return '' ;
82+ } , [ ] ) ;
6883
69- const handleGoogleLogin = async ( tokenResponse : CredentialResponse ) => {
70- setMessageToSend ( {
71- functionName : "OnGoogleSignIn" ,
72- value : tokenResponse . credential ! ,
73- } ) ;
84+ const handleGoogleLogin = async ( tokenResponse : CredentialResponse ) => {
85+ setMessageToSend ( {
86+ functionName : "OnGoogleSignIn" ,
87+ value : tokenResponse . credential ! ,
88+ } ) ;
7489
75- setShowLogin ( false ) ;
76- } ;
90+ setShowLogin ( false ) ;
91+ } ;
7792
78- const handleResize = ( ) => {
79- const container = document . querySelector ( '.container' ) as any ;
93+ const [ googleClientIdState , setGoogleClientId ] = useState ( "" ) ;
94+ const [ nonce , setNonce ] = useState ( "" ) ;
95+ const [ showLogin , setShowLogin ] = useState ( false ) ;
8096
81- let w = window . innerWidth * 0.98 ;
82- let h = window . innerHeight * 0.98 ;
97+ const handleMessage = async ( event : MessageEvent ) => {
98+ if ( ! walletWindow ) {
99+ return ;
100+ }
83101
84- const r = 600 / 960 ;
85- if ( w * r > window . innerHeight ) {
86- w = Math . min ( w , Math . ceil ( h / r ) ) ;
102+ switch ( event . data . type ) {
103+ case "WALLET_OPENED" :
104+ postMessageToWallet ( {
105+ id : generateId ( ) ,
106+ type : 'INIT' ,
107+ sessionId : 'mcyc0abl-8q11zpb' ,
108+ } ) ;
109+
110+ console . log ( authInput )
111+ postMessageToWallet ( {
112+ id : generateId ( ) ,
113+ type : 'REQUEST' ,
114+ action : authInput ?. action ,
115+ payload : authInput ?. payload
116+ } ) ;
117+
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 ;
130+ }
131+ } ) ;
132+
133+ data = { ...data , payload : btoa ( parsedPayload ) } ;
134+ }
135+
136+ console . log ( data ) ;
137+
138+ setMessageToSend ( {
139+ functionName : "HandleResponse" ,
140+ value : JSON . stringify ( data )
141+ } ) ;
142+
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" ) ;
87158 }
88159
89- h = Math . floor ( w * r ) ;
160+ const walletOrigin = new URL ( authInput ?. url || '' ) . origin ;
161+ walletWindow . postMessage ( message , walletOrigin ) ;
162+ } catch ( e ) {
163+ console . error ( e ) ;
164+ }
165+ }
166+
167+ const handleResize = ( ) => {
168+ const container = document . querySelector ( '.container' ) as any ;
169+
170+ let w = window . innerWidth * 0.98 ;
171+ let h = window . innerHeight * 0.98 ;
90172
91- container . style . width = w + "px" ;
92- container . style . height = h + "px" ;
173+ const r = 600 / 960 ;
174+ if ( w * r > window . innerHeight ) {
175+ w = Math . min ( w , Math . ceil ( h / r ) ) ;
93176 }
94177
95- return (
96- < div className = "outer-container" >
97- < div className = "container" >
98- { isLoaded === false && (
99- < div className = "loading-overlay" >
100- < p > Loading... ({ loadingPercentage } %)</ p >
101- </ div >
102- ) }
103- < Unity className = "unity" unityProvider = { unityProvider } />
104- </ div >
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+ }
105189
106- { showLogin && (
107- < div className = "login-outer-container" >
108- < div className = "login-container" >
109- < h2 className = "login-title" > Login with Google</ h2 >
110- < div >
111- < GoogleOAuthProvider clientId = { googleClientIdState } >
112- < GoogleLogin
113- onSuccess = { ( response ) => {
114- handleGoogleLogin ( response ) ;
115- } }
116- shape = "circle"
117- width = { 230 }
118- nonce = { nonce }
119- />
120- </ GoogleOAuthProvider >
121- </ div >
122- </ div >
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 } />
123199 </ div >
124- ) }
125- </ 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 >
126220 ) ;
127221}
128222
0 commit comments