-
Notifications
You must be signed in to change notification settings - Fork 400
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mezoification: Add base state and UI elements #3785
base: main
Are you sure you want to change the base?
Changes from all commits
5bb9810
0f25b31
0a7d996
0ac12cf
141f7de
9c2ac79
52bd1e9
ee66fe0
6422370
789b942
ef04377
ae1f3c5
09361e2
77f3ba0
4a9f079
e56f90d
4671a6e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { Interface } from "ethers/lib/utils" | ||
import { AnyEVMTransaction, sameNetwork } from "../networks" | ||
import { MEZO_TESTNET } from "../constants" | ||
import { sameEVMAddress } from "./utils" | ||
|
||
const BORROWER_CONTRACT_ADDRESS = "0x20fAeA18B6a1D0FCDBCcFfFe3d164314744baF30" | ||
|
||
const BorrowerABI = new Interface([ | ||
"function openTrove(uint256 _maxFeePercentage, uint256 debtAmount, uint256 _assetAmount, address _upperHint, address _lowerHint)", | ||
]) | ||
|
||
// eslint-disable-next-line import/prefer-default-export | ||
export const checkIsBorrowingTx = (tx: AnyEVMTransaction) => { | ||
if ( | ||
!sameNetwork(tx.network, MEZO_TESTNET) || | ||
!tx.blockHash || | ||
!sameEVMAddress(tx.to, BORROWER_CONTRACT_ADDRESS) | ||
) { | ||
return false | ||
} | ||
|
||
try { | ||
const data = BorrowerABI.decodeFunctionData("openTrove", tx.input ?? "") | ||
return data.debtAmount > 0n | ||
} catch (error) { | ||
return false | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
import { createSlice, createSelector } from "@reduxjs/toolkit" | ||
import Emittery from "emittery" | ||
import { AddressOnNetwork } from "../accounts" | ||
import { ETHEREUM } from "../constants" | ||
import { ETHEREUM, TEST_NETWORK_BY_CHAIN_ID } from "../constants" | ||
import { AnalyticsEvent, OneTimeAnalyticsEvent } from "../lib/posthog" | ||
import { EVMNetwork } from "../networks" | ||
import { AnalyticsPreferences, DismissableItem } from "../services/preferences" | ||
|
@@ -11,11 +11,12 @@ import { AccountState, addAddressNetwork } from "./accounts" | |
import { createBackgroundAsyncThunk } from "./utils" | ||
import { UNIXTime } from "../types" | ||
import { DEFAULT_AUTOLOCK_INTERVAL } from "../services/preferences/defaults" | ||
import type { RootState } from "." | ||
|
||
export const defaultSettings = { | ||
hideDust: false, | ||
defaultWallet: false, | ||
showTestNetworks: false, | ||
showTestNetworks: true, | ||
showNotifications: undefined, | ||
collectAnalytics: false, | ||
showAnalyticsNotification: false, | ||
|
@@ -25,6 +26,13 @@ export const defaultSettings = { | |
autoLockInterval: DEFAULT_AUTOLOCK_INTERVAL, | ||
} | ||
|
||
export type MezoClaimStatus = | ||
| "not-eligible" | ||
| "eligible" | ||
| "claimed-sats" | ||
| "borrowed" | ||
| "campaign-complete" | ||
|
||
export type UIState = { | ||
selectedAccount: AddressOnNetwork | ||
showingActivityDetailID: string | null | ||
|
@@ -47,6 +55,13 @@ export type UIState = { | |
routeHistoryEntries?: Partial<Location>[] | ||
slippageTolerance: number | ||
accountSignerSettings: AccountSignerSettings[] | ||
activeCampaigns: { | ||
"mezo-claim"?: { | ||
dateFrom: string | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guessing if we make this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup, it will remain a string There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we should give our serializer/deserializer the ability to deal with dates tbh (not as a blocker though). |
||
dateTo: string | ||
state: MezoClaimStatus | ||
} | ||
} | ||
} | ||
|
||
export type Events = { | ||
|
@@ -63,6 +78,7 @@ export type Events = { | |
updateAnalyticsPreferences: Partial<AnalyticsPreferences> | ||
addCustomNetworkResponse: [string, boolean] | ||
updateAutoLockInterval: number | ||
toggleShowTestNetworks: boolean | ||
} | ||
|
||
export const emitter = new Emittery<Events>() | ||
|
@@ -78,6 +94,7 @@ export const initialState: UIState = { | |
snackbarMessage: "", | ||
slippageTolerance: 0.01, | ||
accountSignerSettings: [], | ||
activeCampaigns: {}, | ||
} | ||
|
||
const uiSlice = createSlice({ | ||
|
@@ -222,6 +239,22 @@ const uiSlice = createSlice({ | |
...state, | ||
settings: { ...state.settings, autoLockInterval: payload }, | ||
}), | ||
updateCampaignState: <T extends keyof UIState["activeCampaigns"]>( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When we start pulling |
||
immerState: UIState, | ||
{ | ||
payload, | ||
}: { | ||
payload: [T, Partial<UIState["activeCampaigns"][T]>] | ||
}, | ||
) => { | ||
const [campaignId, update] = payload | ||
|
||
immerState.activeCampaigns ??= {} | ||
immerState.activeCampaigns[campaignId] = { | ||
...immerState.activeCampaigns[campaignId], | ||
...update, | ||
} | ||
}, | ||
}, | ||
}) | ||
|
||
|
@@ -246,6 +279,7 @@ export const { | |
setSlippageTolerance, | ||
setAccountsSignerSettings, | ||
setAutoLockInterval, | ||
updateCampaignState, | ||
} = uiSlice.actions | ||
|
||
export default uiSlice.reducer | ||
|
@@ -360,6 +394,22 @@ export const setSelectedNetwork = createBackgroundAsyncThunk( | |
}, | ||
) | ||
|
||
export const toggleShowTestNetworks = createBackgroundAsyncThunk( | ||
"ui/toggleShowTestNetworks", | ||
async (value: boolean, { dispatch, getState }) => { | ||
const state = getState() as RootState | ||
|
||
const currentNetwork = state.ui.selectedAccount.network | ||
|
||
// If user is on one of the built-in test networks, don't leave them stranded | ||
if (TEST_NETWORK_BY_CHAIN_ID.has(currentNetwork.chainID)) { | ||
dispatch(setSelectedNetwork(ETHEREUM)) | ||
} | ||
|
||
await emitter.emit("toggleShowTestNetworks", value) | ||
}, | ||
) | ||
|
||
export const refreshBackgroundPage = createBackgroundAsyncThunk( | ||
"ui/refreshBackgroundPage", | ||
async () => { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,8 @@ interface Events extends ServiceLifecycleEvents { | |
* handling sending and persistance concerns. | ||
*/ | ||
export default class AnalyticsService extends BaseService<Events> { | ||
#analyticsUUID: string | undefined = undefined | ||
|
||
/* | ||
* Create a new AnalyticsService. The service isn't initialized until | ||
* startService() is called and resolved. | ||
|
@@ -93,6 +95,7 @@ export default class AnalyticsService extends BaseService<Events> { | |
|
||
protected override async internalStartService(): Promise<void> { | ||
await super.internalStartService() | ||
const { uuid, isNew } = await this.getOrCreateAnalyticsUUID() | ||
|
||
let { isEnabled, hasDefaultOnBeenTurnedOn } = | ||
await this.preferenceService.getAnalyticsPreferences() | ||
|
@@ -114,8 +117,6 @@ export default class AnalyticsService extends BaseService<Events> { | |
} | ||
|
||
if (isEnabled) { | ||
const { uuid, isNew } = await this.getOrCreateAnalyticsUUID() | ||
|
||
browser.runtime.setUninstallURL( | ||
process.env.NODE_ENV === "development" | ||
? "about:blank" | ||
|
@@ -126,6 +127,8 @@ export default class AnalyticsService extends BaseService<Events> { | |
await this.sendAnalyticsEvent(AnalyticsEvent.NEW_INSTALL) | ||
} | ||
} | ||
|
||
this.#analyticsUUID = uuid | ||
} | ||
|
||
protected override async internalStopService(): Promise<void> { | ||
|
@@ -134,6 +137,15 @@ export default class AnalyticsService extends BaseService<Events> { | |
await super.internalStopService() | ||
} | ||
|
||
get analyticsUUID() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From below it looks like we can lose this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you're referring to the error below, that's just to block access until service has initialized. This could happen during tests or if there's an attempt to get this data from within another service's initialization without awaiting There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, I meant that it doesn't look like we're accessing this as a property anywhere—which is good, as leaking the UUID feels like leaking the private state of the analytics service and leaking the implementation detail of using PostHog. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmmm I'm not following, we need this id to get the wallet's campaign state 🤔 |
||
if (!this.#analyticsUUID) { | ||
throw new Error( | ||
"Attempted to access analytics UUID before service started", | ||
) | ||
} | ||
return this.#analyticsUUID | ||
} | ||
|
||
async sendAnalyticsEvent( | ||
eventName: AnalyticsEvent, | ||
payload?: Record<string, unknown>, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lint disable is best accompanied by an explanation.
In this case my thought is that we probably move this into a Mezo or Mezo campaign service, which is where we deal with the Redux service's complexity as well (after we ship this, I mean). Wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point, this is only used for the campaign. I initially put this under
/lib
because I thought this would be also used by the enrichment service.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For sure. I think once we're enriching we'll probably export more anyway—and I wonder if the better approach here is actually making this file an ABI export file (
background/lib/mezo/musd-trovemanager-abi.ts
or so) and then we implementcheckIsBorrowingTx
directly where we need it and let enrichment do its own things with the ABI.Anyway, none of that is blocking.