Giter Club home page Giter Club logo

ilp-connector's Introduction

Interledger.js Monorepo

status codecov

Packages

Payments

Name Version Description
@interledger/pay NPM Package Send payments over Interledger using STREAM
@interledger/stream-receiver NPM Package Simple & composable stateless STREAM receiver

Utilities

Name Version Description
ilp-logger NPM Package Debug logging utility for Interledger modules
ilp-packet NPM Package Serialization/deserialization utility for ILP packets
ilp-plugin NPM Package Connect to a local, open BTP server
ilp-plugin-btp NPM Package One plugin to rule them all
ilp-protocol-ccp NPM Package Serialization/deserialization for the CCP routing protocol
ilp-protocol-ildcp NPM Package Fetch asset and account details from a parent
ilp-protocol-stream NPM Package Reliably send streams of money and data over ILP
oer-utils NPM Package Tools for OER parsing and serialization

Installation

The monorepo is set up to use lerna and pnpm workspaces. To get started run the following:

  1. pnpm install - pnpm will install the dependencies and do the necessary linking (no need to run lerna bootstrap).
  2. pnpm build
  3. pnpm test - This will run the tests in all the packages.

Running script commands

Script commands such as test and lint can be run from the root of the project by running:

# Run tests for all packages
pnpm test

# Run tests for a specific module a package
pnpm test --scope=<package-name>

Or in the package directory:

pnpm test

If you are interested in contributing, please read the contributing guidelines.

For Maintainers

Versioning

Independent versioning is used for this project and releases can only be made from master. You will need to set the GH_TOKEN env variable to your personal GitHub access token. Please make sure that you are up to date with master and that the tests and linting pass. Then use the following to create a release:

# On master
GH_TOKEN=<github-token> lerna version --conventional-commits --create-release github

and follow the command prompts. This will commit the package version changes and create the necessary tags - all of which will be pushed to master. It will also create changelogs and official GitHub releases.

If you want to release an alpha then run

# On master
GH_TOKEN=<github-token> lerna version --conventional-commits --conventional-prerelease --create-release github

This will append -alpha.<alpha-version> to the release name. The alpha release can be graduated (1.0.1-alpha.1 => 1.0.1) by running:

# On master
GH_TOKEN=<github-token> lerna version --conventional-commits --conventional-graduate --create-release github

Adding new packages

All source code is expected to be TypeScript and is placed in the src folder. Tests are put in the test folder. The NPM package will not contain any TypeScript files (*.ts) but will have typings and source maps. A typical project should have the following structure:

|-- src
|-- test
|-- package.json
|-- tsconfig.build.json

The tsconfig.build.json file should have the following

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "composite": true,
    "baseUrl": ".",
    "rootDir": "src",
    "outDir": "dist",
    "tsBuildInfoFile": "./dist/tsconfig.build.tsbuildinfo"
  },
  "include": [
    "src"
  ]
}

The package.json file should specify the following

{
  "name": "<package-name>",
  "license": "Apache-2.0",
  "publishConfig": {
    "access": "public"
  }
}

In the scripts section of the package.json, be sure to have build, cover (which runs tests with coverage) and codecov. These will be called from the CI pipeline. Please use the following as a guideline:

"scripts": {
  "build": "tsc -p tsconfig.build.json",
  "cover": "...",
  "codecov": "curl -s https://codecov.io/bash | bash -s - -s coverage -F <flagname>"
}

The cover script should run the tests with code coverage and output the coverage results in a format that can be uploaded to codecov. The flagname will be used by codecov to track coverage per package. Please make sure it matches the regex ^[a-z0-9_]{1,45}$.

Importing legacy modules

This process preserves the commit history of the legacy modules.

git clone [email protected]:adrianhopebailie/interledgerjs.git
git clone [email protected]:interledgerjs/legacy-module.git
cd legacy-module
git pull
cd ../interledgerjs
lerna import ../legacy-module --dest=packages --preserve-commit --flatten

You then need to replace the tsconfig.json file with the tsconfig.build.json and update the package.json as described above.

Dependencies

We keep devDependencies that are shared across all packages in the root package.json file. Dependencies can be added to individual packages using Lerna

lerna add <package to install> --scope=<package-name>

# Add dev dependency
lerna add <package to install> --scope=<package-name> --dev

Running script commands

Script commands such as test and lint can be run from the root of the project by running

# All tests in all packages
lerna run test

#Scoping to a package
lerna run test --scope=<package-name>

ilp-connector's People

Contributors

