mirror of
https://github.com/Instadapp/assembly.git
synced 2024-07-29 22:37:06 +00:00
wip
This commit is contained in:
parent
b1b221876c
commit
cd003cc517
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="active" class="relative w-[193px]" v-click-outside="hide">
|
<div v-if="active && activeAccount" class="relative w-[193px]" v-click-outside="hide">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class=" relative w-full border border-primary-blue-border rounded pl-3 pr-10 py-2 text-left focus:outline-none focus:ring-1 focus:ring-[#0846E4] focus:border-[#0846E4] sm:text-sm"
|
class=" relative w-full border border-primary-blue-border rounded pl-3 pr-10 py-2 text-left focus:outline-none focus:ring-1 focus:ring-[#0846E4] focus:border-[#0846E4] sm:text-sm"
|
||||||
|
@ -142,7 +142,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
v-else
|
v-if="!active"
|
||||||
@click="activate"
|
@click="activate"
|
||||||
class="hidden md:flex bg-primary-blue-dark hover:bg-primary-blue-hover shadow text-white p-3 rounded h-9 items-center justify-center w-40"
|
class="hidden md:flex bg-primary-blue-dark hover:bg-primary-blue-hover shadow text-white p-3 rounded h-9 items-center justify-center w-40"
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,32 +1,70 @@
|
||||||
<template>
|
<template>
|
||||||
<SidebarContextContainer class="h-full overflow-hidden">
|
<SidebarContextContainer class="h-full overflow-hidden">
|
||||||
<SidebarContextHeader class="xxl:hidden">Strategy</SidebarContextHeader>
|
<SidebarContextHeader>
|
||||||
|
<h1 class="font-bold text-primary-black text-lg">
|
||||||
|
{{ activeStrategy.schema.name }}
|
||||||
|
</h1>
|
||||||
|
<p
|
||||||
|
v-if="activeStrategy.schema.author"
|
||||||
|
class="font-medium text-[#1874FF] text-sm mt-2.5"
|
||||||
|
>
|
||||||
|
{{ activeStrategy.schema.author }}
|
||||||
|
</p>
|
||||||
|
</SidebarContextHeader>
|
||||||
|
|
||||||
<div class="h-full overflow-y-scroll scrollbar-hover">
|
<div class="h-full overflow-y-scroll scrollbar-hover flex flex-col">
|
||||||
<div class="mx-auto" style="max-width: 296px">
|
<div class="mx-auto mb-9" style="width: 296px">
|
||||||
<div class="py-2 sm:py-4">
|
<div
|
||||||
<div v-for="(input, index) in inputs" :key="index">
|
class="flex-shrink-0 font-medium prose prose-sm text-primary-gray"
|
||||||
<input-amount
|
v-if="activeStrategy.schema.details"
|
||||||
:key="index"
|
v-html="activeStrategy.schema.details"
|
||||||
:value="input.value"
|
></div>
|
||||||
:token-key="input.token ? input.token.key : 'eth'"
|
</div>
|
||||||
:token-keys="input.tokenKeys ? input.tokenKeys : activeStrategy.getContext()['tokenKeys']"
|
<div class="flex-1 bg-[#1874FF] bg-opacity-[0.04]">
|
||||||
:placeholder="input.placeholder()"
|
<div class="mx-auto h-full" style="max-width: 296px">
|
||||||
:error="input.error"
|
<div class="space-y-4 py-9 h-full flex flex-col">
|
||||||
@input="$event => input.onInput($event)"
|
<div class="flex-1">
|
||||||
@tokenKeyChanged="
|
<div v-for="(input, index) in inputs" :key="index">
|
||||||
tokenKey => {
|
<input-amount
|
||||||
input.onCustomInput({
|
:key="index"
|
||||||
token: getTokenByKey(tokenKey)
|
:value="input.value"
|
||||||
});
|
:token-key="input.token ? input.token.key : 'eth'"
|
||||||
}
|
:token-keys="
|
||||||
"
|
input.tokenKeys
|
||||||
/>
|
? input.tokenKeys
|
||||||
|
: activeStrategy.getContext()['tokenKeys']
|
||||||
|
"
|
||||||
|
:placeholder="input.placeholder()"
|
||||||
|
@input="$event => input.onInput($event)"
|
||||||
|
@tokenKeyChanged="
|
||||||
|
tokenKey => {
|
||||||
|
input.onCustomInput({
|
||||||
|
token: getTokenByKey(tokenKey)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-auto">
|
||||||
|
<ValidationErrors
|
||||||
|
:error-messages="error ? [error] : []"
|
||||||
|
class="mb-6"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ButtonCTA
|
||||||
|
class="w-full"
|
||||||
|
@click="submit"
|
||||||
|
:loading="pending"
|
||||||
|
:disabled="pending"
|
||||||
|
>
|
||||||
|
{{ activeStrategy.schema.submitText || "Submit" }}
|
||||||
|
</ButtonCTA>
|
||||||
|
|
||||||
|
<p class="text-xs text-[#9FB0C9] mt-2.5 text-center">Instadapp does not charge a fee for this operation</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button @click="submit">Submit</button>
|
|
||||||
|
|
||||||
{{ error }}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,9 +78,9 @@ import { protocolStrategies, DefineStrategy } from "~/core/strategies";
|
||||||
import { useStrategy } from "~/composables/useStrategy";
|
import { useStrategy } from "~/composables/useStrategy";
|
||||||
import InputAmount from "~/components/common/input/InputAmount.vue";
|
import InputAmount from "~/components/common/input/InputAmount.vue";
|
||||||
import { useToken } from "~/composables/useToken";
|
import { useToken } from "~/composables/useToken";
|
||||||
|
import ButtonCTA from "~/components/common/input/ButtonCTA.vue";
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { InputAmount },
|
components: { InputAmount, ButtonCTA },
|
||||||
props: {
|
props: {
|
||||||
protocol: {
|
protocol: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -60,7 +98,13 @@ export default defineComponent({
|
||||||
const strategies: DefineStrategy[] =
|
const strategies: DefineStrategy[] =
|
||||||
protocolStrategies[props.protocol] || [];
|
protocolStrategies[props.protocol] || [];
|
||||||
|
|
||||||
const { inputs, submit, error, strategy : activeStrategy} = useStrategy(
|
const {
|
||||||
|
inputs,
|
||||||
|
submit,
|
||||||
|
error,
|
||||||
|
strategy: activeStrategy,
|
||||||
|
pending
|
||||||
|
} = useStrategy(
|
||||||
strategies.find(strategy => strategy.id === props.strategy)
|
strategies.find(strategy => strategy.id === props.strategy)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -70,6 +114,7 @@ export default defineComponent({
|
||||||
submit,
|
submit,
|
||||||
activeStrategy,
|
activeStrategy,
|
||||||
getTokenByKey,
|
getTokenByKey,
|
||||||
|
pending
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { useBigNumber } from "~/composables/useBigNumber";
|
||||||
import { usePosition } from "~/composables/usePosition";
|
import { usePosition } from "~/composables/usePosition";
|
||||||
import { useToken } from "~/composables/useToken";
|
import { useToken } from "~/composables/useToken";
|
||||||
import { useSorting } from "~/composables/useSorting";
|
import { useSorting } from "~/composables/useSorting";
|
||||||
|
import useEventBus from "../useEventBus";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
times,
|
times,
|
||||||
|
@ -69,6 +70,7 @@ export function useAaveV2Position(
|
||||||
const { activeAccount } = useDSA();
|
const { activeAccount } = useDSA();
|
||||||
const { getTokenByKey, allATokensV2 } = useToken();
|
const { getTokenByKey, allATokensV2 } = useToken();
|
||||||
const { byMaxSupplyOrBorrowDesc } = useSorting()
|
const { byMaxSupplyOrBorrowDesc } = useSorting()
|
||||||
|
const { onEvent } = useEventBus()
|
||||||
|
|
||||||
const resolver = computed(() =>
|
const resolver = computed(() =>
|
||||||
chainId.value === 1
|
chainId.value === 1
|
||||||
|
@ -107,6 +109,7 @@ export function useAaveV2Position(
|
||||||
position.value = await fetchPosition();
|
position.value = await fetchPosition();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onEvent("protocol::aaveV2::refresh", refreshPosition);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
web3,
|
web3,
|
||||||
|
|
24
composables/useEventBus.ts
Normal file
24
composables/useEventBus.ts
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import { onBeforeUnmount } from "@nuxtjs/composition-api";
|
||||||
|
import { TinyEmitter } from "tiny-emitter";
|
||||||
|
|
||||||
|
const eventEmitter = new TinyEmitter();
|
||||||
|
|
||||||
|
export default function useEventBus() {
|
||||||
|
const eventHandlers = [];
|
||||||
|
|
||||||
|
onBeforeUnmount(() =>
|
||||||
|
eventHandlers.forEach(eventHandler =>
|
||||||
|
eventEmitter.off(eventHandler.event, eventHandler.handler)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
onEvent(event, handler) {
|
||||||
|
eventHandlers.push({ event, handler });
|
||||||
|
eventEmitter.on(event, handler);
|
||||||
|
},
|
||||||
|
emitEvent(event, payload) {
|
||||||
|
eventEmitter.emit(event, payload);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -3,15 +3,18 @@ import tokens from "~/constant/tokens";
|
||||||
import { buildStrategy, DefineStrategy, IStrategy } from "~/core/strategies";
|
import { buildStrategy, DefineStrategy, IStrategy } from "~/core/strategies";
|
||||||
import { useBalances } from "./useBalances";
|
import { useBalances } from "./useBalances";
|
||||||
import { useDSA } from "./useDSA";
|
import { useDSA } from "./useDSA";
|
||||||
|
import useEventBus from "./useEventBus";
|
||||||
import { useNotification } from "./useNotification";
|
import { useNotification } from "./useNotification";
|
||||||
import { useSidebar } from "./useSidebar";
|
import { useSidebar } from "./useSidebar";
|
||||||
|
import { useToken } from "./useToken";
|
||||||
import { useWeb3 } from "./useWeb3";
|
import { useWeb3 } from "./useWeb3";
|
||||||
|
|
||||||
export function useStrategy(defineStrategy: DefineStrategy) {
|
export function useStrategy(defineStrategy: DefineStrategy) {
|
||||||
const { web3, networkName, account } = useWeb3();
|
const { web3, networkName, account } = useWeb3();
|
||||||
const { dsa } = useDSA();
|
const { dsa } = useDSA();
|
||||||
const { prices, balances, fetchBalances } = useBalances();
|
const { prices, balances, fetchBalances } = useBalances();
|
||||||
const { close } = useSidebar();
|
const { close } = useSidebar();
|
||||||
|
const { valInt, getTokenByKey } = useToken();
|
||||||
|
const { emitEvent } = useEventBus();
|
||||||
const {
|
const {
|
||||||
showPendingTransaction,
|
showPendingTransaction,
|
||||||
showConfirmedTransaction
|
showConfirmedTransaction
|
||||||
|
@ -20,6 +23,7 @@ export function useStrategy(defineStrategy: DefineStrategy) {
|
||||||
const strategy = buildStrategy(defineStrategy);
|
const strategy = buildStrategy(defineStrategy);
|
||||||
const inputs = ref(strategy.inputs);
|
const inputs = ref(strategy.inputs);
|
||||||
const error = ref("");
|
const error = ref("");
|
||||||
|
const pending = ref(false);
|
||||||
|
|
||||||
strategy.onUpdated(async () => {
|
strategy.onUpdated(async () => {
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
@ -31,21 +35,32 @@ export function useStrategy(defineStrategy: DefineStrategy) {
|
||||||
|
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
error.value = "";
|
error.value = "";
|
||||||
|
pending.value = true;
|
||||||
try {
|
try {
|
||||||
const tx = await strategy.submit({
|
const tx = await strategy.submit({
|
||||||
onReceipt: async () => {
|
onReceipt: async () => {
|
||||||
showConfirmedTransaction(tx);
|
showConfirmedTransaction(tx);
|
||||||
await fetchBalances(true);
|
await fetchBalances(true);
|
||||||
|
|
||||||
|
emitEvent(`protocol::${strategy.schema.protocol}::refresh`,{});
|
||||||
},
|
},
|
||||||
from: account.value
|
from: account.value
|
||||||
});
|
});
|
||||||
showPendingTransaction(tx);
|
showPendingTransaction(tx);
|
||||||
close();
|
close();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
|
||||||
error.value = e.message;
|
error.value = e.message;
|
||||||
}
|
}
|
||||||
|
pending.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
strategy.setProps({
|
||||||
|
convertTokenAmountToBigNumber: valInt,
|
||||||
|
getTokenByKey,
|
||||||
|
})
|
||||||
|
|
||||||
watch(web3, () => strategy.setWeb3(web3.value), { immediate: true });
|
watch(web3, () => strategy.setWeb3(web3.value), { immediate: true });
|
||||||
watch(dsa, () => strategy.setDSA(dsa.value), { immediate: true });
|
watch(dsa, () => strategy.setDSA(dsa.value), { immediate: true });
|
||||||
watch(
|
watch(
|
||||||
|
@ -83,6 +98,7 @@ export function useStrategy(defineStrategy: DefineStrategy) {
|
||||||
strategy,
|
strategy,
|
||||||
inputs,
|
inputs,
|
||||||
submit,
|
submit,
|
||||||
error
|
error,
|
||||||
|
pending,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ export interface IStrategyContext {
|
||||||
inputs: IStrategyInput<StrategyInputType>[];
|
inputs: IStrategyInput<StrategyInputType>[];
|
||||||
dsaTokens?: { [address: string]: IStrategyToken };
|
dsaTokens?: { [address: string]: IStrategyToken };
|
||||||
userTokens?: { [address: string]: IStrategyToken };
|
userTokens?: { [address: string]: IStrategyToken };
|
||||||
|
convertTokenAmountToBigNumber?: (value: any, decimals: any) => string;
|
||||||
|
getTokenByKey?: (key: string) => IStrategyToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IStrategyToken {
|
export interface IStrategyToken {
|
||||||
|
@ -47,17 +49,22 @@ export interface IStrategyInput<InputType extends StrategyInputType> {
|
||||||
}
|
}
|
||||||
) => string | void;
|
) => string | void;
|
||||||
|
|
||||||
defaults?: (context: Omit<IStrategyContext, 'inputs'>) => object;
|
defaults?: (context: Omit<IStrategyContext, "inputs">) => object;
|
||||||
|
|
||||||
value?: any;
|
value?: any;
|
||||||
|
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum StrategyProtocol {
|
||||||
|
AAVE_V2 = "aaveV2"
|
||||||
|
}
|
||||||
export interface IStrategy {
|
export interface IStrategy {
|
||||||
|
protocol: StrategyProtocol;
|
||||||
id?: string;
|
id?: string;
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
|
details?: string;
|
||||||
author?: string;
|
author?: string;
|
||||||
|
|
||||||
inputs: IStrategyInput<StrategyInputType>[];
|
inputs: IStrategyInput<StrategyInputType>[];
|
||||||
|
|
|
@ -6,8 +6,8 @@ export class Strategy {
|
||||||
schema: DefineStrategy;
|
schema: DefineStrategy;
|
||||||
inputs = [];
|
inputs = [];
|
||||||
context = {
|
context = {
|
||||||
web3: null,
|
web3: null as Web3,
|
||||||
dsa: null
|
dsa: null as DSA
|
||||||
};
|
};
|
||||||
|
|
||||||
listeners = [];
|
listeners = [];
|
||||||
|
@ -62,11 +62,6 @@ export class Strategy {
|
||||||
value: input.value || "",
|
value: input.value || "",
|
||||||
error: input.error || "",
|
error: input.error || "",
|
||||||
placeholder: () => {
|
placeholder: () => {
|
||||||
console.log({
|
|
||||||
...this.getContext(),
|
|
||||||
input: this.inputs[idx]
|
|
||||||
});
|
|
||||||
|
|
||||||
return input.placeholder
|
return input.placeholder
|
||||||
? input.placeholder({
|
? input.placeholder({
|
||||||
...this.getContext(),
|
...this.getContext(),
|
||||||
|
@ -111,10 +106,14 @@ export class Strategy {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async spells() {
|
||||||
|
return await this.schema.spells(this.getContext());
|
||||||
|
}
|
||||||
|
|
||||||
async submit(options) {
|
async submit(options) {
|
||||||
await this.validate();
|
await this.validate();
|
||||||
|
|
||||||
const allSpells = await this.schema.spells(this.getContext());
|
const allSpells = await this.spells();
|
||||||
|
|
||||||
const spells = this.context.dsa.Spell();
|
const spells = this.context.dsa.Spell();
|
||||||
|
|
||||||
|
|
|
@ -1,56 +1,94 @@
|
||||||
import tokens from "~/constant/tokens";
|
import {
|
||||||
import { defineStrategy, defineInput, StrategyInputType } from "../../helpers";
|
defineStrategy,
|
||||||
|
defineInput,
|
||||||
|
StrategyInputType,
|
||||||
|
StrategyProtocol
|
||||||
|
} from "../../helpers";
|
||||||
|
|
||||||
export default defineStrategy({
|
export default defineStrategy({
|
||||||
|
protocol: StrategyProtocol.AAVE_V2,
|
||||||
name: "Deposit & Borrow",
|
name: "Deposit & Borrow",
|
||||||
description: "Deposit collateral & borrow asset in a single txn.",
|
description: "Deposit collateral & borrow asset in a single txn.",
|
||||||
|
|
||||||
|
details: `<p class="text-center">This strategy executes:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Deposit collateral</li>
|
||||||
|
<li>Borrow Debt</li>
|
||||||
|
</ul>`,
|
||||||
|
|
||||||
author: "Instadapp Team",
|
author: "Instadapp Team",
|
||||||
|
|
||||||
inputs: [
|
inputs: [
|
||||||
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 ? `${input.token.symbol} to Payback` : "",
|
||||||
validate: ({ input }) => {
|
validate: ({ input }) => {
|
||||||
if (!input.token) {
|
if (!input.token) {
|
||||||
return "Token is required";
|
return "Debt token is required";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.token.balance < input.value) {
|
if (!input.value) {
|
||||||
return "Your amount exceeds your maximum limit.";
|
return "Deb amount is required";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (input.token.balance < input.value) {
|
||||||
|
// return "Your amount exceeds your maximum limit.";
|
||||||
|
// }
|
||||||
},
|
},
|
||||||
defaults: context => {
|
defaults: ({ getTokenByKey }) => ({
|
||||||
return {
|
token: getTokenByKey?.("eth")
|
||||||
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 }) =>
|
||||||
defaults: ({ dsaTokens }) => ({
|
input.token ? `${input.token.symbol} to Withdraw` : "",
|
||||||
token: dsaTokens
|
validate: ({ input }) => {
|
||||||
? Object.values(dsaTokens).find(t => t.key === "dai")
|
if (!input.token) {
|
||||||
: null
|
return "Collateral token is required";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!input.value) {
|
||||||
|
return "Collateral amount is required";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defaults: ({ getTokenByKey }) => ({
|
||||||
|
token: getTokenByKey?.("dai")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
|
|
||||||
spells: async ({ inputs }) => {
|
spells: async ({ inputs, convertTokenAmountToBigNumber }) => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
connector: "aave_v2",
|
connector: "aave_v2",
|
||||||
method: "deposit",
|
method: "deposit",
|
||||||
args: [inputs[0].token.address, inputs[0].value, 0, 0]
|
args: [
|
||||||
|
inputs[0].token.address,
|
||||||
|
convertTokenAmountToBigNumber(
|
||||||
|
inputs[0].value,
|
||||||
|
inputs[0].token.decimals
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
connector: "aave_v2",
|
connector: "aave_v2",
|
||||||
method: "borrow",
|
method: "borrow",
|
||||||
args: [inputs[1].token.address, inputs[1].value, 1, 0, 0]
|
args: [
|
||||||
|
inputs[1].token.address,
|
||||||
|
convertTokenAmountToBigNumber(
|
||||||
|
inputs[1].value,
|
||||||
|
inputs[1].token.decimals
|
||||||
|
),
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,29 @@
|
||||||
import tokens from "~/constant/tokens";
|
import tokens from "~/constant/tokens";
|
||||||
import { defineStrategy, defineInput, StrategyInputType } from "../../helpers";
|
import {
|
||||||
|
defineStrategy,
|
||||||
|
defineInput,
|
||||||
|
StrategyInputType,
|
||||||
|
StrategyProtocol
|
||||||
|
} from "../../helpers";
|
||||||
|
|
||||||
export default defineStrategy({
|
export default defineStrategy({
|
||||||
|
protocol: StrategyProtocol.AAVE_V2,
|
||||||
name: "Payback & Withdraw",
|
name: "Payback & Withdraw",
|
||||||
description: "Payback debt & withdraw collateral in a single txn.",
|
description: "Payback debt & withdraw collateral in a single txn.",
|
||||||
author: "Instadapp Team",
|
author: "Instadapp Team",
|
||||||
|
|
||||||
|
details: `<p class="text-center">This strategy executes:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Payback debt</li>
|
||||||
|
<li>Withdraw collateral</li>
|
||||||
|
</ul>`,
|
||||||
|
|
||||||
inputs: [
|
inputs: [
|
||||||
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 ? `${input.token.symbol} to Payback` : "",
|
||||||
validate: ({ input }) => {
|
validate: ({ input }) => {
|
||||||
if (!input.token) {
|
if (!input.token) {
|
||||||
return "Token is required";
|
return "Token is required";
|
||||||
|
@ -20,27 +33,49 @@ export default defineStrategy({
|
||||||
return "Your amount exceeds your maximum limit.";
|
return "Your amount exceeds your maximum limit.";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
token: tokens.mainnet.getTokenByKey("eth")
|
defaults: ({ getTokenByKey }) => ({
|
||||||
|
token: getTokenByKey?.("dai")
|
||||||
|
})
|
||||||
}),
|
}),
|
||||||
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 }) =>
|
||||||
token: tokens.mainnet.getTokenByKey("dai")
|
input.token ? `${input.token.symbol} to Withdraw` : "",
|
||||||
|
defaults: ({ getTokenByKey }) => ({
|
||||||
|
token: getTokenByKey?.("eth")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
|
|
||||||
spells: async ({ inputs }) => {
|
spells: async ({ inputs, convertTokenAmountToBigNumber }) => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
connector: "aave_v2",
|
connector: "aave_v2",
|
||||||
method: "payback",
|
method: "payback",
|
||||||
args: [inputs[0].token.address, inputs[0].value, 1, 0, 0]
|
args: [
|
||||||
|
inputs[0].token.address,
|
||||||
|
convertTokenAmountToBigNumber(
|
||||||
|
inputs[0].value,
|
||||||
|
inputs[0].token.decimals
|
||||||
|
),
|
||||||
|
12,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
connector: "aave_v2",
|
connector: "aave_v2",
|
||||||
method: "withdraw",
|
method: "withdraw",
|
||||||
args: [inputs[1].token.address, inputs[1].value, 0, 0]
|
args: [
|
||||||
|
inputs[1].token.address,
|
||||||
|
convertTokenAmountToBigNumber(
|
||||||
|
inputs[1].value,
|
||||||
|
inputs[1].token.decimals
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,8 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
||||||
onErrorCaptured(() => {
|
onErrorCaptured((error) => {
|
||||||
|
console.error(error)
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
"@nuxtjs/composition-api": "^0.24.7",
|
"@nuxtjs/composition-api": "^0.24.7",
|
||||||
"@portis/web3": "^4.0.5",
|
"@portis/web3": "^4.0.5",
|
||||||
"@tailwindcss/forms": "^0.3.3",
|
"@tailwindcss/forms": "^0.3.3",
|
||||||
|
"@tailwindcss/typography": "^0.4.1",
|
||||||
"@vueuse/core": "^5.1.4",
|
"@vueuse/core": "^5.1.4",
|
||||||
"@walletconnect/web3-provider": "^1.4.1",
|
"@walletconnect/web3-provider": "^1.4.1",
|
||||||
"bignumber.js": "^9.0.1",
|
"bignumber.js": "^9.0.1",
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
"nuxt": "^2.15.7",
|
"nuxt": "^2.15.7",
|
||||||
"qrcode": "^1.4.4",
|
"qrcode": "^1.4.4",
|
||||||
"slugify": "^1.6.0",
|
"slugify": "^1.6.0",
|
||||||
|
"tiny-emitter": "^2.1.0",
|
||||||
"v-click-outside": "^3.1.2",
|
"v-click-outside": "^3.1.2",
|
||||||
"v-tooltip": "^2.1.3",
|
"v-tooltip": "^2.1.3",
|
||||||
"vue-clipboard2": "^0.3.1",
|
"vue-clipboard2": "^0.3.1",
|
||||||
|
|
|
@ -120,5 +120,6 @@ module.exports = {
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
require('@tailwindcss/forms'),
|
require('@tailwindcss/forms'),
|
||||||
|
require('@tailwindcss/typography'),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
27
yarn.lock
27
yarn.lock
|
@ -1707,6 +1707,16 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
mini-svg-data-uri "^1.2.3"
|
mini-svg-data-uri "^1.2.3"
|
||||||
|
|
||||||
|
"@tailwindcss/typography@^0.4.1":
|
||||||
|
version "0.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.4.1.tgz#51ddbceea6a0ee9902c649dbe58871c81a831212"
|
||||||
|
integrity sha512-ovPPLUhs7zAIJfr0y1dbGlyCuPhpuv/jpBoFgqAc658DWGGrOBWBMpAWLw2KlzbNeVk4YBJMzue1ekvIbdw6XA==
|
||||||
|
dependencies:
|
||||||
|
lodash.castarray "^4.4.0"
|
||||||
|
lodash.isplainobject "^4.0.6"
|
||||||
|
lodash.merge "^4.6.2"
|
||||||
|
lodash.uniq "^4.5.0"
|
||||||
|
|
||||||
"@types/anymatch@*":
|
"@types/anymatch@*":
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-3.0.0.tgz#c95ff14401dbb2869913afac3935af4ad0d37f1a"
|
resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-3.0.0.tgz#c95ff14401dbb2869913afac3935af4ad0d37f1a"
|
||||||
|
@ -7277,11 +7287,21 @@ lodash._reinterpolate@^3.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
|
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
|
||||||
integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
|
integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
|
||||||
|
|
||||||
|
lodash.castarray@^4.4.0:
|
||||||
|
version "4.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115"
|
||||||
|
integrity sha1-wCUTUV4wna3dTCTGDP3c9ZdtkRU=
|
||||||
|
|
||||||
lodash.debounce@^4.0.8:
|
lodash.debounce@^4.0.8:
|
||||||
version "4.0.8"
|
version "4.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||||
integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=
|
integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=
|
||||||
|
|
||||||
|
lodash.isplainobject@^4.0.6:
|
||||||
|
version "4.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
|
||||||
|
integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
|
||||||
|
|
||||||
lodash.kebabcase@^4.1.1:
|
lodash.kebabcase@^4.1.1:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36"
|
resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36"
|
||||||
|
@ -7292,6 +7312,11 @@ lodash.memoize@^4.1.2:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||||
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
||||||
|
|
||||||
|
lodash.merge@^4.6.2:
|
||||||
|
version "4.6.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||||
|
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
||||||
|
|
||||||
lodash.template@^4.5.0:
|
lodash.template@^4.5.0:
|
||||||
version "4.5.0"
|
version "4.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
|
resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
|
||||||
|
@ -11030,7 +11055,7 @@ timsort@^0.3.0:
|
||||||
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
|
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
|
||||||
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
|
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
|
||||||
|
|
||||||
tiny-emitter@^2.0.0:
|
tiny-emitter@^2.0.0, tiny-emitter@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
|
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
|
||||||
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
|
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
|
||||||
|
|
Loading…
Reference in New Issue
Block a user