Unlock.js

An NPM module providing a wrapper around the Unlock smart contract ABI.

Unlock.js can be used both on server side (node.js) applications and front end applications.

Both the Unlock and the PublicLock contracts have been upgraded and support multiple versions. One of the core goals of the Unlock.js library is to provide an abstraction layer over these versions. In its default use, it also hides the complexity of dealing with Ethereum data formats as it yields (and accepts) values as base JavasScript types, such as strings, numbers or booleans.

Installing in A Project

npm i @unlock-protocol/unlock-js

The module provides 2 different classes: web3Service and walletService.

web3Service

web3Service provides a "read-only" API that lets app developers query Unlock's smart contracts (both Unlock and Locks).

walletService

walletService provides a mechanism to send transactions and sign messages for a user. walletService requires the use of a web3 provider which encapsulates the user's wallet information.

Examples

Using Web3Service to retrieve a lock's details:

const ethers = require("ethers");
const { Web3Service } = require("@unlock-protocol/unlock-js");

const networks = {
  4: {
    unlockAddress: "0xd8c88be5e8eb88e38e6ff5ce186d764676012b0b", // Smart contracts docs include all addresses on all networks
    provider: "https://rinkeby.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161",
  },
};

async function run() {
  const web3Service = new Web3Service(networks);

  // This lock exists on Rinkeby (you can create one from the dashboard if needed)
  const lockAddress = "0xF735257c43dB1723AAE2A46d71E467b1b8a8422A";

  const lock = await web3Service.getLock(lockAddress, 4);
  //   {
  //     asOf: 10094781,
  //     name: 'May 4th 2021',
  //     publicLockVersion: 8,
  //     maxNumberOfKeys: -1, // -1 means Infinite
  //     expirationDuration: 345600,
  //     keyPrice: '0.01',
  //     beneficiary: '0xDD8e2548da5A992A63aE5520C6bC92c37a2Bcc44',
  //     balance: '0.02',
  //     outstandingKeys: 11,
  //     currencyContractAddress: null
  //   }
}

run();

Using WalletService to deploy a lock:

const ethers = require("ethers");
const { WalletService } = require("@unlock-protocol/unlock-js");

const networks = {
  4: {
    unlockAddress: "0xd8c88be5e8eb88e38e6ff5ce186d764676012b0b", // Smart contracts docs include all addresses on all networks
    provider: "https://rinkeby.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161",
  },
};

// Initializing RPC provider and connect it to Rinkeby
const provider = new ethers.providers.JsonRpcProvider(networks[4].provider);

// Create a wallet.
// This one should have a little bit of rinkeby eth but please send more if you use it:
// 0x42fb30ae9694c45f76d98d01adf4103fc7b636a6
const wallet = new ethers.Wallet.fromMnemonic(
  "solid entry walnut extend aisle skirt myth clog need analyst edit bench"
).connect(provider);

async function run() {
  const walletService = new WalletService(networks);

  // Connect to a provider with a wallet
  await walletService.connect(provider, wallet);

  // This only resolves when the transaction has been mined, but the callback returns the hash immediately
  await walletService.createLock(
    {
      maxNumberOfKeys: 100,
      name: "testing silver",
      expirationDuration: 12121311,
      keyPrice: "0.01", // Key price needs to be a string
    },
    (error, hash) => {
      // This is the hash of the transaction!
      console.log({ hash });
    }
  );
}

run();

Using WalletService to purchase a key:

const ethers = require("ethers");
const { WalletService } = require("@unlock-protocol/unlock-js");

const networks = {
  4: {
    unlockAddress: "0xd8c88be5e8eb88e38e6ff5ce186d764676012b0b", // Smart contracts docs include all addresses on all networks
    provider: "https://rinkeby.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161",
  },
};

// Initializing RPC provider and connect it to Rinkeby
const provider = new ethers.providers.JsonRpcProvider(networks[4].provider);

// Create a wallet.
// This one should have a little bit of rinkeby eth but please send more if you use it:
// 0x42fb30ae9694c45f76d98d01adf4103fc7b636a6
const wallet = new ethers.Wallet.fromMnemonic(
  "solid entry walnut extend aisle skirt myth clog need analyst edit bench"
).connect(provider);

async function run() {
  const walletService = new WalletService(networks);

  // Connect to a provider with a wallet
  await walletService.connect(provider, wallet);

  // This lock exists on Rinkeby (you can create one from the dashboard if needed)
  const lockAddress = "0xF735257c43dB1723AAE2A46d71E467b1b8a8422A";

  // This only resolves when the transaction has been mined, but the callback returns the hash immediately
  await walletService.purchaseKey(
    {
      lockAddress,
    },
    (error, hash) => {
      // This is the hash of the transaction!
      console.log({ hash });
    }
  );
}

run();

The Integration test suite provides the most complete example of the supported actions:

  • Deploying a lock

  • Purchasing a key on the lock

  • Changing the locks params

  • Withdrawing from the lock

  • ... etc

Last updated