zhereh-frontend

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 6e8d29186fd5c55d5025aab629d43fb96de3ff10
parent 4d4c64b4da8549edb778fbf9f72bea3e3c9ea93c
Author: William Muli <willi.wambu@gmail.com>
Date:   Tue,  4 Jul 2023 14:43:14 +0300

Update wala interface to use PUT and GET methods

Diffstat:
Msrc/components/ProposalForm.svelte | 10++++++----
Msrc/components/ProposalView.svelte | 10++++++----
Asrc/lib/wala.ts | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/shared/wala.ts | 26--------------------------
4 files changed, 101 insertions(+), 34 deletions(-)

diff --git a/src/components/ProposalForm.svelte b/src/components/ProposalForm.svelte @@ -5,7 +5,7 @@ import { publicClient, walletClient } from '../client' import { voteContractAbi } from '../shared/token-vote-abi' import { Routes } from '../shared/types' - import { uploadTextToWala } from '../shared/wala' + import { Wala } from '$lib/wala' type ProposalFormData = { description: string @@ -43,7 +43,8 @@ } const createWithoutOptions = async(description: string, blockWait: number, targetVote: number) => { - const descriptionHash = await uploadTextToWala(description) + const descriptionHash = await new Wala().put(description, 'text/plain') + const { request } = await publicClient($configuredChain).simulateContract({ address: PUBLIC_VOTE_CONTRACT_ADDRESS as `0x${string}`, abi: voteContractAbi, @@ -60,8 +61,9 @@ } const createWithOptions = async(description: string, blockWait: number, targetVote: number, options: string[]) => { - const descriptionHash = await uploadTextToWala(description) - const promises = options.map(option => uploadTextToWala(option)) + const wala = new Wala() + const descriptionHash = await wala.put(description, 'text/plain') + const promises = options.map(option => wala.put(option, 'text/plain')) const optionHashes = (await Promise.all(promises)).map(optionHash => `0x${optionHash}`) const { request } = await publicClient($configuredChain).simulateContract({ address: PUBLIC_VOTE_CONTRACT_ADDRESS as `0x${string}`, diff --git a/src/components/ProposalView.svelte b/src/components/ProposalView.svelte @@ -6,7 +6,8 @@ import { onMount } from "svelte" import { publicClient } from "../client" import { getProposalStateDescription } from "../utils/proposal" - import { getText } from "../shared/wala" + import { Wala } from "../lib/wala" + export let proposal: Proposal let description: string | undefined @@ -23,13 +24,14 @@ const copyAddress = async (text: string) => await copyToClipboard(text) onMount(async () => { + const wala = new Wala() if(proposal.description) { - description = await getText(proposal.description) + description = await wala.get(proposal.description) as string } if(proposal.options) { - const promises = proposal.options.map(option => getText(option)) - options = await Promise.all(promises) + const promises = proposal.options.map(option => wala.get(option)) + options = (await Promise.all(promises)) as string[] } }) </script> diff --git a/src/lib/wala.ts b/src/lib/wala.ts @@ -0,0 +1,89 @@ +import { PUBLIC_WALA_URL } from '$env/static/public' + +export class Wala { + readonly walaUrl: string = PUBLIC_WALA_URL + + /** + * @param url Wala endpoint. + * If url is provided it overrides PUBLIC_WALA_URL environment variable + */ + constructor(url?: string) { + if (url !== undefined) { + this.walaUrl = url + } + } + + /** + * Creates a content address url + * @param hexString content address + * @returns + */ + url(hexString: string): string | undefined { + try { + // Remove '0x' prefix if present + const sanitizedHex = hexString.startsWith('0x') ? hexString.slice(2) : hexString + + // Create a URL object + const url = new URL(this.walaUrl) + url.pathname = sanitizedHex + + return url.href + } catch (error) { + console.error('Error creating URL:', error) + // Handle the error or return a default value + return undefined + } + } + + async put(body: string | FormData, contentType: string): Promise<string> { + const options: RequestInit = { + method: 'PUT', + body, + headers: { + 'Content-Type': contentType + } + } + + const response = await fetch(this.walaUrl, options) + return response.text() + } + + async get(hash: string): Promise<string | Blob> { + const url = this.url(hash) + if(!url) throw new Error('URL is empty') + + const response = await fetch(url) + + if (!response.ok) { + throw new Error( + `Error retrieving data from ${url}: ${response.status} ${response.statusText}` + ) + } + + const contentType = response.headers.get('Content-Type') + + if (!contentType) { + throw new Error(`Cannot determine content type for ${url}`) + } + + if (contentType.includes('application/json')) { + return await response.json() + } else if (contentType.includes('text/plain')) { + return await response.text() + } else if (contentType.includes('text/html')) { + return await response.text() + } else if (contentType.includes('application/pdf')) { + return await response.blob() + } else if (contentType.includes('application/msword')) { + return await response.blob() + } else if ( + contentType.includes( + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' + ) + ) { + return await response.blob() + } else { + throw new Error(`Unsupported content type: ${contentType}`) + } + } +} diff --git a/src/shared/wala.ts b/src/shared/wala.ts @@ -1,26 +0,0 @@ -import { PUBLIC_WALA_URL } from "$env/static/public"; - -export const uploadTextToWala = async (text: string) => { - try { - const response = await fetch(PUBLIC_WALA_URL, { - method: 'PUT', - headers: { - 'Content-Type': 'text/plain' - }, - body: text - }) - return response.text() - } catch (error) { - console.error(error) - } -} - -export const getText = async (hash: string) => { - try { - const h = hash.startsWith('0x') ? hash.substring(2) : hash - const response = await fetch(`${PUBLIC_WALA_URL}/${h}`) - return response.text() - } catch (error) { - console.error(error) - } -}