Hex Artifact Content
Not logged in

Artifact 2619482ec23d66f805f4382b92b9578f57c4fd78:


0000: 27 75 73 65 20 73 74 72 69 63 74 27 0a 0a 63 6f  'use strict'..co
0010: 6e 73 74 20 45 76 65 6e 74 45 6d 69 74 74 65 72  nst EventEmitter
0020: 32 20 3d 20 72 65 71 75 69 72 65 28 27 65 76 65  2 = require('eve
0030: 6e 74 65 6d 69 74 74 65 72 32 27 29 0a 63 6f 6e  ntemitter2').con
0040: 73 74 20 63 72 79 70 74 6f 20 3d 20 72 65 71 75  st crypto = requ
0050: 69 72 65 28 27 63 72 79 70 74 6f 27 29 0a 63 6f  ire('crypto').co
0060: 6e 73 74 20 62 61 73 65 36 34 75 72 6c 20 3d 20  nst base64url = 
0070: 72 65 71 75 69 72 65 28 27 62 61 73 65 36 34 75  require('base64u
0080: 72 6c 27 29 0a 63 6f 6e 73 74 20 69 6c 70 50 61  rl').const ilpPa
0090: 63 6b 65 74 20 3d 20 72 65 71 75 69 72 65 28 27  cket = require('
00a0: 69 6c 70 2d 70 61 63 6b 65 74 27 29 0a 63 6f 6e  ilp-packet').con
00b0: 73 74 20 64 65 62 75 67 20 3d 20 72 65 71 75 69  st debug = requi
00c0: 72 65 28 27 64 65 62 75 67 27 29 0a 63 6f 6e 73  re('debug').cons
00d0: 74 20 69 6e 74 36 34 20 3d 20 72 65 71 75 69 72  t int64 = requir
00e0: 65 28 27 2e 2e 2f 75 74 69 6c 2f 69 6e 74 36 34  e('../util/int64
00f0: 27 29 0a 0a 63 6f 6e 73 74 20 42 74 70 20 3d 20  ')..const Btp = 
0100: 72 65 71 75 69 72 65 28 27 62 74 70 2d 70 61 63  require('btp-pac
0110: 6b 65 74 27 29 0a 63 6f 6e 73 74 20 42 74 70 52  ket').const BtpR
0120: 70 63 20 3d 20 72 65 71 75 69 72 65 28 27 2e 2e  pc = require('..
0130: 2f 6d 6f 64 65 6c 2f 72 70 63 27 29 0a 63 6f 6e  /model/rpc').con
0140: 73 74 20 42 74 70 43 6c 69 65 6e 74 20 3d 20 72  st BtpClient = r
0150: 65 71 75 69 72 65 28 27 2e 2f 63 6c 69 65 6e 74  equire('./client
0160: 27 29 0a 63 6f 6e 73 74 20 42 74 70 4c 69 73 74  ').const BtpList
0170: 65 6e 65 72 20 3d 20 72 65 71 75 69 72 65 28 27  ener = require('
0180: 2e 2f 6c 69 73 74 65 6e 65 72 27 29 0a 63 6f 6e  ./listener').con
0190: 73 74 20 43 75 73 74 6f 6d 52 70 63 20 3d 20 72  st CustomRpc = r
01a0: 65 71 75 69 72 65 28 27 2e 2e 2f 6d 6f 64 65 6c  equire('../model
01b0: 2f 63 75 73 74 6f 6d 2d 72 70 63 27 29 0a 63 6f  /custom-rpc').co
01c0: 6e 73 74 20 56 61 6c 69 64 61 74 6f 72 20 3d 20  nst Validator = 
01d0: 72 65 71 75 69 72 65 28 27 2e 2e 2f 75 74 69 6c  require('../util
01e0: 2f 76 61 6c 69 64 61 74 6f 72 27 29 0a 63 6f 6e  /validator').con
01f0: 73 74 20 67 65 74 42 61 63 6b 65 6e 64 20 3d 20  st getBackend = 
0200: 72 65 71 75 69 72 65 28 27 2e 2e 2f 75 74 69 6c  require('../util
0210: 2f 62 61 63 6b 65 6e 64 27 29 0a 63 6f 6e 73 74  /backend').const
0220: 20 7b 20 70 72 6f 74 6f 63 6f 6c 44 61 74 61 54   { protocolDataT
0230: 6f 49 6c 70 41 6e 64 43 75 73 74 6f 6d 2c 20 69  oIlpAndCustom, i
0240: 6c 70 41 6e 64 43 75 73 74 6f 6d 54 6f 50 72 6f  lpAndCustomToPro
0250: 74 6f 63 6f 6c 44 61 74 61 20 7d 20 3d 0a 20 20  tocolData } =.  
0260: 72 65 71 75 69 72 65 28 27 2e 2e 2f 75 74 69 6c  require('../util
0270: 2f 70 72 6f 74 6f 63 6f 6c 44 61 74 61 43 6f 6e  /protocolDataCon
0280: 76 65 72 74 65 72 27 29 0a 0a 63 6f 6e 73 74 20  verter')..const 
0290: 65 72 72 6f 72 73 20 3d 20 72 65 71 75 69 72 65  errors = require
02a0: 28 27 2e 2e 2f 75 74 69 6c 2f 65 72 72 6f 72 73  ('../util/errors
02b0: 27 29 0a 63 6f 6e 73 74 20 4e 6f 74 41 63 63 65  ').const NotAcce
02c0: 70 74 65 64 45 72 72 6f 72 20 3d 20 65 72 72 6f  ptedError = erro
02d0: 72 73 2e 4e 6f 74 41 63 63 65 70 74 65 64 45 72  rs.NotAcceptedEr
02e0: 72 6f 72 0a 63 6f 6e 73 74 20 49 6e 76 61 6c 69  ror.const Invali
02f0: 64 46 69 65 6c 64 73 45 72 72 6f 72 20 3d 20 65  dFieldsError = e
0300: 72 72 6f 72 73 2e 49 6e 76 61 6c 69 64 46 69 65  rrors.InvalidFie
0310: 6c 64 73 45 72 72 6f 72 0a 63 6f 6e 73 74 20 41  ldsError.const A
0320: 6c 72 65 61 64 79 52 6f 6c 6c 65 64 42 61 63 6b  lreadyRolledBack
0330: 45 72 72 6f 72 20 3d 20 65 72 72 6f 72 73 2e 41  Error = errors.A
0340: 6c 72 65 61 64 79 52 6f 6c 6c 65 64 42 61 63 6b  lreadyRolledBack
0350: 45 72 72 6f 72 0a 63 6f 6e 73 74 20 41 6c 72 65  Error.const Alre
0360: 61 64 79 46 75 6c 66 69 6c 6c 65 64 45 72 72 6f  adyFulfilledErro
0370: 72 20 3d 20 65 72 72 6f 72 73 2e 41 6c 72 65 61  r = errors.Alrea
0380: 64 79 46 75 6c 66 69 6c 6c 65 64 45 72 72 6f 72  dyFulfilledError
0390: 0a 63 6f 6e 73 74 20 52 65 71 75 65 73 74 48 61  .const RequestHa
03a0: 6e 64 6c 65 72 41 6c 72 65 61 64 79 52 65 67 69  ndlerAlreadyRegi
03b0: 73 74 65 72 65 64 45 72 72 6f 72 20 3d 20 65 72  steredError = er
03c0: 72 6f 72 73 2e 52 65 71 75 65 73 74 48 61 6e 64  rors.RequestHand
03d0: 6c 65 72 41 6c 72 65 61 64 79 52 65 67 69 73 74  lerAlreadyRegist
03e0: 65 72 65 64 45 72 72 6f 72 0a 0a 2f 2f 20 54 4f  eredError..// TO
03f0: 44 4f 3a 20 57 68 61 74 20 73 68 6f 75 6c 64 20  DO: What should 
0400: 74 68 65 20 64 65 66 61 75 6c 74 20 70 6f 72 74  the default port
0410: 20 62 65 3f 0a 63 6f 6e 73 74 20 44 45 46 41 55   be?.const DEFAU
0420: 4c 54 5f 50 4f 52 54 20 3d 20 34 31 39 35 0a 0a  LT_PORT = 4195..
0430: 63 6f 6e 73 74 20 49 4e 46 4f 5f 52 45 51 55 45  const INFO_REQUE
0440: 53 54 5f 41 43 43 4f 55 4e 54 20 3d 20 30 20 2f  ST_ACCOUNT = 0 /
0450: 2f 20 65 73 6c 69 6e 74 2d 64 69 73 61 62 6c 65  / eslint-disable
0460: 2d 6c 69 6e 65 20 6e 6f 2d 75 6e 75 73 65 64 2d  -line no-unused-
0470: 76 61 72 73 0a 63 6f 6e 73 74 20 49 4e 46 4f 5f  vars.const INFO_
0480: 52 45 51 55 45 53 54 5f 46 55 4c 4c 20 3d 20 32  REQUEST_FULL = 2
0490: 0a 63 6f 6e 73 74 20 42 41 4c 41 4e 43 45 5f 52  .const BALANCE_R
04a0: 45 51 55 45 53 54 20 3d 20 30 0a 63 6f 6e 73 74  EQUEST = 0.const
04b0: 20 4c 49 4d 49 54 5f 52 45 51 55 45 53 54 20 3d   LIMIT_REQUEST =
04c0: 20 30 0a 0a 63 6f 6e 73 74 20 61 73 73 65 72 74   0..const assert
04d0: 4f 70 74 69 6f 6e 54 79 70 65 20 3d 20 28 6f 70  OptionType = (op
04e0: 74 73 2c 20 66 69 65 6c 64 2c 20 74 79 70 65 29  ts, field, type)
04f0: 20 3d 3e 20 7b 0a 20 20 63 6f 6e 73 74 20 76 61   => {.  const va
0500: 6c 20 3d 20 6f 70 74 73 5b 66 69 65 6c 64 5d 0a  l = opts[field].
0510: 20 20 2f 2f 20 65 73 6c 69 6e 74 2d 64 69 73 61    // eslint-disa
0520: 62 6c 65 2d 6e 65 78 74 2d 6c 69 6e 65 20 76 61  ble-next-line va
0530: 6c 69 64 2d 74 79 70 65 6f 66 0a 20 20 69 66 20  lid-typeof.  if 
0540: 28 21 76 61 6c 20 7c 7c 20 74 79 70 65 6f 66 20  (!val || typeof 
0550: 76 61 6c 20 21 3d 3d 20 74 79 70 65 29 20 7b 0a  val !== type) {.
0560: 20 20 20 20 74 68 72 6f 77 20 6e 65 77 20 49 6e      throw new In
0570: 76 61 6c 69 64 46 69 65 6c 64 73 45 72 72 6f 72  validFieldsError
0580: 28 27 69 6e 76 61 6c 69 64 20 22 27 20 2b 20 66  ('invalid "' + f
0590: 69 65 6c 64 20 2b 20 27 22 3b 20 67 6f 74 20 27  ield + '"; got '
05a0: 20 2b 20 76 61 6c 29 0a 20 20 7d 0a 7d 0a 0a 63   + val).  }.}..c
05b0: 6f 6e 73 74 20 6d 6f 64 75 6c 65 4e 61 6d 65 20  onst moduleName 
05c0: 3d 20 28 70 61 79 6d 65 6e 74 43 68 61 6e 6e 65  = (paymentChanne
05d0: 6c 42 61 63 6b 65 6e 64 2c 20 6f 70 74 73 29 20  lBackend, opts) 
05e0: 3d 3e 20 7b 0a 20 20 63 6f 6e 73 74 20 70 6c 75  => {.  const plu
05f0: 67 69 6e 4e 61 6d 65 20 3d 20 70 61 79 6d 65 6e  ginName = paymen
0600: 74 43 68 61 6e 6e 65 6c 42 61 63 6b 65 6e 64 2e  tChannelBackend.
0610: 70 6c 75 67 69 6e 4e 61 6d 65 0a 20 20 72 65 74  pluginName.  ret
0620: 75 72 6e 20 27 69 6c 70 2d 70 6c 75 67 69 6e 2d  urn 'ilp-plugin-
0630: 27 20 2b 20 70 6c 75 67 69 6e 4e 61 6d 65 2e 74  ' + pluginName.t
0640: 6f 4c 6f 77 65 72 43 61 73 65 28 29 20 2b 20 28  oLowerCase() + (
0650: 6f 70 74 73 2e 6c 69 73 74 65 6e 65 72 20 3f 20  opts.listener ? 
0660: 27 3a 73 65 72 76 65 72 27 20 3a 20 27 3a 63 6c  ':server' : ':cl
0670: 69 65 6e 74 27 29 0a 7d 0a 0a 6d 6f 64 75 6c 65  ient').}..module
0680: 2e 65 78 70 6f 72 74 73 20 3d 20 63 6c 61 73 73  .exports = class
0690: 20 50 6c 75 67 69 6e 50 61 79 6d 65 6e 74 43 68   PluginPaymentCh
06a0: 61 6e 6e 65 6c 20 65 78 74 65 6e 64 73 20 45 76  annel extends Ev
06b0: 65 6e 74 45 6d 69 74 74 65 72 32 20 7b 0a 20 20  entEmitter2 {.  
06c0: 63 6f 6e 73 74 72 75 63 74 6f 72 20 28 70 61 79  constructor (pay
06d0: 6d 65 6e 74 43 68 61 6e 6e 65 6c 42 61 63 6b 65  mentChannelBacke
06e0: 6e 64 2c 20 6f 70 74 73 29 20 7b 0a 20 20 20 20  nd, opts) {.    
06f0: 73 75 70 65 72 28 29 0a 20 20 20 20 63 6f 6e 73  super().    cons
0700: 74 20 42 61 63 6b 65 6e 64 20 3d 20 67 65 74 42  t Backend = getB
0710: 61 63 6b 65 6e 64 28 6f 70 74 73 2e 5f 73 74 6f  ackend(opts._sto
0720: 72 65 29 0a 0a 20 20 20 20 74 68 69 73 2e 5f 6f  re)..    this._o
0730: 70 74 73 20 3d 20 6f 70 74 73 0a 20 20 20 20 74  pts = opts.    t
0740: 68 69 73 2e 5f 73 74 61 74 65 66 75 6c 20 3d 20  his._stateful = 
0750: 21 21 28 6f 70 74 73 2e 5f 62 61 63 6b 65 6e 64  !!(opts._backend
0760: 20 7c 7c 20 6f 70 74 73 2e 5f 73 74 6f 72 65 29   || opts._store)
0770: 0a 20 20 20 20 74 68 69 73 2e 64 65 62 75 67 20  .    this.debug 
0780: 3d 20 70 61 79 6d 65 6e 74 43 68 61 6e 6e 65 6c  = paymentChannel
0790: 42 61 63 6b 65 6e 64 0a 20 20 20 20 20 20 3f 20  Backend.      ? 
07a0: 64 65 62 75 67 28 6d 6f 64 75 6c 65 4e 61 6d 65  debug(moduleName
07b0: 28 70 61 79 6d 65 6e 74 43 68 61 6e 6e 65 6c 42  (paymentChannelB
07c0: 61 63 6b 65 6e 64 2c 20 6f 70 74 73 29 29 0a 20  ackend, opts)). 
07d0: 20 20 20 20 20 3a 20 64 65 62 75 67 28 27 69 6c       : debug('il
07e0: 70 2d 70 6c 75 67 69 6e 2d 76 69 72 74 75 61 6c  p-plugin-virtual
07f0: 27 29 0a 0a 20 20 20 20 69 66 20 28 21 74 68 69  ')..    if (!thi
0800: 73 2e 5f 73 74 61 74 65 66 75 6c 20 26 26 20 70  s._stateful && p
0810: 61 79 6d 65 6e 74 43 68 61 6e 6e 65 6c 42 61 63  aymentChannelBac
0820: 6b 65 6e 64 29 20 7b 0a 20 20 20 20 20 20 74 68  kend) {.      th
0830: 72 6f 77 20 6e 65 77 20 45 72 72 6f 72 28 27 69  row new Error('i
0840: 66 20 74 68 65 20 70 6c 75 67 69 6e 20 69 73 20  f the plugin is 
0850: 73 74 61 74 65 6c 65 73 73 20 28 6e 6f 20 6f 70  stateless (no op
0860: 74 73 2e 5f 73 74 6f 72 65 20 6e 6f 72 20 27 20  ts._store nor ' 
0870: 2b 0a 20 20 20 20 20 20 20 20 27 6f 70 74 73 2e  +.        'opts.
0880: 5f 62 61 63 6b 65 6e 64 29 2c 20 74 68 65 6e 20  _backend), then 
0890: 61 20 70 61 79 6d 65 6e 74 20 63 68 61 6e 6e 65  a payment channe
08a0: 6c 20 62 61 63 6b 65 6e 64 20 63 61 6e 6e 6f 74  l backend cannot
08b0: 20 62 65 20 73 70 65 63 69 66 69 65 64 2e 27 29   be specified.')
08c0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 20 28  .    }..    if (
08d0: 74 68 69 73 2e 5f 73 74 61 74 65 66 75 6c 29 20  this._stateful) 
08e0: 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74 4f 70  {.      assertOp
08f0: 74 69 6f 6e 54 79 70 65 28 6f 70 74 73 2c 20 27  tionType(opts, '
0900: 6d 61 78 42 61 6c 61 6e 63 65 27 2c 20 27 73 74  maxBalance', 'st
0910: 72 69 6e 67 27 29 0a 20 20 20 20 20 20 69 66 20  ring').      if 
0920: 28 6f 70 74 73 2e 6d 69 6e 42 61 6c 61 6e 63 65  (opts.minBalance
0930: 29 20 61 73 73 65 72 74 4f 70 74 69 6f 6e 54 79  ) assertOptionTy
0940: 70 65 28 6f 70 74 73 2c 20 27 6d 69 6e 42 61 6c  pe(opts, 'minBal
0950: 61 6e 63 65 27 2c 20 27 73 74 72 69 6e 67 27 29  ance', 'string')
0960: 0a 0a 20 20 20 20 20 20 74 68 69 73 2e 5f 62 61  ..      this._ba
0970: 63 6b 65 6e 64 20 3d 20 6f 70 74 73 2e 5f 62 61  ckend = opts._ba
0980: 63 6b 65 6e 64 20 7c 7c 20 42 61 63 6b 65 6e 64  ckend || Backend
0990: 0a 20 20 20 20 20 20 74 68 69 73 2e 5f 6d 61 78  .      this._max
09a0: 42 61 6c 61 6e 63 65 20 3d 20 6f 70 74 73 2e 6d  Balance = opts.m
09b0: 61 78 42 61 6c 61 6e 63 65 0a 20 20 20 20 20 20  axBalance.      
09c0: 74 68 69 73 2e 5f 6d 69 6e 42 61 6c 61 6e 63 65  this._minBalance
09d0: 20 3d 20 6f 70 74 73 2e 6d 69 6e 42 61 6c 61 6e   = opts.minBalan
09e0: 63 65 0a 0a 20 20 20 20 20 20 74 68 69 73 2e 5f  ce..      this._
09f0: 74 72 61 6e 73 66 65 72 73 20 3d 20 74 68 69 73  transfers = this
0a00: 2e 5f 62 61 63 6b 65 6e 64 2e 67 65 74 54 72 61  ._backend.getTra
0a10: 6e 73 66 65 72 4c 6f 67 28 7b 0a 20 20 20 20 20  nsferLog({.     
0a20: 20 20 20 6d 61 78 69 6d 75 6d 3a 20 74 68 69 73     maximum: this
0a30: 2e 5f 6d 61 78 42 61 6c 61 6e 63 65 20 7c 7c 20  ._maxBalance || 
0a40: 27 49 6e 66 69 6e 69 74 79 27 2c 0a 20 20 20 20  'Infinity',.    
0a50: 20 20 20 20 6d 69 6e 69 6d 75 6d 3a 20 74 68 69      minimum: thi
0a60: 73 2e 5f 6d 69 6e 42 61 6c 61 6e 63 65 20 7c 7c  s._minBalance ||
0a70: 20 27 2d 49 6e 66 69 6e 69 74 79 27 2c 0a 20 20   '-Infinity',.  
0a80: 20 20 20 20 20 20 73 74 6f 72 65 3a 20 28 6f 70        store: (op
0a90: 74 73 2e 5f 62 61 63 6b 65 6e 64 20 3f 20 75 6e  ts._backend ? un
0aa0: 64 65 66 69 6e 65 64 20 3a 20 6f 70 74 73 2e 5f  defined : opts._
0ab0: 73 74 6f 72 65 29 0a 20 20 20 20 20 20 7d 29 0a  store).      }).
0ac0: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
0ad0: 20 20 20 74 68 69 73 2e 5f 74 72 61 6e 73 66 65     this._transfe
0ae0: 72 73 20 3d 20 42 61 63 6b 65 6e 64 2e 67 65 74  rs = Backend.get
0af0: 54 72 61 6e 73 66 65 72 4c 6f 67 28 7b 0a 20 20  TransferLog({.  
0b00: 20 20 20 20 20 20 6d 61 78 69 6d 75 6d 3a 20 27        maximum: '
0b10: 49 6e 66 69 6e 69 74 79 27 2c 0a 20 20 20 20 20  Infinity',.     
0b20: 20 20 20 6d 69 6e 69 6d 75 6d 3a 20 27 2d 49 6e     minimum: '-In
0b30: 66 69 6e 69 74 79 27 0a 20 20 20 20 20 20 7d 29  finity'.      })
0b40: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 74 68 69 73  .    }..    this
0b50: 2e 5f 63 6f 6e 6e 65 63 74 65 64 20 3d 20 66 61  ._connected = fa
0b60: 6c 73 65 0a 20 20 20 20 74 68 69 73 2e 5f 63 6f  lse.    this._co
0b70: 6e 6e 65 63 74 69 6e 67 20 3d 20 66 61 6c 73 65  nnecting = false
0b80: 0a 20 20 20 20 74 68 69 73 2e 5f 72 65 71 75 65  .    this._reque
0b90: 73 74 48 61 6e 64 6c 65 72 20 3d 20 6e 75 6c 6c  stHandler = null
0ba0: 0a 20 20 20 20 74 68 69 73 2e 5f 73 69 64 65 50  .    this._sideP
0bb0: 72 6f 74 6f 48 61 6e 64 6c 65 72 20 3d 20 7b 7d  rotoHandler = {}
0bc0: 0a 0a 20 20 20 20 69 66 20 28 6f 70 74 73 2e 73  ..    if (opts.s
0bd0: 65 72 76 65 72 29 20 7b 0a 20 20 20 20 20 20 61  erver) {.      a
0be0: 73 73 65 72 74 4f 70 74 69 6f 6e 54 79 70 65 28  ssertOptionType(
0bf0: 6f 70 74 73 2c 20 27 73 65 72 76 65 72 27 2c 20  opts, 'server', 
0c00: 27 73 74 72 69 6e 67 27 29 0a 20 20 20 20 20 20  'string').      
0c10: 74 68 69 73 2e 5f 63 6c 69 65 6e 74 20 3d 20 6e  this._client = n
0c20: 65 77 20 42 74 70 43 6c 69 65 6e 74 28 7b 0a 20  ew BtpClient({. 
0c30: 20 20 20 20 20 20 20 73 65 72 76 65 72 3a 20 6f         server: o
0c40: 70 74 73 2e 73 65 72 76 65 72 2c 0a 20 20 20 20  pts.server,.    
0c50: 20 20 20 20 70 6c 75 67 69 6e 3a 20 74 68 69 73      plugin: this
0c60: 0a 20 20 20 20 20 20 7d 29 0a 20 20 20 20 7d 20  .      }).    } 
0c70: 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 74 68 69  else {.      thi
0c80: 73 2e 5f 63 6c 69 65 6e 74 20 3d 20 6e 75 6c 6c  s._client = null
0c90: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 20 28  .    }..    if (
0ca0: 6f 70 74 73 2e 6c 69 73 74 65 6e 65 72 29 20 7b  opts.listener) {
0cb0: 0a 20 20 20 20 20 20 61 73 73 65 72 74 4f 70 74  .      assertOpt
0cc0: 69 6f 6e 54 79 70 65 28 6f 70 74 73 2c 20 27 6c  ionType(opts, 'l
0cd0: 69 73 74 65 6e 65 72 27 2c 20 27 6f 62 6a 65 63  istener', 'objec
0ce0: 74 27 29 0a 0a 20 20 20 20 20 20 74 68 69 73 2e  t')..      this.
0cf0: 5f 6c 69 73 74 65 6e 65 72 20 3d 20 6e 65 77 20  _listener = new 
0d00: 42 74 70 4c 69 73 74 65 6e 65 72 28 7b 0a 20 20  BtpListener({.  
0d10: 20 20 20 20 20 20 70 6c 75 67 69 6e 3a 20 74 68        plugin: th
0d20: 69 73 2c 0a 20 20 20 20 20 20 20 20 70 6f 72 74  is,.        port
0d30: 3a 20 6f 70 74 73 2e 6c 69 73 74 65 6e 65 72 2e  : opts.listener.
0d40: 70 6f 72 74 20 7c 7c 20 44 45 46 41 55 4c 54 5f  port || DEFAULT_
0d50: 50 4f 52 54 2c 0a 20 20 20 20 20 20 20 20 63 65  PORT,.        ce
0d60: 72 74 3a 20 6f 70 74 73 2e 6c 69 73 74 65 6e 65  rt: opts.listene
0d70: 72 2e 63 65 72 74 2c 0a 20 20 20 20 20 20 20 20  r.cert,.        
0d80: 6b 65 79 3a 20 6f 70 74 73 2e 6c 69 73 74 65 6e  key: opts.listen
0d90: 65 72 2e 6b 65 79 2c 0a 20 20 20 20 20 20 20 20  er.key,.        
0da0: 63 61 3a 20 6f 70 74 73 2e 6c 69 73 74 65 6e 65  ca: opts.listene
0db0: 72 2e 63 61 0a 20 20 20 20 20 20 7d 29 0a 20 20  r.ca.      }).  
0dc0: 20 20 20 20 74 68 69 73 2e 5f 6c 69 73 74 65 6e      this._listen
0dd0: 65 72 2e 6c 69 73 74 65 6e 28 29 2e 63 61 74 63  er.listen().catc
0de0: 68 28 28 65 72 72 29 20 3d 3e 20 7b 0a 20 20 20  h((err) => {.   
0df0: 20 20 20 20 20 64 65 62 75 67 28 27 46 61 69 6c       debug('Fail
0e00: 65 64 20 73 74 61 72 74 69 6e 67 20 77 65 62 73  ed starting webs
0e10: 6f 63 6b 65 74 20 73 65 72 76 65 72 27 2c 20 65  ocket server', e
0e20: 72 72 29 0a 20 20 20 20 20 20 7d 29 0a 20 20 20  rr).      }).   
0e30: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20   } else {.      
0e40: 74 68 69 73 2e 5f 6c 69 73 74 65 6e 65 72 20 3d  this._listener =
0e50: 20 6e 75 6c 6c 0a 20 20 20 20 7d 0a 0a 20 20 20   null.    }..   
0e60: 20 2f 2f 20 72 65 67 69 73 74 65 72 20 52 50 43   // register RPC
0e70: 20 6d 65 74 68 6f 64 73 0a 20 20 20 20 74 68 69   methods.    thi
0e80: 73 2e 5f 72 70 63 20 3d 20 6e 65 77 20 42 74 70  s._rpc = new Btp
0e90: 52 70 63 28 7b 0a 20 20 20 20 20 20 70 6c 75 67  Rpc({.      plug
0ea0: 69 6e 3a 20 74 68 69 73 2c 0a 20 20 20 20 20 20  in: this,.      
0eb0: 64 65 62 75 67 3a 20 74 68 69 73 2e 64 65 62 75  debug: this.debu
0ec0: 67 2c 0a 20 20 20 20 20 20 63 6c 69 65 6e 74 3a  g,.      client:
0ed0: 20 74 68 69 73 2e 5f 63 6c 69 65 6e 74 2c 0a 20   this._client,. 
0ee0: 20 20 20 20 20 68 61 6e 64 6c 65 72 73 3a 20 7b       handlers: {
0ef0: 0a 20 20 20 20 20 20 20 20 5b 42 74 70 2e 54 59  .        [Btp.TY
0f00: 50 45 5f 50 52 45 50 41 52 45 5d 3a 20 74 68 69  PE_PREPARE]: thi
0f10: 73 2e 5f 68 61 6e 64 6c 65 54 72 61 6e 73 66 65  s._handleTransfe
0f20: 72 2e 62 69 6e 64 28 74 68 69 73 29 2c 0a 20 20  r.bind(this),.  
0f30: 20 20 20 20 20 20 5b 42 74 70 2e 54 59 50 45 5f        [Btp.TYPE_
0f40: 46 55 4c 46 49 4c 4c 5d 3a 20 74 68 69 73 2e 5f  FULFILL]: this._
0f50: 68 61 6e 64 6c 65 46 75 6c 66 69 6c 6c 43 6f 6e  handleFulfillCon
0f60: 64 69 74 69 6f 6e 2e 62 69 6e 64 28 74 68 69 73  dition.bind(this
0f70: 29 2c 0a 20 20 20 20 20 20 20 20 5b 42 74 70 2e  ),.        [Btp.
0f80: 54 59 50 45 5f 52 45 4a 45 43 54 5d 3a 20 74 68  TYPE_REJECT]: th
0f90: 69 73 2e 5f 68 61 6e 64 6c 65 52 65 6a 65 63 74  is._handleReject
0fa0: 49 6e 63 6f 6d 69 6e 67 54 72 61 6e 73 66 65 72  IncomingTransfer
0fb0: 2e 62 69 6e 64 28 74 68 69 73 29 2c 0a 20 20 20  .bind(this),.   
0fc0: 20 20 20 20 20 5b 42 74 70 2e 54 59 50 45 5f 4d       [Btp.TYPE_M
0fd0: 45 53 53 41 47 45 5d 3a 20 74 68 69 73 2e 5f 68  ESSAGE]: this._h
0fe0: 61 6e 64 6c 65 52 65 71 75 65 73 74 2e 62 69 6e  andleRequest.bin
0ff0: 64 28 74 68 69 73 29 0a 20 20 20 20 20 20 7d 2c  d(this).      },
1000: 0a 20 20 20 20 20 20 2f 2f 20 63 68 65 63 6b 73  .      // checks
1010: 20 74 68 65 20 74 6f 6b 65 6e 20 77 69 74 68 20   the token with 
1020: 77 68 69 63 68 20 69 6e 63 6f 6d 69 6e 67 20 73  which incoming s
1030: 6f 63 6b 65 74 73 20 61 72 65 20 61 75 74 68 65  ockets are authe
1040: 6e 74 69 63 61 74 65 64 2e 20 49 66 20 74 68 65  nticated. If the
1050: 72 65 0a 20 20 20 20 20 20 2f 2f 20 69 73 20 6e  re.      // is n
1060: 6f 20 6c 69 73 74 65 6e 65 72 2c 20 61 6e 64 20  o listener, and 
1070: 61 64 64 53 6f 63 6b 65 74 20 77 69 6c 6c 20 6e  addSocket will n
1080: 6f 74 20 62 65 20 63 61 6c 6c 65 64 20 66 6f 72  ot be called for
1090: 20 69 6e 63 6f 6d 69 6e 67 0a 20 20 20 20 20 20   incoming.      
10a0: 2f 2f 20 42 54 50 20 63 6f 6e 6e 65 63 74 69 6f  // BTP connectio
10b0: 6e 73 2c 20 74 68 65 6e 20 74 68 69 73 20 61 72  ns, then this ar
10c0: 67 75 6d 65 6e 74 20 69 73 20 75 6e 6e 65 63 65  gument is unnece
10d0: 73 73 61 72 79 2e 0a 20 20 20 20 20 20 61 75 74  ssary..      aut
10e0: 68 43 68 65 63 6b 3a 20 28 6f 70 74 73 2e 61 75  hCheck: (opts.au
10f0: 74 68 43 68 65 63 6b 20 7c 7c 20 66 75 6e 63 74  thCheck || funct
1100: 69 6f 6e 20 28 75 73 65 72 6e 61 6d 65 2c 20 74  ion (username, t
1110: 6f 6b 65 6e 29 20 7b 0a 20 20 20 20 20 20 20 20  oken) {.        
1120: 72 65 74 75 72 6e 20 28 75 73 65 72 6e 61 6d 65  return (username
1130: 20 3d 3d 3d 20 27 27 20 26 26 20 74 6f 6b 65 6e   === '' && token
1140: 20 3d 3d 3d 20 6f 70 74 73 2e 69 6e 63 6f 6d 69   === opts.incomi
1150: 6e 67 53 65 63 72 65 74 29 0a 20 20 20 20 20 20  ngSecret).      
1160: 7d 29 0a 20 20 20 20 7d 29 0a 0a 20 20 20 20 69  }).    })..    i
1170: 66 20 28 21 6f 70 74 73 2e 73 65 72 76 65 72 20  f (!opts.server 
1180: 26 26 20 21 28 6f 70 74 73 2e 70 72 65 66 69 78  && !(opts.prefix
1190: 20 26 26 20 6f 70 74 73 2e 69 6e 66 6f 29 29 20   && opts.info)) 
11a0: 7b 0a 20 20 20 20 20 20 74 68 72 6f 77 20 6e 65  {.      throw ne
11b0: 77 20 45 72 72 6f 72 28 27 77 68 65 6e 20 72 75  w Error('when ru
11c0: 6e 6e 69 6e 67 20 69 6e 20 73 65 72 76 65 72 20  nning in server 
11d0: 6d 6f 64 65 2c 20 74 68 65 20 5c 27 70 72 65 66  mode, the \'pref
11e0: 69 78 5c 27 20 61 6e 64 20 5c 27 69 6e 66 6f 5c  ix\' and \'info\
11f0: 27 20 63 6f 6e 66 69 67 20 70 61 72 61 6d 65 74  ' config paramet
1200: 65 72 73 20 61 72 65 20 72 65 71 75 69 72 65 64  ers are required
1210: 27 29 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66  ').    }..    if
1220: 20 28 74 68 69 73 2e 5f 73 74 61 74 65 66 75 6c   (this._stateful
1230: 20 26 26 20 70 61 79 6d 65 6e 74 43 68 61 6e 6e   && paymentChann
1240: 65 6c 42 61 63 6b 65 6e 64 29 20 7b 0a 20 20 20  elBackend) {.   
1250: 20 20 20 56 61 6c 69 64 61 74 6f 72 2e 76 61 6c     Validator.val
1260: 69 64 61 74 65 50 61 79 6d 65 6e 74 43 68 61 6e  idatePaymentChan
1270: 6e 65 6c 42 61 63 6b 65 6e 64 28 70 61 79 6d 65  nelBackend(payme
1280: 6e 74 43 68 61 6e 6e 65 6c 42 61 63 6b 65 6e 64  ntChannelBackend
1290: 29 0a 0a 20 20 20 20 20 20 74 68 69 73 2e 5f 70  )..      this._p
12a0: 61 79 63 68 61 6e 20 3d 20 70 61 79 6d 65 6e 74  aychan = payment
12b0: 43 68 61 6e 6e 65 6c 42 61 63 6b 65 6e 64 20 7c  ChannelBackend |
12c0: 7c 20 7b 7d 0a 20 20 20 20 20 20 74 68 69 73 2e  | {}.      this.
12d0: 5f 70 61 79 63 68 61 6e 43 6f 6e 74 65 78 74 20  _paychanContext 
12e0: 3d 20 7b 0a 20 20 20 20 20 20 20 20 73 74 61 74  = {.        stat
12f0: 65 3a 20 7b 7d 2c 0a 20 20 20 20 20 20 20 20 72  e: {},.        r
1300: 70 63 3a 20 6e 65 77 20 43 75 73 74 6f 6d 52 70  pc: new CustomRp
1310: 63 28 7b 20 62 74 70 52 70 63 3a 20 74 68 69 73  c({ btpRpc: this
1320: 2e 5f 72 70 63 20 7d 29 2c 0a 20 20 20 20 20 20  ._rpc }),.      
1330: 20 20 62 74 70 52 70 63 3a 20 74 68 69 73 2e 5f    btpRpc: this._
1340: 72 70 63 2c 0a 20 20 20 20 20 20 20 20 62 61 63  rpc,.        bac
1350: 6b 65 6e 64 3a 20 74 68 69 73 2e 5f 62 61 63 6b  kend: this._back
1360: 65 6e 64 2c 0a 20 20 20 20 20 20 20 20 74 72 61  end,.        tra
1370: 6e 73 66 65 72 4c 6f 67 3a 20 74 68 69 73 2e 5f  nsferLog: this._
1380: 74 72 61 6e 73 66 65 72 73 2c 0a 20 20 20 20 20  transfers,.     
1390: 20 20 20 70 6c 75 67 69 6e 3a 20 74 68 69 73 0a     plugin: this.
13a0: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 74        }..      t
13b0: 68 69 73 2e 5f 70 61 79 63 68 61 6e 2e 63 6f 6e  his._paychan.con
13c0: 73 74 72 75 63 74 6f 72 28 74 68 69 73 2e 5f 70  structor(this._p
13d0: 61 79 63 68 61 6e 43 6f 6e 74 65 78 74 2c 20 6f  aychanContext, o
13e0: 70 74 73 29 0a 20 20 20 20 20 20 74 68 69 73 2e  pts).      this.
13f0: 67 65 74 49 6e 66 6f 20 3d 20 28 29 20 3d 3e 20  getInfo = () => 
1400: 4a 53 4f 4e 2e 70 61 72 73 65 28 4a 53 4f 4e 2e  JSON.parse(JSON.
1410: 73 74 72 69 6e 67 69 66 79 28 74 68 69 73 2e 5f  stringify(this._
1420: 70 61 79 63 68 61 6e 2e 67 65 74 49 6e 66 6f 28  paychan.getInfo(
1430: 74 68 69 73 2e 5f 70 61 79 63 68 61 6e 43 6f 6e  this._paychanCon
1440: 74 65 78 74 29 29 29 0a 20 20 20 20 20 20 74 68  text))).      th
1450: 69 73 2e 5f 70 72 65 66 69 78 20 3d 20 6f 70 74  is._prefix = opt
1460: 73 2e 70 72 65 66 69 78 0a 20 20 20 20 20 20 74  s.prefix.      t
1470: 68 69 73 2e 5f 69 6e 66 6f 20 3d 20 74 68 69 73  his._info = this
1480: 2e 67 65 74 49 6e 66 6f 28 29 0a 0a 20 20 20 20  .getInfo()..    
1490: 20 20 74 68 69 73 2e 67 65 74 41 63 63 6f 75 6e    this.getAccoun
14a0: 74 20 3d 20 28 29 20 3d 3e 20 74 68 69 73 2e 5f  t = () => this._
14b0: 70 61 79 63 68 61 6e 2e 67 65 74 41 63 63 6f 75  paychan.getAccou
14c0: 6e 74 28 74 68 69 73 2e 5f 70 61 79 63 68 61 6e  nt(this._paychan
14d0: 43 6f 6e 74 65 78 74 29 0a 20 20 20 20 20 20 74  Context).      t
14e0: 68 69 73 2e 67 65 74 50 65 65 72 41 63 63 6f 75  his.getPeerAccou
14f0: 6e 74 20 3d 20 28 29 20 3d 3e 20 74 68 69 73 2e  nt = () => this.
1500: 5f 70 61 79 63 68 61 6e 2e 67 65 74 50 65 65 72  _paychan.getPeer
1510: 41 63 63 6f 75 6e 74 28 74 68 69 73 2e 5f 70 61  Account(this._pa
1520: 79 63 68 61 6e 43 6f 6e 74 65 78 74 29 0a 20 20  ychanContext).  
1530: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20    } else {.     
1540: 20 74 68 69 73 2e 5f 69 6e 66 6f 20 3d 20 6f 70   this._info = op
1550: 74 73 2e 69 6e 66 6f 20 7c 7c 20 6e 75 6c 6c 0a  ts.info || null.
1560: 20 20 20 20 20 20 69 66 20 28 74 68 69 73 2e 5f        if (this._
1570: 69 6e 66 6f 29 20 7b 0a 20 20 20 20 20 20 20 20  info) {.        
1580: 2f 2f 20 61 75 74 6f 66 69 6c 6c 20 70 72 65 66  // autofill pref
1590: 69 78 20 66 72 6f 6d 20 6f 70 74 73 20 69 66 20  ix from opts if 
15a0: 69 6e 66 6f 20 69 73 20 73 70 65 63 69 66 69 65  info is specifie
15b0: 64 20 61 6e 64 20 64 6f 65 73 20 6e 6f 74 20 69  d and does not i
15c0: 6e 63 6c 75 64 65 20 70 72 65 66 69 78 0a 20 20  nclude prefix.  
15d0: 20 20 20 20 20 20 74 68 69 73 2e 5f 69 6e 66 6f        this._info
15e0: 2e 70 72 65 66 69 78 20 3d 20 74 68 69 73 2e 5f  .prefix = this._
15f0: 69 6e 66 6f 2e 70 72 65 66 69 78 20 7c 7c 20 6f  info.prefix || o
1600: 70 74 73 2e 70 72 65 66 69 78 0a 20 20 20 20 20  pts.prefix.     
1610: 20 7d 0a 0a 20 20 20 20 20 20 74 68 69 73 2e 5f   }..      this._
1620: 70 65 65 72 41 63 63 6f 75 6e 74 4e 61 6d 65 20  peerAccountName 
1630: 3d 20 74 68 69 73 2e 5f 73 74 61 74 65 66 75 6c  = this._stateful
1640: 20 3f 20 27 63 6c 69 65 6e 74 27 20 3a 20 27 73   ? 'client' : 's
1650: 65 72 76 65 72 27 0a 20 20 20 20 20 20 74 68 69  erver'.      thi
1660: 73 2e 5f 61 63 63 6f 75 6e 74 4e 61 6d 65 20 3d  s._accountName =
1670: 20 74 68 69 73 2e 5f 73 74 61 74 65 66 75 6c 20   this._stateful 
1680: 3f 20 27 73 65 72 76 65 72 27 20 3a 20 27 63 6c  ? 'server' : 'cl
1690: 69 65 6e 74 27 0a 20 20 20 20 20 20 74 68 69 73  ient'.      this
16a0: 2e 5f 70 72 65 66 69 78 20 3d 20 6f 70 74 73 2e  ._prefix = opts.
16b0: 70 72 65 66 69 78 0a 0a 20 20 20 20 20 20 2f 2f  prefix..      //
16c0: 20 70 61 79 6d 65 6e 74 20 63 68 61 6e 6e 65 6c   payment channel
16d0: 73 20 61 72 65 6e 27 74 20 75 73 65 64 20 69 6e  s aren't used in
16e0: 20 74 68 65 20 61 73 79 6d 6d 65 74 72 69 63 20   the asymmetric 
16f0: 63 61 73 65 20 73 6f 20 69 74 27 73 20 73 74 75  case so it's stu
1700: 62 62 65 64 20 6f 75 74 0a 20 20 20 20 20 20 74  bbed out.      t
1710: 68 69 73 2e 5f 70 61 79 63 68 61 6e 43 6f 6e 74  his._paychanCont
1720: 65 78 74 20 3d 20 7b 7d 0a 20 20 20 20 20 20 74  ext = {}.      t
1730: 68 69 73 2e 5f 70 61 79 63 68 61 6e 20 3d 20 7b  his._paychan = {
1740: 0a 20 20 20 20 20 20 20 20 63 6f 6e 6e 65 63 74  .        connect
1750: 3a 20 28 29 20 3d 3e 20 50 72 6f 6d 69 73 65 2e  : () => Promise.
1760: 72 65 73 6f 6c 76 65 28 29 2c 0a 20 20 20 20 20  resolve(),.     
1770: 20 20 20 64 69 73 63 6f 6e 6e 65 63 74 3a 20 28     disconnect: (
1780: 29 20 3d 3e 20 50 72 6f 6d 69 73 65 2e 72 65 73  ) => Promise.res
1790: 6f 6c 76 65 28 29 2c 0a 20 20 20 20 20 20 20 20  olve(),.        
17a0: 68 61 6e 64 6c 65 49 6e 63 6f 6d 69 6e 67 50 72  handleIncomingPr
17b0: 65 70 61 72 65 3a 20 28 29 20 3d 3e 20 50 72 6f  epare: () => Pro
17c0: 6d 69 73 65 2e 72 65 73 6f 6c 76 65 28 29 2c 0a  mise.resolve(),.
17d0: 20 20 20 20 20 20 20 20 63 72 65 61 74 65 4f 75          createOu
17e0: 74 67 6f 69 6e 67 43 6c 61 69 6d 3a 20 28 29 20  tgoingClaim: () 
17f0: 3d 3e 20 50 72 6f 6d 69 73 65 2e 72 65 73 6f 6c  => Promise.resol
1800: 76 65 28 29 2c 0a 20 20 20 20 20 20 20 20 68 61  ve(),.        ha
1810: 6e 64 6c 65 49 6e 63 6f 6d 69 6e 67 43 6c 61 69  ndleIncomingClai
1820: 6d 3a 20 28 29 20 3d 3e 20 50 72 6f 6d 69 73 65  m: () => Promise
1830: 2e 72 65 73 6f 6c 76 65 28 29 0a 20 20 20 20 20  .resolve().     
1840: 20 7d 0a 0a 20 20 20 20 20 20 74 68 69 73 2e 67   }..      this.g
1850: 65 74 49 6e 66 6f 20 3d 20 28 29 20 3d 3e 20 74  etInfo = () => t
1860: 68 69 73 2e 5f 69 6e 66 6f 20 26 26 20 4a 53 4f  his._info && JSO
1870: 4e 2e 70 61 72 73 65 28 4a 53 4f 4e 2e 73 74 72  N.parse(JSON.str
1880: 69 6e 67 69 66 79 28 74 68 69 73 2e 5f 69 6e 66  ingify(this._inf
1890: 6f 29 29 0a 20 20 20 20 20 20 74 68 69 73 2e 67  o)).      this.g
18a0: 65 74 41 63 63 6f 75 6e 74 20 3d 20 28 29 20 3d  etAccount = () =
18b0: 3e 20 28 74 68 69 73 2e 5f 70 72 65 66 69 78 20  > (this._prefix 
18c0: 2b 20 74 68 69 73 2e 5f 61 63 63 6f 75 6e 74 4e  + this._accountN
18d0: 61 6d 65 29 0a 20 20 20 20 20 20 74 68 69 73 2e  ame).      this.
18e0: 67 65 74 50 65 65 72 41 63 63 6f 75 6e 74 20 3d  getPeerAccount =
18f0: 20 28 29 20 3d 3e 20 28 74 68 69 73 2e 5f 70 72   () => (this._pr
1900: 65 66 69 78 20 2b 20 74 68 69 73 2e 5f 70 65 65  efix + this._pee
1910: 72 41 63 63 6f 75 6e 74 4e 61 6d 65 29 0a 20 20  rAccountName).  
1920: 20 20 7d 0a 0a 20 20 20 20 74 68 69 73 2e 61 64    }..    this.ad
1930: 64 53 6f 63 6b 65 74 20 3d 20 74 68 69 73 2e 5f  dSocket = this._
1940: 72 70 63 2e 61 64 64 53 6f 63 6b 65 74 2e 62 69  rpc.addSocket.bi
1950: 6e 64 28 74 68 69 73 2e 5f 72 70 63 29 0a 20 20  nd(this._rpc).  
1960: 20 20 2f 2f 20 74 68 69 73 2e 72 65 63 65 69 76    // this.receiv
1970: 65 20 3d 20 74 68 69 73 2e 5f 72 70 63 2e 68 61  e = this._rpc.ha
1980: 6e 64 6c 65 4d 65 73 73 61 67 65 2e 62 69 6e 64  ndleMessage.bind
1990: 28 74 68 69 73 2e 5f 72 70 63 29 0a 20 20 20 20  (this._rpc).    
19a0: 74 68 69 73 2e 69 73 43 6f 6e 6e 65 63 74 65 64  this.isConnected
19b0: 20 3d 20 28 29 20 3d 3e 20 74 68 69 73 2e 5f 63   = () => this._c
19c0: 6f 6e 6e 65 63 74 65 64 0a 20 20 7d 0a 0a 20 20  onnected.  }..  
19d0: 2f 2f 20 64 6f 6e 27 74 20 74 68 72 6f 77 20 65  // don't throw e
19e0: 72 72 6f 72 73 20 65 76 65 6e 20 69 66 20 74 68  rrors even if th
19f0: 65 20 65 76 65 6e 74 20 68 61 6e 64 6c 65 72 20  e event handler 
1a00: 74 68 72 6f 77 73 0a 20 20 2f 2f 20 74 68 69 73  throws.  // this
1a10: 20 69 73 20 65 73 70 65 63 69 61 6c 6c 79 20 69   is especially i
1a20: 6d 70 6f 72 74 61 6e 74 20 69 6e 20 70 6c 75 67  mportant in plug
1a30: 69 6e 20 76 69 72 74 75 61 6c 20 62 65 63 61 75  in virtual becau
1a40: 73 65 0a 20 20 2f 2f 20 65 72 72 6f 72 73 20 63  se.  // errors c
1a50: 61 6e 20 70 72 65 76 65 6e 74 20 74 68 65 20 62  an prevent the b
1a60: 61 6c 61 6e 63 65 20 66 72 6f 6d 20 62 65 69 6e  alance from bein
1a70: 67 20 75 70 64 61 74 65 64 20 63 6f 72 72 65 63  g updated correc
1a80: 74 6c 79 0a 20 20 5f 73 61 66 65 45 6d 69 74 20  tly.  _safeEmit 
1a90: 28 29 20 7b 0a 20 20 20 20 74 72 79 20 7b 0a 20  () {.    try {. 
1aa0: 20 20 20 20 20 74 68 69 73 2e 65 6d 69 74 2e 61       this.emit.a
1ab0: 70 70 6c 79 28 74 68 69 73 2c 20 61 72 67 75 6d  pply(this, argum
1ac0: 65 6e 74 73 29 0a 20 20 20 20 7d 20 63 61 74 63  ents).    } catc
1ad0: 68 20 28 65 72 72 29 20 7b 0a 20 20 20 20 20 20  h (err) {.      
1ae0: 74 68 69 73 2e 64 65 62 75 67 28 27 65 72 72 6f  this.debug('erro
1af0: 72 20 69 6e 20 68 61 6e 64 6c 65 72 20 66 6f 72  r in handler for
1b00: 20 65 76 65 6e 74 27 2c 20 61 72 67 75 6d 65 6e   event', argumen
1b10: 74 73 2c 20 65 72 72 29 0a 20 20 20 20 7d 0a 20  ts, err).    }. 
1b20: 20 7d 0a 0a 20 20 2f 2f 20 54 4f 44 4f 3a 20 54   }..  // TODO: T
1b30: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 73 68 6f  his function sho
1b40: 75 6c 64 20 62 65 20 64 65 70 63 72 65 63 61 74  uld be depcrecat
1b50: 65 64 20 66 72 6f 6d 20 52 46 43 2d 30 30 30 34  ed from RFC-0004
1b60: 2e 20 49 6e 73 74 65 61 64 20 77 65 20 73 68 6f  . Instead we sho
1b70: 75 6c 64 0a 20 20 2f 2f 20 75 73 65 20 72 65 67  uld.  // use reg
1b80: 69 73 74 65 72 53 69 64 65 50 72 6f 74 6f 63 6f  isterSideProtoco
1b90: 6c 48 61 6e 64 6c 65 72 2e 20 28 40 73 68 61 72  lHandler. (@shar
1ba0: 61 66 69 61 6e 29 0a 20 20 72 65 67 69 73 74 65  afian).  registe
1bb0: 72 52 65 71 75 65 73 74 48 61 6e 64 6c 65 72 20  rRequestHandler 
1bc0: 28 68 61 6e 64 6c 65 72 29 20 7b 0a 20 20 20 20  (handler) {.    
1bd0: 69 66 20 28 74 68 69 73 2e 5f 72 65 71 75 65 73  if (this._reques
1be0: 74 48 61 6e 64 6c 65 72 29 20 7b 0a 20 20 20 20  tHandler) {.    
1bf0: 20 20 74 68 72 6f 77 20 6e 65 77 20 52 65 71 75    throw new Requ
1c00: 65 73 74 48 61 6e 64 6c 65 72 41 6c 72 65 61 64  estHandlerAlread
1c10: 79 52 65 67 69 73 74 65 72 65 64 45 72 72 6f 72  yRegisteredError
1c20: 28 27 72 65 71 75 65 73 74 48 61 6e 64 6c 65 72  ('requestHandler
1c30: 20 69 73 20 61 6c 72 65 61 64 79 20 72 65 67 69   is already regi
1c40: 73 74 65 72 65 64 27 29 0a 20 20 20 20 7d 0a 0a  stered').    }..
1c50: 20 20 20 20 69 66 20 28 74 79 70 65 6f 66 20 68      if (typeof h
1c60: 61 6e 64 6c 65 72 20 21 3d 3d 20 27 66 75 6e 63  andler !== 'func
1c70: 74 69 6f 6e 27 29 20 7b 0a 20 20 20 20 20 20 74  tion') {.      t
1c80: 68 72 6f 77 20 6e 65 77 20 49 6e 76 61 6c 69 64  hrow new Invalid
1c90: 46 69 65 6c 64 73 45 72 72 6f 72 28 27 72 65 71  FieldsError('req
1ca0: 75 65 73 74 48 61 6e 64 6c 65 72 20 6d 75 73 74  uestHandler must
1cb0: 20 62 65 20 61 20 66 75 6e 63 74 69 6f 6e 27 29   be a function')
1cc0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 74 68 69 73  .    }..    this
1cd0: 2e 5f 72 65 71 75 65 73 74 48 61 6e 64 6c 65 72  ._requestHandler
1ce0: 20 3d 20 68 61 6e 64 6c 65 72 0a 20 20 7d 0a 0a   = handler.  }..
1cf0: 20 20 64 65 72 65 67 69 73 74 65 72 52 65 71 75    deregisterRequ
1d00: 65 73 74 48 61 6e 64 6c 65 72 20 28 29 20 7b 0a  estHandler () {.
1d10: 20 20 20 20 74 68 69 73 2e 5f 72 65 71 75 65 73      this._reques
1d20: 74 48 61 6e 64 6c 65 72 20 3d 20 6e 75 6c 6c 0a  tHandler = null.
1d30: 20 20 7d 0a 0a 20 20 61 73 79 6e 63 20 63 6f 6e    }..  async con
1d40: 6e 65 63 74 20 28 29 20 7b 0a 20 20 20 20 69 66  nect () {.    if
1d50: 20 28 74 68 69 73 2e 5f 63 6f 6e 6e 65 63 74 65   (this._connecte
1d60: 64 29 20 72 65 74 75 72 6e 0a 20 20 20 20 69 66  d) return.    if
1d70: 20 28 74 68 69 73 2e 5f 63 6f 6e 6e 65 63 74 69   (this._connecti
1d80: 6e 67 29 20 72 65 74 75 72 6e 20 74 68 69 73 2e  ng) return this.
1d90: 5f 63 6f 6e 6e 65 63 74 50 72 6f 6d 69 73 65 0a  _connectPromise.
1da0: 20 20 20 20 74 68 69 73 2e 5f 63 6f 6e 6e 65 63      this._connec
1db0: 74 69 6e 67 20 3d 20 74 72 75 65 0a 0a 20 20 20  ting = true..   
1dc0: 20 6c 65 74 20 66 69 6e 69 73 68 43 6f 6e 6e 65   let finishConne
1dd0: 63 74 50 72 6f 6d 69 73 65 0a 20 20 20 20 74 68  ctPromise.    th
1de0: 69 73 2e 5f 63 6f 6e 6e 65 63 74 50 72 6f 6d 69  is._connectPromi
1df0: 73 65 20 3d 20 6e 65 77 20 50 72 6f 6d 69 73 65  se = new Promise
1e00: 28 28 72 65 73 6f 6c 76 65 29 20 3d 3e 20 7b 0a  ((resolve) => {.
1e10: 20 20 20 20 20 20 66 69 6e 69 73 68 43 6f 6e 6e        finishConn
1e20: 65 63 74 50 72 6f 6d 69 73 65 20 3d 20 72 65 73  ectPromise = res
1e30: 6f 6c 76 65 0a 20 20 20 20 7d 29 0a 0a 20 20 20  olve.    })..   
1e40: 20 74 72 79 20 7b 0a 20 20 20 20 20 20 69 66 20   try {.      if 
1e50: 28 21 28 74 68 69 73 2e 5f 69 6e 66 6f 20 26 26  (!(this._info &&
1e60: 20 74 68 69 73 2e 5f 70 72 65 66 69 78 29 29 20   this._prefix)) 
1e70: 7b 0a 20 20 20 20 20 20 20 20 74 68 69 73 2e 64  {.        this.d
1e80: 65 62 75 67 28 27 69 6e 66 6f 20 6e 6f 74 20 61  ebug('info not a
1e90: 76 61 69 6c 61 62 6c 65 20 6c 6f 63 61 6c 6c 79  vailable locally
1ea0: 2c 20 6c 6f 61 64 69 6e 67 20 72 65 6d 6f 74 65  , loading remote
1eb0: 6c 79 27 29 0a 20 20 20 20 20 20 20 20 63 6f 6e  ly').        con
1ec0: 73 74 20 62 74 70 52 65 73 70 6f 6e 73 65 20 3d  st btpResponse =
1ed0: 20 61 77 61 69 74 20 74 68 69 73 2e 5f 72 70 63   await this._rpc
1ee0: 2e 6d 65 73 73 61 67 65 28 0a 20 20 20 20 20 20  .message(.      
1ef0: 20 20 20 20 5b 7b 0a 20 20 20 20 20 20 20 20 20      [{.         
1f00: 20 20 20 70 72 6f 74 6f 63 6f 6c 4e 61 6d 65 3a     protocolName:
1f10: 20 27 69 6e 66 6f 27 2c 0a 20 20 20 20 20 20 20   'info',.       
1f20: 20 20 20 20 20 63 6f 6e 74 65 6e 74 54 79 70 65       contentType
1f30: 3a 20 42 74 70 2e 4d 49 4d 45 5f 41 50 50 4c 49  : Btp.MIME_APPLI
1f40: 43 41 54 49 4f 4e 5f 4f 43 54 45 54 5f 53 54 52  CATION_OCTET_STR
1f50: 45 41 4d 2c 0a 20 20 20 20 20 20 20 20 20 20 20  EAM,.           
1f60: 20 64 61 74 61 3a 20 42 75 66 66 65 72 2e 66 72   data: Buffer.fr
1f70: 6f 6d 28 5b 20 49 4e 46 4f 5f 52 45 51 55 45 53  om([ INFO_REQUES
1f80: 54 5f 46 55 4c 4c 20 5d 29 0a 20 20 20 20 20 20  T_FULL ]).      
1f90: 20 20 20 20 7d 5d 0a 20 20 20 20 20 20 20 20 29      }].        )
1fa0: 0a 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 72  .        const r
1fb0: 65 73 70 20 3d 20 70 72 6f 74 6f 63 6f 6c 44 61  esp = protocolDa
1fc0: 74 61 54 6f 49 6c 70 41 6e 64 43 75 73 74 6f 6d  taToIlpAndCustom
1fd0: 28 62 74 70 52 65 73 70 6f 6e 73 65 29 0a 20 20  (btpResponse).  
1fe0: 20 20 20 20 20 20 74 68 69 73 2e 5f 69 6e 66 6f        this._info
1ff0: 20 3d 20 28 72 65 73 70 2e 70 72 6f 74 6f 63 6f   = (resp.protoco
2000: 6c 4d 61 70 20 26 26 20 72 65 73 70 2e 70 72 6f  lMap && resp.pro
2010: 74 6f 63 6f 6c 4d 61 70 2e 69 6e 66 6f 29 20 7c  tocolMap.info) |
2020: 7c 20 7b 7d 0a 20 20 20 20 20 20 20 20 69 66 20  | {}.        if 
2030: 28 74 68 69 73 2e 5f 70 72 65 66 69 78 20 26 26  (this._prefix &&
2040: 20 74 68 69 73 2e 5f 70 72 65 66 69 78 20 21 3d   this._prefix !=
2050: 3d 20 74 68 69 73 2e 5f 69 6e 66 6f 2e 70 72 65  = this._info.pre
2060: 66 69 78 29 20 7b 0a 20 20 20 20 20 20 20 20 20  fix) {.         
2070: 20 74 68 72 6f 77 20 6e 65 77 20 45 72 72 6f 72   throw new Error
2080: 28 27 52 65 6d 6f 74 65 20 70 72 65 66 69 78 20  ('Remote prefix 
2090: 64 6f 65 73 20 6e 6f 74 20 6d 61 74 63 68 20 63  does not match c
20a0: 6f 6e 66 69 67 75 72 65 64 20 70 72 65 66 69 78  onfigured prefix
20b0: 27 29 0a 20 20 20 20 20 20 20 20 7d 20 65 6c 73  ').        } els
20c0: 65 20 7b 0a 20 20 20 20 20 20 20 20 20 20 74 68  e {.          th
20d0: 69 73 2e 5f 70 72 65 66 69 78 20 3d 20 74 68 69  is._prefix = thi
20e0: 73 2e 5f 69 6e 66 6f 2e 70 72 65 66 69 78 0a 20  s._info.prefix. 
20f0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
2100: 0a 0a 20 20 20 20 20 20 61 77 61 69 74 20 74 68  ..      await th
2110: 69 73 2e 5f 70 61 79 63 68 61 6e 2e 63 6f 6e 6e  is._paychan.conn
2120: 65 63 74 28 74 68 69 73 2e 5f 70 61 79 63 68 61  ect(this._paycha
2130: 6e 43 6f 6e 74 65 78 74 29 0a 20 20 20 20 7d 20  nContext).    } 
2140: 63 61 74 63 68 20 28 65 72 72 29 20 7b 0a 20 20  catch (err) {.  
2150: 20 20 20 20 64 65 62 75 67 28 27 63 6f 6e 6e 65      debug('conne
2160: 63 74 20 66 61 69 6c 65 64 3a 27 2c 20 65 72 72  ct failed:', err
2170: 29 0a 20 20 20 20 20 20 74 68 69 73 2e 5f 63 6f  ).      this._co
2180: 6e 6e 65 63 74 65 64 20 3d 20 66 61 6c 73 65 0a  nnected = false.
2190: 20 20 20 20 20 20 74 68 72 6f 77 20 65 72 72 0a        throw err.
21a0: 20 20 20 20 7d 0a 20 20 20 20 74 68 69 73 2e 5f      }.    this._
21b0: 76 61 6c 69 64 61 74 6f 72 20 3d 20 6e 65 77 20  validator = new 
21c0: 56 61 6c 69 64 61 74 6f 72 28 7b 0a 20 20 20 20  Validator({.    
21d0: 20 20 61 63 63 6f 75 6e 74 3a 20 74 68 69 73 2e    account: this.
21e0: 67 65 74 41 63 63 6f 75 6e 74 28 29 2c 0a 20 20  getAccount(),.  
21f0: 20 20 20 20 70 65 65 72 3a 20 74 68 69 73 2e 67      peer: this.g
2200: 65 74 50 65 65 72 41 63 63 6f 75 6e 74 28 29 2c  etPeerAccount(),
2210: 0a 20 20 20 20 20 20 70 72 65 66 69 78 3a 20 74  .      prefix: t
2220: 68 69 73 2e 67 65 74 49 6e 66 6f 28 29 2e 70 72  his.getInfo().pr
2230: 65 66 69 78 0a 20 20 20 20 7d 29 0a 0a 20 20 20  efix.    })..   
2240: 20 74 68 69 73 2e 5f 63 6f 6e 6e 65 63 74 65 64   this._connected
2250: 20 3d 20 74 72 75 65 0a 20 20 20 20 74 68 69 73   = true.    this
2260: 2e 5f 63 6f 6e 6e 65 63 74 69 6e 67 20 3d 20 66  ._connecting = f
2270: 61 6c 73 65 0a 20 20 20 20 74 68 69 73 2e 5f 73  alse.    this._s
2280: 61 66 65 45 6d 69 74 28 27 63 6f 6e 6e 65 63 74  afeEmit('connect
2290: 27 29 0a 20 20 20 20 66 69 6e 69 73 68 43 6f 6e  ').    finishCon
22a0: 6e 65 63 74 50 72 6f 6d 69 73 65 28 29 0a 20 20  nectPromise().  
22b0: 7d 0a 0a 20 20 61 73 79 6e 63 20 64 69 73 63 6f  }..  async disco
22c0: 6e 6e 65 63 74 20 28 29 20 7b 0a 20 20 20 20 69  nnect () {.    i
22d0: 66 20 28 21 74 68 69 73 2e 5f 63 6f 6e 6e 65 63  f (!this._connec
22e0: 74 65 64 29 20 72 65 74 75 72 6e 0a 20 20 20 20  ted) return.    
22f0: 74 68 69 73 2e 5f 63 6f 6e 6e 65 63 74 65 64 20  this._connected 
2300: 3d 20 66 61 6c 73 65 0a 0a 20 20 20 20 61 77 61  = false..    awa
2310: 69 74 20 74 68 69 73 2e 5f 70 61 79 63 68 61 6e  it this._paychan
2320: 2e 64 69 73 63 6f 6e 6e 65 63 74 28 74 68 69 73  .disconnect(this
2330: 2e 5f 70 61 79 63 68 61 6e 43 6f 6e 74 65 78 74  ._paychanContext
2340: 29 0a 0a 20 20 20 20 2f 2f 20 63 6c 6f 73 65 73  )..    // closes
2350: 20 61 6c 6c 20 6f 70 65 6e 20 73 6f 63 6b 65 74   all open socket
2360: 73 0a 20 20 20 20 74 68 69 73 2e 5f 72 70 63 2e  s.    this._rpc.
2370: 64 69 73 63 6f 6e 6e 65 63 74 28 29 0a 0a 20 20  disconnect()..  
2380: 20 20 2f 2f 20 73 74 6f 70 20 77 65 62 20 73 6f    // stop web so
2390: 63 6b 65 74 20 73 65 72 76 65 72 2c 20 69 66 20  cket server, if 
23a0: 61 6e 79 0a 20 20 20 20 69 66 20 28 74 68 69 73  any.    if (this
23b0: 2e 5f 6c 69 73 74 65 6e 65 72 29 20 7b 0a 20 20  ._listener) {.  
23c0: 20 20 20 20 74 72 79 20 7b 0a 20 20 20 20 20 20      try {.      
23d0: 20 20 61 77 61 69 74 20 74 68 69 73 2e 5f 6c 69    await this._li
23e0: 73 74 65 6e 65 72 2e 63 6c 6f 73 65 28 29 0a 20  stener.close(). 
23f0: 20 20 20 20 20 7d 20 63 61 74 63 68 20 28 65 72       } catch (er
2400: 72 29 20 7b 0a 20 20 20 20 20 20 20 20 64 65 62  r) {.        deb
2410: 75 67 28 27 46 61 69 6c 65 64 20 73 74 6f 70 70  ug('Failed stopp
2420: 69 6e 67 20 77 65 62 73 6f 63 6b 65 74 20 73 65  ing websocket se
2430: 72 76 65 72 27 2c 20 65 72 72 29 0a 20 20 20 20  rver', err).    
2440: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 74 68    }.    }.    th
2450: 69 73 2e 5f 73 61 66 65 45 6d 69 74 28 27 64 69  is._safeEmit('di
2460: 73 63 6f 6e 6e 65 63 74 27 29 0a 20 20 7d 0a 0a  sconnect').  }..
2470: 20 20 61 73 79 6e 63 20 73 65 6e 64 52 65 71 75    async sendRequ
2480: 65 73 74 20 28 6d 65 73 73 61 67 65 29 20 7b 0a  est (message) {.
2490: 20 20 20 20 74 68 69 73 2e 61 73 73 65 72 74 43      this.assertC
24a0: 6f 6e 6e 65 63 74 69 6f 6e 42 65 66 6f 72 65 43  onnectionBeforeC
24b0: 61 6c 6c 69 6e 67 28 27 73 65 6e 64 52 65 71 75  alling('sendRequ
24c0: 65 73 74 27 29 0a 20 20 20 20 74 68 69 73 2e 5f  est').    this._
24d0: 76 61 6c 69 64 61 74 6f 72 2e 76 61 6c 69 64 61  validator.valida
24e0: 74 65 4f 75 74 67 6f 69 6e 67 4d 65 73 73 61 67  teOutgoingMessag
24f0: 65 28 6d 65 73 73 61 67 65 29 0a 20 20 20 20 74  e(message).    t
2500: 68 69 73 2e 5f 73 61 66 65 45 6d 69 74 28 27 6f  his._safeEmit('o
2510: 75 74 67 6f 69 6e 67 5f 72 65 71 75 65 73 74 27  utgoing_request'
2520: 2c 20 6d 65 73 73 61 67 65 29 0a 0a 20 20 20 20  , message)..    
2530: 74 68 69 73 2e 64 65 62 75 67 28 27 72 65 71 75  this.debug('requ
2540: 65 73 74 69 6e 67 20 77 69 74 68 20 70 6c 75 67  esting with plug
2550: 69 6e 27 2c 20 6d 65 73 73 61 67 65 29 0a 20 20  in', message).  
2560: 20 20 63 6f 6e 73 74 20 62 74 70 52 65 73 70 6f    const btpRespo
2570: 6e 73 65 20 3d 20 61 77 61 69 74 20 74 68 69 73  nse = await this
2580: 2e 5f 72 70 63 2e 6d 65 73 73 61 67 65 28 69 6c  ._rpc.message(il
2590: 70 41 6e 64 43 75 73 74 6f 6d 54 6f 50 72 6f 74  pAndCustomToProt
25a0: 6f 63 6f 6c 44 61 74 61 28 6d 65 73 73 61 67 65  ocolData(message
25b0: 29 29 0a 0a 20 20 20 20 63 6f 6e 73 74 20 7b 20  ))..    const { 
25c0: 69 6c 70 2c 20 63 75 73 74 6f 6d 20 7d 20 3d 20  ilp, custom } = 
25d0: 70 72 6f 74 6f 63 6f 6c 44 61 74 61 54 6f 49 6c  protocolDataToIl
25e0: 70 41 6e 64 43 75 73 74 6f 6d 28 62 74 70 52 65  pAndCustom(btpRe
25f0: 73 70 6f 6e 73 65 29 0a 20 20 20 20 63 6f 6e 73  sponse).    cons
2600: 74 20 70 61 72 73 65 64 20 3d 20 7b 0a 20 20 20  t parsed = {.   
2610: 20 20 20 74 6f 3a 20 74 68 69 73 2e 67 65 74 41     to: this.getA
2620: 63 63 6f 75 6e 74 28 29 2c 0a 20 20 20 20 20 20  ccount(),.      
2630: 66 72 6f 6d 3a 20 74 68 69 73 2e 67 65 74 50 65  from: this.getPe
2640: 65 72 41 63 63 6f 75 6e 74 28 29 2c 0a 20 20 20  erAccount(),.   
2650: 20 20 20 6c 65 64 67 65 72 3a 20 74 68 69 73 2e     ledger: this.
2660: 5f 70 72 65 66 69 78 0a 20 20 20 20 7d 0a 0a 20  _prefix.    }.. 
2670: 20 20 20 69 66 20 28 69 6c 70 29 20 70 61 72 73     if (ilp) pars
2680: 65 64 2e 69 6c 70 20 3d 20 69 6c 70 0a 20 20 20  ed.ilp = ilp.   
2690: 20 69 66 20 28 63 75 73 74 6f 6d 29 20 70 61 72   if (custom) par
26a0: 73 65 64 2e 63 75 73 74 6f 6d 20 3d 20 63 75 73  sed.custom = cus
26b0: 74 6f 6d 0a 0a 20 20 20 20 74 68 69 73 2e 5f 76  tom..    this._v
26c0: 61 6c 69 64 61 74 6f 72 2e 76 61 6c 69 64 61 74  alidator.validat
26d0: 65 49 6e 63 6f 6d 69 6e 67 4d 65 73 73 61 67 65  eIncomingMessage
26e0: 28 70 61 72 73 65 64 29 0a 20 20 20 20 74 68 69  (parsed).    thi
26f0: 73 2e 5f 73 61 66 65 45 6d 69 74 28 27 69 6e 63  s._safeEmit('inc
2700: 6f 6d 69 6e 67 5f 72 65 73 70 6f 6e 73 65 27 2c  oming_response',
2710: 20 70 61 72 73 65 64 29 0a 0a 20 20 20 20 72 65   parsed)..    re
2720: 74 75 72 6e 20 70 61 72 73 65 64 0a 20 20 7d 0a  turn parsed.  }.
2730: 0a 20 20 61 73 79 6e 63 20 5f 68 61 6e 64 6c 65  .  async _handle
2740: 52 65 71 75 65 73 74 20 28 7b 72 65 71 75 65 73  Request ({reques
2750: 74 49 64 2c 20 64 61 74 61 7d 29 20 7b 0a 20 20  tId, data}) {.  
2760: 20 20 63 6f 6e 73 74 20 7b 20 69 6c 70 2c 20 63    const { ilp, c
2770: 75 73 74 6f 6d 2c 20 70 72 6f 74 6f 63 6f 6c 4d  ustom, protocolM
2780: 61 70 20 7d 20 3d 20 70 72 6f 74 6f 63 6f 6c 44  ap } = protocolD
2790: 61 74 61 54 6f 49 6c 70 41 6e 64 43 75 73 74 6f  ataToIlpAndCusto
27a0: 6d 28 64 61 74 61 29 0a 20 20 20 20 63 6f 6e 73  m(data).    cons
27b0: 74 20 6d 65 73 73 61 67 65 20 3d 20 7b 0a 20 20  t message = {.  
27c0: 20 20 20 20 69 64 3a 20 72 65 71 75 65 73 74 49      id: requestI
27d0: 64 2c 0a 20 20 20 20 20 20 74 6f 3a 20 74 68 69  d,.      to: thi
27e0: 73 2e 67 65 74 41 63 63 6f 75 6e 74 28 29 2c 0a  s.getAccount(),.
27f0: 20 20 20 20 20 20 66 72 6f 6d 3a 20 74 68 69 73        from: this
2800: 2e 67 65 74 50 65 65 72 41 63 63 6f 75 6e 74 28  .getPeerAccount(
2810: 29 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 20  ).    }..    if 
2820: 28 69 6c 70 29 20 6d 65 73 73 61 67 65 2e 69 6c  (ilp) message.il
2830: 70 20 3d 20 69 6c 70 0a 20 20 20 20 69 66 20 28  p = ilp.    if (
2840: 63 75 73 74 6f 6d 29 20 6d 65 73 73 61 67 65 2e  custom) message.
2850: 63 75 73 74 6f 6d 20 3d 20 63 75 73 74 6f 6d 0a  custom = custom.
2860: 0a 20 20 20 20 2f 2f 20 69 66 20 74 68 65 72 65  .    // if there
2870: 20 61 72 65 20 73 69 64 65 20 70 72 6f 74 6f 63   are side protoc
2880: 6f 6c 73 20 6f 6e 6c 79 0a 20 20 20 20 69 66 20  ols only.    if 
2890: 28 21 69 6c 70 29 20 7b 0a 20 20 20 20 20 20 69  (!ilp) {.      i
28a0: 66 20 28 70 72 6f 74 6f 63 6f 6c 4d 61 70 2e 69  f (protocolMap.i
28b0: 6e 66 6f 29 20 7b 0a 20 20 20 20 20 20 20 20 69  nfo) {.        i
28c0: 66 20 28 42 75 66 66 65 72 2e 69 73 42 75 66 66  f (Buffer.isBuff
28d0: 65 72 28 70 72 6f 74 6f 63 6f 6c 4d 61 70 2e 69  er(protocolMap.i
28e0: 6e 66 6f 29 20 26 26 0a 20 20 20 20 20 20 20 20  nfo) &&.        
28f0: 20 20 20 20 70 72 6f 74 6f 63 6f 6c 4d 61 70 2e      protocolMap.
2900: 69 6e 66 6f 2e 72 65 61 64 49 6e 74 38 28 29 20  info.readInt8() 
2910: 3d 3d 3d 20 49 4e 46 4f 5f 52 45 51 55 45 53 54  === INFO_REQUEST
2920: 5f 46 55 4c 4c 29 20 7b 0a 20 20 20 20 20 20 20  _FULL) {.       
2930: 20 20 20 72 65 74 75 72 6e 20 5b 7b 0a 20 20 20     return [{.   
2940: 20 20 20 20 20 20 20 20 20 70 72 6f 74 6f 63 6f           protoco
2950: 6c 4e 61 6d 65 3a 20 27 69 6e 66 6f 27 2c 0a 20  lName: 'info',. 
2960: 20 20 20 20 20 20 20 20 20 20 20 63 6f 6e 74 65             conte
2970: 6e 74 54 79 70 65 3a 20 42 74 70 2e 4d 49 4d 45  ntType: Btp.MIME
2980: 5f 41 50 50 4c 49 43 41 54 49 4f 4e 5f 4a 53 4f  _APPLICATION_JSO
2990: 4e 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 64  N,.            d
29a0: 61 74 61 3a 20 42 75 66 66 65 72 2e 66 72 6f 6d  ata: Buffer.from
29b0: 28 4a 53 4f 4e 2e 73 74 72 69 6e 67 69 66 79 28  (JSON.stringify(
29c0: 74 68 69 73 2e 67 65 74 49 6e 66 6f 28 29 29 29  this.getInfo()))
29d0: 0a 20 20 20 20 20 20 20 20 20 20 7d 5d 0a 20 20  .          }].  
29e0: 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20        } else {. 
29f0: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20           return 
2a00: 5b 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 70  [{.            p
2a10: 72 6f 74 6f 63 6f 6c 4e 61 6d 65 3a 20 27 69 6e  rotocolName: 'in
2a20: 66 6f 27 2c 0a 20 20 20 20 20 20 20 20 20 20 20  fo',.           
2a30: 20 63 6f 6e 74 65 6e 74 54 79 70 65 3a 20 42 74   contentType: Bt
2a40: 70 2e 4d 49 4d 45 5f 54 45 58 54 5f 50 4c 41 49  p.MIME_TEXT_PLAI
2a50: 4e 5f 55 54 46 38 2c 0a 20 20 20 20 20 20 20 20  N_UTF8,.        
2a60: 20 20 20 20 64 61 74 61 3a 20 42 75 66 66 65 72      data: Buffer
2a70: 2e 66 72 6f 6d 28 74 68 69 73 2e 67 65 74 41 63  .from(this.getAc
2a80: 63 6f 75 6e 74 28 29 29 0a 20 20 20 20 20 20 20  count()).       
2a90: 20 20 20 7d 5d 0a 20 20 20 20 20 20 20 20 7d 0a     }].        }.
2aa0: 20 20 20 20 20 20 7d 20 65 6c 73 65 20 69 66 20        } else if 
2ab0: 28 70 72 6f 74 6f 63 6f 6c 4d 61 70 2e 62 61 6c  (protocolMap.bal
2ac0: 61 6e 63 65 29 20 7b 0a 20 20 20 20 20 20 20 20  ance) {.        
2ad0: 72 65 74 75 72 6e 20 5b 7b 0a 20 20 20 20 20 20  return [{.      
2ae0: 20 20 20 20 70 72 6f 74 6f 63 6f 6c 4e 61 6d 65      protocolName
2af0: 3a 20 27 62 61 6c 61 6e 63 65 27 2c 0a 20 20 20  : 'balance',.   
2b00: 20 20 20 20 20 20 20 63 6f 6e 74 65 6e 74 54 79         contentTy
2b10: 70 65 3a 20 42 74 70 2e 4d 49 4d 45 5f 41 50 50  pe: Btp.MIME_APP
2b20: 4c 49 43 41 54 49 4f 4e 5f 4f 43 54 45 54 5f 53  LICATION_OCTET_S
2b30: 54 52 45 41 4d 2c 0a 20 20 20 20 20 20 20 20 20  TREAM,.         
2b40: 20 64 61 74 61 3a 20 69 6e 74 36 34 2e 74 6f 42   data: int64.toB
2b50: 75 66 66 65 72 28 61 77 61 69 74 20 74 68 69 73  uffer(await this
2b60: 2e 5f 68 61 6e 64 6c 65 47 65 74 42 61 6c 61 6e  ._handleGetBalan
2b70: 63 65 28 29 29 0a 20 20 20 20 20 20 20 20 7d 5d  ce()).        }]
2b80: 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20 69 66  .      } else if
2b90: 20 28 70 72 6f 74 6f 63 6f 6c 4d 61 70 2e 6c 69   (protocolMap.li
2ba0: 6d 69 74 29 20 7b 0a 20 20 20 20 20 20 20 20 72  mit) {.        r
2bb0: 65 74 75 72 6e 20 5b 7b 0a 20 20 20 20 20 20 20  eturn [{.       
2bc0: 20 20 20 70 72 6f 74 6f 63 6f 6c 4e 61 6d 65 3a     protocolName:
2bd0: 20 27 6c 69 6d 69 74 27 2c 0a 20 20 20 20 20 20   'limit',.      
2be0: 20 20 20 20 63 6f 6e 74 65 6e 74 54 79 70 65 3a      contentType:
2bf0: 20 42 74 70 2e 4d 49 4d 45 5f 41 50 50 4c 49 43   Btp.MIME_APPLIC
2c00: 41 54 49 4f 4e 5f 4a 53 4f 4e 2c 0a 20 20 20 20  ATION_JSON,.    
2c10: 20 20 20 20 20 20 64 61 74 61 3a 20 42 75 66 66        data: Buff
2c20: 65 72 2e 66 72 6f 6d 28 4a 53 4f 4e 2e 73 74 72  er.from(JSON.str
2c30: 69 6e 67 69 66 79 28 61 77 61 69 74 20 74 68 69  ingify(await thi
2c40: 73 2e 5f 68 61 6e 64 6c 65 47 65 74 4c 69 6d 69  s._handleGetLimi
2c50: 74 28 29 29 29 0a 20 20 20 20 20 20 20 20 7d 5d  t())).        }]
2c60: 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20 69 66  .      } else if
2c70: 20 28 70 72 6f 74 6f 63 6f 6c 4d 61 70 2e 63 75   (protocolMap.cu
2c80: 73 74 6f 6d 29 20 7b 0a 20 20 20 20 20 20 20 20  stom) {.        
2c90: 2f 2f 20 44 6f 6e 27 74 20 74 68 72 6f 77 20 2d  // Don't throw -
2ca0: 2d 20 74 68 69 73 20 6d 65 73 73 61 67 65 20 77  - this message w
2cb0: 69 6c 6c 20 62 65 20 65 6d 69 74 74 65 64 2e 0a  ill be emitted..
2cc0: 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20        } else {. 
2cd0: 20 20 20 20 20 20 20 69 66 20 28 74 68 69 73 2e         if (this.
2ce0: 5f 70 61 79 63 68 61 6e 43 6f 6e 74 65 78 74 2e  _paychanContext.
2cf0: 72 70 63 2e 68 61 6e 64 6c 65 50 72 6f 74 6f 63  rpc.handleProtoc
2d00: 6f 6c 73 29 20 7b 0a 20 20 20 20 20 20 20 20 20  ols) {.         
2d10: 20 72 65 74 75 72 6e 20 74 68 69 73 2e 5f 70 61   return this._pa
2d20: 79 63 68 61 6e 43 6f 6e 74 65 78 74 2e 72 70 63  ychanContext.rpc
2d30: 2e 68 61 6e 64 6c 65 50 72 6f 74 6f 63 6f 6c 73  .handleProtocols
2d40: 28 70 72 6f 74 6f 63 6f 6c 4d 61 70 29 0a 20 20  (protocolMap).  
2d50: 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20        } else {. 
2d60: 20 20 20 20 20 20 20 20 20 74 68 72 6f 77 20 6e           throw n
2d70: 65 77 20 45 72 72 6f 72 28 27 55 6e 73 75 70 70  ew Error('Unsupp
2d80: 6f 72 74 65 64 20 73 69 64 65 20 70 72 6f 74 6f  orted side proto
2d90: 63 6f 6c 2e 27 29 0a 20 20 20 20 20 20 20 20 7d  col.').        }
2da0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a  .      }.    }..
2db0: 20 20 20 20 74 68 69 73 2e 5f 76 61 6c 69 64 61      this._valida
2dc0: 74 6f 72 2e 76 61 6c 69 64 61 74 65 49 6e 63 6f  tor.validateInco
2dd0: 6d 69 6e 67 4d 65 73 73 61 67 65 28 6d 65 73 73  mingMessage(mess
2de0: 61 67 65 29 0a 20 20 20 20 74 68 69 73 2e 5f 73  age).    this._s
2df0: 61 66 65 45 6d 69 74 28 27 69 6e 63 6f 6d 69 6e  afeEmit('incomin
2e00: 67 5f 72 65 71 75 65 73 74 27 2c 20 6d 65 73 73  g_request', mess
2e10: 61 67 65 29 0a 0a 20 20 20 20 69 66 20 28 21 74  age)..    if (!t
2e20: 68 69 73 2e 5f 72 65 71 75 65 73 74 48 61 6e 64  his._requestHand
2e30: 6c 65 72 29 20 7b 0a 20 20 20 20 20 20 74 68 72  ler) {.      thr
2e40: 6f 77 20 6e 65 77 20 4e 6f 74 41 63 63 65 70 74  ow new NotAccept
2e50: 65 64 45 72 72 6f 72 28 27 6e 6f 20 72 65 71 75  edError('no requ
2e60: 65 73 74 20 68 61 6e 64 6c 65 72 20 72 65 67 69  est handler regi
2e70: 73 74 65 72 65 64 27 29 0a 20 20 20 20 7d 0a 0a  stered').    }..
2e80: 20 20 20 20 63 6f 6e 73 74 20 72 65 73 70 6f 6e      const respon
2e90: 73 65 20 3d 20 61 77 61 69 74 20 74 68 69 73 2e  se = await this.
2ea0: 5f 72 65 71 75 65 73 74 48 61 6e 64 6c 65 72 28  _requestHandler(
2eb0: 6d 65 73 73 61 67 65 29 0a 20 20 20 20 20 20 2e  message).      .
2ec0: 63 61 74 63 68 28 28 65 29 20 3d 3e 20 28 7b 0a  catch((e) => ({.
2ed0: 20 20 20 20 20 20 20 20 6c 65 64 67 65 72 3a 20          ledger: 
2ee0: 6d 65 73 73 61 67 65 2e 6c 65 64 67 65 72 2c 0a  message.ledger,.
2ef0: 20 20 20 20 20 20 20 20 74 6f 3a 20 74 68 69 73          to: this
2f00: 2e 67 65 74 50 65 65 72 41 63 63 6f 75 6e 74 28  .getPeerAccount(
2f10: 29 2c 0a 20 20 20 20 20 20 20 20 66 72 6f 6d 3a  ),.        from:
2f20: 20 74 68 69 73 2e 67 65 74 41 63 63 6f 75 6e 74   this.getAccount
2f30: 28 29 2c 0a 20 20 20 20 20 20 20 20 69 6c 70 3a  (),.        ilp:
2f40: 20 62 61 73 65 36 34 75 72 6c 28 69 6c 70 50 61   base64url(ilpPa
2f50: 63 6b 65 74 2e 73 65 72 69 61 6c 69 7a 65 49 6c  cket.serializeIl
2f60: 70 45 72 72 6f 72 28 7b 0a 20 20 20 20 20 20 20  pError({.       
2f70: 20 20 20 63 6f 64 65 3a 20 27 46 30 30 27 2c 0a     code: 'F00',.
2f80: 20 20 20 20 20 20 20 20 20 20 6e 61 6d 65 3a 20            name: 
2f90: 27 42 61 64 20 52 65 71 75 65 73 74 27 2c 0a 20  'Bad Request',. 
2fa0: 20 20 20 20 20 20 20 20 20 74 72 69 67 67 65 72           trigger
2fb0: 65 64 42 79 3a 20 74 68 69 73 2e 67 65 74 41 63  edBy: this.getAc
2fc0: 63 6f 75 6e 74 28 29 2c 0a 20 20 20 20 20 20 20  count(),.       
2fd0: 20 20 20 66 6f 72 77 61 72 64 65 64 42 79 3a 20     forwardedBy: 
2fe0: 5b 5d 2c 0a 20 20 20 20 20 20 20 20 20 20 74 72  [],.          tr
2ff0: 69 67 67 65 72 65 64 41 74 3a 20 6e 65 77 20 44  iggeredAt: new D
3000: 61 74 65 28 29 2c 0a 20 20 20 20 20 20 20 20 20  ate(),.         
3010: 20 64 61 74 61 3a 20 4a 53 4f 4e 2e 73 74 72 69   data: JSON.stri
3020: 6e 67 69 66 79 28 7b 20 6d 65 73 73 61 67 65 3a  ngify({ message:
3030: 20 65 2e 6d 65 73 73 61 67 65 20 7d 29 0a 20 20   e.message }).  
3040: 20 20 20 20 20 20 7d 29 29 0a 20 20 20 20 20 20        })).      
3050: 7d 29 29 0a 0a 20 20 20 20 74 68 69 73 2e 5f 76  }))..    this._v
3060: 61 6c 69 64 61 74 6f 72 2e 76 61 6c 69 64 61 74  alidator.validat
3070: 65 4f 75 74 67 6f 69 6e 67 4d 65 73 73 61 67 65  eOutgoingMessage
3080: 28 72 65 73 70 6f 6e 73 65 29 0a 20 20 20 20 74  (response).    t
3090: 68 69 73 2e 5f 73 61 66 65 45 6d 69 74 28 27 6f  his._safeEmit('o
30a0: 75 74 67 6f 69 6e 67 5f 72 65 73 70 6f 6e 73 65  utgoing_response
30b0: 27 2c 20 72 65 73 70 6f 6e 73 65 29 0a 0a 20 20  ', response)..  
30c0: 20 20 72 65 74 75 72 6e 20 69 6c 70 41 6e 64 43    return ilpAndC
30d0: 75 73 74 6f 6d 54 6f 50 72 6f 74 6f 63 6f 6c 44  ustomToProtocolD
30e0: 61 74 61 28 7b 20 69 6c 70 3a 20 72 65 73 70 6f  ata({ ilp: respo
30f0: 6e 73 65 2e 69 6c 70 2c 20 63 75 73 74 6f 6d 3a  nse.ilp, custom:
3100: 20 72 65 73 70 6f 6e 73 65 2e 63 75 73 74 6f 6d   response.custom
3110: 20 7d 29 0a 20 20 7d 0a 0a 20 20 61 73 79 6e 63   }).  }..  async
3120: 20 73 65 6e 64 54 72 61 6e 73 66 65 72 20 28 70   sendTransfer (p
3130: 72 65 54 72 61 6e 73 66 65 72 29 20 7b 0a 20 20  reTransfer) {.  
3140: 20 20 74 68 69 73 2e 61 73 73 65 72 74 43 6f 6e    this.assertCon
3150: 6e 65 63 74 69 6f 6e 42 65 66 6f 72 65 43 61 6c  nectionBeforeCal
3160: 6c 69 6e 67 28 27 73 65 6e 64 54 72 61 6e 73 66  ling('sendTransf
3170: 65 72 27 29 0a 20 20 20 20 63 6f 6e 73 74 20 74  er').    const t
3180: 72 61 6e 73 66 65 72 20 3d 20 4f 62 6a 65 63 74  ransfer = Object
3190: 2e 61 73 73 69 67 6e 28 7b 7d 2c 20 70 72 65 54  .assign({}, preT
31a0: 72 61 6e 73 66 65 72 2c 20 7b 20 6c 65 64 67 65  ransfer, { ledge
31b0: 72 3a 20 74 68 69 73 2e 5f 70 72 65 66 69 78 20  r: this._prefix 
31c0: 7d 29 0a 20 20 20 20 74 68 69 73 2e 5f 76 61 6c  }).    this._val
31d0: 69 64 61 74 6f 72 2e 76 61 6c 69 64 61 74 65 4f  idator.validateO
31e0: 75 74 67 6f 69 6e 67 54 72 61 6e 73 66 65 72 28  utgoingTransfer(
31f0: 74 72 61 6e 73 66 65 72 29 0a 0a 20 20 20 20 2f  transfer)..    /
3200: 2f 20 61 70 70 6c 79 20 74 68 65 20 74 72 61 6e  / apply the tran
3210: 73 66 65 72 20 62 65 66 6f 72 65 20 74 68 65 20  sfer before the 
3220: 6f 74 68 65 72 20 70 6c 75 67 69 6e 20 63 61 6e  other plugin can
3230: 0a 20 20 20 20 2f 2f 20 65 6d 69 74 20 61 6e 79  .    // emit any
3240: 20 65 76 65 6e 74 73 20 61 62 6f 75 74 20 69 74   events about it
3250: 2e 20 69 73 49 6e 63 6f 6d 69 6e 67 20 3d 20 66  . isIncoming = f
3260: 61 6c 73 65 2e 0a 20 20 20 20 61 77 61 69 74 20  alse..    await 
3270: 74 68 69 73 2e 5f 74 72 61 6e 73 66 65 72 73 2e  this._transfers.
3280: 70 72 65 70 61 72 65 28 74 72 61 6e 73 66 65 72  prepare(transfer
3290: 2c 20 66 61 6c 73 65 29 0a 0a 20 20 20 20 74 72  , false)..    tr
32a0: 79 20 7b 0a 20 20 20 20 20 20 61 77 61 69 74 20  y {.      await 
32b0: 74 68 69 73 2e 5f 72 70 63 2e 70 72 65 70 61 72  this._rpc.prepar
32c0: 65 28 74 72 61 6e 73 66 65 72 2c 20 69 6c 70 41  e(transfer, ilpA
32d0: 6e 64 43 75 73 74 6f 6d 54 6f 50 72 6f 74 6f 63  ndCustomToProtoc
32e0: 6f 6c 44 61 74 61 28 74 72 61 6e 73 66 65 72 29  olData(transfer)
32f0: 29 0a 20 20 20 20 20 20 74 68 69 73 2e 64 65 62  ).      this.deb
3300: 75 67 28 27 74 72 61 6e 73 66 65 72 20 61 63 6b  ug('transfer ack
3310: 6e 6f 77 6c 65 64 67 65 64 20 27 20 2b 20 74 72  nowledged ' + tr
3320: 61 6e 73 66 65 72 2e 69 64 29 0a 20 20 20 20 7d  ansfer.id).    }
3330: 20 63 61 74 63 68 20 28 65 29 20 7b 0a 20 20 20   catch (e) {.   
3340: 20 20 20 74 68 69 73 2e 64 65 62 75 67 28 65 2e     this.debug(e.
3350: 6e 61 6d 65 20 2b 20 27 20 64 75 72 69 6e 67 20  name + ' during 
3360: 74 72 61 6e 73 66 65 72 20 27 20 2b 20 74 72 61  transfer ' + tra
3370: 6e 73 66 65 72 2e 69 64 29 0a 20 20 20 20 20 20  nsfer.id).      
3380: 74 68 72 6f 77 20 65 0a 20 20 20 20 7d 0a 0a 20  throw e.    }.. 
3390: 20 20 20 74 68 69 73 2e 5f 73 61 66 65 45 6d 69     this._safeEmi
33a0: 74 28 27 6f 75 74 67 6f 69 6e 67 5f 70 72 65 70  t('outgoing_prep
33b0: 61 72 65 27 2c 20 74 72 61 6e 73 66 65 72 29 0a  are', transfer).
33c0: 20 20 20 20 69 66 20 28 74 68 69 73 2e 5f 73 74      if (this._st
33d0: 61 74 65 66 75 6c 29 20 7b 0a 20 20 20 20 20 20  ateful) {.      
33e0: 74 68 69 73 2e 5f 73 65 74 75 70 54 72 61 6e 73  this._setupTrans
33f0: 66 65 72 45 78 70 69 72 79 28 74 72 61 6e 73 66  ferExpiry(transf
3400: 65 72 2e 69 64 2c 20 74 72 61 6e 73 66 65 72 2e  er.id, transfer.
3410: 65 78 70 69 72 65 73 41 74 29 0a 20 20 20 20 7d  expiresAt).    }
3420: 0a 20 20 7d 0a 0a 20 20 61 73 79 6e 63 20 5f 68  .  }..  async _h
3430: 61 6e 64 6c 65 54 72 61 6e 73 66 65 72 20 28 7b  andleTransfer ({
3440: 64 61 74 61 7d 29 20 7b 0a 20 20 20 20 63 6f 6e  data}) {.    con
3450: 73 74 20 7b 20 69 6c 70 2c 20 63 75 73 74 6f 6d  st { ilp, custom
3460: 20 7d 20 3d 20 70 72 6f 74 6f 63 6f 6c 44 61 74   } = protocolDat
3470: 61 54 6f 49 6c 70 41 6e 64 43 75 73 74 6f 6d 28  aToIlpAndCustom(
3480: 64 61 74 61 29 0a 20 20 20 20 63 6f 6e 73 74 20  data).    const 
3490: 74 72 61 6e 73 66 65 72 20 3d 20 7b 0a 20 20 20  transfer = {.   
34a0: 20 20 20 69 64 3a 20 64 61 74 61 2e 69 64 2c 0a     id: data.id,.
34b0: 20 20 20 20 20 20 61 6d 6f 75 6e 74 3a 20 64 61        amount: da
34c0: 74 61 2e 61 6d 6f 75 6e 74 2c 0a 20 20 20 20 20  ta.amount,.     
34d0: 20 65 78 65 63 75 74 69 6f 6e 43 6f 6e 64 69 74   executionCondit
34e0: 69 6f 6e 3a 20 64 61 74 61 2e 65 78 65 63 75 74  ion: data.execut
34f0: 69 6f 6e 43 6f 6e 64 69 74 69 6f 6e 2c 0a 20 20  ionCondition,.  
3500: 20 20 20 20 65 78 70 69 72 65 73 41 74 3a 20 64      expiresAt: d
3510: 61 74 61 2e 65 78 70 69 72 65 73 41 74 2e 74 6f  ata.expiresAt.to
3520: 49 53 4f 53 74 72 69 6e 67 28 29 2c 0a 20 20 20  ISOString(),.   
3530: 20 20 20 74 6f 3a 20 74 68 69 73 2e 67 65 74 41     to: this.getA
3540: 63 63 6f 75 6e 74 28 29 2c 0a 20 20 20 20 20 20  ccount(),.      
3550: 66 72 6f 6d 3a 20 74 68 69 73 2e 67 65 74 50 65  from: this.getPe
3560: 65 72 41 63 63 6f 75 6e 74 28 29 2c 0a 20 20 20  erAccount(),.   
3570: 20 20 20 6c 65 64 67 65 72 3a 20 74 68 69 73 2e     ledger: this.
3580: 5f 70 72 65 66 69 78 0a 20 20 20 20 7d 0a 0a 20  _prefix.    }.. 
3590: 20 20 20 69 66 20 28 69 6c 70 29 20 74 72 61 6e     if (ilp) tran
35a0: 73 66 65 72 2e 69 6c 70 20 3d 20 69 6c 70 0a 20  sfer.ilp = ilp. 
35b0: 20 20 20 69 66 20 28 63 75 73 74 6f 6d 29 20 74     if (custom) t
35c0: 72 61 6e 73 66 65 72 2e 63 75 73 74 6f 6d 20 3d  ransfer.custom =
35d0: 20 63 75 73 74 6f 6d 0a 0a 20 20 20 20 74 68 69   custom..    thi
35e0: 73 2e 5f 76 61 6c 69 64 61 74 6f 72 2e 76 61 6c  s._validator.val
35f0: 69 64 61 74 65 49 6e 63 6f 6d 69 6e 67 54 72 61  idateIncomingTra
3600: 6e 73 66 65 72 28 74 72 61 6e 73 66 65 72 29 0a  nsfer(transfer).
3610: 20 20 20 20 61 77 61 69 74 20 74 68 69 73 2e 5f      await this._
3620: 74 72 61 6e 73 66 65 72 73 2e 70 72 65 70 61 72  transfers.prepar
3630: 65 28 74 72 61 6e 73 66 65 72 2c 20 74 72 75 65  e(transfer, true
3640: 29 0a 0a 20 20 20 20 74 72 79 20 7b 0a 20 20 20  )..    try {.   
3650: 20 20 20 61 77 61 69 74 20 74 68 69 73 2e 5f 70     await this._p
3660: 61 79 63 68 61 6e 2e 68 61 6e 64 6c 65 49 6e 63  aychan.handleInc
3670: 6f 6d 69 6e 67 50 72 65 70 61 72 65 28 74 68 69  omingPrepare(thi
3680: 73 2e 5f 70 61 79 63 68 61 6e 43 6f 6e 74 65 78  s._paychanContex
3690: 74 2c 20 74 72 61 6e 73 66 65 72 29 0a 20 20 20  t, transfer).   
36a0: 20 7d 20 63 61 74 63 68 20 28 65 29 20 7b 0a 20   } catch (e) {. 
36b0: 20 20 20 20 20 74 68 69 73 2e 64 65 62 75 67 28       this.debug(
36c0: 27 70 6c 75 67 69 6e 20 62 61 63 6b 65 6e 64 20  'plugin backend 
36d0: 72 65 6a 65 63 74 65 64 20 69 6e 63 6f 6d 69 6e  rejected incomin
36e0: 67 20 70 72 65 70 61 72 65 3a 27 2c 20 65 2e 6d  g prepare:', e.m
36f0: 65 73 73 61 67 65 29 0a 20 20 20 20 20 20 61 77  essage).      aw
3700: 61 69 74 20 74 68 69 73 2e 5f 74 72 61 6e 73 66  ait this._transf
3710: 65 72 73 2e 63 61 6e 63 65 6c 28 74 72 61 6e 73  ers.cancel(trans
3720: 66 65 72 2e 69 64 29 0a 20 20 20 20 20 20 74 68  fer.id).      th
3730: 72 6f 77 20 65 0a 20 20 20 20 7d 0a 0a 20 20 20  row e.    }..   
3740: 20 2f 2f 20 73 65 74 20 75 70 20 65 78 70 69 72   // set up expir
3750: 79 20 68 65 72 65 20 74 6f 6f 2c 20 73 6f 20 62  y here too, so b
3760: 6f 74 68 20 73 69 64 65 73 20 63 61 6e 20 73 65  oth sides can se
3770: 6e 64 20 74 68 65 20 65 78 70 69 72 61 74 69 6f  nd the expiratio
3780: 6e 20 6d 65 73 73 61 67 65 0a 20 20 20 20 74 68  n message.    th
3790: 69 73 2e 5f 73 61 66 65 45 6d 69 74 28 27 69 6e  is._safeEmit('in
37a0: 63 6f 6d 69 6e 67 5f 70 72 65 70 61 72 65 27 2c  coming_prepare',
37b0: 20 74 72 61 6e 73 66 65 72 29 0a 20 20 20 20 69   transfer).    i
37c0: 66 20 28 74 68 69 73 2e 5f 73 74 61 74 65 66 75  f (this._statefu
37d0: 6c 29 20 7b 0a 20 20 20 20 20 20 74 68 69 73 2e  l) {.      this.
37e0: 5f 73 65 74 75 70 54 72 61 6e 73 66 65 72 45 78  _setupTransferEx
37f0: 70 69 72 79 28 74 72 61 6e 73 66 65 72 2e 69 64  piry(transfer.id
3800: 2c 20 74 72 61 6e 73 66 65 72 2e 65 78 70 69 72  , transfer.expir
3810: 65 73 41 74 29 0a 20 20 20 20 7d 0a 0a 20 20 20  esAt).    }..   
3820: 20 74 68 69 73 2e 64 65 62 75 67 28 27 61 63 6b   this.debug('ack
3830: 6e 6f 77 6c 65 64 67 69 6e 67 20 74 72 61 6e 73  nowledging trans
3840: 66 65 72 20 69 64 20 27 2c 20 74 72 61 6e 73 66  fer id ', transf
3850: 65 72 2e 69 64 29 0a 20 20 7d 0a 0a 20 20 61 73  er.id).  }..  as
3860: 79 6e 63 20 66 75 6c 66 69 6c 6c 43 6f 6e 64 69  ync fulfillCondi
3870: 74 69 6f 6e 20 28 74 72 61 6e 73 66 65 72 49 64  tion (transferId
3880: 2c 20 66 75 6c 66 69 6c 6c 6d 65 6e 74 2c 20 69  , fulfillment, i
3890: 6c 70 29 20 7b 0a 20 20 20 20 74 68 69 73 2e 61  lp) {.    this.a
38a0: 73 73 65 72 74 43 6f 6e 6e 65 63 74 69 6f 6e 42  ssertConnectionB
38b0: 65 66 6f 72 65 43 61 6c 6c 69 6e 67 28 27 66 75  eforeCalling('fu
38c0: 6c 66 69 6c 6c 43 6f 6e 64 69 74 69 6f 6e 27 29  lfillCondition')
38d0: 0a 20 20 20 20 74 68 69 73 2e 5f 76 61 6c 69 64  .    this._valid
38e0: 61 74 6f 72 2e 76 61 6c 69 64 61 74 65 46 75 6c  ator.validateFul
38f0: 66 69 6c 6c 6d 65 6e 74 28 66 75 6c 66 69 6c 6c  fillment(fulfill
3900: 6d 65 6e 74 29 0a 20 20 20 20 63 6f 6e 73 74 20  ment).    const 
3910: 74 72 61 6e 73 66 65 72 49 6e 66 6f 20 3d 20 61  transferInfo = a
3920: 77 61 69 74 20 74 68 69 73 2e 5f 74 72 61 6e 73  wait this._trans
3930: 66 65 72 73 2e 67 65 74 28 74 72 61 6e 73 66 65  fers.get(transfe
3940: 72 49 64 29 0a 0a 20 20 20 20 69 66 20 28 74 72  rId)..    if (tr
3950: 61 6e 73 66 65 72 49 6e 66 6f 2e 73 74 61 74 65  ansferInfo.state
3960: 20 3d 3d 3d 20 27 63 61 6e 63 65 6c 6c 65 64 27   === 'cancelled'
3970: 29 20 7b 0a 20 20 20 20 20 20 74 68 72 6f 77 20  ) {.      throw 
3980: 6e 65 77 20 41 6c 72 65 61 64 79 52 6f 6c 6c 65  new AlreadyRolle
3990: 64 42 61 63 6b 45 72 72 6f 72 28 74 72 61 6e 73  dBackError(trans
39a0: 66 65 72 49 64 20 2b 20 27 20 68 61 73 20 61 6c  ferId + ' has al
39b0: 72 65 61 64 79 20 62 65 65 6e 20 63 61 6e 63 65  ready been cance
39c0: 6c 6c 65 64 3a 20 27 20 2b 0a 20 20 20 20 20 20  lled: ' +.      
39d0: 20 20 4a 53 4f 4e 2e 73 74 72 69 6e 67 69 66 79    JSON.stringify
39e0: 28 74 72 61 6e 73 66 65 72 49 6e 66 6f 29 29 0a  (transferInfo)).
39f0: 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 20 28 21      }..    if (!
3a00: 74 72 61 6e 73 66 65 72 49 6e 66 6f 2e 69 73 49  transferInfo.isI
3a10: 6e 63 6f 6d 69 6e 67 29 20 7b 0a 20 20 20 20 20  ncoming) {.     
3a20: 20 74 68 72 6f 77 20 6e 65 77 20 45 72 72 6f 72   throw new Error
3a30: 28 74 72 61 6e 73 66 65 72 49 64 20 2b 20 27 20  (transferId + ' 
3a40: 69 73 20 6f 75 74 67 6f 69 6e 67 3b 20 63 61 6e  is outgoing; can
3a50: 6e 6f 74 20 66 75 6c 66 69 6c 6c 27 29 0a 20 20  not fulfill').  
3a60: 20 20 7d 0a 0a 20 20 20 20 69 66 20 28 6e 65 77    }..    if (new
3a70: 20 44 61 74 65 28 74 72 61 6e 73 66 65 72 49 6e   Date(transferIn
3a80: 66 6f 2e 74 72 61 6e 73 66 65 72 2e 65 78 70 69  fo.transfer.expi
3a90: 72 65 73 41 74 29 2e 67 65 74 54 69 6d 65 28 29  resAt).getTime()
3aa0: 20 3c 20 44 61 74 65 2e 6e 6f 77 28 29 29 20 7b   < Date.now()) {
3ab0: 0a 20 20 20 20 20 20 74 68 72 6f 77 20 6e 65 77  .      throw new
3ac0: 20 41 6c 72 65 61 64 79 52 6f 6c 6c 65 64 42 61   AlreadyRolledBa
3ad0: 63 6b 45 72 72 6f 72 28 74 72 61 6e 73 66 65 72  ckError(transfer
3ae0: 49 64 20 2b 20 27 20 68 61 73 20 61 6c 72 65 61  Id + ' has alrea
3af0: 64 79 20 65 78 70 69 72 65 64 3a 20 27 20 2b 0a  dy expired: ' +.
3b00: 20 20 20 20 20 20 20 20 4a 53 4f 4e 2e 73 74 72          JSON.str
3b10: 69 6e 67 69 66 79 28 74 72 61 6e 73 66 65 72 49  ingify(transferI
3b20: 6e 66 6f 29 29 0a 20 20 20 20 7d 0a 0a 20 20 20  nfo)).    }..   
3b30: 20 74 68 69 73 2e 5f 76 61 6c 69 64 61 74 65 46   this._validateF
3b40: 75 6c 66 69 6c 6c 6d 65 6e 74 28 66 75 6c 66 69  ulfillment(fulfi
3b50: 6c 6c 6d 65 6e 74 2c 20 74 72 61 6e 73 66 65 72  llment, transfer
3b60: 49 6e 66 6f 2e 74 72 61 6e 73 66 65 72 2e 65 78  Info.transfer.ex
3b70: 65 63 75 74 69 6f 6e 43 6f 6e 64 69 74 69 6f 6e  ecutionCondition
3b80: 29 0a 20 20 20 20 61 77 61 69 74 20 74 68 69 73  ).    await this
3b90: 2e 5f 74 72 61 6e 73 66 65 72 73 2e 66 75 6c 66  ._transfers.fulf
3ba0: 69 6c 6c 28 74 72 61 6e 73 66 65 72 49 64 2c 20  ill(transferId, 
3bb0: 66 75 6c 66 69 6c 6c 6d 65 6e 74 29 0a 20 20 20  fulfillment).   
3bc0: 20 74 68 69 73 2e 5f 73 61 66 65 45 6d 69 74 28   this._safeEmit(
3bd0: 27 69 6e 63 6f 6d 69 6e 67 5f 66 75 6c 66 69 6c  'incoming_fulfil
3be0: 6c 27 2c 20 74 72 61 6e 73 66 65 72 49 6e 66 6f  l', transferInfo
3bf0: 2e 74 72 61 6e 73 66 65 72 2c 20 66 75 6c 66 69  .transfer, fulfi
3c00: 6c 6c 6d 65 6e 74 29 0a 20 20 20 20 63 6f 6e 73  llment).    cons
3c10: 74 20 70 72 6f 74 6f 63 6f 6c 44 61 74 61 20 3d  t protocolData =
3c20: 20 69 6c 70 0a 20 20 20 20 20 20 3f 20 5b 7b 20   ilp.      ? [{ 
3c30: 70 72 6f 74 6f 63 6f 6c 4e 61 6d 65 3a 20 27 69  protocolName: 'i
3c40: 6c 70 27 2c 20 63 6f 6e 74 65 6e 74 54 79 70 65  lp', contentType
3c50: 3a 20 42 74 70 2e 4d 49 4d 45 5f 41 50 50 4c 49  : Btp.MIME_APPLI
3c60: 43 41 54 49 4f 4e 5f 4f 43 54 45 54 5f 53 54 52  CATION_OCTET_STR
3c70: 45 41 4d 2c 20 64 61 74 61 3a 20 42 75 66 66 65  EAM, data: Buffe
3c80: 72 2e 66 72 6f 6d 28 69 6c 70 2c 20 27 62 61 73  r.from(ilp, 'bas
3c90: 65 36 34 27 29 20 7d 5d 0a 20 20 20 20 20 20 3a  e64') }].      :
3ca0: 20 5b 5d 0a 20 20 20 20 63 6f 6e 73 74 20 72 65   [].    const re
3cb0: 73 75 6c 74 20 3d 20 61 77 61 69 74 20 74 68 69  sult = await thi
3cc0: 73 2e 5f 72 70 63 2e 66 75 6c 66 69 6c 6c 28 74  s._rpc.fulfill(t
3cd0: 72 61 6e 73 66 65 72 49 64 2c 20 66 75 6c 66 69  ransferId, fulfi
3ce0: 6c 6c 6d 65 6e 74 2c 20 70 72 6f 74 6f 63 6f 6c  llment, protocol
3cf0: 44 61 74 61 29 0a 0a 20 20 20 20 63 6f 6e 73 74  Data)..    const
3d00: 20 7b 20 70 72 6f 74 6f 63 6f 6c 4d 61 70 20 7d   { protocolMap }
3d10: 20 3d 20 70 72 6f 74 6f 63 6f 6c 44 61 74 61 54   = protocolDataT
3d20: 6f 49 6c 70 41 6e 64 43 75 73 74 6f 6d 28 72 65  oIlpAndCustom(re
3d30: 73 75 6c 74 29 0a 20 20 20 20 63 6f 6e 73 74 20  sult).    const 
3d40: 7b 20 63 6c 61 69 6d 20 7d 20 3d 20 70 72 6f 74  { claim } = prot
3d50: 6f 63 6f 6c 4d 61 70 20 7c 7c 20 7b 7d 0a 0a 20  ocolMap || {}.. 
3d60: 20 20 20 74 72 79 20 7b 0a 20 20 20 20 20 20 61     try {.      a
3d70: 77 61 69 74 20 74 68 69 73 2e 5f 70 61 79 63 68  wait this._paych
3d80: 61 6e 2e 68 61 6e 64 6c 65 49 6e 63 6f 6d 69 6e  an.handleIncomin
3d90: 67 43 6c 61 69 6d 28 74 68 69 73 2e 5f 70 61 79  gClaim(this._pay
3da0: 63 68 61 6e 43 6f 6e 74 65 78 74 2c 20 63 6c 61  chanContext, cla
3db0: 69 6d 29 0a 20 20 20 20 7d 20 63 61 74 63 68 20  im).    } catch 
3dc0: 28 65 29 20 7b 0a 20 20 20 20 20 20 74 68 69 73  (e) {.      this
3dd0: 2e 64 65 62 75 67 28 27 65 72 72 6f 72 20 68 61  .debug('error ha
3de0: 6e 64 6c 69 6e 67 20 69 6e 63 6f 6d 69 6e 67 20  ndling incoming 
3df0: 63 6c 61 69 6d 3a 27 2c 20 65 29 0a 20 20 20 20  claim:', e).    
3e00: 7d 0a 20 20 7d 0a 0a 20 20 61 73 79 6e 63 20 5f  }.  }..  async _
3e10: 68 61 6e 64 6c 65 46 75 6c 66 69 6c 6c 43 6f 6e  handleFulfillCon
3e20: 64 69 74 69 6f 6e 20 28 7b 64 61 74 61 7d 29 20  dition ({data}) 
3e30: 7b 0a 20 20 20 20 63 6f 6e 73 74 20 74 72 61 6e  {.    const tran
3e40: 73 66 65 72 49 64 20 3d 20 64 61 74 61 2e 69 64  sferId = data.id
3e50: 20 2f 2f 20 54 4f 44 4f 3a 20 75 73 65 6c 65 73   // TODO: useles
3e60: 73 20 72 65 77 72 69 74 65 0a 20 20 20 20 63 6f  s rewrite.    co
3e70: 6e 73 74 20 7b 20 69 6c 70 20 7d 20 3d 20 70 72  nst { ilp } = pr
3e80: 6f 74 6f 63 6f 6c 44 61 74 61 54 6f 49 6c 70 41  otocolDataToIlpA
3e90: 6e 64 43 75 73 74 6f 6d 28 64 61 74 61 29 0a 0a  ndCustom(data)..
3ea0: 20 20 20 20 74 68 69 73 2e 5f 76 61 6c 69 64 61      this._valida
3eb0: 74 6f 72 2e 76 61 6c 69 64 61 74 65 46 75 6c 66  tor.validateFulf
3ec0: 69 6c 6c 6d 65 6e 74 28 64 61 74 61 2e 66 75 6c  illment(data.ful
3ed0: 66 69 6c 6c 6d 65 6e 74 29 0a 20 20 20 20 63 6f  fillment).    co
3ee0: 6e 73 74 20 74 72 61 6e 73 66 65 72 49 6e 66 6f  nst transferInfo
3ef0: 20 3d 20 61 77 61 69 74 20 74 68 69 73 2e 5f 74   = await this._t
3f00: 72 61 6e 73 66 65 72 73 2e 67 65 74 28 74 72 61  ransfers.get(tra
3f10: 6e 73 66 65 72 49 64 29 0a 0a 20 20 20 20 69 66  nsferId)..    if
3f20: 20 28 74 72 61 6e 73 66 65 72 49 6e 66 6f 2e 73   (transferInfo.s
3f30: 74 61 74 65 20 3d 3d 3d 20 27 63 61 6e 63 65 6c  tate === 'cancel
3f40: 6c 65 64 27 29 20 7b 0a 20 20 20 20 20 20 74 68  led') {.      th
3f50: 72 6f 77 20 6e 65 77 20 41 6c 72 65 61 64 79 52  row new AlreadyR
3f60: 6f 6c 6c 65 64 42 61 63 6b 45 72 72 6f 72 28 74  olledBackError(t
3f70: 72 61 6e 73 66 65 72 49 64 20 2b 20 27 20 68 61  ransferId + ' ha
3f80: 73 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20 63  s already been c
3f90: 61 6e 63 65 6c 6c 65 64 3a 20 27 20 2b 0a 20 20  ancelled: ' +.  
3fa0: 20 20 20 20 20 20 4a 53 4f 4e 2e 73 74 72 69 6e        JSON.strin
3fb0: 67 69 66 79 28 74 72 61 6e 73 66 65 72 49 6e 66  gify(transferInf
3fc0: 6f 29 29 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69  o)).    }..    i
3fd0: 66 20 28 74 72 61 6e 73 66 65 72 49 6e 66 6f 2e  f (transferInfo.
3fe0: 69 73 49 6e 63 6f 6d 69 6e 67 29 20 7b 0a 20 20  isIncoming) {.  
3ff0: 20 20 20 20 74 68 72 6f 77 20 6e 65 77 20 45 72      throw new Er
4000: 72 6f 72 28 74 72 61 6e 73 66 65 72 49 64 20 2b  ror(transferId +
4010: 20 27 20 69 73 20 69 6e 63 6f 6d 69 6e 67 3b 20   ' is incoming; 
4020: 72 65 66 75 73 69 6e 67 20 74 6f 20 66 75 6c 66  refusing to fulf
4030: 69 6c 6c 2e 27 29 0a 20 20 20 20 7d 0a 0a 20 20  ill.').    }..  
4040: 20 20 69 66 20 28 6e 65 77 20 44 61 74 65 28 74    if (new Date(t
4050: 72 61 6e 73 66 65 72 49 6e 66 6f 2e 74 72 61 6e  ransferInfo.tran
4060: 73 66 65 72 2e 65 78 70 69 72 65 73 41 74 29 2e  sfer.expiresAt).
4070: 67 65 74 54 69 6d 65 28 29 20 3c 20 44 61 74 65  getTime() < Date
4080: 2e 6e 6f 77 28 29 29 20 7b 0a 20 20 20 20 20 20  .now()) {.      
4090: 74 68 72 6f 77 20 6e 65 77 20 41 6c 72 65 61 64  throw new Alread
40a0: 79 52 6f 6c 6c 65 64 42 61 63 6b 45 72 72 6f 72  yRolledBackError
40b0: 28 74 72 61 6e 73 66 65 72 49 64 20 2b 20 27 20  (transferId + ' 
40c0: 68 61 73 20 61 6c 72 65 61 64 79 20 65 78 70 69  has already expi
40d0: 72 65 64 3a 20 27 20 2b 0a 20 20 20 20 20 20 20  red: ' +.       
40e0: 20 4a 53 4f 4e 2e 73 74 72 69 6e 67 69 66 79 28   JSON.stringify(
40f0: 74 72 61 6e 73 66 65 72 49 6e 66 6f 29 29 0a 20  transferInfo)). 
4100: 20 20 20 7d 0a 0a 20 20 20 20 74 68 69 73 2e 5f     }..    this._
4110: 76 61 6c 69 64 61 74 65 46 75 6c 66 69 6c 6c 6d  validateFulfillm
4120: 65 6e 74 28 64 61 74 61 2e 66 75 6c 66 69 6c 6c  ent(data.fulfill
4130: 6d 65 6e 74 2c 20 74 72 61 6e 73 66 65 72 49 6e  ment, transferIn
4140: 66 6f 2e 74 72 61 6e 73 66 65 72 2e 65 78 65 63  fo.transfer.exec
4150: 75 74 69 6f 6e 43 6f 6e 64 69 74 69 6f 6e 29 0a  utionCondition).
4160: 20 20 20 20 61 77 61 69 74 20 74 68 69 73 2e 5f      await this._
4170: 74 72 61 6e 73 66 65 72 73 2e 66 75 6c 66 69 6c  transfers.fulfil
4180: 6c 28 74 72 61 6e 73 66 65 72 49 64 2c 20 64 61  l(transferId, da
4190: 74 61 2e 66 75 6c 66 69 6c 6c 6d 65 6e 74 29 0a  ta.fulfillment).
41a0: 20 20 20 20 74 68 69 73 2e 5f 73 61 66 65 45 6d      this._safeEm
41b0: 69 74 28 27 6f 75 74 67 6f 69 6e 67 5f 66 75 6c  it('outgoing_ful
41c0: 66 69 6c 6c 27 2c 20 74 72 61 6e 73 66 65 72 49  fill', transferI
41d0: 6e 66 6f 2e 74 72 61 6e 73 66 65 72 2c 20 64 61  nfo.transfer, da
41e0: 74 61 2e 66 75 6c 66 69 6c 6c 6d 65 6e 74 2c 20  ta.fulfillment, 
41f0: 69 6c 70 29 0a 0a 20 20 20 20 6c 65 74 20 72 65  ilp)..    let re
4200: 73 75 6c 74 0a 20 20 20 20 74 72 79 20 7b 0a 20  sult.    try {. 
4210: 20 20 20 20 20 72 65 73 75 6c 74 20 3d 20 61 77       result = aw
4220: 61 69 74 20 74 68 69 73 2e 5f 70 61 79 63 68 61  ait this._paycha
4230: 6e 2e 63 72 65 61 74 65 4f 75 74 67 6f 69 6e 67  n.createOutgoing
4240: 43 6c 61 69 6d 28 0a 20 20 20 20 20 20 20 20 74  Claim(.        t
4250: 68 69 73 2e 5f 70 61 79 63 68 61 6e 43 6f 6e 74  his._paychanCont
4260: 65 78 74 2c 0a 20 20 20 20 20 20 20 20 61 77 61  ext,.        awa
4270: 69 74 20 74 68 69 73 2e 5f 74 72 61 6e 73 66 65  it this._transfe
4280: 72 73 2e 67 65 74 4f 75 74 67 6f 69 6e 67 46 75  rs.getOutgoingFu
4290: 6c 66 69 6c 6c 65 64 28 29 29 0a 20 20 20 20 7d  lfilled()).    }
42a0: 20 63 61 74 63 68 20 28 65 29 20 7b 0a 20 20 20   catch (e) {.   
42b0: 20 20 20 74 68 69 73 2e 64 65 62 75 67 28 27 65     this.debug('e
42c0: 72 72 6f 72 20 63 72 65 61 74 69 6e 67 20 6f 75  rror creating ou
42d0: 74 67 6f 69 6e 67 20 63 6c 61 69 6d 3a 27 2c 20  tgoing claim:', 
42e0: 65 29 0a 20 20 20 20 7d 0a 0a 20 20 20 20 72 65  e).    }..    re
42f0: 74 75 72 6e 20 72 65 73 75 6c 74 20 3d 3d 3d 20  turn result === 
4300: 75 6e 64 65 66 69 6e 65 64 20 3f 20 5b 5d 20 3a  undefined ? [] :
4310: 20 69 6c 70 41 6e 64 43 75 73 74 6f 6d 54 6f 50   ilpAndCustomToP
4320: 72 6f 74 6f 63 6f 6c 44 61 74 61 28 7b 0a 20 20  rotocolData({.  
4330: 20 20 20 20 70 72 6f 74 6f 63 6f 6c 4d 61 70 3a      protocolMap:
4340: 20 7b 0a 20 20 20 20 20 20 20 20 63 6c 61 69 6d   {.        claim
4350: 3a 20 72 65 73 75 6c 74 0a 20 20 20 20 20 20 7d  : result.      }
4360: 0a 20 20 20 20 7d 29 0a 20 20 7d 0a 0a 20 20 2f  .    }).  }..  /
4370: 2f 20 54 4f 44 4f 3a 20 63 6c 61 72 69 66 79 20  / TODO: clarify 
4380: 74 68 65 20 74 79 70 65 20 6f 66 20 72 65 61 73  the type of reas
4390: 6f 6e 0a 20 20 61 73 79 6e 63 20 72 65 6a 65 63  on.  async rejec
43a0: 74 49 6e 63 6f 6d 69 6e 67 54 72 61 6e 73 66 65  tIncomingTransfe
43b0: 72 20 28 74 72 61 6e 73 66 65 72 49 64 2c 20 72  r (transferId, r
43c0: 65 61 73 6f 6e 29 20 7b 0a 20 20 20 20 74 68 69  eason) {.    thi
43d0: 73 2e 61 73 73 65 72 74 43 6f 6e 6e 65 63 74 69  s.assertConnecti
43e0: 6f 6e 42 65 66 6f 72 65 43 61 6c 6c 69 6e 67 28  onBeforeCalling(
43f0: 27 72 65 6a 65 63 74 49 6e 63 6f 6d 69 6e 67 54  'rejectIncomingT
4400: 72 61 6e 73 66 65 72 27 29 0a 20 20 20 20 74 68  ransfer').    th
4410: 69 73 2e 64 65 62 75 67 28 27 67 6f 69 6e 67 20  is.debug('going 
4420: 74 6f 20 72 65 6a 65 63 74 20 27 20 2b 20 74 72  to reject ' + tr
4430: 61 6e 73 66 65 72 49 64 29 0a 20 20 20 20 63 6f  ansferId).    co
4440: 6e 73 74 20 74 72 61 6e 73 66 65 72 49 6e 66 6f  nst transferInfo
4450: 20 3d 20 61 77 61 69 74 20 74 68 69 73 2e 5f 74   = await this._t
4460: 72 61 6e 73 66 65 72 73 2e 67 65 74 28 74 72 61  ransfers.get(tra
4470: 6e 73 66 65 72 49 64 29 0a 0a 20 20 20 20 69 66  nsferId)..    if
4480: 20 28 74 72 61 6e 73 66 65 72 49 6e 66 6f 2e 73   (transferInfo.s
4490: 74 61 74 65 20 3d 3d 3d 20 27 66 75 6c 66 69 6c  tate === 'fulfil
44a0: 6c 65 64 27 29 20 7b 0a 20 20 20 20 20 20 74 68  led') {.      th
44b0: 72 6f 77 20 6e 65 77 20 41 6c 72 65 61 64 79 46  row new AlreadyF
44c0: 75 6c 66 69 6c 6c 65 64 45 72 72 6f 72 28 74 72  ulfilledError(tr
44d0: 61 6e 73 66 65 72 49 64 20 2b 20 27 20 68 61 73  ansferId + ' has
44e0: 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20 66 75   already been fu
44f0: 6c 66 69 6c 6c 65 64 3a 20 27 20 2b 0a 20 20 20  lfilled: ' +.   
4500: 20 20 20 20 20 4a 53 4f 4e 2e 73 74 72 69 6e 67       JSON.string
4510: 69 66 79 28 74 72 61 6e 73 66 65 72 49 6e 66 6f  ify(transferInfo
4520: 29 29 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66  )).    }..    if
4530: 20 28 21 74 72 61 6e 73 66 65 72 49 6e 66 6f 2e   (!transferInfo.
4540: 69 73 49 6e 63 6f 6d 69 6e 67 29 20 7b 0a 20 20  isIncoming) {.  
4550: 20 20 20 20 74 68 72 6f 77 20 6e 65 77 20 45 72      throw new Er
4560: 72 6f 72 28 74 72 61 6e 73 66 65 72 49 64 20 2b  ror(transferId +
4570: 20 27 20 69 73 20 6f 75 74 67 6f 69 6e 67 3b 20   ' is outgoing; 
4580: 63 61 6e 6e 6f 74 20 72 65 6a 65 63 74 2e 27 29  cannot reject.')
4590: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2f 20 54  .    }..    // T
45a0: 4f 44 4f 3a 20 61 64 64 20 72 65 6a 65 63 74 69  ODO: add rejecti
45b0: 6f 6e 52 65 61 73 6f 6e 20 74 6f 20 69 6e 74 65  onReason to inte
45c0: 72 66 61 63 65 0a 20 20 20 20 61 77 61 69 74 20  rface.    await 
45d0: 74 68 69 73 2e 5f 74 72 61 6e 73 66 65 72 73 2e  this._transfers.
45e0: 63 61 6e 63 65 6c 28 74 72 61 6e 73 66 65 72 49  cancel(transferI
45f0: 64 2c 20 72 65 61 73 6f 6e 29 0a 20 20 20 20 74  d, reason).    t
4600: 68 69 73 2e 64 65 62 75 67 28 27 72 65 6a 65 63  his.debug('rejec
4610: 74 65 64 20 27 20 2b 20 74 72 61 6e 73 66 65 72  ted ' + transfer
4620: 49 64 29 0a 0a 20 20 20 20 6c 65 74 20 66 6f 72  Id)..    let for
4630: 77 61 72 64 65 64 42 79 0a 20 20 20 20 69 66 20  wardedBy.    if 
4640: 28 41 72 72 61 79 2e 69 73 41 72 72 61 79 28 72  (Array.isArray(r
4650: 65 61 73 6f 6e 2e 66 6f 72 77 61 72 64 65 64 5f  eason.forwarded_
4660: 62 79 29 29 20 7b 0a 20 20 20 20 20 20 66 6f 72  by)) {.      for
4670: 77 61 72 64 65 64 42 79 20 3d 20 72 65 61 73 6f  wardedBy = reaso
4680: 6e 2e 66 6f 72 77 61 72 64 65 64 5f 62 79 0a 20  n.forwarded_by. 
4690: 20 20 20 7d 20 65 6c 73 65 20 69 66 20 28 74 79     } else if (ty
46a0: 70 65 6f 66 20 72 65 61 73 6f 6e 2e 66 6f 72 77  peof reason.forw
46b0: 61 72 64 65 64 5f 62 79 20 3d 3d 3d 20 27 73 74  arded_by === 'st
46c0: 72 69 6e 67 27 29 20 7b 0a 20 20 20 20 20 20 66  ring') {.      f
46d0: 6f 72 77 61 72 64 65 64 42 79 20 3d 20 5b 72 65  orwardedBy = [re
46e0: 61 73 6f 6e 2e 66 6f 72 77 61 72 64 65 64 5f 62  ason.forwarded_b
46f0: 79 5d 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a  y].    } else {.
4700: 20 20 20 20 20 20 66 6f 72 77 61 72 64 65 64 42        forwardedB
4710: 79 20 3d 20 5b 74 68 69 73 2e 67 65 74 41 63 63  y = [this.getAcc
4720: 6f 75 6e 74 28 29 5d 0a 20 20 20 20 7d 0a 20 20  ount()].    }.  
4730: 20 20 63 6f 6e 73 74 20 72 65 6a 65 63 74 69 6f    const rejectio
4740: 6e 52 65 61 73 6f 6e 20 3d 20 69 6c 70 50 61 63  nReason = ilpPac
4750: 6b 65 74 2e 73 65 72 69 61 6c 69 7a 65 49 6c 70  ket.serializeIlp
4760: 45 72 72 6f 72 28 7b 0a 20 20 20 20 20 20 63 6f  Error({.      co
4770: 64 65 3a 20 72 65 61 73 6f 6e 2e 63 6f 64 65 2c  de: reason.code,
4780: 0a 20 20 20 20 20 20 6e 61 6d 65 3a 20 72 65 61  .      name: rea
4790: 73 6f 6e 2e 6e 61 6d 65 2c 0a 20 20 20 20 20 20  son.name,.      
47a0: 74 72 69 67 67 65 72 65 64 42 79 3a 20 72 65 61  triggeredBy: rea
47b0: 73 6f 6e 2e 74 72 69 67 67 65 72 65 64 5f 62 79  son.triggered_by
47c0: 2c 0a 20 20 20 20 20 20 66 6f 72 77 61 72 64 65  ,.      forwarde
47d0: 64 42 79 2c 0a 20 20 20 20 20 20 74 72 69 67 67  dBy,.      trigg
47e0: 65 72 65 64 41 74 3a 20 72 65 61 73 6f 6e 2e 74  eredAt: reason.t
47f0: 72 69 67 67 65 72 65 64 5f 61 74 2c 0a 20 20 20  riggered_at,.   
4800: 20 20 20 64 61 74 61 3a 20 4a 53 4f 4e 2e 73 74     data: JSON.st
4810: 72 69 6e 67 69 66 79 28 72 65 61 73 6f 6e 2e 61  ringify(reason.a
4820: 64 64 69 74 69 6f 6e 61 6c 5f 69 6e 66 6f 29 20  dditional_info) 
4830: 7c 7c 20 27 27 0a 20 20 20 20 7d 29 0a 0a 20 20  || ''.    })..  
4840: 20 20 74 68 69 73 2e 5f 73 61 66 65 45 6d 69 74    this._safeEmit
4850: 28 27 69 6e 63 6f 6d 69 6e 67 5f 72 65 6a 65 63  ('incoming_rejec
4860: 74 27 2c 20 74 72 61 6e 73 66 65 72 49 6e 66 6f  t', transferInfo
4870: 2e 74 72 61 6e 73 66 65 72 2c 20 72 65 61 73 6f  .transfer, reaso
4880: 6e 29 0a 20 20 20 20 61 77 61 69 74 20 74 68 69  n).    await thi
4890: 73 2e 5f 72 70 63 2e 72 65 6a 65 63 74 28 74 72  s._rpc.reject(tr
48a0: 61 6e 73 66 65 72 49 64 2c 20 5b 7b 0a 20 20 20  ansferId, [{.   
48b0: 20 20 20 70 72 6f 74 6f 63 6f 6c 4e 61 6d 65 3a     protocolName:
48c0: 20 27 69 6c 70 27 2c 0a 20 20 20 20 20 20 63 6f   'ilp',.      co
48d0: 6e 74 65 6e 74 54 79 70 65 3a 20 42 74 70 2e 4d  ntentType: Btp.M
48e0: 49 4d 45 5f 41 50 50 4c 49 43 41 54 49 4f 4e 5f  IME_APPLICATION_
48f0: 4f 43 54 45 54 5f 53 54 52 45 41 4d 2c 0a 20 20  OCTET_STREAM,.  
4900: 20 20 20 20 64 61 74 61 3a 20 72 65 6a 65 63 74      data: reject
4910: 69 6f 6e 52 65 61 73 6f 6e 0a 20 20 20 20 7d 5d  ionReason.    }]
4920: 29 0a 20 20 7d 0a 0a 20 20 61 73 79 6e 63 20 5f  ).  }..  async _
4930: 68 61 6e 64 6c 65 52 65 6a 65 63 74 49 6e 63 6f  handleRejectInco
4940: 6d 69 6e 67 54 72 61 6e 73 66 65 72 20 28 7b 64  mingTransfer ({d
4950: 61 74 61 7d 29 20 7b 0a 20 20 20 20 63 6f 6e 73  ata}) {.    cons
4960: 74 20 74 72 61 6e 73 66 65 72 49 64 20 3d 20 64  t transferId = d
4970: 61 74 61 2e 69 64 0a 20 20 20 20 63 6f 6e 73 74  ata.id.    const
4980: 20 7b 20 69 6c 70 20 7d 20 3d 20 70 72 6f 74 6f   { ilp } = proto
4990: 63 6f 6c 44 61 74 61 54 6f 49 6c 70 41 6e 64 43  colDataToIlpAndC
49a0: 75 73 74 6f 6d 28 64 61 74 61 29 0a 20 20 20 20  ustom(data).    
49b0: 63 6f 6e 73 74 20 70 61 63 6b 65 74 20 3d 20 69  const packet = i
49c0: 6c 70 50 61 63 6b 65 74 2e 64 65 73 65 72 69 61  lpPacket.deseria
49d0: 6c 69 7a 65 49 6c 70 50 61 63 6b 65 74 28 42 75  lizeIlpPacket(Bu
49e0: 66 66 65 72 2e 66 72 6f 6d 28 69 6c 70 2c 20 27  ffer.from(ilp, '
49f0: 62 61 73 65 36 34 27 29 29 2e 64 61 74 61 0a 20  base64')).data. 
4a00: 20 20 20 63 6f 6e 73 74 20 6c 61 73 74 43 6f 6e     const lastCon
4a10: 6e 65 63 74 6f 72 20 3d 20 70 61 63 6b 65 74 2e  nector = packet.
4a20: 66 6f 72 77 61 72 64 65 64 42 79 5b 70 61 63 6b  forwardedBy[pack
4a30: 65 74 2e 66 6f 72 77 61 72 64 65 64 42 79 2e 6c  et.forwardedBy.l
4a40: 65 6e 67 74 68 20 2d 20 31 5d 0a 20 20 20 20 63  ength - 1].    c
4a50: 6f 6e 73 74 20 72 65 6a 65 63 74 69 6f 6e 52 65  onst rejectionRe
4a60: 61 73 6f 6e 20 3d 20 7b 0a 20 20 20 20 20 20 63  ason = {.      c
4a70: 6f 64 65 3a 20 70 61 63 6b 65 74 2e 63 6f 64 65  ode: packet.code
4a80: 2c 0a 20 20 20 20 20 20 6e 61 6d 65 3a 20 70 61  ,.      name: pa
4a90: 63 6b 65 74 2e 6e 61 6d 65 2c 0a 20 20 20 20 20  cket.name,.     
4aa0: 20 74 72 69 67 67 65 72 65 64 5f 62 79 3a 20 70   triggered_by: p
4ab0: 61 63 6b 65 74 2e 74 72 69 67 67 65 72 65 64 42  acket.triggeredB
4ac0: 79 2c 0a 20 20 20 20 20 20 66 6f 72 77 61 72 64  y,.      forward
4ad0: 65 64 5f 62 79 3a 20 6c 61 73 74 43 6f 6e 6e 65  ed_by: lastConne
4ae0: 63 74 6f 72 2c 0a 20 20 20 20 20 20 74 72 69 67  ctor,.      trig
4af0: 67 65 72 65 64 5f 61 74 3a 20 70 61 63 6b 65 74  gered_at: packet
4b00: 2e 74 72 69 67 67 65 72 65 64 41 74 0a 20 20 20  .triggeredAt.   
4b10: 20 7d 0a 20 20 20 20 74 72 79 20 7b 0a 20 20 20   }.    try {.   
4b20: 20 20 20 72 65 6a 65 63 74 69 6f 6e 52 65 61 73     rejectionReas
4b30: 6f 6e 2e 61 64 64 69 74 69 6f 6e 61 6c 5f 69 6e  on.additional_in
4b40: 66 6f 20 3d 20 4a 53 4f 4e 2e 70 61 72 73 65 28  fo = JSON.parse(
4b50: 70 61 63 6b 65 74 2e 64 61 74 61 29 0a 20 20 20  packet.data).   
4b60: 20 7d 20 63 61 74 63 68 20 28 65 29 20 7b 0a 20   } catch (e) {. 
4b70: 20 20 20 20 20 72 65 6a 65 63 74 69 6f 6e 52 65       rejectionRe
4b80: 61 73 6f 6e 2e 61 64 64 69 74 69 6f 6e 61 6c 5f  ason.additional_
4b90: 69 6e 66 6f 20 3d 20 27 6e 6f 74 20 4a 53 4f 4e  info = 'not JSON
4ba0: 27 0a 20 20 20 20 7d 0a 0a 20 20 20 20 74 68 69  '.    }..    thi
4bb0: 73 2e 64 65 62 75 67 28 27 68 61 6e 64 6c 69 6e  s.debug('handlin
4bc0: 67 20 72 65 6a 65 63 74 69 6f 6e 20 6f 66 20 27  g rejection of '
4bd0: 20 2b 20 74 72 61 6e 73 66 65 72 49 64 29 0a 20   + transferId). 
4be0: 20 20 20 63 6f 6e 73 74 20 74 72 61 6e 73 66 65     const transfe
4bf0: 72 49 6e 66 6f 20 3d 20 61 77 61 69 74 20 74 68  rInfo = await th
4c00: 69 73 2e 5f 74 72 61 6e 73 66 65 72 73 2e 67 65  is._transfers.ge
4c10: 74 28 74 72 61 6e 73 66 65 72 49 64 29 0a 0a 20  t(transferId).. 
4c20: 20 20 20 69 66 20 28 74 72 61 6e 73 66 65 72 49     if (transferI
4c30: 6e 66 6f 2e 73 74 61 74 65 20 3d 3d 3d 20 27 66  nfo.state === 'f
4c40: 75 6c 66 69 6c 6c 65 64 27 29 20 7b 0a 20 20 20  ulfilled') {.   
4c50: 20 20 20 74 68 72 6f 77 20 6e 65 77 20 41 6c 72     throw new Alr
4c60: 65 61 64 79 46 75 6c 66 69 6c 6c 65 64 45 72 72  eadyFulfilledErr
4c70: 6f 72 28 74 72 61 6e 73 66 65 72 49 64 20 2b 20  or(transferId + 
4c80: 27 20 68 61 73 20 61 6c 72 65 61 64 79 20 62 65  ' has already be
4c90: 65 6e 20 66 75 6c 66 69 6c 6c 65 64 3a 20 27 20  en fulfilled: ' 
4ca0: 2b 0a 20 20 20 20 20 20 20 20 4a 53 4f 4e 2e 73  +.        JSON.s
4cb0: 74 72 69 6e 67 69 66 79 28 74 72 61 6e 73 66 65  tringify(transfe
4cc0: 72 49 6e 66 6f 29 29 0a 20 20 20 20 7d 0a 0a 20  rInfo)).    }.. 
4cd0: 20 20 20 69 66 20 28 74 72 61 6e 73 66 65 72 49     if (transferI
4ce0: 6e 66 6f 2e 69 73 49 6e 63 6f 6d 69 6e 67 29 20  nfo.isIncoming) 
4cf0: 7b 0a 20 20 20 20 20 20 74 68 72 6f 77 20 6e 65  {.      throw ne
4d00: 77 20 45 72 72 6f 72 28 74 72 61 6e 73 66 65 72  w Error(transfer
4d10: 49 64 20 2b 20 27 20 69 73 20 69 6e 63 6f 6d 69  Id + ' is incomi
4d20: 6e 67 3b 20 70 65 65 72 20 63 61 6e 6e 6f 74 20  ng; peer cannot 
4d30: 72 65 6a 65 63 74 2e 27 29 0a 20 20 20 20 7d 0a  reject.').    }.
4d40: 0a 20 20 20 20 2f 2f 20 54 4f 44 4f 3a 20 61 64  .    // TODO: ad
4d50: 64 20 72 65 6a 65 63 74 69 6f 6e 52 65 61 73 6f  d rejectionReaso
4d60: 6e 20 74 6f 20 69 6e 74 65 72 66 61 63 65 0a 20  n to interface. 
4d70: 20 20 20 61 77 61 69 74 20 74 68 69 73 2e 5f 74     await this._t
4d80: 72 61 6e 73 66 65 72 73 2e 63 61 6e 63 65 6c 28  ransfers.cancel(
4d90: 74 72 61 6e 73 66 65 72 49 64 2c 20 72 65 6a 65  transferId, reje
4da0: 63 74 69 6f 6e 52 65 61 73 6f 6e 29 0a 20 20 20  ctionReason).   
4db0: 20 74 68 69 73 2e 64 65 62 75 67 28 27 70 65 65   this.debug('pee
4dc0: 72 20 72 65 6a 65 63 74 65 64 20 27 20 2b 20 74  r rejected ' + t
4dd0: 72 61 6e 73 66 65 72 49 64 29 0a 0a 20 20 20 20  ransferId)..    
4de0: 74 68 69 73 2e 5f 73 61 66 65 45 6d 69 74 28 27  this._safeEmit('
4df0: 6f 75 74 67 6f 69 6e 67 5f 72 65 6a 65 63 74 27  outgoing_reject'
4e00: 2c 20 74 72 61 6e 73 66 65 72 49 6e 66 6f 2e 74  , transferInfo.t
4e10: 72 61 6e 73 66 65 72 2c 20 72 65 6a 65 63 74 69  ransfer, rejecti
4e20: 6f 6e 52 65 61 73 6f 6e 29 0a 20 20 7d 0a 0a 20  onReason).  }.. 
4e30: 20 61 73 79 6e 63 20 67 65 74 42 61 6c 61 6e 63   async getBalanc
4e40: 65 20 28 29 20 7b 0a 20 20 20 20 74 68 69 73 2e  e () {.    this.
4e50: 61 73 73 65 72 74 43 6f 6e 6e 65 63 74 69 6f 6e  assertConnection
4e60: 42 65 66 6f 72 65 43 61 6c 6c 69 6e 67 28 27 67  BeforeCalling('g
4e70: 65 74 42 61 6c 61 6e 63 65 27 29 0a 20 20 20 20  etBalance').    
4e80: 69 66 20 28 74 68 69 73 2e 5f 73 74 61 74 65 66  if (this._statef
4e90: 75 6c 29 20 7b 0a 20 20 20 20 20 20 72 65 74 75  ul) {.      retu
4ea0: 72 6e 20 74 68 69 73 2e 5f 74 72 61 6e 73 66 65  rn this._transfe
4eb0: 72 73 2e 67 65 74 42 61 6c 61 6e 63 65 28 29 0a  rs.getBalance().
4ec0: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
4ed0: 20 20 20 72 65 74 75 72 6e 20 74 68 69 73 2e 67     return this.g
4ee0: 65 74 50 65 65 72 42 61 6c 61 6e 63 65 28 29 0a  etPeerBalance().
4ef0: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 61 73 79      }.  }..  asy
4f00: 6e 63 20 5f 68 61 6e 64 6c 65 47 65 74 42 61 6c  nc _handleGetBal
4f10: 61 6e 63 65 20 28 29 20 7b 0a 20 20 20 20 72 65  ance () {.    re
4f20: 74 75 72 6e 20 74 68 69 73 2e 5f 74 72 61 6e 73  turn this._trans
4f30: 66 65 72 73 2e 67 65 74 42 61 6c 61 6e 63 65 28  fers.getBalance(
4f40: 29 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54 4f 44 4f  ).  }..  /* TODO
4f50: 3a 20 72 65 61 73 73 65 73 73 20 77 68 65 74 68  : reassess wheth
4f60: 65 72 20 74 68 69 73 20 69 73 20 65 76 65 72 20  er this is ever 
4f70: 6e 65 65 64 65 64 0a 20 20 61 73 79 6e 63 20 67  needed.  async g
4f80: 65 74 46 75 6c 66 69 6c 6c 6d 65 6e 74 20 28 74  etFulfillment (t
4f90: 72 61 6e 73 66 65 72 49 64 29 20 7b 0a 20 20 20  ransferId) {.   
4fa0: 20 74 68 69 73 2e 61 73 73 65 72 74 43 6f 6e 6e   this.assertConn
4fb0: 65 63 74 69 6f 6e 42 65 66 6f 72 65 43 61 6c 6c  ectionBeforeCall
4fc0: 69 6e 67 28 27 67 65 74 46 75 6c 66 69 6c 6c 6d  ing('getFulfillm
4fd0: 65 6e 74 27 29 0a 20 20 20 20 69 66 20 28 74 68  ent').    if (th
4fe0: 69 73 2e 5f 73 74 61 74 65 66 75 6c 29 20 7b 0a  is._stateful) {.
4ff0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 74 68 69        return thi
5000: 73 2e 5f 74 72 61 6e 73 66 65 72 73 2e 67 65 74  s._transfers.get
5010: 46 75 6c 66 69 6c 6c 6d 65 6e 74 28 74 72 61 6e  Fulfillment(tran
5020: 73 66 65 72 49 64 29 0a 20 20 20 20 7d 20 65 6c  sferId).    } el
5030: 73 65 20 7b 0a 20 20 20 20 20 20 72 65 74 75 72  se {.      retur
5040: 6e 20 74 68 69 73 2e 5f 72 70 63 2e 63 61 6c 6c  n this._rpc.call
5050: 28 27 67 65 74 5f 66 75 6c 66 69 6c 6c 6d 65 6e  ('get_fulfillmen
5060: 74 27 2c 20 74 68 69 73 2e 5f 70 72 65 66 69 78  t', this._prefix
5070: 2c 20 5b 20 74 72 61 6e 73 66 65 72 49 64 20 5d  , [ transferId ]
5080: 29 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 2f  ).    }.  }.  */
5090: 0a 0a 20 20 5f 73 65 74 75 70 54 72 61 6e 73 66  ..  _setupTransf
50a0: 65 72 45 78 70 69 72 79 20 28 74 72 61 6e 73 66  erExpiry (transf
50b0: 65 72 49 64 2c 20 65 78 70 69 72 65 73 41 74 29  erId, expiresAt)
50c0: 20 7b 0a 20 20 20 20 63 6f 6e 73 74 20 65 78 70   {.    const exp
50d0: 69 72 79 20 3d 20 44 61 74 65 2e 70 61 72 73 65  iry = Date.parse
50e0: 28 65 78 70 69 72 65 73 41 74 29 0a 20 20 20 20  (expiresAt).    
50f0: 63 6f 6e 73 74 20 6e 6f 77 20 3d 20 6e 65 77 20  const now = new 
5100: 44 61 74 65 28 29 0a 0a 20 20 20 20 73 65 74 54  Date()..    setT
5110: 69 6d 65 6f 75 74 28 0a 20 20 20 20 20 20 74 68  imeout(.      th
5120: 69 73 2e 5f 65 78 70 69 72 65 54 72 61 6e 73 66  is._expireTransf
5130: 65 72 2e 62 69 6e 64 28 74 68 69 73 2c 20 74 72  er.bind(this, tr
5140: 61 6e 73 66 65 72 49 64 29 2c 0a 20 20 20 20 20  ansferId),.     
5150: 20 28 65 78 70 69 72 79 20 2d 20 6e 6f 77 29 29   (expiry - now))
5160: 0a 20 20 7d 0a 0a 20 20 61 73 79 6e 63 20 5f 65  .  }..  async _e
5170: 78 70 69 72 65 54 72 61 6e 73 66 65 72 20 28 74  xpireTransfer (t
5180: 72 61 6e 73 66 65 72 49 64 29 20 7b 0a 20 20 20  ransferId) {.   
5190: 20 63 6f 6e 73 74 20 74 72 61 6e 73 66 65 72 49   const transferI
51a0: 6e 66 6f 20 3d 20 61 77 61 69 74 20 74 68 69 73  nfo = await this
51b0: 2e 5f 74 72 61 6e 73 66 65 72 73 2e 67 65 74 28  ._transfers.get(
51c0: 74 72 61 6e 73 66 65 72 49 64 29 0a 20 20 20 20  transferId).    
51d0: 69 66 20 28 21 74 72 61 6e 73 66 65 72 49 6e 66  if (!transferInf
51e0: 6f 20 7c 7c 20 74 72 61 6e 73 66 65 72 49 6e 66  o || transferInf
51f0: 6f 2e 73 74 61 74 65 20 21 3d 3d 20 27 70 72 65  o.state !== 'pre
5200: 70 61 72 65 64 27 29 20 72 65 74 75 72 6e 0a 0a  pared') return..
5210: 20 20 20 20 74 68 69 73 2e 64 65 62 75 67 28 27      this.debug('
5220: 74 69 6d 69 6e 67 20 6f 75 74 20 27 20 2b 20 74  timing out ' + t
5230: 72 61 6e 73 66 65 72 49 64 29 0a 20 20 20 20 74  ransferId).    t
5240: 72 79 20 7b 0a 20 20 20 20 20 20 61 77 61 69 74  ry {.      await
5250: 20 74 68 69 73 2e 5f 74 72 61 6e 73 66 65 72 73   this._transfers
5260: 2e 63 61 6e 63 65 6c 28 74 72 61 6e 73 66 65 72  .cancel(transfer
5270: 49 64 2c 20 27 65 78 70 69 72 65 64 27 29 0a 20  Id, 'expired'). 
5280: 20 20 20 7d 20 63 61 74 63 68 20 28 65 29 20 7b     } catch (e) {
5290: 0a 20 20 20 20 20 20 74 68 69 73 2e 64 65 62 75  .      this.debu
52a0: 67 28 27 65 72 72 6f 72 20 65 78 70 69 72 69 6e  g('error expirin
52b0: 67 20 27 20 2b 20 74 72 61 6e 73 66 65 72 49 64  g ' + transferId
52c0: 20 2b 20 27 3a 20 27 20 2b 20 65 2e 6d 65 73 73   + ': ' + e.mess
52d0: 61 67 65 29 0a 20 20 20 20 20 20 72 65 74 75 72  age).      retur
52e0: 6e 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63 6f 6e  n.    }..    con
52f0: 73 74 20 72 65 6a 65 63 74 69 6f 6e 52 65 61 73  st rejectionReas
5300: 6f 6e 20 3d 20 69 6c 70 50 61 63 6b 65 74 2e 73  on = ilpPacket.s
5310: 65 72 69 61 6c 69 7a 65 49 6c 70 45 72 72 6f 72  erializeIlpError
5320: 28 7b 0a 20 20 20 20 20 20 63 6f 64 65 3a 20 27  ({.      code: '
5330: 52 30 30 27 2c 0a 20 20 20 20 20 20 6e 61 6d 65  R00',.      name
5340: 3a 20 27 54 72 61 6e 73 66 65 72 20 54 69 6d 65  : 'Transfer Time
5350: 64 20 4f 75 74 27 2c 0a 20 20 20 20 20 20 74 72  d Out',.      tr
5360: 69 67 67 65 72 65 64 42 79 3a 20 74 68 69 73 2e  iggeredBy: this.
5370: 67 65 74 41 63 63 6f 75 6e 74 28 29 2c 0a 20 20  getAccount(),.  
5380: 20 20 20 20 66 6f 72 77 61 72 64 65 64 42 79 3a      forwardedBy:
5390: 20 5b 5d 2c 0a 20 20 20 20 20 20 74 72 69 67 67   [],.      trigg
53a0: 65 72 65 64 41 74 3a 20 6e 65 77 20 44 61 74 65  eredAt: new Date
53b0: 28 29 2c 0a 20 20 20 20 20 20 64 61 74 61 3a 20  (),.      data: 
53c0: 27 65 78 70 69 72 65 64 27 0a 20 20 20 20 7d 29  'expired'.    })
53d0: 0a 0a 20 20 20 20 61 77 61 69 74 20 74 68 69 73  ..    await this
53e0: 2e 5f 72 70 63 2e 72 65 6a 65 63 74 28 74 72 61  ._rpc.reject(tra
53f0: 6e 73 66 65 72 49 64 2c 20 5b 7b 0a 20 20 20 20  nsferId, [{.    
5400: 20 20 70 72 6f 74 6f 63 6f 6c 4e 61 6d 65 3a 20    protocolName: 
5410: 27 69 6c 70 27 2c 0a 20 20 20 20 20 20 63 6f 6e  'ilp',.      con
5420: 74 65 6e 74 54 79 70 65 3a 20 42 74 70 2e 4d 49  tentType: Btp.MI
5430: 4d 45 5f 41 50 50 4c 49 43 41 54 49 4f 4e 5f 4f  ME_APPLICATION_O
5440: 43 54 45 54 5f 53 54 52 45 41 4d 2c 0a 20 20 20  CTET_STREAM,.   
5450: 20 20 20 64 61 74 61 3a 20 72 65 6a 65 63 74 69     data: rejecti
5460: 6f 6e 52 65 61 73 6f 6e 0a 20 20 20 20 7d 5d 29  onReason.    }])
5470: 2e 63 61 74 63 68 28 28 29 20 3d 3e 20 7b 7d 29  .catch(() => {})
5480: 0a 20 20 20 20 74 68 69 73 2e 5f 73 61 66 65 45  .    this._safeE
5490: 6d 69 74 28 28 74 72 61 6e 73 66 65 72 49 6e 66  mit((transferInf
54a0: 6f 2e 69 73 49 6e 63 6f 6d 69 6e 67 20 3f 20 27  o.isIncoming ? '
54b0: 69 6e 63 6f 6d 69 6e 67 27 20 3a 20 27 6f 75 74  incoming' : 'out
54c0: 67 6f 69 6e 67 27 29 20 2b 20 27 5f 63 61 6e 63  going') + '_canc
54d0: 65 6c 27 2c 0a 20 20 20 20 20 20 74 72 61 6e 73  el',.      trans
54e0: 66 65 72 49 6e 66 6f 2e 74 72 61 6e 73 66 65 72  ferInfo.transfer
54f0: 29 0a 20 20 7d 0a 0a 20 20 61 73 79 6e 63 20 5f  ).  }..  async _
5500: 68 61 6e 64 6c 65 45 78 70 69 72 65 54 72 61 6e  handleExpireTran
5510: 73 66 65 72 20 28 74 72 61 6e 73 66 65 72 49 64  sfer (transferId
5520: 29 20 7b 0a 20 20 20 20 63 6f 6e 73 74 20 74 72  ) {.    const tr
5530: 61 6e 73 66 65 72 49 6e 66 6f 20 3d 20 61 77 61  ansferInfo = awa
5540: 69 74 20 74 68 69 73 2e 5f 74 72 61 6e 73 66 65  it this._transfe
5550: 72 73 2e 67 65 74 28 74 72 61 6e 73 66 65 72 49  rs.get(transferI
5560: 64 29 0a 20 20 20 20 69 66 20 28 74 72 61 6e 73  d).    if (trans
5570: 66 65 72 49 6e 66 6f 2e 73 74 61 74 65 20 21 3d  ferInfo.state !=
5580: 3d 20 27 70 72 65 70 61 72 65 64 27 29 20 72 65  = 'prepared') re
5590: 74 75 72 6e 20 74 72 75 65 0a 0a 20 20 20 20 69  turn true..    i
55a0: 66 20 28 44 61 74 65 2e 6e 6f 77 28 29 20 3c 20  f (Date.now() < 
55b0: 44 61 74 65 2e 70 61 72 73 65 28 74 72 61 6e 73  Date.parse(trans
55c0: 66 65 72 49 6e 66 6f 2e 74 72 61 6e 73 66 65 72  ferInfo.transfer
55d0: 2e 65 78 70 69 72 65 73 41 74 29 29 20 7b 0a 20  .expiresAt)) {. 
55e0: 20 20 20 20 20 74 68 72 6f 77 20 6e 65 77 20 45       throw new E
55f0: 72 72 6f 72 28 74 72 61 6e 73 66 65 72 49 64 20  rror(transferId 
5600: 2b 20 27 20 64 6f 65 73 6e 5c 27 74 20 65 78 70  + ' doesn\'t exp
5610: 69 72 65 20 75 6e 74 69 6c 20 27 20 2b 0a 20 20  ire until ' +.  
5620: 20 20 20 20 20 20 74 72 61 6e 73 66 65 72 49 6e        transferIn
5630: 66 6f 2e 74 72 61 6e 73 66 65 72 2e 65 78 70 69  fo.transfer.expi
5640: 72 65 73 41 74 20 2b 20 27 20 28 63 75 72 72 65  resAt + ' (curre
5650: 6e 74 20 74 69 6d 65 20 69 73 20 27 20 2b 0a 20  nt time is ' +. 
5660: 20 20 20 20 20 20 20 6e 65 77 20 44 61 74 65 28         new Date(
5670: 29 2e 74 6f 49 53 4f 53 74 72 69 6e 67 28 29 20  ).toISOString() 
5680: 2b 20 27 29 27 29 0a 20 20 20 20 7d 0a 0a 20 20  + ')').    }..  
5690: 20 20 74 68 69 73 2e 64 65 62 75 67 28 27 74 69    this.debug('ti
56a0: 6d 69 6e 67 20 6f 75 74 20 27 20 2b 20 74 72 61  ming out ' + tra
56b0: 6e 73 66 65 72 49 64 29 0a 20 20 20 20 74 72 79  nsferId).    try
56c0: 20 7b 0a 20 20 20 20 20 20 61 77 61 69 74 20 74   {.      await t
56d0: 68 69 73 2e 5f 74 72 61 6e 73 66 65 72 73 2e 63  his._transfers.c
56e0: 61 6e 63 65 6c 28 74 72 61 6e 73 66 65 72 49 64  ancel(transferId
56f0: 2c 20 27 65 78 70 69 72 65 64 27 29 0a 20 20 20  , 'expired').   
5700: 20 7d 20 63 61 74 63 68 20 28 65 29 20 7b 0a 20   } catch (e) {. 
5710: 20 20 20 20 20 74 68 69 73 2e 64 65 62 75 67 28       this.debug(
5720: 27 65 72 72 6f 72 20 65 78 70 69 72 69 6e 67 20  'error expiring 
5730: 27 20 2b 20 74 72 61 6e 73 66 65 72 49 64 20 2b  ' + transferId +
5740: 20 27 3a 20 27 20 2b 20 65 2e 6d 65 73 73 61 67   ': ' + e.messag
5750: 65 29 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  e).      return 
5760: 74 72 75 65 0a 20 20 20 20 7d 0a 0a 20 20 20 20  true.    }..    
5770: 74 68 69 73 2e 5f 73 61 66 65 45 6d 69 74 28 28  this._safeEmit((
5780: 74 72 61 6e 73 66 65 72 49 6e 66 6f 2e 69 73 49  transferInfo.isI
5790: 6e 63 6f 6d 69 6e 67 20 3f 20 27 69 6e 63 6f 6d  ncoming ? 'incom
57a0: 69 6e 67 27 20 3a 20 27 6f 75 74 67 6f 69 6e 67  ing' : 'outgoing
57b0: 27 29 20 2b 20 27 5f 63 61 6e 63 65 6c 27 2c 0a  ') + '_cancel',.
57c0: 20 20 20 20 20 20 74 72 61 6e 73 66 65 72 49 6e        transferIn
57d0: 66 6f 2e 74 72 61 6e 73 66 65 72 29 0a 20 20 20  fo.transfer).   
57e0: 20 72 65 74 75 72 6e 20 74 72 75 65 0a 20 20 7d   return true.  }
57f0: 0a 0a 20 20 61 73 79 6e 63 20 5f 68 61 6e 64 6c  ..  async _handl
5800: 65 47 65 74 4c 69 6d 69 74 20 28 29 20 7b 0a 20  eGetLimit () {. 
5810: 20 20 20 2f 2f 20 54 4f 44 4f 3a 20 61 64 64 20     // TODO: add 
5820: 75 6e 69 74 20 74 65 73 74 0a 20 20 20 20 72 65  unit test.    re
5830: 74 75 72 6e 20 74 68 69 73 2e 5f 74 72 61 6e 73  turn this._trans
5840: 66 65 72 73 2e 67 65 74 4d 61 78 69 6d 75 6d 28  fers.getMaximum(
5850: 29 0a 20 20 7d 0a 0a 20 20 5f 73 74 72 69 6e 67  ).  }..  _string
5860: 4e 65 67 61 74 65 20 28 6e 75 6d 29 20 7b 0a 20  Negate (num) {. 
5870: 20 20 20 69 66 20 28 69 73 4e 61 4e 28 2b 6e 75     if (isNaN(+nu
5880: 6d 29 29 20 7b 0a 20 20 20 20 20 20 74 68 72 6f  m)) {.      thro
5890: 77 20 6e 65 77 20 45 72 72 6f 72 28 27 69 6e 76  w new Error('inv
58a0: 61 6c 69 64 20 6e 75 6d 62 65 72 3a 20 27 20 2b  alid number: ' +
58b0: 20 6e 75 6d 29 0a 20 20 20 20 7d 20 65 6c 73 65   num).    } else
58c0: 20 69 66 20 28 6e 75 6d 2e 63 68 61 72 41 74 28   if (num.charAt(
58d0: 30 29 20 3d 3d 3d 20 27 2d 27 29 20 7b 0a 20 20  0) === '-') {.  
58e0: 20 20 20 20 72 65 74 75 72 6e 20 6e 75 6d 2e 73      return num.s
58f0: 75 62 73 74 72 69 6e 67 28 31 29 0a 20 20 20 20  ubstring(1).    
5900: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 72  } else {.      r
5910: 65 74 75 72 6e 20 27 2d 27 20 2b 20 6e 75 6d 0a  eturn '-' + num.
5920: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 61 73 79      }.  }..  asy
5930: 6e 63 20 67 65 74 4c 69 6d 69 74 20 28 29 20 7b  nc getLimit () {
5940: 0a 20 20 20 20 74 68 69 73 2e 61 73 73 65 72 74  .    this.assert
5950: 43 6f 6e 6e 65 63 74 69 6f 6e 42 65 66 6f 72 65  ConnectionBefore
5960: 43 61 6c 6c 69 6e 67 28 27 67 65 74 4c 69 6d 69  Calling('getLimi
5970: 74 27 29 0a 20 20 20 20 63 6f 6e 73 74 20 70 65  t').    const pe
5980: 65 72 4d 61 78 42 61 6c 61 6e 63 65 20 3d 20 61  erMaxBalance = a
5990: 77 61 69 74 20 74 68 69 73 2e 5f 72 70 63 2e 6d  wait this._rpc.m
59a0: 65 73 73 61 67 65 28 0a 20 20 20 20 20 20 5b 7b  essage(.      [{
59b0: 0a 20 20 20 20 20 20 20 20 70 72 6f 74 6f 63 6f  .        protoco
59c0: 6c 4e 61 6d 65 3a 20 27 6c 69 6d 69 74 27 2c 0a  lName: 'limit',.
59d0: 20 20 20 20 20 20 20 20 63 6f 6e 74 65 6e 74 54          contentT
59e0: 79 70 65 3a 20 42 74 70 2e 4d 49 4d 45 5f 41 50  ype: Btp.MIME_AP
59f0: 50 4c 49 43 41 54 49 4f 4e 5f 4f 43 54 45 54 5f  PLICATION_OCTET_
5a00: 53 54 52 45 41 4d 2c 0a 20 20 20 20 20 20 20 20  STREAM,.        
5a10: 64 61 74 61 3a 20 42 75 66 66 65 72 2e 66 72 6f  data: Buffer.fro
5a20: 6d 28 5b 20 4c 49 4d 49 54 5f 52 45 51 55 45 53  m([ LIMIT_REQUES
5a30: 54 20 5d 29 0a 20 20 20 20 20 20 7d 5d 0a 20 20  T ]).      }].  
5a40: 20 20 29 0a 20 20 20 20 63 6f 6e 73 74 20 7b 20    ).    const { 
5a50: 70 72 6f 74 6f 63 6f 6c 4d 61 70 20 7d 20 3d 20  protocolMap } = 
5a60: 28 70 72 6f 74 6f 63 6f 6c 44 61 74 61 54 6f 49  (protocolDataToI
5a70: 6c 70 41 6e 64 43 75 73 74 6f 6d 28 70 65 65 72  lpAndCustom(peer
5a80: 4d 61 78 42 61 6c 61 6e 63 65 29 29 0a 20 20 20  MaxBalance)).   
5a90: 20 69 66 20 28 70 72 6f 74 6f 63 6f 6c 4d 61 70   if (protocolMap
5aa0: 2e 6c 69 6d 69 74 29 20 7b 0a 20 20 20 20 20 20  .limit) {.      
5ab0: 72 65 74 75 72 6e 20 74 68 69 73 2e 5f 73 74 72  return this._str
5ac0: 69 6e 67 4e 65 67 61 74 65 28 70 72 6f 74 6f 63  ingNegate(protoc
5ad0: 6f 6c 4d 61 70 2e 6c 69 6d 69 74 29 0a 20 20 20  olMap.limit).   
5ae0: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20   } else {.      
5af0: 74 68 72 6f 77 20 6e 65 77 20 45 72 72 6f 72 28  throw new Error(
5b00: 27 46 61 69 6c 65 64 20 74 6f 20 67 65 74 20 6c  'Failed to get l
5b10: 69 6d 69 74 20 6f 66 20 70 65 65 72 2e 27 29 0a  imit of peer.').
5b20: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 61 73 79      }.  }..  asy
5b30: 6e 63 20 67 65 74 50 65 65 72 42 61 6c 61 6e 63  nc getPeerBalanc
5b40: 65 20 28 29 20 7b 0a 20 20 20 20 74 68 69 73 2e  e () {.    this.
5b50: 61 73 73 65 72 74 43 6f 6e 6e 65 63 74 69 6f 6e  assertConnection
5b60: 42 65 66 6f 72 65 43 61 6c 6c 69 6e 67 28 27 67  BeforeCalling('g
5b70: 65 74 50 65 65 72 42 61 6c 61 6e 63 65 27 29 0a  etPeerBalance').
5b80: 20 20 20 20 63 6f 6e 73 74 20 62 74 70 52 65 73      const btpRes
5b90: 70 6f 6e 73 65 20 3d 20 61 77 61 69 74 20 74 68  ponse = await th
5ba0: 69 73 2e 5f 72 70 63 2e 6d 65 73 73 61 67 65 28  is._rpc.message(
5bb0: 0a 20 20 20 20 20 20 5b 7b 0a 20 20 20 20 20 20  .      [{.      
5bc0: 20 20 70 72 6f 74 6f 63 6f 6c 4e 61 6d 65 3a 20    protocolName: 
5bd0: 27 62 61 6c 61 6e 63 65 27 2c 0a 20 20 20 20 20  'balance',.     
5be0: 20 20 20 63 6f 6e 74 65 6e 74 54 79 70 65 3a 20     contentType: 
5bf0: 42 74 70 2e 4d 49 4d 45 5f 41 50 50 4c 49 43 41  Btp.MIME_APPLICA
5c00: 54 49 4f 4e 5f 4f 43 54 45 54 5f 53 54 52 45 41  TION_OCTET_STREA
5c10: 4d 2c 0a 20 20 20 20 20 20 20 20 64 61 74 61 3a  M,.        data:
5c20: 20 42 75 66 66 65 72 2e 66 72 6f 6d 28 5b 20 42   Buffer.from([ B
5c30: 41 4c 41 4e 43 45 5f 52 45 51 55 45 53 54 20 5d  ALANCE_REQUEST ]
5c40: 29 0a 20 20 20 20 20 20 7d 5d 0a 20 20 20 20 29  ).      }].    )
5c50: 0a 0a 20 20 20 20 63 6f 6e 73 74 20 7b 20 70 72  ..    const { pr
5c60: 6f 74 6f 63 6f 6c 4d 61 70 20 7d 20 3d 20 70 72  otocolMap } = pr
5c70: 6f 74 6f 63 6f 6c 44 61 74 61 54 6f 49 6c 70 41  otocolDataToIlpA
5c80: 6e 64 43 75 73 74 6f 6d 28 62 74 70 52 65 73 70  ndCustom(btpResp
5c90: 6f 6e 73 65 29 0a 20 20 20 20 63 6f 6e 73 74 20  onse).    const 
5ca0: 62 61 6c 61 6e 63 65 20 3d 20 69 6e 74 36 34 2e  balance = int64.
5cb0: 74 6f 53 74 72 69 6e 67 28 70 72 6f 74 6f 63 6f  toString(protoco
5cc0: 6c 4d 61 70 2e 62 61 6c 61 6e 63 65 29 0a 20 20  lMap.balance).  
5cd0: 20 20 69 66 20 28 21 62 61 6c 61 6e 63 65 29 20    if (!balance) 
5ce0: 7b 0a 20 20 20 20 20 20 74 68 72 6f 77 20 6e 65  {.      throw ne
5cf0: 77 20 45 72 72 6f 72 28 27 43 6f 75 6c 64 20 6e  w Error('Could n
5d00: 6f 74 20 67 65 74 20 70 65 65 72 20 62 61 6c 61  ot get peer bala
5d10: 6e 63 65 2e 27 29 0a 20 20 20 20 7d 0a 0a 20 20  nce.').    }..  
5d20: 20 20 72 65 74 75 72 6e 20 74 68 69 73 2e 5f 73    return this._s
5d30: 74 72 69 6e 67 4e 65 67 61 74 65 28 62 61 6c 61  tringNegate(bala
5d40: 6e 63 65 29 0a 20 20 7d 0a 0a 20 20 5f 76 61 6c  nce).  }..  _val
5d50: 69 64 61 74 65 46 75 6c 66 69 6c 6c 6d 65 6e 74  idateFulfillment
5d60: 20 28 66 75 6c 66 69 6c 6c 6d 65 6e 74 2c 20 63   (fulfillment, c
5d70: 6f 6e 64 69 74 69 6f 6e 29 20 7b 0a 20 20 20 20  ondition) {.    
5d80: 74 68 69 73 2e 5f 76 61 6c 69 64 61 74 6f 72 2e  this._validator.
5d90: 76 61 6c 69 64 61 74 65 46 75 6c 66 69 6c 6c 6d  validateFulfillm
5da0: 65 6e 74 28 66 75 6c 66 69 6c 6c 6d 65 6e 74 29  ent(fulfillment)
5db0: 0a 20 20 20 20 63 6f 6e 73 74 20 68 61 73 68 20  .    const hash 
5dc0: 3d 20 63 72 79 70 74 6f 2e 63 72 65 61 74 65 48  = crypto.createH
5dd0: 61 73 68 28 27 73 68 61 32 35 36 27 29 0a 20 20  ash('sha256').  
5de0: 20 20 68 61 73 68 2e 75 70 64 61 74 65 28 66 75    hash.update(fu
5df0: 6c 66 69 6c 6c 6d 65 6e 74 2c 20 27 62 61 73 65  lfillment, 'base
5e00: 36 34 27 29 0a 20 20 20 20 69 66 20 28 62 61 73  64').    if (bas
5e10: 65 36 34 75 72 6c 28 68 61 73 68 2e 64 69 67 65  e64url(hash.dige
5e20: 73 74 28 29 29 20 21 3d 3d 20 63 6f 6e 64 69 74  st()) !== condit
5e30: 69 6f 6e 29 20 7b 0a 20 20 20 20 20 20 74 68 72  ion) {.      thr
5e40: 6f 77 20 6e 65 77 20 4e 6f 74 41 63 63 65 70 74  ow new NotAccept
5e50: 65 64 45 72 72 6f 72 28 27 46 75 6c 66 69 6c 6c  edError('Fulfill
5e60: 6d 65 6e 74 20 64 6f 65 73 20 6e 6f 74 20 6d 61  ment does not ma
5e70: 74 63 68 20 74 68 65 20 63 6f 6e 64 69 74 69 6f  tch the conditio
5e80: 6e 27 29 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  n').    }.  }.. 
5e90: 20 61 73 73 65 72 74 43 6f 6e 6e 65 63 74 69 6f   assertConnectio
5ea0: 6e 42 65 66 6f 72 65 43 61 6c 6c 69 6e 67 20 28  nBeforeCalling (
5eb0: 66 75 6e 63 74 69 6f 6e 4e 61 6d 65 29 20 7b 0a  functionName) {.
5ec0: 20 20 20 20 69 66 20 28 21 74 68 69 73 2e 5f 63      if (!this._c
5ed0: 6f 6e 6e 65 63 74 65 64 29 20 7b 0a 20 20 20 20  onnected) {.    
5ee0: 20 20 74 68 72 6f 77 20 6e 65 77 20 45 72 72 6f    throw new Erro
5ef0: 72 28 60 4d 75 73 74 20 62 65 20 63 6f 6e 6e 65  r(`Must be conne
5f00: 63 74 65 64 20 62 65 66 6f 72 65 20 24 7b 66 75  cted before ${fu
5f10: 6e 63 74 69 6f 6e 4e 61 6d 65 7d 20 63 61 6e 20  nctionName} can 
5f20: 62 65 20 63 61 6c 6c 65 64 2e 60 29 0a 20 20 20  be called.`).   
5f30: 20 7d 0a 20 20 7d 0a 7d 0a                        }.  }.}.