@steerprotocol/strategy-utils 3.1.1 → 3.2.0

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.
Files changed (36) hide show
  1. package/.github/workflows/nodejs.yml +12 -12
  2. package/.vscode/settings.json +6 -0
  3. package/CHANGELOG.md +3 -45
  4. package/asconfig.json +11 -9
  5. package/assembly/index.ts +1 -0
  6. package/assembly/panoptic/host.ts +285 -0
  7. package/assembly/panoptic/index.ts +3 -0
  8. package/assembly/panoptic/methods.ts +64 -0
  9. package/assembly/panoptic/types.ts +911 -0
  10. package/assembly/utils/Math.ts +12 -17
  11. package/assembly/utils/MovingAverages.ts +26 -19
  12. package/assembly/utils/Ranges.ts +15 -15
  13. package/assembly/utils/UniswapLiquidityUtils.ts +48 -0
  14. package/assembly/utils/index.ts +1 -3
  15. package/assembly/utils/types/Position.ts +0 -3
  16. package/assembly/utils/types/Price.ts +54 -0
  17. package/assembly/utils/types/index.ts +1 -4
  18. package/index.js +3 -14
  19. package/package.json +10 -14
  20. package/scripts/build-docs.js +68 -0
  21. package/tests/fixtures/json-compat.ts +30 -0
  22. package/tests/fixtures/panoptic-consumer.ts +24 -0
  23. package/tests/index.test.ts +55 -227
  24. package/assembly/utils/CandleGenerator.ts +0 -60
  25. package/assembly/utils/MarketFeedAggregator.ts +0 -140
  26. package/assembly/utils/SlidingWindow.ts +0 -59
  27. package/assembly/utils/env.ts +0 -23
  28. package/assembly/utils/triggers.ts +0 -438
  29. package/assembly/utils/types/Candle.ts +0 -39
  30. package/assembly/utils/types/DataConnectorConfig.ts +0 -7
  31. package/assembly/utils/types/ExecutionContext.ts +0 -11
  32. package/assembly/utils/types/RawTradeData.ts +0 -14
  33. package/index.html +0 -10
  34. package/readme.md +0 -387
  35. package/tests/debug.wasm +0 -0
  36. package/tests/utils.ts +0 -607
