From f1c0e37d06258d9251e41155f3bede86b7cf1642 Mon Sep 17 00:00:00 2001 From: abefernan <44572727+abefernan@users.noreply.github.com> Date: Fri, 26 Jan 2024 17:13:27 +0100 Subject: [PATCH 01/10] Add Dgraph schema --- db-schema.graphql | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/db-schema.graphql b/db-schema.graphql index 06fa2a33..c73ed2e0 100644 --- a/db-schema.graphql +++ b/db-schema.graphql @@ -1,29 +1,20 @@ type Multisig { - pubkeyJSON: String! - address: String! + id: ID! chainId: String! -} - -type SourceAddress { - nickname: String address: String! - pubkey: String! - multisig: Multisig @relation + pubkeyJSON: String! } type Transaction { - signatures: [Signature] @relation - dataJSON: String + id: ID! txHash: String + dataJSON: String + signatures: [Signature] @hasInverse(field: transaction) } type Signature { - transaction: Transaction! @relation + transaction: Transaction! bodyBytes: String! signature: String! address: String! } - -type Query { - getMultisig(address: String!, chainId: String!): Multisig -} From 885b045bd73db35d02900d29fb0f547d7d2acf8d Mon Sep 17 00:00:00 2001 From: abefernan <44572727+abefernan@users.noreply.github.com> Date: Fri, 26 Jan 2024 17:14:46 +0100 Subject: [PATCH 02/10] Set Dgraph envvars --- .env.sample | 4 ++-- .env.test.sample | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.env.sample b/.env.sample index 11f106ed..ac70cc0c 100644 --- a/.env.sample +++ b/.env.sample @@ -1,4 +1,4 @@ -FAUNADB_SECRET= -FAUNADB_URL=https://graphql.eu.fauna.com/graphql +DGRAPH_SECRET= +DGRAPH_URL=https://nameless-brook-560056.eu-central-1.aws.cloud.dgraph.io/graphql NEXT_PUBLIC_MULTICHAIN=true NEXT_PUBLIC_REGISTRY_NAME=cosmoshub diff --git a/.env.test.sample b/.env.test.sample index 3e303cb2..730b6124 100644 --- a/.env.test.sample +++ b/.env.test.sample @@ -1,4 +1,4 @@ -FAUNADB_SECRET= -FAUNADB_URL=https://graphql.eu.fauna.com/graphql +DGRAPH_SECRET= +DGRAPH_URL=https://nameless-brook-560056.eu-central-1.aws.cloud.dgraph.io/graphql NEXT_PUBLIC_MULTICHAIN=true NEXT_PUBLIC_REGISTRY_NAME=junotestnet From 20d9a5a9e09b84cb2f9327ed04329755c5d24567 Mon Sep 17 00:00:00 2001 From: abefernan <44572727+abefernan@users.noreply.github.com> Date: Fri, 26 Jan 2024 17:14:58 +0100 Subject: [PATCH 03/10] Use Dgraph envvars for request --- lib/request.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/request.ts b/lib/request.ts index d3e48f36..de058b1c 100644 --- a/lib/request.ts +++ b/lib/request.ts @@ -29,7 +29,9 @@ type RequestGraphQlJsonConfig = Omit & { body: { query: str * https://docs.fauna.com/fauna/current/learn/understanding/region_groups */ export const requestGraphQlJson = (config: RequestGraphQlJsonConfig) => - requestJson(process.env.FAUNADB_URL || "https://graphql.fauna.com/graphql", { + requestJson(process.env.DGRAPH_URL || "", { ...config, - headers: { Authorization: `Bearer ${process.env.FAUNADB_SECRET}`, ...config.headers }, + headers: process.env.DGRAPH_SECRET + ? { "X-Auth-Token": process.env.DGRAPH_SECRET, ...config.headers } + : config.headers, }); From a824cfbb6805d80a108b7f3b00befdef8dbf0b67 Mon Sep 17 00:00:00 2001 From: abefernan <44572727+abefernan@users.noreply.github.com> Date: Fri, 26 Jan 2024 17:15:19 +0100 Subject: [PATCH 04/10] Tweak Graphql queries to fi Dgraph --- lib/graphqlHelpers.ts | 92 +++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/lib/graphqlHelpers.ts b/lib/graphqlHelpers.ts index 4d26fc80..9014d2da 100644 --- a/lib/graphqlHelpers.ts +++ b/lib/graphqlHelpers.ts @@ -8,19 +8,22 @@ import { requestGraphQlJson } from "./request"; * @return Returns async function that makes a request to the faunadb graphql endpoint */ const createMultisig = async (multisig: DbAccount) => { - console.log(multisig); return requestGraphQlJson({ body: { query: ` - mutation { - createMultisig(data: { - address: "${multisig.address}" - pubkeyJSON: ${JSON.stringify(multisig.pubkeyJSON)} - chainId: "${multisig.chainId}" - }) { - _id - address - chainId + mutation AddMultisig { + addMultisig( + input: { + chainId: "${multisig.chainId}" + address: "${multisig.address}" + pubkeyJSON: ${JSON.stringify(multisig.pubkeyJSON)} + } + ) { + multisig { + id + chainId + address + } } } `, @@ -39,11 +42,11 @@ const getMultisig = async (address: string, chainId: string) => { return requestGraphQlJson({ body: { query: ` - query { - getMultisig(address: "${address}", chainId: "${chainId}",) { + query GetMultisig { + getMultisig(chainId: "${chainId}", address: "${address}") { + chainId address pubkeyJSON - chainId } } `, @@ -61,9 +64,11 @@ const createTransaction = async (transaction: DbTransaction) => { return requestGraphQlJson({ body: { query: ` - mutation { - createTransaction(data: {dataJSON: ${JSON.stringify(transaction)}}) { - _id + mutation AddTransaction { + addTransaction(input: { dataJSON: ${JSON.stringify(transaction)} }) { + transaction { + id + } } } `, @@ -81,17 +86,14 @@ const findTransactionByID = async (id: string) => { return requestGraphQlJson({ body: { query: ` - query { - findTransactionByID(id: "${id}") { - _id + query GetTransaction { + getTransaction(id: "${id}") { dataJSON txHash signatures { - data { - address - signature - bodyBytes - } + address + signature + bodyBytes } } } @@ -111,13 +113,15 @@ const updateTxHash = async (id: string, txHash: string) => { return requestGraphQlJson({ body: { query: ` - mutation { - updateTransaction(id: ${id}, data: {txHash: "${txHash}"}) { - _id - dataJSON - txHash - signatures { - data { + mutation UpdateTransaction { + updateTransaction( + input: { filter: { id: "${id}" }, set: { txHash: "${txHash}" } } + ) { + transaction { + id + dataJSON + txHash + signatures { address signature bodyBytes @@ -141,17 +145,21 @@ const createSignature = async (signature: DbSignature, transactionId: string) => return requestGraphQlJson({ body: { query: ` - mutation { - createSignature(data: { - transaction: {connect: ${transactionId}}, - bodyBytes: "${signature.bodyBytes}", - signature: "${signature.signature}", - address: "${signature.address}" - }) { - _id - address - signature - address + mutation AddSignature { + addSignature( + input: { + transaction: { id: "${transactionId}" } + address: "${signature.address}" + signature: "${signature.signature}" + bodyBytes: "${signature.bodyBytes}" + } + ) { + signature { + transaction { + id + } + signature + } } } `, From 93502bf72df64714572d7f9b5696e7cfa6857e04 Mon Sep 17 00:00:00 2001 From: abefernan <44572727+abefernan@users.noreply.github.com> Date: Fri, 26 Jan 2024 17:15:52 +0100 Subject: [PATCH 05/10] Tweak graphql responses in edge functions --- pages/[chainName]/[address]/transaction/[transactionID].tsx | 6 +++--- pages/api/chain/[chainId]/multisig/index.ts | 4 ++-- pages/api/transaction/[transactionID]/index.ts | 2 +- pages/api/transaction/[transactionID]/signature.ts | 2 +- pages/api/transaction/index.ts | 4 +++- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/pages/[chainName]/[address]/transaction/[transactionID].tsx b/pages/[chainName]/[address]/transaction/[transactionID].tsx index f35a23da..f6052129 100644 --- a/pages/[chainName]/[address]/transaction/[transactionID].tsx +++ b/pages/[chainName]/[address]/transaction/[transactionID].tsx @@ -40,9 +40,9 @@ export const getServerSideProps: GetServerSideProps = async (context): Promise

