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

@avvy/client

v4.2.8

Published

The Avvy Domains Javascript client provides essential functionality for interacting with `.avax` domains.

Downloads

185

Readme

Introduction

The Avvy Domains Javascript client provides essential functionality for interacting with .avax domains.

Installation

npm i --save @avvy/client 

Usage

Quick start

Forward Resolution

Turn a .avax name into an EVM / C-Chain address:

import AVVY from '@avvy/client'
import { ethers } from 'ethers'

const main = async () => {
  const PROVIDER_URL = 'https://api.avax.network/ext/bc/C/rpc'
  const provider = new ethers.providers.JsonRpcProvider(PROVIDER_URL)
  const avvy = new AVVY(provider)
  const address = await avvy.name('avvydomains.avax').resolve(AVVY.RECORDS.EVM)
  console.log(address)
}

main()

Reverse Resolution

Turn an EVM / C-Chain address into a .avax name:

import AVVY from '@avvy/client'
import { ethers } from 'ethers'

const main = async () => {
  const PROVIDER_URL = 'https://api.avax.network/ext/bc/C/rpc'
  const provider = new ethers.providers.JsonRpcProvider(PROVIDER_URL)
  const avvy = new AVVY(provider)
  const hash = await avvy.reverse(AVVY.RECORDS.EVM, '0x9BC4e7C1Fa4Ca66f6B2F4B6F446Dad80Ec541983')
  const name = await hash.lookup()
  console.log(name.name) // 'avvydomains.avax'
}

main()

Given an ERC721 token ID, retrieve the associated .avax name via reverse resolution

import AVVY from '@avvy/client'
import { ethers } from 'ethers'

const main = async () => {
  const PROVIDER_URL = 'https://api.avax.network/ext/bc/C/rpc'
  const provider = new ethers.providers.JsonRpcProvider(PROVIDER_URL)
  const avvy = new AVVY(provider)
  const tokenId = '6020961683474433630417776251679104264796158969684372136738248890876527059923'
  const hash = avvy.hash(tokenId)
  const name = await hash.lookup()
  console.log(name.name) // 'avvydomains.avax'
}

main()

Fetching User's Domains

To retrieve domains for a given user's wallet, do the following:

import AVVY from '@avvy/client'
import { ethers } from 'ethers'

const main = async () => {
  const PROVIDER_URL = 'https://api.avax.network/ext/bc/C/rpc'
  const provider = new ethers.providers.JsonRpcProvider(PROVIDER_URL)
  const avvy = new AVVY(provider)

  // to fetch the hashes held in the wallet
  const domainHashes = await avvy.wallet('0x9BC4e7C1Fa4Ca66f6B2F4B6F446Dad80Ec541983').domains()

  // to fetch the plaintext of the hashes
  const domainNames = await avvy.batch(domainHashes).lookup()
}

main()

Batch Operations

Batch operations rely on multicall by default.

To reverse resolve a batch of EVM addresses:

const hashes = await avvy.batch([
  '0x...',
  '0x...',
  ...
]).reverse(avvy.RECORDS.EVM)

To convert a batch of hashes into .avax names:

const names = await avvy.batch(hashes).lookup()

To convert EVM addresses to names in one RPC call:

const names = await avvy.batch([
  '0x...',
  '0x...',
  ...
]).reverseToNames(avvy.RECORDS.EVM)

If the operation fails to produce a result for an item in the batch, the result will be null.

Batch Operations via JSON-RPC 2.0

You can optionally run each operation individually at the EVM level, but leverage JSON-RPC 2.0's batch operations. This requires a JSON RPC endpoint, and can be configured as follows:

const avvy = new AVVY(provider, {
  batchJsonRpc: '<JSON_RPC_URL>',
  fetchJson: ethers.utils.fetchJson
})

Provider Support

The Avvy client can be configured to support methods from ethers.js for interacting with naming systems.

ethers.js Configuration

Default configuration for chainId 43114:

const provider = new AVVY.providers.ethersProvider(
  new ethers.providers.JsonRpcProvider(PROVIDER_URL)
)

CommonJS Import

To import AVVY via require, use:

const AVVY = require('@avvy/client/index.cjs')

IMPORTANT: XSS / Code Injection Risk

The client does not perform any validation or sanitization of resolved values. Integrators should assume all values retrieved from .resolve() are untrusted and potentially malicious.

Forward Resolution & Record Types

avvy.name('avvydomains.avax').resolve(key) is the method to perform forward resolution. key can be:

  • An integer, indicating a standard record. A full list of standard records is available in JSON format via AVVY.RECORDS._LIST, or at https://github.com/avvydomains/client-common/blob/master/records/records.json.
  • A string, indicating a custom record. Users can choose arbitrary strings to store data on domains as they see fit.

Name hashes & input signals

Names exist as hashes on-chain. If a user registers a name with Enhanced Privacy, the preimage of the hash is not published to the chain. If a user registers a name with Standard Privacy, the preimage of the hash is published to the chain and can be used to go from hash to name.

  • To convert a name into a hash, use const hash = await avvy.utils.nameHash('name.avax')
  • To convert a hash into a name, use const name = await avvy.hash(hash).lookup() - this will only work if the user registered the name with Standard Privacy

The preimage of the hash is stored as an array of large integers which can be input directly into the Poseidon hashing algorithm. We call this form of the preimage the input signals.

  • To convert a name to input signals, use inputSignals = avvy.utils.encodeNameHashInputSignals('name.avax')
  • To convert input signals t oa name, use name = avvy.utils.decodeNameHashInputSignals(inputSignals)

Resolver & reverse resolver contracts require uint256 name, uint256[] memory path arguments. You can generate those arguments using:

const { name, path } = await avvy.utils.generateNameAndPath

Poseidon Hash Function

This package uses a smart contract to perform hashing calculations. For Enhanced Privacy users, this means that the preimage of the domain gets leaked to the RPC node. For applications, this means that each hash calculation is a network call. We cache the results to reduce the number of network calls.

Integrators can optionally perform the hashing locally by configuring the package as follows:

  1. Install circomlibjs: npm i circomlibjs
  2. Instantiate the Avvy client:
import { buildPoseidon } from 'circomlibjs/src/poseidon_wasm.js'

// ...

const poseidon = await buildPoseidon()
const avvy = new AVVY(provider, {
  poseidon: async (args) => {
    return poseidon.F.toObject(poseidon(args))
  }
})

Accessing contracts directly

import AVVY from '@avvy/client'
import { ethers } from 'ethers'

const main = async () => {
  const PROVIDER_URL = 'https://api.avax.network/ext/bc/C/rpc'
  const provider = new ethers.providers.JsonRpcProvider(PROVIDER_URL)
  const avvy = new AVVY(provider)

  // contracts are available here as ethers.Contract instances
  const contracts = await avvy.contracts
}

main()

Development

Building

npm run build generates files in ./lib from the dependencies in ./client-common.

Environment variables

  • AVVY_CLIENT_COMMON. All client libraries depend on a repository called client-common. By default, the project is added as a git submodule, and builds use the production version of client-common. If you're working locally, you might want to use a local development version of client-common. You can provide an absolute path to the development version using this environment variable.

Non-mainnet chains

To connect the client to non-mainnet chains:

  1. Make sure that the client-common library has contracts for the chain ID you want to connect to
  2. Initialize using const avvy = new AVVY(provider, { chainId: 31337 }) (substitute 31337 with your chainId)