2021-08-22 17:35:46 +00:00
|
|
|
import DSA from "dsa-connect";
|
2021-08-22 11:27:02 +00:00
|
|
|
import Web3 from "web3";
|
2021-08-22 17:35:46 +00:00
|
|
|
import { DefineStrategy, IStrategyContext } from ".";
|
2021-08-22 12:54:23 +00:00
|
|
|
|
2021-08-22 17:35:46 +00:00
|
|
|
export class Strategy {
|
|
|
|
schema: DefineStrategy;
|
|
|
|
inputs = [];
|
|
|
|
context = {
|
2021-08-25 11:13:23 +00:00
|
|
|
web3: null as Web3,
|
|
|
|
dsa: null as DSA
|
2021-08-22 15:45:37 +00:00
|
|
|
};
|
2021-08-22 11:27:02 +00:00
|
|
|
|
2021-08-22 17:35:46 +00:00
|
|
|
listeners = [];
|
2021-08-22 11:27:02 +00:00
|
|
|
|
2021-08-22 17:35:46 +00:00
|
|
|
props: object = {
|
|
|
|
prices: {},
|
|
|
|
dsaTokens: {},
|
2021-08-22 18:32:28 +00:00
|
|
|
userTokens: {}
|
2021-08-22 17:35:46 +00:00
|
|
|
};
|
2021-08-22 11:27:02 +00:00
|
|
|
|
2021-08-22 17:35:46 +00:00
|
|
|
constructor(schema: DefineStrategy) {
|
|
|
|
this.schema = schema;
|
2021-08-22 12:54:23 +00:00
|
|
|
|
2021-08-23 23:07:53 +00:00
|
|
|
this.inputs = this.generateInputs(this.schema.inputs);
|
|
|
|
}
|
|
|
|
|
|
|
|
getBaseContext(): Omit<IStrategyContext, "inputs"> {
|
|
|
|
return {
|
|
|
|
...this.context,
|
2021-08-25 19:51:05 +00:00
|
|
|
...this.props,
|
|
|
|
variables: this.schema.variables || {}
|
2021-08-23 23:07:53 +00:00
|
|
|
};
|
2021-08-22 17:35:46 +00:00
|
|
|
}
|
2021-08-22 11:27:02 +00:00
|
|
|
|
2021-08-22 17:35:46 +00:00
|
|
|
getContext(): IStrategyContext {
|
|
|
|
return {
|
|
|
|
...this.context,
|
|
|
|
...this.props,
|
2021-08-23 23:07:53 +00:00
|
|
|
inputs: this.inputs
|
2021-08-22 17:35:46 +00:00
|
|
|
};
|
|
|
|
}
|
2021-08-22 15:45:37 +00:00
|
|
|
|
2021-08-22 17:35:46 +00:00
|
|
|
setProps(props: object) {
|
|
|
|
Object.assign(this.props, props);
|
2021-08-22 19:34:59 +00:00
|
|
|
|
2021-08-23 23:07:53 +00:00
|
|
|
const inputs = this.inputs;
|
|
|
|
|
|
|
|
for (const input of inputs) {
|
|
|
|
if (typeof input.defaults !== "function") {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Object.assign(input, input.defaults(this.getBaseContext()));
|
|
|
|
}
|
|
|
|
|
|
|
|
this.notifyListeners();
|
2021-08-22 17:35:46 +00:00
|
|
|
}
|
2021-08-22 15:45:37 +00:00
|
|
|
|
2021-08-23 23:07:53 +00:00
|
|
|
generateInputs(inputs) {
|
|
|
|
return inputs.map((input, idx) => {
|
|
|
|
const computedInput = {
|
|
|
|
...input,
|
|
|
|
value: input.value || "",
|
|
|
|
error: input.error || "",
|
|
|
|
placeholder: () => {
|
|
|
|
return input.placeholder
|
|
|
|
? input.placeholder({
|
|
|
|
...this.getContext(),
|
|
|
|
input: this.inputs[idx]
|
|
|
|
})
|
|
|
|
: null;
|
|
|
|
},
|
|
|
|
onInput: (val: any) => {
|
|
|
|
this.inputs[idx].error = "";
|
|
|
|
this.inputs[idx].value = val;
|
|
|
|
|
|
|
|
if (val) {
|
|
|
|
this.inputs[idx].error = this.inputs[idx].validate({
|
|
|
|
...this.getContext(),
|
|
|
|
input: this.inputs[idx]
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
this.notifyListeners();
|
|
|
|
},
|
|
|
|
onCustomInput: (values: object) => {
|
|
|
|
this.inputs[idx] = Object.assign(this.inputs[idx], values);
|
|
|
|
|
|
|
|
this.inputs[idx].error = this.inputs[idx].validate({
|
2021-08-22 17:35:46 +00:00
|
|
|
...this.getContext(),
|
2021-08-23 23:07:53 +00:00
|
|
|
input: this.inputs[idx]
|
2021-08-22 17:35:46 +00:00
|
|
|
});
|
2021-08-23 23:07:53 +00:00
|
|
|
this.notifyListeners();
|
2021-08-22 17:35:46 +00:00
|
|
|
}
|
2021-08-23 23:07:53 +00:00
|
|
|
};
|
2021-08-22 17:35:46 +00:00
|
|
|
|
2021-08-23 23:07:53 +00:00
|
|
|
let defaults = {};
|
2021-08-22 18:32:28 +00:00
|
|
|
|
2021-08-23 23:07:53 +00:00
|
|
|
if (input.defaults) {
|
|
|
|
defaults = input.defaults(this.getBaseContext());
|
2021-08-22 13:49:31 +00:00
|
|
|
}
|
2021-08-23 23:07:53 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
...computedInput,
|
|
|
|
...defaults
|
|
|
|
};
|
|
|
|
});
|
2021-08-22 17:35:46 +00:00
|
|
|
}
|
2021-08-22 12:54:23 +00:00
|
|
|
|
2021-08-25 11:13:23 +00:00
|
|
|
async spells() {
|
|
|
|
return await this.schema.spells(this.getContext());
|
|
|
|
}
|
|
|
|
|
2021-08-22 18:32:28 +00:00
|
|
|
async submit(options) {
|
2021-08-22 17:35:46 +00:00
|
|
|
await this.validate();
|
2021-08-22 12:54:23 +00:00
|
|
|
|
2021-08-25 11:13:23 +00:00
|
|
|
const allSpells = await this.spells();
|
2021-08-22 15:45:37 +00:00
|
|
|
|
2021-08-22 17:35:46 +00:00
|
|
|
const spells = this.context.dsa.Spell();
|
2021-08-22 15:45:37 +00:00
|
|
|
|
2021-08-22 17:35:46 +00:00
|
|
|
for (const spell of allSpells) {
|
|
|
|
spells.add(spell);
|
|
|
|
}
|
|
|
|
|
|
|
|
return await this.context.dsa.cast({
|
|
|
|
spells,
|
2021-08-22 18:32:28 +00:00
|
|
|
onReceipt: options?.onReceipt,
|
|
|
|
from: options?.from
|
2021-08-22 17:35:46 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
async validate() {
|
2021-08-23 23:07:53 +00:00
|
|
|
const inputs = this.inputs;
|
2021-08-22 17:35:46 +00:00
|
|
|
|
|
|
|
for (const input of inputs) {
|
2021-08-22 18:32:28 +00:00
|
|
|
if (typeof input.validate !== "function") {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-08-22 17:35:46 +00:00
|
|
|
const result = await input.validate({
|
|
|
|
...this.getContext(),
|
|
|
|
input
|
2021-08-22 13:49:31 +00:00
|
|
|
});
|
2021-08-22 17:35:46 +00:00
|
|
|
|
|
|
|
if (typeof result === "string") {
|
|
|
|
throw new Error(result || "Error has occurred");
|
2021-08-22 13:49:31 +00:00
|
|
|
}
|
|
|
|
}
|
2021-08-22 17:35:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
setWeb3(web3: Web3) {
|
|
|
|
this.context.web3 = web3;
|
2021-08-23 23:07:53 +00:00
|
|
|
|
|
|
|
this.notifyListeners();
|
2021-08-22 17:35:46 +00:00
|
|
|
}
|
2021-08-22 13:49:31 +00:00
|
|
|
|
2021-08-22 17:35:46 +00:00
|
|
|
setDSA(dsa: DSA) {
|
|
|
|
this.context.dsa = dsa;
|
2021-08-23 23:07:53 +00:00
|
|
|
|
|
|
|
this.notifyListeners();
|
2021-08-22 17:35:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async notifyListeners() {
|
|
|
|
for (const listener of this.listeners) {
|
|
|
|
await listener(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
onUpdated(cb) {
|
|
|
|
this.listeners.push(cb);
|
|
|
|
}
|
|
|
|
}
|