npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

nano-uri

v3.0.0

Published

Tools for generating and parsing nano URIs

Downloads

6

Readme

nano-uri

npm version GitHub license

Library for creating nanopay and nanoauth URIs for use with nautilus.

If there are API-level breaking changes to the library, a major version bump (X.0.0) will be made along with a reddit post announcing the change.

Note that Nautilus will only ever try to support the latest version of this library, with as much backwards compatiblity as is reasonable. That being said, I don't expect all that much to change.

V3.0 Changes!:

The signing format is now FIXED to reduce complexity on implementations: the signer will now sign in this order!: ["timestamp", "label", "account"], so with the default separator: ":", a signed message request might look like this: "1234567:this is for an nft:nano_1234"

Features

  • Easily generate nanopay and nanoauth URI schemes

Examples

Example Link / QR

Example Backend Code (js)

This is the format that Nautilus expects as a response:

// TODO: finish this

// Example POST JSON responses:
// Example Success:
{
    // 0 = success
    "status": 0,
    "label": "Order #1234 - Example Service",
    "message": "Thank you for your purchase!",
    "metadata": {/* arbitrary transaction metadata */}
}

// Example Error:
{

    "status": int,
    // 0 = success
    // anything other than 0 == error
    "message": "<To be shown to the user explaining what went wrong>",
}

Installation

From NPM

npm install nano-uri

In web

<script src="https://unpkg.com/[email protected]" type="text/javascript"></script>
<script type="text/javascript">
  NanoURI.generate.auth(...);
  NanoURI.generate.pay(...);
  NanoURI.generate.sub(...);
  NanoURI.verify.auth(...);
</script>

Usage

| WARNING: do not use any of the private keys or addresses listed below to send real assets! | | ------------------------------------------------------------------------------------------ |

Creating a Block handoff request

import { generate } from "nano-uri";

const data = {
  // @required account: Where the user should send funds to:
  account: "nano_3yxcenuujnn6x7xmg7frakdm5zqu7418n3udquhpqda53oebata1ne9ukipg",

  // @required method: how to handoff the block:
  // Nautilus currently only supports the "post" method (HTTP POST)
  method: {
    type: "post",
    subtype: "handoff",
    url: "https://nautilus.perish.co/handoff",
  },

  // @required amount: The amount of NANO to send (in RAW):
  amount: "1000000000000000000000000000000",

  // @optional label: What the transaction is for
  label: "Block handoff test",

  // @optional message:
  message: "Thank you for using Nautilus!",

  // @optional exact: (default: true), whether the amount must match exactly
  // if false, amounts >= amount will be accepted
  exact: true,

  // @optional work: (default: true), whether the endpoint supports work generation
  // if false, the wallet must provide the work for the block by some other means (CURRENTLY UNSUPPORTED IN NAUTILUS)
  work: true,

  // @optional metadata: (default: {}), arbitrary metadata to be included in the response
  metadata: {
    order_id: "1234",
    service: "Example Service",
  },
};

// @optional: privateKey of the account that is requesting payment, to sign the request:
const privateKey = "75E96A80812E6D7B2B9802AB50B8D8E2628EC98C2A3894978F776652BC7B7F01";

// Returns a correctly formatted and signed nanopay:<base64Encoded> URI
const requestURI = generate.pay(data, privateKey);

// Alternatively, you can use a backwards compatible format by generating the blob the same way, and then adding it as a URI parameter like so:
// note that if put into a QR code it can be hard to scan depending on the size, so it's recommended to only use this in the form of a clickable link:
const payBlob = generate.payBlob(data, privateKey);
const requestURI = `${generate.nano(data)}&pay=${payBlob}`;

Creating an Authentication request

import { generate } from "nano-uri";

