Skip to content

Commit

Permalink
feat: update send endpoints to use raw jsonrpc (#1007)
Browse files Browse the repository at this point in the history
  • Loading branch information
kaladinlight authored Jun 27, 2024
1 parent 12ba404 commit b46095c
Show file tree
Hide file tree
Showing 12 changed files with 102 additions and 23 deletions.
20 changes: 12 additions & 8 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ aliases:
indexer-url: https://btcbook.nownodes.io
indexer-ws-url: wss://btcbook.nownodes.io/wss
indexer-api-key: $NOW_NODES_API_KEY
rpc-url: https://btc.nownodes.io
rpc-api-key: $NOW_NODES_API_KEY
api-autoscaling: true
api-replicas: 2
api-max-replicas: 4
Expand Down Expand Up @@ -192,9 +194,8 @@ aliases:
<<: *bitcoin
environment: dev
pulumi-stack: public-dev-us-east-2
indexer-url: https://btcbook.nownodes.io
indexer-ws-url: wss://btcbook.nownodes.io/wss
indexer-api-key: $NOW_NODES_API_KEY_DEV
rpc-api-key: $NOW_NODES_API_KEY_DEV
api-replicas: 1
api-max-replicas: 2
stateful-service-replicas: 0
Expand Down Expand Up @@ -295,6 +296,8 @@ aliases:
indexer-url: https://dogebook.nownodes.io
indexer-ws-url: wss://dogebook.nownodes.io/wss
indexer-api-key: $NOW_NODES_API_KEY
rpc-url: https://doge.nownodes.io
rpc-api-key: $NOW_NODES_API_KEY
api-autoscaling: true
api-replicas: 2
api-max-replicas: 4
Expand All @@ -308,9 +311,8 @@ aliases:
<<: *dogecoin
environment: dev
pulumi-stack: public-dev-us-east-2
indexer-url: https://dogebook.nownodes.io
indexer-ws-url: wss://dogebook.nownodes.io/wss
indexer-api-key: $NOW_NODES_API_KEY_DEV
rpc-api-key: $NOW_NODES_API_KEY_DEV
api-replicas: 1
api-max-replicas: 2

Expand All @@ -321,6 +323,8 @@ aliases:
indexer-url: https://ltcbook.nownodes.io
indexer-ws-url: wss://ltcbook.nownodes.io/wss
indexer-api-key: $NOW_NODES_API_KEY
rpc-url: https://ltc.nownodes.io
rpc-api-key: $NOW_NODES_API_KEY
api-autoscaling: true
api-replicas: 2
api-max-replicas: 4
Expand All @@ -334,9 +338,8 @@ aliases:
<<: *litecoin
environment: dev
pulumi-stack: public-dev-us-east-2
indexer-url: https://ltcbook.nownodes.io
indexer-ws-url: wss://ltcbook.nownodes.io/wss
indexer-api-key: $NOW_NODES_API_KEY_DEV
rpc-api-key: $NOW_NODES_API_KEY_DEV
api-replicas: 1
api-max-replicas: 2

Expand All @@ -347,6 +350,8 @@ aliases:
indexer-url: https://bchbook.nownodes.io
indexer-ws-url: wss://bchbook.nownodes.io/wss
indexer-api-key: $NOW_NODES_API_KEY
rpc-url: https://bch.nownodes.io
rpc-api-key: $NOW_NODES_API_KEY
api-autoscaling: true
api-replicas: 2
api-max-replicas: 4
Expand All @@ -360,9 +365,8 @@ aliases:
<<: *bitcoincash
environment: dev
pulumi-stack: public-dev-us-east-2
indexer-url: https://bchbook.nownodes.io
indexer-ws-url: wss://bchbook.nownodes.io/wss
indexer-api-key: $NOW_NODES_API_KEY_DEV
rpc-api-key: $NOW_NODES_API_KEY_DEV
api-replicas: 1
api-max-replicas: 2

Expand Down
11 changes: 10 additions & 1 deletion node/coinstacks/bitcoin/api/src/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import { Logger } from '@shapeshiftoss/logger'
const INDEXER_URL = process.env.INDEXER_URL
const INDEXER_WS_URL = process.env.INDEXER_WS_URL
const INDEXER_API_KEY = process.env.INDEXER_API_KEY
const RPC_URL = process.env.RPC_URL
const RPC_API_KEY = process.env.RPC_API_KEY

if (!INDEXER_URL) throw new Error('INDEXER_URL env var not set')
if (!INDEXER_WS_URL) throw new Error('INDEXER_WS_URL env var not set')
if (!RPC_URL) throw new Error('RPC_URL env var not set')

export const logger = new Logger({
namespace: ['unchained', 'coinstacks', 'bitcoin', 'api'],
Expand All @@ -28,7 +31,13 @@ export const formatAddress = (address: string): string => {
return address
}

export const service = new Service({ blockbook, isXpub, addressFormatter: formatAddress })
export const service = new Service({
blockbook,
rpcUrl: RPC_URL,
rpcApiKey: RPC_API_KEY,
isXpub,
addressFormatter: formatAddress,
})

// assign service to be used for all instances of UTXO
UTXO.service = service
4 changes: 3 additions & 1 deletion node/coinstacks/bitcoin/sample.env
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# SECRET ENVIRONMENT VARIABLES
INDEXER_API_KEY=
RPC_API_KEY=

# ENVIRONMENT VARIABLES
INDEXER_URL=https://btcbook.nownodes.io
INDEXER_WS_URL=wss:/btcbook.nownodes.io/wss
LOG_LEVEL=debug
NETWORK=mainnet
NETWORK=mainnet
RPC_URL=https://btc.nownodes.io
11 changes: 10 additions & 1 deletion node/coinstacks/bitcoincash/api/src/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import { Logger } from '@shapeshiftoss/logger'
const INDEXER_URL = process.env.INDEXER_URL
const INDEXER_WS_URL = process.env.INDEXER_WS_URL
const INDEXER_API_KEY = process.env.INDEXER_API_KEY
const RPC_URL = process.env.RPC_URL
const RPC_API_KEY = process.env.RPC_API_KEY

if (!INDEXER_URL) throw new Error('INDEXER_URL env var not set')
if (!INDEXER_WS_URL) throw new Error('INDEXER_WS_URL env var not set')
if (!RPC_URL) throw new Error('RPC_URL env var not set')

export const logger = new Logger({
namespace: ['unchained', 'coinstacks', 'bitcoincash', 'api'],
Expand Down Expand Up @@ -38,7 +41,13 @@ export const formatAddress = (address: string): string => {
return address
}

export const service = new Service({ addressFormatter: formatAddress, blockbook, isXpub })
export const service = new Service({
blockbook,
rpcApiKey: RPC_API_KEY,
rpcUrl: RPC_URL,
isXpub,
addressFormatter: formatAddress,
})

// assign service to be used for all instances of UTXO
UTXO.service = service
4 changes: 3 additions & 1 deletion node/coinstacks/bitcoincash/sample.env
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# SECRET ENVIRONMENT VARIABLES
INDEXER_API_KEY=
RPC_API_KEY=

# ENVIRONMENT VARIABLES
INDEXER_URL=https://bchbook.nownodes.io
INDEXER_WS_URL=wss:/bchbook.nownodes.io/wss
LOG_LEVEL=debug
NETWORK=mainnet
NETWORK=mainnet
RPC_URL=https://bch.nownodes.io
15 changes: 13 additions & 2 deletions node/coinstacks/common/api/src/evm/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,19 @@ export class Service implements Omit<BaseAPI, 'getInfo'>, API {

async sendTx(body: SendTxBody): Promise<string> {
try {
const { result } = await this.blockbook.sendTransaction(body.hex)
return result
const request: RPCRequest = {
jsonrpc: '2.0',
id: 'eth_sendRawTransaction',
method: 'eth_sendRawTransaction',
params: [body.hex],
}

const config = this.rpcApiKey ? { headers: { 'api-key': this.rpcApiKey } } : undefined
const { data } = await axiosNoRetry.post<RPCResponse>(this.rpcUrl, request, config)

if (!data.result) throw new Error(JSON.stringify(data.error))

return data.result as string
} catch (err) {
throw handleError(err)
}
Expand Down
4 changes: 2 additions & 2 deletions node/coinstacks/common/api/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const handleError = (err: unknown): ApiError => {
return new ApiError(
err.response?.statusText || 'Internal Server Error',
err.response?.status ?? 500,
err.response?.data.message || err.message
JSON.stringify(err.response?.data.error) || err.response?.data.message || err.message
)
}

Expand All @@ -25,7 +25,7 @@ export const handleError = (err: unknown): ApiError => {
}

if (err instanceof Error) {
return new ApiError('Internal Server Error', 500, err.message)
return new ApiError('Internal Server Error', 500, err.message || 'unknown error')
}

return new ApiError('Internal Server Error', 500, 'unknown error')
Expand Down
26 changes: 23 additions & 3 deletions node/coinstacks/common/api/src/utxo/service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import axios from 'axios'
import type { Blockbook, Tx as BlockbookTx } from '@shapeshiftoss/blockbook'
import type { AddressFormatter, BadRequestError, BaseAPI, Cursor, SendTxBody } from '../'
import type { AddressFormatter, BadRequestError, BaseAPI, Cursor, RPCRequest, RPCResponse, SendTxBody } from '../'
import { ApiError } from '../'
import type { Account, Address, API, NetworkFee, NetworkFees, RawTx, Tx, TxHistory, Utxo } from './models'
import { handleError, validatePageSize } from '../utils'

const axiosNoRetry = axios.create({ timeout: 5000 })

export interface ServiceArgs {
blockbook: Blockbook
rpcUrl: string
rpcApiKey?: string
isXpub: (pubkey: string) => boolean
addressFormatter?: AddressFormatter
}
Expand All @@ -14,12 +19,16 @@ export class Service implements Omit<BaseAPI, 'getInfo'>, API {
readonly isXpub: (pubkey: string) => boolean

private readonly blockbook: Blockbook
private readonly rpcUrl: string
private readonly rpcApiKey?: string

private formatAddress: AddressFormatter = (address: string) => address.toLowerCase()

constructor(args: ServiceArgs) {
this.blockbook = args.blockbook
this.isXpub = args.isXpub
this.rpcUrl = args.rpcUrl
this.rpcApiKey = args.rpcApiKey

if (args.addressFormatter) this.formatAddress = args.addressFormatter
}
Expand Down Expand Up @@ -140,8 +149,19 @@ export class Service implements Omit<BaseAPI, 'getInfo'>, API {

async sendTx(body: SendTxBody): Promise<string> {
try {
const { result } = await this.blockbook.sendTransaction(body.hex)
return result
const request: RPCRequest = {
jsonrpc: '2.0',
id: 'sendrawtransaction',
method: 'sendrawtransaction',
params: [body.hex],
}

const config = this.rpcApiKey ? { headers: { 'api-key': this.rpcApiKey } } : undefined
const { data } = await axiosNoRetry.post<RPCResponse>(this.rpcUrl, request, config)

if (!data.result) throw new Error(JSON.stringify(data.error))

return data.result as string
} catch (err) {
throw handleError(err)
}
Expand Down
11 changes: 10 additions & 1 deletion node/coinstacks/dogecoin/api/src/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import { Logger } from '@shapeshiftoss/logger'
const INDEXER_URL = process.env.INDEXER_URL
const INDEXER_WS_URL = process.env.INDEXER_WS_URL
const INDEXER_API_KEY = process.env.INDEXER_API_KEY
const RPC_URL = process.env.RPC_URL
const RPC_API_KEY = process.env.RPC_API_KEY

if (!INDEXER_URL) throw new Error('INDEXER_URL env var not set')
if (!INDEXER_WS_URL) throw new Error('INDEXER_WS_URL env var not set')
if (!RPC_URL) throw new Error('RPC_URL env var not set')

export const logger = new Logger({
namespace: ['unchained', 'coinstacks', 'dogecoin', 'api'],
Expand All @@ -23,7 +26,13 @@ const isXpub = (pubkey: string): boolean => {

export const formatAddress = (address: string): string => address

export const service = new Service({ blockbook, isXpub, addressFormatter: formatAddress })
export const service = new Service({
blockbook,
rpcUrl: RPC_URL,
rpcApiKey: RPC_API_KEY,
isXpub,
addressFormatter: formatAddress,
})

// assign service to be used for all instances of UTXO
UTXO.service = service
4 changes: 3 additions & 1 deletion node/coinstacks/dogecoin/sample.env
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# SECRET ENVIRONMENT VARIABLES
INDEXER_API_KEY=
RPC_API_KEY=

# ENVIRONMENT VARIABLES
INDEXER_URL=https://dogebook.nownodes.io
INDEXER_WS_URL=wss:/dogebook.nownodes.io/wss
LOG_LEVEL=debug
NETWORK=mainnet
NETWORK=mainnet
RPC_URL=https://doge.nownodes.io
11 changes: 10 additions & 1 deletion node/coinstacks/litecoin/api/src/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import { Logger } from '@shapeshiftoss/logger'
const INDEXER_URL = process.env.INDEXER_URL
const INDEXER_WS_URL = process.env.INDEXER_WS_URL
const INDEXER_API_KEY = process.env.INDEXER_API_KEY
const RPC_URL = process.env.RPC_URL
const RPC_API_KEY = process.env.RPC_API_KEY

if (!INDEXER_URL) throw new Error('INDEXER_URL env var not set')
if (!INDEXER_WS_URL) throw new Error('INDEXER_WS_URL env var not set')
if (!RPC_URL) throw new Error('RPC_URL env var not set')

export const logger = new Logger({
namespace: ['unchained', 'coinstacks', 'litecoin', 'api'],
Expand All @@ -28,7 +31,13 @@ export const formatAddress = (address: string): string => {
return address
}

export const service = new Service({ blockbook, isXpub, addressFormatter: formatAddress })
export const service = new Service({
blockbook,
rpcUrl: RPC_URL,
rpcApiKey: RPC_API_KEY,
isXpub,
addressFormatter: formatAddress,
})

// assign service to be used for all instances of UTXO
UTXO.service = service
4 changes: 3 additions & 1 deletion node/coinstacks/litecoin/sample.env
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# SECRET ENVIRONMENT VARIABLES
INDEXER_API_KEY=
RPC_API_KEY=

# ENVIRONMENT VARIABLES
INDEXER_URL=https://ltcbook.nownodes.io
INDEXER_WS_URL=wss:/ltcbook.nownodes.io/wss
LOG_LEVEL=debug
NETWORK=mainnet
NETWORK=mainnet
RPC_URL=https://ltc.nownodes.io

0 comments on commit b46095c

Please sign in to comment.