Skip to content

Commit

Permalink
show value & to fields
Browse files Browse the repository at this point in the history
  • Loading branch information
gsteenkamp89 committed Mar 18, 2024
1 parent 6217d74 commit 2f48613
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 68 deletions.
1 change: 1 addition & 0 deletions src/plugins/oSnap/components/Input/Amount.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const dirty = ref(false);
const format = (amount: string) => {
try {
// empty string throws
debugger;
const parsed = parseUnits(amount, props.decimals).toString();
return parsed;
} catch {
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/oSnap/components/Input/MethodParameter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ function validateBytesInput(value: string) {
function validateBytes32Input(value: string) {
try {
if (value.slice(2).length > 64) {
throw new Error('String too long');
if (value.slice(2).length !== 64) {
throw new Error('Not 32 bytes');
}
return isBytesLike(value);
} catch {
Expand Down
143 changes: 80 additions & 63 deletions src/plugins/oSnap/components/TransactionBuilder/SafeImport.vue
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
<script setup lang="ts">
import { parseAmount } from '@/helpers/utils';
import { isAddress } from '@ethersproject/address';
import { isHexString } from '@ethersproject/bytes';
import { SafeImportTransaction, GnosisSafe } from '../../types';
import { SafeImportTransaction, GnosisSafe, Network } from '../../types';
import {
createSafeImportTransaction,
parseValueInput,
isSafeFile,
getABIWriteFunctions,
CreateSafeTransactionParams,
extractSafeMethodAndParams
extractSafeMethodAndParams,
parseValueInput
} from '../../utils';
import AddressInput from '../Input/Address.vue';
import { parseGnosisSafeFile } from '../../utils/safeImport';
import { FunctionFragment } from '@ethersproject/abi';
import MethodParameterInput from '../../components/Input/MethodParameter.vue';
type PartialSafeImportTransaction = Omit<SafeImportTransaction, 'formatted'>;
import AddressInput from '../../components/Input/Address.vue';
import { isAddress } from '@ethersproject/address';
const props = defineProps<{
transaction: SafeImportTransaction | undefined;
network: Network;
setTransactionAsInvalid(): void;
}>();
Expand All @@ -31,9 +25,23 @@ const file = ref<File>();
const safeFile = ref<GnosisSafe.BatchFile>(); // raw, type-safe file
const selectedTransactionIndex = ref<number>();
const processedTransactions = ref<CreateSafeTransactionParams[]>();
const isValueValid = ref(true);
const finalTransaction = ref<CreateSafeTransactionParams>(); // decoded method, extracted args
const isToValid = computed(() => {
if (!finalTransaction?.value?.to) {
return true;
}
return isAddress(finalTransaction.value.to);
});
function updateFinalTransaction(tx: Partial<CreateSafeTransactionParams>) {
finalTransaction.value = {
...finalTransaction.value,
tx
} as CreateSafeTransactionParams;
}
function updateParams(
paramsToUpdate: CreateSafeTransactionParams['parameters']
) {
Expand All @@ -46,6 +54,23 @@ function updateParams(
} as CreateSafeTransactionParams;
}
function updateValue(newValue: string) {
try {
if (!finalTransaction.value) {
return;
}
const parsed = parseValueInput(newValue);
updateFinalTransaction({
value: parsed
});
isValueValid.value = true;
} catch (error) {
isValueValid.value = false;
} finally {
updateTransaction();
}
}
function handleFileChange(event: Event) {
const _file = (event?.currentTarget as HTMLInputElement)?.files?.[0];
if (!_file) return;
Expand All @@ -54,8 +79,6 @@ function handleFileChange(event: Event) {
parseGnosisSafeFile(file.value)
.then(result => {
safeFile.value = result;
// TODO: remove log
console.log(safeFile.value);
})
// TODO: show error
.catch(console.error)
Expand All @@ -64,11 +87,18 @@ function handleFileChange(event: Event) {
function updateTransaction() {
try {
debugger;
if (!finalTransaction.value) {
throw new Error('No Transaction selected');
}
// TODO: validate
if (!isValueValid.value) {
throw new Error('"Value" field is invalid');
}
if (!isToValid.value) {
throw new Error('"To" field is invalid');
}
const tx = createSafeImportTransaction(finalTransaction.value);
console.log(tx);
emit('updateTransaction', tx);
Expand All @@ -80,14 +110,12 @@ function updateTransaction() {
watch(safeFile, safeFile => {
if (safeFile) {
//reset
finalTransaction.value = undefined;
const convertedTxs = safeFile.transactions.map(extractSafeMethodAndParams);
processedTransactions.value = convertedTxs;
}
});
// need a way to select which transaction we want to import
watch(selectedTransactionIndex, index => {
if (
index === undefined ||
Expand All @@ -102,13 +130,12 @@ watch(finalTransaction, updateTransaction);
</script>

<template>
<div class="space-y-2">
<div class="my-3">
<input
accept="application/json"
type="file"
@change="handleFileChange($event)"
/>
<div v-if="file">Selected file: {{ file.name }}</div>
</div>
<div
v-if="safeFile?.transactions?.length"
Expand All @@ -117,55 +144,45 @@ watch(finalTransaction, updateTransaction);
<UiSelect v-model="selectedTransactionIndex">
<template #label>Select Transaction</template>
<option v-for="(tx, i) in safeFile.transactions" :key="i" :value="i">
{{ i + 1 }}. {{ tx?.contractMethod?.name }}
{{ i + 1 }}. {{ tx?.contractMethod?.name ?? 'send Funds' }}
</option>
</UiSelect>
</div>

<div
class="flex flex-col gap-2"
v-if="finalTransaction && finalTransaction.functionFragment?.inputs?.length"
>
<MethodParameterInput
v-for="input in finalTransaction.functionFragment.inputs"
:key="input.name"
:validateOnMount="true"
:parameter="input"
:value="finalTransaction?.parameters?.[input.name] ?? ''"
@update-parameter-value="(e: string) => updateParams({ [input.name]: e })"
<div v-if="finalTransaction" class="flex flex-col gap-2 mt-2">
<AddressInput
:modelValue="finalTransaction.to"
@change="(e: string) => updateFinalTransaction({ to: e })"
:label="$t('safeSnap.to')"
:error="!isToValid ? 'Invalid address' : undefined"
/>
</div>

<div v-if="props.transaction">
<strong>{{ props.transaction.subtype }}</strong>
<!-- ContractInteraction -->
<div v-if="props.transaction.methodName">
{{ props.transaction.methodName }}
</div>
<div v-if="props.transaction.parameters">
<p
v-for="[paramName, paramValue] in Object.entries(
props.transaction.parameters
)"
></p>
</div>
<pre lang="json">
{{ JSON.stringify(props.transaction.parameters) }}</pre
<UiInput
placeholder="123456"
:error="!isValueValid && 'Invalid value'"
:model-value="finalTransaction.value"
@update:model-value="(e: string) => updateFinalTransaction({ value: e })"
>
<template #label>Value (wei)</template>
</UiInput>

<!-- Native Transfer -->
<!-- ContractInteraction With Args -->
<div
class="flex flex-col gap-2"
v-if="finalTransaction.functionFragment?.inputs?.length"
>
<strong class="text-left mt-3">Parameters</strong>
<div class="divider h-[1px] bg-skin-border mb-3" />
<MethodParameterInput
v-for="input in finalTransaction.functionFragment.inputs"
:key="input.name"
:validateOnMount="true"
:parameter="input"
:value="finalTransaction?.parameters?.[input.name] ?? ''"
@update-parameter-value="
(e: string) => updateParams({ [input.name]: e })
"
/>
</div>
</div>

<!-- <div
v-if="props?.transaction?.parameters?.length"
class="flex w-full flex-col gap-4 rounded-2xl border border-skin-border p-3 md:p-4 relative"
>
<ReadOnly v-for="param in props.transaction.parameters">
<strong
class="mr-2 inline-block whitespace-nowrap first-letter:capitalize"
>{{ param.name }} ({{ param.type }})</strong
>
<span class="break-all">{{ param.value }}</span>
</ReadOnly>
</div> -->
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
type Transaction as TTransaction,
type TransactionType as TTransactionType,
type Token,
type TransferFundsTransaction
type TransferFundsTransaction,
SafeImportTransaction
} from '../../types';
import TransactionType from '../Input/TransactionType.vue';
import ContractInteraction from './ContractInteraction.vue';
Expand Down Expand Up @@ -113,7 +114,8 @@ function setTransactionAsInvalid() {

<SafeImport
v-if="transaction.type === 'safeImport'"
:transaction="newTransaction as TRawTransaction"
:transaction="newTransaction as SafeImportTransaction"
:network="network"
:setTransactionAsInvalid="setTransactionAsInvalid"
@update-transaction="updateTransaction"
/>
Expand Down
1 change: 0 additions & 1 deletion src/plugins/oSnap/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ export type SafeImportTransaction = BaseTransaction & {
methodName?: string;
method?: GnosisSafe.BatchTransaction['contractMethod'];
parameters?: GnosisSafe.BatchTransaction['contractInputsValues'];
subtype: string;
};

/**
Expand Down

0 comments on commit 2f48613

Please sign in to comment.