Skip to content

Commit

Permalink
Merge pull request #263 from shkangr/feature/added-failed-tx-to-sprea…
Browse files Browse the repository at this point in the history
…dsheet

Feature/added failed tx to spreadsheet
  • Loading branch information
shkangr authored Sep 21, 2023
2 parents 382e522 + 73a8ab0 commit 3b52b29
Show file tree
Hide file tree
Showing 8 changed files with 456 additions and 9 deletions.
1 change: 1 addition & 0 deletions bridge/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
"elliptic": "^6.5.4",
"ethers": "^5.7.2",
"ethers-aws-kms-signer": "^1.3.2",
"googleapis": "^126.0.0",
"read-bigint": "^0.1.6",
"sqlite3": "^5.1.1",
"tsx": "^3.12.7",
Expand Down
58 changes: 55 additions & 3 deletions bridge/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,10 @@ import {
import { SlackChannel } from "./slack-channel";
import { AwsKmsSigner, AwsKmsSignerCredentials } from "./ethers-aws-kms-signer";
import { SafeWrappedNCGMinter } from "./safe-wrapped-ncg-minter";
import SafeServiceClient from "@safe-global/safe-service-client";
import { ethers } from "ethers";
import EthersAdapter from "@safe-global/safe-ethers-lib";
import Safe from "@safe-global/safe-core-sdk";
import { whitelistAccounts } from "./whitelist/whitelist-accounts";
import { SpreadsheetClient } from "./spreadsheet-client";
import { google } from "googleapis";

consoleStamp(console);

Expand Down Expand Up @@ -130,6 +129,57 @@ process.on("uncaughtException", console.error);
dsn: SENTRY_DSN,
});
}

// Environment Variables for using Google Spread Sheet API
const SLACK_URL: string = Configuration.get("SLACK_URL");

const GOOGLE_SPREADSHEET_URL: string = Configuration.get(
"GOOGLE_SPREADSHEET_URL"
);
const GOOGLE_SPREADSHEET_ID: string = Configuration.get(
"GOOGLE_SPREADSHEET_ID"
);
const GOOGLE_CLIENT_EMAIL: string = Configuration.get(
"GOOGLE_CLIENT_EMAIL"
);
const GOOGLE_CLIENT_PRIVATE_KEY: string = Configuration.get(
"GOOGLE_CLIENT_PRIVATE_KEY"
);
const USE_GOOGLE_SPREAD_SHEET: boolean = Configuration.get(
"USE_GOOGLE_SPREAD_SHEET",
false,
"boolean"
);
const SHEET_MINT: string = Configuration.get("SHEET_MINT");
const SHEET_BURN: string = Configuration.get("SHEET_BURN");

const authorize = new google.auth.JWT(
GOOGLE_CLIENT_EMAIL,
undefined,
GOOGLE_CLIENT_PRIVATE_KEY,
[GOOGLE_SPREADSHEET_URL]
);
const googleSheet = google.sheets({
version: "v4",
auth: authorize,
});

const spreadsheetClient = new SpreadsheetClient(
googleSheet,
GOOGLE_SPREADSHEET_ID,
USE_GOOGLE_SPREAD_SHEET,
{
baseFeeCriterion: BASE_FEE_CRITERION,
baseFee: BASE_FEE,
feeRatio: 0.01,
},
SLACK_URL,
{
mint: SHEET_MINT,
burn: SHEET_BURN,
}
);

const PRIORITY_FEE: number = Configuration.get(
"PRIORITY_FEE",
true,
Expand Down Expand Up @@ -358,6 +408,7 @@ process.on("uncaughtException", console.error);
ncgKmsTransfer,
slackMessageSender,
opensearchClient,
spreadsheetClient,
monitorStateStore,
exchangeHistoryStore,
EXPLORER_ROOT_URL,
Expand Down Expand Up @@ -392,6 +443,7 @@ process.on("uncaughtException", console.error);
minter,
slackMessageSender,
opensearchClient,
spreadsheetClient,
monitorStateStore,
exchangeHistoryStore,
EXPLORER_ROOT_URL,
Expand Down
19 changes: 18 additions & 1 deletion bridge/src/observers/burn-event-observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Integration } from "../integrations";
import { ISlackMessageSender } from "../interfaces/slack-message-sender";
import { IExchangeHistoryStore } from "../interfaces/exchange-history-store";
import { UnwrappingRetryIgnoreEvent } from "../messages/unwrapping-retry-ignore-event";
import { SpreadsheetClient } from "../spreadsheet-client";

