mirror of
https://github.com/Instadapp/assembly.git
synced 2024-07-29 22:37:06 +00:00
wip
This commit is contained in:
parent
60e1cfb5ca
commit
b1b221876c
|
@ -212,6 +212,7 @@ async function getBalances(
|
||||||
}
|
}
|
||||||
const { name, symbol, decimals, type, isStableCoin, key } = tokenData;
|
const { name, symbol, decimals, type, isStableCoin, key } = tokenData;
|
||||||
tokensBalObj[tokenAddress] = {
|
tokensBalObj[tokenAddress] = {
|
||||||
|
address: tokenAddress,
|
||||||
name,
|
name,
|
||||||
symbol,
|
symbol,
|
||||||
decimals,
|
decimals,
|
||||||
|
|
|
@ -18,13 +18,13 @@ export function useStrategy(defineStrategy: DefineStrategy) {
|
||||||
} = useNotification();
|
} = useNotification();
|
||||||
|
|
||||||
const strategy = buildStrategy(defineStrategy);
|
const strategy = buildStrategy(defineStrategy);
|
||||||
const inputs = ref(strategy.getInputs());
|
const inputs = ref(strategy.inputs);
|
||||||
const error = ref("");
|
const error = ref("");
|
||||||
|
|
||||||
strategy.onUpdated(async () => {
|
strategy.onUpdated(async () => {
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
|
||||||
inputs.value = strategy.getInputs();
|
inputs.value = strategy.inputs;
|
||||||
|
|
||||||
console.log("onUpdated");
|
console.log("onUpdated");
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,8 +6,8 @@ export interface IStrategyContext {
|
||||||
dsa: DSA;
|
dsa: DSA;
|
||||||
web3: Web3;
|
web3: Web3;
|
||||||
inputs: IStrategyInput<StrategyInputType>[];
|
inputs: IStrategyInput<StrategyInputType>[];
|
||||||
dsaTokens?: IStrategyToken,
|
dsaTokens?: { [address: string]: IStrategyToken };
|
||||||
userTokens?: IStrategyToken,
|
userTokens?: { [address: string]: IStrategyToken };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IStrategyToken {
|
export interface IStrategyToken {
|
||||||
|
@ -46,6 +46,9 @@ export interface IStrategyInput<InputType extends StrategyInputType> {
|
||||||
input: IStrategyInput<InputType> & StrategyInputParameterMap[InputType];
|
input: IStrategyInput<InputType> & StrategyInputParameterMap[InputType];
|
||||||
}
|
}
|
||||||
) => string | void;
|
) => string | void;
|
||||||
|
|
||||||
|
defaults?: (context: Omit<IStrategyContext, 'inputs'>) => object;
|
||||||
|
|
||||||
value?: any;
|
value?: any;
|
||||||
|
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
|
@ -78,7 +81,7 @@ export function defineStrategy(strategy: IStrategy) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildStrategy(schema: DefineStrategy) {
|
export function buildStrategy(schema: DefineStrategy) {
|
||||||
return new Strategy(schema)
|
return new Strategy(schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DefineStrategy = ReturnType<typeof defineStrategy>;
|
export type DefineStrategy = ReturnType<typeof defineStrategy>;
|
||||||
|
|
|
@ -21,64 +21,94 @@ export class Strategy {
|
||||||
constructor(schema: DefineStrategy) {
|
constructor(schema: DefineStrategy) {
|
||||||
this.schema = schema;
|
this.schema = schema;
|
||||||
|
|
||||||
this.inputs = this.schema.inputs;
|
this.inputs = this.generateInputs(this.schema.inputs);
|
||||||
|
}
|
||||||
|
|
||||||
|
getBaseContext(): Omit<IStrategyContext, "inputs"> {
|
||||||
|
return {
|
||||||
|
...this.context,
|
||||||
|
...this.props
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getContext(): IStrategyContext {
|
getContext(): IStrategyContext {
|
||||||
return {
|
return {
|
||||||
...this.context,
|
...this.context,
|
||||||
...this.props,
|
...this.props,
|
||||||
inputs: this.getInputs()
|
inputs: this.inputs
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
setProps(props: object) {
|
setProps(props: object) {
|
||||||
Object.assign(this.props, props);
|
Object.assign(this.props, props);
|
||||||
|
|
||||||
this.notifyListeners()
|
const inputs = this.inputs;
|
||||||
|
|
||||||
|
for (const input of inputs) {
|
||||||
|
if (typeof input.defaults !== "function") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(input, input.defaults(this.getBaseContext()));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
getInputs() {
|
generateInputs(inputs) {
|
||||||
return this.inputs.map(input => ({
|
return inputs.map((input, idx) => {
|
||||||
...input,
|
const computedInput = {
|
||||||
value: input.value || "",
|
...input,
|
||||||
error: input.error || "",
|
value: input.value || "",
|
||||||
placeholder: () =>
|
error: input.error || "",
|
||||||
input.placeholder
|
placeholder: () => {
|
||||||
? input.placeholder({
|
console.log({
|
||||||
...this.context,
|
|
||||||
inputs: this.inputs,
|
|
||||||
input: {
|
|
||||||
token: {
|
|
||||||
// todo
|
|
||||||
},
|
|
||||||
...input
|
|
||||||
}
|
|
||||||
})
|
|
||||||
: null,
|
|
||||||
onInput: (val: any) => {
|
|
||||||
input.error = "";
|
|
||||||
input.value = val;
|
|
||||||
|
|
||||||
if (val) {
|
|
||||||
input.error = input.validate({
|
|
||||||
...this.getContext(),
|
...this.getContext(),
|
||||||
input
|
input: this.inputs[idx]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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({
|
||||||
|
...this.getContext(),
|
||||||
|
input: this.inputs[idx]
|
||||||
|
});
|
||||||
|
this.notifyListeners();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.notifyListeners();
|
let defaults = {};
|
||||||
},
|
|
||||||
onCustomInput: (values: object) => {
|
|
||||||
input = Object.assign(input, values);
|
|
||||||
|
|
||||||
input.error = input.validate({
|
if (input.defaults) {
|
||||||
...this.getContext(),
|
defaults = input.defaults(this.getBaseContext());
|
||||||
input
|
|
||||||
});
|
|
||||||
this.notifyListeners();
|
|
||||||
}
|
}
|
||||||
}));
|
|
||||||
|
return {
|
||||||
|
...computedInput,
|
||||||
|
...defaults
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async submit(options) {
|
async submit(options) {
|
||||||
|
@ -100,7 +130,7 @@ export class Strategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
async validate() {
|
async validate() {
|
||||||
const inputs = this.getInputs();
|
const inputs = this.inputs;
|
||||||
|
|
||||||
for (const input of inputs) {
|
for (const input of inputs) {
|
||||||
if (typeof input.validate !== "function") {
|
if (typeof input.validate !== "function") {
|
||||||
|
@ -120,10 +150,14 @@ export class Strategy {
|
||||||
|
|
||||||
setWeb3(web3: Web3) {
|
setWeb3(web3: Web3) {
|
||||||
this.context.web3 = web3;
|
this.context.web3 = web3;
|
||||||
|
|
||||||
|
this.notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
setDSA(dsa: DSA) {
|
setDSA(dsa: DSA) {
|
||||||
this.context.dsa = dsa;
|
this.context.dsa = dsa;
|
||||||
|
|
||||||
|
this.notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
async notifyListeners() {
|
async notifyListeners() {
|
||||||
|
|
|
@ -10,7 +10,7 @@ export default defineStrategy({
|
||||||
defineInput({
|
defineInput({
|
||||||
type: StrategyInputType.INPUT_WITH_TOKEN,
|
type: StrategyInputType.INPUT_WITH_TOKEN,
|
||||||
name: "Debt",
|
name: "Debt",
|
||||||
placeholder: ({ input }) => `${input.token.symbol} to Payback`,
|
placeholder: ({ input }) => `${input.token?.symbol} to Payback`,
|
||||||
validate: ({ input }) => {
|
validate: ({ input }) => {
|
||||||
if (!input.token) {
|
if (!input.token) {
|
||||||
return "Token is required";
|
return "Token is required";
|
||||||
|
@ -20,13 +20,23 @@ export default defineStrategy({
|
||||||
return "Your amount exceeds your maximum limit.";
|
return "Your amount exceeds your maximum limit.";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
token: tokens.mainnet.getTokenByKey("eth")
|
defaults: context => {
|
||||||
|
return {
|
||||||
|
token: context.dsaTokens
|
||||||
|
? Object.values(context.dsaTokens).find(t => t.key === "eth")
|
||||||
|
: null
|
||||||
|
};
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
defineInput({
|
defineInput({
|
||||||
type: StrategyInputType.INPUT_WITH_TOKEN,
|
type: StrategyInputType.INPUT_WITH_TOKEN,
|
||||||
name: "Collateral",
|
name: "Collateral",
|
||||||
placeholder: ({ input }) => `${input.token.symbol} to Withdraw`,
|
placeholder: ({ input }) => `${input.token?.symbol} to Withdraw`,
|
||||||
token: tokens.mainnet.getTokenByKey("dai")
|
defaults: ({ dsaTokens }) => ({
|
||||||
|
token: dsaTokens
|
||||||
|
? Object.values(dsaTokens).find(t => t.key === "dai")
|
||||||
|
: null
|
||||||
|
})
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import depositAndBorrow from "./deposit-and-borrow"
|
import depositAndBorrow from "./deposit-and-borrow"
|
||||||
|
import paybackAndWithdraw from "./payback-and-withdraw"
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
depositAndBorrow
|
depositAndBorrow,
|
||||||
|
paybackAndWithdraw,
|
||||||
]
|
]
|
||||||
|
|
47
core/strategies/protocols/aave-v2/payback-and-withdraw.ts
Normal file
47
core/strategies/protocols/aave-v2/payback-and-withdraw.ts
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import tokens from "~/constant/tokens";
|
||||||
|
import { defineStrategy, defineInput, StrategyInputType } from "../../helpers";
|
||||||
|
|
||||||
|
export default defineStrategy({
|
||||||
|
name: "Payback & Withdraw",
|
||||||
|
description: "Payback debt & withdraw collateral in a single txn.",
|
||||||
|
author: "Instadapp Team",
|
||||||
|
|
||||||
|
inputs: [
|
||||||
|
defineInput({
|
||||||
|
type: StrategyInputType.INPUT_WITH_TOKEN,
|
||||||
|
name: "Debt",
|
||||||
|
placeholder: ({ input }) => `${input.token.symbol} to Payback`,
|
||||||
|
validate: ({ input }) => {
|
||||||
|
if (!input.token) {
|
||||||
|
return "Token is required";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.token.balance < input.value) {
|
||||||
|
return "Your amount exceeds your maximum limit.";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
token: tokens.mainnet.getTokenByKey("eth")
|
||||||
|
}),
|
||||||
|
defineInput({
|
||||||
|
type: StrategyInputType.INPUT_WITH_TOKEN,
|
||||||
|
name: "Collateral",
|
||||||
|
placeholder: ({ input }) => `${input.token.symbol} to Withdraw`,
|
||||||
|
token: tokens.mainnet.getTokenByKey("dai")
|
||||||
|
})
|
||||||
|
],
|
||||||
|
|
||||||
|
spells: async ({ inputs }) => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
connector: "aave_v2",
|
||||||
|
method: "payback",
|
||||||
|
args: [inputs[0].token.address, inputs[0].value, 1, 0, 0]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
connector: "aave_v2",
|
||||||
|
method: "withdraw",
|
||||||
|
args: [inputs[1].token.address, inputs[1].value, 0, 0]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user