GithubHelp home page GithubHelp logo

interledgerjs / ilp Goto Github PK

View Code? Open in Web Editor NEW
128.0 22.0 22.0 750 KB

ILP client for browsers/Node.js

License: Other

JavaScript 8.65% TypeScript 91.35%
interledger ipr payment-request psk spsp ilp

ilp's Introduction


ILP

The Javascript client library for Interledger


npm standard circle codecov snyk

The ILP module includes:

  • Simple Payment Setup Protocol (SPSP), a higher level interface for sending ILP payments, which requires the receiver to have an SPSP server.
  • Interledger Dynamic Configuration Protocol (ILDCP), a protocol for exchanging configuration between nodes.
  • STREAM, the recommended Transport Protocol to use for most Interledger applications.
  • createLogger, a function to create a name spaced logger.
  • createMiddleware, a function to create server middleware for an SPSP receiver.
  • createPlugin, a function to get an ILP plugin from the environment or testnet.
  • receive, a function to create an invoice representing a handle to a STREAM server waiting to receive a specific amount.
  • pay, a function to make a STREAM payment to either a Payment Pointer or an ILP Address using appropriate shared secret.

Installation

npm install --save ilp

Note that ilp plugins must be installed alongside this module unless you simply use BTP

Create Plugin

Using ilp.createPlugin is an alias for the deprecated ilp-plugin module. It creates an instance of a BTP plugin that will attempt to connect to a local moneyd instance by default. This can be overridden using environment variables.

The module looks for ILP_PLUGIN_OPTIONS (or ILP_CREDENTIALS however this is deprecated) and ILP_PLUGIN. ILP_PLUGIN_OPTIONS must contain a JSON object and will be passed into the constructor of a new plugin instance. The name of the plugin type to instantiate must be stored as a string in the environment variable ILP_PLUGIN or it will default to ilp-plugin-btp.

By default (i.e. ILP_PLUGIN_OPTIONS and ILP_PLUGIN are not set), a random secret will be generated and a new instance of ilp-plugin-btp will be configured to connect to btp+ws://localhost:7768.

If you are sending to an SPSPv4 receiver using a Payment Pointer, the SPSP module provides a high-level interface to pay and query the server:

'use strict'

const ilp = require('ilp')

;(async function () {
  await ilp.SPSP.pay(ilp.createPlugin(), {
    receiver: '$bob.example.com',
    sourceAmount: '1000'
  })
})()

ilp.SPSP replaces the deprecated ilp-protocol-spsp module and no longer supports payments to servers using PSK2. Only responses from an SPSP server with the content-type of application/spsp4+json are accepted.

Create Middleware

The ilp module provides conveniences functions to create server middleware that can be used to host an SPSP endpoint for receiving payments.

Express example:

 const ilp = require('ilp')
 const app = require('express')()

 ;(async () => {
  const spsp = await ilp.express.createMiddleware({receiver_info:{name: 'Bob Smith'}})
  app.get('/.well-known/pay', spsp)
  app.listen(3000)
 })()

KOA and HAPI support to come...

The ILDCP module allows clients to get their configured address, asset and scale from an upstream parent connector.

'use strict'

const ilp = require('ilp')

;(async function () {
  const plugin = ilp.createPlugin()
  await plugin.connect()
  const { clientAddress, assetScale, assetCode } = await ilp.ILDCP.fetch(plugin.sendData.bind(plugin))
  console.log(`Plugin connected and configured with address ${clientAddress} using asset ${assetCode} and scale ${assetScale}`)
})()

The STREAM module provides an API to use the STREAM protocol to send and receive payments. STREAM is the recommended transport protocol for use with ILP.

The ilp module provides two abstractions over this module that make it simple to send and receive payments.

Receive

receive creates an instance of a STREAM server wrapped around a given plugin (or calls createPlugin if none is provided). It returns an Invoice object which has an address and secret that can be shared with a sender, and a receivePayment() method to wait for the incoming payment.

Pay

pay will either pay a valid SPSP receiver or an ILP address (assuming there is a STREAM server waiting for connections at that address).

To pay using an SPSP receiver, pass the payment pointer as the payee in the form of a string:

'use strict'

const ilp = require('ilp')

