Skip to content

Commit

Permalink
WIP add very incomplete island XP drop watching code
Browse files Browse the repository at this point in the history
  • Loading branch information
Shadowfiend committed Nov 9, 2023
1 parent 0de6925 commit 2dfeebd
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 1 deletion.
133 changes: 133 additions & 0 deletions background/services/island/db.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,154 @@
import Dexie from "dexie"
import { current } from "immer"

Check failure on line 2 in background/services/island/db.ts

View workflow job for this annotation

GitHub Actions / lint

'current' is defined but never used. Allowed unused vars must match /^_+$/u
import { AddressOnNetwork } from "../../accounts"
import { normalizeEVMAddress } from "../../lib/utils"
import { ReferrerStats } from "./types"
import { HexString } from "../../types"

type Realm = {
addressOnNetwork: AddressOnNetwork
name: string
}

type XpClaim = {
transactionHash: HexString
amount: bigint
}

type RealmMembership = {
trackedAccount: AddressOnNetwork
realm: Realm
xpClaims: XpClaim[]
currentlyActive: boolean
}

export class IslandDatabase extends Dexie {
private referralBonuses!: Dexie.Table<
AddressOnNetwork & { referredBy: AddressOnNetwork; referralBonus: bigint },
[string, string, string]
>

private realmMembership!: Dexie.Table<RealmMembership, [HexString, HexString]>

constructor() {
super("taho/island")

this.version(1).stores({
referralBonuses:
"&[address+referredBy.address+network.name+network.chainID],address,referredBy.address",
})

/*this.version(2).stores({

Check failure on line 41 in background/services/island/db.ts

View workflow job for this annotation

GitHub Actions / lint

Expected exception block, space or tab after '/*' in comment

Check failure on line 41 in background/services/island/db.ts

View workflow job for this annotation

GitHub Actions / lint

Expected space or tab before '*/' in comment
realmMembership:
"&[trackedAccount.address,realm.addressOnNetwork.address]",
})*/
}

/**
* Records a membership for the given account in the given realm. The
* membership is added as currently active by default, but this can be set to
* `false` if recording a historic realm memberhsip.
*/
async addRealmMembership(
trackedAccount: AddressOnNetwork,
realm: Realm,
currentlyActive = false,
): Promise<void> {
this.realmMembership.add({
trackedAccount,
realm,
xpClaims: [],
currentlyActive,
})
}

/**
* Clears any realm membership marked as active for the given account. Note
* that typically there should only ever be one realm marked as active, and
* it should be updated using `markRealmMembershipInactive`.
*/
async clearActiveRealmMemberships(
trackedAccount: AddressOnNetwork,
): Promise<void> {
const activeMemberships = await this.realmMembership
.where({
trackedAccount: { address: trackedAccount.address },
currentlyActive: true,
})
.toArray()

await this.realmMembership.bulkPut(
activeMemberships.map((membership) => ({
...membership,
currentlyActive: false,
})),
)
}

/**
* Marks the given realm to be active for the given account. Clears any other
* active realm.
*/
async markRealmMembershipActive(
trackedAccount: AddressOnNetwork,
realm: Realm,
): Promise<void> {
this.realmMembership.update(
[trackedAccount.address, realm.addressOnNetwork.address],
{
currentlyActive: true,
},
)
}

/**
* Marks the given realm to be inactive for the given account.
*/
async markRealmMembershipInactive(
trackedAccount: AddressOnNetwork,
realm: Realm,
): Promise<void> {
this.realmMembership.update(
[trackedAccount.address, realm.addressOnNetwork.address],
{
currentlyActive: false,
},
)
}

/**
* Returns all realm memberships for the given account. Note that this can
* include historic memberships if the account has joined and left more than
* one realm in the past, or if they joined a realm but are not currently in
* it.
*/
async getRealmMembershipsFor(
trackedAccount: AddressOnNetwork,
): Promise<RealmMembership[]> {
return this.realmMembership.where({ trackedAccount }).toArray()
}

/**
* Adds an XP claim for the given realm and tracked account. The XP claim
* represents a transaction that claimed XP, and the amount of XP that was
* claimed.
*/
async addXpClaim(
trackedAccount: AddressOnNetwork,
realm: Realm,
claim: XpClaim,
): Promise<void> {
const existingRealmMembership = (await this.realmMembership.get([
trackedAccount.address,
realm.addressOnNetwork.address,
])) ?? { trackedAccount, realm, xpClaims: [], currentlyActive: false }

// Upsert in case we weren't previously tracking this membership for some
// reason.
await this.realmMembership.put({
...existingRealmMembership,
xpClaims: [...existingRealmMembership.xpClaims, claim],
})
}

async addReferralBonus(
Expand Down
30 changes: 29 additions & 1 deletion background/services/island/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Eligible, ReferrerStats } from "./types"
import BaseService from "../base"
import { getFileHashProspect, getClaimFromFileHash } from "./utils"
import ChainService from "../chain"
import { DOGGO, ETHEREUM } from "../../constants"
import { DOGGO, ETHEREUM, HOUR } from "../../constants"
import { sameNetwork } from "../../networks"
import {
ClaimWithFriends,
Expand All @@ -23,6 +23,7 @@ import { IslandDatabase, getOrCreateDB } from "./db"
import { normalizeEVMAddress } from "../../lib/utils"
import { FeatureFlags, isDisabled, isEnabled } from "../../features"
import { SmartContractFungibleAsset } from "../../assets"
import { Alarms } from "webextension-polyfill"

Check failure on line 26 in background/services/island/index.ts

View workflow job for this annotation

GitHub Actions / lint

`webextension-polyfill` import should occur before import of `../types`

Check failure on line 26 in background/services/island/index.ts

View workflow job for this annotation

GitHub Actions / lint

'Alarms' is defined but never used. Allowed unused vars must match /^_+$/u

export {
TESTNET_TAHO,
Expand Down Expand Up @@ -67,6 +68,12 @@ export default class IslandService extends BaseService<Events> {
},
handler: () => this.startMonitoringIfNeeded(),
},
checkForXpDrop: {
schedule: {
periodInMinutes: 1 * HOUR,
},
handler: () => this.checkForXpDrop(),
},
})
}

Expand Down Expand Up @@ -225,6 +232,27 @@ export default class IslandService extends BaseService<Events> {
return this.db.getReferrerStats(referrer)
}

private async checkForXpDrop(): Promise<void> {
const trackedAddresses =
await this.chainService.getTrackedAddressesOnNetwork(ISLAND_NETWORK)

trackedAddresses.forEach(async (trackedAccount) => {
const memberships = await this.db.getRealmMembershipsFor(trackedAccount)

memberships.forEach(({ realm: { addressOnNetwork } }) => {

Check failure on line 242 in background/services/island/index.ts

View workflow job for this annotation

GitHub Actions / lint

'addressOnNetwork' is defined but never used. Allowed unused args must match /^_+$/u
// TODO Check for eligibility via adjusted getClaimFromFileHash util
// TODO If found, check if we have a claim for it.
})
})
// TODO Hey, we gotta do this for every tracked account!
// TODO Store realm addresses?
// TODO Store realm XP addresses
// TODO Monitor for XP balance changes
// TODO Monitor for XP drops (via underlying asseet URL lookups)

// this.db.
}

private async trackReferrals({
address,
network,
Expand Down

0 comments on commit 2dfeebd

Please sign in to comment.