export class EthereumBurnEventObserver
implements
Expand All @@ -23,6 +24,7 @@ export class EthereumBurnEventObserver
{
private readonly _ncgTransfer: INCGTransfer;
private readonly _opensearchClient: OpenSearchClient;
private readonly _spreadsheetClient: SpreadsheetClient;
private readonly _slackMessageSender: ISlackMessageSender;
private readonly _monitorStateStore: IMonitorStateStore;
private readonly _exchangeHistoryStore: IExchangeHistoryStore;
Expand All @@ -36,6 +38,7 @@ export class EthereumBurnEventObserver
ncgTransfer: INCGTransfer,
slackMessageSender: ISlackMessageSender,
opensearchClient: OpenSearchClient,
spreadsheetClient: SpreadsheetClient,
monitorStateStore: IMonitorStateStore,
exchangeHistoryStore: IExchangeHistoryStore,
explorerUrl: string,
Expand All @@ -47,6 +50,7 @@ export class EthereumBurnEventObserver
this._ncgTransfer = ncgTransfer;
this._slackMessageSender = slackMessageSender;
this._opensearchClient = opensearchClient;
this._spreadsheetClient = spreadsheetClient;
this._monitorStateStore = monitorStateStore;
this._exchangeHistoryStore = exchangeHistoryStore;
this._explorerUrl = explorerUrl;
Expand Down Expand Up @@ -139,7 +143,7 @@ export class EthereumBurnEventObserver
});
console.log("Transferred", nineChroniclesTxId);
} catch (e) {
await this._slackMessageSender.sendMessage(
const slackMsgRes = await this._slackMessageSender.sendMessage(
new UnwrappingFailureEvent(
this._etherscanUrl,
sender,
Expand All @@ -149,6 +153,19 @@ export class EthereumBurnEventObserver
String(e)
)
);

await this._spreadsheetClient.to_spreadsheet_burn({
slackMessageId: `${
slackMsgRes?.channel
}/p${slackMsgRes?.ts?.replace(".", "")}`,
url: this._etherscanUrl,
txId: transactionHash,
sender,
recipient: String(recipient),
amount: amountString,
error: String(e),
});

await this._opensearchClient.to_opensearch("error", {
content: "wNCG -> NCG request failure",
cause: String(e),
Expand Down
23 changes: 21 additions & 2 deletions bridge/src/observers/nine-chronicles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { ISlackMessageSender } from "../interfaces/slack-message-sender";
import { IExchangeFeeRatioPolicy } from "../policies/exchange-fee-ratio";
import { ACCOUNT_TYPE } from "../whitelist/account-type";
import { WhitelistAccount } from "../types/whitelist-account";
import { SpreadsheetClient } from "../spreadsheet-client";

// See also https://ethereum.github.io/yellowpaper/paper.pdf 4.2 The Transaction section.
const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
Expand Down Expand Up @@ -52,6 +53,7 @@ export class NCGTransferredEventObserver
private readonly _ncgTransfer: INCGTransfer;
private readonly _wrappedNcgTransfer: IWrappedNCGMinter;
private readonly _opensearchClient: OpenSearchClient;
private readonly _spreadsheetClient: SpreadsheetClient;
private readonly _slackMessageSender: ISlackMessageSender;
private readonly _monitorStateStore: IMonitorStateStore;
private readonly _exchangeHistoryStore: IExchangeHistoryStore;
Expand All @@ -76,6 +78,7 @@ export class NCGTransferredEventObserver
wrappedNcgTransfer: IWrappedNCGMinter,
slackMessageSender: ISlackMessageSender,
opensearchClient: OpenSearchClient,
spreadsheetClient: SpreadsheetClient,
monitorStateStore: IMonitorStateStore,
exchangeHistoryStore: IExchangeHistoryStore,
explorerUrl: string,
Expand All @@ -94,6 +97,7 @@ export class NCGTransferredEventObserver
this._wrappedNcgTransfer = wrappedNcgTransfer;
this._slackMessageSender = slackMessageSender;
this._opensearchClient = opensearchClient;
this._spreadsheetClient = spreadsheetClient;
this._monitorStateStore = monitorStateStore;
this._exchangeHistoryStore = exchangeHistoryStore;
this._explorerUrl = explorerUrl;
Expand Down Expand Up @@ -463,8 +467,7 @@ export class NCGTransferredEventObserver
errorMessage = JSON.stringify(e);
}

// TODO: it should be replaced with `Integration` Slack implementation.
await this._slackMessageSender.sendMessage(
const slackMsgRes = await this._slackMessageSender.sendMessage(
new WrappingFailureEvent(
this._explorerUrl,
this._ncscanUrl,
Expand All @@ -477,6 +480,21 @@ export class NCGTransferredEventObserver
this._failureSubscribers
)
);

await this._spreadsheetClient.to_spreadsheet_mint({
slackMessageId: `${
slackMsgRes?.channel
}/p${slackMsgRes?.ts?.replace(".", "")}`,
url: this._explorerUrl,
ncscanUrl: this._ncscanUrl,
useNcscan: this._useNcscan,
txId: txId,
sender,
recipient: String(recipient),
amount: amountString,
error: errorMessage,
});

await this._opensearchClient.to_opensearch("error", {
content: "NCG -> wNCG request failure",
cause: errorMessage,
Expand All @@ -485,6 +503,7 @@ export class NCGTransferredEventObserver
recipient: recipient,
amount: amountString,
});

await this._integration.error(
"Unexpected error during wrapping NCG",
{
Expand Down
126 changes: 126 additions & 0 deletions bridge/src/spreadsheet-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { combineNcExplorerUrl, combineUrl } from "./messages/utils";
import { sheets_v4 } from "googleapis";

interface FeePolicy {
baseFeeCriterion: number;
baseFee: number;
feeRatio: number;
}

interface SheetIndexes {
mint: string;
burn: string;
}

export class SpreadsheetClient {
private readonly _googleSheet: sheets_v4.Sheets;
private readonly _googleSpreadSheetId: string;
private readonly _useSpreadSheet: boolean | undefined;
private readonly _feePolicy: FeePolicy;
private readonly _slackUrl: string;
private readonly _sheetIndexes: SheetIndexes;

constructor(
googleSheet: sheets_v4.Sheets,
googleSpreadSheetId: string,
useSpreadSheet: boolean | undefined,
feePolicy: FeePolicy,
slackUrl: string,
sheetIndexes: SheetIndexes
) {
this._googleSheet = googleSheet;
this._googleSpreadSheetId = googleSpreadSheetId;
this._useSpreadSheet = useSpreadSheet;
this._feePolicy = feePolicy;
this._slackUrl = slackUrl;
this._sheetIndexes = sheetIndexes;
}

async to_spreadsheet_mint(data: {
slackMessageId: string;
url: string;
ncscanUrl: string | undefined;
useNcscan: boolean;
txId: string;
sender: string;
recipient: string;
amount: string;
error: string;
}) {
if (!this._useSpreadSheet) return;

try {
const amountNum = Number(data.amount);
const amountFeeApplied =
amountNum >= this._feePolicy.baseFeeCriterion
? (amountNum * 0.99).toFixed(2)
: amountNum - this._feePolicy.baseFee;

return await this._googleSheet.spreadsheets.values.append({
spreadsheetId: this._googleSpreadSheetId,
range: this._sheetIndexes.mint,
valueInputOption: "USER_ENTERED",
requestBody: {
values: [
[
this._slackUrl + data.slackMessageId,
combineNcExplorerUrl(
data.url,
data.ncscanUrl,
data.useNcscan,
data.txId
),
data.sender,
data.recipient,
data.amount,
amountFeeApplied,
data.error,
new Date().toLocaleString("sv"),
],
],
},
});
} catch (e) {
console.log(e);
}

return null;
}

async to_spreadsheet_burn(data: {
slackMessageId: string;
url: string;
txId: string;
sender: string;
recipient: string;
amount: string;
error: string;
}) {
if (!this._useSpreadSheet) return;

try {
return await this._googleSheet.spreadsheets.values.append({
spreadsheetId: this._googleSpreadSheetId,
range: this._sheetIndexes.burn,
valueInputOption: "USER_ENTERED",
requestBody: {
values: [
[
this._slackUrl + data.slackMessageId,
combineUrl(data.url, `/tx/${data.txId}`),
data.sender,
data.recipient,
data.amount,
data.error,
new Date().toLocaleString("sv"),
],
],
},
});
} catch (e) {
console.log(e);
}

return null;
}
}
Loading

0 comments on commit 3b52b29

Please sign in to comment.