diff --git a/src/constants.ts b/src/constants.ts index 067d2fa..f834ef0 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -3,3 +3,4 @@ export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; // contracts interfaces export const ADDR_INTERFACE = '0x3b3b57de'; export const ERC165_INTERFACE = '0x01ffc9a7'; +export const CHAIN_ADDR_INTERFACE = '0x8be4b5f6'; diff --git a/src/errors.ts b/src/errors.ts index 6615436..0a231e4 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -3,3 +3,5 @@ export const NO_ADDR_RESOLUTION = 'KB002: No addr resolution'; export const NO_RESOLVER = 'KB003: No resolver'; export const LIBRARY_NOT_COMPOSED = 'KB004: Library not composed'; export const NO_ADDRESSES_PROVIDED = 'KB005: No contract addresses provided'; +export const NO_CHAIN_ADDR_RESOLUTION = 'KB006: No chain address resolution'; +export const NO_CHAIN_ADDR_RESOLUTION_SET = 'KB007: No chain address resolution set'; diff --git a/src/factories/index.ts b/src/factories/index.ts index 2fed091..ba0242d 100644 --- a/src/factories/index.ts +++ b/src/factories/index.ts @@ -1,5 +1,6 @@ import RNSRegistryData from '@rsksmart/rns-registry/RNSRegistryData.json'; import AddrResolverData from '@rsksmart/rns-resolver/AddrResolverData.json'; +import ChainAddrResolverData from '@rsksmart/rns-resolver/ChainAddrResolverData.json'; import Web3 from 'web3'; import { AbiItem } from 'web3-utils'; import { NetworkId } from '../types'; @@ -22,3 +23,5 @@ export const createContractAddresses = (networkId: NetworkId) => { export const createRegistry = (web3: Web3, address: string) => new web3.eth.Contract(RNSRegistryData.abi as AbiItem[], address) export const createAddrResolver = (web3: Web3, address: string) => new web3.eth.Contract(AddrResolverData.abi as AbiItem[], address) + +export const createChainAddrResolver = (web3: Web3, address: string) => new web3.eth.Contract(ChainAddrResolverData.abi as AbiItem[], address) diff --git a/src/index.ts b/src/index.ts index b7c93cb..2abab51 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,14 +1,14 @@ import Web3 from 'web3/types'; -import { Contract } from 'web3-eth-contract/types'; -import { RNS, Contracts, Options, ContractAddresses } from './types'; -import { hash as namehash } from 'eth-ens-namehash'; -import { createRegistry, createAddrResolver, createContractAddresses } from './factories'; -import { NO_ADDR_RESOLUTION, NO_ADDR_RESOLUTION_SET, NO_RESOLVER, LIBRARY_NOT_COMPOSED } from './errors'; -import { ZERO_ADDRESS, ADDR_INTERFACE, ERC165_INTERFACE } from './constants'; +import { RNS, Contracts, Options, ContractAddresses, ChainId } from './types'; +import { createRegistry, createContractAddresses } from './factories'; +import { LIBRARY_NOT_COMPOSED } from './errors'; +import Resolutions from './resolutions'; export default class implements RNS { - private _contracts!: Contracts - private _contractAddresses!: ContractAddresses + private _contracts!: Contracts; + private _contractAddresses!: ContractAddresses; + private _resolutionHelper!: Resolutions; + private _composed!: boolean; constructor (public web3: Web3, options?: Options) { if(options && options.contractAddresses) { @@ -24,7 +24,11 @@ export default class implements RNS { } public async compose(): Promise { - await this._detectNetwork() + if (!this._composed) { + await this._detectNetwork(); + this._resolutionHelper = new Resolutions(this.web3, this._contracts.registry); + this._composed = true; + } } private async _detectNetwork() { @@ -40,39 +44,12 @@ export default class implements RNS { } } - private async _hasMethod(contractAddress: string, signatureHash: string) { - const code = await this.web3.eth.getCode(contractAddress); - return code.indexOf(signatureHash.slice(2, signatureHash.length)) > 0; - } - - async addr(domain: string): Promise { - await this._detectNetwork(); - - const node: string = namehash(domain); - - const resolverAddress: string = await this._contracts.registry.methods.resolver(node).call(); - - if (resolverAddress === ZERO_ADDRESS) { - throw new Error(NO_RESOLVER); - } - const isErc165Contract = await this._hasMethod(resolverAddress, ERC165_INTERFACE); - if (!isErc165Contract) { - throw new Error(NO_ADDR_RESOLUTION); + async addr(domain: string, chainId?: ChainId): Promise { + await this.compose(); + if (!chainId) { + return this._resolutionHelper.addr(domain); + } else { + return this._resolutionHelper.chainAddr(domain, chainId); } - - const addrResolver: Contract = createAddrResolver(this.web3, resolverAddress); - - const supportsAddr: boolean = await addrResolver.methods.supportsInterface(ADDR_INTERFACE).call(); - if (!supportsAddr) { - throw new Error(NO_ADDR_RESOLUTION); - } - - const addr: string = await addrResolver.methods.addr(node).call(); - - if (addr === ZERO_ADDRESS){ - throw new Error(NO_ADDR_RESOLUTION_SET); - } - - return addr; } } diff --git a/src/resolutions.ts b/src/resolutions.ts new file mode 100644 index 0000000..a260498 --- /dev/null +++ b/src/resolutions.ts @@ -0,0 +1,69 @@ +import Web3 from 'web3/types'; +import { Contract } from 'web3-eth-contract/types'; +import { hash as namehash } from 'eth-ens-namehash'; +import { hasMethod } from './utils'; +import { createAddrResolver, createChainAddrResolver } from './factories'; +import { + NO_ADDR_RESOLUTION, NO_ADDR_RESOLUTION_SET, NO_RESOLVER, + NO_CHAIN_ADDR_RESOLUTION, NO_CHAIN_ADDR_RESOLUTION_SET +} from './errors'; +import { ZERO_ADDRESS, ADDR_INTERFACE, ERC165_INTERFACE, CHAIN_ADDR_INTERFACE } from './constants'; +import { ChainId, Resolutions } from './types'; + +export default class implements Resolutions { + constructor(private web3: Web3, private registry: Contract) { } + + private async _createResolver( + node: string, + methodInterface: string, + errorMessage: string, + contractFactory: (web3: Web3, address: string) => Contract + ): Promise { + const resolverAddress: string = await this.registry.methods.resolver(node).call(); + + if (resolverAddress === ZERO_ADDRESS) { + throw new Error(NO_RESOLVER); + } + + const isErc165Contract = await hasMethod(this.web3, resolverAddress, ERC165_INTERFACE); + if (!isErc165Contract) { + throw new Error(errorMessage); + } + + const resolver: Contract = contractFactory(this.web3, resolverAddress); + + const supportsInterface: boolean = await resolver.methods.supportsInterface(methodInterface).call(); + if (!supportsInterface) { + throw new Error(errorMessage); + } + + return resolver; + } + + async addr(domain: string): Promise { + const node: string = namehash(domain); + + const resolver = await this._createResolver(node, ADDR_INTERFACE, NO_ADDR_RESOLUTION, createAddrResolver); + + const addr: string = await resolver.methods.addr(node).call(); + + if (addr === ZERO_ADDRESS){ + throw new Error(NO_ADDR_RESOLUTION_SET); + } + + return addr; + } + + async chainAddr(domain: string, chainId: ChainId) { + const node: string = namehash(domain); + + const resolver = await this._createResolver(node, CHAIN_ADDR_INTERFACE, NO_CHAIN_ADDR_RESOLUTION, createChainAddrResolver); + + const addr: string = await resolver.methods.chainAddr(node, chainId).call(); + if (!addr || addr === ZERO_ADDRESS){ + throw new Error(NO_CHAIN_ADDR_RESOLUTION_SET); + } + + return addr; + } +} diff --git a/src/types.ts b/src/types.ts index 676441b..911406d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -6,6 +6,13 @@ export enum NetworkId { RSK_TESTNET = 31 } +export enum ChainId { + RSK_MAINNET = '0x80000089', + BITCOIN_MAINNET = '0x80000000', + ETHEREUM_MAINNET = '0x8000003c', + LITECOIN = '0x80000002' +} + export interface ContractAddresses { registry: string } @@ -22,5 +29,10 @@ export interface RNS { web3: Web3 contracts: Contracts compose(): void + addr(domain: string, chainId?: ChainId): Promise +} + +export interface Resolutions { addr(domain: string): Promise + chainAddr(domain: string, chainId: ChainId): Promise } diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..0f9a203 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,6 @@ +import Web3 from "web3"; + +export const hasMethod = async(web3: Web3, contractAddress: string, signatureHash: string) => { + const code = await web3.eth.getCode(contractAddress); + return code.indexOf(signatureHash.slice(2, signatureHash.length)) > 0; +} diff --git a/test/rns.addr.test.ts b/test/rns.addr.test.ts new file mode 100644 index 0000000..a962c32 --- /dev/null +++ b/test/rns.addr.test.ts @@ -0,0 +1,98 @@ +import Web3 from 'web3'; +import RNS from '../src/index'; +import { NO_ADDR_RESOLUTION_SET, NO_RESOLVER, NO_ADDR_RESOLUTION } from '../src/errors'; +import { asyncExpectThrowError } from './utils'; + +const PUBLIC_NODE_MAINNET = 'https://public-node.rsk.co'; +const PUBLIC_NODE_TESTNET = 'https://public-node.testnet.rsk.co'; + +describe ('addr resolution', () => { + describe ('should resolve a name', () => { + test('mainnet', async () => { + const web3 = new Web3(PUBLIC_NODE_MAINNET); + const rns = new RNS(web3); + const addr = await rns.addr('testing.rsk'); + expect(addr).toBe('0x0000000000000000000000000000000001000006'); + }); + + test('testnet', async () => { + const web3 = new Web3(PUBLIC_NODE_TESTNET); + const rns = new RNS(web3); + const addr = await rns.addr('testing.rsk'); + expect(addr).toBe('0x0000000000000000000000000000000001000006'); + }); + }); + + describe ('should throw an error when resolver has not been set', () => { + test('mainnet', async () => { + const web3 = new Web3(PUBLIC_NODE_MAINNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('noresolver.testing.rsk'), NO_RESOLVER); + }); + + test('testnet', async () => { + const web3 = new Web3(PUBLIC_NODE_TESTNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('noresolver.testing.rsk'), NO_RESOLVER); + }); + }); + + describe ('should throw an error when resolver does not support addr interface', () => { + describe ('ERC165 contract as resolver that not implements addr method', () => { + // the resolver address is the NameResolver contract. Is an ERC165 that not supports addr interface + test('mainnet', async () => { + const web3 = new Web3(PUBLIC_NODE_MAINNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('noaddrresolver.testing.rsk'), NO_ADDR_RESOLUTION); + }); + + test('testnet with another ERC165 as resolver', async () => { + const web3 = new Web3(PUBLIC_NODE_TESTNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('noaddrresolver.testing.rsk'), NO_ADDR_RESOLUTION); + }); + }); + + describe('non contract address as a resolver', () => { + test('mainnet', async () => { + const web3 = new Web3(PUBLIC_NODE_MAINNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('accountasresolver.testing.rsk'), NO_ADDR_RESOLUTION); + }); + + test('testnet', async () => { + const web3 = new Web3(PUBLIC_NODE_TESTNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('accountasresolver.testing.rsk'), NO_ADDR_RESOLUTION); + }); + }); + }); + + describe ('should throw an error when no resolution set', () => { + test('mainnet', async () => { + const web3 = new Web3(PUBLIC_NODE_MAINNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('noresolution.testing.rsk'), NO_ADDR_RESOLUTION_SET); + }); + + test('testnet', async () => { + const web3 = new Web3(PUBLIC_NODE_TESTNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('noresolution.testing.rsk'), NO_ADDR_RESOLUTION_SET); + }); + }); + + describe ('should throw an error when domain do not exist', () => { + test('mainnet', async () => { + const web3 = new Web3(PUBLIC_NODE_MAINNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('noexist.testing.rsk'), NO_RESOLVER); + }); + + test('testnet', async () => { + const web3 = new Web3(PUBLIC_NODE_TESTNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('noexist.testing.rsk'), NO_RESOLVER); + }); + }); +}); diff --git a/test/rns.chainAddr.test.ts b/test/rns.chainAddr.test.ts new file mode 100644 index 0000000..1a043c1 --- /dev/null +++ b/test/rns.chainAddr.test.ts @@ -0,0 +1,115 @@ +import Web3 from 'web3'; +import RNS from '../src/index'; +import { NO_CHAIN_ADDR_RESOLUTION, NO_RESOLVER, NO_CHAIN_ADDR_RESOLUTION_SET } from '../src/errors'; +import { asyncExpectThrowError } from './utils'; +import { ChainId } from '../src/types'; + +const PUBLIC_NODE_MAINNET = 'https://public-node.rsk.co'; +const PUBLIC_NODE_TESTNET = 'https://public-node.testnet.rsk.co'; + +describe ('chainAddr resolution', () => { + describe ('should resolve a name for BTC', () => { + test('mainnet', async () => { + const web3 = new Web3(PUBLIC_NODE_MAINNET); + const rns = new RNS(web3); + const addr = await rns.addr('multichain.testing.rsk', ChainId.BITCOIN_MAINNET); + expect(addr).toBe('1Ftu4C8VW18RkB8PZxXwwHocMLyEynLcrG'); + }); + + test('testnet', async () => { + const web3 = new Web3(PUBLIC_NODE_TESTNET); + const rns = new RNS(web3); + const addr = await rns.addr('multichain.testing.rsk', ChainId.BITCOIN_MAINNET); + expect(addr).toBe('1Ftu4C8VW18RkB8PZxXwwHocMLyEynLcrG'); + }); + }); + + describe ('should resolve a name for ETH', () => { + test('mainnet', async () => { + const web3 = new Web3(PUBLIC_NODE_MAINNET); + const rns = new RNS(web3); + const addr = await rns.addr('multichain.testing.rsk', ChainId.ETHEREUM_MAINNET); + expect(addr).toBe('0x0000000000000000000000000000000001000006'); + }); + + test('testnet', async () => { + const web3 = new Web3(PUBLIC_NODE_TESTNET); + const rns = new RNS(web3); + const addr = await rns.addr('multichain.testing.rsk', ChainId.ETHEREUM_MAINNET); + expect(addr).toBe('0x0000000000000000000000000000000001000006'); + }); + }); + + describe ('should throw an error when resolver has not been set', () => { + test('mainnet', async () => { + const web3 = new Web3(PUBLIC_NODE_MAINNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('noresolver.multichain.testing.rsk', ChainId.BITCOIN_MAINNET), NO_RESOLVER); + }); + + test('testnet', async () => { + const web3 = new Web3(PUBLIC_NODE_TESTNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('noresolver.multichain.testing.rsk', ChainId.BITCOIN_MAINNET), NO_RESOLVER); + }); + }); + + describe ('should throw an error when resolver does not support chain addr interface', () => { + describe ('ERC165 contract as resolver that not implements addr method', () => { + // the resolver address is the NameResolver contract. Is an ERC165 that not supports addr interface + test('mainnet', async () => { + const web3 = new Web3(PUBLIC_NODE_MAINNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('nochainaddrresolver.multichain.testing.rsk', ChainId.BITCOIN_MAINNET), NO_CHAIN_ADDR_RESOLUTION); + }); + + test('testnet with another ERC165 as resolver', async () => { + const web3 = new Web3(PUBLIC_NODE_TESTNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('nochainaddrresolver.multichain.testing.rsk', ChainId.BITCOIN_MAINNET), NO_CHAIN_ADDR_RESOLUTION); + }); + }); + + describe('non contract address as a resolver', () => { + test('mainnet', async () => { + const web3 = new Web3(PUBLIC_NODE_MAINNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('accountasresolver.multichain.testing.rsk', ChainId.BITCOIN_MAINNET), NO_CHAIN_ADDR_RESOLUTION); + }); + + test('testnet', async () => { + const web3 = new Web3(PUBLIC_NODE_TESTNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('accountasresolver.multichain.testing.rsk', ChainId.BITCOIN_MAINNET), NO_CHAIN_ADDR_RESOLUTION); + }); + }); + }); + + describe ('should throw an error when no resolution set', () => { + test('mainnet', async () => { + const web3 = new Web3(PUBLIC_NODE_MAINNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('noresolution.multichain.testing.rsk', ChainId.BITCOIN_MAINNET), NO_CHAIN_ADDR_RESOLUTION_SET); + }); + + test('testnet', async () => { + const web3 = new Web3(PUBLIC_NODE_TESTNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('noresolution.multichain.testing.rsk', ChainId.BITCOIN_MAINNET), NO_CHAIN_ADDR_RESOLUTION_SET); + }); + }); + + describe ('should throw an error when domain do not exist', () => { + test('mainnet', async () => { + const web3 = new Web3(PUBLIC_NODE_MAINNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('noexist.multichain.testing.rsk', ChainId.BITCOIN_MAINNET), NO_RESOLVER); + }); + + test('testnet', async () => { + const web3 = new Web3(PUBLIC_NODE_TESTNET); + const rns = new RNS(web3); + await asyncExpectThrowError(async () => await rns.addr('noexist.multichain.testing.rsk', ChainId.BITCOIN_MAINNET), NO_RESOLVER); + }); + }); +}); diff --git a/test/rns.resolution.test.ts b/test/rns.resolution.test.ts deleted file mode 100644 index b5c5e5a..0000000 --- a/test/rns.resolution.test.ts +++ /dev/null @@ -1,96 +0,0 @@ -import Web3 from 'web3'; -import RNS from '../src/index'; -import { NO_ADDR_RESOLUTION_SET, NO_RESOLVER, NO_ADDR_RESOLUTION } from '../src/errors'; -import { asyncExpectThrowError } from './utils'; - -const PUBLIC_NODE_MAINNET = 'https://public-node.rsk.co'; -const PUBLIC_NODE_TESTNET = 'https://public-node.testnet.rsk.co'; - -describe ('should resolve a name', () => { - test('mainnet', async () => { - const web3 = new Web3(PUBLIC_NODE_MAINNET); - const rns = new RNS(web3); - const addr = await rns.addr('testing.rsk'); - expect(addr).toBe('0x0000000000000000000000000000000001000006'); - }); - - test('testnet', async () => { - const web3 = new Web3(PUBLIC_NODE_TESTNET); - const rns = new RNS(web3); - const addr = await rns.addr('testing.rsk'); - expect(addr).toBe('0x0000000000000000000000000000000001000006'); - }); -}); - -describe ('should throw an error when resolver has not been set', () => { - test('mainnet', async () => { - const web3 = new Web3(PUBLIC_NODE_MAINNET); - const rns = new RNS(web3); - await asyncExpectThrowError(async () => await rns.addr('noresolver.testing.rsk'), NO_RESOLVER); - }); - - test('testnet', async () => { - const web3 = new Web3(PUBLIC_NODE_TESTNET); - const rns = new RNS(web3); - await asyncExpectThrowError(async () => await rns.addr('noresolver.testing.rsk'), NO_RESOLVER); - }); -}); - -describe ('should throw an error when resolver does not support addr interface', () => { - describe ('ERC165 contract as resolver that not implements addr method', () => { - // the resolver address is the NameResolver contract. Is an ERC165 that not supports addr interface - test('mainnet', async () => { - const web3 = new Web3(PUBLIC_NODE_MAINNET); - const rns = new RNS(web3); - await asyncExpectThrowError(async () => await rns.addr('noaddrresolver.testing.rsk'), NO_ADDR_RESOLUTION); - }); - - test('testnet with another ERC165 as resolver', async () => { - const web3 = new Web3(PUBLIC_NODE_TESTNET); - const rns = new RNS(web3); - await asyncExpectThrowError(async () => await rns.addr('noaddrresolver.testing.rsk'), NO_ADDR_RESOLUTION); - }); - }); - - describe('non contract address as a resolver', () => { - test('mainnet', async () => { - const web3 = new Web3(PUBLIC_NODE_MAINNET); - const rns = new RNS(web3); - await asyncExpectThrowError(async () => await rns.addr('accountasresolver.testing.rsk'), NO_ADDR_RESOLUTION); - }); - - test('testnet', async () => { - const web3 = new Web3(PUBLIC_NODE_TESTNET); - const rns = new RNS(web3); - await asyncExpectThrowError(async () => await rns.addr('accountasresolver.testing.rsk'), NO_ADDR_RESOLUTION); - }); - }); -}); - -describe ('should throw an error when no resolution set', () => { - test('mainnet', async () => { - const web3 = new Web3(PUBLIC_NODE_MAINNET); - const rns = new RNS(web3); - await asyncExpectThrowError(async () => await rns.addr('noresolution.testing.rsk'), NO_ADDR_RESOLUTION_SET); - }); - - test('testnet', async () => { - const web3 = new Web3(PUBLIC_NODE_TESTNET); - const rns = new RNS(web3); - await asyncExpectThrowError(async () => await rns.addr('noresolution.testing.rsk'), NO_ADDR_RESOLUTION_SET); - }); -}); - -describe ('should throw an error when domain do not exist', () => { - test('mainnet', async () => { - const web3 = new Web3(PUBLIC_NODE_MAINNET); - const rns = new RNS(web3); - await asyncExpectThrowError(async () => await rns.addr('noexist.testing.rsk'), NO_RESOLVER); - }); - - test('testnet', async () => { - const web3 = new Web3(PUBLIC_NODE_TESTNET); - const rns = new RNS(web3); - await asyncExpectThrowError(async () => await rns.addr('noexist.testing.rsk'), NO_RESOLVER); - }); -}); diff --git a/test/rns.setup.test.ts b/test/rns.setup.test.ts index 3b21d62..468fd60 100644 --- a/test/rns.setup.test.ts +++ b/test/rns.setup.test.ts @@ -7,85 +7,85 @@ import { asyncExpectThrowError } from './utils'; const PUBLIC_NODE_MAINNET = 'https://public-node.rsk.co'; const PUBLIC_NODE_TESTNET = 'https://public-node.testnet.rsk.co'; -describe('should set custom address if provided', () => { - const registryAddress = '0x0000000000000000000000000000000000000001'; - const options = { - contractAddresses: { registry: registryAddress } - }; +describe('library setup', () => { + describe('should set custom address if provided', () => { + const registryAddress = '0x0000000000000000000000000000000000000001'; + const options = { + contractAddresses: { registry: registryAddress } + }; - test('mainnet', async () => { - const web3 = new Web3(PUBLIC_NODE_MAINNET) - const rns = new RNS(web3, options) - await rns.compose() - expect(rns.contracts.registry.options.address.toLowerCase()).toBe(registryAddress); - }) + test('mainnet', async () => { + const web3 = new Web3(PUBLIC_NODE_MAINNET) + const rns = new RNS(web3, options) + await rns.compose() + expect(rns.contracts.registry.options.address.toLowerCase()).toBe(registryAddress); + }) - test('testnet', async () => { - const web3 = new Web3(PUBLIC_NODE_TESTNET); - const rns = new RNS(web3, options); - await rns.compose() - expect(rns.contracts.registry.options.address.toLowerCase()).toBe(registryAddress) - }) -}); + test('testnet', async () => { + const web3 = new Web3(PUBLIC_NODE_TESTNET); + const rns = new RNS(web3, options); + await rns.compose() + expect(rns.contracts.registry.options.address.toLowerCase()).toBe(registryAddress) + }) + }); -describe('should return registry address after compose', () => { - test('mainnet', async () => { - const web3 = new Web3(PUBLIC_NODE_MAINNET) - const rns = new RNS(web3) - await rns.compose() - expect(rns.contracts.registry.options.address.toLowerCase()).toBe(RNSRegistryData.address.rskMainnet) - }) + describe('should return registry address after compose', () => { + test('mainnet', async () => { + const web3 = new Web3(PUBLIC_NODE_MAINNET) + const rns = new RNS(web3) + await rns.compose() + expect(rns.contracts.registry.options.address.toLowerCase()).toBe(RNSRegistryData.address.rskMainnet) + }) - test('testnet', async () => { - const web3 = new Web3(PUBLIC_NODE_TESTNET); - const rns = new RNS(web3); - await rns.compose() - expect(rns.contracts.registry.options.address.toLowerCase()).toBe(RNSRegistryData.address.rskTestnet) - }) -}); - -describe('should fail when getting contracts if library not composed', () => { - test('mainnet', () => { - const web3 = new Web3(PUBLIC_NODE_MAINNET); - const rns = new RNS(web3); - let error; - try { - rns.contracts; - } catch (_error) { - error = _error.message; - } finally { - expect(error).toBe(LIBRARY_NOT_COMPOSED); - }; + test('testnet', async () => { + const web3 = new Web3(PUBLIC_NODE_TESTNET); + const rns = new RNS(web3); + await rns.compose() + expect(rns.contracts.registry.options.address.toLowerCase()).toBe(RNSRegistryData.address.rskTestnet) + }) }); - test('testnet', () => { - const web3 = new Web3(PUBLIC_NODE_TESTNET) - const rns = new RNS(web3) - let error; - try { - rns.contracts; - } catch (_error) { - error = _error.message; - } finally { - expect(error).toBe(LIBRARY_NOT_COMPOSED); - }; - }); -}); + describe('should fail when getting contracts if library not composed', () => { + test('mainnet', () => { + const web3 = new Web3(PUBLIC_NODE_MAINNET); + const rns = new RNS(web3); + let error; + try { + rns.contracts; + } catch (_error) { + error = _error.message; + } finally { + expect(error).toBe(LIBRARY_NOT_COMPOSED); + }; + }); -describe('should fail when compose if invalid network', () => { - it('', async () => { - const web3 = new Web3('https://invalid.rsk.co') - const rns = new RNS(web3) - await asyncExpectThrowError(async () => await rns.compose()); + test('testnet', () => { + const web3 = new Web3(PUBLIC_NODE_TESTNET) + const rns = new RNS(web3) + let error; + try { + rns.contracts; + } catch (_error) { + error = _error.message; + } finally { + expect(error).toBe(LIBRARY_NOT_COMPOSED); + }; + }); }); -}); - -// describe('should fail when compose if custom network and no addresses provided', () => { -// it('', async () => { -// const web3 = new Web3('http://localhost:7545') -// const rns = new RNS(web3) -// await asyncExpectThrowError(async () => await rns.compose(), NO_ADDRESSES_PROVIDED); -// }); -// }); + describe('should fail when compose if invalid network', () => { + it('', async () => { + const web3 = new Web3('https://invalid.rsk.co') + const rns = new RNS(web3) + await asyncExpectThrowError(async () => await rns.compose()); + }); + }); + // describe('should fail when compose if custom network and no addresses provided', () => { + // it('', async () => { + // const web3 = new Web3('http://localhost:7545') + // const rns = new RNS(web3) + // await asyncExpectThrowError(async () => await rns.compose(), NO_ADDRESSES_PROVIDED); + // }); + // }); +});