Hex Artifact Content
Not logged in

Artifact 27910dc7ea28450967fd01e4ad52251e0b140c33:


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 63 72 79 70 74 6f 20 3d 20 72 65 71  nst crypto = req
0020: 75 69 72 65 28 27 63 72 79 70 74 6f 27 29 0a 63  uire('crypto').c
0030: 6f 6e 73 74 20 75 75 69 64 20 3d 20 72 65 71 75  onst uuid = requ
0040: 69 72 65 28 27 75 75 69 64 34 27 29 0a 63 6f 6e  ire('uuid4').con
0050: 73 74 20 69 6c 70 50 61 63 6b 65 74 20 3d 20 72  st ilpPacket = r
0060: 65 71 75 69 72 65 28 27 69 6c 70 2d 70 61 63 6b  equire('ilp-pack
0070: 65 74 27 29 0a 63 6f 6e 73 74 20 62 74 70 50 61  et').const btpPa
0080: 63 6b 65 74 20 3d 20 72 65 71 75 69 72 65 28 27  cket = require('
0090: 62 74 70 2d 70 61 63 6b 65 74 27 29 0a 63 6f 6e  btp-packet').con
00a0: 73 74 20 62 61 73 65 36 34 75 72 6c 20 3d 20 72  st base64url = r
00b0: 65 71 75 69 72 65 28 27 62 61 73 65 36 34 75 72  equire('base64ur
00c0: 6c 27 29 0a 0a 63 6f 6e 73 74 20 73 69 6e 6f 6e  l')..const sinon
00d0: 20 3d 20 72 65 71 75 69 72 65 28 27 73 69 6e 6f   = require('sino
00e0: 6e 27 29 0a 63 6f 6e 73 74 20 63 68 61 69 20 3d  n').const chai =
00f0: 20 72 65 71 75 69 72 65 28 27 63 68 61 69 27 29   require('chai')
0100: 0a 63 68 61 69 2e 75 73 65 28 72 65 71 75 69 72  .chai.use(requir
0110: 65 28 27 63 68 61 69 2d 61 73 2d 70 72 6f 6d 69  e('chai-as-promi
0120: 73 65 64 27 29 29 0a 63 6f 6e 73 74 20 61 73 73  sed')).const ass
0130: 65 72 74 20 3d 20 63 68 61 69 2e 61 73 73 65 72  ert = chai.asser
0140: 74 0a 63 6f 6e 73 74 20 65 78 70 65 63 74 20 3d  t.const expect =
0150: 20 63 68 61 69 2e 65 78 70 65 63 74 0a 0a 63 6f   chai.expect..co
0160: 6e 73 74 20 4f 62 6a 53 74 6f 72 65 20 3d 20 72  nst ObjStore = r
0170: 65 71 75 69 72 65 28 27 2e 2f 68 65 6c 70 65 72  equire('./helper
0180: 73 2f 6f 62 6a 53 74 6f 72 65 27 29 0a 63 6f 6e  s/objStore').con
0190: 73 74 20 50 6c 75 67 69 6e 50 61 79 6d 65 6e 74  st PluginPayment
01a0: 43 68 61 6e 6e 65 6c 20 3d 20 72 65 71 75 69 72  Channel = requir
01b0: 65 28 27 2e 2e 27 29 0a 63 6f 6e 73 74 20 4d 6f  e('..').const Mo
01c0: 63 6b 53 6f 63 6b 65 74 20 3d 20 72 65 71 75 69  ckSocket = requi
01d0: 72 65 28 27 2e 2f 68 65 6c 70 65 72 73 2f 6d 6f  re('./helpers/mo
01e0: 63 6b 53 6f 63 6b 65 74 27 29 0a 63 6f 6e 73 74  ckSocket').const
01f0: 20 7b 20 70 72 6f 74 6f 63 6f 6c 44 61 74 61 54   { protocolDataT
0200: 6f 49 6c 70 41 6e 64 43 75 73 74 6f 6d 2c 20 69  oIlpAndCustom, i
0210: 6c 70 41 6e 64 43 75 73 74 6f 6d 54 6f 50 72 6f  lpAndCustomToPro
0220: 74 6f 63 6f 6c 44 61 74 61 20 7d 20 3d 0a 20 20  tocolData } =.  
0230: 72 65 71 75 69 72 65 28 27 2e 2e 2f 73 72 63 2f  require('../src/
0240: 75 74 69 6c 2f 70 72 6f 74 6f 63 6f 6c 44 61 74  util/protocolDat
0250: 61 43 6f 6e 76 65 72 74 65 72 27 29 0a 0a 63 6f  aConverter')..co
0260: 6e 73 74 20 69 6e 66 6f 20 3d 20 7b 0a 20 20 70  nst info = {.  p
0270: 72 65 66 69 78 3a 20 27 65 78 61 6d 70 6c 65 2e  refix: 'example.
0280: 72 65 64 2e 27 2c 0a 20 20 63 75 72 72 65 6e 63  red.',.  currenc
0290: 79 43 6f 64 65 3a 20 27 55 53 44 27 2c 0a 20 20  yCode: 'USD',.  
02a0: 63 75 72 72 65 6e 63 79 53 63 61 6c 65 3a 20 32  currencyScale: 2
02b0: 2c 0a 20 20 63 6f 6e 6e 65 63 74 6f 72 73 3a 20  ,.  connectors: 
02c0: 5b 20 7b 20 69 64 3a 20 27 6f 74 68 65 72 27 2c  [ { id: 'other',
02d0: 20 6e 61 6d 65 3a 20 27 6f 74 68 65 72 27 2c 20   name: 'other', 
02e0: 63 6f 6e 6e 65 63 74 6f 72 3a 20 27 70 65 65 72  connector: 'peer
02f0: 2e 75 73 64 2e 6f 74 68 65 72 27 20 7d 20 5d 0a  .usd.other' } ].
0300: 7d 0a 0a 63 6f 6e 73 74 20 70 65 65 72 41 64 64  }..const peerAdd
0310: 72 65 73 73 20 3d 20 27 65 78 61 6d 70 6c 65 2e  ress = 'example.
0320: 72 65 64 2e 63 6c 69 65 6e 74 27 0a 63 6f 6e 73  red.client'.cons
0330: 74 20 6f 70 74 69 6f 6e 73 20 3d 20 7b 0a 20 20  t options = {.  
0340: 70 72 65 66 69 78 3a 20 27 65 78 61 6d 70 6c 65  prefix: 'example
0350: 2e 72 65 64 2e 27 2c 0a 20 20 63 75 72 72 65 6e  .red.',.  curren
0360: 63 79 43 6f 64 65 3a 20 27 55 53 44 27 2c 0a 20  cyCode: 'USD',. 
0370: 20 63 75 72 72 65 6e 63 79 53 63 61 6c 65 3a 20   currencyScale: 
0380: 32 2c 0a 20 20 6d 61 78 42 61 6c 61 6e 63 65 3a  2,.  maxBalance:
0390: 20 27 31 30 30 30 30 30 30 27 2c 0a 20 20 6d 69   '1000000',.  mi
03a0: 6e 42 61 6c 61 6e 63 65 3a 20 27 2d 34 30 27 2c  nBalance: '-40',
03b0: 0a 20 20 73 65 72 76 65 72 3a 20 27 62 74 70 2b  .  server: 'btp+
03c0: 77 73 73 3a 2f 2f 75 73 65 72 3a 70 6c 61 63 65  wss://user:place
03d0: 68 6f 6c 64 65 72 40 65 78 61 6d 70 6c 65 2e 63  holder@example.c
03e0: 6f 6d 2f 72 70 63 27 2c 0a 20 20 69 6e 66 6f 3a  om/rpc',.  info:
03f0: 20 69 6e 66 6f 0a 7d 0a 0a 64 65 73 63 72 69 62   info.}..describ
0400: 65 28 27 53 65 6e 64 27 2c 20 28 29 20 3d 3e 20  e('Send', () => 
0410: 7b 0a 20 20 62 65 66 6f 72 65 45 61 63 68 28 66  {.  beforeEach(f
0420: 75 6e 63 74 69 6f 6e 20 2a 20 28 29 20 7b 0a 20  unction * () {. 
0430: 20 20 20 6f 70 74 69 6f 6e 73 2e 5f 73 74 6f 72     options._stor
0440: 65 20 3d 20 6e 65 77 20 4f 62 6a 53 74 6f 72 65  e = new ObjStore
0450: 28 29 0a 20 20 20 20 74 68 69 73 2e 70 6c 75 67  ().    this.plug
0460: 69 6e 20 3d 20 6e 65 77 20 50 6c 75 67 69 6e 50  in = new PluginP
0470: 61 79 6d 65 6e 74 43 68 61 6e 6e 65 6c 28 6f 70  aymentChannel(op
0480: 74 69 6f 6e 73 29 0a 0a 20 20 20 20 74 68 69 73  tions)..    this
0490: 2e 6d 6f 63 6b 53 6f 63 6b 65 74 49 6e 64 65 78  .mockSocketIndex
04a0: 20 3d 20 30 0a 20 20 20 20 74 68 69 73 2e 6d 6f   = 0.    this.mo
04b0: 63 6b 53 6f 63 6b 65 74 20 3d 20 6e 65 77 20 4d  ckSocket = new M
04c0: 6f 63 6b 53 6f 63 6b 65 74 28 29 0a 20 20 20 20  ockSocket().    
04d0: 74 68 69 73 2e 6d 6f 63 6b 53 6f 63 6b 65 74 0a  this.mockSocket.
04e0: 20 20 20 20 20 20 2e 72 65 70 6c 79 28 62 74 70        .reply(btp
04f0: 50 61 63 6b 65 74 2e 54 59 50 45 5f 4d 45 53 53  Packet.TYPE_MESS
0500: 41 47 45 2c 20 28 7b 20 72 65 71 75 65 73 74 49  AGE, ({ requestI
0510: 64 20 7d 29 20 3d 3e 20 62 74 70 50 61 63 6b 65  d }) => btpPacke
0520: 74 2e 73 65 72 69 61 6c 69 7a 65 52 65 73 70 6f  t.serializeRespo
0530: 6e 73 65 28 72 65 71 75 65 73 74 49 64 2c 20 5b  nse(requestId, [
0540: 5d 29 29 0a 0a 20 20 20 20 79 69 65 6c 64 20 74  ]))..    yield t
0550: 68 69 73 2e 70 6c 75 67 69 6e 2e 61 64 64 53 6f  his.plugin.addSo
0560: 63 6b 65 74 28 74 68 69 73 2e 6d 6f 63 6b 53 6f  cket(this.mockSo
0570: 63 6b 65 74 2c 20 7b 20 75 73 65 72 6e 61 6d 65  cket, { username
0580: 3a 20 27 75 73 65 72 27 2c 20 74 6f 6b 65 6e 3a  : 'user', token:
0590: 20 27 70 6c 61 63 65 68 6f 6c 64 65 72 27 20 7d   'placeholder' }
05a0: 29 0a 20 20 20 20 79 69 65 6c 64 20 74 68 69 73  ).    yield this
05b0: 2e 70 6c 75 67 69 6e 2e 63 6f 6e 6e 65 63 74 28  .plugin.connect(
05c0: 29 0a 0a 20 20 20 20 74 68 69 73 2e 65 72 72 6f  )..    this.erro
05d0: 72 20 3d 20 7b 0a 20 20 20 20 20 20 63 6f 64 65  r = {.      code
05e0: 3a 20 27 46 30 30 27 2c 0a 20 20 20 20 20 20 6e  : 'F00',.      n
05f0: 61 6d 65 3a 20 27 42 61 64 20 52 65 71 75 65 73  ame: 'Bad Reques
0600: 74 27 2c 0a 20 20 20 20 20 20 74 72 69 67 67 65  t',.      trigge
0610: 72 65 64 41 74 3a 20 6e 65 77 20 44 61 74 65 28  redAt: new Date(
0620: 29 2c 0a 20 20 20 20 20 20 64 61 74 61 3a 20 4a  ),.      data: J
0630: 53 4f 4e 2e 73 74 72 69 6e 67 69 66 79 28 7b 20  SON.stringify({ 
0640: 6d 65 73 73 61 67 65 3a 20 27 50 65 65 72 20 69  message: 'Peer i
0650: 73 6e 5c 27 74 20 66 65 65 6c 69 6e 67 20 6c 69  sn\'t feeling li
0660: 6b 65 20 69 74 2e 27 20 7d 29 0a 20 20 20 20 7d  ke it.' }).    }
0670: 0a 20 20 7d 29 0a 0a 20 20 61 66 74 65 72 45 61  .  })..  afterEa
0680: 63 68 28 66 75 6e 63 74 69 6f 6e 20 2a 20 28 29  ch(function * ()
0690: 20 7b 0a 20 20 20 20 61 73 73 65 72 74 28 79 69   {.    assert(yi
06a0: 65 6c 64 20 74 68 69 73 2e 6d 6f 63 6b 53 6f 63  eld this.mockSoc
06b0: 6b 65 74 2e 69 73 44 6f 6e 65 28 29 2c 20 27 72  ket.isDone(), 'r
06c0: 65 71 75 65 73 74 20 68 61 6e 64 6c 65 72 73 20  equest handlers 
06d0: 6d 75 73 74 20 68 61 76 65 20 62 65 65 6e 20 63  must have been c
06e0: 61 6c 6c 65 64 27 29 0a 20 20 7d 29 0a 0a 20 20  alled').  })..  
06f0: 64 65 73 63 72 69 62 65 28 27 52 50 43 27 2c 20  describe('RPC', 
0700: 28 29 20 3d 3e 20 7b 0a 20 20 20 20 69 74 28 27  () => {.    it('
0710: 73 68 6f 75 6c 64 20 74 68 72 6f 77 20 61 6e 20  should throw an 
0720: 65 72 72 6f 72 20 6f 6e 20 61 6e 20 65 72 72 6f  error on an erro
0730: 72 20 63 6f 64 65 27 2c 20 66 75 6e 63 74 69 6f  r code', functio
0740: 6e 20 28 29 20 7b 0a 20 20 20 20 20 20 63 6f 6e  n () {.      con
0750: 73 74 20 65 78 70 65 63 74 65 64 52 65 71 75 65  st expectedReque
0760: 73 74 49 64 20 3d 20 31 32 33 34 0a 20 20 20 20  stId = 1234.    
0770: 20 20 74 68 69 73 2e 6d 6f 63 6b 53 6f 63 6b 65    this.mockSocke
0780: 74 2e 72 65 70 6c 79 28 62 74 70 50 61 63 6b 65  t.reply(btpPacke
0790: 74 2e 54 59 50 45 5f 4d 45 53 53 41 47 45 2c 20  t.TYPE_MESSAGE, 
07a0: 28 7b 72 65 71 75 65 73 74 49 64 2c 20 64 61 74  ({requestId, dat
07b0: 61 7d 29 20 3d 3e 20 7b 0a 20 20 20 20 20 20 20  a}) => {.       
07c0: 20 61 73 73 65 72 74 2e 65 71 75 61 6c 28 72 65   assert.equal(re
07d0: 71 75 65 73 74 49 64 2c 20 65 78 70 65 63 74 65  questId, expecte
07e0: 64 52 65 71 75 65 73 74 49 64 29 0a 20 20 20 20  dRequestId).    
07f0: 20 20 20 20 72 65 74 75 72 6e 20 62 74 70 50 61      return btpPa
0800: 63 6b 65 74 2e 73 65 72 69 61 6c 69 7a 65 45 72  cket.serializeEr
0810: 72 6f 72 28 74 68 69 73 2e 65 72 72 6f 72 2c 20  ror(this.error, 
0820: 72 65 71 75 65 73 74 49 64 2c 20 5b 5d 29 0a 20  requestId, []). 
0830: 20 20 20 20 20 7d 29 0a 0a 20 20 20 20 20 20 63       })..      c
0840: 6f 6e 73 74 20 63 6c 6c 70 4d 65 73 73 61 67 65  onst cllpMessage
0850: 20 3d 20 62 74 70 50 61 63 6b 65 74 2e 73 65 72   = btpPacket.ser
0860: 69 61 6c 69 7a 65 4d 65 73 73 61 67 65 28 65 78  ializeMessage(ex
0870: 70 65 63 74 65 64 52 65 71 75 65 73 74 49 64 2c  pectedRequestId,
0880: 20 5b 5d 29 0a 20 20 20 20 20 20 72 65 74 75 72   []).      retur
0890: 6e 20 65 78 70 65 63 74 28 74 68 69 73 2e 70 6c  n expect(this.pl
08a0: 75 67 69 6e 2e 5f 72 70 63 2e 5f 63 61 6c 6c 28  ugin._rpc._call(
08b0: 65 78 70 65 63 74 65 64 52 65 71 75 65 73 74 49  expectedRequestI
08c0: 64 2c 20 63 6c 6c 70 4d 65 73 73 61 67 65 29 29  d, cllpMessage))
08d0: 0a 20 20 20 20 20 20 20 20 2e 74 6f 2e 65 76 65  .        .to.eve
08e0: 6e 74 75 61 6c 6c 79 2e 62 65 2e 72 65 6a 65 63  ntually.be.rejec
08f0: 74 65 64 0a 20 20 20 20 7d 29 0a 0a 20 20 20 20  ted.    })..    
0900: 2f 2f 20 54 4f 44 4f 3a 20 72 65 61 73 73 65 73  // TODO: reasses
0910: 73 20 77 68 65 74 68 65 72 20 74 68 69 73 20 74  s whether this t
0920: 65 73 74 20 63 61 73 65 20 69 73 20 73 74 69 6c  est case is stil
0930: 6c 20 6e 65 63 65 73 73 61 72 79 20 28 63 63 3a  l necessary (cc:
0940: 20 73 68 61 72 61 66 69 61 6e 29 0a 20 20 20 20   sharafian).    
0950: 69 74 2e 73 6b 69 70 28 27 73 68 6f 75 6c 64 20  it.skip('should 
0960: 73 65 6e 64 20 61 75 74 68 6f 72 69 7a 61 74 69  send authorizati
0970: 6f 6e 20 62 65 61 72 65 72 20 74 6f 6b 65 6e 27  on bearer token'
0980: 2c 20 66 75 6e 63 74 69 6f 6e 20 28 29 20 7b 0a  , function () {.
0990: 20 20 20 20 20 20 2f 2f 20 6e 6f 63 6b 28 27 68        // nock('h
09a0: 74 74 70 73 3a 2f 2f 65 78 61 6d 70 6c 65 2e 63  ttps://example.c
09b0: 6f 6d 27 2c 20 7b 0a 20 20 20 20 20 20 2f 2f 20  om', {.      // 
09c0: 20 20 72 65 71 68 65 61 64 65 72 73 3a 20 7b 0a    reqheaders: {.
09d0: 20 20 20 20 20 20 2f 2f 20 20 20 20 20 27 41 75        //     'Au
09e0: 74 68 6f 72 69 7a 61 74 69 6f 6e 27 3a 20 27 42  thorization': 'B
09f0: 65 61 72 65 72 20 27 20 2b 20 74 68 69 73 2e 70  earer ' + this.p
0a00: 6c 75 67 69 6e 2e 5f 67 65 74 41 75 74 68 54 6f  lugin._getAuthTo
0a10: 6b 65 6e 28 29 0a 20 20 20 20 20 20 2f 2f 20 20  ken().      //  
0a20: 20 7d 0a 20 20 20 20 20 20 2f 2f 20 7d 29 0a 20   }.      // }). 
0a30: 20 20 20 20 20 2f 2f 20 20 20 2e 70 6f 73 74 28       //   .post(
0a40: 27 2f 72 70 63 3f 6d 65 74 68 6f 64 3d 6d 65 74  '/rpc?method=met
0a50: 68 6f 64 26 70 72 65 66 69 78 3d 65 78 61 6d 70  hod&prefix=examp
0a60: 6c 65 2e 72 65 64 2e 27 2c 20 5b 5d 29 0a 20 20  le.red.', []).  
0a70: 20 20 20 20 2f 2f 20 20 20 2e 72 65 70 6c 79 28      //   .reply(
0a80: 32 30 30 2c 20 7b 20 61 3a 20 27 62 27 20 7d 29  200, { a: 'b' })
0a90: 0a 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 65  ..      return e
0aa0: 78 70 65 63 74 28 74 68 69 73 2e 70 6c 75 67 69  xpect(this.plugi
0ab0: 6e 2e 5f 72 70 63 2e 63 61 6c 6c 28 27 6d 65 74  n._rpc.call('met
0ac0: 68 6f 64 27 2c 20 27 65 78 61 6d 70 6c 65 2e 72  hod', 'example.r
0ad0: 65 64 2e 27 2c 20 5b 5d 29 29 0a 20 20 20 20 20  ed.', [])).     
0ae0: 20 20 20 2e 74 6f 2e 65 76 65 6e 74 75 61 6c 6c     .to.eventuall
0af0: 79 2e 64 65 65 70 2e 65 71 75 61 6c 28 7b 20 61  y.deep.equal({ a
0b00: 3a 20 27 62 27 20 7d 29 0a 20 20 20 20 7d 29 0a  : 'b' }).    }).
0b10: 20 20 7d 29 0a 0a 20 20 64 65 73 63 72 69 62 65    })..  describe
0b20: 28 27 73 65 6e 64 52 65 71 75 65 73 74 27 2c 20  ('sendRequest', 
0b30: 28 29 20 3d 3e 20 7b 0a 20 20 20 20 62 65 66 6f  () => {.    befo
0b40: 72 65 45 61 63 68 28 66 75 6e 63 74 69 6f 6e 20  reEach(function 
0b50: 2a 20 28 29 20 7b 0a 20 20 20 20 20 20 74 68 69  * () {.      thi
0b60: 73 2e 6d 65 73 73 61 67 65 20 3d 20 7b 0a 20 20  s.message = {.  
0b70: 20 20 20 20 20 20 66 72 6f 6d 3a 20 74 68 69 73        from: this
0b80: 2e 70 6c 75 67 69 6e 2e 67 65 74 41 63 63 6f 75  .plugin.getAccou
0b90: 6e 74 28 29 2c 0a 20 20 20 20 20 20 20 20 74 6f  nt(),.        to
0ba0: 3a 20 70 65 65 72 41 64 64 72 65 73 73 2c 0a 20  : peerAddress,. 
0bb0: 20 20 20 20 20 20 20 6c 65 64 67 65 72 3a 20 74         ledger: t
0bc0: 68 69 73 2e 70 6c 75 67 69 6e 2e 67 65 74 49 6e  his.plugin.getIn
0bd0: 66 6f 28 29 2e 70 72 65 66 69 78 2c 0a 20 20 20  fo().prefix,.   
0be0: 20 20 20 20 20 69 6c 70 3a 20 62 61 73 65 36 34       ilp: base64
0bf0: 75 72 6c 28 27 73 6f 6d 65 5f 62 61 73 65 36 34  url('some_base64
0c00: 5f 65 6e 63 6f 64 65 64 5f 64 61 74 61 5f 67 6f  _encoded_data_go
0c10: 65 73 5f 68 65 72 65 27 29 2c 0a 20 20 20 20 20  es_here'),.     
0c20: 20 20 20 63 75 73 74 6f 6d 3a 20 7b 0a 20 20 20     custom: {.   
0c30: 20 20 20 20 20 20 20 66 69 65 6c 64 3a 20 27 73         field: 's
0c40: 6f 6d 65 20 73 74 75 66 66 27 0a 20 20 20 20 20  ome stuff'.     
0c50: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20     }.      }..  
0c60: 20 20 20 20 74 68 69 73 2e 72 65 73 70 6f 6e 73      this.respons
0c70: 65 20 3d 20 7b 0a 20 20 20 20 20 20 20 20 66 72  e = {.        fr
0c80: 6f 6d 3a 20 70 65 65 72 41 64 64 72 65 73 73 2c  om: peerAddress,
0c90: 0a 20 20 20 20 20 20 20 20 74 6f 3a 20 74 68 69  .        to: thi
0ca0: 73 2e 70 6c 75 67 69 6e 2e 67 65 74 41 63 63 6f  s.plugin.getAcco
0cb0: 75 6e 74 28 29 2c 0a 20 20 20 20 20 20 20 20 6c  unt(),.        l
0cc0: 65 64 67 65 72 3a 20 74 68 69 73 2e 70 6c 75 67  edger: this.plug
0cd0: 69 6e 2e 67 65 74 49 6e 66 6f 28 29 2e 70 72 65  in.getInfo().pre
0ce0: 66 69 78 2c 0a 20 20 20 20 20 20 20 20 69 6c 70  fix,.        ilp
0cf0: 3a 20 62 61 73 65 36 34 75 72 6c 28 27 73 6f 6d  : base64url('som
0d00: 65 5f 6f 74 68 65 72 5f 62 61 73 65 36 34 5f 65  e_other_base64_e
0d10: 6e 63 6f 64 65 64 5f 64 61 74 61 5f 67 6f 65 73  ncoded_data_goes
0d20: 5f 68 65 72 65 27 29 2c 0a 20 20 20 20 20 20 20  _here'),.       
0d30: 20 63 75 73 74 6f 6d 3a 20 7b 0a 20 20 20 20 20   custom: {.     
0d40: 20 20 20 20 20 66 69 65 6c 64 3a 20 27 73 6f 6d       field: 'som
0d50: 65 20 6f 74 68 65 72 20 73 74 75 66 66 27 0a 20  e other stuff'. 
0d60: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
0d70: 0a 20 20 20 20 7d 29 0a 0a 20 20 20 20 69 74 28  .    })..    it(
0d80: 27 73 68 6f 75 6c 64 20 73 65 6e 64 20 61 20 72  'should send a r
0d90: 65 71 75 65 73 74 27 2c 20 66 75 6e 63 74 69 6f  equest', functio
0da0: 6e 20 2a 20 28 29 20 7b 0a 20 20 20 20 20 20 74  n * () {.      t
0db0: 68 69 73 2e 6d 6f 63 6b 53 6f 63 6b 65 74 2e 72  his.mockSocket.r
0dc0: 65 70 6c 79 28 62 74 70 50 61 63 6b 65 74 2e 54  eply(btpPacket.T
0dd0: 59 50 45 5f 4d 45 53 53 41 47 45 2c 20 28 7b 72  YPE_MESSAGE, ({r
0de0: 65 71 75 65 73 74 49 64 2c 20 64 61 74 61 7d 29  equestId, data})
0df0: 20 3d 3e 20 7b 0a 20 20 20 20 20 20 20 20 63 6f   => {.        co
0e00: 6e 73 74 20 7b 69 6c 70 2c 20 63 75 73 74 6f 6d  nst {ilp, custom
0e10: 7d 20 3d 20 70 72 6f 74 6f 63 6f 6c 44 61 74 61  } = protocolData
0e20: 54 6f 49 6c 70 41 6e 64 43 75 73 74 6f 6d 28 64  ToIlpAndCustom(d
0e30: 61 74 61 29 0a 20 20 20 20 20 20 20 20 61 73 73  ata).        ass
0e40: 65 72 74 2e 65 71 75 61 6c 28 69 6c 70 2c 20 74  ert.equal(ilp, t
0e50: 68 69 73 2e 6d 65 73 73 61 67 65 2e 69 6c 70 29  his.message.ilp)
0e60: 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74 2e  .        assert.
0e70: 64 65 65 70 45 71 75 61 6c 28 63 75 73 74 6f 6d  deepEqual(custom
0e80: 2c 20 74 68 69 73 2e 6d 65 73 73 61 67 65 2e 63  , this.message.c
0e90: 75 73 74 6f 6d 29 0a 0a 20 20 20 20 20 20 20 20  ustom)..        
0ea0: 72 65 74 75 72 6e 20 62 74 70 50 61 63 6b 65 74  return btpPacket
0eb0: 2e 73 65 72 69 61 6c 69 7a 65 52 65 73 70 6f 6e  .serializeRespon
0ec0: 73 65 28 72 65 71 75 65 73 74 49 64 2c 0a 20 20  se(requestId,.  
0ed0: 20 20 20 20 20 20 20 20 69 6c 70 41 6e 64 43 75          ilpAndCu
0ee0: 73 74 6f 6d 54 6f 50 72 6f 74 6f 63 6f 6c 44 61  stomToProtocolDa
0ef0: 74 61 28 74 68 69 73 2e 72 65 73 70 6f 6e 73 65  ta(this.response
0f00: 29 29 0a 20 20 20 20 20 20 7d 29 0a 0a 20 20 20  )).      })..   
0f10: 20 20 20 63 6f 6e 73 74 20 6f 75 74 67 6f 69 6e     const outgoin
0f20: 67 20 3d 20 6e 65 77 20 50 72 6f 6d 69 73 65 28  g = new Promise(
0f30: 28 72 65 73 6f 6c 76 65 29 20 3d 3e 20 74 68 69  (resolve) => thi
0f40: 73 2e 70 6c 75 67 69 6e 2e 6f 6e 28 27 6f 75 74  s.plugin.on('out
0f50: 67 6f 69 6e 67 5f 72 65 71 75 65 73 74 27 2c 20  going_request', 
0f60: 72 65 73 6f 6c 76 65 29 29 0a 20 20 20 20 20 20  resolve)).      
0f70: 63 6f 6e 73 74 20 69 6e 63 6f 6d 69 6e 67 20 3d  const incoming =
0f80: 20 6e 65 77 20 50 72 6f 6d 69 73 65 28 28 72 65   new Promise((re
0f90: 73 6f 6c 76 65 29 20 3d 3e 20 74 68 69 73 2e 70  solve) => this.p
0fa0: 6c 75 67 69 6e 2e 6f 6e 28 27 69 6e 63 6f 6d 69  lugin.on('incomi
0fb0: 6e 67 5f 72 65 73 70 6f 6e 73 65 27 2c 20 72 65  ng_response', re
0fc0: 73 6f 6c 76 65 29 29 0a 0a 20 20 20 20 20 20 63  solve))..      c
0fd0: 6f 6e 73 74 20 72 65 73 70 6f 6e 73 65 20 3d 20  onst response = 
0fe0: 79 69 65 6c 64 20 74 68 69 73 2e 70 6c 75 67 69  yield this.plugi
0ff0: 6e 2e 73 65 6e 64 52 65 71 75 65 73 74 28 74 68  n.sendRequest(th
1000: 69 73 2e 6d 65 73 73 61 67 65 29 0a 20 20 20 20  is.message).    
1010: 20 20 79 69 65 6c 64 20 6f 75 74 67 6f 69 6e 67    yield outgoing
1020: 0a 20 20 20 20 20 20 79 69 65 6c 64 20 69 6e 63  .      yield inc
1030: 6f 6d 69 6e 67 0a 0a 20 20 20 20 20 20 61 73 73  oming..      ass
1040: 65 72 74 2e 65 71 75 61 6c 28 72 65 73 70 6f 6e  ert.equal(respon
1050: 73 65 2e 69 6c 70 2c 20 74 68 69 73 2e 72 65 73  se.ilp, this.res
1060: 70 6f 6e 73 65 2e 69 6c 70 29 0a 20 20 20 20 20  ponse.ilp).     
1070: 20 61 73 73 65 72 74 2e 64 65 65 70 45 71 75 61   assert.deepEqua
1080: 6c 28 72 65 73 70 6f 6e 73 65 2e 63 75 73 74 6f  l(response.custo
1090: 6d 2c 20 74 68 69 73 2e 72 65 73 70 6f 6e 73 65  m, this.response
10a0: 2e 63 75 73 74 6f 6d 29 0a 20 20 20 20 7d 29 0a  .custom).    }).
10b0: 0a 20 20 20 20 69 74 28 27 73 68 6f 75 6c 64 20  .    it('should 
10c0: 72 65 73 70 6f 6e 64 20 74 6f 20 61 20 72 65 71  respond to a req
10d0: 75 65 73 74 27 2c 20 66 75 6e 63 74 69 6f 6e 20  uest', function 
10e0: 2a 20 28 29 20 7b 0a 20 20 20 20 20 20 74 68 69  * () {.      thi
10f0: 73 2e 72 65 73 70 6f 6e 73 65 2e 74 6f 20 3d 20  s.response.to = 
1100: 74 68 69 73 2e 6d 65 73 73 61 67 65 2e 66 72 6f  this.message.fro
1110: 6d 20 3d 20 70 65 65 72 41 64 64 72 65 73 73 0a  m = peerAddress.
1120: 20 20 20 20 20 20 74 68 69 73 2e 72 65 73 70 6f        this.respo
1130: 6e 73 65 2e 66 72 6f 6d 20 3d 20 74 68 69 73 2e  nse.from = this.
1140: 6d 65 73 73 61 67 65 2e 74 6f 20 3d 20 74 68 69  message.to = thi
1150: 73 2e 70 6c 75 67 69 6e 2e 67 65 74 41 63 63 6f  s.plugin.getAcco
1160: 75 6e 74 28 29 0a 0a 20 20 20 20 20 20 74 68 69  unt()..      thi
1170: 73 2e 70 6c 75 67 69 6e 2e 72 65 67 69 73 74 65  s.plugin.registe
1180: 72 52 65 71 75 65 73 74 48 61 6e 64 6c 65 72 28  rRequestHandler(
1190: 28 72 65 71 75 65 73 74 29 20 3d 3e 20 7b 0a 20  (request) => {. 
11a0: 20 20 20 20 20 20 20 61 73 73 65 72 74 2e 65 71         assert.eq
11b0: 75 61 6c 28 72 65 71 75 65 73 74 2e 69 6c 70 2c  ual(request.ilp,
11c0: 20 74 68 69 73 2e 6d 65 73 73 61 67 65 2e 69 6c   this.message.il
11d0: 70 29 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  p).        asser
11e0: 74 2e 64 65 65 70 45 71 75 61 6c 28 72 65 71 75  t.deepEqual(requ
11f0: 65 73 74 2e 63 75 73 74 6f 6d 2c 20 74 68 69 73  est.custom, this
1200: 2e 6d 65 73 73 61 67 65 2e 63 75 73 74 6f 6d 29  .message.custom)
1210: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
1220: 50 72 6f 6d 69 73 65 2e 72 65 73 6f 6c 76 65 28  Promise.resolve(
1230: 74 68 69 73 2e 72 65 73 70 6f 6e 73 65 29 0a 20  this.response). 
1240: 20 20 20 20 20 7d 29 0a 0a 20 20 20 20 20 20 74       })..      t
1250: 68 69 73 2e 6d 6f 63 6b 53 6f 63 6b 65 74 2e 72  his.mockSocket.r
1260: 65 70 6c 79 28 62 74 70 50 61 63 6b 65 74 2e 54  eply(btpPacket.T
1270: 59 50 45 5f 52 45 53 50 4f 4e 53 45 2c 20 28 7b  YPE_RESPONSE, ({
1280: 72 65 71 75 65 73 74 49 64 2c 20 64 61 74 61 7d  requestId, data}
1290: 29 20 3d 3e 20 7b 0a 20 20 20 20 20 20 20 20 63  ) => {.        c
12a0: 6f 6e 73 74 20 7b 69 6c 70 2c 20 63 75 73 74 6f  onst {ilp, custo
12b0: 6d 7d 20 3d 20 70 72 6f 74 6f 63 6f 6c 44 61 74  m} = protocolDat
12c0: 61 54 6f 49 6c 70 41 6e 64 43 75 73 74 6f 6d 28  aToIlpAndCustom(
12d0: 64 61 74 61 29 0a 20 20 20 20 20 20 20 20 61 73  data).        as
12e0: 73 65 72 74 2e 65 71 75 61 6c 28 69 6c 70 2c 20  sert.equal(ilp, 
12f0: 74 68 69 73 2e 72 65 73 70 6f 6e 73 65 2e 69 6c  this.response.il
1300: 70 29 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  p).        asser
1310: 74 2e 64 65 65 70 45 71 75 61 6c 28 63 75 73 74  t.deepEqual(cust
1320: 6f 6d 2c 20 74 68 69 73 2e 72 65 73 70 6f 6e 73  om, this.respons
1330: 65 2e 63 75 73 74 6f 6d 29 0a 20 20 20 20 20 20  e.custom).      
1340: 7d 29 0a 0a 20 20 20 20 20 20 63 6f 6e 73 74 20  })..      const 
1350: 69 6e 63 6f 6d 69 6e 67 20 3d 20 6e 65 77 20 50  incoming = new P
1360: 72 6f 6d 69 73 65 28 28 72 65 73 6f 6c 76 65 29  romise((resolve)
1370: 20 3d 3e 20 74 68 69 73 2e 70 6c 75 67 69 6e 2e   => this.plugin.
1380: 6f 6e 28 27 69 6e 63 6f 6d 69 6e 67 5f 72 65 71  on('incoming_req
1390: 75 65 73 74 27 2c 20 72 65 73 6f 6c 76 65 29 29  uest', resolve))
13a0: 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 6f 75 74  .      const out
13b0: 67 6f 69 6e 67 20 3d 20 6e 65 77 20 50 72 6f 6d  going = new Prom
13c0: 69 73 65 28 28 72 65 73 6f 6c 76 65 29 20 3d 3e  ise((resolve) =>
13d0: 20 74 68 69 73 2e 70 6c 75 67 69 6e 2e 6f 6e 28   this.plugin.on(
13e0: 27 6f 75 74 67 6f 69 6e 67 5f 72 65 73 70 6f 6e  'outgoing_respon
13f0: 73 65 27 2c 20 72 65 73 6f 6c 76 65 29 29 0a 0a  se', resolve))..
1400: 20 20 20 20 20 20 63 6f 6e 73 74 20 62 74 70 4d        const btpM
1410: 65 73 73 61 67 65 20 3d 20 62 74 70 50 61 63 6b  essage = btpPack
1420: 65 74 2e 73 65 72 69 61 6c 69 7a 65 4d 65 73 73  et.serializeMess
1430: 61 67 65 28 31 31 31 31 2c 0a 20 20 20 20 20 20  age(1111,.      
1440: 20 20 69 6c 70 41 6e 64 43 75 73 74 6f 6d 54 6f    ilpAndCustomTo
1450: 50 72 6f 74 6f 63 6f 6c 44 61 74 61 28 74 68 69  ProtocolData(thi
1460: 73 2e 6d 65 73 73 61 67 65 29 29 0a 20 20 20 20  s.message)).    
1470: 20 20 79 69 65 6c 64 20 74 68 69 73 2e 70 6c 75    yield this.plu
1480: 67 69 6e 2e 5f 72 70 63 2e 68 61 6e 64 6c 65 4d  gin._rpc.handleM
1490: 65 73 73 61 67 65 28 74 68 69 73 2e 6d 6f 63 6b  essage(this.mock
14a0: 53 6f 63 6b 65 74 49 6e 64 65 78 2c 20 62 74 70  SocketIndex, btp
14b0: 4d 65 73 73 61 67 65 29 0a 0a 20 20 20 20 20 20  Message)..      
14c0: 79 69 65 6c 64 20 69 6e 63 6f 6d 69 6e 67 0a 20  yield incoming. 
14d0: 20 20 20 20 20 79 69 65 6c 64 20 6f 75 74 67 6f       yield outgo
14e0: 69 6e 67 0a 20 20 20 20 7d 29 0a 0a 20 20 20 20  ing.    })..    
14f0: 69 74 28 27 73 68 6f 75 6c 64 20 72 65 74 75 72  it('should retur
1500: 6e 20 61 6e 20 49 4c 50 20 65 72 72 6f 72 20 69  n an ILP error i
1510: 66 20 74 68 65 20 72 65 71 75 65 73 74 20 68 61  f the request ha
1520: 6e 64 6c 65 72 20 65 72 72 6f 72 73 27 2c 20 66  ndler errors', f
1530: 75 6e 63 74 69 6f 6e 20 2a 20 28 29 20 7b 0a 20  unction * () {. 
1540: 20 20 20 20 20 74 68 69 73 2e 72 65 73 70 6f 6e       this.respon
1550: 73 65 2e 74 6f 20 3d 20 74 68 69 73 2e 6d 65 73  se.to = this.mes
1560: 73 61 67 65 2e 66 72 6f 6d 20 3d 20 70 65 65 72  sage.from = peer
1570: 41 64 64 72 65 73 73 0a 20 20 20 20 20 20 74 68  Address.      th
1580: 69 73 2e 72 65 73 70 6f 6e 73 65 2e 66 72 6f 6d  is.response.from
1590: 20 3d 20 74 68 69 73 2e 6d 65 73 73 61 67 65 2e   = this.message.
15a0: 74 6f 20 3d 20 74 68 69 73 2e 70 6c 75 67 69 6e  to = this.plugin
15b0: 2e 67 65 74 41 63 63 6f 75 6e 74 28 29 0a 0a 20  .getAccount().. 
15c0: 20 20 20 20 20 74 68 69 73 2e 70 6c 75 67 69 6e       this.plugin
15d0: 2e 72 65 67 69 73 74 65 72 52 65 71 75 65 73 74  .registerRequest
15e0: 48 61 6e 64 6c 65 72 28 28 72 65 71 75 65 73 74  Handler((request
15f0: 29 20 3d 3e 20 7b 0a 20 20 20 20 20 20 20 20 72  ) => {.        r
1600: 65 74 75 72 6e 20 50 72 6f 6d 69 73 65 2e 72 65  eturn Promise.re
1610: 6a 65 63 74 28 6e 65 77 20 45 72 72 6f 72 28 27  ject(new Error('
1620: 74 68 69 73 20 69 73 20 61 6e 20 65 72 72 6f 72  this is an error
1630: 27 29 29 0a 20 20 20 20 20 20 7d 29 0a 0a 20 20  ')).      })..  
1640: 20 20 20 20 74 68 69 73 2e 6d 6f 63 6b 53 6f 63      this.mockSoc
1650: 6b 65 74 2e 72 65 70 6c 79 28 62 74 70 50 61 63  ket.reply(btpPac
1660: 6b 65 74 2e 54 59 50 45 5f 52 45 53 50 4f 4e 53  ket.TYPE_RESPONS
1670: 45 2c 20 28 7b 64 61 74 61 7d 29 20 3d 3e 20 7b  E, ({data}) => {
1680: 0a 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 7b  .        const {
1690: 69 6c 70 7d 20 3d 20 70 72 6f 74 6f 63 6f 6c 44  ilp} = protocolD
16a0: 61 74 61 54 6f 49 6c 70 41 6e 64 43 75 73 74 6f  ataToIlpAndCusto
16b0: 6d 28 64 61 74 61 29 0a 20 20 20 20 20 20 20 20  m(data).        
16c0: 63 6f 6e 73 74 20 65 72 72 6f 72 20 3d 20 69 6c  const error = il
16d0: 70 50 61 63 6b 65 74 2e 64 65 73 65 72 69 61 6c  pPacket.deserial
16e0: 69 7a 65 49 6c 70 45 72 72 6f 72 28 42 75 66 66  izeIlpError(Buff
16f0: 65 72 2e 66 72 6f 6d 28 69 6c 70 2c 20 27 62 61  er.from(ilp, 'ba
1700: 73 65 36 34 27 29 29 0a 20 20 20 20 20 20 20 20  se64')).        
1710: 61 73 73 65 72 74 2e 65 71 75 61 6c 28 65 72 72  assert.equal(err
1720: 6f 72 2e 63 6f 64 65 2c 20 27 46 30 30 27 29 0a  or.code, 'F00').
1730: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 2e 65          assert.e
1740: 71 75 61 6c 28 65 72 72 6f 72 2e 6e 61 6d 65 2c  qual(error.name,
1750: 20 27 42 61 64 20 52 65 71 75 65 73 74 27 29 0a   'Bad Request').
1760: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 2e 65          assert.e
1770: 71 75 61 6c 28 65 72 72 6f 72 2e 74 72 69 67 67  qual(error.trigg
1780: 65 72 65 64 42 79 2c 20 74 68 69 73 2e 70 6c 75  eredBy, this.plu
1790: 67 69 6e 2e 67 65 74 41 63 63 6f 75 6e 74 28 29  gin.getAccount()
17a0: 29 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  ).        assert
17b0: 2e 64 65 65 70 45 71 75 61 6c 28 65 72 72 6f 72  .deepEqual(error
17c0: 2e 66 6f 72 77 61 72 64 65 64 42 79 2c 20 5b 5d  .forwardedBy, []
17d0: 29 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  ).        assert
17e0: 2e 64 65 65 70 45 71 75 61 6c 28 4a 53 4f 4e 2e  .deepEqual(JSON.
17f0: 70 61 72 73 65 28 65 72 72 6f 72 2e 64 61 74 61  parse(error.data
1800: 29 2c 20 7b 20 6d 65 73 73 61 67 65 3a 20 27 74  ), { message: 't
1810: 68 69 73 20 69 73 20 61 6e 20 65 72 72 6f 72 27  his is an error'
1820: 20 7d 29 0a 20 20 20 20 20 20 7d 29 0a 0a 20 20   }).      })..  
1830: 20 20 20 20 63 6f 6e 73 74 20 62 74 70 4d 65 73      const btpMes
1840: 73 61 67 65 20 3d 20 62 74 70 50 61 63 6b 65 74  sage = btpPacket
1850: 2e 73 65 72 69 61 6c 69 7a 65 4d 65 73 73 61 67  .serializeMessag
1860: 65 28 31 31 31 31 2c 0a 20 20 20 20 20 20 20 20  e(1111,.        
1870: 69 6c 70 41 6e 64 43 75 73 74 6f 6d 54 6f 50 72  ilpAndCustomToPr
1880: 6f 74 6f 63 6f 6c 44 61 74 61 28 74 68 69 73 2e  otocolData(this.
1890: 6d 65 73 73 61 67 65 29 29 0a 20 20 20 20 20 20  message)).      
18a0: 79 69 65 6c 64 20 74 68 69 73 2e 70 6c 75 67 69  yield this.plugi
18b0: 6e 2e 5f 72 70 63 2e 68 61 6e 64 6c 65 4d 65 73  n._rpc.handleMes
18c0: 73 61 67 65 28 74 68 69 73 2e 6d 6f 63 6b 53 6f  sage(this.mockSo
18d0: 63 6b 65 74 49 6e 64 65 78 2c 20 62 74 70 4d 65  cketIndex, btpMe
18e0: 73 73 61 67 65 29 0a 20 20 20 20 7d 29 0a 0a 20  ssage).    }).. 
18f0: 20 20 20 69 74 28 27 73 68 6f 75 6c 64 20 74 68     it('should th
1900: 72 6f 77 20 61 6e 20 65 72 72 6f 72 20 69 66 20  row an error if 
1910: 61 20 68 61 6e 64 6c 65 72 20 69 73 20 61 6c 72  a handler is alr
1920: 65 61 64 79 20 72 65 67 69 73 74 65 72 65 64 27  eady registered'
1930: 2c 20 66 75 6e 63 74 69 6f 6e 20 2a 20 28 29 20  , function * () 
1940: 7b 0a 20 20 20 20 20 20 74 68 69 73 2e 70 6c 75  {.      this.plu
1950: 67 69 6e 2e 72 65 67 69 73 74 65 72 52 65 71 75  gin.registerRequ
1960: 65 73 74 48 61 6e 64 6c 65 72 28 28 29 20 3d 3e  estHandler(() =>
1970: 20 7b 7d 29 0a 20 20 20 20 20 20 61 73 73 65 72   {}).      asser
1980: 74 2e 74 68 72 6f 77 73 28 28 29 20 3d 3e 20 74  t.throws(() => t
1990: 68 69 73 2e 70 6c 75 67 69 6e 2e 72 65 67 69 73  his.plugin.regis
19a0: 74 65 72 52 65 71 75 65 73 74 48 61 6e 64 6c 65  terRequestHandle
19b0: 72 28 28 29 20 3d 3e 20 7b 7d 29 2c 0a 20 20 20  r(() => {}),.   
19c0: 20 20 20 20 20 2f 72 65 71 75 65 73 74 48 61 6e       /requestHan
19d0: 64 6c 65 72 20 69 73 20 61 6c 72 65 61 64 79 20  dler is already 
19e0: 72 65 67 69 73 74 65 72 65 64 2f 29 0a 20 20 20  registered/).   
19f0: 20 7d 29 0a 0a 20 20 20 20 69 74 28 27 73 68 6f   })..    it('sho
1a00: 75 6c 64 20 74 68 72 6f 77 20 61 6e 20 65 72 72  uld throw an err
1a10: 6f 72 20 69 66 20 6e 6f 20 68 61 6e 64 6c 65 72  or if no handler
1a20: 20 69 73 20 72 65 67 69 73 74 65 72 65 64 27 2c   is registered',
1a30: 20 66 75 6e 63 74 69 6f 6e 20 2a 20 28 29 20 7b   function * () {
1a40: 0a 20 20 20 20 20 20 74 68 69 73 2e 72 65 73 70  .      this.resp
1a50: 6f 6e 73 65 2e 74 6f 20 3d 20 74 68 69 73 2e 6d  onse.to = this.m
1a60: 65 73 73 61 67 65 2e 66 72 6f 6d 20 3d 20 70 65  essage.from = pe
1a70: 65 72 41 64 64 72 65 73 73 0a 20 20 20 20 20 20  erAddress.      
1a80: 74 68 69 73 2e 72 65 73 70 6f 6e 73 65 2e 66 72  this.response.fr
1a90: 6f 6d 20 3d 20 74 68 69 73 2e 6d 65 73 73 61 67  om = this.messag
1aa0: 65 2e 74 6f 20 3d 20 74 68 69 73 2e 70 6c 75 67  e.to = this.plug
1ab0: 69 6e 2e 67 65 74 41 63 63 6f 75 6e 74 28 29 0a  in.getAccount().
1ac0: 0a 20 20 20 20 20 20 61 73 73 65 72 74 2e 69 73  .      assert.is
1ad0: 4e 6f 74 4f 6b 28 74 68 69 73 2e 70 6c 75 67 69  NotOk(this.plugi
1ae0: 6e 2e 5f 72 65 71 75 65 73 74 48 61 6e 64 6c 65  n._requestHandle
1af0: 72 2c 20 27 68 61 6e 64 6c 65 72 20 73 68 6f 75  r, 'handler shou
1b00: 6c 64 20 6e 6f 74 20 62 65 20 72 65 67 69 73 74  ld not be regist
1b10: 65 72 65 64 20 79 65 74 27 29 0a 0a 20 20 20 20  ered yet')..    
1b20: 20 20 74 68 69 73 2e 70 6c 75 67 69 6e 2e 72 65    this.plugin.re
1b30: 67 69 73 74 65 72 52 65 71 75 65 73 74 48 61 6e  gisterRequestHan
1b40: 64 6c 65 72 28 28 72 65 71 75 65 73 74 29 20 3d  dler((request) =
1b50: 3e 20 7b 0a 20 20 20 20 20 20 20 20 61 73 73 65  > {.        asse
1b60: 72 74 2e 64 65 65 70 45 71 75 61 6c 28 72 65 71  rt.deepEqual(req
1b70: 75 65 73 74 2c 20 74 68 69 73 2e 6d 65 73 73 61  uest, this.messa
1b80: 67 65 29 0a 20 20 20 20 20 20 20 20 72 65 74 75  ge).        retu
1b90: 72 6e 20 50 72 6f 6d 69 73 65 2e 72 65 73 6f 6c  rn Promise.resol
1ba0: 76 65 28 74 68 69 73 2e 72 65 73 70 6f 6e 73 65  ve(this.response
1bb0: 29 0a 20 20 20 20 20 20 7d 29 0a 0a 20 20 20 20  ).      })..    
1bc0: 20 20 74 68 69 73 2e 70 6c 75 67 69 6e 2e 64 65    this.plugin.de
1bd0: 72 65 67 69 73 74 65 72 52 65 71 75 65 73 74 48  registerRequestH
1be0: 61 6e 64 6c 65 72 28 29 0a 0a 20 20 20 20 20 20  andler()..      
1bf0: 63 6f 6e 73 74 20 62 74 70 4d 65 73 73 61 67 65  const btpMessage
1c00: 20 3d 20 62 74 70 50 61 63 6b 65 74 2e 73 65 72   = btpPacket.ser
1c10: 69 61 6c 69 7a 65 4d 65 73 73 61 67 65 28 31 31  ializeMessage(11
1c20: 31 31 2c 0a 20 20 20 20 20 20 20 20 69 6c 70 41  11,.        ilpA
1c30: 6e 64 43 75 73 74 6f 6d 54 6f 50 72 6f 74 6f 63  ndCustomToProtoc
1c40: 6f 6c 44 61 74 61 28 74 68 69 73 2e 6d 65 73 73  olData(this.mess
1c50: 61 67 65 29 29 0a 20 20 20 20 20 20 79 69 65 6c  age)).      yiel
1c60: 64 20 65 78 70 65 63 74 28 74 68 69 73 2e 70 6c  d expect(this.pl
1c70: 75 67 69 6e 2e 5f 72 70 63 2e 68 61 6e 64 6c 65  ugin._rpc.handle
1c80: 4d 65 73 73 61 67 65 28 74 68 69 73 2e 6d 6f 63  Message(this.moc
1c90: 6b 53 6f 63 6b 65 74 49 6e 64 65 78 2c 20 62 74  kSocketIndex, bt
1ca0: 70 4d 65 73 73 61 67 65 29 29 0a 20 20 20 20 20  pMessage)).     
1cb0: 20 20 20 2e 74 6f 2e 62 65 2e 72 65 6a 65 63 74     .to.be.reject
1cc0: 65 64 57 69 74 68 28 2f 6e 6f 20 72 65 71 75 65  edWith(/no reque
1cd0: 73 74 20 68 61 6e 64 6c 65 72 20 72 65 67 69 73  st handler regis
1ce0: 74 65 72 65 64 2f 29 0a 20 20 20 20 7d 29 0a 0a  tered/).    })..
1cf0: 20 20 20 20 69 74 28 27 73 68 6f 75 6c 64 20 74      it('should t
1d00: 68 72 6f 77 20 61 6e 20 65 72 72 6f 72 20 6f 6e  hrow an error on
1d10: 20 6e 6f 20 72 65 73 70 6f 6e 73 65 27 2c 20 66   no response', f
1d20: 75 6e 63 74 69 6f 6e 20 2a 20 28 29 20 7b 0a 20  unction * () {. 
1d30: 20 20 20 20 20 63 6f 6e 73 74 20 63 6c 6f 63 6b       const clock
1d40: 20 3d 20 73 69 6e 6f 6e 2e 75 73 65 46 61 6b 65   = sinon.useFake
1d50: 54 69 6d 65 72 73 28 7b 20 74 6f 46 61 6b 65 3a  Timers({ toFake:
1d60: 20 5b 27 73 65 74 54 69 6d 65 6f 75 74 27 5d 20   ['setTimeout'] 
1d70: 7d 29 0a 0a 20 20 20 20 20 20 74 68 69 73 2e 6d  })..      this.m
1d80: 6f 63 6b 53 6f 63 6b 65 74 2e 72 65 70 6c 79 28  ockSocket.reply(
1d90: 62 74 70 50 61 63 6b 65 74 2e 54 59 50 45 5f 4d  btpPacket.TYPE_M
1da0: 45 53 53 41 47 45 2c 20 28 29 20 3d 3e 20 7b 0a  ESSAGE, () => {.
1db0: 20 20 20 20 20 20 20 20 2f 2f 20 73 65 6e 64 69          // sendi
1dc0: 6e 67 20 6e 6f 20 72 65 73 70 6f 6e 73 65 20 62  ng no response b
1dd0: 61 63 6b 20 74 72 69 67 67 65 72 73 20 61 20 74  ack triggers a t
1de0: 69 6d 65 6f 75 74 20 6f 6e 20 74 68 65 20 73 65  imeout on the se
1df0: 6e 64 69 6e 67 20 73 69 64 65 0a 20 20 20 20 20  nding side.     
1e00: 20 20 20 63 6c 6f 63 6b 2e 74 69 63 6b 28 31 30     clock.tick(10
1e10: 30 30 30 29 0a 20 20 20 20 20 20 7d 29 0a 0a 20  000).      }).. 
1e20: 20 20 20 20 20 72 65 74 75 72 6e 20 65 78 70 65       return expe
1e30: 63 74 28 74 68 69 73 2e 70 6c 75 67 69 6e 2e 73  ct(this.plugin.s
1e40: 65 6e 64 52 65 71 75 65 73 74 28 74 68 69 73 2e  endRequest(this.
1e50: 6d 65 73 73 61 67 65 29 29 2e 74 6f 2e 65 76 65  message)).to.eve
1e60: 6e 74 75 61 6c 6c 79 2e 62 65 2e 72 65 6a 65 63  ntually.be.rejec
1e70: 74 65 64 0a 20 20 20 20 7d 29 0a 0a 20 20 20 20  ted.    })..    
1e80: 69 74 28 27 73 68 6f 75 6c 64 20 6e 6f 74 20 73  it('should not s
1e90: 65 6e 64 20 77 69 74 68 6f 75 74 20 61 6e 20 61  end without an a
1ea0: 63 63 6f 75 6e 74 20 6f 72 20 74 6f 2d 66 72 6f  ccount or to-fro
1eb0: 6d 27 2c 20 66 75 6e 63 74 69 6f 6e 20 28 29 20  m', function () 
1ec0: 7b 0a 20 20 20 20 20 20 74 68 69 73 2e 6d 65 73  {.      this.mes
1ed0: 73 61 67 65 2e 61 63 63 6f 75 6e 74 20 3d 20 75  sage.account = u
1ee0: 6e 64 65 66 69 6e 65 64 0a 20 20 20 20 20 20 74  ndefined.      t
1ef0: 68 69 73 2e 6d 65 73 73 61 67 65 2e 74 6f 20 3d  his.message.to =
1f00: 20 75 6e 64 65 66 69 6e 65 64 0a 20 20 20 20 20   undefined.     
1f10: 20 74 68 69 73 2e 6d 65 73 73 61 67 65 2e 66 72   this.message.fr
1f20: 6f 6d 20 3d 20 75 6e 64 65 66 69 6e 65 64 0a 0a  om = undefined..
1f30: 20 20 20 20 20 20 72 65 74 75 72 6e 20 65 78 70        return exp
1f40: 65 63 74 28 74 68 69 73 2e 70 6c 75 67 69 6e 2e  ect(this.plugin.
1f50: 73 65 6e 64 52 65 71 75 65 73 74 28 74 68 69 73  sendRequest(this
1f60: 2e 6d 65 73 73 61 67 65 29 29 0a 20 20 20 20 20  .message)).     
1f70: 20 20 20 2e 74 6f 2e 65 76 65 6e 74 75 61 6c 6c     .to.eventuall
1f80: 79 2e 62 65 2e 72 65 6a 65 63 74 65 64 57 69 74  y.be.rejectedWit
1f90: 68 28 2f 6d 75 73 74 20 68 61 76 65 20 61 20 64  h(/must have a d
1fa0: 65 73 74 69 6e 61 74 69 6f 6e 2f 29 0a 20 20 20  estination/).   
1fb0: 20 7d 29 0a 0a 20 20 20 20 69 74 28 27 73 68 6f   })..    it('sho
1fc0: 75 6c 64 20 6e 6f 74 20 73 65 6e 64 20 77 69 74  uld not send wit
1fd0: 68 20 69 6e 63 6f 72 72 65 63 74 20 6c 65 64 67  h incorrect ledg
1fe0: 65 72 27 2c 20 66 75 6e 63 74 69 6f 6e 20 28 29  er', function ()
1ff0: 20 7b 0a 20 20 20 20 20 20 74 68 69 73 2e 6d 65   {.      this.me
2000: 73 73 61 67 65 2e 6c 65 64 67 65 72 20 3d 20 27  ssage.ledger = '
2010: 62 6f 67 75 73 27 0a 20 20 20 20 20 20 72 65 74  bogus'.      ret
2020: 75 72 6e 20 65 78 70 65 63 74 28 74 68 69 73 2e  urn expect(this.
2030: 70 6c 75 67 69 6e 2e 73 65 6e 64 52 65 71 75 65  plugin.sendReque
2040: 73 74 28 74 68 69 73 2e 6d 65 73 73 61 67 65 29  st(this.message)
2050: 29 0a 20 20 20 20 20 20 20 20 2e 74 6f 2e 65 76  ).        .to.ev
2060: 65 6e 74 75 61 6c 6c 79 2e 62 65 2e 72 65 6a 65  entually.be.reje
2070: 63 74 65 64 57 69 74 68 28 2f 6c 65 64 67 65 72  ctedWith(/ledger
2080: 20 2e 2b 20 6d 75 73 74 20 6d 61 74 63 68 20 49   .+ must match I
2090: 4c 50 20 70 72 65 66 69 78 2f 29 0a 20 20 20 20  LP prefix/).    
20a0: 7d 29 0a 20 20 7d 29 0a 0a 20 20 64 65 73 63 72  }).  })..  descr
20b0: 69 62 65 28 27 73 65 6e 64 54 72 61 6e 73 66 65  ibe('sendTransfe
20c0: 72 20 28 6c 6f 67 20 61 6e 64 20 62 61 6c 61 6e  r (log and balan
20d0: 63 65 20 6c 6f 67 69 63 29 27 2c 20 28 29 20 3d  ce logic)', () =
20e0: 3e 20 7b 0a 20 20 20 20 62 65 66 6f 72 65 45 61  > {.    beforeEa
20f0: 63 68 28 66 75 6e 63 74 69 6f 6e 20 2a 20 28 29  ch(function * ()
2100: 20 7b 0a 20 20 20 20 20 20 74 68 69 73 2e 66 75   {.      this.fu
2110: 6c 66 69 6c 6c 6d 65 6e 74 20 3d 20 72 65 71 75  lfillment = requ
2120: 69 72 65 28 27 63 72 79 70 74 6f 27 29 2e 72 61  ire('crypto').ra
2130: 6e 64 6f 6d 42 79 74 65 73 28 33 32 29 0a 20 20  ndomBytes(32).  
2140: 20 20 20 20 74 68 69 73 2e 74 72 61 6e 73 66 65      this.transfe
2150: 72 20 3d 20 7b 0a 20 20 20 20 20 20 20 20 69 64  r = {.        id
2160: 3a 20 75 75 69 64 28 29 2c 0a 20 20 20 20 20 20  : uuid(),.      
2170: 20 20 6c 65 64 67 65 72 3a 20 74 68 69 73 2e 70    ledger: this.p
2180: 6c 75 67 69 6e 2e 67 65 74 49 6e 66 6f 28 29 2e  lugin.getInfo().
2190: 70 72 65 66 69 78 2c 0a 20 20 20 20 20 20 20 20  prefix,.        
21a0: 66 72 6f 6d 3a 20 74 68 69 73 2e 70 6c 75 67 69  from: this.plugi
21b0: 6e 2e 67 65 74 41 63 63 6f 75 6e 74 28 29 2c 0a  n.getAccount(),.
21c0: 20 20 20 20 20 20 20 20 74 6f 3a 20 70 65 65 72          to: peer
21d0: 41 64 64 72 65 73 73 2c 0a 20 20 20 20 20 20 20  Address,.       
21e0: 20 65 78 70 69 72 65 73 41 74 3a 20 6e 65 77 20   expiresAt: new 
21f0: 44 61 74 65 28 44 61 74 65 2e 6e 6f 77 28 29 20  Date(Date.now() 
2200: 2b 20 31 30 30 30 30 29 2e 74 6f 49 53 4f 53 74  + 10000).toISOSt
2210: 72 69 6e 67 28 29 2c 0a 20 20 20 20 20 20 20 20  ring(),.        
2220: 61 6d 6f 75 6e 74 3a 20 27 35 27 2c 0a 20 20 20  amount: '5',.   
2230: 20 20 20 20 20 63 75 73 74 6f 6d 3a 20 7b 0a 20       custom: {. 
2240: 20 20 20 20 20 20 20 20 20 66 69 65 6c 64 3a 20           field: 
2250: 27 73 6f 6d 65 20 73 74 75 66 66 27 0a 20 20 20  'some stuff'.   
2260: 20 20 20 20 20 7d 2c 0a 20 20 20 20 20 20 20 20       },.        
2270: 65 78 65 63 75 74 69 6f 6e 43 6f 6e 64 69 74 69  executionConditi
2280: 6f 6e 3a 20 62 61 73 65 36 34 75 72 6c 28 63 72  on: base64url(cr
2290: 79 70 74 6f 0a 20 20 20 20 20 20 20 20 20 20 2e  ypto.          .
22a0: 63 72 65 61 74 65 48 61 73 68 28 27 73 68 61 32  createHash('sha2
22b0: 35 36 27 29 0a 20 20 20 20 20 20 20 20 20 20 2e  56').          .
22c0: 75 70 64 61 74 65 28 74 68 69 73 2e 66 75 6c 66  update(this.fulf
22d0: 69 6c 6c 6d 65 6e 74 29 0a 20 20 20 20 20 20 20  illment).       
22e0: 20 20 20 2e 64 69 67 65 73 74 28 29 29 0a 20 20     .digest()).  
22f0: 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 74 68 69      }..      thi
2300: 73 2e 62 74 70 54 72 61 6e 73 66 65 72 20 3d 20  s.btpTransfer = 
2310: 62 74 70 50 61 63 6b 65 74 2e 73 65 72 69 61 6c  btpPacket.serial
2320: 69 7a 65 50 72 65 70 61 72 65 28 0a 20 20 20 20  izePrepare(.    
2330: 20 20 20 20 4f 62 6a 65 63 74 2e 61 73 73 69 67      Object.assig
2340: 6e 28 7b 7d 2c 20 74 68 69 73 2e 74 72 61 6e 73  n({}, this.trans
2350: 66 65 72 2c 20 7b 74 72 61 6e 73 66 65 72 49 64  fer, {transferId
2360: 3a 20 74 68 69 73 2e 74 72 61 6e 73 66 65 72 2e  : this.transfer.
2370: 69 64 7d 29 2c 0a 20 20 20 20 20 20 20 20 31 32  id}),.        12
2380: 33 34 35 2c 20 2f 2f 20 72 65 71 75 65 73 74 49  345, // requestI
2390: 64 0a 20 20 20 20 20 20 20 20 69 6c 70 41 6e 64  d.        ilpAnd
23a0: 43 75 73 74 6f 6d 54 6f 50 72 6f 74 6f 63 6f 6c  CustomToProtocol
23b0: 44 61 74 61 28 74 68 69 73 2e 74 72 61 6e 73 66  Data(this.transf
23c0: 65 72 29 0a 20 20 20 20 20 20 29 0a 20 20 20 20  er).      ).    
23d0: 20 20 74 68 69 73 2e 62 74 70 46 75 6c 66 69 6c    this.btpFulfil
23e0: 6c 6d 65 6e 74 20 3d 20 62 74 70 50 61 63 6b 65  lment = btpPacke
23f0: 74 2e 73 65 72 69 61 6c 69 7a 65 46 75 6c 66 69  t.serializeFulfi
2400: 6c 6c 28 7b 0a 20 20 20 20 20 20 20 20 74 72 61  ll({.        tra
2410: 6e 73 66 65 72 49 64 3a 20 74 68 69 73 2e 74 72  nsferId: this.tr
2420: 61 6e 73 66 65 72 2e 69 64 2c 0a 20 20 20 20 20  ansfer.id,.     
2430: 20 20 20 66 75 6c 66 69 6c 6c 6d 65 6e 74 3a 20     fulfillment: 
2440: 74 68 69 73 2e 66 75 6c 66 69 6c 6c 6d 65 6e 74  this.fulfillment
2450: 0a 20 20 20 20 20 20 7d 2c 20 39 38 37 36 35 2c  .      }, 98765,
2460: 20 5b 5d 29 0a 20 20 20 20 7d 29 0a 0a 20 20 20   []).    })..   
2470: 20 69 74 28 27 73 68 6f 75 6c 64 20 73 65 6e 64   it('should send
2480: 20 61 20 74 72 61 6e 73 66 65 72 27 2c 20 61 73   a transfer', as
2490: 79 6e 63 20 66 75 6e 63 74 69 6f 6e 20 28 29 20  ync function () 
24a0: 7b 0a 20 20 20 20 20 20 74 68 69 73 2e 6d 6f 63  {.      this.moc
24b0: 6b 53 6f 63 6b 65 74 2e 72 65 70 6c 79 28 62 74  kSocket.reply(bt
24c0: 70 50 61 63 6b 65 74 2e 54 59 50 45 5f 50 52 45  pPacket.TYPE_PRE
24d0: 50 41 52 45 2c 20 28 7b 72 65 71 75 65 73 74 49  PARE, ({requestI
24e0: 64 2c 20 64 61 74 61 7d 29 20 3d 3e 20 7b 0a 20  d, data}) => {. 
24f0: 20 20 20 20 20 20 20 61 73 73 65 72 74 2e 65 71         assert.eq
2500: 75 61 6c 28 64 61 74 61 2e 74 72 61 6e 73 66 65  ual(data.transfe
2510: 72 49 64 2c 20 74 68 69 73 2e 74 72 61 6e 73 66  rId, this.transf
2520: 65 72 2e 69 64 29 0a 20 20 20 20 20 20 20 20 61  er.id).        a
2530: 73 73 65 72 74 2e 65 71 75 61 6c 28 64 61 74 61  ssert.equal(data
2540: 2e 61 6d 6f 75 6e 74 2c 20 2b 74 68 69 73 2e 74  .amount, +this.t
2550: 72 61 6e 73 66 65 72 2e 61 6d 6f 75 6e 74 29 0a  ransfer.amount).
2560: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 2e 65          assert.e
2570: 71 75 61 6c 28 64 61 74 61 2e 65 78 65 63 75 74  qual(data.execut
2580: 69 6f 6e 43 6f 6e 64 69 74 69 6f 6e 2c 20 74 68  ionCondition, th
2590: 69 73 2e 74 72 61 6e 73 66 65 72 2e 65 78 65 63  is.transfer.exec
25a0: 75 74 69 6f 6e 43 6f 6e 64 69 74 69 6f 6e 29 0a  utionCondition).
25b0: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 2e 65          assert.e
25c0: 71 75 61 6c 28 64 61 74 61 2e 65 78 70 69 72 65  qual(data.expire
25d0: 73 41 74 2e 67 65 74 54 69 6d 65 28 29 2c 0a 20  sAt.getTime(),. 
25e0: 20 20 20 20 20 20 20 20 20 6e 65 77 20 44 61 74           new Dat
25f0: 65 28 74 68 69 73 2e 74 72 61 6e 73 66 65 72 2e  e(this.transfer.
2600: 65 78 70 69 72 65 73 41 74 29 2e 67 65 74 54 69  expiresAt).getTi
2610: 6d 65 28 29 29 0a 20 20 20 20 20 20 20 20 63 6f  me()).        co
2620: 6e 73 74 20 7b 63 75 73 74 6f 6d 7d 20 3d 20 70  nst {custom} = p
2630: 72 6f 74 6f 63 6f 6c 44 61 74 61 54 6f 49 6c 70  rotocolDataToIlp
2640: 41 6e 64 43 75 73 74 6f 6d 28 64 61 74 61 29 0a  AndCustom(data).
2650: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 2e 64          assert.d
2660: 65 65 70 45 71 75 61 6c 28 63 75 73 74 6f 6d 2c  eepEqual(custom,
2670: 20 74 68 69 73 2e 74 72 61 6e 73 66 65 72 2e 63   this.transfer.c
2680: 75 73 74 6f 6d 29 0a 0a 20 20 20 20 20 20 20 20  ustom)..        
2690: 72 65 74 75 72 6e 20 62 74 70 50 61 63 6b 65 74  return btpPacket
26a0: 2e 73 65 72 69 61 6c 69 7a 65 52 65 73 70 6f 6e  .serializeRespon
26b0: 73 65 28 72 65 71 75 65 73 74 49 64 2c 20 5b 5d  se(requestId, []
26c0: 29 0a 20 20 20 20 20 20 7d 29 0a 0a 20 20 20 20  ).      })..    
26d0: 20 20 63 6f 6e 73 74 20 73 65 6e 74 20 3d 20 6e    const sent = n
26e0: 65 77 20 50 72 6f 6d 69 73 65 28 28 72 65 73 6f  ew Promise((reso
26f0: 6c 76 65 29 20 3d 3e 20 74 68 69 73 2e 70 6c 75  lve) => this.plu
2700: 67 69 6e 2e 6f 6e 28 27 6f 75 74 67 6f 69 6e 67  gin.on('outgoing
2710: 5f 70 72 65 70 61 72 65 27 2c 20 72 65 73 6f 6c  _prepare', resol
2720: 76 65 29 29 0a 20 20 20 20 20 20 61 77 61 69 74  ve)).      await
2730: 20 74 68 69 73 2e 70 6c 75 67 69 6e 2e 73 65 6e   this.plugin.sen
2740: 64 54 72 61 6e 73 66 65 72 28 74 68 69 73 2e 74  dTransfer(this.t
2750: 72 61 6e 73 66 65 72 29 0a 20 20 20 20 20 20 61  ransfer).      a
2760: 77 61 69 74 20 73 65 6e 74 0a 0a 20 20 20 20 20  wait sent..     
2770: 20 2f 2f 20 54 4f 44 4f 3a 20 40 73 68 61 72 61   // TODO: @shara
2780: 66 69 61 6e 2c 20 77 68 65 6e 20 69 73 20 74 68  fian, when is th
2790: 65 20 62 61 6c 61 6e 63 65 20 73 75 70 70 6f 73  e balance suppos
27a0: 65 64 20 74 6f 20 62 65 20 75 70 64 61 74 65 64  ed to be updated
27b0: 3f 0a 20 20 20 20 20 20 2f 2f 20 41 74 20 74 68  ?.      // At th
27c0: 65 20 6d 6f 6d 65 6e 74 2c 20 61 20 63 61 6c 6c  e moment, a call
27d0: 20 74 6f 20 73 65 6e 64 54 72 61 6e 73 66 65 72   to sendTransfer
27e0: 20 64 6f 65 73 20 6e 6f 74 20 75 70 64 61 74 65   does not update
27f0: 20 74 68 65 20 62 61 6c 61 6e 63 65 2c 20 73 65   the balance, se
2800: 65 20 62 65 6c 6f 77 3a 0a 20 20 20 20 20 20 2f  e below:.      /
2810: 2f 20 61 77 61 69 74 20 6e 65 77 20 50 72 6f 6d  / await new Prom
2820: 69 73 65 28 61 73 79 6e 63 20 28 72 65 73 6f 6c  ise(async (resol
2830: 76 65 2c 20 72 65 6a 65 63 74 29 20 3d 3e 20 7b  ve, reject) => {
2840: 0a 20 20 20 20 20 20 2f 2f 20 20 20 73 65 74 54  .      //   setT
2850: 69 6d 65 6f 75 74 28 61 73 79 6e 63 20 28 29 20  imeout(async () 
2860: 3d 3e 20 7b 0a 20 20 20 20 20 20 2f 2f 20 20 20  => {.      //   
2870: 20 20 63 6f 6e 73 74 20 62 61 6c 61 6e 63 65 20    const balance 
2880: 3d 20 61 77 61 69 74 20 74 68 69 73 2e 70 6c 75  = await this.plu
2890: 67 69 6e 2e 67 65 74 42 61 6c 61 6e 63 65 28 29  gin.getBalance()
28a0: 0a 20 20 20 20 20 20 2f 2f 20 20 20 20 20 63 6f  .      //     co
28b0: 6e 73 6f 6c 65 2e 6c 6f 67 28 27 62 61 6c 61 6e  nsole.log('balan
28c0: 63 65 27 2c 20 62 61 6c 61 6e 63 65 29 0a 20 20  ce', balance).  
28d0: 20 20 20 20 2f 2f 20 20 20 20 20 72 65 73 6f 6c      //     resol
28e0: 76 65 28 29 0a 20 20 20 20 20 20 2f 2f 20 20 20  ve().      //   
28f0: 7d 2c 20 32 30 30 29 0a 20 20 20 20 20 20 2f 2f  }, 200).      //
2900: 20 7d 29 0a 20 20 20 20 7d 29 0a 0a 20 20 20 20   }).    })..    
2910: 69 74 28 27 73 68 6f 75 6c 64 20 72 6f 6c 6c 20  it('should roll 
2920: 62 61 63 6b 20 61 20 74 72 61 6e 73 66 65 72 20  back a transfer 
2930: 69 66 20 74 68 65 20 52 50 43 20 63 61 6c 6c 20  if the RPC call 
2940: 66 61 69 6c 73 27 2c 20 66 75 6e 63 74 69 6f 6e  fails', function
2950: 20 2a 20 28 29 20 7b 0a 20 20 20 20 20 20 74 68   * () {.      th
2960: 69 73 2e 6d 6f 63 6b 53 6f 63 6b 65 74 2e 72 65  is.mockSocket.re
2970: 70 6c 79 28 62 74 70 50 61 63 6b 65 74 2e 54 59  ply(btpPacket.TY
2980: 50 45 5f 50 52 45 50 41 52 45 2c 20 28 7b 72 65  PE_PREPARE, ({re
2990: 71 75 65 73 74 49 64 2c 20 64 61 74 61 7d 29 20  questId, data}) 
29a0: 3d 3e 20 7b 0a 20 20 20 20 20 20 20 20 72 65 74  => {.        ret
29b0: 75 72 6e 20 62 74 70 50 61 63 6b 65 74 2e 73 65  urn btpPacket.se
29c0: 72 69 61 6c 69 7a 65 45 72 72 6f 72 28 74 68 69  rializeError(thi
29d0: 73 2e 65 72 72 6f 72 2c 0a 20 20 20 20 20 20 20  s.error,.       
29e0: 20 20 20 72 65 71 75 65 73 74 49 64 2c 20 5b 5d     requestId, []
29f0: 29 0a 20 20 20 20 20 20 7d 29 0a 0a 20 20 20 20  ).      })..    
2a00: 20 20 79 69 65 6c 64 20 65 78 70 65 63 74 28 74    yield expect(t
2a10: 68 69 73 2e 70 6c 75 67 69 6e 2e 73 65 6e 64 54  his.plugin.sendT
2a20: 72 61 6e 73 66 65 72 28 74 68 69 73 2e 74 72 61  ransfer(this.tra
2a30: 6e 73 66 65 72 29 29 0a 20 20 20 20 20 20 20 20  nsfer)).        
2a40: 2e 74 6f 2e 65 76 65 6e 74 75 61 6c 6c 79 2e 62  .to.eventually.b
2a50: 65 2e 72 65 6a 65 63 74 65 64 0a 0a 20 20 20 20  e.rejected..    
2a60: 20 20 61 73 73 65 72 74 2e 65 71 75 61 6c 28 28    assert.equal((
2a70: 79 69 65 6c 64 20 74 68 69 73 2e 70 6c 75 67 69  yield this.plugi
2a80: 6e 2e 67 65 74 42 61 6c 61 6e 63 65 28 29 29 2c  n.getBalance()),
2a90: 20 27 30 27 2c 20 27 62 61 6c 61 6e 63 65 20 73   '0', 'balance s
2aa0: 68 6f 75 6c 64 20 62 65 20 72 6f 6c 6c 65 64 20  hould be rolled 
2ab0: 62 61 63 6b 27 29 0a 20 20 20 20 7d 29 0a 0a 20  back').    }).. 
2ac0: 20 20 20 69 74 28 27 73 68 6f 75 6c 64 20 72 65     it('should re
2ad0: 63 65 69 76 65 20 61 20 74 72 61 6e 73 66 65 72  ceive a transfer
2ae0: 27 2c 20 66 75 6e 63 74 69 6f 6e 20 2a 20 28 29  ', function * ()
2af0: 20 7b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 72   {.      const r
2b00: 65 63 65 69 76 65 64 20 3d 20 6e 65 77 20 50 72  eceived = new Pr
2b10: 6f 6d 69 73 65 28 28 72 65 73 6f 6c 76 65 2c 20  omise((resolve, 
2b20: 72 65 6a 65 63 74 29 20 3d 3e 20 7b 0a 20 20 20  reject) => {.   
2b30: 20 20 20 20 20 74 68 69 73 2e 70 6c 75 67 69 6e       this.plugin
2b40: 2e 6f 6e 28 27 69 6e 63 6f 6d 69 6e 67 5f 70 72  .on('incoming_pr
2b50: 65 70 61 72 65 27 2c 20 28 74 72 61 6e 73 66 65  epare', (transfe
2b60: 72 29 20 3d 3e 20 7b 0a 20 20 20 20 20 20 20 20  r) => {.        
2b70: 20 20 74 72 79 20 7b 0a 20 20 20 20 20 20 20 20    try {.        
2b80: 20 20 20 20 61 73 73 65 72 74 2e 64 65 65 70 45      assert.deepE
2b90: 71 75 61 6c 28 74 72 61 6e 73 66 65 72 2c 20 74  qual(transfer, t
2ba0: 68 69 73 2e 74 72 61 6e 73 66 65 72 29 0a 20 20  his.transfer).  
2bb0: 20 20 20 20 20 20 20 20 7d 20 63 61 74 63 68 20          } catch 
2bc0: 28 65 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20  (e) {.          
2bd0: 20 20 72 65 6a 65 63 74 28 65 29 0a 20 20 20 20    reject(e).    
2be0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
2bf0: 20 20 72 65 73 6f 6c 76 65 28 29 0a 20 20 20 20    resolve().    
2c00: 20 20 20 20 7d 29 0a 20 20 20 20 20 20 7d 29 0a      }).      }).
2c10: 0a 20 20 20 20 20 20 74 68 69 73 2e 74 72 61 6e  .      this.tran
2c20: 73 66 65 72 2e 66 72 6f 6d 20 3d 20 70 65 65 72  sfer.from = peer
2c30: 41 64 64 72 65 73 73 0a 20 20 20 20 20 20 74 68  Address.      th
2c40: 69 73 2e 74 72 61 6e 73 66 65 72 2e 74 6f 20 3d  is.transfer.to =
2c50: 20 74 68 69 73 2e 70 6c 75 67 69 6e 2e 67 65 74   this.plugin.get
2c60: 41 63 63 6f 75 6e 74 28 29 0a 0a 20 20 20 20 20  Account()..     
2c70: 20 74 68 69 73 2e 6d 6f 63 6b 53 6f 63 6b 65 74   this.mockSocket
2c80: 2e 72 65 70 6c 79 28 62 74 70 50 61 63 6b 65 74  .reply(btpPacket
2c90: 2e 54 59 50 45 5f 52 45 53 50 4f 4e 53 45 29 0a  .TYPE_RESPONSE).
2ca0: 0a 20 20 20 20 20 20 79 69 65 6c 64 20 74 68 69  .      yield thi
2cb0: 73 2e 70 6c 75 67 69 6e 2e 5f 72 70 63 2e 68 61  s.plugin._rpc.ha
2cc0: 6e 64 6c 65 4d 65 73 73 61 67 65 28 74 68 69 73  ndleMessage(this
2cd0: 2e 6d 6f 63 6b 53 6f 63 6b 65 74 49 6e 64 65 78  .mockSocketIndex
2ce0: 2c 20 74 68 69 73 2e 62 74 70 54 72 61 6e 73 66  , this.btpTransf
2cf0: 65 72 29 0a 20 20 20 20 20 20 79 69 65 6c 64 20  er).      yield 
2d00: 72 65 63 65 69 76 65 64 0a 20 20 20 20 7d 29 0a  received.    }).
2d10: 0a 20 20 20 20 69 74 28 27 73 68 6f 75 6c 64 20  .    it('should 
2d20: 6e 6f 74 20 72 61 63 65 20 77 68 65 6e 20 72 65  not race when re
2d30: 61 64 69 6e 67 20 74 68 65 20 62 61 6c 61 6e 63  ading the balanc
2d40: 65 27 2c 20 66 75 6e 63 74 69 6f 6e 20 2a 20 28  e', function * (
2d50: 29 20 7b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20  ) {.      const 
2d60: 74 72 61 6e 73 66 65 72 32 20 3d 20 4f 62 6a 65  transfer2 = Obje
2d70: 63 74 2e 61 73 73 69 67 6e 28 7b 7d 2c 20 74 68  ct.assign({}, th
2d80: 69 73 2e 74 72 61 6e 73 66 65 72 2c 20 7b 20 69  is.transfer, { i
2d90: 64 3a 20 75 75 69 64 28 29 20 7d 29 0a 20 20 20  d: uuid() }).   
2da0: 20 20 20 63 6f 6e 73 74 20 66 75 6c 66 69 6c 6c     const fulfill
2db0: 6d 65 6e 74 32 20 3d 20 62 74 70 50 61 63 6b 65  ment2 = btpPacke
2dc0: 74 2e 73 65 72 69 61 6c 69 7a 65 46 75 6c 66 69  t.serializeFulfi
2dd0: 6c 6c 28 7b 0a 20 20 20 20 20 20 20 20 74 72 61  ll({.        tra
2de0: 6e 73 66 65 72 49 64 3a 20 74 72 61 6e 73 66 65  nsferId: transfe
2df0: 72 32 2e 69 64 2c 0a 20 20 20 20 20 20 20 20 66  r2.id,.        f
2e00: 75 6c 66 69 6c 6c 6d 65 6e 74 3a 20 74 68 69 73  ulfillment: this
2e10: 2e 66 75 6c 66 69 6c 6c 6d 65 6e 74 0a 20 20 20  .fulfillment.   
2e20: 20 20 20 7d 2c 20 39 38 37 36 35 2c 20 5b 5d 29     }, 98765, [])
2e30: 0a 0a 20 20 20 20 20 20 74 68 69 73 2e 6d 6f 63  ..      this.moc
2e40: 6b 53 6f 63 6b 65 74 0a 20 20 20 20 20 20 20 20  kSocket.        
2e50: 2e 72 65 70 6c 79 28 62 74 70 50 61 63 6b 65 74  .reply(btpPacket
2e60: 2e 54 59 50 45 5f 50 52 45 50 41 52 45 2c 20 28  .TYPE_PREPARE, (
2e70: 7b 72 65 71 75 65 73 74 49 64 2c 20 64 61 74 61  {requestId, data
2e80: 7d 29 20 3d 3e 20 7b 0a 20 20 20 20 20 20 20 20  }) => {.        
2e90: 20 20 72 65 74 75 72 6e 20 62 74 70 50 61 63 6b    return btpPack
2ea0: 65 74 2e 73 65 72 69 61 6c 69 7a 65 52 65 73 70  et.serializeResp
2eb0: 6f 6e 73 65 28 72 65 71 75 65 73 74 49 64 2c 20  onse(requestId, 
2ec0: 5b 5d 29 0a 20 20 20 20 20 20 20 20 7d 29 0a 20  []).        }). 
2ed0: 20 20 20 20 20 20 20 2e 72 65 70 6c 79 28 62 74         .reply(bt
2ee0: 70 50 61 63 6b 65 74 2e 54 59 50 45 5f 50 52 45  pPacket.TYPE_PRE
2ef0: 50 41 52 45 2c 20 28 7b 72 65 71 75 65 73 74 49  PARE, ({requestI
2f00: 64 2c 20 64 61 74 61 7d 29 20 3d 3e 20 7b 0a 20  d, data}) => {. 
2f10: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20           return 
2f20: 62 74 70 50 61 63 6b 65 74 2e 73 65 72 69 61 6c  btpPacket.serial
2f30: 69 7a 65 52 65 73 70 6f 6e 73 65 28 72 65 71 75  izeResponse(requ
2f40: 65 73 74 49 64 2c 20 5b 5d 29 0a 20 20 20 20 20  estId, []).     
2f50: 20 20 20 7d 29 0a 20 20 20 20 20 20 20 20 2e 72     }).        .r
2f60: 65 70 6c 79 28 62 74 70 50 61 63 6b 65 74 2e 54  eply(btpPacket.T
2f70: 59 50 45 5f 52 45 53 50 4f 4e 53 45 29 0a 20 20  YPE_RESPONSE).  
2f80: 20 20 20 20 20 20 2e 72 65 70 6c 79 28 62 74 70        .reply(btp
2f90: 50 61 63 6b 65 74 2e 54 59 50 45 5f 52 45 53 50  Packet.TYPE_RESP
2fa0: 4f 4e 53 45 29 0a 0a 20 20 20 20 20 20 79 69 65  ONSE)..      yie
2fb0: 6c 64 20 74 68 69 73 2e 70 6c 75 67 69 6e 2e 73  ld this.plugin.s
2fc0: 65 6e 64 54 72 61 6e 73 66 65 72 28 74 68 69 73  endTransfer(this
2fd0: 2e 74 72 61 6e 73 66 65 72 29 0a 20 20 20 20 20  .transfer).     
2fe0: 20 79 69 65 6c 64 20 74 68 69 73 2e 70 6c 75 67   yield this.plug
2ff0: 69 6e 2e 73 65 6e 64 54 72 61 6e 73 66 65 72 28  in.sendTransfer(
3000: 74 72 61 6e 73 66 65 72 32 29 0a 0a 20 20 20 20  transfer2)..    
3010: 20 20 63 6f 6e 73 74 20 73 65 6e 64 31 20 3d 20    const send1 = 
3020: 74 68 69 73 2e 70 6c 75 67 69 6e 2e 5f 72 70 63  this.plugin._rpc
3030: 2e 68 61 6e 64 6c 65 4d 65 73 73 61 67 65 28 74  .handleMessage(t
3040: 68 69 73 2e 6d 6f 63 6b 53 6f 63 6b 65 74 49 6e  his.mockSocketIn
3050: 64 65 78 2c 20 74 68 69 73 2e 62 74 70 46 75 6c  dex, this.btpFul
3060: 66 69 6c 6c 6d 65 6e 74 29 0a 20 20 20 20 20 20  fillment).      
3070: 63 6f 6e 73 74 20 73 65 6e 64 32 20 3d 20 74 68  const send2 = th
3080: 69 73 2e 70 6c 75 67 69 6e 2e 5f 72 70 63 2e 68  is.plugin._rpc.h
3090: 61 6e 64 6c 65 4d 65 73 73 61 67 65 28 74 68 69  andleMessage(thi
30a0: 73 2e 6d 6f 63 6b 53 6f 63 6b 65 74 49 6e 64 65  s.mockSocketInde
30b0: 78 2c 20 66 75 6c 66 69 6c 6c 6d 65 6e 74 32 29  x, fulfillment2)
30c0: 0a 0a 20 20 20 20 20 20 79 69 65 6c 64 20 50 72  ..      yield Pr
30d0: 6f 6d 69 73 65 2e 61 6c 6c 28 5b 20 73 65 6e 64  omise.all([ send
30e0: 31 2c 20 73 65 6e 64 32 20 5d 29 0a 20 20 20 20  1, send2 ]).    
30f0: 20 20 61 73 73 65 72 74 2e 65 71 75 61 6c 28 79    assert.equal(y
3100: 69 65 6c 64 20 74 68 69 73 2e 70 6c 75 67 69 6e  ield this.plugin
3110: 2e 67 65 74 42 61 6c 61 6e 63 65 28 29 2c 20 27  .getBalance(), '
3120: 2d 31 30 27 2c 0a 20 20 20 20 20 20 20 20 27 62  -10',.        'b
3130: 6f 74 68 20 74 72 61 6e 73 66 65 72 73 20 73 68  oth transfers sh
3140: 6f 75 6c 64 20 62 65 20 61 70 70 6c 69 65 64 20  ould be applied 
3150: 74 6f 20 74 68 65 20 62 61 6c 61 6e 63 65 27 29  to the balance')
3160: 0a 20 20 20 20 7d 29 0a 0a 20 20 20 20 69 74 28  .    })..    it(
3170: 27 73 68 6f 75 6c 64 20 6e 6f 74 20 61 70 70 6c  'should not appl
3180: 79 20 74 77 69 63 65 20 77 68 65 6e 20 74 77 6f  y twice when two
3190: 20 69 64 65 6e 74 69 63 61 6c 20 74 72 61 6e 73   identical trans
31a0: 66 65 72 73 20 63 6f 6d 65 20 69 6e 20 77 69 74  fers come in wit
31b0: 68 20 74 68 65 20 73 61 6d 65 20 69 64 27 2c 20  h the same id', 
31c0: 66 75 6e 63 74 69 6f 6e 20 2a 20 28 29 20 7b 0a  function * () {.
31d0: 20 20 20 20 20 20 74 68 69 73 2e 6d 6f 63 6b 53        this.mockS
31e0: 6f 63 6b 65 74 0a 20 20 20 20 20 20 20 20 2e 72  ocket.        .r
31f0: 65 70 6c 79 28 62 74 70 50 61 63 6b 65 74 2e 54  eply(btpPacket.T
3200: 59 50 45 5f 50 52 45 50 41 52 45 2c 20 28 7b 72  YPE_PREPARE, ({r
3210: 65 71 75 65 73 74 49 64 2c 20 64 61 74 61 7d 29  equestId, data})
3220: 20 3d 3e 20 7b 0a 20 20 20 20 20 20 20 20 20 20   => {.          
3230: 72 65 74 75 72 6e 20 62 74 70 50 61 63 6b 65 74  return btpPacket
3240: 2e 73 65 72 69 61 6c 69 7a 65 52 65 73 70 6f 6e  .serializeRespon
3250: 73 65 28 72 65 71 75 65 73 74 49 64 2c 20 5b 5d  se(requestId, []
3260: 29 0a 20 20 20 20 20 20 20 20 7d 29 0a 20 20 20  ).        }).   
3270: 20 20 20 20 20 2e 72 65 70 6c 79 28 62 74 70 50       .reply(btpP
3280: 61 63 6b 65 74 2e 54 59 50 45 5f 50 52 45 50 41  acket.TYPE_PREPA
3290: 52 45 2c 20 28 7b 72 65 71 75 65 73 74 49 64 2c  RE, ({requestId,
32a0: 20 64 61 74 61 7d 29 20 3d 3e 20 7b 0a 20 20 20   data}) => {.   
32b0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 62 74         return bt
32c0: 70 50 61 63 6b 65 74 2e 73 65 72 69 61 6c 69 7a  pPacket.serializ
32d0: 65 52 65 73 70 6f 6e 73 65 28 72 65 71 75 65 73  eResponse(reques
32e0: 74 49 64 2c 20 5b 5d 29 0a 20 20 20 20 20 20 20  tId, []).       
32f0: 20 7d 29 0a 20 20 20 20 20 20 20 20 2e 72 65 70   }).        .rep
3300: 6c 79 28 62 74 70 50 61 63 6b 65 74 2e 54 59 50  ly(btpPacket.TYP
3310: 45 5f 45 52 52 4f 52 29 0a 20 20 20 20 20 20 20  E_ERROR).       
3320: 20 2e 72 65 70 6c 79 28 62 74 70 50 61 63 6b 65   .reply(btpPacke
3330: 74 2e 54 59 50 45 5f 52 45 53 50 4f 4e 53 45 29  t.TYPE_RESPONSE)
3340: 0a 0a 20 20 20 20 20 20 79 69 65 6c 64 20 74 68  ..      yield th
3350: 69 73 2e 70 6c 75 67 69 6e 2e 73 65 6e 64 54 72  is.plugin.sendTr
3360: 61 6e 73 66 65 72 28 74 68 69 73 2e 74 72 61 6e  ansfer(this.tran
3370: 73 66 65 72 29 0a 20 20 20 20 20 20 79 69 65 6c  sfer).      yiel
3380: 64 20 74 68 69 73 2e 70 6c 75 67 69 6e 2e 73 65  d this.plugin.se
3390: 6e 64 54 72 61 6e 73 66 65 72 28 74 68 69 73 2e  ndTransfer(this.
33a0: 74 72 61 6e 73 66 65 72 29 0a 0a 20 20 20 20 20  transfer)..     
33b0: 20 63 6f 6e 73 74 20 73 65 6e 64 31 20 3d 20 74   const send1 = t
33c0: 68 69 73 2e 70 6c 75 67 69 6e 2e 5f 72 70 63 2e  his.plugin._rpc.
33d0: 68 61 6e 64 6c 65 4d 65 73 73 61 67 65 28 74 68  handleMessage(th
33e0: 69 73 2e 6d 6f 63 6b 53 6f 63 6b 65 74 49 6e 64  is.mockSocketInd
33f0: 65 78 2c 20 74 68 69 73 2e 62 74 70 46 75 6c 66  ex, this.btpFulf
3400: 69 6c 6c 6d 65 6e 74 29 0a 20 20 20 20 20 20 63  illment).      c
3410: 6f 6e 73 74 20 73 65 6e 64 32 20 3d 20 74 68 69  onst send2 = thi
3420: 73 2e 70 6c 75 67 69 6e 2e 5f 72 70 63 2e 68 61  s.plugin._rpc.ha
3430: 6e 64 6c 65 4d 65 73 73 61 67 65 28 74 68 69 73  ndleMessage(this
3440: 2e 6d 6f 63 6b 53 6f 63 6b 65 74 49 6e 64 65 78  .mockSocketIndex
3450: 2c 20 74 68 69 73 2e 62 74 70 46 75 6c 66 69 6c  , this.btpFulfil
3460: 6c 6d 65 6e 74 29 0a 20 20 20 20 20 20 20 20 2e  lment).        .
3470: 63 61 74 63 68 28 28 65 29 20 3d 3e 20 7b 7d 29  catch((e) => {})
3480: 0a 0a 20 20 20 20 20 20 79 69 65 6c 64 20 50 72  ..      yield Pr
3490: 6f 6d 69 73 65 2e 61 6c 6c 28 5b 20 73 65 6e 64  omise.all([ send
34a0: 31 2c 20 73 65 6e 64 32 20 5d 29 0a 20 20 20 20  1, send2 ]).    
34b0: 20 20 61 73 73 65 72 74 2e 65 71 75 61 6c 28 79    assert.equal(y
34c0: 69 65 6c 64 20 74 68 69 73 2e 70 6c 75 67 69 6e  ield this.plugin
34d0: 2e 67 65 74 42 61 6c 61 6e 63 65 28 29 2c 20 27  .getBalance(), '
34e0: 2d 35 27 2c 0a 20 20 20 20 20 20 20 20 27 6f 6e  -5',.        'on
34f0: 6c 79 20 6f 6e 65 20 6f 66 20 74 68 65 20 74 72  ly one of the tr
3500: 61 6e 73 66 65 72 73 20 73 68 6f 75 6c 64 20 62  ansfers should b
3510: 65 20 61 70 70 6c 69 65 64 20 74 6f 20 74 68 65  e applied to the
3520: 20 62 61 6c 61 6e 63 65 27 29 0a 20 20 20 20 7d   balance').    }
3530: 29 0a 0a 20 20 20 20 69 74 28 27 73 68 6f 75 6c  )..    it('shoul
3540: 64 20 6e 6f 74 20 72 61 63 65 20 77 68 65 6e 20  d not race when 
3550: 74 77 6f 20 64 69 66 66 65 72 65 6e 74 20 74 72  two different tr
3560: 61 6e 73 66 65 72 73 20 63 6f 6d 65 20 69 6e 20  ansfers come in 
3570: 77 69 74 68 20 74 68 65 20 73 61 6d 65 20 69 64  with the same id
3580: 27 2c 20 66 75 6e 63 74 69 6f 6e 20 2a 20 28 29  ', function * ()
3590: 20 7b 0a 20 20 20 20 20 20 74 68 69 73 2e 6d 6f   {.      this.mo
35a0: 63 6b 53 6f 63 6b 65 74 0a 20 20 20 20 20 20 20  ckSocket.       
35b0: 20 2e 72 65 70 6c 79 28 62 74 70 50 61 63 6b 65   .reply(btpPacke
35c0: 74 2e 54 59 50 45 5f 50 52 45 50 41 52 45 2c 20  t.TYPE_PREPARE, 
35d0: 28 7b 72 65 71 75 65 73 74 49 64 2c 20 64 61 74  ({requestId, dat
35e0: 61 7d 29 20 3d 3e 20 7b 0a 20 20 20 20 20 20 20  a}) => {.       
35f0: 20 20 20 72 65 74 75 72 6e 20 62 74 70 50 61 63     return btpPac
3600: 6b 65 74 2e 73 65 72 69 61 6c 69 7a 65 52 65 73  ket.serializeRes
3610: 70 6f 6e 73 65 28 72 65 71 75 65 73 74 49 64 2c  ponse(requestId,
3620: 20 5b 5d 29 0a 20 20 20 20 20 20 20 20 7d 29 0a   []).        }).
3630: 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 74 72 61  .      const tra
3640: 6e 73 66 65 72 32 20 3d 20 4f 62 6a 65 63 74 2e  nsfer2 = Object.
3650: 61 73 73 69 67 6e 28 7b 7d 2c 20 74 68 69 73 2e  assign({}, this.
3660: 74 72 61 6e 73 66 65 72 2c 20 7b 20 61 6d 6f 75  transfer, { amou
3670: 6e 74 3a 20 27 31 30 27 20 7d 29 0a 0a 20 20 20  nt: '10' })..   
3680: 20 20 20 63 6f 6e 73 74 20 73 65 6e 64 31 20 3d     const send1 =
3690: 20 74 68 69 73 2e 70 6c 75 67 69 6e 2e 73 65 6e   this.plugin.sen
36a0: 64 54 72 61 6e 73 66 65 72 28 74 68 69 73 2e 74  dTransfer(this.t
36b0: 72 61 6e 73 66 65 72 29 0a 20 20 20 20 20 20 63  ransfer).      c
36c0: 6f 6e 73 74 20 73 65 6e 64 32 20 3d 20 74 68 69  onst send2 = thi
36d0: 73 2e 70 6c 75 67 69 6e 2e 73 65 6e 64 54 72 61  s.plugin.sendTra
36e0: 6e 73 66 65 72 28 74 72 61 6e 73 66 65 72 32 29  nsfer(transfer2)
36f0: 0a 0a 20 20 20 20 20 20 2f 2f 20 6f 6e 65 20 6f  ..      // one o
3700: 66 20 74 68 65 73 65 20 73 68 6f 75 6c 64 20 62  f these should b
3710: 65 20 72 65 6a 65 63 74 65 64 20 62 65 63 61 75  e rejected becau
3720: 73 65 20 74 68 65 79 20 61 72 65 20 74 77 6f 20  se they are two 
3730: 74 72 61 6e 73 66 65 72 20 77 69 74 68 20 74 68  transfer with th
3740: 65 0a 20 20 20 20 20 20 2f 2f 20 73 61 6d 65 20  e.      // same 
3750: 49 44 20 62 75 74 20 64 69 66 66 65 72 65 6e 74  ID but different
3760: 20 64 61 74 61 0a 20 20 20 20 20 20 79 69 65 6c   data.      yiel
3770: 64 20 65 78 70 65 63 74 28 50 72 6f 6d 69 73 65  d expect(Promise
3780: 2e 61 6c 6c 28 5b 20 73 65 6e 64 31 2c 20 73 65  .all([ send1, se
3790: 6e 64 32 20 5d 29 29 0a 20 20 20 20 20 20 20 20  nd2 ])).        
37a0: 2e 74 6f 2e 65 76 65 6e 74 75 61 6c 6c 79 2e 62  .to.eventually.b
37b0: 65 2e 72 65 6a 65 63 74 65 64 57 69 74 68 28 2f  e.rejectedWith(/
37c0: 74 72 61 6e 73 66 65 72 20 2e 2a 20 6d 61 74 63  transfer .* matc
37d0: 68 65 73 20 74 68 65 20 69 64 20 6f 66 20 2e 2a  hes the id of .*
37e0: 20 62 75 74 20 6e 6f 74 20 74 68 65 20 63 6f 6e   but not the con
37f0: 74 65 6e 74 73 2f 29 0a 20 20 20 20 7d 29 0a 0a  tents/).    })..
3800: 20 20 20 20 69 74 28 27 73 68 6f 75 6c 64 20 6e      it('should n
3810: 6f 74 20 73 65 6e 64 20 61 20 74 72 61 6e 73 66  ot send a transf
3820: 65 72 20 77 69 74 68 6f 75 74 20 69 64 27 2c 20  er without id', 
3830: 66 75 6e 63 74 69 6f 6e 20 28 29 20 7b 0a 20 20  function () {.  
3840: 20 20 20 20 74 68 69 73 2e 74 72 61 6e 73 66 65      this.transfe
3850: 72 2e 69 64 20 3d 20 75 6e 64 65 66 69 6e 65 64  r.id = undefined
3860: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 65 78  .      return ex
3870: 70 65 63 74 28 74 68 69 73 2e 70 6c 75 67 69 6e  pect(this.plugin
3880: 2e 73 65 6e 64 54 72 61 6e 73 66 65 72 28 74 68  .sendTransfer(th
3890: 69 73 2e 74 72 61 6e 73 66 65 72 29 29 2e 74 6f  is.transfer)).to
38a0: 2e 65 76 65 6e 74 75 61 6c 6c 79 2e 62 65 2e 72  .eventually.be.r
38b0: 65 6a 65 63 74 65 64 0a 20 20 20 20 7d 29 0a 0a  ejected.    })..
38c0: 20 20 20 20 69 74 28 27 73 68 6f 75 6c 64 20 6e      it('should n
38d0: 6f 74 20 73 65 6e 64 20 61 20 74 72 61 6e 73 66  ot send a transf
38e0: 65 72 20 77 69 74 68 20 61 6e 20 69 6e 76 61 6c  er with an inval
38f0: 69 64 20 69 64 27 2c 20 66 75 6e 63 74 69 6f 6e  id id', function
3900: 20 28 29 20 7b 0a 20 20 20 20 20 20 74 68 69 73   () {.      this
3910: 2e 74 72 61 6e 73 66 65 72 2e 69 64 20 3d 20 36  .transfer.id = 6
3920: 36 36 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  66.      return 
3930: 65 78 70 65 63 74 28 74 68 69 73 2e 70 6c 75 67  expect(this.plug
3940: 69 6e 2e 73 65 6e 64 54 72 61 6e 73 66 65 72 28  in.sendTransfer(
3950: 74 68 69 73 2e 74 72 61 6e 73 66 65 72 29 29 2e  this.transfer)).
3960: 74 6f 2e 65 76 65 6e 74 75 61 6c 6c 79 2e 62 65  to.eventually.be
3970: 2e 72 65 6a 65 63 74 65 64 0a 20 20 20 20 7d 29  .rejected.    })
3980: 0a 0a 20 20 20 20 69 74 28 27 73 68 6f 75 6c 64  ..    it('should
3990: 20 6e 6f 74 20 73 65 6e 64 20 61 20 74 72 61 6e   not send a tran
39a0: 73 66 65 72 20 77 69 74 68 6f 75 74 20 74 6f 27  sfer without to'
39b0: 2c 20 66 75 6e 63 74 69 6f 6e 20 28 29 20 7b 0a  , function () {.
39c0: 20 20 20 20 20 20 64 65 6c 65 74 65 20 74 68 69        delete thi
39d0: 73 2e 74 72 61 6e 73 66 65 72 2e 74 6f 0a 20 20  s.transfer.to.  
39e0: 20 20 20 20 72 65 74 75 72 6e 20 65 78 70 65 63      return expec
39f0: 74 28 74 68 69 73 2e 70 6c 75 67 69 6e 2e 73 65  t(this.plugin.se
3a00: 6e 64 54 72 61 6e 73 66 65 72 28 74 68 69 73 2e  ndTransfer(this.
3a10: 74 72 61 6e 73 66 65 72 29 29 2e 74 6f 2e 65 76  transfer)).to.ev
3a20: 65 6e 74 75 61 6c 6c 79 2e 62 65 2e 72 65 6a 65  entually.be.reje
3a30: 63 74 65 64 0a 20 20 20 20 7d 29 0a 0a 20 20 20  cted.    })..   
3a40: 20 69 74 28 27 73 68 6f 75 6c 64 20 6e 6f 74 20   it('should not 
3a50: 73 65 6e 64 20 61 20 74 72 61 6e 73 66 65 72 20  send a transfer 
3a60: 77 69 74 68 20 61 6e 20 69 6e 76 61 6c 69 64 20  with an invalid 
3a70: 74 6f 27 2c 20 66 75 6e 63 74 69 6f 6e 20 28 29  to', function ()
3a80: 20 7b 0a 20 20 20 20 20 20 74 68 69 73 2e 74 72   {.      this.tr
3a90: 61 6e 73 66 65 72 2e 74 6f 20 3d 20 27 24 24 24  ansfer.to = '$$$
3aa0: 20 63 61 77 69 6f 6d 64 61 41 57 20 28 24 51 40   cawiomdaAW ($Q@
3ab0: 40 29 24 40 24 27 0a 20 20 20 20 20 20 72 65 74  @)$@$'.      ret
3ac0: 75 72 6e 20 65 78 70 65 63 74 28 74 68 69 73 2e  urn expect(this.
3ad0: 70 6c 75 67 69 6e 2e 73 65 6e 64 54 72 61 6e 73  plugin.sendTrans
3ae0: 66 65 72 28 74 68 69 73 2e 74 72 61 6e 73 66 65  fer(this.transfe
3af0: 72 29 29 2e 74 6f 2e 65 76 65 6e 74 75 61 6c 6c  r)).to.eventuall
3b00: 79 2e 62 65 2e 72 65 6a 65 63 74 65 64 0a 20 20  y.be.rejected.  
3b10: 20 20 7d 29 0a 0a 20 20 20 20 69 74 28 27 73 68    })..    it('sh
3b20: 6f 75 6c 64 20 6e 6f 74 20 73 65 6e 64 20 61 20  ould not send a 
3b30: 74 72 61 6e 73 66 65 72 20 77 69 74 68 20 61 20  transfer with a 
3b40: 6e 6f 6e 2d 73 74 72 69 6e 67 20 74 6f 27 2c 20  non-string to', 
3b50: 66 75 6e 63 74 69 6f 6e 20 28 29 20 7b 0a 20 20  function () {.  
3b60: 20 20 20 20 74 68 69 73 2e 74 72 61 6e 73 66 65      this.transfe
3b70: 72 2e 74 6f 20 3d 20 34 32 0a 20 20 20 20 20 20  r.to = 42.      
3b80: 72 65 74 75 72 6e 20 65 78 70 65 63 74 28 74 68  return expect(th
3b90: 69 73 2e 70 6c 75 67 69 6e 2e 73 65 6e 64 54 72  is.plugin.sendTr
3ba0: 61 6e 73 66 65 72 28 74 68 69 73 2e 74 72 61 6e  ansfer(this.tran
3bb0: 73 66 65 72 29 29 2e 74 6f 2e 65 76 65 6e 74 75  sfer)).to.eventu
3bc0: 61 6c 6c 79 2e 62 65 2e 72 65 6a 65 63 74 65 64  ally.be.rejected
3bd0: 0a 20 20 20 20 7d 29 0a 0a 20 20 20 20 69 74 28  .    })..    it(
3be0: 27 73 68 6f 75 6c 64 20 6e 6f 74 20 73 65 6e 64  'should not send
3bf0: 20 61 20 74 72 61 6e 73 66 65 72 20 77 69 74 68   a transfer with
3c00: 20 6e 6f 6e 2d 6f 62 6a 65 63 74 20 64 61 74 61   non-object data
3c10: 27 2c 20 66 75 6e 63 74 69 6f 6e 20 28 29 20 7b  ', function () {
3c20: 0a 20 20 20 20 20 20 74 68 69 73 2e 74 72 61 6e  .      this.tran
3c30: 73 66 65 72 2e 64 61 74 61 20 3d 20 39 30 30 30  sfer.data = 9000
3c40: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 65 78  .      return ex
3c50: 70 65 63 74 28 74 68 69 73 2e 70 6c 75 67 69 6e  pect(this.plugin
3c60: 2e 73 65 6e 64 54 72 61 6e 73 66 65 72 28 74 68  .sendTransfer(th
3c70: 69 73 2e 74 72 61 6e 73 66 65 72 29 29 2e 74 6f  is.transfer)).to
3c80: 2e 65 76 65 6e 74 75 61 6c 6c 79 2e 62 65 2e 72  .eventually.be.r
3c90: 65 6a 65 63 74 65 64 0a 20 20 20 20 7d 29 0a 0a  ejected.    })..
3ca0: 20 20 20 20 69 74 28 27 73 68 6f 75 6c 64 20 6e      it('should n
3cb0: 6f 74 20 73 65 6e 64 20 61 20 74 72 61 6e 73 66  ot send a transf
3cc0: 65 72 20 77 69 74 68 20 6e 6f 20 61 6d 6f 75 6e  er with no amoun
3cd0: 74 27 2c 20 66 75 6e 63 74 69 6f 6e 20 28 29 20  t', function () 
3ce0: 7b 0a 20 20 20 20 20 20 74 68 69 73 2e 74 72 61  {.      this.tra
3cf0: 6e 73 66 65 72 2e 61 6d 6f 75 6e 74 20 3d 20 75  nsfer.amount = u
3d00: 6e 64 65 66 69 6e 65 64 0a 20 20 20 20 20 20 72  ndefined.      r
3d10: 65 74 75 72 6e 20 65 78 70 65 63 74 28 74 68 69  eturn expect(thi
3d20: 73 2e 70 6c 75 67 69 6e 2e 73 65 6e 64 54 72 61  s.plugin.sendTra
3d30: 6e 73 66 65 72 28 74 68 69 73 2e 74 72 61 6e 73  nsfer(this.trans
3d40: 66 65 72 29 29 2e 74 6f 2e 65 76 65 6e 74 75 61  fer)).to.eventua
3d50: 6c 6c 79 2e 62 65 2e 72 65 6a 65 63 74 65 64 0a  lly.be.rejected.
3d60: 20 20 20 20 7d 29 0a 0a 20 20 20 20 69 74 28 27      })..    it('
3d70: 73 68 6f 75 6c 64 20 6e 6f 74 20 73 65 6e 64 20  should not send 
3d80: 61 20 74 72 61 6e 73 66 65 72 20 77 69 74 68 20  a transfer with 
3d90: 6e 6f 6e 2d 6e 75 6d 62 65 72 20 61 6d 6f 75 6e  non-number amoun
3da0: 74 27 2c 20 66 75 6e 63 74 69 6f 6e 20 28 29 20  t', function () 
3db0: 7b 0a 20 20 20 20 20 20 74 68 69 73 2e 74 72 61  {.      this.tra
3dc0: 6e 73 66 65 72 2e 61 6d 6f 75 6e 74 20 3d 20 27  nsfer.amount = '
3dd0: 62 6f 67 75 73 27 0a 20 20 20 20 20 20 72 65 74  bogus'.      ret
3de0: 75 72 6e 20 65 78 70 65 63 74 28 74 68 69 73 2e  urn expect(this.
3df0: 70 6c 75 67 69 6e 2e 73 65 6e 64 54 72 61 6e 73  plugin.sendTrans
3e00: 66 65 72 28 74 68 69 73 2e 74 72 61 6e 73 66 65  fer(this.transfe
3e10: 72 29 29 2e 74 6f 2e 65 76 65 6e 74 75 61 6c 6c  r)).to.eventuall
3e20: 79 2e 62 65 2e 72 65 6a 65 63 74 65 64 0a 20 20  y.be.rejected.  
3e30: 20 20 7d 29 0a 0a 20 20 20 20 69 74 28 27 73 68    })..    it('sh
3e40: 6f 75 6c 64 20 6e 6f 74 20 73 65 6e 64 20 61 20  ould not send a 
3e50: 74 72 61 6e 73 66 65 72 20 77 69 74 68 20 61 6d  transfer with am
3e60: 6f 75 6e 74 20 6f 76 65 72 20 6c 69 6d 69 74 27  ount over limit'
3e70: 2c 20 66 75 6e 63 74 69 6f 6e 20 28 29 20 7b 0a  , function () {.
3e80: 20 20 20 20 20 20 74 68 69 73 2e 74 72 61 6e 73        this.trans
3e90: 66 65 72 2e 61 6d 6f 75 6e 74 20 3d 20 27 35 30  fer.amount = '50
3ea0: 2e 30 27 0a 20 20 20 20 20 20 72 65 74 75 72 6e  .0'.      return
3eb0: 20 65 78 70 65 63 74 28 74 68 69 73 2e 70 6c 75   expect(this.plu
3ec0: 67 69 6e 2e 73 65 6e 64 54 72 61 6e 73 66 65 72  gin.sendTransfer
3ed0: 28 74 68 69 73 2e 74 72 61 6e 73 66 65 72 29 29  (this.transfer))
3ee0: 2e 74 6f 2e 65 76 65 6e 74 75 61 6c 6c 79 2e 62  .to.eventually.b
3ef0: 65 2e 72 65 6a 65 63 74 65 64 0a 20 20 20 20 7d  e.rejected.    }
3f00: 29 0a 0a 20 20 20 20 69 74 28 27 73 68 6f 75 6c  )..    it('shoul
3f10: 64 20 6e 6f 74 20 73 65 6e 64 20 61 20 74 72 61  d not send a tra
3f20: 6e 73 66 65 72 20 77 69 74 68 20 6e 65 67 61 74  nsfer with negat
3f30: 69 76 65 20 61 6d 6f 75 6e 74 27 2c 20 66 75 6e  ive amount', fun
3f40: 63 74 69 6f 6e 20 28 29 20 7b 0a 20 20 20 20 20  ction () {.     
3f50: 20 74 68 69 73 2e 74 72 61 6e 73 66 65 72 2e 61   this.transfer.a
3f60: 6d 6f 75 6e 74 20 3d 20 27 2d 35 2e 30 27 0a 20  mount = '-5.0'. 
3f70: 20 20 20 20 20 72 65 74 75 72 6e 20 65 78 70 65       return expe
3f80: 63 74 28 74 68 69 73 2e 70 6c 75 67 69 6e 2e 73  ct(this.plugin.s
3f90: 65 6e 64 54 72 61 6e 73 66 65 72 28 74 68 69 73  endTransfer(this
3fa0: 2e 74 72 61 6e 73 66 65 72 29 29 2e 74 6f 2e 65  .transfer)).to.e
3fb0: 76 65 6e 74 75 61 6c 6c 79 2e 62 65 2e 72 65 6a  ventually.be.rej
3fc0: 65 63 74 65 64 0a 20 20 20 20 7d 29 0a 20 20 7d  ected.    }).  }
3fd0: 29 0a 7d 29 0a                                   ).}).