const data = {
  // @required method: how to handoff the block:
  // Nautilus currently only supports the "post" method (HTTP POST)
  method: {
    type: "post",
    subtype: "handoff",
    url: "https://nautilus.perish.co/handoff",
  },

  // @required account: Who is requesting the authentication:
  account: "nano_3yxcenuujnn6x7xmg7frakdm5zqu7418n3udquhpqda53oebata1ne9ukipg",

  // @required label: What the authentication request is for:
  label: "Login with your NANO Account",

  // @optional message:
  message: "See this content after login",

  // @optional separator: separator to use in the format when signing the response:
  // default:
  separator: ":",

  // @optional metadata: (default: {}), arbitrary metadata to be included in the response
  metadata: {
    order_id: "1234",
    service: "Example Service",
  },
};

// @optional: privateKey of the account that is requesting authentication, to sign the request:
const privateKey = "75E96A80812E6D7B2B9802AB50B8D8E2628EC98C2A3894978F776652BC7B7F01";

// Returns a correctly formatted and signed nanoauth:<base64Encoded> URI
const requestURI = generate.auth(data, privateKey);

// Alternatively, you can use a backwards compatible format by generating the blob the same way, and then adding it as a URI parameter like so:
// note that if put into a QR code it can be hard to scan depending on the size, so it's recommended to only use this in the form of a clickable link:
const authBlob = generate.authBlob(data, privateKey);
const requestURI = `${generate.nano(data)}&auth=${authBlob}`;

Verifying an authentication request

import { verify } from "nano-uri";

const data = {
  // @required account: whoever signed the request:
  account: "nano_11qwaxtmb5c7xc16wat5rgirbxzug1kgq8tf996xi8kf5cdcrjyaiy39foun",

  // @required signature: signature of the request:
  signature:
    "C1FCCB4092AF1A2683BA3DB0F69FFFC11A961E995C3C10ACFB5F302767E91BB340A1475000AAEDD94E36D45DA0FC91DEEB9B02ABCEF7B98FBF78B5B3B9419D0C",

  // @required signed: the text that was signed:
  signed:
    "736F6D655F72616E646F6D5F6E6F6E63653A313636313339333830303A4C6F67696E20746F205065726973683A6E616E6F5F33383731337839357A796A73717A78366E6D3164736F6D316A6D6D3636386F776B6562393931336178366E66676A3135617A336E7538786B78353739",

  // @optional formatted: the decoded signed text:
  formatted:
    "1589788984:Login with your NANO Account:nano_3yxcenuujnn6x7xmg7frakdm5zqu7418n3udquhpqda53oebata1ne9ukipg",
};

// true if the signature is valid, false otherwise
const isValid = verify.auth(data);

Creating a Subscription request

import { generate } from "nano-uri";

const data = {
  // @required account: Where the user should send funds to:
  account: "nano_3yxcenuujnn6x7xmg7frakdm5zqu7418n3udquhpqda53oebata1ne9ukipg",

  // @required amount: The amount of NANO to send (in RAW):
  amount: "1000000000000000000000000000000",

  // @required frequency: How often the subscription should be paid (cron format):
  frequency: "0 0 1 * *",// every 1st of the month

  // @optional label: What the subscription is for
  label: "Nautilus Pro",

  // @optional message:
  message: "Thank you for using Nautilus!",
};

// @optional: privateKey of the account that is requesting payment, to sign the request:
const privateKey = "75E96A80812E6D7B2B9802AB50B8D8E2628EC98C2A3894978F776652BC7B7F01";

// Returns a correctly formatted and signed nanosub:<base64Encoded> URI
const requestURI = generate.sub(data, privateKey);

Creating a regular nano: URI

import { generate } from "nano-uri";

const data = {
  // @required account: Where the user should send funds to:
  account: "nano_3yxcenuujnn6x7xmg7frakdm5zqu7418n3udquhpqda53oebata1ne9ukipg",

  // @required amount: amount in raw
  amount: "1000000000000000000000000000000",

  // @optional label: What the transaction is for
  label: "NANO URI test",

  // @optional message:
  message: "Thank you for using Nautilus!",
};

// Returns a correctly formatted nano: URI
const requestURI = generate.nano(data);

Donate

If this project helped you, feel free to donate at the Nautilus Node's address: nano_38713x95zyjsqzx6nm1dsom1jmm668owkeb9913ax6nfgj15az3nu8xkx579