Giter VIP home page Giter VIP logo

golem-js's Introduction


golem-js SDK logo

Golem JavaScript API

GitHub npm node-current npm type definitions GitHub Workflow Status GitHub issues Discord

Table of contents

Features

Become a Requestor in the Golem Network and use this SDK to:

  • 🌐 Acquire compute resources from Providers using a convenient API
  • 🚒 Run your workloads with these resources and get the results back to your machine
  • πŸ” Build N-tier application deployments and run them within a VPN
  • πŸ’° Settle payments with Providers for the resources you've utilized

Getting Started

What's Golem and golem-js?

The Golem Network fosters a global group of creators building ambitious software solutions that will shape the technological landscape of future generations by accessing computing resources across the platform. Golem Network is an accessible, reliable, open access and censorship-resistant protocol, democratizing access to digital resources and connecting users through a flexible, open-source platform.

golem-js is the JavaScript API that allows developers to connect to their Golem nodes and manage their distributed, computational loads through Golem Network.

SDK Learning resources

Installation

To quickly get started with a new project using golem-js, you can use the following template:

npx @golem-sdk/cli@latest new my-awesome-golem-project

@golem-sdk/golem-js is available as a NPM package.

You can install it through npm:

npm install @golem-sdk/golem-js

or by yarn:

yarn add @golem-sdk/golem-js

Supported environments

The SDK is designed to work with LTS versions of Node (starting from 18) and with browsers. The minimum supported yagna version is 0.15.2.

Getting started with Golem Network

Before you start using the SDK, you need to have yagna installed and running on your machine. Yagna is a service that communicates and performs operations on the Golem Network, upon your requests via the SDK. You can follow the instructions below or visit the official documentation to set it up.

# Join the network as a requestor
curl -sSf https://join.golem.network/as-requestor | bash -

# Start the golem node on your machine,
# you can use `daemonize` to run this in background
yagna service run

Now that you have yagna running, you can initialize your requestor and request funds (tGLM tokens) on the test network.

# IN SEPARATE TERMINAL (if not daemonized)
# Initialize your requestor
yagna payment init --sender --network holesky

# Request funds on the test network
yagna payment fund --network holesky

# Check the status of the funds
yagna payment status --network holesky

Obtain an app-key to use with SDK

If you don't have any app-keys available from yagna app-key list, go ahead and create one with the command below. You will need this key in order to communicate with yagna from your application. You can set it as YAGNA_APPKEY environment variable.

yagna app-key create my-golem-app

Usage

You can rent a single machine and run a simple task on it:

import { MarketOrderSpec, GolemNetwork } from "@golem-sdk/golem-js";

// Define the order that we're going to place on the market
const order: MarketOrderSpec = {
  demand: {
    workload: { imageTag: "golem/alpine:latest" },
  },
  market: {
    // We're only going to rent the provider for 5 minutes max
    rentHours: 5 / 60,
    pricing: {
      model: "linear",
      maxStartPrice: 0.5,
      maxCpuPerHourPrice: 1.0,
      maxEnvPerHourPrice: 0.5,
    },
  },
};

(async () => {
  const glm = new GolemNetwork();

  try {
    await glm.connect();
    // Rent a machine
    const rental = await glm.oneOf({ order });
    await rental
      .getExeUnit()
      .then((exe) => exe.run("echo Hello, Golem! πŸ‘‹"))
      .then((res) => console.log(res.stdout));
    await rental.stopAndFinalize();
  } catch (err) {
    console.error("Failed to run the example", err);
  } finally {
    await glm.disconnect();
  }
})().catch(console.error);

Read about other available usage patterns to learn more on how you can leverage the SDK.

Examples

The examples directory in the repository contains various usage patterns for the SDK. You can browse through them and learn about the recommended practices. All examples are automatically tested during our release process.

You can find even more examples and tutorials in the JavaScript API section of the Golem Network Docs.

Documentation

Visit our official documentation to learn more about the JavaScript SDK and how to use it.

Debugging

The SDK uses the debug package to provide debug logs. To enable them, set the DEBUG environment variable to golem-js:* or golem-js:market:* to see all logs or only the market-related ones, respectively. For more information, please refer to the debug package documentation.

Testing

Read the dedicated testing documentation to learn more about how to run tests of the SDK.

Contributing

Read the Contributing Guide for details on how you can get involved. In case you find an issue with the examples or the SDK itself, feel free to submit an issue report to the repository.

Discord

Feel invited to join our Discord. You can meet other SDK users and developers in the #sdk-discussion and #js-discussion channels.

