From d1494cdc66e1fb0a0ec0cf8c595e8b777433acdd Mon Sep 17 00:00:00 2001 From: Keefer Taylor Date: Wed, 9 Dec 2020 19:07:57 -0700 Subject: [PATCH 1/4] Add a function to retrieve a delegate --- src/chain/tezos/TezosNodeReader.ts | 34 ++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/src/chain/tezos/TezosNodeReader.ts b/src/chain/tezos/TezosNodeReader.ts index a11cca16..bf218265 100644 --- a/src/chain/tezos/TezosNodeReader.ts +++ b/src/chain/tezos/TezosNodeReader.ts @@ -37,6 +37,32 @@ export namespace TezosNodeReader { }); } + /** + * Gets the baker for a smart contract or an implicit account. + * + * @param {string} server Tezos node to query + * @param {stirng} address The smart contract address or implicit account to query. + */ + export async function getBaker(server: string, address: string): Promise { + const requestUrl = `"/chains/main/blocks/head/context/contracts/${address}/delegate"` + + try { + const delegate = await performGetRequest(server, requestUrl) + // Delegate is a string, even though `performGetRequest` purports to return an object. + return (delegate as unknown) as string + } catch (error: any) { + const tezosRequestError = error as TezosRequestError + + // Tezos returns a 404 if delegate is not set. + if (tezosRequestError.httpStatus === 404) { + return undefined + } + + // Otherwise, re-throw the error. + throw tezosRequestError + } + } + /** * Gets a block for a given hash. * @@ -46,7 +72,7 @@ export namespace TezosNodeReader { * @returns {Promise} Block */ export function getBlock(server: string, hash: string = 'head', chainid: string = 'main'): Promise { - return performGetRequest(server, `chains/${chainid}/blocks/${hash}`).then(json => { return json }); + return performGetRequest(server, `chains/${chainid}/blocks/${hash}`).then(json => { return json }); } /** @@ -70,7 +96,7 @@ export namespace TezosNodeReader { if (offset <= 0) { return getBlock(server); } const head = await getBlock(server); - return performGetRequest(server, `chains/${chainid}/blocks/${Number(head['header']['level']) - offset}`).then(json => { return json }); + return performGetRequest(server, `chains/${chainid}/blocks/${Number(head['header']['level']) - offset}`).then(json => { return json }); } /** @@ -84,7 +110,7 @@ export namespace TezosNodeReader { */ export function getAccountForBlock(server: string, blockHash: string, accountHash: string, chainid: string = 'main'): Promise { return performGetRequest(server, `chains/${chainid}/blocks/${blockHash}/context/contracts/${accountHash}`) - .then(json => json); + .then(json => json); } /** @@ -111,7 +137,7 @@ export namespace TezosNodeReader { */ export async function getSpendableBalanceForAccount(server: string, accountHash: string, chainid: string = 'main'): Promise { const account = await performGetRequest(server, `chains/${chainid}/blocks/head/context/contracts/${accountHash}`) // TODO: get /balance - .then(json => json); + .then(json => json); return parseInt(account.balance.toString(), 10); } From 2ae1d71c128eacbc3c6c07a1f7d939477876c373 Mon Sep 17 00:00:00 2001 From: Keefer Taylor Date: Wed, 9 Dec 2020 19:24:41 -0700 Subject: [PATCH 2/4] add integration tests --- .../chain/tezos/TezosNodeReader.spec.ts | 88 ++++++++++++------- src/chain/tezos/TezosNodeReader.ts | 4 +- 2 files changed, 60 insertions(+), 32 deletions(-) diff --git a/integration_test/chain/tezos/TezosNodeReader.spec.ts b/integration_test/chain/tezos/TezosNodeReader.spec.ts index 8e537825..65c5a035 100644 --- a/integration_test/chain/tezos/TezosNodeReader.spec.ts +++ b/integration_test/chain/tezos/TezosNodeReader.spec.ts @@ -10,54 +10,82 @@ import FetchSelector from '../../../src/utils/FetchSelector'; FetchSelector.setFetch(fetch); import { TezosNodeReader } from '../../../src/chain/tezos/TezosNodeReader'; -import { tezosServer, keys } from '../../TestAssets'; +// import { tezosServer, keys } from '../../TestAssets'; + +const tezosServer = "https://rpctest.tzbeta.net" describe('TezosNodeReader integration test suite', () => { - it('Get chain head', async () => { - const result = await TezosNodeReader.getBlockHead(tezosServer); + // it('Get chain head', async () => { + // const result = await TezosNodeReader.getBlockHead(tezosServer); - expect(result['header']['level']).to.be.greaterThan(1); - }); + // expect(result['header']['level']).to.be.greaterThan(1); + // }); - it('Get account counter', async () => { - const result = await TezosNodeReader.getCounterForAccount(tezosServer, keys.publicKeyHash); + // it('Get account counter', async () => { + // const result = await TezosNodeReader.getCounterForAccount(tezosServer, keys.publicKeyHash); - expect(result).to.be.greaterThan(1); - }); + // expect(result).to.be.greaterThan(1); + // }); - it('Get account reveal status', async () => { - const result = await TezosNodeReader.isManagerKeyRevealedForAccount(tezosServer, keys.publicKeyHash); + // it('Get account reveal status', async () => { + // const result = await TezosNodeReader.isManagerKeyRevealedForAccount(tezosServer, keys.publicKeyHash); - expect(result).to.be.true; - }); + // expect(result).to.be.true; + // }); - it('Get account manager key', async () => { - const result = await TezosNodeReader.getAccountManagerForBlock(tezosServer, 'head', keys.publicKeyHash); + // it('Get account manager key', async () => { + // const result = await TezosNodeReader.getAccountManagerForBlock(tezosServer, 'head', keys.publicKeyHash); - expect(result).to.be.equal(keys.publicKey); - }); + // expect(result).to.be.equal(keys.publicKey); + // }); - it('Get account info', async () => { - const result = await TezosNodeReader.getAccountForBlock(tezosServer, 'head', keys.publicKeyHash); + // it('Get account info', async () => { + // const result = await TezosNodeReader.getAccountForBlock(tezosServer, 'head', keys.publicKeyHash); - expect(parseInt(result.balance, 10)).to.be.greaterThan(10000); - }); + // expect(parseInt(result.balance, 10)).to.be.greaterThan(10000); + // }); + + // it('Get account spendable balance', async () => { + // const result = await TezosNodeReader.getSpendableBalanceForAccount(tezosServer, keys.publicKeyHash); - it('Get account spendable balance', async () => { - const result = await TezosNodeReader.getSpendableBalanceForAccount(tezosServer, keys.publicKeyHash); + // expect(result).to.be.greaterThan(10000); + // }); - expect(result).to.be.greaterThan(10000); + // it('Get account funding burn flag', async () => { + // const result = await TezosNodeReader.isImplicitAndEmpty(tezosServer, keys.publicKeyHash); + + // expect(result).to.be.false; + // }); + + // it('Get head', async () => { + // const result = await TezosNodeReader.getBlock(tezosServer); + + // expect(result.header.level).to.be.greaterThan(1); + // }); + + it('Gets delegate for a delegated implicit account', async () => { + const result = await TezosNodeReader.getBaker(tezosServer, "tz1PnUd6R31MnjEE8VhfZhZdbGc1hrWQvjnK"); + expect(result).to.not.be.undefined }); - it('Get account funding burn flag', async () => { - const result = await TezosNodeReader.isImplicitAndEmpty(tezosServer, keys.publicKeyHash); + it('Gets delegate for a delegated smart contract', async () => { + const result = await TezosNodeReader.getBaker(tezosServer, "KT1DRJPyaDTgeXrM2cgQdp5siNF8PP5RLS7T"); + expect(result).to.not.be.undefined + }); - expect(result).to.be.false; + it('Gets delegate for a baker as itself', async () => { + const baker = "tz1Na5QB98cDA3BC1SQU4w3iiWGVGktU14LE" + const result = await TezosNodeReader.getBaker(tezosServer, baker); + expect(result).to.be.equal(baker) }); - it('Get head', async () => { - const result = await TezosNodeReader.getBlock(tezosServer); + it('Returns undefined for undelegated implicit account', async () => { + const result = await TezosNodeReader.getBaker(tezosServer, "tz1fzHtv2UqtXzFUBHuBPh2xXVv5Pv5MTh5Z"); + expect(result).to.be.undefined + }); - expect(result.header.level).to.be.greaterThan(1); + it('Returns undefined for undelegated smart contract', async () => { + const result = await TezosNodeReader.getBaker(tezosServer, "KT1BipUDR93YFCJjVpghzVFS8N45Lkgigfqs"); + expect(result).to.be.undefined }); }); diff --git a/src/chain/tezos/TezosNodeReader.ts b/src/chain/tezos/TezosNodeReader.ts index bf218265..e2fd68a6 100644 --- a/src/chain/tezos/TezosNodeReader.ts +++ b/src/chain/tezos/TezosNodeReader.ts @@ -44,13 +44,13 @@ export namespace TezosNodeReader { * @param {stirng} address The smart contract address or implicit account to query. */ export async function getBaker(server: string, address: string): Promise { - const requestUrl = `"/chains/main/blocks/head/context/contracts/${address}/delegate"` + const requestUrl = `chains/main/blocks/head/context/contracts/${address}/delegate` try { const delegate = await performGetRequest(server, requestUrl) // Delegate is a string, even though `performGetRequest` purports to return an object. return (delegate as unknown) as string - } catch (error: any) { + } catch (error) { const tezosRequestError = error as TezosRequestError // Tezos returns a 404 if delegate is not set. From e128be6d377e9d65726f196226d95a16a1f63a91 Mon Sep 17 00:00:00 2001 From: Keefer Taylor Date: Wed, 9 Dec 2020 19:27:15 -0700 Subject: [PATCH 3/4] revert changes --- .../chain/tezos/TezosNodeReader.spec.ts | 68 +++++++++---------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/integration_test/chain/tezos/TezosNodeReader.spec.ts b/integration_test/chain/tezos/TezosNodeReader.spec.ts index 65c5a035..840d0fd8 100644 --- a/integration_test/chain/tezos/TezosNodeReader.spec.ts +++ b/integration_test/chain/tezos/TezosNodeReader.spec.ts @@ -10,58 +10,56 @@ import FetchSelector from '../../../src/utils/FetchSelector'; FetchSelector.setFetch(fetch); import { TezosNodeReader } from '../../../src/chain/tezos/TezosNodeReader'; -// import { tezosServer, keys } from '../../TestAssets'; - -const tezosServer = "https://rpctest.tzbeta.net" +import { tezosServer, keys } from '../../TestAssets'; describe('TezosNodeReader integration test suite', () => { - // it('Get chain head', async () => { - // const result = await TezosNodeReader.getBlockHead(tezosServer); + it('Get chain head', async () => { + const result = await TezosNodeReader.getBlockHead(tezosServer); - // expect(result['header']['level']).to.be.greaterThan(1); - // }); + expect(result['header']['level']).to.be.greaterThan(1); + }); - // it('Get account counter', async () => { - // const result = await TezosNodeReader.getCounterForAccount(tezosServer, keys.publicKeyHash); + it('Get account counter', async () => { + const result = await TezosNodeReader.getCounterForAccount(tezosServer, keys.publicKeyHash); - // expect(result).to.be.greaterThan(1); - // }); + expect(result).to.be.greaterThan(1); + }); - // it('Get account reveal status', async () => { - // const result = await TezosNodeReader.isManagerKeyRevealedForAccount(tezosServer, keys.publicKeyHash); + it('Get account reveal status', async () => { + const result = await TezosNodeReader.isManagerKeyRevealedForAccount(tezosServer, keys.publicKeyHash); - // expect(result).to.be.true; - // }); + expect(result).to.be.true; + }); - // it('Get account manager key', async () => { - // const result = await TezosNodeReader.getAccountManagerForBlock(tezosServer, 'head', keys.publicKeyHash); + it('Get account manager key', async () => { + const result = await TezosNodeReader.getAccountManagerForBlock(tezosServer, 'head', keys.publicKeyHash); - // expect(result).to.be.equal(keys.publicKey); - // }); + expect(result).to.be.equal(keys.publicKey); + }); - // it('Get account info', async () => { - // const result = await TezosNodeReader.getAccountForBlock(tezosServer, 'head', keys.publicKeyHash); + it('Get account info', async () => { + const result = await TezosNodeReader.getAccountForBlock(tezosServer, 'head', keys.publicKeyHash); - // expect(parseInt(result.balance, 10)).to.be.greaterThan(10000); - // }); + expect(parseInt(result.balance, 10)).to.be.greaterThan(10000); + }); - // it('Get account spendable balance', async () => { - // const result = await TezosNodeReader.getSpendableBalanceForAccount(tezosServer, keys.publicKeyHash); + it('Get account spendable balance', async () => { + const result = await TezosNodeReader.getSpendableBalanceForAccount(tezosServer, keys.publicKeyHash); - // expect(result).to.be.greaterThan(10000); - // }); + expect(result).to.be.greaterThan(10000); + }); - // it('Get account funding burn flag', async () => { - // const result = await TezosNodeReader.isImplicitAndEmpty(tezosServer, keys.publicKeyHash); + it('Get account funding burn flag', async () => { + const result = await TezosNodeReader.isImplicitAndEmpty(tezosServer, keys.publicKeyHash); - // expect(result).to.be.false; - // }); + expect(result).to.be.false; + }); - // it('Get head', async () => { - // const result = await TezosNodeReader.getBlock(tezosServer); + it('Get head', async () => { + const result = await TezosNodeReader.getBlock(tezosServer); - // expect(result.header.level).to.be.greaterThan(1); - // }); + expect(result.header.level).to.be.greaterThan(1); + }); it('Gets delegate for a delegated implicit account', async () => { const result = await TezosNodeReader.getBaker(tezosServer, "tz1PnUd6R31MnjEE8VhfZhZdbGc1hrWQvjnK"); From 1c9eabf8ae0583ddb9a6b429bf6c0e72ee9d201f Mon Sep 17 00:00:00 2001 From: Keefer Taylor Date: Wed, 9 Dec 2020 19:38:58 -0700 Subject: [PATCH 4/4] s/getBaker/getDelegate --- integration_test/chain/tezos/TezosNodeReader.spec.ts | 10 +++++----- src/chain/tezos/TezosNodeReader.ts | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/integration_test/chain/tezos/TezosNodeReader.spec.ts b/integration_test/chain/tezos/TezosNodeReader.spec.ts index 840d0fd8..4c9fcc35 100644 --- a/integration_test/chain/tezos/TezosNodeReader.spec.ts +++ b/integration_test/chain/tezos/TezosNodeReader.spec.ts @@ -62,28 +62,28 @@ describe('TezosNodeReader integration test suite', () => { }); it('Gets delegate for a delegated implicit account', async () => { - const result = await TezosNodeReader.getBaker(tezosServer, "tz1PnUd6R31MnjEE8VhfZhZdbGc1hrWQvjnK"); + const result = await TezosNodeReader.getDelegate(tezosServer, "tz1PnUd6R31MnjEE8VhfZhZdbGc1hrWQvjnK"); expect(result).to.not.be.undefined }); it('Gets delegate for a delegated smart contract', async () => { - const result = await TezosNodeReader.getBaker(tezosServer, "KT1DRJPyaDTgeXrM2cgQdp5siNF8PP5RLS7T"); + const result = await TezosNodeReader.getDelegate(tezosServer, "KT1DRJPyaDTgeXrM2cgQdp5siNF8PP5RLS7T"); expect(result).to.not.be.undefined }); it('Gets delegate for a baker as itself', async () => { const baker = "tz1Na5QB98cDA3BC1SQU4w3iiWGVGktU14LE" - const result = await TezosNodeReader.getBaker(tezosServer, baker); + const result = await TezosNodeReader.getDelegate(tezosServer, baker); expect(result).to.be.equal(baker) }); it('Returns undefined for undelegated implicit account', async () => { - const result = await TezosNodeReader.getBaker(tezosServer, "tz1fzHtv2UqtXzFUBHuBPh2xXVv5Pv5MTh5Z"); + const result = await TezosNodeReader.getDelegate(tezosServer, "tz1fzHtv2UqtXzFUBHuBPh2xXVv5Pv5MTh5Z"); expect(result).to.be.undefined }); it('Returns undefined for undelegated smart contract', async () => { - const result = await TezosNodeReader.getBaker(tezosServer, "KT1BipUDR93YFCJjVpghzVFS8N45Lkgigfqs"); + const result = await TezosNodeReader.getDelegate(tezosServer, "KT1BipUDR93YFCJjVpghzVFS8N45Lkgigfqs"); expect(result).to.be.undefined }); }); diff --git a/src/chain/tezos/TezosNodeReader.ts b/src/chain/tezos/TezosNodeReader.ts index e2fd68a6..975dfb86 100644 --- a/src/chain/tezos/TezosNodeReader.ts +++ b/src/chain/tezos/TezosNodeReader.ts @@ -38,12 +38,12 @@ export namespace TezosNodeReader { } /** - * Gets the baker for a smart contract or an implicit account. + * Gets the delegate for a smart contract or an implicit account. * * @param {string} server Tezos node to query * @param {stirng} address The smart contract address or implicit account to query. */ - export async function getBaker(server: string, address: string): Promise { + export async function getDelegate(server: string, address: string): Promise { const requestUrl = `chains/main/blocks/head/context/contracts/${address}/delegate` try {