;(async function () {
  await ilp.pay(100, '$bob.example.com')
})()

To pay using a given ILP Address and shared secret pass these in as an object:

'use strict'

const ilp = require('ilp')

;(async function () {
  await ilp.pay(100, { destinationAccount: 'g.bob.1234', sharedSecret: Buffer.from('******', 'base64') })
})()

Examples are provided in example.js.

ilp's People

Contributors

adrianhopebailie avatar emschwartz avatar justmoon avatar michielbdejong avatar sentientwaffle avatar vhpoet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ilp's Issues

Add SPSP client

Currently, the ilp module implements IPR, but not SPSP.

Part of the reason was that the server-side of SPSP is very simple and there are many server-side frameworks, so you'd end up with a module that doesn't do very much and needs tons of glue for different use cases.

However, the story is different for the client side. There is a bit more logic involved and the flows are more standardized. (While a server might be only a merchant or only a payee, clients have to handle all SPSP responses pretty much the same way.)

So I think we should have a module that implements SPSP client-side functionality. Question is whether this should be in ilp or in a separate module spsp. (Leaning towards the latter, but input is welcome.)

Fix support for node 6.2

Just placeholder basically.
I don't have solution for #90 and no time to work on it this week, so creating this issue as a replacement.

Add support for Loopback Transport

For the Loopback Transport, I was thinking of adding something like:

const PluginBtp = require('ilp-plugin-btp')

ilp.createLoop = async (serverAddress) => {
  const loopbackClient = new PluginBtp(serverAddress)
  await loopbackClient.connect()
  // ...
}

const loop = await ilp.createLoop(serverAddress)
loop.pay({ sourceAmount, minDestinationAmount, expiresAt })
loop.payChunked({ destinationAmount, deadline })
loop.setStreamRate({ destinationRate })

We could also try to make the interfaces for loops the same as the proposed interface for streams (.chargeUpTo etc).

Or we could expose a slightly lower interface than what's currently described in interledger/rfcs#413, and expose the accept/reject decision to the application layer:

