Add submitpackage endpoint
This commit is contained in:
		
							parent
							
								
									93d9538845
								
							
						
					
					
						commit
						9f0b3bd769
					
				| @ -1,4 +1,4 @@ | |||||||
| import { IBitcoinApi, TestMempoolAcceptResult } from './bitcoin-api.interface'; | import { IBitcoinApi, SubmitPackageResult, TestMempoolAcceptResult } from './bitcoin-api.interface'; | ||||||
| import { IEsploraApi } from './esplora-api.interface'; | import { IEsploraApi } from './esplora-api.interface'; | ||||||
| 
 | 
 | ||||||
| export interface AbstractBitcoinApi { | export interface AbstractBitcoinApi { | ||||||
| @ -23,6 +23,7 @@ export interface AbstractBitcoinApi { | |||||||
|   $getScriptHashTransactions(address: string, lastSeenTxId: string): Promise<IEsploraApi.Transaction[]>; |   $getScriptHashTransactions(address: string, lastSeenTxId: string): Promise<IEsploraApi.Transaction[]>; | ||||||
|   $sendRawTransaction(rawTransaction: string): Promise<string>; |   $sendRawTransaction(rawTransaction: string): Promise<string>; | ||||||
|   $testMempoolAccept(rawTransactions: string[], maxfeerate?: number): Promise<TestMempoolAcceptResult[]>; |   $testMempoolAccept(rawTransactions: string[], maxfeerate?: number): Promise<TestMempoolAcceptResult[]>; | ||||||
|  |   $submitPackage(rawTransactions: string[], maxfeerate?: number, maxburnamount?: number): Promise<SubmitPackageResult>; | ||||||
|   $getOutspend(txId: string, vout: number): Promise<IEsploraApi.Outspend>; |   $getOutspend(txId: string, vout: number): Promise<IEsploraApi.Outspend>; | ||||||
|   $getOutspends(txId: string): Promise<IEsploraApi.Outspend[]>; |   $getOutspends(txId: string): Promise<IEsploraApi.Outspend[]>; | ||||||
|   $getBatchedOutspends(txId: string[]): Promise<IEsploraApi.Outspend[][]>; |   $getBatchedOutspends(txId: string[]): Promise<IEsploraApi.Outspend[][]>; | ||||||
|  | |||||||
| @ -218,3 +218,21 @@ export interface TestMempoolAcceptResult { | |||||||
|   }, |   }, | ||||||
|   ['reject-reason']?: string, |   ['reject-reason']?: string, | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | export interface SubmitPackageResult { | ||||||
|  |   package_msg: string; | ||||||
|  |   "tx-results": { [wtxid: string]: TxResult }; | ||||||
|  |   "replaced-transactions"?: string[]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export interface TxResult { | ||||||
|  |   txid: string; | ||||||
|  |   "other-wtxid"?: string; | ||||||
|  |   vsize?: number; | ||||||
|  |   fees?: { | ||||||
|  |     base: number; | ||||||
|  |     "effective-feerate"?: number; | ||||||
|  |     "effective-includes"?: string[]; | ||||||
|  |   }; | ||||||
|  |   error?: string; | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| import * as bitcoinjs from 'bitcoinjs-lib'; | import * as bitcoinjs from 'bitcoinjs-lib'; | ||||||
| import { AbstractBitcoinApi, HealthCheckHost } from './bitcoin-api-abstract-factory'; | import { AbstractBitcoinApi, HealthCheckHost } from './bitcoin-api-abstract-factory'; | ||||||
| import { IBitcoinApi, TestMempoolAcceptResult } from './bitcoin-api.interface'; | import { IBitcoinApi, SubmitPackageResult, TestMempoolAcceptResult } from './bitcoin-api.interface'; | ||||||
| import { IEsploraApi } from './esplora-api.interface'; | import { IEsploraApi } from './esplora-api.interface'; | ||||||
| import blocks from '../blocks'; | import blocks from '../blocks'; | ||||||
| import mempool from '../mempool'; | import mempool from '../mempool'; | ||||||
| @ -196,6 +196,10 @@ class BitcoinApi implements AbstractBitcoinApi { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   $submitPackage(rawTransactions: string[], maxfeerate?: number, maxburnamount?: number): Promise<SubmitPackageResult> { | ||||||
|  |     return this.bitcoindClient.submitPackage(rawTransactions, maxfeerate ?? undefined, maxburnamount ?? undefined); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   async $getOutspend(txId: string, vout: number): Promise<IEsploraApi.Outspend> { |   async $getOutspend(txId: string, vout: number): Promise<IEsploraApi.Outspend> { | ||||||
|     const txOut = await this.bitcoindClient.getTxOut(txId, vout, false); |     const txOut = await this.bitcoindClient.getTxOut(txId, vout, false); | ||||||
|     return { |     return { | ||||||
|  | |||||||
| @ -58,6 +58,7 @@ class BitcoinRoutes { | |||||||
|           .get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId', this.getTransaction) |           .get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId', this.getTransaction) | ||||||
|           .post(config.MEMPOOL.API_URL_PREFIX + 'tx', this.$postTransaction) |           .post(config.MEMPOOL.API_URL_PREFIX + 'tx', this.$postTransaction) | ||||||
|           .post(config.MEMPOOL.API_URL_PREFIX + 'txs/test', this.$testTransactions) |           .post(config.MEMPOOL.API_URL_PREFIX + 'txs/test', this.$testTransactions) | ||||||
|  |           .post(config.MEMPOOL.API_URL_PREFIX + 'txs/package', this.$submitPackage) | ||||||
|           .get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId/hex', this.getRawTransaction) |           .get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId/hex', this.getRawTransaction) | ||||||
|           .get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId/status', this.getTransactionStatus) |           .get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId/status', this.getTransactionStatus) | ||||||
|           .get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId/outspends', this.getTransactionOutspends) |           .get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId/outspends', this.getTransactionOutspends) | ||||||
| @ -794,6 +795,19 @@ class BitcoinRoutes { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   private async $submitPackage(req: Request, res: Response) { | ||||||
|  |     try { | ||||||
|  |       const rawTxs = Common.getTransactionsFromRequest(req); | ||||||
|  |       const maxfeerate = parseFloat(req.query.maxfeerate as string); | ||||||
|  |       const maxburneamount = parseFloat(req.query.maxburneamount as string); | ||||||
|  |       const result = await bitcoinApi.$submitPackage(rawTxs, maxfeerate, maxburneamount); | ||||||
|  |       res.send(result); | ||||||
|  |     } catch (e: any) { | ||||||
|  |       handleError(req, res, 400, e.message && e.code ? 'submitpackage RPC error: ' + JSON.stringify({ code: e.code, message: e.message }) | ||||||
|  |         : (e.message || 'Error')); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default new BitcoinRoutes(); | export default new BitcoinRoutes(); | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ import { AbstractBitcoinApi, HealthCheckHost } from './bitcoin-api-abstract-fact | |||||||
| import { IEsploraApi } from './esplora-api.interface'; | import { IEsploraApi } from './esplora-api.interface'; | ||||||
| import logger from '../../logger'; | import logger from '../../logger'; | ||||||
| import { Common } from '../common'; | import { Common } from '../common'; | ||||||
| import { TestMempoolAcceptResult } from './bitcoin-api.interface'; | import { SubmitPackageResult, TestMempoolAcceptResult } from './bitcoin-api.interface'; | ||||||
| 
 | 
 | ||||||
| interface FailoverHost { | interface FailoverHost { | ||||||
|   host: string, |   host: string, | ||||||
| @ -332,6 +332,10 @@ class ElectrsApi implements AbstractBitcoinApi { | |||||||
|     throw new Error('Method not implemented.'); |     throw new Error('Method not implemented.'); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   $submitPackage(rawTransactions: string[]): Promise<SubmitPackageResult> { | ||||||
|  |     throw new Error('Method not implemented.'); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   $getOutspend(txId: string, vout: number): Promise<IEsploraApi.Outspend> { |   $getOutspend(txId: string, vout: number): Promise<IEsploraApi.Outspend> { | ||||||
|     return this.failoverRouter.$get<IEsploraApi.Outspend>('/tx/' + txId + '/outspend/' + vout); |     return this.failoverRouter.$get<IEsploraApi.Outspend>('/tx/' + txId + '/outspend/' + vout); | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -83,6 +83,7 @@ module.exports = { | |||||||
|   signRawTransaction: 'signrawtransaction', // bitcoind v0.7.0+
 |   signRawTransaction: 'signrawtransaction', // bitcoind v0.7.0+
 | ||||||
|   stop: 'stop', |   stop: 'stop', | ||||||
|   submitBlock: 'submitblock', // bitcoind v0.7.0+
 |   submitBlock: 'submitblock', // bitcoind v0.7.0+
 | ||||||
|  |   submitPackage: 'submitpackage', | ||||||
|   validateAddress: 'validateaddress', |   validateAddress: 'validateaddress', | ||||||
|   verifyChain: 'verifychain', // bitcoind v0.9.0+
 |   verifyChain: 'verifychain', // bitcoind v0.9.0+
 | ||||||
|   verifyMessage: 'verifymessage', |   verifyMessage: 'verifymessage', | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user