This commit is contained in:
Georges KABBOUCHI 2021-08-22 21:32:28 +03:00
parent 63dfc0c4c8
commit 6c3e80b291
7 changed files with 182 additions and 32 deletions

View File

@ -0,0 +1,81 @@
<template>
<Dropdown>
<template #trigger="{ toggle }">
<Button
:disabled="disabled"
color="grey"
class="flex px-3 py-1"
:class="{ 'pointer-events-none': disabled }"
:style="{ background: disabled ? 'none' : '' }"
@click="toggle"
>
<div class="flex flex-col items-center">
<IconCurrency :currency="tokenKey" />
<div
class="mt-2 font-semibold text-center text-11"
:class="{
'dark:text-grey-pure': disabled
}"
>
{{ label }}
</div>
</div>
</Button>
</template>
<template #menu="{ close }">
<DropdownMenu class="px-1 max-h-60">
<span v-if="!tokens.length" class="font-medium whitespace-no-wrap"
>No tokens available!</span
>
<div
v-else
class="flex flex-col overflow-x-hidden overflow-y-auto scrollbar-hover' pl-1 space-y-2 scrollbar"
>
<Button
v-for="(tokenKey, index) in tokens"
:key="index"
color="grey"
class="py-2 pl-2 pr-4 mr-1"
@click="select(tokenKey, close)"
>
<TokenSelectOption :token-key="tokenKey" class="w-full" />
</Button>
</div>
</DropdownMenu>
</template>
</Dropdown>
</template>
<script>
import { computed, defineComponent } from '@nuxtjs/composition-api'
import { useToken } from '~/composables/useToken'
import DropdownMenu from '~/components/protocols/DropdownMenu.vue'
import Dropdown from './common/input/Dropdown.vue'
export default defineComponent({
components: {
DropdownMenu,
Dropdown
},
model: {
prop: 'tokenKey',
event: 'change',
},
props: {
tokenKey: { type: String, default: null },
tokens: { type: Array, default: () => [] },
disabled: { type: Boolean, default: false },
},
setup(props, { emit }) {
const { getTokenByKey } = useToken()
const token = computed(() => getTokenByKey(props.tokenKey))
const label = computed(() => (props.disabled ? token.value?.symbol : 'Change'))
function select(tokenKey, callback) {
emit('change', tokenKey)
callback()
}
return { select, label }
},
})
</script>

View File

@ -0,0 +1,25 @@
<template>
<div class="flex items-center">
<IconCurrency :currency="tokenKey" no-height class="w-8 h-8" />
<div
class="ml-2 font-semibold text-center text-ocean-blue-pure text-12 dark:text-light"
>
{{ symbol }}
</div>
</div>
</template>
<script>
import { computed, defineComponent } from '@nuxtjs/composition-api'
import { useToken } from '~/composables/useToken'
export default defineComponent({
props: {
tokenKey: { type: String, required: true },
},
setup(props) {
const { getTokenByKey } = useToken()
return { symbol: computed(() => getTokenByKey(props.tokenKey)?.symbol) }
},
})
</script>

View File