const loop = await ilp.createLoop(serverAddress)
const loopbackHandler = (ilpPacket) => (ilpPacket.amount >= minDestinationAmount)
loop.pay({ sourceAmount, expiresAt, loopbackHandler)

Round request amounts to ledger precision

As mentioned here, requiring exact amounts on the incoming transfer could create unfulfillable requests if the request precision is higher than supported by the ledger. The client should round request amounts or return an error if the number is too precise for the ledger.

Payment sequence

@emschwartz
Hi Evan,

Could you help me, please. I have a look into the sample of ilp client and notice that receiver create a request to the sender before payment, isn't it? Why do you use this scheme? Is it means that if I would like to make a payment I have to notify receiver before and ask him to generate request?

empty sourceExpiryDuration

Trying to get a quote for a local payment

ILP.SPSP.quote(plugin, { receiver: '[email protected], sourceAmount: 3 })

returns an SpspPayment with an empty sourceExpiryDuration. Passing this SpspPayment to sendPayment throws an exception AssertionError: missing sourceExpiryDuration

SpspPayment

{
  id: '9db0ee76-9e1a-4ce9-a85c-3d197f6789e6',
  sourceAmount: '3',
  destinationAmount: '3',
  destinationAccount: 'wallet1.username',
  connectorAccount: 'wallet1.username',
  sourceExpiryDuration: undefined,
  spsp: {
    destination_account: 'wallet1.username',
    shared_secret: 'iwVMVRGKEjXg73pCSGFifQ',
    maximum_destination_amount: '100000000000',
    minimum_destination_amount: '0.001',
    ledger_info: {
      currency_code: 'USD',
      currency_symbol: '$',
      precision: 10,
      scale: 2
    },
    receiver_info: {
      
    }
  }
}

Make PSKv1 receivers work with a single function call

This is how you currently create a PSKv1 receiver in this module:

const receiverSecret = Buffer.from('secret_seed')
const { sharedSecret, destinationAccount } = ILP.PSK.generateParams({
  destinationAccount: (await ILP.ILDCP.get(receiver)).address,
  receiverSecret
})

const stopListening = await ILP.PSK.listen(receiver, { receiverSecret }, (params) => {
  // ... review payment ...

  stopListening()
  return params.fulfill()
})

I.e. you first call ILP.PSK.generateParams and then call ILP.PSK.listen.

Proposal: Allow users to use only ILP.PSK.listen, like so:

const receiverSecret = Buffer.from('secret_seed')

const listener = await ILP.PSK.listen(receiver, { receiverSecret }, (params) => {
  // ... review payment ...

  listener.close()
  return params.fulfill()
})
const { sharedSecret, destinationAccount } = listener

Note that we can avoid an extra ILDCP call this way. generateParams would continue to exist as a method, but its use would be optional.

Invalid quoteQuery checking

Hi guys,

I investigate how to integrate Interledger with two private ledgers.

Previously you said that I can use ilp directly with five-bells-connector. Seems you have an error with quoteQuery params checking.

Have a look here:

connector-name 2016-08-24T13:25:23.356Z koa INFO <-- GET /quote?source_address=http%3A%2F%2Flocalhost%3A3001%2Filp_account&destination_address=http%3A%2F%2Flocalhost%3A3001%2Filp_account&destination_amount=50
connector-name 2016-08-24T13:25:23.362Z error-handler WARN Invalid URI parameter: Missing required parameter: source_ledger or source_account

connector-name 2016-08-24T13:26:27.834Z koa INFO <-- GET /quote?source_ledger=http%3A%2F%2Flocalhost%3A3001%2Filp_account&destination_address=http%3A%2F%2Flocalhost%3A3001%2Filp_account&destination_amount=50
connector-name 2016-08-24T13:26:27.840Z error-handler WARN Invalid URI parameter: Missing required parameter: destination_ledger or destination_account
`

To solve it you can either make changes here ilp-core->src->lib->client.js or modify five-bells-connectors

For client.js you can do:
const quoteQuery = {
source_ledger: (yield plugin.getAccount()),
...
destination_ledger: params.destinationAddress,
...
}

Refactor `ilp` module

(with @sharafian)

The ILP module should have the following exports:

  • SPSP - SPSP client (and server?)
  • ILQP - implements Interledger Quoting Protocol (refactored out of ilp-core)
  • IPR - implements the Interledger Payment Request (with this update)
  • PluginCommon - when we switch to the Common Ledger API, we should bundle that plugin with this module and use it by default (we might want to bundle ilp-plugin-bells in the meantime)
  • Packet? - it might be useful to bundle some helper functions for creating ILP packets, though this might not be necessary as long as we stick with a JSON packet

And it could export a couple of helper functions (from the root ilp) that bundle common steps using the aforementioned modules:

  • constructTransferFromSource - this would return a Transfer object with an ILP packet attached. If the account identifiers given are ILP addresses, it would just use ILQP for quoting and construct the transfer from there. If they are SPSP identifiers, it could detect that and use SPSP to resolve those to ILP addresses
  • constructTransferFromDestination - same as above but based on a fixed destination amount
  • constructTransferFromPacket - basically quoting a Payment Request
  • sendTransfer - the main difference between this and a plugin's sendTransfer function would be that this one would only resolve once it gets the fulfillment (as opposed to just when the transfer is accepted by the ledger)

As suggested by @sharafian, we can get rid of the unusual quote format from ilp-core and replace it with normal Transfer objects (that include ILP packets). If we want to provide easier access to fields like the destination amount that are nested in the ILP packet, we can add some extra helper functions for that.

Running Plug-in

Hi,
I'm new to this but I just wanted some help running this plug-in. I just downloaded/saved the zip file but I'm not sure where I'm supposed to run the code in the instructions or which file I am supposed to open. Please let me know if you have any guidance.

Thanks!

support ledgers with no connector

the code snippets in the readme seem to fail if you try them against a ledger that doesn't have a connector running on it (even if alice and bob are both at that ledger).

Add plain quote functionality

Originally this library was designed to focus only on the functionality needed to create and pay for payment requests.

In order to use this library for SPSP and any use case involving fixed source amount payments, we need a plain quote method.

process doesn't exit

Try out either of the code samples in the readme, you'll see the payment is successful, but the node process does not terminate afterwards.

Is that related to this todo?

workaround: after the console.log('sender result:', result) line, add process.exit(0).

wrong ilp addresses

Trying to get a quote for a local payment

ILP.SPSP.quote(plugin, { receiver: '[email protected], sourceAmount: 3 })

returns an SpspPayment with all of the ILP addresses set to wallet1.username. Not sure if this is an ILP issue.

SpspPayment

{
  id: '9db0ee76-9e1a-4ce9-a85c-3d197f6789e6',
  sourceAmount: '3',
  destinationAmount: '3',
  destinationAccount: 'wallet1.username',
  connectorAccount: 'wallet1.username',
  sourceExpiryDuration: undefined,
  spsp: {
    destination_account: 'wallet1.username',
    shared_secret: 'iwVMVRGKEjXg73pCSGFifQ',
    maximum_destination_amount: '100000000000',
    minimum_destination_amount: '0.001',
    ledger_info: {
      currency_code: 'USD',
      currency_symbol: '$',
      precision: 10,
      scale: 2
    },
    receiver_info: {
      
    }
  }
}

Webfinger lookup for [email protected]

{
  "subject": "acct:[email protected]",
  "links": [
    {
      "rel": "https://interledger.org/rel/ledgerUri",
      "href": "http://wallet1.com/ledger"
    },
    {
      "rel": "https://interledger.org/rel/socketIOUri",
      "href": "http://wallet1.com/api/socket.io"
    },
    {
      "rel": "https://interledger.org/rel/ilpAddress",
      "href": "wallet1.alice"
    },
    {
      "rel": "https://interledger.org/rel/sender/payment",
      "href": "http://wallet1.com/api/payments"
    },
    {
      "rel": "https://interledger.org/rel/sender/quote",
      "href": "http://wallet1.com/api/payments/quote"
    },
    {
      "rel": "https://interledger.org/rel/spsp/v2",
      "href": "http://wallet1.com/api/spsp/alice"
    }
  ]
}

Plugin instance

FiveBellsLedger{
  _events: {
    maxListeners: 10,
    '_rpc:notification': [
      Function
    ]
  },
  newListener: false,
  verboseMemoryLeak: false,
  configPrefix: undefined,
  account: 'http://wallet1.com/ledger/accounts/admin',
  username: 'admin',
  identifier: undefined,
  credentials: {
    username: 'admin',
    password: 'asdasd',
    account: 'http://wallet1.com/ledger/accounts/admin'
  },
  connector: null,
  debugReplyNotifications: false,
  rpcId: 1,
  connection: null,
  connecting: false,
  ready: true,
  connected: false,
  ws: null,
  disconnect: [
    Function
  ],
  connect: [
    Function
  ],
  isConnected: [
    Function
  ],
  ledgerContext: LedgerContext{
    host: 'http://wallet1.com/ledger',
    ledgerMetadata: {
      connectors: [
        Object
      ],
      currency_code: 'USD',
      currency_symbol: '$',
      ilp_prefix: 'wallet1.',
      condition_sign_public_key: 'fs2ey9+WKsPzNlqE+W7DJClJPdXDekP53PWDmhPJAaU=',
      urls: [
        Object
      ],
      precision: 10,
      scale: 2
    },
    urls: {
      transfer: 'http://wallet1.com/ledger/transfers/:id',
      transfer_fulfillment: 'http://wallet1.com/ledger/transfers/:id/fulfillment',
      transfer_rejection: 'http://wallet1.com/ledger/transfers/:id/rejection',
      account: 'http://wallet1.com/ledger/accounts/:name',
      auth_token: 'http://wallet1.com/ledger/auth_token',
      websocket: 'ws://wallet1.com/ledger/websocket',
      message: 'http://wallet1.com/ledger/messages'
    },
    prefix: 'wallet1.'
  }
}

Error: Got empty quote response from the connector

In UI, Sending from Blue Demo to Red Demo fails to get quote, but Red to Blue is okay for some reason).

At testing with sample code for sending...

request: { address: 'ilpdemo.blue.winthan.6d58cadf-816d-4d42-9337-1ad52e49085c',
  amount: '10',
  expires_at: '2016-12-16T10:37:46.961Z',
  condition: 'cc:0:3:8UbkYVu_IquZ6Skp9VjKabB6d_iE5ayeRFdB1KS4zPE:32' }
Error: Got empty quote response from the connector
    at client.connect.then.then.then (/Users/winthan/node/node_modules/ilp/src/lib/sender.js:115:17)

From sgd.interledger to usd.interledger ( Both connectors are having the peer public keys in connector ledgers for trust, and it broadcasts all time. But it is having as following quote issues.

request: { address: 'sg.sgd.interledger.winthan.3f2ccf06-f8ed-437f-b17e-e430431a92bc',
  amount: '10',
  expires_at: '2016-12-16T10:39:12.615Z',
  condition: 'cc:0:3:xz5KorW4n3f2F4eCSJZxJZXBTqiZnRtCc8nwqXvwUK0:32' }
Error: Got empty quote response from the connector
    at client.connect.then.then.then (/Users/winthan/node/node_modules/ilp/src/lib/sender.js:115:17)

Refactor API for latest suite of protocols

The ilp module should be updated for the latest suite of protocols. It should expose a reasonable API for ILP and PSK/Paystream.

Here is a sketch of what the new API might look like:

Basic Usage: PayStream

const ilp = require('ilp')

;(async () => {
  // Connect to a PayStream, defaults to using moneyd
  const socket = await ilp.createConnection([ilp address], [shared secret])

  // Lower the paystream maximum by 1000 (minimum will be lowered if necessary)
  await socket.pay('1000')
  // Lower the paystream minimum by 2000
  socket.payUpTo('2000')
  // Increase the paystream minimum by 4000 (maximum will be increased if necessary)
  await socket.charge('4000')
  // Increase the paystream maximum by 2000
  socket.chargeUpTo('2000')
  // Write some data
  socket.write(Buffer.alloc(128))
  await socket.flush()
  // Read data
  socket.on('data', (data) => {
    console.log(data.toString('utf8'))
  })
})()

Basic Usage: Raw packet

const ilp = require('ilp')

;(async () => {
  const { fulfillment, data } = await ilp.sendPacket({
    destination: 'test.bob',
    amount: '100',
    executionCondition: '...',
    expiresAt: '...',
    data: Buffer.alloc(0)
  })
})()

Advanced Usage: Using a custom plugin

const { create as createIlp } = require('ilp')
const CustomPlugin = require('ilp-plugin-custom')

;(async () => {
  const ilp = createIlp({
    plugin: new CustomPlugin({ /* ... */ })
  })

  // ... ready to use
})()

payRequest should be idempotent

It should use a deterministic transfer id based on the request address (which is unique per-request) and a sender secret. Ledger plugins are supposed to reject multiple transfers with the same id. The sender secret prevents an attacker who is able to observe the payment request from blocking the payment by squatting on transfer ids.

It should catch the RepeatError added in interledger/rfcs#94 and call getFulfillment to return the fulfillment instead of returning that error. This depends on interledger-deprecated/ilp-plugin-tests#5

It would probably be good to add a test for this to the integration tests

Current master not compatible with blue.ilpdemo.org

When you try to run the psk sample code from the readme against two accounts on blue.ilpdemo.org, it fails:

request: { address: 'de.eur.blue.jam.~psk.2ZQkTFtiMyM.Ox38P-XneFqfW8fUGJ_Upw.fe467539-e88f-4bcc-a109-286206d3efac',
  amount: '10',
  expires_at: '2017-03-15T13:44:36.870Z',
  condition: '5F7iWFAzXazcEqzDRRT2S2d2w4ZtdmY5AWhzKmTMmvw' }
paymentParams { sourceAmount: '10',
  connectorAccount: undefined,
  destinationAmount: '10',
  destinationAccount: 'de.eur.blue.jam.~psk.2ZQkTFtiMyM.Ox38P-XneFqfW8fUGJ_Upw.fe467539-e88f-4bcc-a109-286206d3efac',
  destinationMemo: { data: undefined, expires_at: '2017-03-15T13:44:36.870Z' },
  expiresAt: '2017-03-15T13:44:19.178Z',
  executionCondition: '5F7iWFAzXazcEqzDRRT2S2d2w4ZtdmY5AWhzKmTMmvw' }
{ InvalidFieldsError: Body did not match schema Transfer
    at InvalidFieldsError (/Users/michiel/gh/interledgerjs/ilp/node_modules/ilp-plugin-bells/src/errors/index.js:5:5)
    at FiveBellsLedger._sendTransfer (/Users/michiel/gh/interledgerjs/ilp/node_modules/ilp-plugin-bells/src/lib/plugin.js:526:49)
    at next (native)
    at onFulfilled (/Users/michiel/gh/interledgerjs/ilp/node_modules/co/index.js:65:19)
    at process._tickCallback (internal/process/next_tick.js:103:7) name: 'InvalidFieldsError' }

This is related to interledger-deprecated/ilp-plugin-bells#111

Allow specifying the account in createRequest

Right now it will use the account details from the ledger plugin for all requests. However, there are some (albeit rare) cases when we want to create a request on behalf of another account. This would largely happen in cases where there is an admin listener that is creating requests and fulfilling transfers on behalf of other users.

function naming `toLedgerUnits` vs `toCurrencyUnits`

I find the function names toInteger and toDecimal confusing. Whether an amount is in ledger units or in currency units doesn't define whether that amount is integer, nor whether it is represented in decimal. I propose to rename this functions to toLedgerUnits and toCurrencyUnits, respectively.

Also, in comments:

This is a decimal, NOT an integer. It will be shifted by the receiving ledger's scale to get the integer amount.

->

In currency units, NOT ledger units. It will be shifted by the receiving ledger's scale to get ledger units.

Type Error in express.ts

Description

I tried to install this ilp client using npm and then executed it in my Node.js project, but got an error:
node_modules/ilp/src/extensions/express.ts:44:48 - error TS2345: Argument of type 'string | ParsedQs | string[] | ParsedQs[]' is not assignable to parameter of type 'string'. Type 'ParsedQs' is not assignable to type 'string'.
It looks like the variable reference in express.ts can be some object types rather than string type.

Expected Behaviour

Execute successfully and correctly.

Environment

  • Node.js: v10.16.3
  • ilp: v14.1.0
  • Nest.js (the framework I use): v7.4.0
  • Windows 10, Visual Studio Code

Should not quietly swallow callback errors

If the ILP.PSK.listen callback throws, it seems like the ilp module just quietly eats the error by default.

We should think about ways to create a better developer experience.

Simpler constructor

Currently the example is:

const sender = ILP.createSender({
  _plugin: FiveBellsLedgerPlugin,
  prefix: 'ilpdemo.red.',
  account: 'https://red.ilpdemo.org/ledger/accounts/alice',
  password: 'alice'
})

Could that be just:

const sender = ILP.createSender({
  account: '[email protected]',
  password: 'alice'
})
  • Use the same identifier as SPSP
  • Detect prefix automatically
  • Assume Five Bells Ledger as the default (not sure if this is a good idea, weigh in please!)

better error for invalid quoteResponse

This is an exception I get on SPSP.quote. Would be good to indicate that the error message is about the response, not the params I supplied.

destination_account must be a string
  at validateSPSPResponse (/Users/vh/localhost/ilp-kit/node_modules/ilp/src/lib/spsp.js:51:3)
  at _querySPSP (/Users/vh/localhost/ilp-kit/node_modules/ilp/src/lib/spsp.js:45:3)
  at _querySPSP.next (<anonymous>)
  at onFulfilled (/Users/vh/localhost/ilp-kit/node_modules/co/index.js:65:19)
  at process._tickCallback (internal/process/next_tick.js:103:7)
name: 'AssertionError',
actual: false,
expected: true,
operator: '==',
message: 'destination_account must be a string',
generatedMessage: false }

Payment guards?

May be I am missing something, but the documentation does not seem to cover one important aspect:

  • what is preventing someone to call the pay method in a loop 10000 times to send money that does not exist?

Is the API going to check some balance / wallet before making the transfer? if So, where and how? The example code (copied below from the readme), does not seem to indicate any source wallet address

await ilp.pay(100, '$bob.example.com')

I understand this is just an API, but if the API does what it says (namely making the payment), the receiver would endup with that 100 amount irrespective of caller has it or not. Currently all banks use one or the other form of API, but they all are tied to some user account and need valid credentials - which does not seem to be the case in these ILP APIs.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.