2.1.0 • Published 2 years ago

near-wallet-selector v2.1.0

Weekly downloads
-
License
ISC
Repository
github
Last release
2 years ago

NEAR Wallet Selector

The NEAR Wallet Selector makes it easy for users to interact with your dApp. This package presents a modal to switch between a number of supported wallet types:

Preview

React, Vue and Angular variations of the Guest Book dApp can be found in the examples directory. You can use these to gain a concrete understanding of how to integrate near-wallet-selector into your own dApp.

Preview

Installation and Usage

The easiest way to use near-wallet-selector is to install it from the NPM registry:

# Using Yarn
yarn add near-wallet-selector

# Using NPM.
npm install near-wallet-selector

Then use it in your dApp:

import NearWalletSelector from "near-wallet-selector";

const selector = new NearWalletSelector({
  wallets: ["near-wallet", "sender-wallet", "ledger-wallet"],
  networkId: "testnet",
  contract: { contractId: "guest-book.testnet" },
});

Options

type BuiltInWalletId = "near-wallet" | "sender-wallet" | "ledger-wallet";
type NetworkId = "mainnet" | "betanet" | "testnet" | "customnet";
type Theme = "dark" | "light" | "auto";

interface NetworkConfiguration {
  networkId: string;
  nodeUrl: string;
  helperUrl: string;
  explorerUrl: string;
  restApiUrl: string;
}

interface Options {
  // List of wallets you want to support in your dApp.
  wallets: Array<BuiltInWalletId>;
  // Network ID matching that of your dApp.
  networkId: NetworkId;
  // Required when networkId is 'customnet'.
  network?: NetworkConfiguration;
  contract: {
    // Account ID of the Smart Contract used for 'view' and 'signAndSendTransaction' calls.
    contractId: string;
    // Optional: Specify limited access to particular methods on the Smart Contract.
    methodNames?: Array<string>;
  };
  ui?: {
    // Optional: Specify light/dark theme for UI. Defaults to the browser configuration when
    // omitted or set to 'auto'.
    theme?: Theme;
    // Optional: Provides customisation description text in the UI.
    description?: string;
  };
}

API Reference

.init()

Parameters

  • N/A

Returns

  • Promise<void>

Description

Initialises the selector using the configured options before rendering the UI. If a user has previously signed in, this method will also initialise the selected wallet, ready to handle transaction signing.

Example

await selector.init();

.show()

**Parameters**

  • N/A

Returns

  • void

Description

Opens the modal for users to sign in to their preferred wallet. You can also use this method to switch wallets.

Example

selector.show();

.hide()

Parameters

  • N/A

Returns

  • void

Description

Closes the modal.

Example

selector.hide();

.signIn(params)

Parameters

  • params (object)
    • walletId (string): ID of the wallet (see example for specific values).
    • accountId (string?): Required for hardware wallets (e.g. Ledger Wallet). This is the account ID related to the public key found at derivationPath.
    • derviationPath (string?): Required for hardware wallets (e.g. Ledger Wallet). This is the path to the public key on your device.

Returns

  • Promise<void>

Description

Programmatically sign in to a specific wallet without presenting the UI. Hardware wallets (e.g. Ledger Wallet) require accountId and derivationPath to validate access key permissions.

Example

// NEAR Wallet.
await selector.signIn({
  walletId: "near-wallet",
});

// Sender Wallet.
await selector.signIn({
  walletId: "sender-wallet",
});

// Ledger Wallet
await selector.signIn({
  walletId: "ledger-wallet",
  accountId: "account-id.testnet",
  derviationPath: "44'/397'/0'/0'/1'",
});

.signOut()

Parameters

  • N/A

Returns

  • Promise<void>

Description

Signs out of the selected wallet.

Example

await selector.signOut();

.isSignedIn()

Parameters

  • N/A

Returns

  • Promise<boolean>

Description

Determines whether the user is signed in.

Example

const signedIn = await selector.isSignedIn();
console.log(signedIn) // true

.getAccount()

Parameters

  • N/A

Returns

  • Promise<object | null>: Resolves to an object containing accountId and balance.

Description

Retrieves account information when the user is signed in. Returns null when the user is signed out.

Example

const account = await selector.getAccount();
console.log(account); // { accountId: "test.testnet", balance: "999999999999" }

.on(event, callback)

