@rosen-bridge/rosen-extractor 11.1.1 → 11.1.2-6083137b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +87 -0
- package/dist/getRosenData/abstract/abstractRosenDataExtractor.d.ts +3 -3
- package/dist/getRosenData/abstract/abstractRosenDataExtractor.d.ts.map +1 -1
- package/dist/getRosenData/abstract/abstractRosenDataExtractor.js +1 -1
- package/package.json +5 -4
- package/dist/getRosenData/cardano/cardanoGraphQLRosenExtractor.d.ts +0 -18
- package/dist/getRosenData/cardano/cardanoGraphQLRosenExtractor.d.ts.map +0 -1
- package/dist/getRosenData/cardano/cardanoGraphQLRosenExtractor.js +0 -94
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @rosen-bridge/rosen-extractor
|
|
2
2
|
|
|
3
|
+
## 11.1.2-6083137b
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Update dependencies
|
|
8
|
+
- Update dependencies
|
|
9
|
+
- Update dependencies
|
|
10
|
+
- Update dependencies
|
|
11
|
+
- Update dependencies
|
|
12
|
+
- Update dependencies
|
|
13
|
+
- Update dependencies
|
|
14
|
+
- @rosen-bridge/abstract-logger@4.0.0-6083137b
|
|
15
|
+
- @rosen-bridge/tokens@5.0.0-6083137b
|
|
16
|
+
|
|
3
17
|
## 11.1.1
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/README.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# @rosen-bridge/rosen-extractor
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://www.npmjs.com/package/@rosen-bridge/rosen-extractor"><img src="https://img.shields.io/npm/v/@rosen-bridge/rosen-extractor"></a>
|
|
5
|
+
<img src="https://img.shields.io/npm/l/@rosen-bridge/rosen-extractor"></a>
|
|
6
|
+
<p>
|
|
7
|
+
|
|
8
|
+
## Table of contents
|
|
9
|
+
|
|
10
|
+
- [Description](#description)
|
|
11
|
+
- [Installation](#installation)
|
|
12
|
+
- [Usage](#usage)
|
|
13
|
+
|
|
14
|
+
## Description
|
|
15
|
+
|
|
16
|
+
`@rosen-bridge/rosen-extractor` is a core Rosen Bridge module responsible for extracting and validating bridge request data from blockchain transactions. It converts chain-specific transaction data into a standardized bridge request format consumed by Rosen Watcher and Guard services as part of the bridge verification and execution pipeline.
|
|
17
|
+
|
|
18
|
+
The extractor module is responsible for identifying and parsing bridge requests embedded in transactions across supported blockchains. It achieves this through a set of chain-specific extractors (such as `ErgoNodeRosenExtractor`, `CardanoKoiosExtractor`, and others), each of which understands the transaction structure and data formats of its respective chain and provider.
|
|
19
|
+
|
|
20
|
+
In addition to raw data extraction, the module performs several validation and normalization steps required by the bridge protocol (note that these steps are taken in the `AbstractRosenExtractor` class):
|
|
21
|
+
|
|
22
|
+
- Destination addresses are validated against the target chain using `@rosen-bridge/address-codec` package.
|
|
23
|
+
- Tokens are resolved through `TokenMap` to ensure the requested asset is supported on both the source and target chains.
|
|
24
|
+
- Transfer amounts are normalized to account for differing decimal precisions across blockchains using `TokenMap.wrapAmount`.
|
|
25
|
+
|
|
26
|
+
The output of the extractor is a normalized bridge request object containing the target chain and address, source transaction information, token identifiers on both chains, transfer amount, and the bridge and network fees specified in the transaction. This object represents the canonical input used by Rosen Watchers for observation and by Guards for verification and signing.
|
|
27
|
+
|
|
28
|
+
The fees extracted by this package represent the values explicitly declared by the user in the transaction. They do not reflect the effective fees enforced by the protocol. If the specified fees are below the configured minimum fee—defined on-chain on Ergo—the Rosen Guards will apply the minimum fee instead. For more information on fee configuration and enforcement, see the [`@rosen-bridge/minimum-fee`](https://www.npmjs.com/package/@rosen-bridge/minimum-fee) package.
|
|
29
|
+
|
|
30
|
+
The extracted bridge request data includes the following fields:
|
|
31
|
+
|
|
32
|
+
- **`toChain`**: Target blockchain
|
|
33
|
+
- **`toAddress`**: Destination address on the target blockchain
|
|
34
|
+
- **`bridgeFee`**: Bridge fee specified in the transaction
|
|
35
|
+
- **`networkFee`**: Network fee specified in the transaction
|
|
36
|
+
- **`fromAddress`**: Source address transferring assets to the lock address
|
|
37
|
+
- **`sourceChainTokenId`**: Token identifier on the source blockchain
|
|
38
|
+
- **`amount`**: Transfer amount
|
|
39
|
+
- **`targetChainTokenId`**: Token identifier on the target blockchain
|
|
40
|
+
- **`sourceTxId`**: Source transaction identifier
|
|
41
|
+
- **`rawData`**: Raw transaction data from which the request was extracted
|
|
42
|
+
|
|
43
|
+
> Note: The `rawData` field is a small subset of the original transaction data while omitting the irrelevant data. It is included for reference and debugging purposes. For example, on Bitcoin, the `rawData` is the scriptPubKey of OP_RETURN output that contains Rosen data while on Bitcoin-Runes, it is the entire transaction outputs.
|
|
44
|
+
|
|
45
|
+
There are two functions that can be used to extract the bridge request data:
|
|
46
|
+
|
|
47
|
+
1. `extractData`: This function takes a transaction data as input and returns the extracted bridge request data. It is implemented in the child classes based on the chain and provider.
|
|
48
|
+
2. `get`: This function wraps the `extractData` function and adds additional validation and normalization steps (i.e., validate the destination address and normalize the amount). It is recommended to use this function instead of `extractData` as it provides a more consistent and reliable output. It is implemented in the `AbstractRosenExtractor` class.
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
npm i @rosen-bridge/rosen-extractor
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
To use the class, The transaction data must be provided in the format expected by the specific extractor class being used. Here's a basic example of how to use this package:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { ErgoNodeRosenExtractor } from '@rosen-bridge/rosen-extractor';
|
|
62
|
+
import { TokenMap } from '@rosen-bridge/tokens';
|
|
63
|
+
import ergoNodeClientFactory from '@rosen-clients/ergo-node';
|
|
64
|
+
|
|
65
|
+
// generate the Ergo node client
|
|
66
|
+
const ergoNodeUrl = '';
|
|
67
|
+
const nodeClient = ergoNodeClientFactory(ergoNodeUrl);
|
|
68
|
+
|
|
69
|
+
// get the transaction from Ergo node
|
|
70
|
+
const lockTxId =
|
|
71
|
+
'9115d6d6f22269949de1118f1415e7ef8aa717b232f3c6a3710178475a87af05'; // a sample lock transaction
|
|
72
|
+
const tx = await nodeClient.getTxById(lockTxId);
|
|
73
|
+
|
|
74
|
+
// generate the TokenMap
|
|
75
|
+
const tokenMapJson = {}; // you can get the token map json from GitHub releases (https://github.com/rosen-bridge/contract/releases)
|
|
76
|
+
const tokenMap = new TokenMap();
|
|
77
|
+
await tokenMap.updateConfigByJson(tokenMapJson);
|
|
78
|
+
|
|
79
|
+
// generate the Rosen Extractor for Ergo Node provider
|
|
80
|
+
const ergoLockAddress =
|
|
81
|
+
'nB3L2PD3J4rMmyGk7nnNdESpPXxhPRQ4t1chF8LTXtceMQjKCEgL2pFjPY6cehGjyEFZyHEomBTFXZyqfonvxDozrTtK5JzatD8SdmcPeJNWPvdRb5UxEMXE4WQtpAFzt2veT8Z6bmoWN'; // the Rosen lock address on Ergo the time of the sample
|
|
82
|
+
const rosenExtractor = new ErgoNodeRosenExtractor(ergoLockAddress, tokenMap);
|
|
83
|
+
|
|
84
|
+
// extract and display the Rosen data
|
|
85
|
+
const res = rosenExtractor.get(tx);
|
|
86
|
+
console.log(res);
|
|
87
|
+
```
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { TokenMap } from '@rosen-bridge/tokens';
|
|
2
2
|
import { RosenData } from './types';
|
|
3
|
-
import {
|
|
3
|
+
import { AbstractLogger } from '@rosen-bridge/abstract-logger';
|
|
4
4
|
export default abstract class AbstractRosenDataExtractor<TransactionType> {
|
|
5
5
|
protected readonly lockAddress: string;
|
|
6
6
|
protected readonly tokens: TokenMap;
|
|
7
|
-
protected readonly logger:
|
|
7
|
+
protected readonly logger: AbstractLogger;
|
|
8
8
|
protected readonly storeRawData: boolean;
|
|
9
9
|
abstract readonly chain: string;
|
|
10
|
-
constructor(lockAddress: string, tokens: TokenMap, logger?:
|
|
10
|
+
constructor(lockAddress: string, tokens: TokenMap, logger?: AbstractLogger, storeRawData?: boolean);
|
|
11
11
|
/**
|
|
12
12
|
* extracts RosenData from given lock transaction and wrap the amount
|
|
13
13
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstractRosenDataExtractor.d.ts","sourceRoot":"","sources":["../../../lib/getRosenData/abstract/abstractRosenDataExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"abstractRosenDataExtractor.d.ts","sourceRoot":"","sources":["../../../lib/getRosenData/abstract/abstractRosenDataExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,cAAc,EAAe,MAAM,+BAA+B,CAAC;AAG5E,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,0BAA0B,CAAC,eAAe;IAIpE,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM;IACtC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ;IACnC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,cAAc;IACzC,SAAS,CAAC,QAAQ,CAAC,YAAY;IANjC,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAGX,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,QAAQ,EAChB,MAAM,GAAE,cAAkC,EAC1C,YAAY,UAAO;IAGxC;;OAEG;IACH,GAAG,GAAI,aAAa,eAAe,KAAG,SAAS,GAAG,SAAS,CAoBzD;IAEF;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,CAAC,WAAW,EAAE,eAAe,KAAK,SAAS,GAAG,SAAS,CAAC;CAC/E"}
|
|
@@ -35,4 +35,4 @@ export default class AbstractRosenDataExtractor {
|
|
|
35
35
|
return data;
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
38
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3RSb3NlbkRhdGFFeHRyYWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvZ2V0Um9zZW5EYXRhL2Fic3RyYWN0L2Fic3RyYWN0Um9zZW5EYXRhRXh0cmFjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBa0IsV0FBVyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDNUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRTlELE1BQU0sQ0FBQyxPQUFPLE9BQWdCLDBCQUEwQjtJQUlqQztJQUNBO0lBQ0E7SUFDQTtJQUpyQixZQUNxQixXQUFtQixFQUNuQixNQUFnQixFQUNoQixTQUF5QixJQUFJLFdBQVcsRUFBRSxFQUMxQyxlQUFlLElBQUk7UUFIbkIsZ0JBQVcsR0FBWCxXQUFXLENBQVE7UUFDbkIsV0FBTSxHQUFOLE1BQU0sQ0FBVTtRQUNoQixXQUFNLEdBQU4sTUFBTSxDQUFvQztRQUMxQyxpQkFBWSxHQUFaLFlBQVksQ0FBTztJQUNyQyxDQUFDO0lBRUo7O09BRUc7SUFDSCxHQUFHLEdBQUcsQ0FBQyxXQUE0QixFQUF5QixFQUFFO1FBQzVELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDM0MsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNULElBQUksQ0FBQztnQkFDSCxlQUFlLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDaEQsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ2YsZ0RBQWdELElBQUksQ0FBQyxTQUFTLGVBQWUsSUFBSSxDQUFDLE9BQU8sa0JBQWtCLENBQUMsRUFBRSxDQUMvRyxDQUFDO2dCQUNGLE9BQU8sU0FBUyxDQUFDO1lBQ25CLENBQUM7WUFDRCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNO2lCQUN0QixVQUFVLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQztpQkFDcEUsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3JCLHVEQUF1RDtZQUN2RCxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUN2QixJQUFJLENBQUMsT0FBTyxHQUFHLDRCQUE0QixDQUFDO1lBQzlDLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDLENBQUM7Q0FNSCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRva2VuTWFwIH0gZnJvbSAnQHJvc2VuLWJyaWRnZS90b2tlbnMnO1xuaW1wb3J0IHsgUm9zZW5EYXRhIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBBYnN0cmFjdExvZ2dlciwgRHVtbXlMb2dnZXIgfSBmcm9tICdAcm9zZW4tYnJpZGdlL2Fic3RyYWN0LWxvZ2dlcic7XG5pbXBvcnQgeyB2YWxpZGF0ZUFkZHJlc3MgfSBmcm9tICdAcm9zZW4tYnJpZGdlL2FkZHJlc3MtY29kZWMnO1xuXG5leHBvcnQgZGVmYXVsdCBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdFJvc2VuRGF0YUV4dHJhY3RvcjxUcmFuc2FjdGlvblR5cGU+IHtcbiAgYWJzdHJhY3QgcmVhZG9ubHkgY2hhaW46IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgbG9ja0FkZHJlc3M6IHN0cmluZyxcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgdG9rZW5zOiBUb2tlbk1hcCxcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgbG9nZ2VyOiBBYnN0cmFjdExvZ2dlciA9IG5ldyBEdW1teUxvZ2dlcigpLFxuICAgIHByb3RlY3RlZCByZWFkb25seSBzdG9yZVJhd0RhdGEgPSB0cnVlLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIGV4dHJhY3RzIFJvc2VuRGF0YSBmcm9tIGdpdmVuIGxvY2sgdHJhbnNhY3Rpb24gYW5kIHdyYXAgdGhlIGFtb3VudFxuICAgKi9cbiAgZ2V0ID0gKHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvblR5cGUpOiBSb3NlbkRhdGEgfCB1bmRlZmluZWQgPT4ge1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmV4dHJhY3REYXRhKHRyYW5zYWN0aW9uKTtcbiAgICBpZiAoZGF0YSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdmFsaWRhdGVBZGRyZXNzKGRhdGEudG9DaGFpbiwgZGF0YS50b0FkZHJlc3MpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICBgUmVjZWl2ZXIgYWRkcmVzcyB2YWxpZGF0aW9uIGZhaWxlZCAoYWRkcmVzcyBbJHtkYXRhLnRvQWRkcmVzc31dIG9uIGNoYWluIFske2RhdGEudG9DaGFpbn1dKSB3aXRoIGVycm9yOiAke2V9YCxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGRhdGEuYW1vdW50ID0gdGhpcy50b2tlbnNcbiAgICAgICAgLndyYXBBbW91bnQoZGF0YS5zb3VyY2VDaGFpblRva2VuSWQsIEJpZ0ludChkYXRhLmFtb3VudCksIHRoaXMuY2hhaW4pXG4gICAgICAgIC5hbW91bnQudG9TdHJpbmcoKTtcbiAgICAgIC8vIENvbmRpdGlvbmFsbHkgc2V0IHJhd0RhdGEgYmFzZWQgb24gc3RvcmVSYXdEYXRhIGZsYWdcbiAgICAgIGlmICghdGhpcy5zdG9yZVJhd0RhdGEpIHtcbiAgICAgICAgZGF0YS5yYXdEYXRhID0gJ3Jhdy1kYXRhIGV4dHJhY3Rpb24gaXMgb2ZmJztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG4gIH07XG5cbiAgLyoqXG4gICAqIGV4dHJhY3RzIFJvc2VuRGF0YSBmcm9tIGdpdmVuIGxvY2sgdHJhbnNhY3Rpb25cbiAgICovXG4gIGFic3RyYWN0IGV4dHJhY3REYXRhOiAodHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uVHlwZSkgPT4gUm9zZW5EYXRhIHwgdW5kZWZpbmVkO1xufVxuIl19
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rosen-bridge/rosen-extractor",
|
|
3
|
-
"version": "11.1.
|
|
3
|
+
"version": "11.1.2-6083137b",
|
|
4
4
|
"description": "this project contains methods to get rosen data from blockchain",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"@blockfrost/openapi": "^0.1.80",
|
|
32
32
|
"@cardano-ogmios/schema": "^6.0.3",
|
|
33
33
|
"@emurgo/cardano-serialization-lib-nodejs": "^13.2.1",
|
|
34
|
-
"@rosen-bridge/abstract-logger": "
|
|
34
|
+
"@rosen-bridge/abstract-logger": "4.0.0-6083137b",
|
|
35
35
|
"@rosen-bridge/address-codec": "^1.0.1",
|
|
36
36
|
"@rosen-bridge/json-bigint": "^1.1.0",
|
|
37
|
-
"@rosen-bridge/tokens": "
|
|
37
|
+
"@rosen-bridge/tokens": "5.0.0-6083137b",
|
|
38
38
|
"bitcoinjs-lib": "^6.1.5",
|
|
39
39
|
"ergo-lib-wasm-nodejs": "^0.24.1",
|
|
40
40
|
"ethers": "6.13.2",
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
"rosen"
|
|
55
55
|
],
|
|
56
56
|
"engines": {
|
|
57
|
-
"node": ">=22.18.0"
|
|
57
|
+
"node": ">=22.18.0",
|
|
58
|
+
"npm": "11.6.2"
|
|
58
59
|
}
|
|
59
60
|
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { RosenData, TokenTransformation } from '../abstract/types';
|
|
2
|
-
import AbstractRosenDataExtractor from '../abstract/abstractRosenDataExtractor';
|
|
3
|
-
import { GraphQLTransaction, GraphQLTxOutput } from './types';
|
|
4
|
-
export declare class CardanoGraphQLRosenExtractor extends AbstractRosenDataExtractor<GraphQLTransaction> {
|
|
5
|
-
readonly chain = "cardano";
|
|
6
|
-
/**
|
|
7
|
-
* extracts RosenData from given lock transaction in graphql format
|
|
8
|
-
* @param transaction the lock transaction in graphql format
|
|
9
|
-
*/
|
|
10
|
-
extractRawData: (transaction: GraphQLTransaction) => RosenData | undefined;
|
|
11
|
-
/**
|
|
12
|
-
* extracts and builds token transformation from UTXO and tokenMap
|
|
13
|
-
* @param box transaction output
|
|
14
|
-
* @param toChain event target chain
|
|
15
|
-
*/
|
|
16
|
-
getAssetTransformation: (box: GraphQLTxOutput, toChain: string) => TokenTransformation | undefined;
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=cardanoGraphQLRosenExtractor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cardanoGraphQLRosenExtractor.d.ts","sourceRoot":"","sources":["../../../lib/getRosenData/cardano/cardanoGraphQLRosenExtractor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,0BAA0B,MAAM,wCAAwC,CAAC;AAEhF,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAI9D,qBAAa,4BAA6B,SAAQ,0BAA0B,CAAC,kBAAkB,CAAC;IAC9F,QAAQ,CAAC,KAAK,aAAiB;IAC/B;;;OAGG;IACH,cAAc,GAAI,aAAa,kBAAkB,KAAG,SAAS,GAAG,SAAS,CA8DvE;IAEF;;;;OAIG;IACH,sBAAsB,GACpB,KAAK,eAAe,EACpB,SAAS,MAAM,KACd,mBAAmB,GAAG,SAAS,CA8BhC;CACH"}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { isPlainObject } from 'lodash-es';
|
|
2
|
-
import AbstractRosenDataExtractor from '../abstract/abstractRosenDataExtractor';
|
|
3
|
-
import { CARDANO_CHAIN, CARDANO_NATIVE_TOKEN } from '../const';
|
|
4
|
-
import JsonBigInt from '@rosen-bridge/json-bigint';
|
|
5
|
-
import { getCardanoTokenId, parseRosenData } from './utils';
|
|
6
|
-
export class CardanoGraphQLRosenExtractor extends AbstractRosenDataExtractor {
|
|
7
|
-
chain = CARDANO_CHAIN;
|
|
8
|
-
/**
|
|
9
|
-
* extracts RosenData from given lock transaction in graphql format
|
|
10
|
-
* @param transaction the lock transaction in graphql format
|
|
11
|
-
*/
|
|
12
|
-
extractRawData = (transaction) => {
|
|
13
|
-
const baseError = `No rosen data found for tx [${transaction.hash}]`;
|
|
14
|
-
const metadata = transaction.metadata;
|
|
15
|
-
try {
|
|
16
|
-
if (!metadata || metadata.length === 0) {
|
|
17
|
-
this.logger.debug(baseError + `: No metadata`);
|
|
18
|
-
return undefined;
|
|
19
|
-
}
|
|
20
|
-
const data = metadata.find((data) => data?.key === '0')?.value;
|
|
21
|
-
const rosenData = parseRosenData(data);
|
|
22
|
-
if (rosenData) {
|
|
23
|
-
const lockOutputs = transaction.outputs.filter((output) => output?.address === this.lockAddress);
|
|
24
|
-
for (let i = 0; i < lockOutputs.length; i++) {
|
|
25
|
-
const output = lockOutputs[i];
|
|
26
|
-
if (!output) {
|
|
27
|
-
this.logger.debug(`No rosen asset transformation found for box [${transaction.hash}.${i}]: box is undefined!`);
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
const assetTransformation = this.getAssetTransformation(output, rosenData.toChain);
|
|
31
|
-
if (assetTransformation) {
|
|
32
|
-
return {
|
|
33
|
-
...rosenData,
|
|
34
|
-
sourceChainTokenId: assetTransformation.from,
|
|
35
|
-
amount: assetTransformation.amount,
|
|
36
|
-
targetChainTokenId: assetTransformation.to,
|
|
37
|
-
sourceTxId: transaction.hash,
|
|
38
|
-
// TODO: save rawData in CBOR (local:ergo/rosen-bridge/utils#293)
|
|
39
|
-
rawData: JsonBigInt.stringify(data),
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
else
|
|
43
|
-
this.logger.debug(`No rosen asset transformation found for box [${transaction.hash}.${i}]: box assets: ${JsonBigInt.stringify(output.tokens)}`);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
this.logger.debug(baseError + `: No valid transformation found in any output boxes`);
|
|
47
|
-
}
|
|
48
|
-
else
|
|
49
|
-
this.logger.debug(baseError +
|
|
50
|
-
`: Incomplete metadata. isPlain: ${isPlainObject(data)}, data: ${JsonBigInt.stringify(data)}`);
|
|
51
|
-
}
|
|
52
|
-
catch (e) {
|
|
53
|
-
this.logger.debug(`An error occurred while getting Cardano rosen data from GraphQL: ${e}`);
|
|
54
|
-
if (e instanceof Error && e.stack) {
|
|
55
|
-
this.logger.debug(e.stack);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return undefined;
|
|
59
|
-
};
|
|
60
|
-
/**
|
|
61
|
-
* extracts and builds token transformation from UTXO and tokenMap
|
|
62
|
-
* @param box transaction output
|
|
63
|
-
* @param toChain event target chain
|
|
64
|
-
*/
|
|
65
|
-
getAssetTransformation = (box, toChain) => {
|
|
66
|
-
// try to build transformation using locked assets
|
|
67
|
-
for (const boxToken of box.tokens) {
|
|
68
|
-
const token = this.tokens.search(CARDANO_CHAIN, {
|
|
69
|
-
tokenId: getCardanoTokenId(boxToken.asset.policyId, boxToken.asset.assetName),
|
|
70
|
-
});
|
|
71
|
-
if (token.length > 0 && Object.hasOwn(token[0], toChain))
|
|
72
|
-
return {
|
|
73
|
-
from: this.tokens.getID(token[0], CARDANO_CHAIN),
|
|
74
|
-
to: this.tokens.getID(token[0], toChain),
|
|
75
|
-
amount: boxToken.quantity,
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
// try to build transformation using locked ADA
|
|
79
|
-
const lovelace = this.tokens.search(CARDANO_CHAIN, {
|
|
80
|
-
tokenId: CARDANO_NATIVE_TOKEN,
|
|
81
|
-
});
|
|
82
|
-
if (lovelace.length > 0 && Object.hasOwn(lovelace[0], toChain)) {
|
|
83
|
-
return {
|
|
84
|
-
from: CARDANO_NATIVE_TOKEN,
|
|
85
|
-
to: this.tokens.getID(lovelace[0], toChain),
|
|
86
|
-
amount: box.value,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
return undefined;
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FyZGFub0dyYXBoUUxSb3NlbkV4dHJhY3Rvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9nZXRSb3NlbkRhdGEvY2FyZGFuby9jYXJkYW5vR3JhcGhRTFJvc2VuRXh0cmFjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFMUMsT0FBTywwQkFBMEIsTUFBTSx3Q0FBd0MsQ0FBQztBQUNoRixPQUFPLEVBQUUsYUFBYSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRS9ELE9BQU8sVUFBVSxNQUFNLDJCQUEyQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxjQUFjLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFNUQsTUFBTSxPQUFPLDRCQUE2QixTQUFRLDBCQUE4QztJQUNyRixLQUFLLEdBQUcsYUFBYSxDQUFDO0lBQy9COzs7T0FHRztJQUNILGNBQWMsR0FBRyxDQUFDLFdBQStCLEVBQXlCLEVBQUU7UUFDMUUsTUFBTSxTQUFTLEdBQUcsK0JBQStCLFdBQVcsQ0FBQyxJQUFJLEdBQUcsQ0FBQztRQUNyRSxNQUFNLFFBQVEsR0FBRyxXQUFXLENBQUMsUUFBUSxDQUFDO1FBQ3RDLElBQUksQ0FBQztZQUNILElBQUksQ0FBQyxRQUFRLElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDdkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLGVBQWUsQ0FBQyxDQUFDO2dCQUMvQyxPQUFPLFNBQVMsQ0FBQztZQUNuQixDQUFDO1lBQ0QsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxFQUFFLEdBQUcsS0FBSyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUM7WUFDL0QsTUFBTSxTQUFTLEdBQUcsY0FBYyxD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QyxFQUFFLE9BQU8sQ0FBQztnQkFDdEQsT0FBTztvQkFDTCxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLGFBQWEsQ0FBQztvQkFDaEQsRUFBRSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUM7b0JBQ3hDLE1BQU0sRUFBRSxRQUFRLENBQUMsUUFBUTtpQkFDMUIsQ0FBQztRQUNOLENBQUM7UUFFRCwrQ0FBK0M7UUFDL0MsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFO1lBQ2pELE9BQU8sRUFBRSxvQkFBb0I7U0FDOUIsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQy9ELE9BQU87Z0JBQ0wsSUFBSSxFQUFFLG9CQUFvQjtnQkFDMUIsRUFBRSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUM7Z0JBQzNDLE1BQU0sRUFBRSxHQUFHLENBQUMsS0FBSzthQUNsQixDQUFDO1FBQ0osQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLFNBQVMsQ0FBQztRQUNuQixDQUFDO0lBQ0gsQ0FBQyxDQUFDO0NBQ0giLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpc1BsYWluT2JqZWN0IH0gZnJvbSAnbG9kYXNoLWVzJztcbmltcG9ydCB7IFJvc2VuRGF0YSwgVG9rZW5UcmFuc2Zvcm1hdGlvbiB9IGZyb20gJy4uL2Fic3RyYWN0L3R5cGVzJztcbmltcG9ydCBBYnN0cmFjdFJvc2VuRGF0YUV4dHJhY3RvciBmcm9tICcuLi9hYnN0cmFjdC9hYnN0cmFjdFJvc2VuRGF0YUV4dHJhY3Rvcic7XG5pbXBvcnQgeyBDQVJEQU5PX0NIQUlOLCBDQVJEQU5PX05BVElWRV9UT0tFTiB9IGZyb20gJy4uL2NvbnN0JztcbmltcG9ydCB7IEdyYXBoUUxUcmFuc2FjdGlvbiwgR3JhcGhRTFR4T3V0cHV0IH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgSnNvbkJpZ0ludCBmcm9tICdAcm9zZW4tYnJpZGdlL2pzb24tYmlnaW50JztcbmltcG9ydCB7IGdldENhcmRhbm9Ub2tlbklkLCBwYXJzZVJvc2VuRGF0YSB9IGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgY2xhc3MgQ2FyZGFub0dyYXBoUUxSb3NlbkV4dHJhY3RvciBleHRlbmRzIEFic3RyYWN0Um9zZW5EYXRhRXh0cmFjdG9yPEdyYXBoUUxUcmFuc2FjdGlvbj4ge1xuICByZWFkb25seSBjaGFpbiA9IENBUkRBTk9fQ0hBSU47XG4gIC8qKlxuICAgKiBleHRyYWN0cyBSb3NlbkRhdGEgZnJvbSBnaXZlbiBsb2NrIHRyYW5zYWN0aW9uIGluIGdyYXBocWwgZm9ybWF0XG4gICAqIEBwYXJhbSB0cmFuc2FjdGlvbiB0aGUgbG9jayB0cmFuc2FjdGlvbiBpbiBncmFwaHFsIGZvcm1hdFxuICAgKi9cbiAgZXh0cmFjdFJhd0RhdGEgPSAodHJhbnNhY3Rpb246IEdyYXBoUUxUcmFuc2FjdGlvbik6IFJvc2VuRGF0YSB8IHVuZGVmaW5lZCA9PiB7XG4gICAgY29uc3QgYmFzZUVycm9yID0gYE5vIHJvc2VuIGRhdGEgZm91bmQgZm9yIHR4IFske3RyYW5zYWN0aW9uLmhhc2h9XWA7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0cmFuc2FjdGlvbi5tZXRhZGF0YTtcbiAgICB0cnkge1xuICAgICAgaWYgKCFtZXRhZGF0YSB8fCBtZXRhZGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYmFzZUVycm9yICsgYDogTm8gbWV0YWRhdGFgKTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRhdGEgPSBtZXRhZGF0YS5maW5kKChkYXRhKSA9PiBkYXRhPy5rZXkgPT09ICcwJyk/LnZhbHVlO1xuICAgICAgY29uc3Qgcm9zZW5EYXRhID0gcGFyc2VSb3NlbkRhdGEoZGF0YSk7XG4gICAgICBpZiAocm9zZW5EYXRhKSB7XG4gICAgICAgIGNvbnN0IGxvY2tPdXRwdXRzID0gdHJhbnNhY3Rpb24ub3V0cHV0cy5maWx0ZXIoXG4gICAgICAgICAgKG91dHB1dCkgPT4gb3V0cHV0Py5hZGRyZXNzID09PSB0aGlzLmxvY2tBZGRyZXNzLFxuICAgICAgICApO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxvY2tPdXRwdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgY29uc3Qgb3V0cHV0ID0gbG9ja091dHB1dHNbaV07XG4gICAgICAgICAgaWYgKCFvdXRwdXQpIHtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgICAgICAgICBgTm8gcm9zZW4gYXNzZXQgdHJhbnNmb3JtYXRpb24gZm91bmQgZm9yIGJveCBbJHt0cmFuc2FjdGlvbi5oYXNofS4ke2l9XTogYm94IGlzIHVuZGVmaW5lZCFgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYXNzZXRUcmFuc2Zvcm1hdGlvbiA9IHRoaXMuZ2V0QXNzZXRUcmFuc2Zvcm1hdGlvbihcbiAgICAgICAgICAgICAgb3V0cHV0LFxuICAgICAgICAgICAgICByb3NlbkRhdGEudG9DaGFpbixcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoYXNzZXRUcmFuc2Zvcm1hdGlvbikge1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIC4uLnJvc2VuRGF0YSxcbiAgICAgICAgICAgICAgICBzb3VyY2VDaGFpblRva2VuSWQ6IGFzc2V0VHJhbnNmb3JtYXRpb24uZnJvbSxcbiAgICAgICAgICAgICAgICBhbW91bnQ6IGFzc2V0VHJhbnNmb3JtYXRpb24uYW1vdW50LFxuICAgICAgICAgICAgICAgIHRhcmdldENoYWluVG9rZW5JZDogYXNzZXRUcmFuc2Zvcm1hdGlvbi50byxcbiAgICAgICAgICAgICAgICBzb3VyY2VUeElkOiB0cmFuc2FjdGlvbi5oYXNoLFxuICAgICAgICAgICAgICAgIC8vIFRPRE86IHNhdmUgcmF3RGF0YSBpbiBDQk9SIChsb2NhbDplcmdvL3Jvc2VuLWJyaWRnZS91dGlscyMyOTMpXG4gICAgICAgICAgICAgICAgcmF3RGF0YTogSnNvbkJpZ0ludC5zdHJpbmdpZnkoZGF0YSksXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICAgICAgICAgICAgYE5vIHJvc2VuIGFzc2V0IHRyYW5zZm9ybWF0aW9uIGZvdW5kIGZvciBib3ggWyR7XG4gICAgICAgICAgICAgICAgICB0cmFuc2FjdGlvbi5oYXNoXG4gICAgICAgICAgICAgICAgfS4ke2l9XTogYm94IGFzc2V0czogJHtKc29uQmlnSW50LnN0cmluZ2lmeShvdXRwdXQudG9rZW5zKX1gLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICBiYXNlRXJyb3IgKyBgOiBObyB2YWxpZCB0cmFuc2Zvcm1hdGlvbiBmb3VuZCBpbiBhbnkgb3V0cHV0IGJveGVzYCxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZVxuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgICBiYXNlRXJyb3IgK1xuICAgICAgICAgICAgYDogSW5jb21wbGV0ZSBtZXRhZGF0YS4gaXNQbGFpbjogJHtpc1BsYWluT2JqZWN0KFxuICAgICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgKX0sIGRhdGE6ICR7SnNvbkJpZ0ludC5zdHJpbmdpZnkoZGF0YSl9YCxcbiAgICAgICAgKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgYEFuIGVycm9yIG9jY3VycmVkIHdoaWxlIGdldHRpbmcgQ2FyZGFubyByb3NlbiBkYXRhIGZyb20gR3JhcGhRTDogJHtlfWAsXG4gICAgICApO1xuICAgICAgaWYgKGUgaW5zdGFuY2VvZiBFcnJvciAmJiBlLnN0YWNrKSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGUuc3RhY2spO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9O1xuXG4gIC8qKlxuICAgKiBleHRyYWN0cyBhbmQgYnVpbGRzIHRva2VuIHRyYW5zZm9ybWF0aW9uIGZyb20gVVRYTyBhbmQgdG9rZW5NYXBcbiAgICogQHBhcmFtIGJveCB0cmFuc2FjdGlvbiBvdXRwdXRcbiAgICogQHBhcmFtIHRvQ2hhaW4gZXZlbnQgdGFyZ2V0IGNoYWluXG4gICAqL1xuICBnZXRBc3NldFRyYW5zZm9ybWF0aW9uID0gKFxuICAgIGJveDogR3JhcGhRTFR4T3V0cHV0LFxuICAgIHRvQ2hhaW46IHN0cmluZyxcbiAgKTogVG9rZW5UcmFuc2Zvcm1hdGlvbiB8IHVuZGVmaW5lZCA9PiB7XG4gICAgLy8gdHJ5IHRvIGJ1aWxkIHRyYW5zZm9ybWF0aW9uIHVzaW5nIGxvY2tlZCBhc3NldHNcbiAgICBmb3IgKGNvbnN0IGJveFRva2VuIG9mIGJveC50b2tlbnMpIHtcbiAgICAgIGNvbnN0IHRva2VuID0gdGhpcy50b2tlbnMuc2VhcmNoKENBUkRBTk9fQ0hBSU4sIHtcbiAgICAgICAgdG9rZW5JZDogZ2V0Q2FyZGFub1Rva2VuSWQoXG4gICAgICAgICAgYm94VG9rZW4uYXNzZXQucG9saWN5SWQsXG4gICAgICAgICAgYm94VG9rZW4uYXNzZXQuYXNzZXROYW1lLFxuICAgICAgICApLFxuICAgICAgfSk7XG4gICAgICBpZiAodG9rZW4ubGVuZ3RoID4gMCAmJiBPYmplY3QuaGFzT3duKHRva2VuWzBdLCB0b0NoYWluKSlcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBmcm9tOiB0aGlzLnRva2Vucy5nZXRJRCh0b2tlblswXSwgQ0FSREFOT19DSEFJTiksXG4gICAgICAgICAgdG86IHRoaXMudG9rZW5zLmdldElEKHRva2VuWzBdLCB0b0NoYWluKSxcbiAgICAgICAgICBhbW91bnQ6IGJveFRva2VuLnF1YW50aXR5LFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIHRyeSB0byBidWlsZCB0cmFuc2Zvcm1hdGlvbiB1c2luZyBsb2NrZWQgQURBXG4gICAgY29uc3QgbG92ZWxhY2UgPSB0aGlzLnRva2Vucy5zZWFyY2goQ0FSREFOT19DSEFJTiwge1xuICAgICAgdG9rZW5JZDogQ0FSREFOT19OQVRJVkVfVE9LRU4sXG4gICAgfSk7XG4gICAgaWYgKGxvdmVsYWNlLmxlbmd0aCA+IDAgJiYgT2JqZWN0Lmhhc093bihsb3ZlbGFjZVswXSwgdG9DaGFpbikpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGZyb206IENBUkRBTk9fTkFUSVZFX1RPS0VOLFxuICAgICAgICB0bzogdGhpcy50b2tlbnMuZ2V0SUQobG92ZWxhY2VbMF0sIHRvQ2hhaW4pLFxuICAgICAgICBhbW91bnQ6IGJveC52YWx1ZSxcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9O1xufVxuIl19
|