     @handshakeTimeout ?= DEFAULT_HANDSHAKE_TIMEOUT_MS
     @isListening = false
     @isLegacy = false # TODO: remove when native apps are updated
-    @hasParent = window? and window.self isnt window.top
+    isInAppBrowser = window._portalIsInAppBrowser
+    @hasParent = (window? and window.self isnt window.top) or isInAppBrowser
     @parent = window?.parent
 
     @client = new RPCClient({
       timeout: timeout
       postMessage: (msg, origin) =>
-        @parent?.postMessage msg, origin
+        if isInAppBrowser
+          queue = try
+            JSON.parse localStorage['portal:queue']
+          catch
+            null
+          queue ?= []
+          queue.push msg
+          localStorage['portal:queue'] = JSON.stringify queue
+        else
+          @parent?.postMessage msg, origin
     })
 
     useSw ?= navigator.serviceWorker and window.location.protocol isnt 'http:'

    @parent = parent
    @hasParent = true

  # Binds global message listener
  # Must be called before .call()
  listen: =>
    @isListening = true
    selfWindow.addEventListener 'message', @onMessage

    @clientValidation = @client.call 'ping', null, {timeout: @handshakeTimeout}
    .then (registeredMethods) =>

Promise = if Promise? then Promise else require 'promiz'
_map = require 'lodash/map'
_isEmpty = require 'lodash/isEmpty'

RPCClient = require './rpc_client'

