Skip to content

Instantly share code, notes, and snippets.

@cellog
Created July 17, 2019 23:41
Show Gist options
  • Save cellog/296b62111a5f00a830702f18c38c4b6a to your computer and use it in GitHub Desktop.
Save cellog/296b62111a5f00a830702f18c38c4b6a to your computer and use it in GitHub Desktop.
Data Iframe Mailbox
import BlockchainHandler from './blockchainHandler/BlockchainHandler'
import {
ConstantsType,
BlockchainData,
FetchWindow,
SetTimeoutWindow,
} from './blockchainHandler/blockChainTypes'
import { isValidPaywallConfig } from '../utils/validators'
import { PaywallConfig, PurchaseKeyRequest } from '../unlockTypes'
import { IframePostOfficeWindow } from '../windowTypes'
import { waitFor } from '../utils/promises'
import { iframePostOffice, PostMessageListener } from '../utils/postOffice'
import { MessageTypes, PostMessages, ExtractPayload } from '../messageTypes'
export default class Mailbox {
private handler?: BlockchainHandler
private constants: ConstantsType
private configuration?: PaywallConfig
private window: FetchWindow & SetTimeoutWindow & IframePostOfficeWindow
private postMessage: (
type: MessageTypes,
payload: ExtractPayload<MessageTypes>
) => void
private addPostMessageListener: (
type: string,
listener: PostMessageListener
) => void
private data?: BlockchainData
constructor(
constants: ConstantsType,
window: FetchWindow & SetTimeoutWindow & IframePostOfficeWindow
) {
this.constants = constants
this.window = window
const { postMessage, addHandler } = iframePostOffice(
this.window,
'data iframe'
)
this.postMessage = postMessage
this.addPostMessageListener = addHandler
}
async init() {
this.setupPostMessageListeners()
// lazy-loading the blockchain handler, this is essential to implement
// code splitting
const [
{
default: Web3ProxyProvider,
} /* import('../../providers/Web3ProxyProvider') */,
{
default: BlockchainHandlerClass,
} /* './blockchainHandler/BlockchainHandler' */,
{
walletService: walletServiceClass,
web3Service: web3ServiceClass,
} /* import('@unlock-protocol/unlock-js') */,
] = await Promise.all([
import('../providers/Web3ProxyProvider'),
import('./blockchainHandler/BlockchainHandler'),
import('@unlock-protocol/unlock-js'),
])
const web3Service = new web3ServiceClass(this.constants)
const walletService = new walletServiceClass(this.constants)
const provider = new Web3ProxyProvider(this.window)
await walletService.connect(provider)
await waitFor(this.configuration)
this.handler = new BlockchainHandlerClass({
web3Service,
walletService,
constants: this.constants,
configuration: this.configuration as PaywallConfig,
emitChanges: this.emitChanges,
emitError: this.emitError,
window: this.window,
})
}
setupPostMessageListeners() {
this.addPostMessageListener(PostMessages.CONFIG, this.setConfig)
this.addPostMessageListener(PostMessages.SEND_UPDATES, this.emitChanges)
this.addPostMessageListener(PostMessages.PURCHASE_KEY, this.purchaseKey)
}
setConfig(config: unknown) {
if (!isValidPaywallConfig(config)) {
this.emitError(
new Error('Invalid paywall configuration, cannot continue')
)
return
}
this.configuration = config as PaywallConfig
}
purchaseKey(details: PurchaseKeyRequest) {
if (!this.data || !this.handler) return
if (!this.data.locks[details.lock]) {
this.emitError(
new Error(`Cannot purchase key on unknown lock: "${details.lock}"`)
)
return
}
const lock = this.data.locks[details.lock]
this.handler.purchaseKey({
lockAddress: details.lock,
amountToSend: lock.keyPrice,
erc20Address: lock.currencyContractAddress,
})
}
emitChanges(data?: BlockchainData) {
if (data) {
this.data = data
}
if (!this.data) return
this.postMessage(PostMessages.UPDATE_ACCOUNT, this.data.account)
this.postMessage(PostMessages.UPDATE_ACCOUNT_BALANCE, this.data.balance)
this.postMessage(PostMessages.UPDATE_NETWORK, this.data.network)
this.postMessage(PostMessages.UPDATE_LOCKS, this.data.locks)
}
emitError(error: Error) {
if (process.env.UNLOCK_ENV === 'dev') {
console.error(error)
}
this.postMessage(PostMessages.ERROR, error.message)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment