Giter Site home page Giter Site logo

xpring-eng / xpring-js Goto Github PK

View Code? Open in Web Editor NEW
77.0 20.0 27.0 21.59 MB

Xpring-JS has been deprecated; please use xrpl.js instead.

Home Page: https://github.com/XRPLF/xrpl.js

License: MIT License

TypeScript 98.60% Shell 0.60% JavaScript 0.80%
xpring-js xrp xrp-ledger ilp interledger javascript sdk xpring interledger-protocol ripple

xpring-js's Introduction

This project has been deprecated; instead, use: xrpl.js

Xpring-JS was the JavaScript client side library of the Xpring SDK.

Features

Xpring-JS provides the following features:

  • XRP:
    • Wallet generation and derivation (Seed-based or HD Wallet-based)
    • Address validation
    • Account balance retrieval
    • Sending XRP payments
    • Retrieval of payment transactions and account payment history
    • Enabling of Deposit Authorization for an XRPL account
  • Interledger (ILP):
    • Account balance retrieval
    • Send ILP Payments

Installation

Client Side Library

Xpring-JS is available as an NPM package. Simply install with:

$ npm i xpring-js

Xpring-JS can be used on the web with webpack, as it uses some Node modules. The sample webpack.config.js can be used as a starting point for web applications.

rippled Node

Xpring SDK needs to communicate with a rippled node which has gRPC enabled. Consult the rippled documentation for details on how to build your own node.

To get developers started right away, Xpring currently provides nodes.

If you are using Xpring-JS in a node environment, use the following addresses to bootstrap your application:

# Testnet
test.xrp.xpring.io:50051

# Mainnet
main.xrp.xpring.io:50051

If you are using Xpring-JS from within a browser, use the following addresses to bootstrap your application:

# Testnet
https://envoy.test.xrp.xpring.io

# Mainnet
https://envoy.main.xrp.xpring.io

Hermes Node

Xpring SDK's IlpClient needs to communicate with Xpring's ILP infrastructure through an instance of Hermes.

In order to connect to the Hermes instance that Xpring currently operates, you will need to create an ILP wallet here

Once your wallet has been created, you can use the gRPC URL specified in your wallet, as well as your access token to check your balance and send payments over ILP.

Usage: XRP

Note: Xpring SDK only works with the X-Address format. For more information about this format, see the Utilities section and http://xrpaddress.info.

Wallets

A wallet is a fundamental model object in XpringKit which provides key management, address derivation, and signing functionality. Wallets can be derived from either a seed or a mnemonic and derivation path. You can also choose to generate a new random HD wallet.

Wallet Derivation

Xpring-JS can derive a wallet from a seed or it can derive a hierarchical deterministic wallet (HDWallet) from a mnemonic and derivation path.

Hierarchical Deterministic Wallets

A hierarchical deterministic wallet is created using a mnemonic and a derivation path. Simply pass the mnemonic and derivation path to the wallet generation function. Note that you can omit the derivation path and have a default path be used instead.

const { Wallet } = require('xpring-js')

const mnemonic =
  'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'

const hdWallet1 = Wallet.generateWalletFromMnemonic(mnemonic) // Has default derivation path
const hdWallet2 = Wallet.generateWalletFromMnemonic(
  mnemonic,
  Wallet.getDefaultDerivationPath(),
) // Same as hdWallet1

const hdWallet = Wallet.generateWalletFromMnemonic(
  mnemonic,
  "m/44'/144'/0'/0/1",
) // Wallet with custom derivation path.
Seed Based Wallets

You can construct a seed based wallet by passing a base58check encoded seed string.

const { Wallet } = require('xpring-js')

const seedWallet = Wallet.generateWalletFromSeed(
  'snRiAJGeKCkPVddbjB3zRwiYDBm1M',
)

Wallet Generation

Xpring-JS can generate a new and random HD Wallet. The result of a wallet generation call is a tuple which contains the following:

  • A randomly generated mnemonic
  • The derivation path used, which is the default path
  • A reference to the new wallet
const { WalletFactory, XrplNetwork } = require('xpring-js')