See also

golem-js's People

Contributors

azawlocki avatar braunmann avatar cryptobench avatar dependabot[bot] avatar etam avatar figurestudios avatar filipgolem avatar grisha87 avatar jalas167 avatar kamirr avatar kmazurek avatar mateuszsrebrny avatar mdtanrikulu avatar mfranciszkiewicz avatar mgordel avatar pgrzy-golem avatar pociej avatar prekucki avatar sewerynkras avatar shadeofblue avatar stranger80 avatar vandavv 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

Watchers

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

golem-js's Issues

decrease verbosity of logs

generally, most of the debug logs should only be presented when the example is run with --debug flag
please compare to yapapi's verbosity

Graceful shutdown on interruption ( ctrl + c ) doesn't work as intended

$ yarn ts:blender
yarn run v1.22.5
$ ts-node-script ./blender/blender.ts
Using subnet: community.3
2020-11-19 12:59:37 [yajsapi] info: GFTP Version:0.1.2
2020-11-19 12:59:38 [yajsapi] info: Demand published on the market
2020-11-19 12:59:42 [yajsapi] info: Received proposals from 1 providers so far
2020-11-19 12:59:44 [yajsapi] info: Received proposals from 2 providers so far
2020-11-19 12:59:44 [yajsapi] info: Agreement proposed to provider 'manchester.3'
2020-11-19 12:59:44 [yajsapi] info: Received proposals from 3 providers so far
2020-11-19 12:59:44 [yajsapi] info: Received proposals from 4 providers so far
2020-11-19 12:59:44 [yajsapi] info: Received proposals from 5 providers so far
2020-11-19 12:59:46 [yajsapi] info: Received proposals from 6 providers so far
2020-11-19 12:59:52 [yajsapi] info: Agreement confirmed by provider 'manchester.3'
2020-11-19 12:59:52 [yajsapi] info: Task sent to provider 'manchester.3', task data: 50
2020-11-19 12:59:54 [yajsapi] info: Agreement proposed to provider 'ada'
2020-11-19 13:00:00 [yajsapi] info: Task computed by provider 'manchester.3', task data: 50
2020-11-19 13:00:00 [yajsapi] info: Task sent to provider 'manchester.3', task data: 40
result= output_50.png
^C
adam@IMAPP1006 ~/Downloads/golem-requestor-linux-pre-rel-v0.5.0-495172ea/yajsapi/examples (b0.2 u=)
$ Unhandled rejection undefined

2020-11-19 13:00:05 [yajsapi] error: fail= undefined

"Double payment" strikes back

In testing session we catched Double payment again but in different form this time, both payments had value.

2020-11-19 13:08:31 [yajsapi] info: Accepted payment: 0.03736446749000000 for invoice e480fb53-7e36-455
2020-11-19 13:08:31 [yajsapi] info: Total cost: 0.09931349073911111
2020-11-19 13:08:31 [yajsapi] info: Accepted payment: 0.03508967915111111 for invoice 9f473075-3990-4b0
2020-11-19 13:08:31 [yajsapi] info: Total cost: 0.10234954429411111
2020-11-19 13:08:31 [yajsapi] info: Accepted payment: 0.003036053555000000 for invoice 14015461-32f3-429

Pass `--subnet-tag` as argument like yapapi

For testing sessions it is nice to have the option to pass the subnet flag as an argument.

I propose the same name or the argument as yapapi is using:

 --subnet-tag devnet-alpha.2

No graceful shutdown after a TimeoutError

When [yajsapi] error: fail= TimeoutError: task timeout exceeded. timeout=900000 happens, yajsapi displays errors like:

  • HTTP 500 (from getExecBatchResults)
  • Error [ERR_STREAM_DESTROYED]: Cannot call write after a stream was destroyed (gftp is closed too early)
  • [yajsapi] error: Failed to destroy activity: ...

Lag on loggger

There is 0 > x >= 2 seconds lag due to dequeuing get method. Have better async dequeuing logic

Payment phase lasted too long

Payment phase lasted for 66s which is twice as much as market negotiations and activity together 34.1s