@@ -1,4 +1,4 @@
1
- export function _getMax(arr: Array<f64>): f64 {
1
+ export function _getMax(arr: Array<f32>): f32 {
2
2
  let max = arr[0];
3
3
  for (let i = 1; i < arr.length; i++) {
4
4
  if (arr[i] > max) {
@@ -8,41 +8,36 @@ export function _getMax(arr: Array<f64>): f64 {
8
8
  return max;
9
9
  }
10
10
 
11
- export function getMax(a: f64, b: f64): f64 {
11
+ export function getMax(a: f32, b: f32): f32 {
12
12
  if (a >= b) return a
13
13
  return b
14
14
  }
15
15
 
16
16
 
17
- export function _normalDensity(std: f64, mean: f64, x: f64): f64 {
18
- return f64(
19
- (f64(Math.E) ** (((x - mean) / std) ** 2 / -2) / std) *
20
- Math.sqrt(2 * f64(Math.PI))
17
+ export function _normalDensity(std: f32, mean: f32, x: f32): f32 {
18
+ return f32(
19
+ (f32(Math.E) ** (((x - mean) / std) ** 2 / -2) / std) *
20
+ Math.sqrt(2 * f32(Math.PI))
21
21
  );
22
22
  }
23
23
 
24
- export function _standardDeviation(list:f64[]): f64 {
24
+ export function _standardDeviation(list:f32[]): f32 {
25
25
  const mean = _mean(list)
26
- const sqrdDiff: f64[] = []
26
+ const sqrdDiff: f32[] = []
27
27
  for (let i = 0; i < list.length; i++){
28
28
  sqrdDiff.push((list[i]-mean)*(list[i]-mean))
29
29
  }
30
30
  const variance = _mean(sqrdDiff)
31
31
  const stddev = Math.sqrt(variance)
32
- return f64(stddev)
32
+ return f32(stddev)
33
33
  }
34
34
 
35
35
  // SMA simple moving average
36
- export function _mean(list: f64[]): f64 {
36
+ export function _mean(list: f32[]): f32 {
37
37
  const length = list.length;
38
- let total: f64 = 0.0;
38
+ let total: f32 = 0.0;
39
39
  for (let i = 0; i < length; i++){
40
40
  total += list[i]
41
41
  }
42
- return total / f64(length)
43
- }
44
-
45
- export function closestDivisibleNumber(num: number, divisor: number, floor: boolean): number {
46
- if (floor) return Math.floor(num / divisor) * divisor;
47
- return Math.ceil(num / divisor) * divisor;
42
+ return total / f32(length)
48
43
  }
@@ -1,18 +1,22 @@
1
+
2
+
3
+ // WARNING: classes will initially be allocated 1 page of memory, you will likely need to add size or flatten these classes
1
4
  export class SMA {
2
- private readonly prices: f64[] = [];
5
+ private readonly prices: f32[] = [];
3
6
  private interval: i32 = 0;
4
- private result: f64 = 0
5
- // private prevEMA: f64;
7
+ private result: f32;
8
+ private prevEMA: f32;
6
9
 
7
10
  constructor(interval: i32) {
8
11
  this.interval = interval;
9
12
  }
10
13
 
11
- getResult(): f64 {
14
+ getResult(): f32 {
12
15
  return this.result;
13
16
  }
14
17
 
15
- update(price: f64): void {
18
+
19
+ update(price: f32): void {
16
20
  this.prices.push(price);
17
21
 
18
22
  if (this.prices.length > this.interval) {
@@ -20,47 +24,50 @@ export class SMA {
20
24
  }
21
25
 
22
26
  if (this.prices.length === this.interval) {
23
- let result = f64(0);
27
+ let result = f32(0);
24
28
  for (let priceIndex = 0; priceIndex < this.prices.length; priceIndex++) {
25
- result = result + this.prices[priceIndex];
29
+ result = result + this.prices[priceIndex]
26
30
  }
27
- this.result = result / f64(this.prices.length || 1);
31
+ this.result = result / f32(this.prices.length || 1);
28
32
  }
33
+
29
34
  }
30
35
  }
31
36
 
32
37
  export class EMA {
33
- private readonly prices: f64[] = [];
38
+ private readonly prices: f32[] = [];
34
39
  private interval: i32 = 0;
35
- private result: f64 = 0
40
+ private result: f32;
36
41
  private multiplier: i32;
37
- private prevEMA: f64 = 0
42
+ private prevEMA : f32
43
+
38
44
 
39
45
  constructor(interval: i32, multiplier: i32) {
40
46
  this.interval = interval;
41
47
  this.multiplier = multiplier;
42
48
  }
43
49
 
44
- getResult(): f64 {
50
+ getResult(): f32 {
45
51
  return this.result;
46
52
  }
47
53
 
48
- update(price: f64): void {
54
+ update(price: f32): void {
49
55
  this.prices.push(price);
50
56
 
51
57
  if (this.prices.length > this.interval) {
52
58
  this.prices.shift();
53
- } // remove oldest price
59
+ } // remove oldest price
54
60
 
55
61
  if (!this.prevEMA) {
56
62
  this.prevEMA = price;
57
63
  }
58
64
 
59
- let p1 = price * (f64(this.multiplier) / (1 + f64(this.interval)));
60
- let p2 =
61
- this.prevEMA * (1 - f64(this.multiplier) / (1 + f64(this.interval)));
62
65
 
63
- this.result = f64(p1 + p2);
66
+ let p1 = price * (f32(this.multiplier) / (1 + f32(this.interval)))
67
+ let p2 = this.prevEMA * (1 - (f32(this.multiplier) / (1 + f32(this.interval))))
68
+
69
+ this.result = f32(p1 + p2)
64
70
  this.prevEMA = this.result;
71
+
65
72
  }
66
- }
73
+ }
@@ -1,47 +1,47 @@
1
- import { Candle } from "./types/Candle";
1
+ import { Price } from "./types/Price";
2
2
  import { getMax, _mean, _getMax } from "./Math";
3
3
 
4
- export function getAverageTrueRange(candles: Array<Candle>): f64 {
5
- let rangeSum: f64 = 0;
6
- for (let i = 1; i < candles.length; i++) {
7
- const currentPrice = candles[i];
4
+ export function getAverageTrueRange(prices: Array<Price>, interval: i32): f32 {
5
+ let rangeSum: f32 = 0;
6
+ for (let i = 1; i < prices.length; i++) {
7
+ const currentPrice = prices[i];
8
8
 
9
9
  const currentHigh = currentPrice.high
10
10
  const currentLow = currentPrice.low
11
- const previousClose = candles[i - 1].close
11
+ const previousClose = prices[i - 1].close
12
12
 
13
13
  const range1 = Math.abs(currentHigh - previousClose);
14
14
  const range2 = Math.abs(currentLow - previousClose);
15
15
  const range3 = Math.abs(currentHigh - currentLow);
16
16
 
17
- let max = _getMax([f64(range1), f64(range2), f64(range3)]);
17
+ let max = _getMax([f32(range1), f32(range2), f32(range3)]);
18
18
  rangeSum += max;
19
19
  }
20
20
 
21
21
 
22
- return f64(rangeSum) / f64(candles.length - 1);
22
+ return f32(rangeSum) / f32(prices.length - 1);
23
23
 
24
24
  }
25
25
 
26
26
 
27
- export function trailingStop(percent: f64, prices: Candle[]): f64 {
27
+ export function trailingStop(percent: f32, prices: Price[]): f32 {
28
28
  // Get the current price of the asset pair
29
29
  const currentPrice = prices[prices.length - 1];
30
30
 
31
31
  // Calculate the trailing stop price
32
- const trailingStopPrice = currentPrice.close - (currentPrice.close * f64(percent / 100));
32
+ const trailingStopPrice = currentPrice.close - (currentPrice.close * f32(percent / 100));
33
33
 
34
34
  // Return the trailing stop price
35
- return f64(trailingStopPrice);
35
+ return trailingStopPrice;
36
36
  }
37
37
 
38
- export function trueRange(price: Candle): f64{
39
- const trueRange = getMax(f64(price.high) - f64(price.low),getMax(f64(Math.abs(price.high-price.close)),f64(Math.abs(price.low-price.close))));
38
+ export function trueRange(price: Price): f32{
39
+ const trueRange = getMax(price.high - price.low,getMax(f32(Math.abs(price.high-price.close)),f32(Math.abs(price.low-price.close))));
40
40
  return trueRange;
41
41
  }
42
42
 
43
- export function averageTrueRange(prices: Candle[]): f64 {
44
- const trueRanges: f64[] = []
43
+ export function averageTrueRange(prices: Price[]): f32 {
44
+ const trueRanges: f32[] = []
45
45
  for (let i = 0; i < prices.length; i++) {
46
46
  trueRanges.push(trueRange(prices[i]));
47
47
  }
@@ -0,0 +1,48 @@
1
+ import {Position } from "./types";
2
+
3
+ export function getTickSpacing(poolFee: i32): i32{
4
+ let spacing = 0;
5
+ switch (poolFee){
6
+ case 100:
7
+ spacing = 1;
8
+ break;
9
+ case 500:
10
+ spacing = 10;
11
+ break;
12
+ case 3000:
13
+ spacing = 60;
14
+ break;
15
+ default:
16
+ spacing = 200;
17
+ }
18
+ return spacing;
19
+ }
20
+
21
+ // Function shaped for making positions with the UniLiquidityManager contract for ease
22
+ export function renderULMResult(positions: Array<Position>): string {
23
+
24
+ // Construct necessary object
25
+ const lowerTicks: Array<i32> = []
26
+ const upperTicks: Array<i32> = []
27
+ const weights: Array<i32> = []
28
+
29
+ for (let i = 0; i < positions.length; i++) {
30
+ lowerTicks.push(positions[i].startTick)
31
+ upperTicks.push(positions[i].endTick)
32
+ weights.push(positions[i].weight)
33
+ }
34
+
35
+ return `{"functionName":"tend(uint256,(int24[],int24[],uint16[]),bytes)",
36
+ "typesArray":["uint256","tuple(int24[],int24[],uint16[])","bytes"],
37
+ "valuesArray":[10000, [[`+lowerTicks.toString() +'],['+upperTicks.toString()+'],['+ weights.toString() +`]], "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000ffffffffffffffffffffffffffffffffffffffff"]
38
+ }`
39
+ // The bytes value here is a placeholder for encoding that gets replaced with time-sensitive data upon execution. It will actually be the swap amount for rebalancing (int256) and slippage limit (uint160)
40
+ }
41
+
42
+ // TODO: Might need to be rewritten for assets
43
+ // Price must be in the native token
44
+ // token0 for token1
45
+ export function getTickFromPrice(price: f32): f32 {
46
+ const tick = Math.log(price) / Math.log(f32(1.0001));
47
+ return f32(tick);
48
+ }
@@ -1,8 +1,6 @@
1
1
  export * from './Math';
2
2
  export * from './MovingAverages';
3
3
  export * from './Ranges';
4
- export * from './SlidingWindow';
4
+ export * from './UniswapLiquidityUtils';
5
5
  export * from './console';
6
- export * from './env';
7
6
  export * from './types';
8
- export * from './triggers'
@@ -1,6 +1,3 @@
1
- import { JSON } from 'json-as/assembly';
2
-
3
- @serializable
4
1
  export class Position
5
2
  {
6
3
  constructor(
@@ -0,0 +1,54 @@
1
+ import { JSON } from "json-as/assembly";
2
+
3
+ @serializable
4
+ export class Price {
5
+ constructor(
6
+ public high: f32 = 0,
7
+ public low: f32 = 0,
8
+ public open: f32 = 0,
9
+ public close: f32 = 0
10
+ ) {}
11
+ }
12
+
13
+ function parsePriceField(candle: JSON.Obj, key: string): f32 {
14
+ const value = candle.get(key);
15
+
16
+ if (value === null) {
17
+ return 0;
18
+ }
19
+
20
+ if (value!.type == JSON.Types.String) {
21
+ return f32.parse(value!.get<string>());
22
+ }
23
+
24
+ return f32.parse(value!.toString());
25
+ }
26
+
27
+ export function parsePrices(_prices: string): Array<Price> {
28
+ const payload = JSON.parse<JSON.Obj>(_prices);
29
+ const dataValue = payload.get("data");
30
+
31
+ if (dataValue === null) {
32
+ return [];
33
+ }
34
+
35
+ const data = dataValue!.get<JSON.Arr>();
36
+ if (data.length == 0) {
37
+ return [];
38
+ }
39
+
40
+ const candles = data.getAs<JSON.Arr>(0);
41
+ const result = new Array<Price>();
42
+
43
+ for (let priceIndex = 0; priceIndex < candles.length; priceIndex++) {
44
+ const candle = candles.getAs<JSON.Obj>(priceIndex);
45
+ result.push(new Price(
46
+ parsePriceField(candle, "high"),
47
+ parsePriceField(candle, "low"),
48
+ parsePriceField(candle, "open"),
49
+ parsePriceField(candle, "close"),
50
+ ));
51
+ }
52
+
53
+ return result;
54
+ }
@@ -1,5 +1,2 @@
1
- export * from './Candle';
2
- export * from './ExecutionContext';
3
- export * from './DataConnectorConfig';
4
1
  export * from './Position';
5
- export * from './RawTradeData';
2
+ export * from './Price';
package/index.js CHANGED
@@ -1,14 +1,3 @@
1
- // const fs = require("fs");
2
- // import * as AsBind from "as-bind/dist/as-bind.cjs.js";
3
-
4
- // const imports = {
5
- // console: { // File which you are injecting
6
- // log(strPtr) {
7
- // console.log(strPtr)
8
- // }
9
- // }
10
- // };
11
-
12
- // const asBindInstance = AsBind.instantiateSync(fs.readFileSync(__dirname + "/build/untouched.wasm"), imports)
13
-
14
- // module.exports = asBindInstance.exports;
1
+ throw new Error(
2
+ '@steerprotocol/strategy-utils is an AssemblyScript source package. Import from assembly/index.ts in AssemblyScript strategies.',
3
+ );
package/package.json CHANGED
@@ -1,42 +1,38 @@
1
1
  {
2
2
  "name": "@steerprotocol/strategy-utils",
3
- "version": "3.1.1",
3
+ "version": "3.2.0",
4
4
  "description": "Strategy utilities library for Steer Protocol strategies",
5
5
  "main": "assembly/index.ts",
6
6
  "types": "assembly/index.ts",
7
7
  "scripts": {
8
8
  "test": "yarn jest",
9
- "asbuild:debug": "asc assembly/index.ts --target debug",
10
- "asbuild:release": "asc assembly/index.ts --target release",
11
- "asbuild": "npm run asbuild:debug && npm run asbuild:release",
12
- "start": "npx serve .",
13
- "docs": "typedoc --tsconfig ./tsconfig.json",
9
+ "asbuild:untouched": "asc assembly/index.ts --target debug --exportRuntime",
10
+ "asbuild:optimized": "asc assembly/index.ts --target release --exportRuntime",
11
+ "asbuild": "npm run asbuild:untouched && npm run asbuild:optimized",
12
+ "docs": "node scripts/build-docs.js",
14
13
  "strategy": "yarn asbuild && yarn test",
15
14
  "semantic-release": "semantic-release",
16
- "commit": "cz",
17
- "postinstall": "patch-package"
15
+ "commit": "cz"
18
16
  },
19
17
  "author": "Derek Barrera <derekbarrera@gmail.com>",
20
18
  "license": "ISC",
21
19
  "dependencies": {
20
+ "@assemblyscript/loader": "^0.28.19",
22
21
  "@babel/preset-typescript": "^7.14.5",
23
22
  "@semantic-release/changelog": "^5.0.1",
24
23
  "@semantic-release/git": "^9.0.0",
25
- "@steerprotocol/app-loader": "^0.2.2",
26
- "@steerprotocol/base-strategy": "0.1.0",
27
- "as-bignum": "^0.2.23",
24
+ "@steerprotocol/base-strategy": "^0.0.2",
28
25
  "commitizen": "^4.2.4",
29
26
  "conventional-changelog-conventionalcommits": "^4.6.0",
30
- "json-as": "^0.5.43",
31
- "patch-package": "^8.0.0",
32
27
  "typescript": "^4.3.5",
28
+ "json-as": "^1.2.6",
33
29
  "visitor-as": "^0.11.4"
34
30
  },
35
31
  "devDependencies": {
36
32
  "@babel/preset-env": "^7.14.8",
37
33
  "@types/jest": "^27.0.1",
38
34
  "@types/node": "^16.11.11",
39
- "assemblyscript": "^0.27.0",
35
+ "assemblyscript": "^0.28.19",
40
36
  "babel-core": "^6.26.3",
41
37
  "babel-jest": "^27.0.6",
42
38
  "cz-conventional-changelog": "3.3.0",
@@ -0,0 +1,68 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ const docsDir = path.join(process.cwd(), 'docs');
5
+ fs.mkdirSync(docsDir, { recursive: true });
6
+
7
+ const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
8
+ const files = [
9
+ 'assembly/index.ts',
10
+ 'assembly/utils/index.ts',
11
+ 'assembly/panoptic/index.ts',
12
+ 'assembly/panoptic/methods.ts',
13
+ 'assembly/panoptic/types.ts',
14
+ 'assembly/panoptic/host.ts',
15
+ ].filter((file) => fs.existsSync(file));
16
+
17
+ const methodFile = 'assembly/panoptic/methods.ts';
18
+ const methods = fs.existsSync(methodFile)
19
+ ? Array.from(fs.readFileSync(methodFile, 'utf8').matchAll(/export const ([A-Z0-9_]+) = \"([^\"]+)\";/g)).map((match) => ({
20
+ name: match[1],
21
+ method: match[2],
22
+ }))
23
+ : [];
24
+
25
+ const escapeHtml = (value) => value
26
+ .replace(/&/g, '&amp;')
27
+ .replace(/</g, '&lt;')
28
+ .replace(/>/g, '&gt;')
29
+ .replace(/\"/g, '&quot;');
30
+
31
+ const html = `<!doctype html>
32
+ <html lang="en">
33
+ <head>
34
+ <meta charset="utf-8">
35
+ <meta name="viewport" content="width=device-width, initial-scale=1">
36
+ <title>${escapeHtml(packageJson.name)} ${escapeHtml(packageJson.version)}</title>
37
+ <style>
38
+ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; margin: 2rem; line-height: 1.5; color: #1f2937; }
39
+ main { max-width: 960px; }
40
+ code { background: #f3f4f6; padding: 0.125rem 0.25rem; border-radius: 4px; }
41
+ table { border-collapse: collapse; width: 100%; margin-top: 1rem; }
42
+ th, td { border: 1px solid #d1d5db; padding: 0.5rem; text-align: left; }
43
+ th { background: #f9fafb; }
44
+ </style>
45
+ </head>
46
+ <body>
47
+ <main>
48
+ <h1>${escapeHtml(packageJson.name)} ${escapeHtml(packageJson.version)}</h1>
49
+ <p>AssemblyScript source package for Steer strategy utilities.</p>
50
+ <h2>Import</h2>
51
+ <pre><code>import { PanopticMethods, erc20ApproveFragment } from "@steerprotocol/strategy-utils/assembly";</code></pre>
52
+ <h2>Entrypoints</h2>
53
+ <ul>
54
+ ${files.map((file) => `<li><code>${escapeHtml(file)}</code></li>`).join('\n ')}
55
+ </ul>
56
+ <h2>Panoptic RuntimeAdapter Methods</h2>
57
+ <table>
58
+ <thead><tr><th>Constant</th><th>Method</th></tr></thead>
59
+ <tbody>
60
+ ${methods.map(({ name, method }) => `<tr><td><code>${escapeHtml(name)}</code></td><td><code>${escapeHtml(method)}</code></td></tr>`).join('\n ')}
61
+ </tbody>
62
+ </table>
63
+ </main>
64
+ </body>
65
+ </html>
66
+ `;
67
+
68
+ fs.writeFileSync(path.join(docsDir, 'index.html'), html);
@@ -0,0 +1,30 @@
1
+ import { JSON } from "json-as/assembly";
2
+ import { MerkleArtifactDto } from "../../assembly/panoptic/types";
3
+ import { parsePrices } from "../../assembly/utils/types/Price";
4
+
5
+ export function parseStringifiedPrices(): string {
6
+ const prices = parsePrices('{"data":[[{"high":"123.4","low":"120.1","open":"121.2","close":"122.3"},{"high":124.5,"low":121.2,"open":122.3,"close":123.4}]]}');
7
+
8
+ if (prices.length != 2) {
9
+ return "bad-length:" + prices.length.toString();
10
+ }
11
+
12
+ if (prices[0].high < 123.39 || prices[0].high > 123.41) {
13
+ return "bad-string-high:" + prices[0].high.toString();
14
+ }
15
+
16
+ if (prices[0].close < 122.29 || prices[0].close > 122.31) {
17
+ return "bad-string-close:" + prices[0].close.toString();
18
+ }
19
+
20
+ if (prices[1].high < 124.49 || prices[1].high > 124.51) {
21
+ return "bad-number-high:" + prices[1].high.toString();
22
+ }
23
+
24
+ return "ok";
25
+ }
26
+
27
+ export function roundTripMerkleProofActions(input: string): string {
28
+ const artifact = JSON.parse<MerkleArtifactDto>(input);
29
+ return JSON.stringify<Map<string, string[]>>(artifact.proofsByAction);
30
+ }
@@ -0,0 +1,24 @@
1
+ import {
2
+ DynamicJobFragmentDto,
3
+ Erc20ApproveFragmentRequestDto,
4
+ PanopticMethods,
5
+ erc20ApproveFragment,
6
+ } from "../../assembly";
7
+
8
+ export function buildTypedPanopticRequest(): string {
9
+ const request = new Erc20ApproveFragmentRequestDto();
10
+ request.args.token = "0x00000000000000000000000000000000000000a0";
11
+ request.args.spender = "0x00000000000000000000000000000000000000b0";
12
+ request.args.amount = "100";
13
+
14
+ return PanopticMethods.ERC20_APPROVE_FRAGMENT
15
+ + ":" + request.args.token
16
+ + ":" + request.args.spender
17
+ + ":" + request.args.amount;
18
+ }
19
+
20
+ export function compileTypedPanopticWrapper(): string {
21
+ const response = erc20ApproveFragment(new Erc20ApproveFragmentRequestDto());
22
+ const fragment: DynamicJobFragmentDto = response.result;
23
+ return fragment.value;
24
+ }