Skip to content

Commit

Permalink
resolve merge conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
allenan committed Jul 2, 2020
2 parents 7e11547 + fa21ebe commit d47bd1b
Show file tree
Hide file tree
Showing 20 changed files with 624 additions and 375 deletions.
8 changes: 4 additions & 4 deletions integration_tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"test": "jest"
},
"dependencies": {
"@helium/crypto": "^0.0.25",
"@helium/http": "^0.0.25",
"@helium/transactions": "^0.0.25"
"@helium/crypto": "^0.0.27",
"@helium/http": "^0.0.27",
"@helium/transactions": "^0.0.27"
},
"version": "0.0.25"
"version": "0.0.27"
}
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"integration_tests",
"packages/*"
],
"version": "0.0.25",
"version": "0.0.27",
"npmClient": "yarn"
}
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,18 @@
]
},
"devDependencies": {
"@types/jest": "26.0.0",
"@typescript-eslint/eslint-plugin": "3.3.0",
"@types/jest": "26.0.3",
"@typescript-eslint/eslint-plugin": "3.5.0",
"coveralls": "3.1.0",
"eslint-config-airbnb-typescript": "8.0.2",
"eslint-plugin-import": "2.21.2",
"jest": "26.0.1",
"eslint-plugin-import": "2.22.0",
"jest": "26.1.0",
"lerna": "3.22.1",
"nock": "12.0.3",
"nock": "13.0.0",
"prettier-standard": "16.3.0",
"rimraf": "3.0.2",
"standard": "14.3.4",
"ts-jest": "26.1.0",
"ts-jest": "26.1.1",
"typescript": "3.9.5"
}
}
2 changes: 1 addition & 1 deletion packages/crypto-react-native/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@helium/crypto-react-native",
"version": "0.0.25",
"version": "0.0.27",
"description": "Cryptography utilities including mnemonics, keypairs and base58-check encoding for React Native",
"keywords": [
"helium",
Expand Down
2 changes: 1 addition & 1 deletion packages/crypto/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@helium/crypto",
"version": "0.0.25",
"version": "0.0.27",
"description": "Cryptography utilities including mnemonics, keypairs and base58-check encoding",
"keywords": [
"helium",
Expand Down
19 changes: 19 additions & 0 deletions packages/http/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ await client.accounts.get('an-account-address')
await client.accounts.list()
```

##### Get an Accounts Stats

```js
await client.accounts.getStats('an-account-address')
```

#### Blocks
##### Get a Block

Expand Down Expand Up @@ -157,3 +163,16 @@ const pendingTxns = await list.take(10)
pendingTxns //= [PendingTransacion]
```

#### Election Groups

##### Get an Election Group

```js
await client.elections.get('hash')
```

##### List Election Groups
```js
const list = await client.elections.list()
const elections = await list.take(10)
```
2 changes: 1 addition & 1 deletion packages/http/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@helium/http",
"version": "0.0.25",
"version": "0.0.27",
"description": "HTTP library for interacting with the Helium blockchain API",
"keywords": [
"helium",
Expand Down
9 changes: 7 additions & 2 deletions packages/http/src/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import PendingTransactions from './resources/PendingTransactions'
import type Account from './models/Account'
import type Block from './models/Block'
import type Hotspot from './models/Hotspot'
import Elections from './resources/Elections'

interface AccountFromAddressFn {
(address: string): Account
Expand All @@ -33,8 +34,8 @@ export default class Client {

constructor(network: Network = Network.production) {
this.network = network
this.axios = axios.create({
baseURL: this.network.endpoint,
this.axios = axios.create({
baseURL: this.network.endpoint,
})
this.axios.defaults.raxConfig = {
instance: this.axios,
Expand Down Expand Up @@ -68,6 +69,10 @@ export default class Client {
return new Hotspots(this)
}

public get elections(): Elections {
return new Elections(this)
}

public get hotspot(): HotspotFromAddressFn {
return this.hotspots.fromAddress.bind(this.hotspots)
}
Expand Down
37 changes: 37 additions & 0 deletions packages/http/src/models/Account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,43 @@ function toBalance(value: number | undefined, type: CurrencyType): Balance | und
return new Balance(value, type)
}

export interface HTTPStatsObject {
last_week: Array<HTTPTimelineStats>
last_month: Array<HTTPTimelineStats>
last_day: Array<HTTPTimelineStats>
}

export interface HTTPTimelineStats {
timestamp: string
balance: number
}

export interface TimelineStats {
timestamp: string
balance?: Balance
}

export class AccountStats {
constructor(data: HTTPStatsObject) {
this.lastWeek = data.last_week.map((s) => ({
timestamp: s.timestamp,
balance: toBalance(s.balance, CurrencyType.default),
}))
this.lastMonth = data.last_month.map((s) => ({
timestamp: s.timestamp,
balance: toBalance(s.balance, CurrencyType.default),
}))
this.lastDay = data.last_day.map((s) => ({
timestamp: s.timestamp,
balance: toBalance(s.balance, CurrencyType.default),
}))
}

public lastWeek: Array<TimelineStats>
public lastMonth: Array<TimelineStats>
public lastDay: Array<TimelineStats>
}

export default class Account {
private client: Client
public speculativeNonce?: number
Expand Down
5 changes: 4 additions & 1 deletion packages/http/src/models/Balance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ const DC_TO_USD_MULTIPLIER = 0.00001

export default class Balance {
public integerBalance: number
public floatBalance: number
public type: CurrencyType
public bigBalance: BigNumber

constructor(integerBalance: number | undefined, type: CurrencyType) {
this.integerBalance = Math.round(integerBalance || 0)
this.integerBalance = integerBalance || 0
this.bigBalance = new BigNumber(this.integerBalance)
this.floatBalance = this.bigBalance.times(type.coefficient).toNumber()
this.type = type
this.bigBalance = new BigNumber(this.integerBalance).times(type.coefficient)
}
Expand Down
9 changes: 9 additions & 0 deletions packages/http/src/models/Election.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default interface Election {
type: string
time: number
proof: string
members: Array<string>
height: number
hash: string
delay: number
}
3 changes: 3 additions & 0 deletions packages/http/src/models/Hotspot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface HTTPHotspotObject {
lng?: number
lat?: number
block?: number
block_added?: number
geocode?: HTTPGeocodeObject
address: string
status?: Status
Expand Down Expand Up @@ -59,6 +60,7 @@ export default class Hotspot {
public address: string
public status?: Status
public nonce?: number
public blockAdded?: number

constructor(client: Client, hotspot: HTTPHotspotObject) {
this.client = client
Expand All @@ -72,6 +74,7 @@ export default class Hotspot {
this.block = hotspot.block
this.status = hotspot.status
this.nonce = hotspot.nonce
this.blockAdded = hotspot.block_added
if (hotspot.geocode) {
this.geocode = camelcaseKeys(hotspot.geocode) as any
}
Expand Down
14 changes: 14 additions & 0 deletions packages/http/src/models/__tests__/Balance.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
import Balance from '../Balance'
import CurrencyType from '../CurrencyType'

describe('floatBalance', () => {
it('returns a float based on the currency type', () => {
const balance = new Balance(123456789012, CurrencyType.default)
expect(balance.floatBalance).toBe(1234.56789012)
})
})

describe('integerBalance', () => {
it('returns the integer balance', () => {
const balance = new Balance(123456789012, CurrencyType.default)
expect(balance.integerBalance).toBe(123456789012)
})
})

describe('toString', () => {
it('handles numbers with a large amount of decimal places', () => {
const balance = new Balance(1, CurrencyType.default)
Expand Down
8 changes: 7 additions & 1 deletion packages/http/src/resources/Accounts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type Client from '../Client'
import Account from '../models/Account'
import Account, { AccountStats } from '../models/Account'
import type { HTTPAccountObject } from '../models/Account'
import ResourceList from '../ResourceList'

Expand Down Expand Up @@ -31,4 +31,10 @@ export default class Accounts {
const { data: { data: account } } = await this.client.get(url)
return new Account(this.client, account)
}

async getStats(address: string): Promise<AccountStats> {
const url = `/accounts/${address}/stats`
const { data: { data: stats } } = await this.client.get(url)
return new AccountStats(stats)
}
}
29 changes: 29 additions & 0 deletions packages/http/src/resources/Elections.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type Client from '../Client'
import ResourceList from '../ResourceList'
import Election from '../models/Election'

interface ListParams {
cursor?: string
}

export default class Elections {
private client!: Client

constructor(client: Client) {
this.client = client
}

async list(params: ListParams = {}): Promise<ResourceList<Election>> {
const url = '/elections'
const response = await this.client.get(url, { cursor: params.cursor })
const { data: { data: elections, cursor } } = response
return new ResourceList(elections, this.list.bind(this), cursor)
}

async get(hash: string): Promise<Election> {
// using transactions api for lookup, there is no /elections/hash endpoint
const url = `/transactions/${hash}`
const { data: { data: election } } = await this.client.get(url)
return election
}
}
2 changes: 1 addition & 1 deletion packages/http/src/resources/Stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ export default class Stats {
async get(): Promise<any> {
const url = `/stats`
const { data: { data: stats } } = await this.client.get(url)
return camelcaseKeys(stats)
return camelcaseKeys(stats, { deep: true })
}
}
35 changes: 35 additions & 0 deletions packages/http/src/resources/__tests__/Accounts.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,27 @@ const accountFixture = (params = {}) => ({
...params,
})

const accountStatsFixture = (params = {}) => ({
last_week: [
{
timestamp: '2020-06-30T00:00:00.000000Z',
balance: 1,
},
],
last_month: [
{
timestamp: '2020-06-30T00:00:00.000000Z',
balance: 1,
},
{
timestamp: '2020-06-29T16:00:00.000000Z',
balance: 2,
},
],
last_day: [],
...params,
})

describe('get', () => {
nock('https://api.helium.io').get('/v1/accounts/my-address').reply(200, {
data: accountFixture(),
Expand All @@ -28,6 +49,20 @@ describe('get', () => {
})
})

describe('getStats', () => {
nock('https://api.helium.io').get('/v1/accounts/my-address/stats').reply(200, {
data: accountStatsFixture(),
})

it('retrieves account stats', async () => {
const client = new Client()
const stats = await client.accounts.getStats('my-address')
expect(stats.lastWeek.length).toBe(1)
expect(stats.lastMonth.length).toBe(2)
expect(stats.lastDay.length).toBe(0)
})
})

describe('list', () => {
describe('with manual pagination', () => {
nock('https://api.helium.io')
Expand Down
Loading

0 comments on commit d47bd1b

Please sign in to comment.