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

wise-js

v1.1.2

Published

JS library for dApps to authenticate with WISE

Downloads

16

Readme

wise-js was renamed to walletify-js on April 2023

wise-js

Construct and decode authentication requests for Stacks apps.

This package provides the auth logic used by the WISE App. If you're looking to integrate WISE authentication into your react-native app, wise-js provides a simple API using Stacks. if you're not familiar with Stacks, You should first take a look into Stacks Authentication.

Wise

Installation

npm i --save wise-js

or

yarn add wise-js

Usage

  1. For react-native use this guide to install react-native-crypto.

    The react-native-crypto is A port of node's crypto module to React Native.

  2. Include the app config into your app, and change the appDomain to your domain.

import {
  AppConfig,
} from 'wise-js';

const appDomain = 'https://example.com';
const manifestURIPath = '/manifest.json';
const scopes = ['store_write', 'publish_data'];
const appConfig = new AppConfig(scopes, appDomain, undefined, manifestURIPath);

The app domain is the URL to your website/app. This is how the Stacks authentication system identifies apps and determines what credentials to provide. Changing the appDomain is equivalent to changing the app.

scopes where you set the basic permissions for your app to read and store user data. If your app will allow users to share data with other users, you will need an additional publish_data permission.

manifestURIPath is the location of your app manifest file. This file contains information about your app that is shown to the user during authentication.

  1. Make a sessionStore class to customize where your authentication data is located. for example, this is the sessionStore class that implements @react-native-async-storage/async-storage.
import AsyncStorage from '@react-native-async-storage/async-storage';
import {
  SessionData,
  SessionOptions,
  SessionDataStore,
} from 'wise-js';

const LOCALSTORAGE_SESSION_KEY = 'wise-session';

export class AsyncStorageStore extends SessionDataStore {
  key: string;

  constructor(sessionOptions?: SessionOptions) {
    super(sessionOptions);
    if (
      sessionOptions
            && sessionOptions.storeOptions
            && sessionOptions.storeOptions.localStorageKey
            && typeof sessionOptions.storeOptions.localStorageKey === 'string'
    ) {
      this.key = sessionOptions.storeOptions.localStorageKey;
    } else {
      this.key = LOCALSTORAGE_SESSION_KEY;
    }
    this.init();
  }

  async init() {
    const data = await this.getData(this.key);
    if (!data) {
      const sessionData = new SessionData({});
      this.setSessionData(sessionData);
    }
  }

  async getData(key: string) {
    return AsyncStorage.getItem(key);
  }

  async getSessionData(): Promise<SessionData> {
    const data = await AsyncStorage.getItem(this.key);
    if (!data) {
      console.log('No session data was found in localStorage');
      return {};
    }
    // @ts-ignore
    const dataJSON = JSON.parse(data);
    return SessionData.fromJSON(dataJSON);
  }

  async setSessionData(session: SessionData) {
    await AsyncStorage.setItem(this.key, session.toString());
  }

  async deleteSessionData() {
    await AsyncStorage.removeItem(this.key);
    await this.setSessionData(new SessionData({}));
  }
}

Important Note: Don't forget to install @react-native-async-storage/async-storage

  1. Use the sessionStorage and appConfig to create your userSession;
import {
  WiseUserSession,
} from 'wise-js';

const userSession = new WiseUserSession({
    appConfig,
    sessionStore,
});

We will also initiate a UserSession object using the previous configurations.

  1. Use the userSession to initiate authentication flow.
import {
  useCallback,
  useEffect,
  useState,
} from 'react';
import {
  Alert,
  DeviceEventEmitter,
  Linking,
  Platform,
} from 'react-native';
import {
  getParameterByName,
} from 'wise-js';

