@spheron/fnslib
TypeScript icon, indicating that this package has built-in type declarations

1.0.22 • Public • Published

Spheron

🧰 FNSlib is the ultimate solution for working with the FNS(.fil) on the FEVM chain. Powered by Spheron.
It is built with ethers.js at its core, and inspired by and modelled on the ENS Package.

NOTE!!!

🌟 Welcome to FNSlib 🌟

Our project is in the early development stage, meaning things might change.

But don't worry, we're actively seeking feedback! So if you see something that needs improvement, please don't hesitate to create an issue or PR. 🙌

Good news! FNSlib can already be used on both Filecoin Mainnet and Filecoin Hyperspace testnet networks. 🚀

Installation

You can find the FNS library in NPM package - https://www.npmjs.com/package/@spheron/fnslib

Using NPM

npm install @spheron/fnslib ethers

Using Yarn

yarn add @spheron/fnslib ethers

Getting Started

🚀 Ready to get started with FNSlib? 🚀

You only need to grab an 🌟 ethers provider instance 🌟 from https://filecoin-hyperspace.chainstacklabs.com/rpc/v1 (Testnet) or https://filecoin-mainnet.chainstacklabs.com/rpc/v1 (Mainnet).

Once you've got your hands on that, creating a new FNS instance is a breeze! Just pass it in using setProvider and you're good to go. 💪

Happy coding! 🤖👨‍💻👩‍💻

import { FNS } from '@spheron/fnslib'
import { ethers } from 'ethers'

const provider = new ethers.providers.JsonRpcProvider(providerUrl)

const FNSInstance = new FNS()
await FNSInstance.setProvider(provider)

NOTE: If using FNSlib with Node, you may need to pass the --experimental-specifier-resolution=node flag.

node --experimental-specifier-resolution=node ./index.js

Single-use Providers

If you want to use a specific provider to make a single call occasionally, you can easily do so.

import { FNS } from '@spheron/fnslib'

const FNSInstance = new FNS()

const callWithProvider = await FNSInstance.withProvider(otherProvider).getText(
  'juan.fil',
  'foo',
)

Name Availability

Check if a name is available to be registered on the FEVM Naming Service.

const name = 'juan.fil'
const isAvailable = await FNSInstance.getAvailable(name)

Price

View the current price of registering or updating a name on the FEVM Naming Service. The price is determined by market demand and is subject to change.

const name = 'juan.fil'
const price = await FNSInstance.getPrice(name, duration)

Expiration

View the timestamp in which a particular registered name will expire.

const name = 'juan.fil'
const price = await FNSInstance.getExpiry(name)

Profiles

You can fetch almost all information about an FNS name (or address) using getProfile. If an address is used as the first argument, it will fetch the primary name and give the same response as a name would. It will automatically get all the records for a name, as well as get the resolver address for the name. Specific records can also be used as an input, if you only want to get certain ones. If an address is used as an input alongside this, you also save 1 RPC call.

NOTE:
The profile function will always request an ETH addr record. For names, this means the address will always at the top level of the returned object. For addresses, this means the "match" property (a boolean value for matching reverse/forward resolution) will always be at the top level of the returned object. coinType is the cryptocurrency coin type index from SLIP44

/* Normal profile fetching */
const profile = await FNSInstance.getProfile('juan.fil')

Get Blockchain Address

🔍 Need to find the blockchain address associated with your FNS name and coinType? 🔍

Our handy function can help! Simply provide the node (FNS name) and coinType, and we'll return the associated blockchain address. If no address is found, don't worry - the function will return 0. 😎

At the moment, FNSlib supports BTC, LTC, DOGE, and native FIL, but we're always looking to add support for more major chains in the future.

If you have a specific request for a coinType, head to our 💬 discord channel and let us know. We're always considering new ideas for subsequent updates. 🚀

Our goal is to make FNSlib as comprehensive and user-friendly as possible, and we appreciate your feedback and suggestions. So don't hesitate to reach out and help us achieve this goal. 💪

Keep building something great. 🤖👨‍💻👩‍💻

enum BlockchainIdentifier {
  BITCOIN = 0,
  LITECOIN = 2,
  DOGECOIN = 3,
  FILCOIN = 4610,
  FILCOINEVM = 461,
}


/* For FIL Address - t410fkyutpa243vojf5klstpwld6twufgr3gv5rmsx5y */

const  address  =  await FNSInstance.getAddress('juan.fil', BlockchainIdentifier.FILCOIN)


/* For FIL(ETH) Address - 0x562937835cdD5C92F54B94Df658Fd3b50A68ecD5 */

const  address  =  await FNSInstance.getAddress('juan.fil', BlockchainIdentifier.FILCOINEVM)


/* For BTC - 3FZbgi29cpjq2GjdwV8eyHuJJnkLtktZc5 */