adrianhopebailie avatar alandotcom avatar alexlakatos avatar clark800 avatar emschwartz avatar gip avatar justmoon avatar justmoon-admin avatar kincaidoneil avatar kruisdraad avatar martinlowinski avatar matthewphinney avatar michielbdejong avatar naoitoi avatar njlie avatar roblav96 avatar sappenin avatar sentientwaffle avatar tangjeff0 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ilp-connector's Issues

Add ability to add connectors through configuration

The getConnectors method on the ledger plugin should be viewed as an automatic configuration (similar to getPrefix) and connectors should be able to override it via their configuration.

We should assume that most connectors will pass in a list of connectors via the config and using getConnectors should be the exception (although still supported.)

Proposed config

# Provide a basic list of peers
CONNECTOR_PEERS=https://connie.ilpdemo.org,https://fred.example.com # default = ''

# Whether to automatically populate the list of peers by calling getConnectors
# on all ledger plugins
CONNECTOR_AUTOLOAD_PEERS=true # default = false

Connector should work even if started before the ledger

As discussed in interledger-deprecated/ilp-kit#59, the connector should not cause problems even if one or more of its ledgers is offline when it starts up. The connector should keep trying to connect to the ledger that's down (or hasn't started), and only offer to facilitate payments once it has successfully connected. It should also stop facilitating payments if it is temporarily disconnected from a ledger.

Support GET /payments/:id

Connectors should store the details of payments they've facilitated and allow clients to query them

Set Interledger network up

@emschwartz
Hi Evan,
I would like to connect 2 private ledgers. Interledger seems very suitable for that. I've run five-bells-demo and looked into the code. However, I still have misunderstanding. You use js-ilp-plugin-bells and five-bells-connector. Unfortunately, I didn't find unified connector implementation (only for five-bells demo). To achieve my plans I need my own plugin and unified connector as well, isn't it?

Regarding plugin: I know you already have some different plugins, cool. What kind of plugins do you plan to implement and when?

Connector should (re-)broadcast scale and precision along with routes.

Prerequisite for #269. Please see that ticket for more context / motivation.

This should be implemented in a backwards-compatible way, meaning if a connector does not receive scale and precision information from another connector it should behave as it does now. It MUST always broadcast scale and precision for any ledger that it is the final destination for. For any other destination, it will forward the scale and precision information (or lack thereof) that it received.

Retry ledger requests

If connectors receive 500 or other errors from the ledgers while putting transfers they should retry sending them. This is extremely important on the execution side in Universal mode, because if they don't retry they will lose money when transfers time out

Allow authenticating with ledgers using a key

The connector should have a default key and the ability to pass in a specific key per ledger via CONNECTOR_CREDENTIALS. If an account is set up to use the default key, that ledger does not need to appear in CONNECTOR_CREDENTIALS at all.

Use multiledger abstraction for all ledger interactions

The connector should be able to interface with multiple different kinds of ledgers. The connector has the multiledger abstraction, but there are a number of places (e.g. balanceCache, testPaymentExpiry) where other parts of the code assume the connector is dealing with only five-bells-ledgers. All of the functionality necessary for interacting with the ledgers should be moved into the multiledger abstraction and all other parts of the code should use that abstraction layer.

The config will also need to be changed so that the ledger-related options specify which type of ledger they are for.

Quoting: Option to generate complete payment objects

Even though source_account and destination_account are not currently needed, it would be nice to be able to provide them, such that the /quote endpoint can generate a complete, ready-to-use payment object.

Connector should not broadcast routes to itself

Dec 02 02:47:01 ip-10-0-4-69.us-west-2.compute.internal five-bells-wallet[26819]: [ledger] 2016-12-02T02:47:01.606Z ledger:messages debug connie -> connie: { method: 'broadcast_routes', data: [ { source_ledger: 'us.usd.red.', destination_ledger: 'de.eur.blue.', points: [Object], min_message_window: 2, source_account: 'us.usd.red.connie' }, { source_ledger: 'us.usd.red.', destination_ledger: 'peer.3iTvp.usd.', points: [Object], min_message_window: 1, source_account: 'us.usd.red.connie' } ] }

Rename "Currency Pairs" to "Asset Pairs"

Since ILP is intended to be able to support more than just currency exchange, we should rename the "thing" in the connector currently called "currency" to be "asset".

Looking at the code, It appears that the connector endpoint is already called "/pairs" and uses the term "asset" in its property values, so perhaps this is just a documentation change for this page?

Make Optimistic mode work again

