-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e4724dd
commit 8df1d39
Showing
13 changed files
with
233 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { Injectable, Logger } from '@nestjs/common'; | ||
import { NestDataLoader } from '@applifting-io/nestjs-dataloader'; | ||
import { Address } from 'src/core/bitcoin-api/bitcoin-api.schema'; | ||
import { BitcoinApiService } from 'src/core/bitcoin-api/bitcoin-api.service'; | ||
import { DataLoaderResponse } from 'src/common/type/dataloader'; | ||
import { BitcoinTransaction } from '../transaction/transaction.model'; | ||
|
||
@Injectable() | ||
export class BitcoinAddressLoader implements NestDataLoader<string, Address> { | ||
private logger = new Logger(BitcoinAddressLoader.name); | ||
|
||
constructor(private bitcoinApiService: BitcoinApiService) {} | ||
|
||
public getBatchFunction() { | ||
return (addresses: string[]) => { | ||
this.logger.debug(`Loading bitcoin addresses stats: ${addresses.join(', ')}`); | ||
return Promise.all( | ||
addresses.map((address) => this.bitcoinApiService.getAddress({ address })), | ||
); | ||
}; | ||
} | ||
} | ||
export type BitcoinAddressLoaderResponse = DataLoaderResponse<BitcoinAddressLoader>; | ||
|
||
export interface BitcoinAddressBalance { | ||
satoshi: number; | ||
pendingSatoshi: number; | ||
} | ||
|
||
@Injectable() | ||
export class BitcoinAddressBalanceLoader implements NestDataLoader<string, BitcoinAddressBalance> { | ||
private logger = new Logger(BitcoinAddressBalanceLoader.name); | ||
|
||
constructor(private bitcoinApiService: BitcoinApiService) {} | ||
|
||
public getBatchFunction() { | ||
return (addresses: string[]) => { | ||
this.logger.debug(`Loading bitcoin addresses balance: ${addresses.join(', ')}`); | ||
return Promise.all( | ||
addresses.map(async (address) => { | ||
// XXX: Miners has higher chance of getting this error: Too many unspent transaction outputs (>9000). Contact support to raise limits. | ||
const utxos = await this.bitcoinApiService.getAddressTxsUtxo({ address }); | ||
|
||
let satoshi = 0; | ||
let pendingSatoshi = 0; | ||
utxos.forEach((utxo) => { | ||
satoshi += utxo.value; | ||
if (!utxo.status.confirmed) { | ||
pendingSatoshi += utxo.value; | ||
} | ||
}); | ||
return { | ||
satoshi, | ||
pendingSatoshi, | ||
}; | ||
}), | ||
); | ||
}; | ||
} | ||
} | ||
export type BitcoinAddressBalanceLoaderResponse = DataLoaderResponse<BitcoinAddressBalanceLoader>; | ||
|
||
export interface BitcoinAddressTxsLoaderProps { | ||
address: string; | ||
afterTxid?: string; | ||
} | ||
|
||
@Injectable() | ||
export class BitcoinAddressTxsLoader | ||
implements NestDataLoader<BitcoinAddressTxsLoaderProps, BitcoinTransaction[]> | ||
{ | ||
private logger = new Logger(BitcoinAddressTxsLoader.name); | ||
|
||
constructor(private bitcoinApiService: BitcoinApiService) {} | ||
|
||
public getBatchFunction() { | ||
return (batchProps: BitcoinAddressTxsLoaderProps[]) => { | ||
this.logger.debug(`Loading bitcoin addresses txs: ${batchProps}`); | ||
return Promise.all( | ||
batchProps.map(async (props) => { | ||
const txs = await this.bitcoinApiService.getAddressTxs({ | ||
address: props.address, | ||
after_txid: props.afterTxid, | ||
}); | ||
return txs.map((tx) => BitcoinTransaction.from(tx)); | ||
}), | ||
); | ||
}; | ||
} | ||
} | ||
export type BitcoinAddressTxsLoaderResponse = DataLoaderResponse<BitcoinAddressTxsLoader>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,19 @@ | ||
import { Module } from '@nestjs/common'; | ||
import { BitcoinApiModule } from 'src/core/bitcoin-api/bitcoin-api.module'; | ||
import { BitcoinAddressResolver } from './address.resolver'; | ||
import { | ||
BitcoinAddressLoader, | ||
BitcoinAddressTxsLoader, | ||
BitcoinAddressBalanceLoader, | ||
} from './address.dataloader'; | ||
|
||
@Module({ | ||
providers: [BitcoinAddressResolver], | ||
imports: [BitcoinApiModule], | ||
providers: [ | ||
BitcoinAddressResolver, | ||
BitcoinAddressLoader, | ||
BitcoinAddressTxsLoader, | ||
BitcoinAddressBalanceLoader, | ||
], | ||
}) | ||
export class AddressModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,63 @@ | ||
import { Float, Parent, ResolveField, Resolver } from '@nestjs/graphql'; | ||
import DataLoader from 'dataloader'; | ||
import { Loader } from '@applifting-io/nestjs-dataloader'; | ||
import { Args, Float, Parent, ResolveField, Resolver } from '@nestjs/graphql'; | ||
import { BitcoinApiService } from 'src/core/bitcoin-api/bitcoin-api.service'; | ||
import { BitcoinBaseTransaction, BitcoinTransaction } from '../transaction/transaction.model'; | ||
import { BitcoinAddress } from './address.model'; | ||
import { | ||
BitcoinAddressBalanceLoader, | ||
BitcoinAddressBalanceLoaderResponse, | ||
BitcoinAddressLoader, | ||
BitcoinAddressLoaderResponse, | ||
BitcoinAddressTxsLoader, | ||
BitcoinAddressTxsLoaderProps, | ||
BitcoinAddressTxsLoaderResponse, | ||
} from './address.dataloader'; | ||
|
||
@Resolver(() => BitcoinAddress) | ||
export class BitcoinAddressResolver { | ||
constructor(private bitcoinApiService: BitcoinApiService) {} | ||
|
||
@ResolveField(() => Float) | ||
public async satoshi(@Parent() address: BitcoinAddress): Promise<number> { | ||
// TODO: Implement this resolver | ||
// get satoshi/pendingSatoshi from the address UTXOs | ||
return 0; | ||
public async satoshi( | ||
@Parent() address: BitcoinAddress, | ||
@Loader(BitcoinAddressBalanceLoader) | ||
addressBalanceLoader: DataLoader<string, BitcoinAddressBalanceLoaderResponse>, | ||
): Promise<number> { | ||
const { satoshi } = await addressBalanceLoader.load(address.address); | ||
return satoshi; | ||
} | ||
|
||
@ResolveField(() => Float) | ||
public async pendingSatoshi(@Parent() address: BitcoinAddress): Promise<number> { | ||
// TODO: Implement this Resolver | ||
return 0; | ||
public async pendingSatoshi( | ||
@Parent() address: BitcoinAddress, | ||
@Loader(BitcoinAddressBalanceLoader) | ||
addressBalanceLoader: DataLoader<string, BitcoinAddressBalanceLoaderResponse>, | ||
): Promise<number> { | ||
const { pendingSatoshi } = await addressBalanceLoader.load(address.address); | ||
return pendingSatoshi; | ||
} | ||
|
||
@ResolveField(() => Float) | ||
public async transactionCount(@Parent() address: BitcoinAddress): Promise<number> { | ||
// TODO: Implement this resolver | ||
return 0; | ||
public async transactionCount( | ||
@Parent() address: BitcoinAddress, | ||
@Loader(BitcoinAddressLoader) addressLoader: DataLoader<string, BitcoinAddressLoaderResponse>, | ||
): Promise<number> { | ||
// XXX: addressInfo.mempool_stats.tx_count is not included in the response, not sure if it should be included | ||
const stats = await addressLoader.load(address.address); | ||
return stats.chain_stats.tx_count; | ||
} | ||
|
||
@ResolveField(() => [BitcoinTransaction]) | ||
public async transactions(@Parent() address: BitcoinAddress): Promise<BitcoinBaseTransaction[]> { | ||
// TODO: Implement this resolver | ||
// use dataloaders to fetch transactions | ||
return []; | ||
public async transactions( | ||
@Parent() address: BitcoinAddress, | ||
@Loader(BitcoinAddressTxsLoader) | ||
addressTxsLoader: DataLoader<BitcoinAddressTxsLoaderProps, BitcoinAddressTxsLoaderResponse>, | ||
@Args('afterTxid', { nullable: true }) afterTxid?: string, | ||
): Promise<BitcoinBaseTransaction[]> { | ||
return await addressTxsLoader.load({ | ||
address: address.address, | ||
afterTxid: afterTxid, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters