@avvy/client
TypeScript icon, indicating that this package has built-in type declarations

4.2.8 • Public • Published

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:

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)

Versions

Current Tags

  • Version
    Downloads (Last 7 Days)
    • Tag
  • 4.2.8
    20
    • latest

Version History

Package Sidebar

Install

npm i @avvy/client

Weekly Downloads

103

Version

4.2.8

License

ISC

Unpacked Size

577 kB

Total Files

23

Last publish

Collaborators

  • connorbode