Date: Thu, 8 Feb 2024 16:19:25 +0100 Subject: [PATCH 06/10] Remove faunadb dependency --- package-lock.json | 153 ---------------------------------------------- package.json | 1 - 2 files changed, 154 deletions(-) diff --git a/package-lock.json b/package-lock.json index d27bcd22..98323da1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -64,7 +64,6 @@ "eslint": "8.48.0", "eslint-config-next": "13.4.19", "eslint-config-prettier": "^9.0.0", - "faunadb": "^4.8.0", "jest": "^29.6.4", "jest-environment-jsdom": "^29.6.4", "lucide-react": "^0.274.0", @@ -4390,14 +4389,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dependencies": { - "string-width": "^4.1.0" - } - }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -4869,38 +4860,6 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" }, - "node_modules/boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dependencies": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boxen/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4965,11 +4924,6 @@ "node-int64": "^0.4.0" } }, - "node_modules/btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA==" - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -5136,17 +5090,6 @@ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, - "node_modules/cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -5531,14 +5474,6 @@ "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.9.0.tgz", "integrity": "sha512-MN/yUe6mkJwHnCFfsNPeCfXVhyxHYW6c/xDUzrSbBycYzw++XvWDMJArXp2pLdgD6FQ8DW79vkPjeNKVrXaHeQ==" }, - "node_modules/cross-fetch": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", - "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", - "dependencies": { - "node-fetch": "^2.6.12" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -5943,14 +5878,6 @@ "node": ">=12" } }, - "node_modules/dotenv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", - "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", - "engines": { - "node": ">=10" - } - }, "node_modules/electron-to-chromium": { "version": "1.4.510", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.510.tgz", @@ -6729,24 +6656,6 @@ "reusify": "^1.0.4" } }, - "node_modules/faunadb": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/faunadb/-/faunadb-4.8.0.tgz", - "integrity": "sha512-pjl5WUYQ8GqM4ESk3mv0RXfxtQMHWb92XWkxjf3nWiAkf2HVtsENfTbyGPunzw4zDbdhn9aQSSxbwahaLLDR7Q==", - "hasInstallScript": true, - "dependencies": { - "base64-js": "^1.2.0", - "boxen": "^5.0.1", - "btoa-lite": "^1.0.0", - "chalk": "^4.1.1", - "cross-fetch": "^3.1.5", - "dotenv": "^8.2.0", - "fn-annotate": "^1.1.3", - "node-abort-controller": "^3.0.1", - "object-assign": "^4.1.0", - "util-deprecate": "^1.0.2" - } - }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", @@ -6815,14 +6724,6 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" }, - "node_modules/fn-annotate": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fn-annotate/-/fn-annotate-1.2.0.tgz", - "integrity": "sha512-j2gv2wkRhQgkJNf1ygdca8ynP3tK+a87bowc+RG81iWTye3yKIOeAkrKYv0Kqyh8yCeSyljOk3ZFelfXUFpirA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/follow-redirects": { "version": "1.15.3", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", @@ -8969,49 +8870,6 @@ "url": "https://github.com/sponsors/colinhacks" } }, - "node_modules/node-abort-controller": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", - "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -11406,17 +11264,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dependencies": { - "string-width": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/package.json b/package.json index f39b7fce..6eac7ed5 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,6 @@ "eslint": "8.48.0", "eslint-config-next": "13.4.19", "eslint-config-prettier": "^9.0.0", - "faunadb": "^4.8.0", "jest": "^29.6.4", "jest-environment-jsdom": "^29.6.4", "lucide-react": "^0.274.0", From b4dc05e98d799bca2b527164f8e16bdc01608215 Mon Sep 17 00:00:00 2001 From: abefernan <44572727+abefernan@users.noreply.github.com> Date: Thu, 8 Feb 2024 16:19:54 +0100 Subject: [PATCH 07/10] Change comments refering to Fauna --- lib/graphqlHelpers.ts | 26 +++++++++++++------------- lib/multisigHelpers.ts | 4 ++-- lib/request.ts | 4 ---- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/lib/graphqlHelpers.ts b/lib/graphqlHelpers.ts index 9014d2da..2218cd6d 100644 --- a/lib/graphqlHelpers.ts +++ b/lib/graphqlHelpers.ts @@ -2,10 +2,10 @@ import { DbAccount, DbSignature, DbTransaction } from "../types"; import { requestGraphQlJson } from "./request"; /** - * Creates multisig record in faunadb + * Creates multisig record in dgraph * * @param {object} multisig an object with address (string), pubkey JSON and chainId - * @return Returns async function that makes a request to the faunadb graphql endpoint + * @return Returns async function that makes a request to the dgraph graphql endpoint */ const createMultisig = async (multisig: DbAccount) => { return requestGraphQlJson({ @@ -36,7 +36,7 @@ const createMultisig = async (multisig: DbAccount) => { * * @param {string} address A multisig address. * @param {string} chainId The chainId the multisig belongs to. - * @return Returns async function that makes a request to the faunadb graphql endpoint + * @return Returns async function that makes a request to the dgraph graphql endpoint */ const getMultisig = async (address: string, chainId: string) => { return requestGraphQlJson({ @@ -55,10 +55,10 @@ const getMultisig = async (address: string, chainId: string) => { }; /** - * Creates transaction record in faunadb + * Creates transaction record in dgraph * * @param {object} transaction The base transaction - * @return Returns async function that makes a request to the faunadb graphql endpoint + * @return Returns async function that makes a request to the dgraph graphql endpoint */ const createTransaction = async (transaction: DbTransaction) => { return requestGraphQlJson({ @@ -77,10 +77,10 @@ const createTransaction = async (transaction: DbTransaction) => { }; /** - * Retrieves a transaction from faunadb + * Retrieves a transaction from dgraph * - * @param {string} id Faunadb resource id - * @return Returns async function that makes a request to the faunadb graphql endpoint + * @param {string} id dgraph resource id + * @return Returns async function that makes a request to the dgraph graphql endpoint */ const findTransactionByID = async (id: string) => { return requestGraphQlJson({ @@ -103,11 +103,11 @@ const findTransactionByID = async (id: string) => { }; /** - * Updates txHash of transaction on FaunaDB + * Updates txHash of transaction on dgraph * - * @param {string} id Faunadb resource id + * @param {string} id dgraph resource id * @param {string} txHash tx hash returned from broadcasting a tx - * @return Returns async function that makes a request to the faunadb graphql endpoint + * @return Returns async function that makes a request to the dgraph graphql endpoint */ const updateTxHash = async (id: string, txHash: string) => { return requestGraphQlJson({ @@ -135,11 +135,11 @@ const updateTxHash = async (id: string, txHash: string) => { }; /** - * Creates signature record in faunadb + * Creates signature record in dgraph * * @param {object} signature an object with bodyBytes (string) and signature set (Uint8 Array) * @param {string} transactionId id of the transaction to relate the signature with - * @return Returns async function that makes a request to the faunadb graphql endpoint + * @return Returns async function that makes a request to the dgraph graphql endpoint */ const createSignature = async (signature: DbSignature, transactionId: string) => { return requestGraphQlJson({ diff --git a/lib/multisigHelpers.ts b/lib/multisigHelpers.ts index 2c9ae887..3c6f7770 100644 --- a/lib/multisigHelpers.ts +++ b/lib/multisigHelpers.ts @@ -38,7 +38,7 @@ const createMultisigFromCompressedSecp256k1Pubkeys = async ( const multisigPubkey = createMultisigThresholdPubkey(pubkeys, threshold); const multisigAddress = pubkeyToAddress(multisigPubkey, addressPrefix); - // save multisig to fauna + // save multisig to relational offchain database const multisig = { address: multisigAddress, pubkeyJSON: JSON.stringify(multisigPubkey), @@ -73,7 +73,7 @@ const getMultisigAccount = async ( // we need the multisig pubkeys to create transactions, if the multisig // is new, and has never submitted a transaction its pubkeys will not be // available from a node. If the multisig was created with this instance - // of this tool its pubkey will be available in the fauna datastore + // of this tool its pubkey will be available in the relational offchain database const addressError = checkAddress(address, addressPrefix); if (addressError) { throw new Error(addressError); diff --git a/lib/request.ts b/lib/request.ts index de058b1c..263d27a3 100644 --- a/lib/request.ts +++ b/lib/request.ts @@ -24,10 +24,6 @@ export const requestGhJson = (endpoint: string, { headers, ...restConfig }: Requ type RequestGraphQlJsonConfig = Omit & { body: { query: string } }; -/** - * The fallback URL works for classic databases,for more information about regions see: - * https://docs.fauna.com/fauna/current/learn/understanding/region_groups - */ export const requestGraphQlJson = (config: RequestGraphQlJsonConfig) => requestJson(process.env.DGRAPH_URL || "", { ...config, From ee2ffbf2e15abe36b56a473ae470df50b751bf3e Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Sat, 10 Feb 2024 22:56:05 +0100 Subject: [PATCH 08/10] Fix getMultisig implementation --- db-schema.graphql | 7 ++-- lib/graphqlHelpers.ts | 33 +++++++++++++++---- .../multisig/[multisigAddress]/index.ts | 8 ++--- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/db-schema.graphql b/db-schema.graphql index c73ed2e0..a376c75c 100644 --- a/db-schema.graphql +++ b/db-schema.graphql @@ -1,7 +1,10 @@ type Multisig { id: ID! - chainId: String! - address: String! + # The @search annotation allows us to query the list of multisigs and filter + # by (chainId, address) pairs. We use "hash" since we only need exact matches. + # See https://dgraph.io/docs/graphql/schema/directives/search/#string + chainId: String! @search(by: [hash]) + address: String! @search(by: [hash]) pubkeyJSON: String! } diff --git a/lib/graphqlHelpers.ts b/lib/graphqlHelpers.ts index 2218cd6d..836f1530 100644 --- a/lib/graphqlHelpers.ts +++ b/lib/graphqlHelpers.ts @@ -32,27 +32,46 @@ const createMultisig = async (multisig: DbAccount) => { }; /** - * Gets multisig pubkey from faundb + * This is the format returned by the graphQL API. + * + * Keep the format in sync with `GetMultisigAccountResponse` because + * we return the full object in the API. Right now address and chainId + * are somewhat unnecessary to query but still nice for debgging. + */ +interface MultisigFromQuery { + address: string; + chainId: string; + pubkeyJSON: string; +} + +/** + * Gets multisig pubkey from DB * * @param {string} address A multisig address. * @param {string} chainId The chainId the multisig belongs to. * @return Returns async function that makes a request to the dgraph graphql endpoint */ -const getMultisig = async (address: string, chainId: string) => { - return requestGraphQlJson({ +async function getMultisig( + address: string, + chainId: string, +): Promise { + const result = await requestGraphQlJson({ body: { query: ` - query GetMultisig { - getMultisig(chainId: "${chainId}", address: "${address}") { - chainId + query MultisigsByAddressAndChainId { + queryMultisig(filter: {address: {eq: "${address}"}, chainId: {eq: "${chainId}"}}) { address + chainId pubkeyJSON } } `, }, }); -}; + const elements: [MultisigFromQuery] = result.data.queryMultisig; + const first = elements.find(() => true); + return first; +} /** * Creates transaction record in dgraph diff --git a/pages/api/chain/[chainId]/multisig/[multisigAddress]/index.ts b/pages/api/chain/[chainId]/multisig/[multisigAddress]/index.ts index fb1bb76e..0c782b75 100644 --- a/pages/api/chain/[chainId]/multisig/[multisigAddress]/index.ts +++ b/pages/api/chain/[chainId]/multisig/[multisigAddress]/index.ts @@ -8,13 +8,13 @@ export default async function multisigAddressApi(req: NextApiRequest, res: NextA const multisigAddress = req.query.multisigAddress?.toString() || ""; const chainId = req.query.chainId?.toString() || ""; console.log("Function `getMultisig` invoked", multisigAddress, chainId); - const getRes = await getMultisig(multisigAddress, chainId); - if (!getRes.data.getMultisig) { + const multisig = await getMultisig(multisigAddress, chainId); + if (!multisig) { res.status(404).send("Multisig not found"); return; } - console.log("success", getRes.data.getMultisig); - res.status(200).send(getRes.data.getMultisig); + console.log("success", multisig); + res.status(200).send(multisig); return; // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (err: any) { From 00ec1b64beb659645d98d52256b6e26fd9b85f97 Mon Sep 17 00:00:00 2001 From: abefernan <44572727+abefernan@users.noreply.github.com> Date: Tue, 5 Mar 2024 12:14:05 +0100 Subject: [PATCH 09/10] Remove migration warning --- components/MigrationWarning.tsx | 24 ------------------------ pages/_app.tsx | 2 -- 2 files changed, 26 deletions(-) delete mode 100644 components/MigrationWarning.tsx diff --git a/components/MigrationWarning.tsx b/components/MigrationWarning.tsx deleted file mode 100644 index 39c8c087..00000000 --- a/components/MigrationWarning.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; - -export default function MigrationWarning() { - return ( - - Warning! - - This app will no longer be available at this URL from March 1st, 2024. - - - A new instance is deployed at{" "} - - https://multisig.confio.run - - , connecting to a new database. You can start using this instance for new signing requests. - Re-importing multisigs by address or public keys may be needed. - - - Any pending transactions on this app will be lost when that time arrives. In the meantime, - both deployments can be used but no data is shared between them. - - - ); -} diff --git a/pages/_app.tsx b/pages/_app.tsx index 51357acc..f0d96ac6 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,5 +1,4 @@ import Header from "@/components/Header"; -import MigrationWarning from "@/components/MigrationWarning"; import { Toaster } from "@/components/ui/toaster"; import { TooltipProvider } from "@/components/ui/tooltip"; import ThemeProvider from "@/context/ThemesContext"; @@ -13,7 +12,6 @@ export default function MultisigApp({ Component, pageProps }: AppProps) {