@ -92,7 +92,7 @@
</template> </template>
<script> <script>
import { defineComponent, watch, ref, toRef } from '@nuxtjs/composition-api' import { defineComponent, watch, ref, toRef, computed } from '@nuxtjs/composition-api'
import { useInputListeners } from '@/composables/useInputListeners' import { useInputListeners } from '@/composables/useInputListeners'
import SVGSpinner from '@/assets/img/icons/spinner.svg' import SVGSpinner from '@/assets/img/icons/spinner.svg'
import { v4 as uuid } from 'uuid' import { v4 as uuid } from 'uuid'
@ -124,7 +124,9 @@ export default defineComponent({
setup(props, context) { setup(props, context) {
const id = uuid() const id = uuid()
const { symbol, getTokenByKey } = useToken(null, toRef(props, 'tokenKey')) const { getTokenByKey } = useToken()
const token = computed(() => getTokenByKey(props.tokenKey))
const symbol = computed(() => token.value?.symbol)
const { formatDecimal } = useFormatting() const { formatDecimal } = useFormatting()
const { amountPattern } = usePattern() const { amountPattern } = usePattern()

View File

@ -6,16 +6,28 @@
<div class="mx-auto" style="max-width: 296px"> <div class="mx-auto" style="max-width: 296px">
<div class="py-2 sm:py-4"> <div class="py-2 sm:py-4">
<div v-for="(input, index) in inputs" :key="index"> <div v-for="(input, index) in inputs" :key="index">
<input <input-amount
type="text" :key="index"
:value="input.value" :value="input.value"
@input="$event => input.onInput($event.target.value)" :token-key="input.token ? input.token.key : 'eth'"
:token-keys="input.tokenKeys ? input.tokenKeys : []"
:placeholder="input.placeholder()" :placeholder="input.placeholder()"
:error="input.error"
@input="$event => input.onInput($event)"
@tokenKeyChanged="
tokenKey => {
input.onCustomInput({
token: {
key: tokenKey,
symbol: tokenKey.toUpperCase(),
}
});
}
"
/> />
{{ input.error }}
</div> </div>
<button @submit="submit">Submit</button> <button @click="submit">Submit</button>
{{ error }} {{ error }}
</div> </div>
@ -29,8 +41,10 @@ import { defineComponent } from "@nuxtjs/composition-api";
import { useSidebar } from "~/composables/useSidebar"; import { useSidebar } from "~/composables/useSidebar";
import { protocolStrategies, DefineStrategy } from "~/core/strategies"; import { protocolStrategies, DefineStrategy } from "~/core/strategies";
import { useStrategy } from "~/composables/useStrategy"; import { useStrategy } from "~/composables/useStrategy";
import InputAmount from "~/components/common/input/InputAmount.vue";
export default defineComponent({ export default defineComponent({
components: { InputAmount },
props: { props: {
protocol: { protocol: {
type: String, type: String,

View File

@ -2,12 +2,19 @@ import { nextTick, onMounted, ref, watch } from "@nuxtjs/composition-api";
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 { useNotification } from "./useNotification";
import { useSidebar } from "./useSidebar";
import { useWeb3 } from "./useWeb3"; import { useWeb3 } from "./useWeb3";
export function useStrategy(defineStrategy: DefineStrategy) { export function useStrategy(defineStrategy: DefineStrategy) {
const { web3, networkName } = useWeb3(); const { web3, networkName, account } = useWeb3();
const { dsa } = useDSA(); const { dsa } = useDSA();
const { prices, balances } = useBalances(); const { prices, balances, fetchBalances } = useBalances();
const { close } = useSidebar();
const {
showPendingTransaction,
showConfirmedTransaction
} = useNotification();
const strategy = buildStrategy(defineStrategy); const strategy = buildStrategy(defineStrategy);
const inputs = ref(strategy.getInputs()); const inputs = ref(strategy.getInputs());
@ -17,11 +24,22 @@ export function useStrategy(defineStrategy: DefineStrategy) {
await nextTick(); await nextTick();
inputs.value = strategy.getInputs(); inputs.value = strategy.getInputs();
console.log("onUpdated");
}); });
const submit = async () => { const submit = async () => {
error.value = "";
try { try {
await strategy.submit(); const tx = await strategy.submit({
onReceipt: async () => {
showConfirmedTransaction(tx);
await fetchBalances(true);
},
from: account.value
});
showPendingTransaction(tx);
close();
} catch (e) { } catch (e) {
error.value = e.message; error.value = e.message;
} }
@ -55,6 +73,6 @@ export function useStrategy(defineStrategy: DefineStrategy) {
strategy, strategy,
inputs, inputs,
submit, submit,
error, error
}; };
} }

View File

@ -15,7 +15,7 @@ export class Strategy {
props: object = { props: object = {
prices: {}, prices: {},
dsaTokens: {}, dsaTokens: {},
userTokens: {}, userTokens: {}
}; };
constructor(schema: DefineStrategy) { constructor(schema: DefineStrategy) {
@ -47,10 +47,10 @@ export class Strategy {
...this.context, ...this.context,
inputs: this.inputs, inputs: this.inputs,
input: { input: {
...input,
token: { token: {
// todo // todo
} },
...input
} }
}) })
: null, : null,
@ -65,19 +65,28 @@ export class Strategy {
}); });
} }
this.notifyListeners();
},
onCustomInput: (values: object) => {
// input = Object.assign(input, values);
input.error = input.validate({
...this.getContext(),
input
});
this.notifyListeners(); this.notifyListeners();
} }
})); }));
} }
async submit() { async submit(options) {
await this.validate(); await this.validate();
const allSpells = await this.schema.spells(this.getContext()); const allSpells = await this.schema.spells(this.getContext());
const spells = this.context.dsa.Spell(); const spells = this.context.dsa.Spell();
console.log(spells); console.log(allSpells);
for (const spell of allSpells) { for (const spell of allSpells) {
spells.add(spell); spells.add(spell);
@ -85,7 +94,8 @@ export class Strategy {
return await this.context.dsa.cast({ return await this.context.dsa.cast({
spells, spells,
onReceipt: this.onReceipt onReceipt: options?.onReceipt,
from: options?.from
}); });
} }
@ -93,6 +103,10 @@ export class Strategy {
const inputs = this.getInputs(); const inputs = this.getInputs();
for (const input of inputs) { for (const input of inputs) {
if (typeof input.validate !== "function") {
continue;
}
const result = await input.validate({ const result = await input.validate({
...this.getContext(), ...this.getContext(),
input input
@ -104,13 +118,7 @@ export class Strategy {
} }
} }
onReceipt(txHash: string, txReceipt: any) {
// do something
}
setWeb3(web3: Web3) { setWeb3(web3: Web3) {
console.log(web3);
this.context.web3 = web3; this.context.web3 = web3;
} }

View File

@ -1,8 +1,4 @@
import { import { defineStrategy, defineInput, StrategyInputType } from "../../helpers";
defineStrategy,
defineInput,
StrategyInputType
} from "../../helpers";
export default defineStrategy({ export default defineStrategy({
name: "Deposit & Borrow", name: "Deposit & Borrow",
@ -22,12 +18,18 @@ export default defineStrategy({
if (input.token.balance < input.value) { if (input.token.balance < input.value) {
return "Your amount exceeds your maximum limit."; return "Your amount exceeds your maximum limit.";
} }
} },
tokenKeys: ["eth", "dai"],
tokens: [{ key: "eth", symbol: "ETH" }],
token: { key: "eth", symbol: "ETH", address : "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" }
}), }),
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`,
tokenKeys: ["eth", "dai"],
tokens: [{ key: "eth", symbol: "ETH" }],
token: { key: "dai", symbol: "DAI", address : "0x6B175474E89094C44Da98b954EedeAC495271d0F" }
}) })
], ],
@ -41,7 +43,7 @@ export default defineStrategy({
{ {
connector: "aave_v2", connector: "aave_v2",
method: "borrow", method: "borrow",
args: [inputs[1].token.address, inputs[1].value, 0, 0, 0] args: [inputs[1].token.address, inputs[1].value, 1, 0, 0]
} }
]; ];
} }