Parameters

  • event (string): Name of the event. This can be either signIn or signOut.
  • callback (() => void): Handler to be triggered when the event fires.

Returns

  • object
    • remove (() => void): Removes the event handler.

Description

Attach an event handler to important events.

Example

const subscription = selector.on("signIn", () => {
   console.log("User signed in!");
});

// Unsubscribe.
subscription.remove();

.off(event, callback)

Parameters

  • event (string): Name of the event. This can be either signIn or signOut.
  • callback (() => void): Original handler passed to .on(event, callback).

Returns

  • void

Description

Removes the event handler attached to the given event.

Example

const handleSignIn = () => {
  console.log("User signed in!");
}

selector.on("signIn", handleSignIn);
selector.off("signIn", handleSignIn);

.contract.getContractId()

Parameters

  • N/A

Returns

  • string

Description

Retrieves account ID of the configured Smart Contract.

Example

const contractId = selector.contract.getContractId();
console.log(contractId); // "guest-book.testnet"

.contract.view(params)

Parameters

  • params (object)
    • methodName (string): Name of the method on the Smart Contract.
    • args (object?): Object containing the parameters for the method.
    • finality (string?): Defaults to "optimistic". More details on this here.

Returns

  • Promise<unknown>

Description

Executes a view method on the Smart Contract. Sign in isn't required for these calls.

Example

await selector.contract.view({
  methodName: "getMessages"
});

.contract.signAndSendTransaction(params)

Parameters

  • params (object)
    • actions (Array<Action>)
      • type (string): Action type. See below for available values.
      • params (object?): Parameters for the Action (if applicable).

Returns

  • Promise<object>: More details on this can be found here.

Description

Signs one or more actions before sending to the network. The user must be signed in to call this method as there's at least charges for gas spent.

Note: Sender Wallet only supports "FunctionCall" action types right now. If you wish to use other NEAR Actions in your dApp, it's recommended to remove this wallet in your configuration.

Below are the 8 supported NEAR Actions:

export interface CreateAccountAction {
  type: "CreateAccount";
}

export interface DeployContractAction {
  type: "DeployContract";
  params: {
    code: Uint8Array;
  };
}

export interface FunctionCallAction {
  type: "FunctionCall";
  params: {
    methodName: string;
    args: object;
    gas: string;
    deposit: string;
  };
}

export interface TransferAction {
  type: "Transfer";
  params: {
    deposit: string;
  };
}

export interface StakeAction {
  type: "Stake";
  params: {
    stake: string;
    publicKey: string;
  };
}  

export interface AddKeyAction {
  type: "AddKey";
  params: {
    publicKey: string;
    accessKey: {
      nonce?: number;
      permission:
        | "FullAccess"
        | {
            receiverId: string;
            allowance?: string;
            methodNames?: Array<string>;
          };
    };
  };
}

export interface DeleteKeyAction {
  type: "DeleteKey";
  params: {
    publicKey: string;
  };
}

export interface DeleteAccountAction {
  type: "DeleteAccount";
  params: {
    beneficiaryId: string;
  };
}

Example

await selector.contract.signAndSendTransaction({
  actions: [{
    type: "FunctionCall",
    params: {
      methodName: "addMessage",
      args: { text: "Hello World!" },
      gas: "30000000000000",
      deposit: "10000000000000000000000",
    }
  }]
});

Known Issues

At the time of writing, there is an issue with Sender Wallet where the signed in state is lost when navigating back to a dApp you had previously signed in to - this includes browser refreshes.

Contributing

Contributors may find the examples directory useful as it provides a quick and consistent way to manually test new changes and/or bug fixes. Below is a common workflow you can use:

  • Execute yarn link in the root directory.
  • Navigate to the examples/{framework} directory.
  • Execute yarn link near-wallet-selector to create a symlink locally.
  • Execute yarn start

Editor Setup

This project uses ESLint (with Prettier) to enforce a consistent coding style. It's important that you configure your editor correctly to avoid issues when you're ready to open a Pull Request.

Although this project uses Prettier, it's simply an "internal" dependency to our ESLint configuration. This is because we want Prettier to handle code styling while avoiding conflicts with ESLint which specifically focuses on potentially problematic code. As a result, it's important that you switch off Prettier in your editor and ensure only ESLint is enabled.

License

This repository is distributed under the terms of both the MIT license and the Apache License (Version 2.0). See LICENSE-MIT and LICENSE-APACHE for details.