Skip to content
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

refactor: update signature creation #5089

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2017,7 +2017,7 @@ SPEC CHECKSUMS:
SwiftNIOTLS: 598af547490133e9aac52aed0c23c4a90c31dcfc
SwiftNIOTransportServices: 0b2b407819d82eb63af558c5396e33c945759503
SwiftProtobuf: b70d65f419fbfe61a2d58003456ca5da58e337d6
Yoga: 805bf71192903b20fc14babe48080582fee65a80
Yoga: d17d2cc8105eed528474683b42e2ea310e1daf61
ZIPFoundation: b1f0de4eed33e74a676f76e12559ab6b75990197
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb

Expand Down
2 changes: 1 addition & 1 deletion src/components/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,7 @@ const EdgeBuyTabScreen = () => {
}}
/>
<Stack.Screen name="pluginListBuy" component={GuiPluginListScene} options={firstSceneScreenOptions} />
<Stack.Screen name="guiPluginWebView" component={FiatPluginWebViewComponent} />
<Stack.Screen name="guiPluginWebView" component={FiatPluginWebViewComponent} options={{ animationEnabled: false }} />
<Stack.Screen
name="pluginViewBuy"
component={GuiPluginViewScene}
Expand Down
42 changes: 35 additions & 7 deletions src/plugins/gui/providers/paybisProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { SendScene2Params } from '../../../components/scenes/SendScene2'
import { locale } from '../../../locales/intl'
import { lstrings } from '../../../locales/strings'
import { EdgeAsset, StringMap } from '../../../types/types'
import { sha512HashAndSign } from '../../../util/crypto'
import { CryptoAmount } from '../../../util/CryptoAmount'
import { SendErrorNoTransaction } from '../fiatPlugin'
import { FiatDirection, FiatPaymentType, FiatPluginUi, SaveTxActionParams } from '../fiatPluginTypes'
Expand Down Expand Up @@ -205,6 +204,7 @@ const asPublicRequestResponse = asObject({
type PaymentMethodId = ReturnType<typeof asPaymentMethodId>
type PaybisBuyPairs = ReturnType<typeof asPaybisBuyPairs>
type PaybisSellPairs = ReturnType<typeof asPaybisSellPairs>
type Signature = string | undefined

interface InitializePairs {
url: string
Expand Down Expand Up @@ -684,6 +684,37 @@ export const paybisProvider: FiatProviderFactory = {
}
}

const openWebViewAndCreateSignature = async (showUi: FiatPluginUi | undefined, privateKey: string, body: string): Promise<Signature> => {
return await new Promise<Signature>(resolve => {
if (showUi === undefined) return undefined
/* eslint-disable-next-line @typescript-eslint/no-floating-promises */
showUi.openWebView({
url: '',
html: `
<!DOCTYPE html>
<html>
<head>
<!-- TODO: import library -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/jsrsasign-all-min.js"></script>
</head>
<body>
<script>
const sig = new KJUR.crypto.Signature({ 'alg': 'SHA512withRSAandMGF1' });
sig.init(\`${privateKey}\`);
sig.updateString(\`${body}\`);
window.ReactNativeWebView.postMessage(hextob64(sig.sign()));
</script>
</body>
</html>
`,
onMessage: (signature: Signature) => {
resolve(signature)
showUi.exitScene()
}
})
})
}

const paybisFetch = async (params: {
method: 'POST' | 'GET'
url: string
Expand All @@ -698,13 +729,10 @@ const paybisFetch = async (params: {
const urlObj = new URL(url + '/' + path, true)
const body = bodyParams != null ? JSON.stringify(bodyParams) : undefined

let signature: string | undefined
let signature: Signature
if (privateKey != null) {
if (body == null) throw new Error('Paybis: Cannot sign without body')
// Because we will be doing a slow CPU operation in sha512HashAndSign, we need to first
// call waitForAnimationFrame to ensure the UI spinner is rendered.
if (showUi != null) await showUi.waitForAnimationFrame()
signature = sha512HashAndSign(body, privateKey)
signature = await openWebViewAndCreateSignature(showUi, privateKey, body)
}
queryParams.apikey = apiKey
urlObj.set('query', queryParams)
Expand All @@ -715,7 +743,7 @@ const paybisFetch = async (params: {
'Content-Type': 'application/json'
}
}
if (signature != null) {
if (signature !== undefined) {
options.headers = {
...options.headers,
'x-request-signature': signature
Expand Down
7 changes: 5 additions & 2 deletions src/plugins/gui/scenes/FiatPluginWebView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { WebView, WebViewNavigation } from 'react-native-webview'

import { SceneWrapper } from '../../../components/common/SceneWrapper'
import { useHandler } from '../../../hooks/useHandler'
import { config } from '../../../theme/appConfig'
import { EdgeSceneProps } from '../../../types/routerTypes'

export interface FiatPluginOpenWebViewParams {
url: string
html?: string
injectedJs?: string
onClose?: () => void
onMessage?: (message: string, injectJs: (js: string) => void) => void
Expand All @@ -17,7 +19,7 @@ interface Props extends EdgeSceneProps<'guiPluginWebView'> {}

export function FiatPluginWebViewComponent(props: Props): JSX.Element {
const { route } = props
const { injectedJs, onClose, onMessage, onUrlChange, url } = route.params
const { injectedJs, onClose, onMessage, onUrlChange, url, html } = route.params

const webViewRef = React.useRef<WebView>(null)

Expand All @@ -43,14 +45,15 @@ export function FiatPluginWebViewComponent(props: Props): JSX.Element {
return (
<SceneWrapper hasTabs>
<WebView
style={config.lightTheme.guiPluginWebView}
allowUniversalAccessFromFileURLs
geolocationEnabled
javaScriptEnabled
allowsInlineMediaPlayback
mediaPlaybackRequiresUserAction={false}
ref={webViewRef}
scalesPageToFit
source={{ uri: url }}
source={html ? { html } : { url }}
onMessage={handleMessage}
onNavigationStateChange={handleNavigationStateChange}
injectedJavaScriptBeforeContentLoaded={injectedJs}
Expand Down
7 changes: 6 additions & 1 deletion src/theme/variables/edgeDark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -517,5 +517,10 @@ export const edgeDark: Theme = {
txDirBgSwap: palette.blueGrayOp70,
txDirFgReceive: palette.lightGreen,
txDirFgSend: palette.lightRed,
txDirFgSwap: palette.blueGray
txDirFgSwap: palette.blueGray,

// guiPluginWebView
guiPluginWebView: {
backgroundColor: palette.transparent
}
}
7 changes: 6 additions & 1 deletion src/theme/variables/edgeLight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -473,5 +473,10 @@ export const edgeLight: Theme = {
txDirBgSwap: palette.grayOp70,
txDirFgReceive: palette.lightGreen,
txDirFgSend: palette.lightRed,
txDirFgSwap: palette.lightGray
txDirFgSwap: palette.lightGray,

// guiPluginWebView
guiPluginWebView: {
backgroundColor: palette.transparent
}
}
7 changes: 6 additions & 1 deletion src/theme/variables/testDark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -514,5 +514,10 @@ export const testDark: Theme = {
txDirBgSwap: palette.grayOp70,
txDirFgReceive: palette.lightGreen,
txDirFgSend: palette.lightRed,
txDirFgSwap: palette.lightGray
txDirFgSwap: palette.lightGray,

// guiPluginWebView
guiPluginWebView: {
backgroundColor: palette.transparent
}
}
7 changes: 6 additions & 1 deletion src/theme/variables/testLight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -473,5 +473,10 @@ export const testLight: Theme = {
txDirBgSwap: palette.grayOp70,
txDirFgReceive: palette.lightGreen,
txDirFgSend: palette.lightRed,
txDirFgSwap: palette.lightGray
txDirFgSwap: palette.lightGray,

// guiPluginWebView
guiPluginWebView: {
backgroundColor: palette.transparent
}
}
5 changes: 5 additions & 0 deletions src/types/Theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -460,4 +460,9 @@ export interface Theme {
txDirFgReceive: string
txDirFgSend: string
txDirFgSwap: string

// guiPluginWebView
guiPluginWebView: {
backgroundColor: string
}
}