- From 1ae3a540703ded75e3652e83d66b16d73da121bb Mon Sep 17 00:00:00 2001 From: abefernan <44572727+abefernan@users.noreply.github.com> Date: Tue, 5 Mar 2024 12:30:35 +0100 Subject: [PATCH 10/10] Update readme with dgraph --- README.md | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index d068f99f..650b01a4 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Cosmoshub Multisig App -This app allows for multisig users to create, sign and broadcast transactions on any stargate enabled chain. It's built with Cosmjs, Next.js, FaunaDB and Vercel. +This app allows for multisig users to create, sign and broadcast transactions on any stargate enabled chain. It's built with Cosmjs, Next.js, Dgraph and Vercel. -[The app is live here](https://cosmos-multisig-ui-kohl.vercel.app/). +[The app is live here](https://multisig.confio.run). [Here is a user guide on how to use the app](https://github.com/samepant/cosmoshub-legacy-multisig/blob/master/docs/App%20User%20Guide.md) @@ -16,19 +16,18 @@ This app uses Vercel for deployment and hosting, since they support next.js's se ### 2. Setup environment variables -In the Vercel control panel for your new app, go to `Settings -> Environment Variables` and add in the keys and values from this repo's `.env.sample` file. The only remaining variable should be the `FAUNADB_SECRET`, which will be available once you setup your FaunaDB instance. +In the Vercel control panel for your new app, go to `Settings -> Environment Variables` and add in the keys and values from this repo's `.env.sample` file. The only remaining variable should be the `DGRAPH_SECRET`, which will be available once you setup your DGraph instance. -### 3. Initializing FaunaDB +### 3. Initializing DGraph -This app relies on FaunaDB as for storing account, transaction and signature details. +This app relies on DGraph as for storing account, transaction and signature details. -- Create a [FaunaDB](https://dashboard.fauna.com/) account -- Create a new database - - Use the "Classic" region -- Click the "Graphql" tab, and import the `db-schema.graphql` file in the root of this repo -- Click the "Security" tab, and create a key. Copy that key into your vercel app's environment variables as the `FAUNADB_SECRET` value +- Create a [DGraph](https://cloud.dgraph.io) account +- Launch a new backend +- Click the `Develop -> Schema` menu item, and past the contents of the `db-schema.graphql` file in the root of this repo +- Click the `Admin -> Settings` menu item, and create a key. Copy that key into your vercel app's environment variables as the `DGRAPH_SECRET` value -As your instance of the app is used, you can return to the FaunaDB dashboard to view records for any accounts, transactions or signatures. +As your instance of the app is used, you can return to the DGraph dashboard to view records for any accounts, transactions or signatures. ### 4. Successful Deployment @@ -46,17 +45,16 @@ It's recommended that you make your simapp instance mimic the denomination of co A more in depth tutorial on this is coming soon :) -### 3. Initializing FaunaDB +### 3. Initializing DGraph -This app relies on FaunaDB as for storing account, transaction and signature details. +This app relies on DGraph as for storing account, transaction and signature details. -- Create a [FaunaDB](https://dashboard.fauna.com/) account -- Create a new database - - Use the "Europe (EU)" region -- Click the "Graphql" tab, and import the `db-schema.graphql` file in the root of this repo -- Click the "Security" tab, and create a key. Copy that key into the `.env.local` file for the `FAUNADB_SECRET` value +- Create a [DGraph](https://cloud.dgraph.io) account +- Launch a new backend +- Click the `Develop -> Schema` menu item, and past the contents of the `db-schema.graphql` file in the root of this repo +- Click the `Admin -> Settings` menu item, and create a key. Copy that key into your vercel app's environment variables as the `DGRAPH_SECRET` value -As your instance of the app is used, you can return to the FaunaDB dashboard to view records for any accounts, transactions or signatures created. +As your instance of the app is used, you can return to the DGraph dashboard to view records for any accounts, transactions or signatures. ### 3. Run your instance