export const useAuthentication = () => {
  const [pendingAuthentication, setPendingAuthentication] = useState<boolean>(false);

  const createSession = useCallback(async () => {
    // Method to check if the user is already authenticated.
    const signedIn = await userSession.isUserSignedIn();
    if (signedIn) {
      // Method to retrieve the user's profile data
      const sessionData = await userSession.loadUserData();
      console.warn('Use is logged in with session data', sessionData);
    } else {
      console.warn('User is not logged In');
    }
  }, []);
   const resumeAuthentication = useCallback(
           (linkingUrl: string) => {
              Linking.canOpenURL(linkingUrl)
                      .then(supported => {
                         if (supported) {
                            setPendingAuth(true);
                            const authResponse = getParameterByName('authResponse', linkingUrl);
                            setLoading();
                            userSession
                                    .handlePendingSignIn(authResponse || '')
                                    .then(() => {
                                       createSession();
                                       setPendingAuth(false);
                                    })
                                    .catch(() => {
                                       setFailure();
                                       setPendingAuth(false);
                                    });
                         }
                      })
                      .catch(() => {
                         setFailure();
                         setPendingAuth(false);
                      });
           },
           [createSession],
   );
  useEffect(() => {
    createSession();
    // setup listener for url changes.
    const subscription = DeviceEventEmitter.addListener('url', ({ url: linkingUrl }) => {
      if (e.url && !pendingAuthentication) {
         resumeAuthentication(linkingUrl);
      }
    });
    return () => subscription.remove();
  }, []);
  
   useEffect(() => {
      const getUrlAsync = async () => {
         // Get the deep link used to open the app for first time
         const initialUrl = await Linking.getInitialURL();
         resumeAuthentication(initialUrl || '');
      };

      getUrlAsync();
   }, []);
   
  const signIn = useCallback(async () => {
    // Method to generate generate the authentication request payload.
     const url = await userSession.generateAuthURL();
    // This part where you communicate with WISE to authenticate.
     Linking.openURL(url);
  }, []);
  
  const signOut = useCallback(async () => {
    await userSession.signUserOut();
  }, []);

  return {
    signIn,
    signOut,
  };
};
  1. Make a manifest.json file on your hosting domain.
{
    short_name: "Pravica",
    name: "Pravica",
    icons: [
        {
            src: "https://app.pravica.io/new-logo.png",
            sizes: "64x64 32x32 24x24 16x16",
            type: "image/png"
        }
    ],
    start_url: "https://app.pravica.io",
    display: "standalone",
    theme_color: "#000000",
    background_color: "#2679ff"
}
  1. To initiate Stacks Gaia client with your app.
import {
   WiseCustomStorage,
} from 'wise-js';

export const wiseStorage = new WiseCustomStorage({
  userSession,
});

Gaia storage provides a way for users to save both public and private data off-chain while retaining complete control over it.

  1. To enable routing back to your app from WISE you have to configure the universal links for (IOS) and app links for (Android).

Create a folder on your hosting domain root with the name .well-known to put the universal links for (IOS) and app links for (Android) configuration files.

1- For IOS:

  • create a file with the name ‘apple-app-site-association’:
{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": "MXLF5SQD6Q.io.pravica",
                "paths": [ "*" ]
            }
        ]
    }
}
  • Replace MXLF5SQD6Q with your Team ID you can get it from https://developer.apple.com.

  • Replace io.pravica with your Bundle Identifier.

  • Then Add the Associated Domains Entitlement to Your App.

    To set up the entitlement in your app, open the target’s Signing & Capabilities tab in Xcode and add the Associated Domains capability and fill in the domain of your site with the prefix applinks:

    img.png -Add this code to your AppDelegate.m:

    #import "RCTLinkingManager.h"
    
    - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
      restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
      {
      return [RCTLinkingManager application:application
                       continueUserActivity:userActivity
                         restorationHandler:restorationHandler];
      }
      

For Reference: https://developer.apple.com/documentation/Xcode/supporting-associated-domains.

2- For Android:

  • create a file with the name assetlinks.json:
[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "io.pravica",
    "sha256_cert_fingerprints": ["DB:1C:4B:5C:BA:2D:DD:6E:56:47:87:93:FA:D0:7E:BF:4B:15:DF:71:99:19:73:8E:3F:2F:54:F0:C8:8B:FC:C4"]
  }
}]
  • Replace io.pravica with your Bundle Identifier.
  • Replace sha256_cert_fingerprints with your fingerprint. The SHA256 fingerprints of your app’s signing certificate. You can use the following command to generate the fingerprint via the Java keytool.
keytool -list -v -keystore my-release-key.keystore
  • To enable link handling verification for your app, set android:autoVerify="true" in any one of the web URL intent filters in your app manifest that include the android.intent.action.VIEW intent action and android.intent.category.BROWSABLE intent category, as shown in the following manifest code snippet:
<activity ...>

    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="https" android:host="app.pravica.io"/>
    </intent-filter>

</activity>
  • Replace app.pravica.io with your domain URL.

For Reference: https://developer.android.com/training/app-links/verify-site-associations.