Skip to content

Commit

Permalink
feat: utxo consolidate to single transaction row (#5994)
Browse files Browse the repository at this point in the history
  • Loading branch information
kaladinlight authored Jan 16, 2024
1 parent 4dddea1 commit 348cfdf
Show file tree
Hide file tree
Showing 27 changed files with 2,362 additions and 256 deletions.
68 changes: 28 additions & 40 deletions packages/chain-adapters/src/cosmossdk/CosmosSdkBaseAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,7 @@ import type { AssetId, ChainId } from '@shapeshiftoss/caip'
import { fromChainId, generateAssetIdFromCosmosSdkDenom } from '@shapeshiftoss/caip'
import type { BIP44Params } from '@shapeshiftoss/types'
import { KnownChainIds } from '@shapeshiftoss/types'
import type {
BaseTransactionParser,
ParsedTx,
Tx,
} from '@shapeshiftoss/unchained-client/dist/cosmossdk'
import type { V1Api as CosmosV1Api } from '@shapeshiftoss/unchained-client/dist/cosmossdk/cosmos'
import { V1Api as ThorchainV1Api } from '@shapeshiftoss/unchained-client/dist/cosmossdk/thorchain'
import type { Validator as CosmosSdkValidator } from '@shapeshiftoss/unchained-client/dist/cosmossdk/types'
import type { Client } from '@shapeshiftoss/unchained-client/dist/websocket'
import * as unchained from '@shapeshiftoss/unchained-client'
import { bech32 } from 'bech32'

import type { ChainAdapter as IChainAdapter } from '../api'
Expand Down Expand Up @@ -69,25 +61,14 @@ export const assertIsValidatorAddress = (validator: string, chainId: CosmosSdkCh
}
}

