assembly/core/strategies/helpers/strategy.ts

141 lines
3.0 KiB
TypeScript
Raw Normal View History

2021-08-22 15:45:37 +00:00
import DSA, { Spell } from "dsa-connect";
2021-08-22 11:27:02 +00:00
import Web3 from "web3";
2021-08-22 13:49:31 +00:00
import slugify from "slugify";
2021-08-22 11:27:02 +00:00
export interface IStrategyContext {
2021-08-22 15:45:37 +00:00
dsa: DSA;
2021-08-22 11:27:02 +00:00
web3: Web3;
2021-08-22 15:45:37 +00:00
inputs: IStrategyInput<StrategyInputType>[];
2021-08-22 11:27:02 +00:00
}
export interface IStrategyToken {
2021-08-22 13:49:31 +00:00
address: string;
key: string;
symbol: string;
balance: string;
2021-08-22 11:27:02 +00:00
2021-08-22 13:49:31 +00:00
supply: string;
borrow: string;
2021-08-22 11:27:02 +00:00
}
export enum StrategyInputType {
INPUT = "input",
INPUT_WITH_TOKEN = "input-with-token"
}
2021-08-22 15:45:37 +00:00
export type StrategyInputParameterMap = {
[StrategyInputType.INPUT]: {};
2021-08-22 12:54:23 +00:00
2021-08-22 15:45:37 +00:00
[StrategyInputType.INPUT_WITH_TOKEN]: {
token?: IStrategyToken;
};
};
export interface IStrategyInput<InputType extends StrategyInputType> {
type: InputType;
2021-08-22 11:27:02 +00:00
name: string;
2021-08-22 15:45:37 +00:00
placeholder: (
context: IStrategyContext & {
input: IStrategyInput<InputType> & StrategyInputParameterMap[InputType];
}
) => string;
2021-08-22 13:49:31 +00:00
validate?: (
2021-08-22 15:45:37 +00:00
context: IStrategyContext & {
input: IStrategyInput<InputType> & StrategyInputParameterMap[InputType];
}
) => string | void;
2021-08-22 11:27:02 +00:00
value?: any;
2021-08-22 12:54:23 +00:00
[key: string]: any;
2021-08-22 11:27:02 +00:00
}
export interface IStrategy {
2021-08-22 12:54:23 +00:00
id?: string;
2021-08-22 11:27:02 +00:00
name: string;
description: string;
author?: string;
2021-08-22 15:45:37 +00:00
inputs: IStrategyInput<any>[];
2021-08-22 11:27:02 +00:00
2021-08-22 15:45:37 +00:00
spells: (context: IStrategyContext) => Promise<Spell[]> | Spell[];
2021-08-22 12:54:23 +00:00
submitText?: string;
2021-08-22 11:27:02 +00:00
}
2021-08-22 15:45:37 +00:00
export function defineInput<InputType extends StrategyInputType>(
input: IStrategyInput<InputType>
) {
return input as IStrategyInput<any>;
}
2021-08-22 13:49:31 +00:00
export function defineStrategy(strategy: IStrategy) {
2021-08-22 15:45:37 +00:00
const context = {
web3: null,
dsa: null
};
2021-08-22 13:49:31 +00:00
return {
...strategy,
2021-08-22 15:45:37 +00:00
id: strategy.id ? strategy.id : slugify(strategy.name).toLowerCase(),
2021-08-22 13:49:31 +00:00
inputs: strategy.inputs.map(input => ({
...input,
value: null,
2021-08-22 15:45:37 +00:00
placeholder: () =>
input.placeholder
? input.placeholder({
...context,
inputs: strategy.inputs,
input: {
...input,
token: {
// todo
}
}
})
: null,
2021-08-22 13:49:31 +00:00
onInput: (val: any) => {
input.value = val;
}
})),
2021-08-22 15:45:37 +00:00
submit: async () => {
2021-08-22 13:49:31 +00:00
await this.validate({
...context,
inputs: strategy.inputs
});
2021-08-22 12:54:23 +00:00
2021-08-22 15:45:37 +00:00
const allSpells = await strategy.spells({
2021-08-22 13:49:31 +00:00
...context,
inputs: strategy.inputs
});
2021-08-22 12:54:23 +00:00
2021-08-22 15:45:37 +00:00
const spells = context.dsa.Spell();
for (const spell of allSpells) {
spells.add(spell);
}
2021-08-22 13:49:31 +00:00
return await context.dsa.cast({
spells,
onReceipt: this.onReceipt
});
},
2021-08-22 15:45:37 +00:00
validate: async () => {
2021-08-22 13:49:31 +00:00
for (const input of this.inputs) {
const result = await input.validate({
...context,
inputs: strategy.inputs,
input
});
if (result !== true) {
throw new Error(result || "Error has occurred");
}
}
},
onReceipt: (txHash: string, txReceipt: any) => {
// do something
}
};
2021-08-22 11:27:02 +00:00
}
2021-08-22 13:49:31 +00:00
export type DefineStrategy = ReturnType<typeof defineStrategy>;