-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add PostMessageProvider, it work on iframe of zkid wallet pwa app. (#20)
- Loading branch information
1 parent
d08c36c
commit f042638
Showing
16 changed files
with
351 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"mode": "pre", | ||
"tag": "beta", | ||
"initialVersions": { | ||
"@zcloak/login-did": "1.1.1", | ||
"@zcloak/login-providers": "1.1.1", | ||
"@zcloak/login-rpc": "1.0.1", | ||
"@zcloak/login-rpc-defines": "1.1.1", | ||
"@zcloak/login-verify": "1.1.3" | ||
}, | ||
"changesets": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
"@zcloak/login-rpc-defines": minor | ||
"@zcloak/login-providers": minor | ||
"@zcloak/login-rpc": minor | ||
--- | ||
|
||
add PostMessageProvider, it work on iframe of zkid wallet pwa app. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// Copyright 2021-2023 zcloak authors & contributors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import type { Request, RpcMethods, RpcRequest } from '@zcloak/login-rpc'; | ||
import type { ZkidWalletProvider } from './types'; | ||
|
||
import { BaseProvider } from './base/Provider'; | ||
|
||
declare module '@zcloak/login-rpc/rpcs' { | ||
interface Rpcs { | ||
credential_import: [{ credential: HexString }, undefined]; | ||
} | ||
} | ||
|
||
declare global { | ||
interface Window { | ||
zkid?: { request: Request; events: any }; | ||
} | ||
} | ||
|
||
type HexString = `0x${string}`; | ||
|
||
const waitReady: Promise<void> = new Promise<void>((resolve) => { | ||
if (document.readyState === 'complete') { | ||
resolve(); | ||
} else { | ||
self.addEventListener('load', () => resolve()); | ||
} | ||
}); | ||
|
||
const request: Request = async (method: RpcMethods, params: RpcRequest<RpcMethods>) => { | ||
await waitReady; | ||
if (!self.zkid) throw new Error('Please install zkID Wallet'); | ||
|
||
return self.zkid.request(method, params); | ||
}; | ||
|
||
export class ExtensionProvider extends BaseProvider implements ZkidWalletProvider { | ||
public static async isInstalled(): Promise<boolean> { | ||
await ExtensionProvider.isReady(); | ||
|
||
return !!self.zkid; | ||
} | ||
|
||
public static isReady(): Promise<void> { | ||
return waitReady; | ||
} | ||
|
||
constructor() { | ||
super(request); | ||
|
||
waitReady.then(() => { | ||
if (!self.zkid) { | ||
console.warn( | ||
'Not zkID Wallet context, please install zkID Wallet https://chrome.google.com/webstore/detail/zkid-wallet/ahkpfejaeoepmfopmbhjgjekibmfcfgo' | ||
); | ||
} | ||
}); | ||
|
||
self.zkid?.events?.on?.('zkID_Wallet_didLoggedChanged', this.#didChanged); | ||
self.zkid?.events?.on?.('zkID_Wallet_lock', this.#lock); | ||
self.zkid?.events?.on?.('zkID_Wallet_unlock', this.#unlock); | ||
} | ||
|
||
#didChanged = (...args: any[]) => { | ||
this.emit('did_changed', ...args); | ||
}; | ||
|
||
#lock = (...args: any[]) => { | ||
this.emit('lock', ...args); | ||
}; | ||
|
||
#unlock = (...args: any[]) => { | ||
this.emit('unlock', ...args); | ||
}; | ||
|
||
public importCredential(data: HexString) { | ||
return this.request('credential_import', { credential: data }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
// Copyright 2021-2023 zcloak authors & contributors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import type { ZkidWalletProvider } from './types'; | ||
|
||
import { | ||
isTransportEventMessage, | ||
isTransportResponseMessage, | ||
Request, | ||
RpcMethods, | ||
RpcRequest, | ||
RpcResponse | ||
} from '@zcloak/login-rpc'; | ||
|
||
import { BaseProvider } from './base/Provider'; | ||
|
||
type Handlers = Record< | ||
string, | ||
{ | ||
resolve: (data: RpcResponse<RpcMethods>) => void; | ||
reject: (error: Error) => void; | ||
} | ||
>; | ||
type HexString = `0x${string}`; | ||
|
||
let increaseId = 0; | ||
|
||
const handlers: Handlers = {}; | ||
|
||
const request: Request = (method: RpcMethods, params: RpcRequest<RpcMethods>) => { | ||
if (self === parent) throw new Error('Please open on zkID Wallet'); | ||
|
||
return new Promise((resolve, reject) => { | ||
const id = `${Date.now()}.${increaseId++}`; | ||
|
||
handlers[id] = { reject, resolve }; | ||
|
||
const message = { | ||
jsonrpc: '2.0', | ||
id, | ||
method, | ||
params | ||
}; | ||
|
||
parent.postMessage(message, '*'); | ||
}); | ||
}; | ||
|
||
export class PostMessageProvider extends BaseProvider implements ZkidWalletProvider { | ||
private readonly allowedOrigins: RegExp[] | null = null; | ||
|
||
constructor(allowedOrigins: RegExp[] | null = null) { | ||
super(request); | ||
|
||
this.allowedOrigins = allowedOrigins; | ||
self.addEventListener('message', this.#handleMessage); | ||
} | ||
|
||
private isValidMessage = ({ data, origin, source }: MessageEvent): boolean => { | ||
const emptyOrMalformed = !data; | ||
const sentFromParentEl = source === parent; | ||
let validOrigin = true; | ||
|
||
if (Array.isArray(this.allowedOrigins)) { | ||
validOrigin = this.allowedOrigins.find((regExp) => regExp.test(origin)) !== undefined; | ||
} | ||
|
||
return !emptyOrMalformed && sentFromParentEl && validOrigin; | ||
}; | ||
|
||
#handleMessage = (message: MessageEvent) => { | ||
if (this.isValidMessage(message)) { | ||
if (isTransportEventMessage(message.data)) { | ||
// event transport message | ||
|
||
if (message.data.event === 'zkID_Wallet_didLoggedChanged') { | ||
this.emit('did_changed', message.data.data); | ||
} else if (message.data.event === 'zkID_Wallet_lock') { | ||
this.emit('lock', message.data.data); | ||
} else if (message.data.event === 'zkID_Wallet_unlock') { | ||
this.emit('unlock', message.data.data); | ||
} | ||
} else if (isTransportResponseMessage(message.data)) { | ||
// response transport message | ||
|
||
const handler = handlers[message.data.id]; | ||
|
||
if (!handler) { | ||
console.error(`Unknown response: ${JSON.stringify(message.data)}`); | ||
|
||
return; | ||
} | ||
|
||
delete handlers[message.data.id]; | ||
|
||
if (message.data.error) { | ||
handler.reject(new Error(message.data.error.message)); | ||
} else { | ||
handler.resolve(message.data.result); | ||
} | ||
} | ||
} | ||
}; | ||
|
||
public importCredential(data: HexString) { | ||
return this.request('credential_import', { credential: data }); | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
// Copyright 2021-2023 zcloak authors & contributors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
export * from './ZkidWalletProvider'; | ||
export * from './ExtensionProvider'; | ||
export * from './PostMessageProvider'; | ||
export * from './zkidWallet'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,11 @@ | ||
// Copyright 2021-2023 zcloak authors & contributors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import { BaseProvider } from './base/Provider'; | ||
|
||
export type ProviderEvents = 'did_changed' | 'lock' | 'unlock'; | ||
type HexString = `0x${string}`; | ||
|
||
export interface ZkidWalletProvider extends BaseProvider { | ||
importCredential(data: HexString): Promise<void>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Copyright 2021-2023 zcloak authors & contributors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
import { ExtensionProvider } from './ExtensionProvider'; | ||
import { PostMessageProvider } from './PostMessageProvider'; | ||
import { ZkidWalletProvider } from './types'; | ||
|
||
export function adaptZkidWallet(allowedOrigins: RegExp[] | null = null): ZkidWalletProvider { | ||
if (self !== parent) { | ||
return new PostMessageProvider(allowedOrigins); | ||
} else { | ||
return new ExtensionProvider(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,58 @@ | ||
// Copyright 2021-2023 zcloak authors & contributors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
export interface RpcError { | ||
export interface RpcErrorInterface { | ||
code: number; | ||
message: string; | ||
meaning: string; | ||
} | ||
|
||
export class RpcError extends Error { | ||
public code: number; | ||
public meaning: string; | ||
|
||
constructor(code: number, message: string, meaning: string) { | ||
super(message); | ||
this.code = code; | ||
this.meaning = meaning; | ||
} | ||
|
||
public toJson(): RpcErrorInterface { | ||
return { | ||
code: this.code, | ||
message: this.message, | ||
meaning: this.meaning | ||
}; | ||
} | ||
|
||
public static fromCode(code: number): RpcErrorInterface { | ||
switch (code) { | ||
case -32700: | ||
return new RpcError( | ||
code, | ||
'Parse error', | ||
'Invalid JSON was received by the server. An error occurred on the server while parsing the JSON text.' | ||
).toJson(); | ||
case -32600: | ||
return new RpcError(code, 'Invalid Request', 'The JSON sent is not a valid Request object.').toJson(); | ||
case -32601: | ||
return new RpcError(code, 'Method not found', 'The method does not exist / is not available.').toJson(); | ||
case -32602: | ||
return new RpcError(code, 'Invalid params', 'Invalid method parameter(s).').toJson(); | ||
case -32603: | ||
return new RpcError(code, 'Internal error', 'Internal JSON-Rpc error.').toJson(); | ||
case -32001: | ||
return new RpcError(code, 'User Reject', 'User reject operation').toJson(); | ||
default: | ||
return new RpcError(code, 'Unknown Error', 'Unknown Error').toJson(); | ||
} | ||
} | ||
|
||
public static fromError(error: any): RpcErrorInterface { | ||
return new RpcError( | ||
error?.code ?? -1, | ||
error?.message ?? 'Unknown Error', | ||
error?.reason ?? 'Unknown Error' | ||
).toJson(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ | |
export * from './errors'; | ||
export * from './request'; | ||
export * from './rpcs'; | ||
export * from './transport'; |
Oops, something went wrong.