const  address  =  await FNSInstance.getAddress('juan.fil', BlockchainIdentifier.BITCOIN)


/* For LTC - MGxNPPB7eBoWPUaprtX9v9CXJZoD2465zN */
const  address  =  await FNSInstance.getAddress('juan.fil', BlockchainIdentifier.LITECOIN)

/* For DOGE - DLCDJhnh6aGotar6b182jpzbNEyXb3C361 */

const  address  =  await FNSInstance.getAddress('juan.fil', BlockchainIdentifier.DOGECOIN)

Normal content fetching

To get ipfs content hash attached to a fns name

The code block is used to fetch the content hash associated with a FNS name 'juan.fil'. The content hash is a unique identifier for the content associated with the FNS name.

The code uses the getContent function of the FNSInstance object to retrieve the content hash. The await keyword is used to wait for the content hash to be retrieved before assigning it to the contentHash variable.

Once the content hash is retrieved, it is returned as a string. In this case, the content hash is ipfs://QmZYmH5iDbD6v3U2ixoVAjioSzvWJszDzYdbeCLquGSpVm.

Overall, this code block demonstrates how to use the FNSlib to retrieve the content associated with a FNS name. It is a crucial feature of the FNSlib, enabling users to easily retrieve content associated with FNS names on the FEVM chain.

const contentHash = await FNSInstance.getContent('juan.fil')
/* ipfs://QmZYmH5iDbD6v3U2ixoVAjioSzvWJszDzYdbeCLquGSpVm */

FNS name fetching

The getNameNode function is used to retrieve the node associated with an address. The node variable will contain the node associated with the provided address. This node can then be used to retrieve the FNS name associated with it.

The getAddrName function takes a node as input and retrieves the FNS name associated with it. The name variable will contain the FNS name associated with the provided node.

Overall, this code block demonstrates how to use the FNSlib to retrieve the FNS name associated with an address on the FEVM chain. It is a useful feature that enables users to easily retrieve FNS names associated with specific addresses.

The code block below is used to retrieve the FNS name associated with an address on the FEVM chain. Here is an explanation of how it works:

const address = '0x562937835cdD5C92F54B94Df658Fd3b50A68ecD5'
const node = await FNSInstance.getNameNode(address)
const name = await FNSInstance.getAddrName(node)
/* juan.fil */

Profile fetching from an address

const profile = await FNSInstance.getProfile(
  '0x562937835cdD5C92F54B94Df658Fd3b50A68ecD5',
)

/* Get all records of a specific type (or multiple) */
const profile = await FNSInstance.getProfile('juan.fil', {
  texts: true,
  coinTypes: true,
  contentHash: true,
})

/* Get specific records */
const profile = await FNSInstance.getProfile('juan.fil', {
  texts: ['foo'],
  coinTypes: ['FIL'],
})

Returns:

type RecordItem = {
  key: string | number
  type: 'addr' | 'text' | 'contentHash'
  coin?: string
  addr?: string
  value?: string
}

type ProfileReturn = {
  address?: string // ONLY RETURNED AT TOP-LEVEL FOR NAME QUERIES
  name?: string // ONLY RETURNED AT TOP-LEVEL FOR ADDRESS QUERIES
  records: {
    contentHash?: ContentHashObject | null
    texts?: RecordItem[]
    coinTypes?: RecordItem[]
  }
  resolverAddress: string
}

Ownership Levels

The getOwner function returns not only an owner (and potentially a registrant), but also a ownershipLevel value. This value essentially means the contract for the "real owner" of any given name. In most cases it means the NFT contract of the name, but if there is no NFT then it's just the registry. This value is useful for input into the transferName function, where a contract needs to be specified.

Write Transaction Options

Currently, some write functions have an options argument. While this may expand over time, it currently just allows you to pass an address or index for an account array to ethers for specifying the signer of the transaction.

Register A Name

/* write operation to register name */
await FNSInstance.register('aromedev.fil', address, duration, { value: 2000 })
/* write operation to set record */
await FNSInstance.setRecord('arome.fil', {
  type: 'contentHash',
  record: ipfsHash,
  resolverAddress,
})

Internal Structure

Raw Functions

Raw functions are a crucial part of how FNSlib works. In the function file itself a raw and decode function both need to be defined, with the export being an object with those properties. This allows for the encoding and decoding of contract calls to be split, meaning that multiple calls can be batched together. For calling a raw function by itself, the raw and decode functions are stitched together with a provider call. This is done using importGenerator which is explained below.

importGenerator

The importGenerator function generates a wrapped function for any given input. The result of the wrapped function obfuscates the processing that FNSlib does, and exposes a cleaner API to the user/developer. The reason we do this is to:

  1. Pass through all the required variables for the function
  2. Split individual functions from the main class
  3. Dynamically load functions and their dependencies
  4. Allow each function's dependencies to be imported regularly
  5. Remove duplicate code
  6. Make it easier to isolate errors
  7. Stitch raw and decode functions together

