-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch '226-update-koios-cbor' into 'dev'
Update koios rosen extractor(cbor) Closes #226 See merge request ergo/rosen-bridge/utils!253
- Loading branch information
Showing
8 changed files
with
1,935 additions
and
10 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@rosen-bridge/rosen-extractor': minor | ||
--- | ||
|
||
Update koios rosen extractor to use the new interfaces from cardano serialization lib |
125 changes: 125 additions & 0 deletions
125
packages/rosen-extractor/lib/getRosenData/cardano/CardanoKoiosCborRosenExtractor.ts
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,125 @@ | ||
import { isPlainObject } from 'lodash-es'; | ||
import { RosenData, TokenTransformation } from '../abstract/types'; | ||
import AbstractRosenDataExtractor from '../abstract/AbstractRosenDataExtractor'; | ||
import { CARDANO_CHAIN, CARDANO_NATIVE_TOKEN } from '../const'; | ||
import { KoiosCborTransaction } from './types'; | ||
import JsonBigInt from '@rosen-bridge/json-bigint'; | ||
import { getDictValue, parseRosenData } from './utils'; | ||
import { TransactionOutputJSON } from './cardanoSerializationTypes'; | ||
|
||
export class CardanoKoiosCborRosenExtractor extends AbstractRosenDataExtractor<KoiosCborTransaction> { | ||
readonly chain = CARDANO_CHAIN; | ||
|
||
/** | ||
* extracts RosenData from given lock transaction in Koios format | ||
* @param transaction the lock transaction in Koios format | ||
*/ | ||
extractRawData = ( | ||
transaction: KoiosCborTransaction | ||
): RosenData | undefined => { | ||
const baseError = `No rosen data found for tx [${transaction.tx_hash}]`; | ||
if (!transaction.auxiliary_data) return undefined; | ||
const metadata = transaction.auxiliary_data.metadata; | ||
try { | ||
if (metadata && Object.prototype.hasOwnProperty.call(metadata, '0')) { | ||
/** | ||
* TODO: local/ergo/rosen-bridge/utils/-/issues/228 | ||
* Use `decode_metadatum_to_json_str` provided by cardano serialization | ||
* lib after updating guard-service to use latest version of | ||
* `@emurgo/cardano-serialization-lib-nodejs` | ||
*/ | ||
const data = getDictValue(JsonBigInt.parse(metadata[0])); | ||
const rosenData = parseRosenData(data); | ||
if (rosenData) { | ||
const lockOutputs = transaction.body.outputs.filter( | ||
(output) => output.address === this.lockAddress | ||
); | ||
for (const output of lockOutputs) { | ||
const assetTransformation = this.getAssetTransformation( | ||
output, | ||
rosenData.toChain | ||
); | ||
if (assetTransformation) { | ||
return { | ||
...rosenData, | ||
sourceChainTokenId: assetTransformation.from, | ||
amount: assetTransformation.amount, | ||
targetChainTokenId: assetTransformation.to, | ||
sourceTxId: transaction.tx_hash, | ||
}; | ||
} | ||
} | ||
this.logger.debug( | ||
baseError + `: No valid transformation found in any output boxes` | ||
); | ||
} else | ||
this.logger.debug( | ||
baseError + | ||
`: Incomplete metadata. isPlain: ${isPlainObject( | ||
data | ||
)}, data: ${JsonBigInt.stringify(data)}` | ||
); | ||
} else | ||
this.logger.debug( | ||
baseError + `: Invalid metadata: ${JsonBigInt.stringify(metadata)}` | ||
); | ||
} catch (e) { | ||
this.logger.debug( | ||
`An error occurred while getting Cardano rosen data from Koios: ${e}` | ||
); | ||
if (e instanceof Error && e.stack) { | ||
this.logger.debug(e.stack); | ||
} | ||
} | ||
return undefined; | ||
}; | ||
|
||
/** | ||
* extracts and builds token transformation from UTXO and tokenMap | ||
* @param box transaction output | ||
* @param toChain event target chain | ||
*/ | ||
getAssetTransformation = ( | ||
box: TransactionOutputJSON, | ||
toChain: string | ||
): TokenTransformation | undefined => { | ||
// try to build transformation using locked assets | ||
if (box.amount.multiasset) { | ||
const assets = box.amount.multiasset; | ||
for (const policyId of Object.keys(assets)) { | ||
for (const assetName of Object.keys(assets[policyId])) { | ||
const token = this.tokens.search(CARDANO_CHAIN, { | ||
policyId: policyId, | ||
assetName: assetName, | ||
}); | ||
if (token.length > 0 && Object.hasOwn(token[0], toChain)) { | ||
return { | ||
from: this.tokens.getID(token[0], CARDANO_CHAIN), | ||
to: this.tokens.getID(token[0], toChain), | ||
amount: assets[policyId][assetName].toString(), | ||
}; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// try to build transformation using locked ADA | ||
const lovelace = this.tokens.search(CARDANO_CHAIN, { | ||
[this.tokens.getIdKey(CARDANO_CHAIN)]: CARDANO_NATIVE_TOKEN, | ||
}); | ||
if (lovelace.length > 0 && Object.hasOwn(lovelace[0], toChain)) { | ||
return { | ||
from: CARDANO_NATIVE_TOKEN, | ||
to: this.tokens.getID(lovelace[0], toChain), | ||
amount: box.amount.coin, | ||
}; | ||
} else { | ||
this.logger.debug( | ||
`No rosen asset transformation found for box with assets: ${JsonBigInt.stringify( | ||
box.amount | ||
)}` | ||
); | ||
return undefined; | ||
} | ||
}; | ||
} |
Oops, something went wrong.