Skip to content

Commit

Permalink
check if safe address & chainId match
Browse files Browse the repository at this point in the history
  • Loading branch information
gsteenkamp89 committed Mar 25, 2024
1 parent dfb2406 commit 7cb56ed
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 31 deletions.
4 changes: 4 additions & 0 deletions src/helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,7 @@ export function toChecksumAddress(address: string) {
return address;
}
}

export function addressEqual(address1: string, address2: string) {
return address1.toLowerCase() === address2.toLowerCase();
}
34 changes: 17 additions & 17 deletions src/plugins/oSnap/components/Input/FileInput/FileInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
import { ref, defineProps, watch } from 'vue';
import { getFileFromEvent, isFileOfType } from './utils';
// Props definition
const props = defineProps<{
fileType: File['type'];
error?: string | undefined;
multiple?: boolean;
}>();
// Emits definition
const emit = defineEmits<{
(event: 'update:file', file: File | null): void;
(
Expand All @@ -17,16 +16,13 @@ const emit = defineEmits<{
): void;
}>();
// Internal state
const file = ref<File | null>(null);
const fileInputState = ref<'IDLE' | 'ERROR' | 'VALID' | 'INVALID_TYPE'>(
props.error ? 'ERROR' : 'IDLE'
);
// Computed properties for UI updates
const isDropping = ref(false);
// Methods
const handleFileChange = (event: Event | DragEvent) => {
isDropping.value = false;
const _file = getFileFromEvent(event);
Expand All @@ -40,7 +36,6 @@ const handleFileChange = (event: Event | DragEvent) => {
}
};
// Watchers
watch(file, newFile => {
emit('update:file', newFile);
});
Expand All @@ -49,7 +44,6 @@ watch(fileInputState, newState => {
emit('update:fileInputState', newState);
});
// Utility functions
const toggleDropping = () => {
isDropping.value = !isDropping.value;
};
Expand All @@ -70,18 +64,24 @@ const toggleDropping = () => {
'bg-green/10 border-green/50 text-green/80': fileInputState === 'VALID'
}"
>
<div class="flex flex-col gap-1 items-center justify-center">
<div
class="flex line-clamp-2 flex-col gap-1 items-center text-center justify-center"
>
<i-ho-upload />
<span v-if="fileInputState === 'VALID' && file">{{ file.name }}</span>
<span v-else-if="fileInputState === 'INVALID_TYPE'"
>File type must be <strong>{{ props.fileType }}</strong
>. Please choose another.</span
>
<span v-else-if="props.error">{{ props.error }}</span>
<span class="line-clamp-2">
<template v-if="props.error">{{ props.error }}</template>
<template v-else-if="fileInputState === 'INVALID_TYPE'"
>File type must be <strong>{{ props.fileType }}</strong
>. Please choose another.</template
>

<span v-else="fileInputState === 'IDLE'"
>Click to select file, or drag n drop</span
>
<template v-else-if="fileInputState === 'VALID' && file">{{
file.name
}}</template>
<template v-else="fileInputState === 'IDLE'"
>Click to select file, or drag n drop</template
>
</span>
</div>

<input
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ function addImportedTransactions(transactions: SafeImportTransaction[]) {
><span class="ml-2 inline-block">{{ transactions.length }}</span>
<TransactionImport
@update:imported-transactions="addImportedTransactions"
:safe="props.safe"
:network="props.network"
/>
</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
<script setup lang="ts">
import { GnosisSafe, Network, SafeImportTransaction } from '../../types';
import {
GnosisSafe,
Network,
SafeImportTransaction,
isErrorWithMessage
} from '../../types';
import { initializeSafeImportTransaction } from '../../utils';
import { parseGnosisSafeFile } from '../../utils/safeImport';
import FileInput from '../Input/FileInput/FileInput.vue';
const props = defineProps<{
network: Network;
safe: GnosisSafe | null;
}>();
// Emits definition
Expand All @@ -19,27 +25,29 @@ const emit = defineEmits<{
const file = ref<File>(); // raw file, if valid type
const safeFile = ref<GnosisSafe.BatchFile>(); // parsed, type-safe file
const isFileInvalid = computed(() => {
return file.value && !safeFile.value;
});
const error = ref<string>();
function resetState() {
file.value = undefined;
safeFile.value = undefined;
error.value = undefined;
}
// TODO: check network and "createdFromSafeAddress"
// TODO: allow multiple files at once
watch(file, async () => {
if (!file.value) return;
parseGnosisSafeFile(file.value)
parseGnosisSafeFile(file.value, props.safe)
.then(result => {
safeFile.value = result;
})
.catch(e => {
safeFile.value = undefined;
console.error(e);
if (isErrorWithMessage(e)) {
error.value = e.message;
return;
}
error.value = 'Safe file corrupted. Please select another.';
});
});
Expand All @@ -63,9 +71,7 @@ watch(safeFile, safeFile => {
<template>
<div class="text-skin-link mt-2">Import from Safe, or use the builder</div>
<FileInput
:error="
isFileInvalid ? 'Safe file corrupted. Please select another.' : undefined
"
:error="error"
@update:file="handleFileChange"
:file-type="'application/json'"
/>
Expand Down
30 changes: 26 additions & 4 deletions src/plugins/oSnap/utils/safeImport.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,47 @@
import { addressEqual } from '@/helpers/utils';
import { GnosisSafe } from '../types';
import { isSafeFile } from './validators';

export async function parseGnosisSafeFile(
file: File
file: File,
safe: GnosisSafe | null
): Promise<GnosisSafe.BatchFile> {
return new Promise((res, rej) => {
const reader = new FileReader();
reader.readAsText(file);
reader.onload = async () => {
try {
if (typeof reader.result !== 'string') {
throw new Error('Buffer can not be parsed');
return rej(new Error('Buffer can not be parsed'));
}
const json = JSON.parse(reader.result);
if (!isSafeFile(json)) {
throw new Error('Not a Gnosis Safe transaction file!');
return rej(new Error('Not a valid Safe transaction file.'));
}
if (!isCreatedFromSafe(json, safe)) {
return rej(
new Error(
"Safe file does not match the selected treasury's address or chain ID"
)
);
}
return res(json);
} catch (err) {
rej(err);
return rej(new Error('Safe file corrupted. Please select another.'));
}
};
});
}

function isCreatedFromSafe(
batchFile: GnosisSafe.BatchFile,
safe: GnosisSafe | null
): boolean {
if (safe && batchFile.meta.createdFromSafeAddress) {
return (
safe.network === batchFile.chainId &&
addressEqual(safe.safeAddress, batchFile.meta.createdFromSafeAddress)
);
}
return false;
}

0 comments on commit 7cb56ed

Please sign in to comment.