Skip to content

Commit

Permalink
fix handling for parseInt
Browse files Browse the repository at this point in the history
  • Loading branch information
jac18281828 committed Dec 7, 2022
1 parent 5a4d23c commit 51dacf5
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 20 deletions.
91 changes: 90 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,90 @@
# governance
# Collective Governance TypeScript API

### Installation

### npm

```
$ npm install @momentranks/governance
```

#### Yarn

```
$ yarn add @momentranks/governance
```

#### Usage

Connect an existing Governance contract from the builder address and build transaction id

```
import {
Wallet,
EthWallet,
Storage,
Governance,
Meta,
GovernanceBuilder,
CollectiveGovernance,
MetaStorage,
CollectiveStorage,
} from '@momentranks/governance';
import Web3 from 'web3';
export interface Collective {
governance: Governance;
storage: Storage;
meta: Meta;
web3: Web3;
wallet: Wallet;
}
export async function connect(): Promise<Collective> {
try {
const rpcUrl = 'wss://localhost:8545';
const privateKey = 'XXXXXXXXXXXX';
const abiPath = 'node_modules/@momentranks/governance/abi';
const builderAddress = '0xd64f3Db037B263D54561a2cc9885Db370B51E354';
const maximumGas = 10000000;
const buildTransaction = '0x0f7f3e13055547b8b6ac5b28285abc960266c6297094ab451ca9de318cbf5906';
const web3 = new Web3(rpcUrl);
const wallet = new EthWallet(privateKey, web3);
wallet.connect();
const builder = new GovernanceBuilder(abiPath, builderAddress, web3, wallet, maximumGas);
const contractAddress = await builder.discoverContractAddress(buildTransaction);
const governance = new CollectiveGovernance(abiPath, contractAddress.governanceAddress, web3, wallet, maximumGas);
const name = await governance.name();
const version = await governance.version();
const metaAddress = contractAddress.metaAddress;
const meta = new MetaStorage(abiPath, metaAddress, web3);
const metaName = await meta.name();
const metaVersion = await meta.version();
if (version !== metaVersion) {
throw new Error('MetaStorage version mismatch');
}
const community = await meta.community();
console.log(`Community: ${community}`);
const communityUrl = await meta.url();
console.log(`Community Url: ${communityUrl}`);
const description = await meta.description();
console.log(`Description: ${description}`);
const storageAddress = contractAddress.storageAddress;
const storage = new CollectiveStorage(abiPath, storageAddress, web3);
const storageVersion = await storage.version();
if (version != storageVersion) {
throw new Error('Storage version mismatch');
}
return { governance, storage, meta, web3, wallet };
} catch (error) {
throw new Error('Run failed');
}
}
```
10 changes: 10 additions & 0 deletions governance/__test__/version.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { parseIntOrThrow } from '../version';