const transformValidator = (validator: CosmosSdkValidator): Validator => ({
const transformValidator = (validator: unchained.cosmossdk.types.Validator): Validator => ({
address: validator.address,
moniker: validator.moniker,
tokens: validator.tokens,
commission: validator.commission.rate,
apr: validator.apr,
})

const parsedTxToTransaction = (parsedTx: ParsedTx): Transaction => ({
...parsedTx,
transfers: parsedTx.transfers.map(transfer => ({
assetId: transfer.assetId,
from: transfer.from,
to: transfer.to,
type: transfer.type,
value: transfer.totalValue,
})),
})

export const cosmosSdkChainIds = [
KnownChainIds.CosmosMainnet,
KnownChainIds.ThorchainMainnet,
Expand All @@ -103,8 +84,8 @@ export interface ChainAdapterArgs {
chainId?: CosmosSdkChainId
coinName: string
providers: {
http: CosmosV1Api | ThorchainV1Api
ws: Client<Tx>
http: unchained.cosmos.V1Api | unchained.thorchain.V1Api
ws: unchained.ws.Client<unchained.cosmossdk.Tx>
}
}

Expand All @@ -113,7 +94,7 @@ export interface CosmosSdkBaseAdapterArgs extends ChainAdapterArgs {
chainId: CosmosSdkChainId
defaultBIP44Params: BIP44Params
denom: Denom
parser: BaseTransactionParser<Tx>
parser: unchained.cosmossdk.BaseTransactionParser<unchained.cosmossdk.Tx>
supportedChainIds: ChainId[]
}

Expand All @@ -123,13 +104,13 @@ export abstract class CosmosSdkBaseAdapter<T extends CosmosSdkChainId> implement
protected readonly defaultBIP44Params: BIP44Params
protected readonly supportedChainIds: ChainId[]
protected readonly providers: {
http: CosmosV1Api | ThorchainV1Api
ws: Client<Tx>
http: unchained.cosmos.V1Api | unchained.thorchain.V1Api
ws: unchained.ws.Client<unchained.cosmossdk.Tx>
}

protected assetId: AssetId
protected denom: string
protected parser: BaseTransactionParser<Tx>
protected parser: unchained.cosmossdk.BaseTransactionParser<unchained.cosmossdk.Tx>

protected constructor(args: CosmosSdkBaseAdapterArgs) {
this.assetId = args.assetId
Expand Down Expand Up @@ -171,7 +152,7 @@ export abstract class CosmosSdkBaseAdapter<T extends CosmosSdkChainId> implement
async getAccount(pubkey: string): Promise<Account<T>> {
try {
const account = await (async () => {
if (this.providers.http instanceof ThorchainV1Api) {
if (this.providers.http instanceof unchained.thorchain.V1Api) {
const data = await this.providers.http.getAccount({ pubkey })
return { ...data, delegations: [], redelegations: [], undelegations: [], rewards: [] }
}
Expand Down Expand Up @@ -251,12 +232,7 @@ export abstract class CosmosSdkBaseAdapter<T extends CosmosSdkChainId> implement
cursor: input.cursor,
})

const txs = await Promise.all(
data.txs.map(async tx => {
const parsedTx = await this.parser.parse(tx, input.pubkey)
return parsedTxToTransaction(parsedTx)
}),
)
const txs = await Promise.all(data.txs.map(tx => this.parseTx(tx, input.pubkey)))

return {
cursor: data.cursor,
Expand Down Expand Up @@ -382,10 +358,7 @@ export abstract class CosmosSdkBaseAdapter<T extends CosmosSdkChainId> implement
await this.providers.ws.subscribeTxs(
subscriptionId,
{ topic: 'txs', addresses: [address] },
async msg => {
const parsedTx = await this.parser.parse(msg.data, msg.address)
onMessage(parsedTxToTransaction(parsedTx))
},
async msg => onMessage(await this.parseTx(msg.data, msg.address)),
err => onError({ message: err.message }),
)
}
Expand All @@ -405,7 +378,7 @@ export abstract class CosmosSdkBaseAdapter<T extends CosmosSdkChainId> implement
}

async getValidators(): Promise<Validator[]> {
if (this.providers.http instanceof ThorchainV1Api) return []
if (this.providers.http instanceof unchained.thorchain.V1Api) return []

try {
const data = await this.providers.http.getValidators()
Expand All @@ -416,7 +389,7 @@ export abstract class CosmosSdkBaseAdapter<T extends CosmosSdkChainId> implement
}

async getValidator(address: string): Promise<Validator | undefined> {
if (this.providers.http instanceof ThorchainV1Api) return
if (this.providers.http instanceof unchained.thorchain.V1Api) return

try {
const validator = await this.providers.http.getValidator({ pubkey: address })
Expand All @@ -425,4 +398,19 @@ export abstract class CosmosSdkBaseAdapter<T extends CosmosSdkChainId> implement
return ErrorHandler(err)
}
}

private async parseTx(tx: unchained.cosmossdk.Tx, pubkey: string): Promise<Transaction> {
const parsedTx = await this.parser.parse(tx, pubkey)

return {
...parsedTx,
transfers: parsedTx.transfers.map(transfer => ({
assetId: transfer.assetId,
from: [transfer.from],
to: [transfer.to],
type: transfer.type,
value: transfer.totalValue,
})),
}
}
}
76 changes: 20 additions & 56 deletions packages/chain-adapters/src/evm/EvmBaseAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -413,40 +413,12 @@ export abstract class EvmBaseAdapter<T extends EvmChainId> implements IChainAdap
cursor: input.cursor,
})

const txs = await Promise.all(
data.txs.map(async tx => {
const parsedTx = await this.parser.parse(tx, input.pubkey)

return {
address: input.pubkey,
blockHash: parsedTx.blockHash,
blockHeight: parsedTx.blockHeight,
blockTime: parsedTx.blockTime,
chainId: parsedTx.chainId,
chain: this.getType(),
confirmations: parsedTx.confirmations,
txid: parsedTx.txid,
fee: parsedTx.fee,
status: parsedTx.status,
trade: parsedTx.trade,
transfers: parsedTx.transfers.map(transfer => ({
assetId: transfer.assetId,
from: transfer.from,
to: transfer.to,
type: transfer.type,
value: transfer.totalValue,
id: transfer.id,
token: transfer.token,
})),
data: parsedTx.data,
}
}),
)
const transactions = await Promise.all(data.txs.map(tx => this.parseTx(tx, input.pubkey)))

return {
cursor: data.cursor ?? '',
pubkey: input.pubkey,
transactions: txs,
transactions,
}
}

Expand Down Expand Up @@ -585,32 +557,7 @@ export abstract class EvmBaseAdapter<T extends EvmChainId> implements IChainAdap
await this.providers.ws.subscribeTxs(
subscriptionId,
{ topic: 'txs', addresses: [address] },
async msg => {
const tx = await this.parser.parse(msg.data, msg.address)

onMessage({
address: tx.address,
blockHash: tx.blockHash,
blockHeight: tx.blockHeight,
blockTime: tx.blockTime,
chainId: tx.chainId,
confirmations: tx.confirmations,
fee: tx.fee,
status: tx.status,
trade: tx.trade,
transfers: tx.transfers.map(transfer => ({
assetId: transfer.assetId,
from: transfer.from,
to: transfer.to,
type: transfer.type,
value: transfer.totalValue,
id: transfer.id,
token: transfer.token,
})),
txid: tx.txid,
data: tx.data,
})
},
async msg => onMessage(await this.parseTx(msg.data, msg.address)),
err => onError({ message: err.message }),
)
}
Expand Down Expand Up @@ -713,6 +660,23 @@ export abstract class EvmBaseAdapter<T extends EvmChainId> implements IChainAdap
} as FeeDataEstimate<T>
}

private async parseTx(tx: unchained.evm.types.Tx, pubkey: string): Promise<Transaction> {
const parsedTx = await this.parser.parse(tx, pubkey)

return {
...parsedTx,
transfers: parsedTx.transfers.map(transfer => ({
assetId: transfer.assetId,
from: [transfer.from],
to: [transfer.to],
type: transfer.type,
value: transfer.totalValue,
id: transfer.id,
token: transfer.token,
})),
}
}

get httpProvider(): unchained.evm.Api {
return this.providers.http
}
Expand Down
4 changes: 3 additions & 1 deletion packages/chain-adapters/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ export type Transaction = Omit<unchained.StandardTx, 'transfers'> & {
data?: TxMetadata
}

export type TxTransfer = Omit<unchained.Transfer, 'components' | 'totalValue'> & {
export type TxTransfer = Omit<unchained.Transfer, 'components' | 'totalValue' | 'from' | 'to'> & {
from: string[]
to: string[]
value: string
}

Expand Down
Loading

0 comments on commit 348cfdf

Please sign in to comment.