// Generate a random wallet.
const walletFactory = new WalletFactory(XrplNetwork.Test)
const generationResult = await walletFactory.generateRandomWallet()!
const newWallet = generationResult.wallet

// Wallet can be recreated with the artifacts of the initial generation.
const copyOfNewWallet = Wallet.generateWalletFromMnemonic(
  generationResult.mnemonic,
  generationResult.derivationPath,
)

Wallet Properties

A generated wallet can provide its public key, private key, and address on the XRP ledger.

const { WalletFactory, XrplNetwork } = require('xpring-js')

const mnemonic =
  'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'

const walletFactory = new WalletFactory(XrplNetwork.Test)
const wallet = await walletFactory.generateRandomHdWallet(mnemonic)!

console.log(wallet.getAddress()) // XVMFQQBMhdouRqhPMuawgBMN1AVFTofPAdRsXG5RkPtUPNQ
console.log(wallet.getPublicKey()) // 031D68BC1A142E6766B2BDFB006CCFE135EF2E0E2E94ABB5CF5C9AB6104776FBAE
console.log(wallet.getPrivateKey()) // 0090802A50AA84EFB6CDB225F17C27616EA94048C179142FECF03F4712A07EA7A4

Signing / Verifying

A wallet can also sign and verify arbitrary hex messages. Generally, users should use the functions on XrpClient to perform cryptographic functions rather than using these low level APIs.

const { WalletFactory, XrplNetwork } = require('xpring-js')

const mnemonic =
  'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'
const message = 'deadbeef'

const walletFactory = new WalletFactory(XrplNetwork.Test)
const wallet = await walletFactory.generateRandomHdWallet(mnemonic)!

const signature = wallet.sign(message)
wallet.verify(message, signature) // true

XrpClient

XrpClient is a gateway into the XRP Ledger. XrpClient is initialized with a URL for a remote rippled node and an enum indicating the network the remote node runs on (see: ‘Server Side Component’ section above).

const { XrpClient, XrplNetwork } = require('xpring-js')

const remoteURL = 'test.xrp.xpring.io:50051' // Testnet URL, use main.xrp.xpring.io:50051 for Mainnet
const xrpClient = new XrpClient(remoteURL, XrplNetwork.Test)

Retrieving a Balance

An XrpClient can check the balance of an account on the XRP Ledger.

const { XrpClient, XrplNetwork } = require('xpring-js')

const remoteURL = 'test.xrp.xpring.io:50051' // Testnet URL, use main.xrp.xpring.io:50051 for Mainnet
const xrpClient = new XrpClient(remoteURL, XrplNetwork.Test)

const address = 'X7u4MQVhU2YxS4P9fWzQjnNuDRUkP3GM6kiVjTjcQgUU3Jr'

const balance = await xrpClient.getBalance(address)
console.log(balance) // Logs a balance in drops of XRP

Checking Payment Status

An XrpClient can check the status of a payment on the XRP Ledger.

This method can only determine the status of payment transactions which do not have the partial payment flag (tfPartialPayment) set.

Xpring-JS returns the following transaction states:

  • succeeded: The transaction was successfully validated and applied to the XRP Ledger.
  • failed: The transaction was successfully validated but not applied to the XRP Ledger. Or the operation will never be validated.
  • pending: The transaction has not yet been validated, but may be validated in the future.
  • unknown: The transaction status could not be determined, the hash represented a non-payment type transaction, or the hash represented a transaction with the tfPartialPayment flag set.

Note: For more information, see Reliable Transaction Submission and Transaction Results.

These states are determined by the TransactionStatus enum.

const { XrpClient, XrplNetwork } = require('xpring-js')

const remoteURL = 'test.xrp.xpring.io:50051' // Testnet URL, use main.xrp.xpring.io:50051 for Mainnet
const xrpClient = new XrpClient(remoteURL, XrplNetwork.Test)

const transactionHash =
  '9FC7D277C1C8ED9CE133CC17AEA9978E71FC644CE6F5F0C8E26F1C635D97AF4A'
