assembly/core/strategies/helpers/strategy.ts

198 lines
4.2 KiB
TypeScript
Raw Permalink Normal View History

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;
2021-09-05 11:46:39 +00:00
components = [];
2021-08-22 17:35:46 +00:00
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-09-05 11:46:39 +00:00
this.components = this.generateComponents(this.schema.components);
2021-08-23 23:07:53 +00:00
}
2021-09-05 11:46:39 +00:00
getBaseContext(): Omit<IStrategyContext, "components"> {
2021-08-23 23:07:53 +00:00
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 {
2021-08-26 16:38:31 +00:00
...this.getBaseContext(),
2021-09-05 11:46:39 +00:00
components: this.components
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-09-05 11:46:39 +00:00
const components = this.components;
2021-08-23 23:07:53 +00:00
2021-09-05 11:46:39 +00:00
for (const component of components) {
if (typeof component.defaults !== "function") {
2021-08-23 23:07:53 +00:00
continue;
}
2021-09-05 11:46:39 +00:00
if (component.defaulted) {
2021-09-04 16:50:56 +00:00
continue;
2021-08-26 22:27:26 +00:00
}
2021-09-05 11:46:39 +00:00
Object.assign(component, component.defaults(this.getBaseContext()));
2021-09-04 16:50:56 +00:00
2021-09-05 11:46:39 +00:00
component.defaulted = true;
2021-08-23 23:07:53 +00:00
}
2021-09-05 15:28:08 +00:00
this.notifyListeners("SET_PROPS");
2021-08-22 17:35:46 +00:00
}
2021-08-22 15:45:37 +00:00
2021-09-05 11:46:39 +00:00
generateComponents(components) {
return components.map((component, idx) => {
const computedComponent = {
...component,
value: component.value || "",
error: component.error || "",
2021-08-23 23:07:53 +00:00
placeholder: () => {
2021-09-05 11:46:39 +00:00
return component.placeholder
? component.placeholder({
2021-08-23 23:07:53 +00:00
...this.getContext(),
2021-09-05 11:46:39 +00:00
component: this.components[idx]
2021-08-23 23:07:53 +00:00
})
: null;
},
onInput: (val: any) => {
2021-09-05 11:46:39 +00:00
this.components[idx].error = "";
this.components[idx].value = val;
2021-08-23 23:07:53 +00:00
if (val) {
2021-09-05 11:46:39 +00:00
this.components[idx].error = this.components[idx].validate({
2021-08-23 23:07:53 +00:00
...this.getContext(),
2021-09-05 11:46:39 +00:00
component: this.components[idx]
2021-08-23 23:07:53 +00:00
});
}
2021-09-05 15:28:08 +00:00
this.notifyListeners("onInput");
2021-08-23 23:07:53 +00:00
},
onCustomInput: (values: object) => {
2021-09-05 11:46:39 +00:00
this.components[idx] = Object.assign(this.components[idx], values);
2021-08-23 23:07:53 +00:00
2021-09-05 11:46:39 +00:00
this.components[idx].error = this.components[idx].validate({
2021-08-22 17:35:46 +00:00
...this.getContext(),
2021-09-05 11:46:39 +00:00
component: this.components[idx]
2021-08-22 17:35:46 +00:00
});
2021-09-05 15:28:08 +00:00
this.notifyListeners("onCustomInput");
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-09-05 11:46:39 +00:00
if (component.defaults) {
defaults = component.defaults(this.getBaseContext());
2021-08-22 13:49:31 +00:00
}
2021-08-23 23:07:53 +00:00
return {
2021-09-05 11:46:39 +00:00
...computedComponent,
2021-08-23 23:07:53 +00:00
...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-09-05 11:46:39 +00:00
const components = this.components;
2021-08-22 17:35:46 +00:00
2021-09-05 11:46:39 +00:00
for (const component of components) {
if (typeof component.validate !== "function") {
2021-08-22 18:32:28 +00:00
continue;
}
2021-09-05 11:46:39 +00:00
const result = await component.validate({
2021-08-22 17:35:46 +00:00
...this.getContext(),
2021-09-05 11:46:39 +00:00
component
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-26 18:34:27 +00:00
if (this.schema.validate) {
const result = await this.schema.validate(this.getContext());
if (typeof result === "string") {
throw new Error(result || "Error has occurred");
}
}
2021-08-22 17:35:46 +00:00
}
setWeb3(web3: Web3) {
this.context.web3 = web3;
2021-08-23 23:07:53 +00:00
2021-09-05 15:28:08 +00:00
this.notifyListeners("WEB3");
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
2021-09-05 15:28:08 +00:00
this.notifyListeners("DSA");
2021-08-22 17:35:46 +00:00
}
2021-09-05 15:28:08 +00:00
async notifyListeners( from = "") {
if(from && process.env.NODE_ENV === "development") {
console.log(`${from} updated`);
}
2021-08-22 17:35:46 +00:00
for (const listener of this.listeners) {
await listener(this);
}
2021-09-05 11:01:19 +00:00
2021-09-05 11:46:39 +00:00
this.components.forEach(component =>
component.update?.({
...this.getContext(),
component
})
);
2021-08-22 17:35:46 +00:00
}
onUpdated(cb) {
this.listeners.push(cb);
}
}