From 4483653524e3db7f04e71b48077ec608652af705 Mon Sep 17 00:00:00 2001 From: aulneau Date: Tue, 14 Dec 2021 07:55:52 -0600 Subject: [PATCH] fix: network fixes --- src/api/read-only/call-read-only-function.ts | 21 ++++++----- src/api/smartcontracts/fetchers.test.ts | 26 +++++++------- src/network/index.ts | 38 ++++++++++++-------- src/transactions/builders/builders.test.ts | 4 ++- 4 files changed, 51 insertions(+), 38 deletions(-) diff --git a/src/api/read-only/call-read-only-function.ts b/src/api/read-only/call-read-only-function.ts index 13eebcea..0a8fe00c 100644 --- a/src/api/read-only/call-read-only-function.ts +++ b/src/api/read-only/call-read-only-function.ts @@ -19,7 +19,7 @@ import type { ReadOnlyFunctionOptions, ReadOnlyFunctionResponse } from './types' */ export async function callReadOnlyFunction( options: ReadOnlyFunctionOptions -): Promise { +): Promise { const { contractName, contractAddress, @@ -28,16 +28,19 @@ export async function callReadOnlyFunction( senderAddress = contractAddress, } = options; - let isMainnet = true; - try { - isMainnet = isMainnetAddress(contractAddress); - } catch (e) { - throw new Error( - '[micro-stacks] callReadOnlyFunction -> Incorrect Stacks addressed passed to contractAddress' - ); + let network = options.network; + if (!options.network) { + try { + network = isMainnetAddress(contractAddress) ? new StacksMainnet() : new StacksTestnet(); + } catch (e) { + console.error(e); + throw new Error( + '[micro-stacks] callReadOnlyFunction -> Incorrect Stacks addressed passed to contractAddress' + ); + } } - const network = options.network || isMainnet ? new StacksMainnet() : new StacksTestnet(); + if (!network) throw Error('[micro-stacks] callReadOnlyFunction -> no network defined'); const url = network.getReadOnlyFunctionCallApiUrl(contractAddress, contractName, functionName); diff --git a/src/api/smartcontracts/fetchers.test.ts b/src/api/smartcontracts/fetchers.test.ts index e90f365b..e8d01f33 100644 --- a/src/api/smartcontracts/fetchers.test.ts +++ b/src/api/smartcontracts/fetchers.test.ts @@ -8,6 +8,7 @@ import * as TRANSACTION_EVENT_SMART_CONTRACT_LOG_200_RESPONSE from '../../../tes //import * as TRANSACTION_EVENT_FUNGIBLE_ASSET_200_RESPONSE from '../../../../tests/mocks/api/smartcontracts/TransactionEventFungibleAsset200.json'; //import * as TRANSACTION_EVENT_NON_FUNGIBLE_ASSET_200_RESPONSE from '../../../../tests/mocks/api/smartcontracts/TransactionEventNonFungibleAsset200.json'; import * as CONTRACT_SOURCE_200_RESPONSE from '../../../tests/mocks/api/smartcontracts/ContractSourceResponse200.json'; + const CONTRACT_DATA_MAP_ENTRY = { data: '0x0a0c000000010a6d6f6e737465722d69640100000000000000000000000000000001', proof: '0x123', @@ -19,7 +20,6 @@ import { fetchContractEventsById, fetchContractInterface, fetchContractSource, - fetchReadOnlyFunction, } from './fetchers'; import { contractEndpoint, contractsEndpoint, v2Endpoint } from '../utils'; import { HIRO_TESTNET_DEFAULT } from 'micro-stacks/network'; @@ -147,16 +147,16 @@ describe('smartcontracts fetchers', () => { }); // TODO: the spec returns 'null' - test(fetchReadOnlyFunction.name, async () => { - const args = { - url: HIRO_TESTNET_DEFAULT, - contractName: contract_name, - contractAddress: contract_address, - functionName: functionName, - functionArgs: functionArgs, - senderAddress: senderAddress, - }; - const data = await fetchReadOnlyFunction(args); - expect(data).toEqual({ body: null }); - }); + // test(callReadOnlyFunction.name, async () => { + // const args = { + // url: HIRO_TESTNET_DEFAULT, + // contractName: contract_name, + // contractAddress: contract_address, + // functionName: functionName, + // functionArgs: functionArgs, + // senderAddress: senderAddress, + // }; + // const data = await callReadOnlyFunction(args); + // expect(data).toEqual({ body: null }); + // }); }); diff --git a/src/network/index.ts b/src/network/index.ts index d36fd4f0..87c3280c 100644 --- a/src/network/index.ts +++ b/src/network/index.ts @@ -7,7 +7,10 @@ export const HIRO_TESTNET_DEFAULT = 'https://stacks-node-api.testnet.stacks.co'; export const HIRO_MOCKNET_DEFAULT = 'http://localhost:3999'; export interface NetworkConfig { - url: string; + // TODO: deprecate + url?: string; + coreApiUrl?: string; + bnsLookupUrl?: string; fetcher?: Fetcher; } @@ -55,12 +58,12 @@ export interface StacksNetwork { export class StacksMainnet implements StacksNetwork { version = TransactionVersion.Mainnet; chainId = ChainID.Mainnet; - bnsLookupUrl = 'https://stacks-node-api.mainnet.stacks.co'; broadcastEndpoint = '/v2/transactions'; transferFeeEstimateEndpoint = '/v2/fees/transfer'; accountEndpoint = '/v2/accounts'; contractAbiEndpoint = '/v2/contracts/interface'; readOnlyFunctionCallEndpoint = '/v2/contracts/call-read'; + bnsLookupUrl: string; private _coreApiUrl: string; private fetcher: Fetcher; @@ -73,47 +76,52 @@ export class StacksMainnet implements StacksNetwork { } constructor(networkConfig: NetworkConfig = { url: HIRO_MAINNET_DEFAULT }) { - this._coreApiUrl = networkConfig.url; + if (!networkConfig.url && !networkConfig.coreApiUrl) + throw Error('[miro-stacks] Network initialized with no api url'); + this._coreApiUrl = (networkConfig.url || networkConfig.coreApiUrl) as string; + this.bnsLookupUrl = (networkConfig.bnsLookupUrl || + networkConfig.url || + networkConfig.coreApiUrl) as string; this.fetcher = networkConfig.fetcher || fetchPrivate; } getCoreApiUrl = () => this._coreApiUrl; isMainnet = () => this.version === TransactionVersion.Mainnet; - getBroadcastApiUrl = () => `${this.coreApiUrl}${this.broadcastEndpoint}`; - getTransferFeeEstimateApiUrl = () => `${this.coreApiUrl}${this.transferFeeEstimateEndpoint}`; + getBroadcastApiUrl = () => `${this.getCoreApiUrl()}${this.broadcastEndpoint}`; + getTransferFeeEstimateApiUrl = () => `${this.getCoreApiUrl()}${this.transferFeeEstimateEndpoint}`; getAccountApiUrl = (address: string) => - `${this.coreApiUrl}${this.accountEndpoint}/${address}?proof=0`; + `${this.getCoreApiUrl()}${this.accountEndpoint}/${address}?proof=0`; getAbiApiUrl = (address: string, contract: string) => - `${this.coreApiUrl}${this.contractAbiEndpoint}/${address}/${contract}`; + `${this.getCoreApiUrl()}${this.contractAbiEndpoint}/${address}/${contract}`; getReadOnlyFunctionCallApiUrl = ( contractAddress: string, contractName: string, functionName: string ) => - `${this.coreApiUrl}${ + `${this.getCoreApiUrl()}${ this.readOnlyFunctionCallEndpoint }/${contractAddress}/${contractName}/${encodeURIComponent(functionName)}`; - getInfoUrl = () => `${this.coreApiUrl}/v2/info`; - getBlockTimeInfoUrl = () => `${this.coreApiUrl}/extended/v1/info/network_block_times`; - getPoxInfoUrl = () => `${this.coreApiUrl}/v2/pox`; + getInfoUrl = () => `${this.getCoreApiUrl()}/v2/info`; + getBlockTimeInfoUrl = () => `${this.getCoreApiUrl()}/extended/v1/info/network_block_times`; + getPoxInfoUrl = () => `${this.getCoreApiUrl()}/v2/pox`; getRewardsUrl = (address: string, options?: any) => { - let url = `${this.coreApiUrl}/extended/v1/burnchain/rewards/${address}`; + let url = `${this.getCoreApiUrl()}/extended/v1/burnchain/rewards/${address}`; if (options) { url = `${url}?limit=${options.limit}&offset=${options.offset}`; } return url; }; getRewardsTotalUrl = (address: string) => - `${this.coreApiUrl}/extended/v1/burnchain/rewards/${address}/total`; + `${this.getCoreApiUrl()}/extended/v1/burnchain/rewards/${address}/total`; getRewardHoldersUrl = (address: string, options?: any) => { - let url = `${this.coreApiUrl}/extended/v1/burnchain/reward_slot_holders/${address}`; + let url = `${this.getCoreApiUrl()}/extended/v1/burnchain/reward_slot_holders/${address}`; if (options) { url = `${url}?limit=${options.limit}&offset=${options.offset}`; } return url; }; getStackerInfoUrl = (contractAddress: string, contractName: string) => - `${this.coreApiUrl}${this.readOnlyFunctionCallEndpoint} + `${this.getCoreApiUrl()}${this.readOnlyFunctionCallEndpoint} ${contractAddress}/${contractName}/get-stacker-info`; getNameInfo(fullyQualifiedName: string) { diff --git a/src/transactions/builders/builders.test.ts b/src/transactions/builders/builders.test.ts index 357b3a97..5b30e5d1 100644 --- a/src/transactions/builders/builders.test.ts +++ b/src/transactions/builders/builders.test.ts @@ -1537,12 +1537,14 @@ describe('tx builders', function () { network, senderAddress, }; - fetchMock.mockOnce(`{"okay": true, "result": "0x${mockResult}"}`); const apiUrl = network.getReadOnlyFunctionCallApiUrl( contractAddress, contractName, functionName ); + + fetchMock.mockOnce(`{"okay": true, "result": "0x${mockResult}"}`, { url: apiUrl }); + const result = await callReadOnlyFunction(options); expect(fetchMock.mock.calls.length).toEqual(1); expect(fetchMock.mock.calls[0][0]).toEqual(apiUrl);