const transactionStatus = xrpClient.getPaymentStatus(transactionHash) // TransactionStatus.Succeeded

Note: The example transactionHash may lead to a "Transaction not found." error because the Testnet is regularly reset, or the accessed node may only maintain one month of history. Recent transaction hashes can be found in the XRP Ledger Explorer: https://livenet.xrpl.org/

Retrieve specific payment

An XrpClient can return a specific payment transaction identified by hash.

const { XrpClient, XrplNetwork } = require('xpring-js')

const remoteURL = 'alpha.test.xrp.xpring.io:50051' // Testnet URL, use alpha.xrp.xpring.io:50051 for Mainnet
const xrpClient = new XrpClient(remoteURL, XrplNetwork.Test)
const transactionHash =
  '9FC7D277C1C8ED9CE133CC17AEA9978E71FC644CE6F5F0C8E26F1C635D97AF4A'
const payment = await xrpClient.getPayment(transactionHash)

Note: The example transactionHash may lead to a "Transaction not found." error because the Testnet is regularly reset, or the accessed node may only maintain one month of history. Recent transaction hashes can be found in the XRP Ledger Explorer: https://livenet.xrpl.org/

Payment history

An XrpClient can return a list of payments to and from an account.

const { XrpClient, XrplNetwork } = require('xpring-js')

const remoteURL = 'alpha.test.xrp.xpring.io:50051' // Testnet URL, use alpha.xrp.xpring.io:50051 for Mainnet
const xrpClient = new XrpClient(remoteURL, XrplNetwork.Test)
const address = 'XVMFQQBMhdouRqhPMuawgBMN1AVFTofPAdRsXG5RkPtUPNQ'
const transactions = await xrpClient.paymentHistory(address)

Sending XRP

An XrpClient can send XRP to other accounts on the XRP Ledger.

Note: The payment operation will block the calling thread until the operation reaches a definitive and irreversible success or failure state.

const { WalletFactory, XrpClient, XrplNetwork } = require("xpring-js");

const remoteURL = test.xrp.xpring.io:50051; // Testnet URL, use main.xrp.xpring.io:50051 for Mainnet
const xrpClient = new XrpClient(remoteURL, XrplNetwork.Test);

// Amount of XRP to send
const amount = BigInt("10");

// Destination address.
const destinationAddress = "X7u4MQVhU2YxS4P9fWzQjnNuDRUkP3GM6kiVjTjcQgUU3Jr";

// Wallet which will send XRP
const walletFactory = new WalletFactory(XrplNetwork.Test)
const generationResult = await walletFactory.generateRandomWallet()!
const senderWallet = generationResult.wallet;

const transactionResult = await xrpClient.sendXrp(amount, destinationAddress, senderWallet);

Note: The above example will yield an "Account not found." error because the randomly generated wallet contains no XRP.

Enabling Deposit Authorization

const { WalletFactory, XrpClient, XrplNetwork } = require("xpring-js");

const remoteURL = test.xrp.xpring.io:50051; // Testnet URL, use main.xrp.xpring.io:50051 for Mainnet
const xrpClient = new XrpClient(remoteURL, XrplNetwork.Test);

// Wallet for which to enable Deposit Authorization
const walletFactory = new WalletFactory(XrplNetwork.Test)
const seedWallet = await walletFactory.generateRandomWallet(
  'snRiAJGeKCkPVddbjB3zRwiYDBm1M',
)!

const transactionResult = await xrpClient.enableDepositAuth(seedWallet);
const transactionHash = transactionResult.hash;
const transactionStatus = transactionResult.status;
const validated = transactionResult.validated;

Utilities

Address validation

The Utils object provides an easy way to validate addresses.

const { Utils } = require('xpring-js')

const rippleClassicAddress = 'rnysDDrRXxz9z66DmCmfWpq4Z5s4TyUP3G'
const rippleXAddress = 'X7jjQ4d6bz1qmjwxYUsw6gtxSyjYv5iWPqPEjGqqhn9Woti'
const bitcoinAddress = '1DiqLtKZZviDxccRpowkhVowsbLSNQWBE8'