$ YAGNA_APPKEY=$(yagna app-key list --json | jq -r .values[0][1]) yarn run ts:blender
yarn run v1.22.10
$ ts-node-script ./blender/blender.ts
Using subnet: community.3
[...]
result= output_0.png
2020-11-19 13:00:14 [yajsapi] info: Computation finished in 34.1s
2020-11-19 13:00:14 [yajsapi] info: Negotiated 2 agreements with 2 providers
2020-11-19 13:00:14 [yajsapi] info: Provider 'friendly-error' computed 4 tasks
2020-11-19 13:00:14 [yajsapi] info: Provider 'univac.3' computed 2 tasks
2020-11-19 13:00:14 [yajsapi] info: Provider 'manchester.3' did not compute any tasks
2020-11-19 13:00:14 [yajsapi] info: Accepted payment: 0.06630091567800001 for invoice fa479baf-99c3-42e
2020-11-19 13:00:14 [yajsapi] info: Total cost: 0.11400723553883334
2020-11-19 13:00:14 [yajsapi] info: Accepted payment: 0.04770631986083333 for invoice ee3d7025-17cf-4f7
2020-11-19 13:00:16 [yajsapi] info: Received proposals from 6 providers so far
2020-11-19 13:00:20 [yajsapi] info: Received proposals from 6 providers so far
2020-11-19 13:00:22 [yajsapi] info: Received proposals from 6 providers so far
2020-11-19 13:00:26 [yajsapi] info: Received proposals from 7 providers so far
✨  Done in 110.11s.

Failed to create activity 408 after computation finished

Phillip - OSX catalina, yajsapi latest version - 408 after computation is finished.
GJ - had this too on mac-js

    2021-02-11 12:20:40 [yajsapi] info: Computation finished in 402.1s
    2021-02-11 12:20:40 [yajsapi] info: Negotiated 2 agreements with 2 providers
    2021-02-11 12:20:40 [yajsapi] info: Provider 'tytus “(ʘ_ʘ)‏ romek ᕦ ξ–– ! ξ–– α•₯ i atomek' computed 6 tasks
    2021-02-11 12:20:40 [yajsapi] info: Provider 'ziomek' did not compute any tasks
    2021-02-11 12:20:40 [yajsapi] info: Provider 'ziomek' did not compute any tasks
    2021-02-11 12:20:40 [yajsapi] info: Provider 'glen.4' did not compute any tasks
    2021-02-11 12:20:40 [yajsapi] info: Provider 'tytus “(ʘ_ʘ)‏ romek ᕦ ξ–– ! ξ–– α•₯ i atomek' did not compute any tasks
    2021-02-11 12:20:40 [yajsapi] info: Provider 'tytus “(ʘ_ʘ)‏ romek ᕦ ξ–– ! ξ–– α•₯ i atomek' did not compute any tasks
    2021-02-11 12:20:40 [yajsapi] info: Provider 'glen.4' did not compute any tasks
    2021-02-11 12:20:42 [yajsapi] info: Accepted payment: 0.002062975904072222 for invoice 8545e468-7fe7-4d9
    2021-02-11 12:20:47 [yajsapi] error: Failed to create activity for agreement 1b7cb6cb26391c9f7e4f964df0fe9d7557c2e2839393ee56aae668ba680fbba7: Error: Request failed with status code 408
    2021-02-11 12:20:47 [yajsapi] error: Worker finished with error: Error: Request failed with status code 408
    2021-02-11 12:21:01 [yajsapi] info: Finished waiting for payments. Summary:
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ (index) β”‚  Agreement   β”‚              Provider Name               β”‚ Tasks Computed β”‚         Cost         β”‚
    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
    β”‚    0    β”‚ 'd6270cbcdf' β”‚ 'tytus “(ʘ_ʘ)‏ romek ᕦ ξ–– ! ξ–– α•₯ i atomek' β”‚       6        β”‚ 0.002062975904072222 β”‚
    β”‚    1    β”‚ '1b7cb6cb26' β”‚                 'glen.4'                 β”‚       0        β”‚  '0 (no invoices?)'  β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    2021-02-11 12:21:01 [yajsapi] info: Total Cost: 0.002062975904072222
    ✨  Done in 426.28s.

yagnadatadir.zip

ederenn - Win 10 - js - 408 after computation is finished.
    2021-02-11 12:30:26 [yajsapi] debug: waitForApproval(3ded7fbbc00297e5d89e17f6eafbfbb91fe5708e81c677ee13ed3891cb573149) raised ApiException Error: Request failed with status code 408
    Done in 100.78s.

yagna_rCURRENT (5).log

yajsapi (2).log

[UX] Add user friendly warning for new added apis

If anyone tries to run updated yapapi/yajsapi from source (or on upcoming release when released) with yagna < 0.5.0, they will have 404 status code for new payment api.

