@steerprotocol/strategy-utils 3.1.2 → 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.
- package/.github/workflows/nodejs.yml +12 -12
- package/.vscode/settings.json +6 -0
- package/CHANGELOG.md +3 -45
- package/asconfig.json +11 -9
- package/assembly/index.ts +1 -0
- package/assembly/panoptic/host.ts +285 -0
- package/assembly/panoptic/index.ts +3 -0
- package/assembly/panoptic/methods.ts +64 -0
- package/assembly/panoptic/types.ts +911 -0
- package/assembly/utils/Math.ts +12 -17
- package/assembly/utils/MovingAverages.ts +26 -19
- package/assembly/utils/Ranges.ts +15 -15
- package/assembly/utils/UniswapLiquidityUtils.ts +48 -0
- package/assembly/utils/index.ts +1 -3
- package/assembly/utils/types/Position.ts +0 -3
- package/assembly/utils/types/Price.ts +54 -0
- package/assembly/utils/types/index.ts +1 -4
- package/index.js +3 -14
- package/package.json +10 -14
- package/scripts/build-docs.js +68 -0
- package/tests/fixtures/json-compat.ts +30 -0
- package/tests/fixtures/panoptic-consumer.ts +24 -0
- package/tests/index.test.ts +55 -227
- package/assembly/utils/CandleGenerator.ts +0 -60
- package/assembly/utils/MarketFeedAggregator.ts +0 -140
- package/assembly/utils/SlidingWindow.ts +0 -59
- package/assembly/utils/env.ts +0 -23
- package/assembly/utils/triggers.ts +0 -585
- package/assembly/utils/types/Candle.ts +0 -39
- package/assembly/utils/types/DataConnectorConfig.ts +0 -7
- package/assembly/utils/types/ExecutionContext.ts +0 -11
- package/assembly/utils/types/RawTradeData.ts +0 -14
- package/index.html +0 -10
- package/readme.md +0 -387
- package/tests/debug.wasm +0 -0
- package/tests/utils.ts +0 -607
package/assembly/utils/Math.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function _getMax(arr: Array<
|
|
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:
|
|
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:
|
|
18
|
-
return
|
|
19
|
-
(
|
|
20
|
-
Math.sqrt(2 *
|
|
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:
|
|
24
|
+
export function _standardDeviation(list:f32[]): f32 {
|
|
25
25
|
const mean = _mean(list)
|
|
26
|
-
const sqrdDiff:
|
|
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
|
|
32
|
+
return f32(stddev)
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
// SMA simple moving average
|
|
36
|
-
export function _mean(list:
|
|
36
|
+
export function _mean(list: f32[]): f32 {
|
|
37
37
|
const length = list.length;
|
|
38
|
-
let total:
|
|
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 /
|
|
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:
|
|
5
|
+
private readonly prices: f32[] = [];
|
|
3
6
|
private interval: i32 = 0;
|
|
4
|
-
private result:
|
|
5
|
-
|
|
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():
|
|
14
|
+
getResult(): f32 {
|
|
12
15
|
return this.result;
|
|
13
16
|
}
|
|
14
17
|
|
|
15
|
-
|
|
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 =
|
|
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 /
|
|
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:
|
|
38
|
+
private readonly prices: f32[] = [];
|
|
34
39
|
private interval: i32 = 0;
|
|
35
|
-
private result:
|
|
40
|
+
private result: f32;
|
|
36
41
|
private multiplier: i32;
|
|
37
|
-
private prevEMA:
|
|
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():
|
|
50
|
+
getResult(): f32 {
|
|
45
51
|
return this.result;
|
|
46
52
|
}
|
|
47
53
|
|
|
48
|
-
update(price:
|
|
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
|
-
}
|
|
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.
|
|
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
|
+
}
|
package/assembly/utils/Ranges.ts
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Price } from "./types/Price";
|
|
2
2
|
import { getMax, _mean, _getMax } from "./Math";
|
|
3
3
|
|
|
4
|
-
export function getAverageTrueRange(
|
|
5
|
-
let rangeSum:
|
|
6
|
-
for (let i = 1; i <
|
|
7
|
-
const currentPrice =
|
|
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 =
|
|
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([
|
|
17
|
+
let max = _getMax([f32(range1), f32(range2), f32(range3)]);
|
|
18
18
|
rangeSum += max;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
return
|
|
22
|
+
return f32(rangeSum) / f32(prices.length - 1);
|
|
23
23
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
export function trailingStop(percent:
|
|
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 *
|
|
32
|
+
const trailingStopPrice = currentPrice.close - (currentPrice.close * f32(percent / 100));
|
|
33
33
|
|
|
34
34
|
// Return the trailing stop price
|
|
35
|
-
return
|
|
35
|
+
return trailingStopPrice;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
export function trueRange(price:
|
|
39
|
-
const trueRange = getMax(
|
|
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:
|
|
44
|
-
const trueRanges:
|
|
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
|
+
}
|
package/assembly/utils/index.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
export * from './Math';
|
|
2
2
|
export * from './MovingAverages';
|
|
3
3
|
export * from './Ranges';
|
|
4
|
-
export * from './
|
|
4
|
+
export * from './UniswapLiquidityUtils';
|
|
5
5
|
export * from './console';
|
|
6
|
-
export * from './env';
|
|
7
6
|
export * from './types';
|
|
8
|
-
export * from './triggers'
|
|
@@ -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
|
+
}
|
package/index.js
CHANGED
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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.
|
|
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:
|
|
10
|
-
"asbuild:
|
|
11
|
-
"asbuild": "npm run asbuild:
|
|
12
|
-
"
|
|
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/
|
|
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.
|
|
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, '&')
|
|
27
|
+
.replace(/</g, '<')
|
|
28
|
+
.replace(/>/g, '>')
|
|
29
|
+
.replace(/\"/g, '"');
|
|
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
|
+
}
|