Utils.isValidAddress(rippleClassicAddress) // returns true
Utils.isValidAddress(rippleXAddress) // returns true
Utils.isValidAddress(bitcoinAddress) // returns false

You can also validate if an address is an X-Address or a classic address.

const { Utils } = require('xpring-js')

const rippleClassicAddress = 'rnysDDrRXxz9z66DmCmfWpq4Z5s4TyUP3G'
const rippleXAddress = 'X7jjQ4d6bz1qmjwxYUsw6gtxSyjYv5iWPqPEjGqqhn9Woti'
const bitcoinAddress = '1DiqLtKZZviDxccRpowkhVowsbLSNQWBE8'

Utils.isValidXAddress(rippleClassicAddress) // returns false
Utils.isValidXAddress(rippleXAddress) // returns true
Utils.isValidXAddress(bitcoinAddress) // returns false

Utils.isValidClassicAddress(rippleClassicAddress) // returns true
Utils.isValidClassicAddress(rippleXAddress) // returns false
Utils.isValidClassicAddress(bitcoinAddress) // returns false

X-Address Encoding

You can encode and decode X-Addresses with the SDK.

const { Utils } = require('xpring-js')

const rippleClassicAddress = 'rnysDDrRXxz9z66DmCmfWpq4Z5s4TyUP3G'
const tag = 12345

// Encode an X-Address.
const xAddress = Utils.encodeXAddress(rippleClassicAddress, tag) // X7jjQ4d6bz1qmjwxYUsw6gtxSyjYv5xRB7JM3ht8XC4P45P

// Decode an X-Address.
const decodedClassicAddress = Utils.decodeXAddress(xAddress)

console.log(decodedClassicAddress.address) // rnysDDrRXxz9z66DmCmfWpq4Z5s4TyUP3G
console.log(decodedClassicAddress.tag) // 12345

Usage: PayID

Two classes are used to work with PayID: PayIdClient and XrpPayIdClient.

PayIdClient

PayIdClient can resolve addresses on arbitrary cryptocurrency networks.

Single Address Resolution

// Resolve on Bitcoin Mainnet.
const network = 'btc-mainnet'
const payId = 'georgewashington$xpring.money'

const payIdClient = new PayIdClient()

const resolvedAddressComponents = await payIdClient.addressForPayId(
  payId,
  network,
)
console.log(resolvedAddressComponents.address)

All Addresses

PayIdClient can retrieve all available addresses.

import { PayIdClient } from 'xpring-js'

const payId = 'georgewashington$xpring.money'

const payIdClient = new PayIdClient()
const allAddresses = await payIdClient.allAddressesForPayId(payId)

XrpPayIdClient

