From 9ae437bbcd41c2968772a492ac2b03b000dea744 Mon Sep 17 00:00:00 2001 From: abefernan <44572727+abefernan@users.noreply.github.com> Date: Thu, 27 Jun 2024 11:33:49 +0200 Subject: [PATCH] Add transaction graphql helpers --- graphql/transaction.ts | 158 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 graphql/transaction.ts diff --git a/graphql/transaction.ts b/graphql/transaction.ts new file mode 100644 index 0000000..1e904cf --- /dev/null +++ b/graphql/transaction.ts @@ -0,0 +1,158 @@ +import { StdFee } from "@cosmjs/amino"; +import { EncodeObject } from "@cosmjs/proto-signing"; +import { gql } from "graphql-request"; +import { z } from "zod"; +import { DbMultisig, DbMultisigId, DbSignatureObj, gqlClient } from "."; + +export const DbTransaction = z.object({ + id: z.string(), + txHash: z.string().nullish(), + creator: z.lazy(() => DbMultisig.nullish()), + // When parsed with JSON.parse it's DbTransactionParsedDataJson + dataJSON: z.string(), + signatures: z.lazy(() => z.array(DbSignatureObj)), +}); +export type DbTransaction = Readonly>; + +export interface DbTransactionParsedDataJson { + readonly accountNumber: number; + readonly sequence: number; + readonly chainId: string; + readonly msgs: EncodeObject[]; + readonly fee: StdFee; + readonly memo: string; +} + +export type DbTransactionDraft = Pick & { creator: DbMultisigId }; + +export const DbTransactionId = DbTransaction.pick({ id: true }); +export type DbTransactionId = Readonly>; + +export const getTransaction = async (id: string): Promise => { + type Response = { readonly getTransaction: DbTransaction | null }; + type Variables = { readonly id: string }; + + const { getTransaction: fetchedTx } = await gqlClient.request( + gql` + query GetTransaction($id: ID!) { + getTransaction(id: $id) { + id + txHash + creator { + id + chainId + address + creator + pubkeyJSON + } + dataJSON + signatures { + bodyBytes + signature + address + } + } + } + `, + { id }, + ); + + if (!fetchedTx) { + return null; + } + + DbTransaction.parse(fetchedTx); + + return fetchedTx; +}; + +const DbMultisigTxs = z.object({ transactions: z.array(DbTransaction) }); +type DbMultisigTxs = Readonly>; + +export const getTransactions = async (creatorId: string): Promise => { + type Response = { readonly getMultisig: DbMultisigTxs }; + type Variables = { readonly creatorId: string }; + + const { getMultisig } = await gqlClient.request( + gql` + query GetTransactions($creatorId: ID!) { + getMultisig(id: $creatorId) { + transactions { + id + txHash + creator { + id + chainId + address + creator + pubkeyJSON + } + dataJSON + signatures { + bodyBytes + signature + address + } + } + } + } + `, + { creatorId }, + ); + + const fetchedTxs: DbMultisigTxs = { transactions: getMultisig.transactions.reverse() }; + DbMultisigTxs.parse(fetchedTxs); + + return fetchedTxs.transactions; +}; + +export const createTransaction = async (transaction: DbTransactionDraft) => { + type Response = { readonly addTransaction: { readonly transaction: readonly DbTransactionId[] } }; + type Variables = { readonly dataJSON: string; readonly creatorId: string }; + + const { addTransaction } = await gqlClient.request( + gql` + mutation CreateTransaction($dataJSON: String!, $creatorId: ID!) { + addTransaction(input: { dataJSON: $dataJSON, creator: { id: $creatorId } }) { + transaction { + id + } + } + } + `, + { ...transaction, creatorId: transaction.creator.id }, + ); + + const createdTx = addTransaction.transaction[0]; + DbTransactionId.parse(createdTx); + + return createdTx.id; +}; + +const DbTransactionTxHash = z.object({ txHash: z.string() }); +type DbTransactionTxHash = Readonly>; + +export const updateTxHash = async (id: string, txHash: string) => { + type Response = { + readonly updateTransaction: { readonly transaction: readonly DbTransactionTxHash[] }; + }; + type Variables = { readonly id: string; readonly txHash: string }; + + const { updateTransaction } = await gqlClient.request( + gql` + mutation UpdateTxHash($id: [ID!], $txHash: String!) { + updateTransaction(input: { filter: { id: $id }, set: { txHash: $txHash } }) { + transaction { + txHash + } + } + } + `, + { id, txHash }, + ); + + const updatedTx = updateTransaction.transaction[0]; + DbTransactionTxHash.parse(updatedTx); + + return updatedTx.txHash; +};