In "optimistic" mode, the sender sends a payment with no condition. It is completely up to the connectors to pass on the payment. Honest connectors should.

This used to work in the connector but now it returns a UnacceptableExpiryError: Destination transfers with execution conditions must have an expires_at field for connector to agree to authorize them. This is because the validateExpiry function assumes that if the payment is a Universal mode payment if it is not an Atomic mode payment. Here it checks the expiry, but it should not be a problem if there is no expiry set and there is no condition set.

Error: Prefix has not been set

When you have a single bells plugin and no pairs, the connector prints an error on startup.

Steps to reproduce

  • Set up a connector with a single ilp-plugin-bells, e.g.

    CONNECTOR_LEDGERS={"ilpdemo.red.":{"currency":"USD","plugin":"ilp-plugin-bells","options":{"account":"https://red.ilpdemo.org/ledger/accounts/alice","password":"alice"}}}
    
  • Make sure no pairs are configured

Expected behavior

The connector starts up and simply doesn't trade (since it has no pairs.)

It prints a warning that it has been configured with zero pairs and won't do any trading.

Actual behavior

The connector throws a cryptic exception:

[connector] 2016-11-30T18:30:15.255Z connector:app error Error: Prefix has not been set
[connector]     at FiveBellsLedger.getPrefix (/opt/ilp-kit/node_modules/ilp-plugin-bells/src/lib/plugin.js:325:29)
[connector]     at RouteBroadcaster._crawlClient (/opt/ilp-kit/node_modules/ilp-connector/src/lib/route-broadcaster.js:100:45)
[connector]     at next (native)
[connector]     at onFulfilled (/opt/ilp-kit/node_modules/co/index.js:65:19)
[connector]     at /opt/ilp-kit/node_modules/co/index.js:54:5
[connector]     at Promise._execute (/opt/ilp-kit/node_modules/bluebird/js/release/debuggability.js:299:9)
[connector]     at Promise._resolveFromExecutor (/opt/ilp-kit/node_modules/bluebird/js/release/promise.js:481:18)
[connector]     at new Promise (/opt/ilp-kit/node_modules/bluebird/js/release/promise.js:77:14)
[connector]     at co (/opt/ilp-kit/node_modules/co/index.js:50:10)
[connector]     at toPromise (/opt/ilp-kit/node_modules/co/index.js:118:63)
[connector]     at Array.map (native)
[connector]     at arrayToPromise (/opt/ilp-kit/node_modules/co/index.js:154:26)
[connector]     at toPromise (/opt/ilp-kit/node_modules/co/index.js:120:49)
[connector]     at next (/opt/ilp-kit/node_modules/co/index.js:99:29)
[connector]     at onFulfilled (/opt/ilp-kit/node_modules/co/index.js:69:7)
[connector]     at /opt/ilp-kit/node_modules/co/index.js:54:5
[connector] npm run start-prod-connector exited with code 0

What's happening?

@sharafian and I already did some debugging and what is happening here is that the pairs initialization is what actually calls connect on the various plugins. If there are no pairs, the plugins don't get initialized, so when we reach RouteBroadcaster#start, the plugins aren't connected. Since RouteBroadcaster calls getPrefix, we get the above error.

Connector should be able to round destination amount

Based on how our current iterations of the routing and quoting protocols, we should be able to let connector round destination amounts to the correct precision when quoting. There are several cases to handle:

1. Destination is local

The connector can get the precision from the local destination metadata.

It will also attach precision and scale information when broadcasting local routes.

2. Destination is not local but is included in routing table

In this case, the routing table will contain the correct precision and scale and therefore allows the connector to round correctly.

When rebroadcasting incoming routes, the connector will forward the precision and scale information.

3. Destination is not local and not included in routing table, but a prefix route exists

When quoting for a prefix route (a route that aggregates multiple destination ledgers via a single prefix), the connector will recursively call the next connector in the chain for a quote.

4. Destination is not local and not included in routing table and no prefix route exists

In this case, the connector will return an AssetsNotTradedError when quoting.

5. Destination uses a Tail Routing Table (TRT)

We don't yet support the Tail Routing Table (TRT) feature, but assume that this will be added in the future. The way rounding works with a TRT is that the TRT must contain the scale and precision information for the final destination ledger. However, it does not need to contain precision and scale for any other ledgers in the tail.

Duplicate Code

Most of the bottom of both src/backends/one-to-one.js and src/backends/fixerio/index.js are identical.

Schema Quote.json is not loaded

