Created
July 17, 2019 23:41
-
-
Save cellog/296b62111a5f00a830702f18c38c4b6a to your computer and use it in GitHub Desktop.
Data Iframe Mailbox
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
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