What I propose instead, it's better to indicate "to be able to use this version of sdk you need to update yagna to something above >= 0.5.0" warning, so user will know what needs to be done.

Fix Winston File transport bug

(node:18568) UnhandledPromiseRejectionWarning: Error: write after end
    at writeAfterEnd (/Users/mdt/projects/Golem/yajsapi/node_modules/readable-stream/lib/_stream_writable.js:261:12)
    at PassThrough.Writable.write (/Users/mdt/projects/Golem/yajsapi/node_modules/readable-stream/lib/_stream_writable.js:305:21)
    at File.log (/Users/mdt/projects/Golem/yajsapi/node_modules/winston/lib/winston/transports/file.js:185:34)
    at File._write (/Users/mdt/projects/Golem/yajsapi/node_modules/winston-transport/index.js:82:19)
    at doWrite (/Users/mdt/projects/Golem/yajsapi/node_modules/winston-transport/node_modules/readable-stream/lib/_stream_writable.js:428:64)
    at writeOrBuffer (/Users/mdt/projects/Golem/yajsapi/node_modules/winston-transport/node_modules/readable-stream/lib/_stream_writable.js:417:5)
    at File.Writable.write (/Users/mdt/projects/Golem/yajsapi/node_modules/winston-transport/node_modules/readable-stream/lib/_stream_writable.js:334:11)
    at DerivedLogger.ondata (/Users/mdt/projects/Golem/yajsapi/node_modules/readable-stream/lib/_stream_readable.js:681:20)
    at DerivedLogger.emit (events.js:327:22)
    at addChunk (/Users/mdt/projects/Golem/yajsapi/node_modules/readable-stream/lib/_stream_readable.js:298:12)
    at readableAddChunk (/Users/mdt/projects/Golem/yajsapi/node_modules/readable-stream/lib/_stream_readable.js:280:11)
    at DerivedLogger.Readable.push (/Users/mdt/projects/Golem/yajsapi/node_modules/readable-stream/lib/_stream_readable.js:241:10)
    at DerivedLogger.Transform.push (/Users/mdt/projects/Golem/yajsapi/node_modules/readable-stream/lib/_stream_transform.js:139:32)
    at DerivedLogger._transform (/Users/mdt/projects/Golem/yajsapi/node_modules/winston/lib/winston/logger.js:305:12)
    at DerivedLogger.Transform._read (/Users/mdt/projects/Golem/yajsapi/node_modules/readable-stream/lib/_stream_transform.js:177:10)
    at DerivedLogger.Transform._write (/Users/mdt/projects/Golem/yajsapi/node_modules/readable-stream/lib/_stream_transform.js:164:83)
(node:18568) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:18568) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

add a @deprectated decorator

as part of our backwards compatibility flow, we should include a deprecation notice for any classes, methods and fuctions that we want to remove in a future version of our API

to that end, we'd like to have a @deprecated decorator which emits a WARNING log each time such deprectated component is called/instantiated/etc

"undefined offers have been collected from the market"

the warning message lacks the actual value and uses a value of undefined instead

2020-11-17 17:40:04 [yajsapi] warn: undefined offers have been collected from the market, but
no provider has responded for 20s. Make sure you're using the latest released versions of yagna and yajsapi, and the correct subnet.

long tasks frequently fail on providers

initial research: may be caused by not repeating the getExecBatchResults call after the timeout happens.

fixed by:
#90

example (video conversion):

  async function* worker(ctx: WorkContext, tasks) {
    let sentFile = "/golem/resource/input.file";

    let sendPath = path.join(__dirname, "./input.mp4");

    //ctx.log(`Sending file: ${sendPath}`);

    ctx.send_file(sendPath,sentFile);

    //ctx.log(`Sent: ${sendPath}`);

    for await (let task of tasks) {
      let outputNum: any = task.data();
      let presets = ["Fast 480p30", "VP9 MKV 1080p30"];
      let preset = "Fast 480p30";
      let outputFile = `output_${outputNum}.mkv`;
      let downloadLog = path.join(__dirname, `log_${outputNum}.txt`);
      let downloadFile2 = path.join(__dirname, `output_${outputNum}.txt`);

      //ctx.log(`output num: ${outputNum}`);
      //ctx.log(`downloading to ${downloadLog}`);

      let commands = [
        "-c",
        //`exec >/golem/output/output.txt 2>&1;
        `cd /golem/output/;
        echo $PWD > log.txt;
        echo preset:${preset} >> log.txt;
        echo output_file:${outputFile} >> log.txt;
        ls -lah ${sentFile} >> log.txt;
        which HandBrakeCLI >> log.txt;
        HandBrakeCLI -i ${sentFile} -o ${outputFile} --preset '${preset}' >> log.txt 2>&1;
        ls -lah >> log.txt;`
      ]

      //ctx.log("Running commands:");
      //ctx.log(commands);

      ctx.run("/bin/sh", commands);
      ctx.log("commands done");

      ctx.log("downloading");
      ctx.download_file("/golem/output/log.txt", downloadLog);
      ctx.download_file(`/golem/output/${outputFile}`,path.join(__dirname, outputFile));
      ctx.log("downloading done");

      yield ctx.commit();
      // TODO: Check
      // job results are valid // and reject by:
      // task.reject_task(msg = 'invalid file')
      task.accept_task(outputFile);
    }

    ctx.log("no more frames to render");
    return;
  }