describe('parseIntOrThrow', () => {
it('must parse a proper number', () => {
expect(parseIntOrThrow('110571')).toBe(110571);
});
it('must throw if not a number', () => {
expect(() => parseIntOrThrow('')).toThrow();
});
});
16 changes: 13 additions & 3 deletions governance/collectivegovernance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ export class CollectiveGovernance implements Governance {

async version(): Promise<number> {
const version = await this.contract.methods.version().call();
return parseInt(version);
const v = parseInt(version);
if (v) {
return v;
}
throw new Error('Version is not a number');
}

async propose(): Promise<number> {
Expand Down Expand Up @@ -141,7 +145,10 @@ export class CollectiveGovernance implements Governance {
this.logger.info(tx);
const event: EventData = tx.events['ProposalMeta'];
const metaId = parseInt(event.returnValues['metaId']);
return metaId;
if (metaId) {
return metaId;
}
throw new Error('Metadata Id is not a number');
}

async attachTransaction(
Expand All @@ -162,7 +169,10 @@ export class CollectiveGovernance implements Governance {
this.logger.info(attachTx);
const event: EventData = attachTx.events['ProposalTransactionAttached'];
const transactionId = parseInt(event.returnValues['transactionId']);
return transactionId;
if (transactionId) {
return transactionId;
}
throw new Error('Transaction id is not a number');
}

async configure(proposalId: number, quorum: number): Promise<void> {
Expand Down
34 changes: 20 additions & 14 deletions governance/collectivestorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import Web3 from 'web3';
import { ContractAbi } from './contractabi';
import { Storage } from './storage';
import { parseIntOrThrow } from './version';

export class CollectiveStorage extends ContractAbi implements Storage {
static ABI_NAME = 'Storage.json';
Expand All @@ -49,42 +50,42 @@ export class CollectiveStorage extends ContractAbi implements Storage {

async version(): Promise<number> {
const version = await this.contract.methods.version().call();
return parseInt(version);
return parseIntOrThrow(version);
}

async quorumRequired(proposalId: number): Promise<number> {
const quorum = await this.contract.methods.quorumRequired(proposalId).call();
return parseInt(quorum);
return parseIntOrThrow(quorum);
}

async voteDelay(proposalId: number): Promise<number> {
const delay = await this.contract.methods.voteDelay(proposalId).call();
return parseInt(delay);
return parseIntOrThrow(delay);
}

async voteDuration(proposalId: number): Promise<number> {
const duration = await this.contract.methods.voteDuration(proposalId).call();
return parseInt(duration);
return parseIntOrThrow(duration);
}

async startTime(proposalId: number): Promise<number> {
const timeStr = await this.contract.methods.startTime(proposalId).call();
return parseInt(timeStr);
return parseIntOrThrow(timeStr);
}

async endTime(proposalId: number): Promise<number> {
const timeStr = await this.contract.methods.endTime(proposalId).call();
return parseInt(timeStr);
return parseIntOrThrow(timeStr);
}

async getWinningChoice(proposalId: number): Promise<number> {
const choiceNum = await this.contract.methods.getWinningChoice(proposalId).call();
return parseInt(choiceNum);
return parseIntOrThrow(choiceNum);
}

async choiceCount(proposalId: number): Promise<number> {
const choiceCount = await this.contract.methods.choiceCount(proposalId).call();
return parseInt(choiceCount);
return parseIntOrThrow(choiceCount);
}

async getChoice(
Expand All @@ -93,11 +94,16 @@ export class CollectiveStorage extends ContractAbi implements Storage {
): Promise<{ name: string; description: string; transactionId: number; voteCount: number }> {
const metaData = await this.contract.methods.getChoice(proposalId, choiceId).call();
const decodedName = this.web3.utils.hexToAscii(metaData[0]);
return {
name: decodedName,
description: metaData[1],
transactionId: parseInt(metaData[2]),
voteCount: parseInt(metaData[3]),
};
const transactionId = parseIntOrThrow(metaData[2]);
const voteCount = parseIntOrThrow(metaData[3]);
if (transactionId && voteCount) {
return {
name: decodedName,
description: metaData[1],
transactionId: transactionId,
voteCount: voteCount,
};
}
throw new Error('Choice returned invalid data');
}
}
6 changes: 5 additions & 1 deletion governance/metastorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ export class MetaStorage extends ContractAbi implements Meta {

async version(): Promise<number> {
const version = await this.contract.methods.version().call();
return parseInt(version);
const v = parseInt(version);
if (v) {
return v;
}
throw new Error('Version is not a number');
}

async community(): Promise<string> {
Expand Down
40 changes: 40 additions & 0 deletions governance/version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: BSD-3-Clause
/*
* BSD 3-Clause License
*
* Copyright (c) 2022, collective
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

export function parseIntOrThrow(num: string): number {
const n = parseInt(num);
if (n) {
return n;
}
throw new Error(`${num} is not a number`);
}
6 changes: 5 additions & 1 deletion system/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ export async function blocktimeNow(web3: Web3): Promise<number> {
const blockNumber = await web3.eth.getBlockNumber();
const block = await web3.eth.getBlock(blockNumber);
if (typeof block.timestamp === 'string') {
return parseInt(block.timestamp);
const ts = parseInt(block.timestamp);
if (ts) {
return ts;
}
throw new Error('Timestamp is not a number');
}
return block.timestamp;
}

0 comments on commit 51dacf5

Please sign in to comment.