zh-web-sdk 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +84 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
- package/src/onboarding/OnboardingApp.tsx +3 -2
package/README.md
CHANGED
|
@@ -34,3 +34,87 @@ The pipeline automatically updates the version in package.json after merge to ma
|
|
|
34
34
|
- `BREAKING CHANGE` is a major release (`1.0.0` to `2.0.0`)
|
|
35
35
|
- `feat` is a minor release (`1.0.0` to `1.1.0`)
|
|
36
36
|
- default is a patch release (`1.0.0` to `1.0.1`)
|
|
37
|
+
|
|
38
|
+
## Mobile usage
|
|
39
|
+
In order to use our SDK on Mobile Apps you should follow the guide below. You won't need to install or have `zh-web-sdk` as a dependency in your project to use it for Mobile Apps.
|
|
40
|
+
|
|
41
|
+
### React native guide
|
|
42
|
+
|
|
43
|
+
#### Events
|
|
44
|
+
We forward events that come from the UI to the Native App using the `postMessage` API. You can handle these events using `onMessage` from the `WebView` component. Currently these are the events we have:
|
|
45
|
+
- **ONBOARDING_APP_LOADED:** Sent when the App is loaded
|
|
46
|
+
- **ONBOARDING_CLOSE_BUTTON_CLICKED:** Sent when the user clicks the Close button on the top-right corner
|
|
47
|
+
|
|
48
|
+
#### Messages
|
|
49
|
+
To control the `WebView` you can also send messages *down*, using the `postMessage` API. Currently the accepted messages are:
|
|
50
|
+
- `{type: "OPEN_ONBOARDING_MODAL", payload:{userOnboardingJWT: "<JWT_HERE>"} }`: It will open the onboarding modal with the JWT provided
|
|
51
|
+
- `{type: "CLOSE_ONBOARDING_MODAL"}`: It will close the onboarding modal
|
|
52
|
+
|
|
53
|
+
The example below shows how you can implement the mentioned methods in a `react-native` project
|
|
54
|
+
|
|
55
|
+
```jsx
|
|
56
|
+
const App = () => {
|
|
57
|
+
const webViewRef = useRef<WebView>(null)
|
|
58
|
+
const jwt = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c`
|
|
59
|
+
/*
|
|
60
|
+
Receive messages from sdk-mobile. Currently we expose the following event types:
|
|
61
|
+
"ONBOARDING_APP_LOADED" and "ONBOARDING_CLOSE_BUTTON_CLICKED"
|
|
62
|
+
you should be able to take action based on these events.
|
|
63
|
+
*/
|
|
64
|
+
const handleMessage = (event: WebViewMessageEvent) => {
|
|
65
|
+
try {
|
|
66
|
+
const parsedMessage = JSON.parse(event.nativeEvent.data)
|
|
67
|
+
if (parsedMessage.type === "ONBOARDING_APP_LOADED") {
|
|
68
|
+
// setOnboardingAppLoaded(true)
|
|
69
|
+
}
|
|
70
|
+
if (
|
|
71
|
+
parsedMessage.type === "ONBOARDING_CLOSE_BUTTON_CLICKED"
|
|
72
|
+
) {
|
|
73
|
+
setIsWebViewOpen(false)
|
|
74
|
+
}
|
|
75
|
+
} catch (e) {
|
|
76
|
+
alert(
|
|
77
|
+
`could not parse message: ${JSON.stringify(event.nativeEvent.data)}`,
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/* You can also send messages to sdk-mobile, currently we accept the following messages:
|
|
82
|
+
* "OPEN_ONBOARDING_MODAL" and "CLOSE_ONBOARDING_MODAL"
|
|
83
|
+
* Note that the "true;" after the postMessage is required
|
|
84
|
+
* and recommended by the official react-native-webview docs
|
|
85
|
+
* https://github.com/react-native-webview/react-native-webview/blob/master/docs/Guide.md#the-injectedjavascript-prop
|
|
86
|
+
*/
|
|
87
|
+
const openModalType = `{
|
|
88
|
+
type: 'OPEN_ONBOARDING_MODAL',
|
|
89
|
+
payload: { userOnboardingJWT: '${jwt}' } }`
|
|
90
|
+
const openOnboardingModal = () => {
|
|
91
|
+
webViewRef.current?.injectJavaScript(
|
|
92
|
+
`window.postMessage(${openModalType});true;`,
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
const closeModalType = `{ type: 'CLOSE_ONBOARDING_MODAL' }`
|
|
96
|
+
const closeModal = () =>
|
|
97
|
+
webViewRef.current?.injectJavaScript(
|
|
98
|
+
`window.postMessage(${closeModalType});true;`,
|
|
99
|
+
)
|
|
100
|
+
return (
|
|
101
|
+
<SafeAreaProvider style={{ flex: 1 }}>
|
|
102
|
+
<SafeAreaView style={{ flex: 1 }}>
|
|
103
|
+
<TouchableOpacity onPress={() => closeOnboardingModal()}>
|
|
104
|
+
<Text>Close modal</Text>
|
|
105
|
+
</TouchableOpacity>
|
|
106
|
+
<TouchableOpacity onPress={() => openOnboardingModal()}>
|
|
107
|
+
<Text>Open modal</Text>
|
|
108
|
+
</TouchableOpacity>
|
|
109
|
+
<WebView
|
|
110
|
+
ref={webViewRef}
|
|
111
|
+
onMessage={handleMessage}
|
|
112
|
+
source={{
|
|
113
|
+
uri: `${sdkMobileServer}?userOnboardingJWT=${jwt}&zeroHashOnboardingURL=${zeroHashOnboardingURL}`,
|
|
114
|
+
}}
|
|
115
|
+
/>
|
|
116
|
+
</SafeAreaView>
|
|
117
|
+
</SafeAreaProvider>
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
```
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ Error generating stack: `+i.message+`
|
|
|
9
9
|
The error may be correlated with this previous error:
|
|
10
10
|
${ji.current.stack}
|
|
11
11
|
|
|
12
|
-
`),Be}Cn(()=>{ji.current=void 0,Rn.current=void 0,zi.current=Lr});let Fi=(0,D.useMemo)(()=>D.default.createElement(C,ut({},Lr,{ref:$})),[$,C,Lr]);return(0,D.useMemo)(()=>w?D.default.createElement(de.Provider,{value:Ps},Fi):Fi,[de,Fi,Ps])}let _=D.default.memo(y);if(_.WrappedComponent=C,_.displayName=y.displayName=c,s){let O=D.default.forwardRef(function(N,de){return D.default.createElement(_,ut({},N,{reactReduxForwardedRef:de}))});return O.displayName=c,O.WrappedComponent=C,(0,ws.default)(O,C)}return(0,ws.default)(_,C)}}var Es=Qy;var Nr=q(Oe());function Ky({store:e,context:t,children:n,serverState:r,stabilityCheck:o="once",noopCheck:i="once"}){let l=(0,Nr.useMemo)(()=>{let a=Ci(e);return{store:e,subscription:a,getServerState:r?()=>r:void 0,stabilityCheck:o,noopCheck:i}},[e,r,o,i]),u=(0,Nr.useMemo)(()=>e.getState(),[e]);Cn(()=>{let{subscription:a}=l;return a.onStateChange=a.notifyNestedSubs,a.trySubscribe(),u!==e.getState()&&a.notifyNestedSubs(),()=>{a.tryUnsubscribe(),a.onStateChange=void 0}},[l,u]);let s=t||lt;return Nr.default.createElement(s.Provider,{value:l},n)}var xs=Ky;Md(up.useSyncExternalStoreWithSelector);ip(lp.useSyncExternalStore);Id(as.unstable_batchedUpdates);var Jy="ONBOARDING_",sp=Jy+"SEND_JWT_TOKEN";function fe(e){return"Minified Redux error #"+e+"; visit https://redux.js.org/Errors?code="+e+" for the full message or use the non-minified dev environment for full errors. "}var ap=function(){return typeof Symbol=="function"&&Symbol.observable||"@@observable"}(),ks=function(){return Math.random().toString(36).substring(7).split("").join(".")},Pi={INIT:"@@redux/INIT"+ks(),REPLACE:"@@redux/REPLACE"+ks(),PROBE_UNKNOWN_ACTION:function(){return"@@redux/PROBE_UNKNOWN_ACTION"+ks()}};function Zy(e){if(typeof e!="object"||e===null)return!1;for(var t=e;Object.getPrototypeOf(t)!==null;)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t}function cp(e,t,n){var r;if(typeof t=="function"&&typeof n=="function"||typeof n=="function"&&typeof arguments[3]=="function")throw new Error(fe(0));if(typeof t=="function"&&typeof n>"u"&&(n=t,t=void 0),typeof n<"u"){if(typeof n!="function")throw new Error(fe(1));return n(cp)(e,t)}if(typeof e!="function")throw new Error(fe(2));var o=e,i=t,l=[],u=l,s=!1;function a(){u===l&&(u=l.slice())}function p(){if(s)throw new Error(fe(3));return i}function h(S){if(typeof S!="function")throw new Error(fe(4));if(s)throw new Error(fe(5));var C=!0;return a(),u.push(S),function(){if(C){if(s)throw new Error(fe(6));C=!1,a();var c=u.indexOf(S);u.splice(c,1),l=null}}}function m(S){if(!Zy(S))throw new Error(fe(7));if(typeof S.type>"u")throw new Error(fe(8));if(s)throw new Error(fe(9));try{s=!0,i=o(i,S)}finally{s=!1}for(var C=l=u,f=0;f<C.length;f++){var c=C[f];c()}return S}function g(S){if(typeof S!="function")throw new Error(fe(10));o=S,m({type:Pi.REPLACE})}function w(){var S,C=h;return S={subscribe:function(c){if(typeof c!="object"||c===null)throw new Error(fe(11));function d(){c.next&&c.next(p())}d();var y=C(d);return{unsubscribe:y}}},S[ap]=function(){return this},S}return m({type:Pi.INIT}),r={dispatch:m,subscribe:h,getState:p,replaceReducer:g},r[ap]=w,r}var fp=cp;function qy(e){Object.keys(e).forEach(function(t){var n=e[t],r=n(void 0,{type:Pi.INIT});if(typeof r>"u")throw new Error(fe(12));if(typeof n(void 0,{type:Pi.PROBE_UNKNOWN_ACTION()})>"u")throw new Error(fe(13))})}function dp(e){for(var t=Object.keys(e),n={},r=0;r<t.length;r++){var o=t[r];typeof e[o]=="function"&&(n[o]=e[o])}var i=Object.keys(n),l,u;try{qy(n)}catch(s){u=s}return function(a,p){if(a===void 0&&(a={}),u)throw u;if(!1)var h;for(var m=!1,g={},w=0;w<i.length;w++){var S=i[w],C=n[S],f=a[S],c=C(f,p);if(typeof c>"u"){var d=p&&p.type;throw new Error(fe(14))}g[S]=c,m=m||c!==f}return m=m||i.length!==Object.keys(a).length,m?g:a}}var Pr="SET_ONBOARDING_MODAL_STATE",Ti="SET_USER_ONBOARDING_JWT",Ri="ONBOARDING_APP_LOADED";var by={isOnboardingAppActive:!1,isOnboardingAppLoaded:!1,userOnboardingJWT:""},ev=(e,t)=>({...e,isOnboardingAppActive:!!t.isOnboardingAppActive}),tv=(e,t)=>({...e,isOnboardingAppLoaded:!!t.isOnboardingAppLoaded}),nv=(e,t)=>({...e,userOnboardingJWT:t.userOnboardingJWT}),pp={[Pr]:ev,[Ri]:tv,[Ti]:nv},rv=(e=by,t)=>t.type&&pp[t.type]?pp[t.type](e,t):e,mp=rv;var ov=dp({appState:mp}),hp=ov;var iv=fp(hp),Rt=iv;var yp=()=>Rt.dispatch({type:Pr,isOnboardingAppActive:!0}),Tr=()=>Rt.dispatch({type:Pr,isOnboardingAppActive:!1});var Ir=q(Rr()),dv=Date.now(),pv=({isOnboardingAppActive:e,isOnboardingAppLoaded:t,userOnboardingJWT:n,zeroHashOnboardingURL:r})=>{let[o,i]=(0,Kt.useState)(ls),l=()=>{let a=yd(),p=vd[a];i({...ls,...p})},u=(0,Kt.useRef)(null);(0,Kt.useEffect)(()=>{r&&t&&n&&u.current?.contentWindow&&u.current.contentWindow.postMessage({type:sp,userOnboardingJWT:n},r)},[t,n,r]),(0,Kt.useEffect)(()=>{if(l(),window)return _r.forEach(({size:a})=>{window.matchMedia(`(min-width: ${a}px)`).addEventListener("change",l)}),()=>_r.forEach(({size:a})=>{window.matchMedia(`(min-width: ${a}px)`).removeEventListener("change",l)})},[]);let s=new URL(r);return s.searchParams.set("name",dv.toString()),window&&s.searchParams.set("origin",window.location.origin),(0,Ir.jsx)("div",{style:e?gd:Sd,onClick:Tr,children:(0,Ir.jsx)("div",{style:{...wd,...o},children:(0,Ir.jsx)("div",{style:{...Ed},children:(0,Ir.jsx)("iframe",{ref:u,title:"
|
|
12
|
+
`),Be}Cn(()=>{ji.current=void 0,Rn.current=void 0,zi.current=Lr});let Fi=(0,D.useMemo)(()=>D.default.createElement(C,ut({},Lr,{ref:$})),[$,C,Lr]);return(0,D.useMemo)(()=>w?D.default.createElement(de.Provider,{value:Ps},Fi):Fi,[de,Fi,Ps])}let _=D.default.memo(y);if(_.WrappedComponent=C,_.displayName=y.displayName=c,s){let O=D.default.forwardRef(function(N,de){return D.default.createElement(_,ut({},N,{reactReduxForwardedRef:de}))});return O.displayName=c,O.WrappedComponent=C,(0,ws.default)(O,C)}return(0,ws.default)(_,C)}}var Es=Qy;var Nr=q(Oe());function Ky({store:e,context:t,children:n,serverState:r,stabilityCheck:o="once",noopCheck:i="once"}){let l=(0,Nr.useMemo)(()=>{let a=Ci(e);return{store:e,subscription:a,getServerState:r?()=>r:void 0,stabilityCheck:o,noopCheck:i}},[e,r,o,i]),u=(0,Nr.useMemo)(()=>e.getState(),[e]);Cn(()=>{let{subscription:a}=l;return a.onStateChange=a.notifyNestedSubs,a.trySubscribe(),u!==e.getState()&&a.notifyNestedSubs(),()=>{a.tryUnsubscribe(),a.onStateChange=void 0}},[l,u]);let s=t||lt;return Nr.default.createElement(s.Provider,{value:l},n)}var xs=Ky;Md(up.useSyncExternalStoreWithSelector);ip(lp.useSyncExternalStore);Id(as.unstable_batchedUpdates);var Jy="ONBOARDING_",sp=Jy+"SEND_JWT_TOKEN";function fe(e){return"Minified Redux error #"+e+"; visit https://redux.js.org/Errors?code="+e+" for the full message or use the non-minified dev environment for full errors. "}var ap=function(){return typeof Symbol=="function"&&Symbol.observable||"@@observable"}(),ks=function(){return Math.random().toString(36).substring(7).split("").join(".")},Pi={INIT:"@@redux/INIT"+ks(),REPLACE:"@@redux/REPLACE"+ks(),PROBE_UNKNOWN_ACTION:function(){return"@@redux/PROBE_UNKNOWN_ACTION"+ks()}};function Zy(e){if(typeof e!="object"||e===null)return!1;for(var t=e;Object.getPrototypeOf(t)!==null;)t=Object.getPrototypeOf(t);return Object.getPrototypeOf(e)===t}function cp(e,t,n){var r;if(typeof t=="function"&&typeof n=="function"||typeof n=="function"&&typeof arguments[3]=="function")throw new Error(fe(0));if(typeof t=="function"&&typeof n>"u"&&(n=t,t=void 0),typeof n<"u"){if(typeof n!="function")throw new Error(fe(1));return n(cp)(e,t)}if(typeof e!="function")throw new Error(fe(2));var o=e,i=t,l=[],u=l,s=!1;function a(){u===l&&(u=l.slice())}function p(){if(s)throw new Error(fe(3));return i}function h(S){if(typeof S!="function")throw new Error(fe(4));if(s)throw new Error(fe(5));var C=!0;return a(),u.push(S),function(){if(C){if(s)throw new Error(fe(6));C=!1,a();var c=u.indexOf(S);u.splice(c,1),l=null}}}function m(S){if(!Zy(S))throw new Error(fe(7));if(typeof S.type>"u")throw new Error(fe(8));if(s)throw new Error(fe(9));try{s=!0,i=o(i,S)}finally{s=!1}for(var C=l=u,f=0;f<C.length;f++){var c=C[f];c()}return S}function g(S){if(typeof S!="function")throw new Error(fe(10));o=S,m({type:Pi.REPLACE})}function w(){var S,C=h;return S={subscribe:function(c){if(typeof c!="object"||c===null)throw new Error(fe(11));function d(){c.next&&c.next(p())}d();var y=C(d);return{unsubscribe:y}}},S[ap]=function(){return this},S}return m({type:Pi.INIT}),r={dispatch:m,subscribe:h,getState:p,replaceReducer:g},r[ap]=w,r}var fp=cp;function qy(e){Object.keys(e).forEach(function(t){var n=e[t],r=n(void 0,{type:Pi.INIT});if(typeof r>"u")throw new Error(fe(12));if(typeof n(void 0,{type:Pi.PROBE_UNKNOWN_ACTION()})>"u")throw new Error(fe(13))})}function dp(e){for(var t=Object.keys(e),n={},r=0;r<t.length;r++){var o=t[r];typeof e[o]=="function"&&(n[o]=e[o])}var i=Object.keys(n),l,u;try{qy(n)}catch(s){u=s}return function(a,p){if(a===void 0&&(a={}),u)throw u;if(!1)var h;for(var m=!1,g={},w=0;w<i.length;w++){var S=i[w],C=n[S],f=a[S],c=C(f,p);if(typeof c>"u"){var d=p&&p.type;throw new Error(fe(14))}g[S]=c,m=m||c!==f}return m=m||i.length!==Object.keys(a).length,m?g:a}}var Pr="SET_ONBOARDING_MODAL_STATE",Ti="SET_USER_ONBOARDING_JWT",Ri="ONBOARDING_APP_LOADED";var by={isOnboardingAppActive:!1,isOnboardingAppLoaded:!1,userOnboardingJWT:""},ev=(e,t)=>({...e,isOnboardingAppActive:!!t.isOnboardingAppActive}),tv=(e,t)=>({...e,isOnboardingAppLoaded:!!t.isOnboardingAppLoaded}),nv=(e,t)=>({...e,userOnboardingJWT:t.userOnboardingJWT}),pp={[Pr]:ev,[Ri]:tv,[Ti]:nv},rv=(e=by,t)=>t.type&&pp[t.type]?pp[t.type](e,t):e,mp=rv;var ov=dp({appState:mp}),hp=ov;var iv=fp(hp),Rt=iv;var yp=()=>Rt.dispatch({type:Pr,isOnboardingAppActive:!0}),Tr=()=>Rt.dispatch({type:Pr,isOnboardingAppActive:!1});var Ir=q(Rr()),dv=Date.now(),pv=({isOnboardingAppActive:e,isOnboardingAppLoaded:t,userOnboardingJWT:n,zeroHashOnboardingURL:r})=>{let[o,i]=(0,Kt.useState)(ls),l=()=>{let a=yd(),p=vd[a];i({...ls,...p})},u=(0,Kt.useRef)(null);(0,Kt.useEffect)(()=>{r&&t&&n&&u.current?.contentWindow&&u.current.contentWindow.postMessage({type:sp,userOnboardingJWT:n},r)},[t,n,r]),(0,Kt.useEffect)(()=>{if(l(),window)return _r.forEach(({size:a})=>{window.matchMedia(`(min-width: ${a}px)`).addEventListener("change",l)}),()=>_r.forEach(({size:a})=>{window.matchMedia(`(min-width: ${a}px)`).removeEventListener("change",l)})},[]);let s=new URL(r);return s.searchParams.set("name",dv.toString()),window&&s.searchParams.set("origin",window.location.origin),(0,Ir.jsx)("div",{style:e?gd:Sd,onClick:Tr,children:(0,Ir.jsx)("div",{style:{...wd,...o},children:(0,Ir.jsx)("div",{style:{...Ed},children:(0,Ir.jsx)("iframe",{ref:u,title:"ZeroHash Onboarding",src:s.toString(),allowFullScreen:!0,allow:"camera 'self' https://verify.soraid.com; fullscreen 'self' https://verify.soraid.com; accelerometer 'self' https://verify.soraid.com; gyroscope 'self' https://verify.soraid.com; magnetometer 'self' https://verify.soraid.com;",style:xd})})})})},mv=e=>({isOnboardingAppActive:e.appState.isOnboardingAppActive,isOnboardingAppLoaded:e.appState.isOnboardingAppLoaded,userOnboardingJWT:e.appState.userOnboardingJWT}),wp=Es(mv)(pv);var Os=q(Rr()),_s=is,kp="",Ep={ONBOARDING_APP_LOADED:()=>{Rt.dispatch({type:Ri,isOnboardingAppLoaded:!0})},ONBOARDING_CLOSE_BUTTON_CLICKED:()=>{Tr()}},hv=e=>{if(e.origin===kp){let t=e.data;if(t&&t.type&&Ep[t.type])try{Ep[t.type](t.payload)}catch(n){console.error(n)}}},Li=class{rootQuerySelector="";onboardingInitialized=!1;constructor({zeroHashOnboardingURL:t=is,rootQuerySelector:n,userOnboardingJWT:r}){_s=t,kp=new URL(_s).origin,n&&(this.rootQuerySelector=n),window.addEventListener("message",hv,!1),r&&this.setUserOnboardingJWT({userOnboardingJWT:r})}setUserOnboardingJWT(t){Rt.dispatch({type:Ti,userOnboardingJWT:t.userOnboardingJWT})}isOnboardingModalOpen(){return Rt.getState().appState.isOnboardingAppActive}openOnboardingModal(t){if(t.userOnboardingJWT&&this.setUserOnboardingJWT({userOnboardingJWT:t.userOnboardingJWT}),yp(),this.onboardingInitialized)return;let n=null;if(this.rootQuerySelector&&(n=document.querySelector(this.rootQuerySelector)),!n){n=document.createElement("div");let r=hd();n.id=r,n.style.position="absolute",n.style.top="0",n.style.left="0",this.rootQuerySelector=`#${r}`,document.querySelector("body").appendChild(n)}if(n){let r=n.attachShadow({mode:"closed"});xp.default.createRoot(r).render((0,Os.jsx)(xs,{store:Rt,children:(0,Os.jsx)(wp,{zeroHashOnboardingURL:_s})})),this.onboardingInitialized=!0}else{let r="failed to append ZeroHash root to the page: root not found";throw console.error(r),new Error(r)}}closeOnboardingModal(){Tr()}};window&&(window.zerohash=Li);var x1=Li;export{Li as ZeroHashSDK,x1 as default};
|
|
13
13
|
/*! Bundled license information:
|
|
14
14
|
|
|
15
15
|
react/cjs/react.production.min.js:
|