diff --git a/compliant-reward-distribution/frontend/src/apiReqeuests.ts b/compliant-reward-distribution/frontend/src/apiReqeuests.ts index 593185bb..03b4c64b 100644 --- a/compliant-reward-distribution/frontend/src/apiReqeuests.ts +++ b/compliant-reward-distribution/frontend/src/apiReqeuests.ts @@ -1,4 +1,5 @@ -import { AccountAddress, AtomicStatementV2, CredentialStatement, VerifiablePresentation } from '@concordium/web-sdk'; +import JSONBig from 'json-bigint'; +import { AtomicStatementV2, CredentialStatement, VerifiablePresentation } from '@concordium/web-sdk'; /** * Represents the stored data in the database of an indexed account (excluding tweet/zkProof data). @@ -11,7 +12,7 @@ import { AccountAddress, AtomicStatementV2, CredentialStatement, VerifiablePrese * conditions via a ZK proof. A manual check of the completed tasks is required before releasing the reward. */ interface StateData { - accountAddress: AccountAddress.Type; + accountAddress: string; blockTime: string; transactionHash: string; claimed: boolean; @@ -31,7 +32,7 @@ interface StateData { * @property tweetSubmitTime - The timestamp when the tweet was submitted. */ interface TweetData { - accountAddress: AccountAddress.Type; + accountAddress: string; tweetId: string | undefined; tweetValid: boolean; tweetVerificationVersion: number; @@ -51,7 +52,7 @@ interface TweetData { * @property zkProofVerificationSubmitTime - The timestamp when the ZK proof was submitted. */ interface ZkProofData { - accountAddress: AccountAddress.Type; + accountAddress: string; uniquenessHash: string; zkProofValid: boolean; zkProofVerificationVersion: number; @@ -65,7 +66,7 @@ interface ZkProofData { * @property tweetData - Stored data of a submitted tweet if present. * @property zkProofData - Stored data of a submitted ZK proof if present. */ -interface AccountData { +export interface AccountData { stateData: StateData | undefined; tweetData: TweetData | undefined; zkProofData: ZkProofData | undefined; @@ -79,7 +80,7 @@ interface AccountData { * @returns The request options for the specified method. * @throws An error if the method is invalid or if the body is incorrectly provided for the method. */ -function createRequestOptions(method: string, body?: string): RequestInit { +function createRequestOptions(method: string, body?: object): RequestInit { switch (method) { case 'GET': return { @@ -92,7 +93,7 @@ function createRequestOptions(method: string, body?: string): RequestInit { return { method: 'POST', headers: new Headers({ 'content-type': 'application/json' }), - body: body, + body: JSONBig.stringify(body), }; default: throw new Error(`Invalid method: ${method}`); @@ -110,7 +111,7 @@ function createRequestOptions(method: string, body?: string): RequestInit { * @throws An error if the method is invalid, if the body is incorrectly provided for the method, * or if the backend responses with an error. */ -async function sendBackendRequest(endpoint: string, method: string, body?: string): Promise { +async function sendBackendRequest(endpoint: string, method: string, body?: object): Promise { const api = `api/${endpoint}`; const requestOption = createRequestOptions(method, body); @@ -145,7 +146,7 @@ async function sendBackendRequest(endpoint: string, method: string, body?: strin async function parseResponse(response: Response): Promise { try { // Parse the response as type `T` - return (await response.json()) as T; + return JSONBig.parse(await response.text()) as T; } catch (e) { throw new Error(`Failed to parse the response from the backend into expected type.`); } @@ -162,16 +163,16 @@ async function parseResponse(response: Response): Promise { * @throws An error if the backend responses with an error. */ export async function setClaimed(signer: string, signature: string, recentBlockHeight: bigint, accountAddress: string) { - const body = JSON.stringify({ + const body = { signingData: { signer, message: { accountAddresses: [accountAddress], }, signature, - blockHeight: Number(recentBlockHeight), + blockHeight: recentBlockHeight, }, - }); + }; return await sendBackendRequest('setClaimed', 'POST', body); } @@ -194,7 +195,7 @@ export async function getPendingApprovals( limit: number, offset: number, ): Promise { - const body = JSON.stringify({ + const body = { signingData: { signer, message: { @@ -202,9 +203,9 @@ export async function getPendingApprovals( offset, }, signature, - blockHeight: Number(recentBlockHeight), + blockHeight: recentBlockHeight, }, - }); + }; const response = await sendBackendRequest('getPendingApprovals', 'POST', body); return await parseResponse(response); @@ -225,16 +226,16 @@ export async function getAccountData( signature: string, recentBlockHeight: bigint, ): Promise { - const body = JSON.stringify({ + const body = { signingData: { signer, message: { accountAddress, }, signature, - blockHeight: Number(recentBlockHeight), + blockHeight: recentBlockHeight, }, - }); + }; const response = await sendBackendRequest('getAccountData', 'POST', body); return await parseResponse(response); @@ -274,16 +275,16 @@ export async function getStatement(): Promise { * @throws An error if the backend responses with an error. */ export async function submitTweet(signer: string, signature: string, recentBlockHeight: bigint, tweet: string) { - const body = JSON.stringify({ + const body = { signingData: { signer, message: { tweet, }, signature, - blockHeight: Number(recentBlockHeight), + blockHeight: recentBlockHeight, }, - }); + }; return await sendBackendRequest('postTweet', 'POST', body); } @@ -297,10 +298,10 @@ export async function submitTweet(signer: string, signature: string, recentBlock * @throws An error if the backend responses with an error. */ export async function submitZkProof(presentation: VerifiablePresentation, recentBlockHeight: bigint) { - const body = JSON.stringify({ - blockHeight: Number(recentBlockHeight), + const body = { + blockHeight: recentBlockHeight, presentation: presentation, - }); + }; return await sendBackendRequest('postZKProof', 'POST', body); } diff --git a/compliant-reward-distribution/frontend/src/components/Admin/AdminGetAccountData.tsx b/compliant-reward-distribution/frontend/src/components/Admin/AdminGetAccountData.tsx index 7439cd6a..bc3982f4 100644 --- a/compliant-reward-distribution/frontend/src/components/Admin/AdminGetAccountData.tsx +++ b/compliant-reward-distribution/frontend/src/components/Admin/AdminGetAccountData.tsx @@ -8,7 +8,7 @@ import { ConcordiumGRPCClient } from '@concordium/web-sdk'; import { getRecentBlock, requestSignature, validateAccountAddress } from '../../utils'; import { WalletProvider } from '../../wallet-connection'; import { SCHEMA_GET_ACCOUNT_DATA_MESSAGE } from '../../constants'; -import { getAccountData } from '../../apiReqeuests'; +import { AccountData, getAccountData } from '../../apiReqeuests'; interface Props { signer: string | undefined; @@ -20,7 +20,7 @@ export function AdminGetAccountData(props: Props) { const { signer, provider, grpcClient } = props; const [error, setError] = useState(undefined); - const [accountData, setAccountData] = useState(undefined); + const [accountData, setAccountData] = useState(undefined); interface FormType { address: string; @@ -50,7 +50,7 @@ export function AdminGetAccountData(props: Props) { ); const data = await getAccountData(signer, address, signature, recentBlockHeight); - setAccountData(JSONbig.stringify(data)); + setAccountData(data); } catch (error) { setError((error as Error).message); } @@ -78,7 +78,7 @@ export function AdminGetAccountData(props: Props) {
- {accountData &&
{JSON.stringify(JSON.parse(accountData), undefined, 2)}
} + {accountData &&
{JSONbig.stringify(accountData, undefined, 2)}
} {error && {error}} diff --git a/compliant-reward-distribution/frontend/src/components/Admin/AdminGetPendingApprovals.tsx b/compliant-reward-distribution/frontend/src/components/Admin/AdminGetPendingApprovals.tsx index a1a07363..dbd64877 100644 --- a/compliant-reward-distribution/frontend/src/components/Admin/AdminGetPendingApprovals.tsx +++ b/compliant-reward-distribution/frontend/src/components/Admin/AdminGetPendingApprovals.tsx @@ -8,7 +8,7 @@ import { ConcordiumGRPCClient } from '@concordium/web-sdk'; import { getRecentBlock, requestSignature } from '../../utils'; import { WalletProvider } from '../../wallet-connection'; import { LIMIT, OFFSET, SCHEMA_GET_PENDING_APPROVALS_MESSAGE } from '../../constants'; -import { getPendingApprovals } from '../../apiReqeuests'; +import { AccountData, getPendingApprovals } from '../../apiReqeuests'; interface Props { signer: string | undefined; @@ -20,7 +20,7 @@ export function AdminGetPendingApprovals(props: Props) { const { signer, grpcClient, provider } = props; const [error, setError] = useState(undefined); - const [pendingApprovals, setPendingApprovals] = useState(undefined); + const [pendingApprovals, setPendingApprovals] = useState(undefined); const { handleSubmit } = useForm<[]>({ mode: 'all' }); @@ -44,7 +44,7 @@ export function AdminGetPendingApprovals(props: Props) { ); const data = await getPendingApprovals(signer, signature, recentBlockHeight, LIMIT, OFFSET); - setPendingApprovals(JSONbig.stringify(data)); + setPendingApprovals(data); } catch (error) { setError((error as Error).message); } @@ -62,9 +62,7 @@ export function AdminGetPendingApprovals(props: Props) { {error && {error}} - {pendingApprovals && ( -
{JSON.stringify(JSON.parse(pendingApprovals), undefined, 2)}
- )} + {pendingApprovals &&
{JSONbig.stringify(pendingApprovals, undefined, 2)}
} diff --git a/compliant-reward-distribution/frontend/src/utils.ts b/compliant-reward-distribution/frontend/src/utils.ts index 4fa95497..8e41dee9 100644 --- a/compliant-reward-distribution/frontend/src/utils.ts +++ b/compliant-reward-distribution/frontend/src/utils.ts @@ -31,7 +31,7 @@ export async function getRecentBlock(grpcClient: ConcordiumGRPCClient | undefine const recentBlockHeight = bestBlockHeight.value - RECENT_BLOCK_DURATION; - const recentBlockHash = ((await grpcClient.getBlocksAtHeight(recentBlockHeight)) as BlockHash.Type[])[0]; + const recentBlockHash = (await grpcClient.getBlocksAtHeight(recentBlockHeight))[0]; if (!recentBlockHash) { throw Error(`Couldn't get 'recentBlockHash' from chain`); diff --git a/compliant-reward-distribution/frontend/src/wallet-connection.tsx b/compliant-reward-distribution/frontend/src/wallet-connection.tsx index 4fbe4d32..8e7c416c 100644 --- a/compliant-reward-distribution/frontend/src/wallet-connection.tsx +++ b/compliant-reward-distribution/frontend/src/wallet-connection.tsx @@ -93,7 +93,7 @@ export class BrowserWalletProvider extends WalletProvider { const payload = Buffer.from( serializeTypeValue( { - block_hash: Buffer.from(recentBlockHash.buffer).toString('hex'), + block_hash: BlockHash.toHexString(recentBlockHash), context_string: CONTEXT_STRING, message, }, @@ -207,7 +207,7 @@ export class WalletConnectProvider extends WalletProvider { const payload = Buffer.from( serializeTypeValue( { - block_hash: Buffer.from(recentBlockHash.buffer).toString('hex'), + block_hash: BlockHash.toHexString(recentBlockHash), context_string: CONTEXT_STRING, message, }, @@ -270,7 +270,7 @@ export class WalletConnectProvider extends WalletProvider { // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (e: any) { if (isWalletConnectError(e)) { - throw new Error('Proof request rejected in wallet: ' + JSON.stringify(e)); + throw new Error('Generating proof request rejected in wallet: ' + JSON.stringify(e)); } throw e; } diff --git a/compliant-reward-distribution/indexer-and-server/src/error.rs b/compliant-reward-distribution/indexer-and-server/src/error.rs index a533e143..90c58d13 100644 --- a/compliant-reward-distribution/indexer-and-server/src/error.rs +++ b/compliant-reward-distribution/indexer-and-server/src/error.rs @@ -78,7 +78,7 @@ pub enum ServerError { UnderFlow, #[error( "The account was not captured by the indexer and is not in the database. Only accounts \ - earlier than block height {0} are captured." + later than block height {0} are captured." )] AccountNotExist(AbsoluteBlockHeight), #[error("Claim already expired. Your account creation has to be not older than {0}.")]