XrpPayIdClient can resolve addresses on the XRP Ledger network. The class always coerces returned addresses into an X-Address. (See https://xrpaddress.info/)

import { XrplNetwork, XrpPayIdClient } from 'xpring-js'

// Use XrplNetwork.Main for Mainnet.
const xrpPayIdClient = new XrpPayIdClient(XrplNetwork.Test)

const payId = 'georgewashington$xpring.money'
const resolvedXAddress = await xrpPayIdClient.xrpAddressForPayId()

Usage: ILP

IlpClient

IlpClient is the main interface into the ILP network. IlpClient must be initialized with the URL of a Hermes instance. This can be found in your wallet.

All calls to IlpClient must pass an access token, which can be generated in your wallet.

const { IlpClient } = require('xpring-js')

const grpcUrl = 'hermes-grpc-test.xpring.dev' // Testnet Hermes URL
const ilpClient = new IlpClient(grpcUrl)

Retrieving a Balance

An IlpClient can check the balance of an account on a connector.

const { IlpClient } = require('xpring-js')

const grpcUrl = 'prod.grpcng.wallet.xpring.io' // Testnet ILP Wallet URL
const ilpClient = new IlpClient(grpcUrl)

const balance = await ilpClient.getBalance('demo_user', '2S1PZh3fEKnKg') // Just a demo user on Testnet
console.log(
  'Net balance was ' +
    balance.netBalance +
    ' with asset scale ' +
    balance.assetScale,
)

Sending a Payment

An IlpClient can send an ILP payment to another ILP address by supplying a Payment Pointer and a sender's account ID

const { PaymentRequest, IlpClient } = require("xpring-js")
const bigInt = require("big-integer")

const grpcUrl = "prod.grpcng.wallet.xpring.io" // Testnet ILP Wallet URL
const ilpClient = new IlpClient(grpcUrl)
const paymentRequest = new PaymentRequest({
    amount: 100,
    destinationPaymentPointer: "$xpring.money/demo_receiver",
    senderAccountId: "demo_user"
  })

PaymentResponse payment = ilpClient.sendPayment(paymentRequest, "2S1PZh3fEKnKg");

Usage: Xpring

Xpring components compose PayID and XRP components to make complex interactions easy.

import { WalletFactory, XpringClient, XrpClient, XrpPayIdClient, XrplNetwork } from 'xpring-js'

const network = XrplNetwork.Test

// Build an XrpClient
const rippledUrl = 'test.xrp.xpring.io:50051'
const xrpClient = new XrpClient(rippledUrl, network)

// Build a PayIdClient
const payIdClient = new XrpPayIdClient(network)

// XpringClient combines functionality from XRP and PayID
const xpringClient = new XpringClient(payIdClient, xrpClient)

// A wallet with some balance on TestNet.
const walletFactory = new WalletFactory(XrplNetwork.Test)
const generationResult =
const wallet = await walletFactory.generateRandomWallet('snYP7oArxKepd3GPDcrjMsJYiJeJB')!

// A PayID which will receive the payment.
const payId = 'alice$dev.payid.xpring.money'

// Send XRP to the given PayID.
const transactionHash = await xpringClient.send(amount, payId, wallet)

xpring-js's People

Contributors

0xclarity avatar dependabot-preview[bot] avatar dependabot[bot] avatar intelliot avatar keefertaylor avatar loisrp avatar mvadari avatar nkramer44 avatar schenkty avatar stormtv avatar tedkalaw avatar theotherian avatar tlongwell avatar xpringcontinuousintegration 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

Watchers

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

xpring-js's Issues

[PayID] xrpAddressForPayID resolves mainnet address as testnet T-address

I'm testing PayID resolution using Xpring-SDK-Demo/node/src/index-payid.js with pay$rabbitkick.club as example:

$ curl --header 'PayID-Version: 1.0' --header 'Accept: application/xrpl-mainnet+json' 'https://rabbitkick.club/pay'
{
  "addresses": [
    {
      "paymentNetwork": "XRPL",
      "environment": "MAINNET",
      "addressDetailsType": "CryptoAddressDetails",
      "addressDetails": {
        "address": "rabbitZWLG8PptsrPjuvKX4uAGjS5B64PP"
      }
    }
  ]
}

Looking at the above response, xrpAddressForPayID("pay$rabbitkick.club") should resolve to a mainnet address X7m8Yc9tJQKkQzbNJFzoXCSYJ6bFyc2EuwwQLr6Nw6szAB8, but it resolves to T76Jx5J1wM1miWMq2dj2RCUS893dVUNHiLfidgvkmK8mYk9 instead.

Current result
T76Jx5J1wM1miWMq2dj2RCUS893dVUNHiLfidgvkmK8mYk9

Expected result:
X7m8Yc9tJQKkQzbNJFzoXCSYJ6bFyc2EuwwQLr6Nw6szAB8 or rabbitZWLG8PptsrPjuvKX4uAGjS5B64PP

Walkthrough or Clear Tutorial?

Is there anyone that can provide a more clear walkthrough for a firsttime user of this platform as to how to develop apps to send/receive payments?

network client functionality does not work

I am unable to properly use the network client. It appears tests are based on a fake network client which allows this issue to pass through. I would recommend that all tests use an active network client connected to the test net

Setup instructions

Perhaps for the README:

Initially, it didn't work because I hadn't initialized/updated the submodule;

Next, I got this error:
Currency.proto:1:10: Unrecognized syntax identifier "proto3". This parser only recognizes "proto2".

I think that was because of:

% protoc --version
libprotoc 2.6.1

I installed the newer version of protobuf and that appears to fix things. Now using:

% protoc --version
libprotoc 3.9.1

Next, I got this error:
test/fakes/fake-network-client.ts:5:25 - error TS2307: Cannot find module 'assert'.

I resolved that with npm install @types/node.

Change IlpClient.sendPayment API names

First, we should align Xpring-JS with the other sdks by changing the IlpClient.send API to IlpClient.sendPayment.

Second, we should change the second parameter of that API from paymentPointer to destinationPaymentPointer, and change sender to senderAccountId

API should be:

sendPayment(
    amount: BigInteger | number | string,
    destinationPaymentPointer: string,
    senderAccountId: string,
    bearerToken?: string,
  ): Promise<SendPaymentResponse>

How to make this library work in the browser?

Hi, I tried shimming everything as in your example webpack.config.js but i still get this runtime error:

image

Do you have any idea which http2 module I can use to shim/replace the http2 node module?

Deprecation Notice on Wallet

Hello there, I've been playing with the Xpring-JS library and I find it quite neat to use and really simple to comprehend kudos on that

I also found out that there's a deprecation notice that vscode is warning me about about Wallet methods are deprecated
image

however I was not able to import the WalletFactory from the package

image

I was able to figure out that the mentioned class is inside the common library ibut it says in the readme that is not meant to consume directly

is it safe to pull the common library or should I wait for the sdk to pull the wallet factory from there?

I'm using

  • "xpring-js": "^5.3.1"
  • node v14.15.4
  • Windows 10

Cannot compile in webpack environment due to dependency expecting nodejs packages.

I have previously used Xpring-js with react-scripts which automates the webpack process, but I have since built my environment from scratch, and am only now having issues with xpring. It seems to be coming from a lot of node modules that are unused in the browser context, such as tls, dns, http2 etc, and I have successfully stopped some of them. The issue seems to be entirely coming from the dependency '@grpc/grpc-js'

ERROR in ./node_modules/@grpc/grpc-js/build/src/channel-credentials.js
Module not found: Error: Can't resolve 'google-auth-library' in ...

'google-auth-library' and 'http2' are the two that are still problematic.

Prepend "Bearer " to auth token for ILP API

This won't change anything functionally, but in order to abide by correct standards, the ILP SDK should add Bearer to the beginning of all auth tokens, if they do not already have them.

Similarly, we should wrap bearerToken in a class called IlpCallCredentials, which will do this for us and make the bearer token more strongly typed.

How to send from a classic address

I'm looking for a way to send xrp from a classic address, but it seems like send() requires the sender to be a wallet. Maybe I am missing something.

How to get the seed of a generated wallet in string form

Hello all,

I am trying to get a seed value from one of my wallets in string form and regenerate that wallet from the seed (similar to how the xpring.io website works). However I can't seem to figure out what I am doing wrong. Here is some sample code, however the wallets never match up.

var o = bip39.mnemonicToEntropy(mnemonic);
var seed = addressCodec.encodeSeed(Buffer.from(o, 'hex'), 'secp256k1');
var wallet = Wallet.generateWalletFromMnemonic(mnemonic, undefined, true);
var wallet2 = Wallet.generateWalletFromSeed(seed, true);
console.log("*** WALLET FROM MNEMONIC")
console.log(JSON.stringify(wallet))
console.log("*** WALLET FROM SEED")
console.log(JSON.stringify(wallet2))

// Output from wallet vs wallet 2 does not match.

Any help would be GREATLY appreciated.

Utils.isValidClassicAddress is not a function

If I run this:

const { Utils } = require('xpring-js')

const rippleClassicAddress = 'rnysDDrRXxz9z66DmCmfWpq4Z5s4TyUP3G'
Utils.isValidClassicAddress(rippleClassicAddress)

I get thsi error:

TypeError: Utils.isValidClassicAddress is not a function
    at Object.<anonymous> (index.js:31:7)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47

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.