-
Notifications
You must be signed in to change notification settings - Fork 91
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
frontend: use postmessage to communicate with the iframe #3146
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,104 +10,123 @@ | |
|
||
<script lang="js"> | ||
;(() => { | ||
const { | ||
address, | ||
apiKey, | ||
baseCurrency, | ||
mode, | ||
quoteCurrency, | ||
} = window.frameElement?.dataset; | ||
|
||
if (mode === 'debug') { | ||
console.info(window.frameElement?.dataset); | ||
|
||
if (window.top === window) { | ||
showError('Unexpected error'); | ||
return; | ||
} | ||
|
||
if ( // this should never happen, but if it does we stop here | ||
!address | ||
|| !baseCurrency | ||
|| !quoteCurrency | ||
) { | ||
document.body.append( | ||
Object.assign(document.createElement('h1'), { | ||
style: 'color: red; padding: 1rem;', | ||
textContent: `Unexpected error: | ||
const onMessage = (event) => { | ||
switch (event.data?.action) { | ||
case 'configuration': | ||
const { | ||
address, | ||
apiKey, | ||
baseCurrency, | ||
mode, | ||
quoteCurrency, | ||
} = event.data || {}; | ||
|
||
if ( // this should never happen, but if it does we stop here | ||
!address | ||
|| !baseCurrency | ||
|| !quoteCurrency | ||
) { | ||
showError(`Unexpected error: | ||
${!address ? 'Address missing' : ''} | ||
${!baseCurrency ? 'BaseCurrency missing' : ''} | ||
${!quoteCurrency ? 'QuoteCurrency missing' : ''} | ||
` | ||
}) | ||
); | ||
return; | ||
} | ||
`); | ||
return; | ||
} | ||
const currency = baseCurrency.toUpperCase(); | ||
|
||
const currency = baseCurrency.toUpperCase(); | ||
// add the btcdirect CSS | ||
document.head.appendChild( | ||
Object.assign(document.createElement('link'), { | ||
href: ( | ||
mode === 'production' | ||
? 'https://cdn.btcdirect.eu/fiat-to-coin/fiat-to-coin.css' | ||
: 'https://cdn-sandbox.btcdirect.eu/fiat-to-coin/fiat-to-coin.css' | ||
), | ||
rel: 'stylesheet', | ||
}) | ||
); | ||
|
||
// add the btcdirect CSS | ||
document.head.appendChild( | ||
Object.assign(document.createElement('link'), { | ||
href: ( | ||
// add the btcdirect script | ||
(function (btc, d, i, r, e, c, t) { | ||
btc[r] = btc[r] || function () { | ||
(btc[r].q = btc[r].q || []).push(arguments) | ||
}; | ||
c = d.createElement(i); | ||
c.id = r; c.src = e; c.async = true; | ||
c.type = 'module'; c.dataset.btcdirect = ''; | ||
t = d.getElementsByTagName(i)[0]; | ||
t.parentNode.insertBefore(c, t); | ||
})(window, document, 'script', 'btcdirect', | ||
mode === 'production' | ||
? 'https://cdn.btcdirect.eu/fiat-to-coin/fiat-to-coin.css' | ||
: 'https://cdn-sandbox.btcdirect.eu/fiat-to-coin/fiat-to-coin.css' | ||
), | ||
rel: 'stylesheet', | ||
}) | ||
); | ||
|
||
// add the btcdirect script | ||
(function (btc, d, i, r, e, c, t) { | ||
btc[r] = btc[r] || function () { | ||
(btc[r].q = btc[r].q || []).push(arguments) | ||
}; | ||
c = d.createElement(i); | ||
c.id = r; c.src = e; c.async = true; | ||
c.type = 'module'; c.dataset.btcdirect = ''; | ||
t = d.getElementsByTagName(i)[0]; | ||
t.parentNode.insertBefore(c, t); | ||
})(window, document, 'script', 'btcdirect', | ||
mode === 'production' | ||
? 'https://cdn.btcdirect.eu/fiat-to-coin/fiat-to-coin.js' | ||
: 'https://cdn-sandbox.btcdirect.eu/fiat-to-coin/fiat-to-coin.js' | ||
); | ||
|
||
btcdirect('init', { | ||
token: apiKey, | ||
debug: mode === 'debug', | ||
locale: window.frameElement?.dataset.locale || 'en-US', | ||
theme: window.frameElement?.dataset.theme || 'light', | ||
}); | ||
|
||
// fiat to coin order | ||
btcdirect('wallet-addresses', { | ||
addresses: { | ||
address, | ||
currency, | ||
id: 'BitBox', | ||
walletName: 'BitBox' | ||
} | ||
}); | ||
|
||
btcdirect('set-parameters', | ||
mode === 'production' ? { | ||
baseCurrency: currency, | ||
fixedCurrency: true, | ||
quoteCurrency, | ||
// paymentMethod: any of 'bancontact', 'bankTransfer', 'creditCard', 'giropay', 'iDeal', 'sofort', 'applepay' | ||
showWalletAddress: false, | ||
} : { | ||
baseCurrency: currency, | ||
fixedCurrency: true, | ||
paymentMethod: 'sofort', // sandbox currently only supports sofort payment method | ||
quoteCurrency, | ||
showWalletAddress: false, | ||
? 'https://cdn.btcdirect.eu/fiat-to-coin/fiat-to-coin.js' | ||
: 'https://cdn-sandbox.btcdirect.eu/fiat-to-coin/fiat-to-coin.js' | ||
); | ||
|
||
btcdirect('init', { | ||
token: apiKey, | ||
debug: mode === 'debug', | ||
locale: window.frameElement?.dataset.locale || 'en-GB', | ||
theme: window.frameElement?.dataset.theme || 'light', | ||
}); | ||
|
||
// fiat to coin order | ||
btcdirect('wallet-addresses', { | ||
addresses: { | ||
address, | ||
currency, | ||
id: 'BitBox', | ||
walletName: 'BitBox' | ||
} | ||
}); | ||
|
||
btcdirect('set-parameters', | ||
mode === 'production' ? { | ||
baseCurrency: currency, | ||
fixedCurrency: true, | ||
quoteCurrency, | ||
// paymentMethod: any of 'bancontact', 'bankTransfer', 'creditCard', 'giropay', 'iDeal', 'sofort', 'applepay' | ||
showWalletAddress: false, | ||
} : { | ||
baseCurrency: currency, | ||
fixedCurrency: true, | ||
paymentMethod: 'sofort', // sandbox currently only supports sofort payment method | ||
quoteCurrency, | ||
showWalletAddress: false, | ||
} | ||
); | ||
|
||
window.addEventListener('btcdirect-embeddable-fiat-to-coin-order-confirmed', (event) => { | ||
console.log('btcdirect-embeddable-fiat-to-coin-order-confirmed', event); | ||
// Handle the event | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here you could directly post a message to pass the order confirmation, maybe? And leave the TODO in the handler inside btcdirect.tsx. No strong opinion, tho There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I only tested once, this event is fired after the user clicked proceed to payment and not really useful this way, I'll just remove. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. removed in #3152 |
||
// Note that the sent information from the widget is found inside event.detail | ||
}); | ||
|
||
break; | ||
} | ||
); | ||
}; | ||
|
||
window.addEventListener('message', onMessage); | ||
|
||
// Request the parent to send attributes | ||
window.parent.postMessage({ | ||
action: 'request-configuration' | ||
}, '*'); | ||
|
||
window.addEventListener('btcdirect-embeddable-fiat-to-coin-order-confirmed', (event) => { | ||
console.log('btcdirect-embeddable-fiat-to-coin-order-confirmed', event); | ||
// Handle the event | ||
// Note that the sent information from the widget is found inside event.detail | ||
}); | ||
function showError(message) { | ||
document.body.append( | ||
Object.assign(document.createElement('h1'), { | ||
style: 'color: red; padding: 1rem;', | ||
textContent: message, | ||
}) | ||
); | ||
} | ||
|
||
})(); | ||
</script> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is the file we host on but in order for it to communicate with the react app we need the changes in this PR in btcdirect.tsx |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,7 @@ | |
* limitations under the License. | ||
*/ | ||
|
||
import { useState, useEffect, createRef, useContext, useRef } from 'react'; | ||
import { useState, useEffect, createRef, useContext, useRef, useCallback } from 'react'; | ||
import { useTranslation } from 'react-i18next'; | ||
import { getBTCDirectInfo } from '@/api/exchanges'; | ||
import { AppContext } from '@/contexts/AppContext'; | ||
|
@@ -94,15 +94,45 @@ export const BTCDirect = ({ accounts, code }: TProps) => { | |
}, 200); | ||
}; | ||
|
||
const locale = i18n.resolvedLanguage ? localeMapping[i18n.resolvedLanguage] : 'en-GB'; | ||
|
||
const onMessage = useCallback((event: MessageEvent) => { | ||
// if (!isDevserver && event.origin !== 'https://shiftcrypto.io') { return; } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this commented? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll update once we have the backend part, the correct subdomain is If you don't mind I'll continue in #3152 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated in #3152 |
||
|
||
if (!account || !btcdirectInfo?.success) { | ||
return; | ||
} | ||
switch (event.data.action) { | ||
case 'request-configuration': | ||
event.source?.postMessage({ | ||
action: 'configuration', | ||
address, | ||
locale, | ||
theme: isDarkMode ? 'dark' : 'light', | ||
baseCurrency: getCoinCode(account.coinCode), | ||
quoteCurrency: 'EUR', | ||
mode: isTesting || debug ? 'debug' : 'production', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this correct? I didn't test it (no pun intended 😇 ) but I think that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as discussed in DM it would be great to align with the backend, so we need something like isProdservers in the frontend. Alternative: maybethe backend could pass 'debug' or 'production' in another field in some existing api call. |
||
apiKey: btcdirectInfo.apiKey, | ||
}, { | ||
targetOrigin: event.origin | ||
}); | ||
break; | ||
} | ||
|
||
}, [account, address, btcdirectInfo, locale, isDarkMode, isTesting]); | ||
|
||
useEffect(() => { | ||
window.addEventListener('message', onMessage); | ||
return () => window.removeEventListener('message', onMessage); | ||
}); | ||
|
||
if (!account || !config) { | ||
return null; | ||
} | ||
|
||
const hasOnlyBTCAccounts = accounts.every(({ coinCode }) => isBitcoinOnly(coinCode)); | ||
const translationContext = hasOnlyBTCAccounts ? 'bitcoin' : 'crypto'; | ||
|
||
const locale = i18n.resolvedLanguage ? localeMapping[i18n.resolvedLanguage] : 'en-GB'; | ||
|
||
return ( | ||
<div className="contentWithGuide"> | ||
<div className="container"> | ||
|
@@ -137,15 +167,6 @@ export const BTCDirect = ({ accounts, code }: TProps) => { | |
frameBorder="0" | ||
className={`${style.iframe} ${!iframeLoaded ? style.hide : ''}`} | ||
allow="camera" | ||
data-locale={locale} | ||
data-theme={isDarkMode ? 'dark' : 'light'} | ||
data-base-currency={getCoinCode(account.coinCode)} | ||
data-quote-currency={'EUR'} | ||
data-address={address} | ||
data-mode={ | ||
isTesting || debug ? 'debug' : 'production' | ||
} | ||
data-api-key={btcdirectInfo.apiKey} | ||
src={btcdirectInfo.url}> | ||
</iframe> | ||
)} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: take locale and theme from onMessage "configuration" / event.data
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rebased this branch without the backend commit and fixed "locale" and "theme" in #3152