Skip to content

Commit

Permalink
fixes retry handler to rebuild gql client, fixes syntax on query params
Browse files Browse the repository at this point in the history
  • Loading branch information
aristidesstaffieri committed Nov 3, 2023
1 parent 5b03ba5 commit a33bdff
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 31 deletions.
12 changes: 11 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,24 @@ async function main() {
};
},
});
const renewClient = new Client({
url: conf.mercuryGraphQL,
exchanges: [fetchExchange],
});
const mercurySession = {
token: conf.mercuryKey,
backend: conf.mercuryBackend,
email: conf.mercuryEmail,
password: conf.mercuryPassword,
userId: conf.mercuryUserId,
};
const mercuryClient = new MercuryClient(mercurySession, client, logger);
const mercuryClient = new MercuryClient(
conf.mercuryGraphQL,
mercurySession,
client,
renewClient,
logger
);
const server = initApiServer(mercuryClient, conf);

try {
Expand Down
72 changes: 56 additions & 16 deletions src/service/mercury/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { Client } from "@urql/core";
import axios, { AxiosError } from "axios";
import { Client, CombinedError, fetchExchange } from "@urql/core";
import axios from "axios";
import { Logger } from "pino";
import { Address, nativeToScVal, xdr } from "soroban-client";
import { mutation, query } from "./queries";

const ERROR_MESSAGES = {
JWT_EXPIRED: "jwt expired",
};

function getGraphQlError(error?: CombinedError) {
if (!error) return;
const [err] = error.graphQLErrors;
return err.message;
}

export interface NewEventSubscriptionPayload {
contract_id?: string;
max_single_size: number;
Expand All @@ -25,21 +35,27 @@ interface MercurySession {
}

export class MercuryClient {
mercuryUrl: string;
urqlClient: Client;
renewClient: Client;
mercurySession: MercurySession;
eventsURL: string;
entryURL: string;
logger: Logger;

constructor(
mercuryUrl: string,
mercurySession: MercurySession,
urqlClient: Client,
renewClient: Client,
logger: Logger
) {
this.mercuryUrl = mercuryUrl;
this.mercurySession = mercurySession;
this.eventsURL = `${mercurySession.backend}/event`;
this.entryURL = `${mercurySession.backend}/entry`;
this.urqlClient = urqlClient;
this.renewClient = renewClient;
this.logger = logger;
}

Expand All @@ -53,10 +69,29 @@ export class MercuryClient {

renewMercuryToken = async () => {
try {
const { data } = await this.urqlClient.query(mutation.authenticate, {
email: this.mercurySession.email,
password: this.mercurySession.password,
const { data, error } = await this.renewClient.mutation(
mutation.authenticate,
{
email: this.mercurySession.email,
password: this.mercurySession.password,
}
);

if (error) {
throw new Error(getGraphQlError(error));
}

// rebuild client and hold onto new token for subscription rest calls
const client = new Client({
url: this.mercuryUrl,
exchanges: [fetchExchange],
fetchOptions: () => {
return {
headers: { authorization: `Bearer ${data.authenticate.jwtToken}` },
};
},
});
this.urqlClient = client;
this.mercurySession.token = data.authenticate.jwtToken;

return {
Expand All @@ -65,7 +100,7 @@ export class MercuryClient {
};
} catch (error) {
const _error = JSON.stringify(error);
this.logger.error(_error);
this.logger.error(error);
return {
data: null,
error: _error,
Expand All @@ -77,16 +112,16 @@ export class MercuryClient {
try {
return await method();
} catch (error: unknown) {
let status = 400;
if (error instanceof AxiosError) {
status = error.response?.status || 400;
if (error instanceof Error) {
if (error.message === ERROR_MESSAGES.JWT_EXPIRED) {
await this.renewMercuryToken();
this.logger.info("renewed expired jwt");
return await method();
}
this.logger.error(error.message);
throw new Error(error.message);
}

if (status === 401) {
this.logger.debug("renewing jwt, and retrying");
await this.renewMercuryToken();
return await method();
}
const _error = JSON.stringify(error);
this.logger.error(_error);
throw new Error(_error);
Expand Down Expand Up @@ -229,8 +264,13 @@ export class MercuryClient {
try {
const getData = async () => {
const data = await this.urqlClient.query(query.getAccountHistory, {
publicKeyText: pubKey,
pubKey,
});
const errorMessage = getGraphQlError(data.error);
if (errorMessage) {
throw new Error(errorMessage);
}

return data;
};
const data = await this.renewAndRetry(getData);
Expand All @@ -241,7 +281,7 @@ export class MercuryClient {
};
} catch (error) {
const _error = JSON.stringify(error);
this.logger.error(_error);
this.logger.error(error);
return {
data: null,
error: _error,
Expand Down
34 changes: 20 additions & 14 deletions src/service/mercury/queries.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
export const mutation = {
authenticate: `
mutation Auth {
mutation Auth($email: String!, $password: String!) {
authenticate(input: {email: $email, password: $password}) {
jwtToken
}
}
`,
newAccountSubscription: `
mutation NewAccountSubscription {
mutation NewAccountSubscription($pubKey: String!, $userId: String!) {
createFullAccountSubscription(
input: {fullAccountSubscription: {$pubKey: PUBKEY!, $userId: USER_ID!}}
input: {fullAccountSubscription: pubKey: $pubKey, userId: $userId}}
) {
fullAccountSubscription {
publickey
Expand All @@ -36,7 +36,7 @@ export const query = {
${contractIds.map(
(id) =>
`
entryUpdateByContractIdAndKey(ledgerKey: ${ledgerKey}, contract: ${id}) {
entryUpdateByContractIdAndKey(ledgerKey: $${ledgerKey}, contract: $${id}) {
nodes {
contractId
keyXdr
Expand All @@ -51,8 +51,8 @@ export const query = {
}
`,
getAccountHistory: `
query GetAccountHistory {
eventByTopic(t1: "AAAADgAAAARtaW50") {
query GetAccountHistory($pubKey: String!) {
mintEvent: eventByTopic(t1: "AAAADgAAAARtaW50") {
edges {
node {
contractId
Expand All @@ -66,7 +66,8 @@ export const query = {
}
}
}
eventByTopic(t1: "AAAADgAAAAh0cmFuc2Zlcg==", $t2: PUBKEY!) {
transferToEvent: eventByTopic(t1: "AAAADgAAAAh0cmFuc2Zlcg==", t2: $pubKey) {
edges {
node {
contractId
Expand All @@ -80,7 +81,7 @@ export const query = {
}
}
}
eventByTopic(t1: "AAAADgAAAAh0cmFuc2Zlcg==", $t3: PUBKEY!) {
transferFromEvent: eventByTopic(t1: "AAAADgAAAAh0cmFuc2Zlcg==", t3: $pubKey) {
edges {
node {
contractId
Expand All @@ -94,17 +95,21 @@ export const query = {
}
}
}
createAccountByPublicKey($publicKeyText: PUBKEY!) {
createAccountByPublicKey(publicKeyText: $pubKey) {
edges {
node
node {
destination
}
}
}
createAccountToPublicKey($publicKeyText: PUBKEY!) {
createAccountToPublicKey(publicKeyText: $pubKey) {
edges {
node
node {
destination
}
}
}
paymentsByPublicKey($publicKeyText: PUBKEY!) {
paymentsByPublicKey(publicKeyText: $pubKey) {
edges {
node {
amount
Expand All @@ -122,7 +127,7 @@ export const query = {
}
}
}
paymentsToPublicKey($publicKeyText: PUBKEY!) {
paymentsToPublicKey(publicKeyText: $pubKey) {
edges {
node {
amount
Expand All @@ -140,6 +145,7 @@ export const query = {
}
}
}
}
`,
};

0 comments on commit a33bdff

Please sign in to comment.