(win-js) additional ctrl c was needed when stopping computations

yagna_rCURRENT.log
yajsapi.log

@ederenn - Win 10+ js

Terminate batch job (Y/N)? 2021-02-11 12:37:15 [yajsapi] error: Computation interrupted by the user.
2021-02-11 12:37:15 [yajsapi] info: Computation finished in 353.3s
2021-02-11 12:37:15 [yajsapi] info: Negotiated 0 agreements with 0 providers
2021-02-11 12:37:15 [yajsapi] info: Provider 'tytus “(ʘ_ʘ)‏ romek ᕦ ξ–– ! ξ–– α•₯ i atomek' did not compute any tasks
2021-02-11 12:37:15 [yajsapi] info: Provider 'tytus “(ʘ_ʘ)‏ romek ᕦ ξ–– ! ξ–– α•₯ i atomek' did not compute any tasks
2021-02-11 12:37:15 [yajsapi] info: Provider 'tytus “(ʘ_ʘ)‏ romek ᕦ ξ–– ! ξ–– α•₯ i atomek' did not compute any tasks
2021-02-11 12:37:15 [yajsapi] info: Provider 'tytus “(ʘ_ʘ)‏ romek ᕦ ξ–– ! ξ–– α•₯ i atomek' did not compute any tasks
2021-02-11 12:37:27 [yajsapi] debug: GFTP server closed, code=null
2021-02-11 12:37:30 [yajsapi] debug: waitForApproval(431d719045b1b74fb7d919e52220bb0a7f6ebca39c1ee52bbcc08694f4a1581f) raised ApiException Error: Request failed with status code 408

^C
C:\Users\ederenn\Projects\yajsapi\examples>

yajsapi catching up with yapapi

Implementations


  • ExecutorEvents
  • SmartQueue + Consumer + AsyncLock
  • asyncWrapper



Updates


  • WorkContext
  • Activity
  • Blender example
  • Project Structure changes <Callable (util), Task, Task Status, EventLoop(util)>



provider_tasks and provider_cost are indexed by provider names, which are not unique

    # Maps a provider name to the list of task ids computed by the provider
    provider_tasks: Dict[str, List[str]]

    # Map a provider name to the sum of amounts in this provider's invoices
    provider_cost: Dict[str, float]

It should map Node_ID to List[str] and Node_ID to float.

also, this code has to map unique Node_IDs to table rows:

    const results = [...this.confirmed_agreements].map(
      (agr_id) => {
        const name = this.agreement_provider_name[agr_id];
        const tasks = this.provider_tasks[name];
        const cost = this.provider_cost[name] || "0 (no invoices?)";
        return {
          'Provider Name': name,
          'Tasks Computed': tasks ? tasks.length : 0,
          'Cost': cost,
        };
      }
    );
    console.table(results);

Move Payment tables in log, under another flag

Tables as a payment indicator is a nice feature however, I am in favor of moving them under a separate flag i.e. "-t" so developers won't have any problem parsing regular log of the library.

createAllocation error is not clearly explained

Using subnet: devnet-alpha.4, network: rinkeby, driver: zksync
[yajsapi] debug: Using image repository: _girepo._tcp.dev.golem.network -> http://yacn.dev.golem.network:8000.
[yajsapi] debug: Creating allocation using payment platform zksync-rinkeby-tglm
[yajsapi] error: Request failed with status code 400
[yajsapi] error: Executor - Error: Request failed with status code 400

Error: Error: Request failed with status code 400
    at _AllocationTask.ready (yajsapi/rest/payment.ts:175:13)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

✨  Done in 3.73s.

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.