While updating the unit tests to work with five-bells-shared/pull/169, I found a rather odd bug related to tv4: When the function validate(schemaId, json) is called, json is successfully validated even if schemaId was not added before. The expected behavior would be that function validates throws an error along the lines unknown schemaId, but it does not.

Since the new validator introduced with five-bells-shared/pull/169 throws an error message as expected, this test case fails. The reason for the failure is that the schema Quote.json is not added. Quote.json is in ilp-connector/schemas, but services/validate.js loads the schemas from five-bells-shared/schemas and, thus, does not load Quote.json.

Simply copying the schemas from ilp-connector/schemas to five-bells-shared/schemas does not solve it.

On a side note: Does the current connector implementation validates quote request based on the schema? Does not look like, or I might have missed the code.

Automatically determine *_ledger from *_account

If a user provides source_account and/or destination_account in a /quote request, the connector should automatically determine the corresponding {source|destination}_ledger value.

Ideally without string manipulating any URIs. ;)

Document BACKEND env var & load backends like plugins

Instead of loading the backend from a local folder, the connector should treat backends the same way it treats ledger plugins and require the name that's given so you can more easily use a custom one.

We should also document the API expected from a backend, and document the environment variables for setting it up.

SonarQube errors in ilp-connector code

SonarQube shows 28 errors in the ilp connector code

Most of these (25) are places where there should be a yield" statement added to the generator

Example code missing a yield in src/backends/fixerio/index.js, 63
/**

  • Get backend status
    */
  • getStatus () {
    return {
    backendStatus: healthStatus.statusOk
    }
    }
    "A generator without a yield statement is at best confusing, and at worst a bug in your code, since the iterator produced by your code will always be empty."

Here are the other places where this occurs:
src/backends/fixerio/index.js
Line 63
Line 93
Line 143

src/backends/ilp-quoter/index.js
Line 66

src/backends/one-to-one.js
Line 28
Line 34
Line 48
Line 91

src/errors/assets-not-traded-error.js
Line 8

src/errors/external-error.js
Line 7

src/errors/invalid-amount-specified-error.js
Line 7

src/errors/no-amount-specified-error.js
Line 7

src/errors/no-related-destination-debit-error.js
Line 8

src/errors/no-related-source-credit-error.js
Line 8

src/errors/unacceptable-amount-error.js
Line 7

src/errors/unacceptable-conditions-error.js
Line 8

src/errors/unacceptable-expiry-error.js
Line 8

src/errors/unacceptable-quoter-amount-error.js
Line 7

src/errors/unacceptable-rate-error.js
Line 8

src/errors/unrelated-notification-error.js
Line 8

src/errors/unsupported-pair-error.js
Line 8

src/models/quote.js
Line 6
Line 24

src/models/subscriptions.js
Line 8

src/lib/message-router.js
Line 108

In addition, there are a few other issues:

src/lib/config.js
Remove this useless assignment to local variable "ledgerCredentials"
Line 206

src/lib/message-router.js
Change this condition so that it does not always evaluate to "true".
Line 162

src/backends/ilp-quoter/index.js
Change this condition so that it does not always evaluate to "true".
Line 60

Connector should verify notification from Ledger

This issue is a follow up to #94

To fix RILP-254,
(1) Connector should not trust any transfer (e.g. the ones from Sender). It should only trust the notification from Ledger.
(2) Connector should verify the notification from Ledger, e.g., via digital signature.

Issue 94 fixes (1).
This new issue is for (2).

Don't round down when not necessary

Here's the feedback I got

I've set CONNECTOR_FX_SPREAD=0 CONNECTOR_SLIPPAGE=0.

When I transfer £10 from wallet a to wallet b, £10 is sent from a but only £9.99 is received by wallet b. Is there another parameter to change that could account for the £0.01 lost or is this a rounding error?

Connector should recognize local transfers

If you request a quote from a connector from one account to another on the same ledger, right now the connector won't recognize that there is a direct path and it will give you a path from ledger A -> B -> A instead. The connector should (take pity on you and) return a simple transfer object with no nested transfers (and probably no fee)

Don't expire other connectors' routes

As far as I can tell, all connectors effectively need to have the same route broadcast interval and expiration time. If a connector has rates that don't change very often, they might not want to waste the effort rebroadcasting the same data over and over again. However, right now the other connectors would expire the routes. This may even create an incentive to have a lower than average time in case there are some connectors with lower times.

Routes should probably carry something like cache control headers so you know how long another connectors' routes are valid for, rather than expiring everything on your own interval.

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.