ContractManager

The contract manager is where all the contracts are dynamically loaded in and resolved based on the network. A new instance of ContractManager is created every time you switch providers.

initialProvider

The initialProvider, and similarly checkInitialProvider are used when creating single-use class instances with withProvider. It allows withProvider to act as a new FNS instance without having to await a promise, which simplifies the API. checkInitialProvider is run on every function call given that it's extremely lightweight.

Individual Functions

Utils

Utils can be imported at follows import { encodeContenthash } from '@spheron/fnslib/utils/contentHash'

getName

Gets the primary name for a specified address.

Input:

  • address: string
    • Target address

Output:

  • name: string | null
    • Resolved name
  • match: boolean
    • Forward resolved match check value

getOwner

Gets the owner of a specified name. See ownership levels for more details about the output.

Input:

  • name: string
    • Target name

Output:

  • owner: string
    • Controller of records for name
  • registrant: string?
    • NFT Owner
  • ownershipLevel: string
    • Level at which the ownership data is being read

getProfile

Gets the profile of a specified name or address, or just certain records if specified.

Input:

  • nameOrAddress: string
    • Target name or address
  • options: object?
    • contentHash: boolean?
    • texts: boolean? | string[]?
      • Array of keys, or true for all keys
    • coinTypes: boolean? | string[]?
      • Array of keys, or true for all keys

Output:

  • resolverAddress: string
    • Address of resolver
  • records: object
    • matching records from input
    • contentHash: object? | null?
      • Decoded content hash
    • texts: array?
      • key: string
      • value: string
    • coinTypes: array?
      • key: number
      • coin: string
        • Coin name
      • value: string
        • Decoded address
  • name: string?
    • Only applicable for address inputs
    • Resolved name
  • address: string?
    • Only applicable for name inputs
    • Resolved address
  • match: boolean?
    • Only applicable for address inputs
    • Forward resolved match check value

getRecords

Gets all the records of a specified name, or just certain records if specified.

Input:

  • name: string
  • options: object?
    • contentHash: boolean?
    • texts: boolean? | string[]?
      • Array of keys, or true for all keys
    • coinTypes: boolean? | string[]?
      • Array of keys, or true for all keys

Output: see getProfile

getResolver

Gets the resolver for a specified name.

Input:

  • name: string
    • Target name

Output:

  • string
    • Resolver address

getContentHash

Gets the content hash record for a specified name.

Input:

  • name: string
    • Target name

Output:

  • object | null
    • Decoded content hash

getText

Gets a text record for a specified name.

Input:

  • name: string
    • Target name
  • key: string
    • Target key

Output:

  • string | null
    • Text record value

getAddr

Gets an address record for a specified name.

Input:

  • name: string
    • Target name
  • coinType: string? | number?
    • Target coin
    • Defaults to 60 (ETH) if undefined

Output:

  • string | null
    • Address record value

setName

Sets the primary name for a specified address.

Input:

  • name: string
    • Name to set
  • address: string?
    • Setting other primary names requires authorisation
    • Address to set name for
  • resolver: string?
    • Setting other primary names requires authorisation
    • Target resolver

Output:

  • transaction

setRecords

Sets multiple records at once for the specified name.

Input:

  • name: string
    • Target name
  • records: object
    • contentHash: string?
      • Formatted and encoded content hash
    • texts: array?
      • object
        • key: string
          • Text key
        • value: string
          • Text value
    • coinTypes: array?
      • object
        • key: string
          • Coin name or ID
        • value: string
          • Coin address

Output:

  • transaction

setResolver

Sets the resolver for the specified name, using the specified contract.

Input:

  • name: string
    • Target Name
  • contract: registry | nameWrapper
    • Target contract
  • resolver: string?
    • Leaving this undefined will use the default public resolver

Output:

  • transaction

transferName

Transfers a name, using the specified contract.

Input:

  • name: string
    • Target name
  • newOwner: string
    • Address to transfer name to
  • contract: registry | nameWrapper | baseRegistrar
    • Target contract

Output:

  • transaction

Contribution

We encourage you to read the contribution guidelines to learn about our development process and how to propose bug fixes and improvements before submitting a pull request.

The Spheron community extends beyond issues and pull requests! You can support Spheron in many other ways as well.

Community

For help, discussions or any other queries: Join us on Discord

Readme

Keywords

none

Package Sidebar

Install

npm i @spheron/fnslib

Weekly Downloads

1

Version

1.0.22

License

MIT

Unpacked Size

2.04 MB

Total Files

548

Last publish

Collaborators

  • izrake
  • abhinav-spheron
  • spheron-ilij4
  • spheron_dusanstanis
  • mitrasish