mirror of
https://github.com/MetaFam/TheGame.git
synced 2026-02-11 22:45:04 -05:00
Allow users to force-update their linked ETH address
Removed sc_identity_id from Player table because it enforces ETH addresses to be used as the single source of truth for users and prevents conflicts when users update their ETH address in the ledger. sc_identity_id is not needing anywhere in our backend / data model.
This commit is contained in:
committed by
Alec LaLonde
parent
ba0be9fb09
commit
63eeca916f
@@ -1,4 +1,8 @@
|
||||
import { Constants, isNotNullOrUndefined } from '@metafam/utils';
|
||||
import {
|
||||
Constants,
|
||||
getLatestEthAddress,
|
||||
isNotNullOrUndefined,
|
||||
} from '@metafam/utils';
|
||||
import bluebird from 'bluebird';
|
||||
import { Request, Response } from 'express';
|
||||
import fetch from 'node-fetch';
|
||||
@@ -7,9 +11,6 @@ import { SCAccountsData, SCAlias, sourcecred as sc } from 'sourcecred';
|
||||
import {
|
||||
AccountType_Enum,
|
||||
Player_Account_Constraint,
|
||||
Player_Constraint,
|
||||
Player_Insert_Input,
|
||||
Player_Update_Column,
|
||||
} from '../../../lib/autogen/hasura-sdk';
|
||||
import { client } from '../../../lib/hasuraClient';
|
||||
import { computeRank } from '../../../lib/rankHelpers';
|
||||
@@ -73,10 +74,7 @@ export const migrateSourceCredAccounts = async (
|
||||
const discordId = linkedAccounts.find(({ type }) => type === 'DISCORD')
|
||||
?.identifier;
|
||||
|
||||
const ethAddress = a.account.identity.aliases.find((alias) => {
|
||||
const parts = sc.core.graph.NodeAddress.toParts(alias.address);
|
||||
return parts.indexOf('ethereum') > 0;
|
||||
})?.description;
|
||||
const ethAddress = getLatestEthAddress(a.account.identity);
|
||||
|
||||
if (!ethAddress) return null;
|
||||
|
||||
@@ -148,32 +146,11 @@ export const migrateSourceCredAccounts = async (
|
||||
},
|
||||
{ concurrency: 10 },
|
||||
);
|
||||
const usersToInsert: Player_Insert_Input[] = result
|
||||
.filter(isNotNullOrUndefined)
|
||||
.map((player) => ({
|
||||
username: player.ethereum_address,
|
||||
ethereum_address: player.ethereum_address,
|
||||
sc_identity_id: player.scIdentityId,
|
||||
rank: player.rank,
|
||||
total_xp: player.totalXp,
|
||||
}));
|
||||
const usersSkipped = result.filter(isNotNullOrUndefined);
|
||||
|
||||
const resultInsert = await client.UpsertPlayer({
|
||||
objects: usersToInsert,
|
||||
onConflict: {
|
||||
constraint: Player_Constraint.PlayerEthereumAddressUniqueKey,
|
||||
update_columns: [
|
||||
Player_Update_Column.ScIdentityId,
|
||||
Player_Update_Column.Username,
|
||||
Player_Update_Column.TotalXp,
|
||||
Player_Update_Column.Rank,
|
||||
],
|
||||
},
|
||||
});
|
||||
res.json({
|
||||
resultInsert,
|
||||
numUpdated: accountList.length - usersToInsert.length,
|
||||
numInserted: usersToInsert.length,
|
||||
numSkipped: usersSkipped.length,
|
||||
numUpdated: accountList.length - usersSkipped.length,
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn('Error migrating players/accounts', e.message);
|
||||
|
||||
@@ -29,60 +29,17 @@ export const UpsertAccount = gql`
|
||||
}
|
||||
`;
|
||||
|
||||
export const UpsertPlayer = gql`
|
||||
mutation UpsertPlayer(
|
||||
$objects: [player_insert_input!]!
|
||||
$onConflict: player_on_conflict
|
||||
) {
|
||||
insert_player(on_conflict: $onConflict, objects: $objects) {
|
||||
affected_rows
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const DeleteDuplicatePlayers = gql`
|
||||
mutation DeleteDuplicatePlayers($scIds: [String!] = "") {
|
||||
delete_player_account(
|
||||
where: { Player: { sc_identity_id: { _in: $scIds } } }
|
||||
) {
|
||||
affected_rows
|
||||
}
|
||||
delete_player(where: { sc_identity_id: { _in: $scIds } }) {
|
||||
affected_rows
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const UpdatePlayer = gql`
|
||||
mutation UpdatePlayer(
|
||||
$ethAddress: String
|
||||
$identityId: String
|
||||
$username: String
|
||||
$rank: PlayerRank_enum
|
||||
$totalXp: numeric
|
||||
$discordId: String
|
||||
) {
|
||||
update_player(
|
||||
where: {
|
||||
_or: [
|
||||
{
|
||||
ethereum_address: { _eq: $ethAddress }
|
||||
sc_identity_id: { _eq: $identityId }
|
||||
}
|
||||
{
|
||||
ethereum_address: { _eq: $ethAddress }
|
||||
sc_identity_id: { _is_null: true }
|
||||
}
|
||||
{
|
||||
ethereum_address: { _eq: $ethAddress }
|
||||
username: { _eq: $username }
|
||||
}
|
||||
{ sc_identity_id: { _eq: $identityId } }
|
||||
{ discord_id: { _eq: $discordId } }
|
||||
]
|
||||
}
|
||||
where: { ethereum_address: { _eq: $ethAddress } }
|
||||
_set: {
|
||||
ethereum_address: $ethAddress
|
||||
sc_identity_id: $identityId
|
||||
rank: $rank
|
||||
total_xp: $totalXp
|
||||
discord_id: $discordId
|
||||
@@ -92,7 +49,6 @@ export const UpdatePlayer = gql`
|
||||
returning {
|
||||
id
|
||||
ethereum_address
|
||||
sc_identity_id
|
||||
username
|
||||
}
|
||||
}
|
||||
|
||||
4
packages/discord-bot/.env.sample
Normal file
4
packages/discord-bot/.env.sample
Normal file
@@ -0,0 +1,4 @@
|
||||
DISCORD_BOT_TOKEN=
|
||||
DISCORD_BOT_CLIENT_ID=
|
||||
DISCORD_BOT_CLIENT_SECRET=
|
||||
GITHUB_API_TOKEN=
|
||||
@@ -21,7 +21,7 @@
|
||||
"dependencies": {
|
||||
"@types/express": "4.17.11",
|
||||
"@types/node-fetch": "2.5.10",
|
||||
"@metafam/utils": "^1.0.0",
|
||||
"@metafam/utils": "1.0.0",
|
||||
"@typeit/discord": "4.0.10",
|
||||
"discord.js": "12.5.3",
|
||||
"dotenv": "9.0.2",
|
||||
|
||||
@@ -5,9 +5,14 @@ import { loadSourceCredLedger, manager } from '../../sourcecred';
|
||||
|
||||
const addressUtils = sc.plugins.ethereum.utils.address;
|
||||
|
||||
type SetEthAddressArgs = {
|
||||
ethAddress: string;
|
||||
force: string;
|
||||
};
|
||||
|
||||
export abstract class SetEthAddress {
|
||||
@Command('!setAddress :ethAddress')
|
||||
async setAddress(message: CommandMessage) {
|
||||
@Command('!setAddress :ethAddress :force')
|
||||
async setAddress(message: CommandMessage<SetEthAddressArgs>) {
|
||||
const res = await loadSourceCredLedger();
|
||||
|
||||
if (res.error) {
|
||||
@@ -47,14 +52,21 @@ export abstract class SetEthAddress {
|
||||
|
||||
const account = manager.ledger.account(baseIdentityId);
|
||||
|
||||
const existing = account.identity.aliases.find((alias) => {
|
||||
const existingEthAliases = account.identity.aliases.filter((alias) => {
|
||||
const parts = sc.core.graph.NodeAddress.toParts(alias.address);
|
||||
return parts.indexOf('ethereum') > 0;
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
const latestEthAlias = existingEthAliases[existingEthAliases.length - 1];
|
||||
|
||||
const shouldForceUpdate = message.args.force === 'force';
|
||||
|
||||
if (latestEthAlias && !shouldForceUpdate) {
|
||||
await message.reply(
|
||||
`You already have linked the following ETH Address: \`${existing.description}\`.`,
|
||||
`You already have linked the following ETH Address: \`${latestEthAlias.description}\`. Are you sure you want to update it? Warning: This cannot be undone and you will have to recreate your MyMeta profile!
|
||||
|
||||
To force update your address, type \`!setAddress ${ethAddress} force\`.
|
||||
`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"bignumber.js": "9.0.1",
|
||||
"ethers": "5.3.0",
|
||||
"js-base64": "3.6.1",
|
||||
"uuid": "8.3.2"
|
||||
"uuid": "8.3.2",
|
||||
"sourcecred": "0.9.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,3 +5,4 @@ export * as DiscordUtil from './discordHelpers';
|
||||
export * as numbers from './numbers';
|
||||
export * from './promiseHelpers';
|
||||
export * from './rankHelpers';
|
||||
export * from './sourceCredHelpers';
|
||||
|
||||
15
packages/utils/src/sourceCredHelpers.ts
Normal file
15
packages/utils/src/sourceCredHelpers.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { ethers } from 'ethers';
|
||||
import { SCIdentity, sourcecred as sc } from 'sourcecred';
|
||||
|
||||
export const getLatestEthAddress = (identity: SCIdentity): string | null => {
|
||||
const ethAddress = identity.aliases.find((alias) => {
|
||||
const parts = sc.core.graph.NodeAddress.toParts(alias.address);
|
||||
return parts.indexOf('ethereum') > 0;
|
||||
})?.description;
|
||||
|
||||
if (ethAddress && ethers.utils.isAddress(ethAddress)) {
|
||||
return ethAddress.toLowerCase();
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
Reference in New Issue
Block a user