mirror of
https://github.com/MetaFam/TheGame.git
synced 2026-04-24 03:00:09 -04:00
* First pass at composedb models * Removed patterns as they're not supported yet * Started hooking up the edit profile page to composedb * Got PoC working for persisting username to ComposeDB * Some fixes after bumping urql to 3.x * Refactored setup logic into ProfileWizardContext * Implemented fetching from ComposeDB for first three profile wizard screens * Refactored wizard stuff again to simplify it * Finished upgrading profile setup components * Added query to fetch all profile fields from composeDB * Load profile data from composeDB on player page * Unified composeDB models into one, updated setup flow to use new model * Fixed a couple errors in first-time setup flow * Added new linkProfileNode action to validate ceramic node on the backend * Call new linkProfileNode action * Implemented proper persistence w/ verification of a user's ceramic profile node * Fetch profile details from ComposeDB during [username] page SSR * Added PlayerHydrationContext for dynamically refreshing player data on player page * Implemented player hydration from Hasura * Slight refactor of Setup components to accept a player object * Added ComposeDB migration modal, still need to implement image migration * Added useImageReader, updated EditProfileModal to get the appropriate picked file data * Implemented persisting ComposeDB profile fields from edit profile modal * Check in composeDB graphql definition because generating it at build time may be problematic * Merged in new setup profile image field page * Fixed and tested image upload during setup * Fixed background image URL form field name * Added fallback for non-SSR player pages * Implemented fetching file size and dimensions before persisting to ComposeDB * Fix lint issues * More debug logs * Set CERAMIC_URL in deployment action * Don't delete / recreate stuff * Fix setup / avatar upload * Fixed edit profile field saving, updated useUser to load from composeDB * Fixed construction of profile payload when changing an image * Pull in additional data in seed-db script * Fixed white background in menus * Updated GA4 ID * Point to ceramic mainnet * Bumped composedb version * Fix ceramic API change * Update frontend ceramic_url as well * Only authenticate the DID for the model the compose client connects to * Create a new model, last one got hosed * Updated model ID in definition * Reinstate original deployment action * Fixed player loading * Handle errors during DAO sync * Handle questchain lookup errors during SSR build * Replaced IDX cache actions / triggers with composeDB ones * Added mainnet check to composeDB port modal * Fixed issue where saving from the edit profile modal was wiping out fields * Add ComposeDBPromptModal to setup pages as well * Upgrade Hasura * Added context to 'port data' modal * fix bad merge * Hasura 2.0 requires a flag for our sloppy queries to still work * add comment to begin wokr * refactor: 💄 Update profile UI to new design * style: 💄 Minor style changes * Add getPlayer import * Make changes requested in #1559 * Delete EditAvatarImage.tsx.orig * Delete EditBackgroundImage.tsx.orig * Delete EditDescription.tsx.orig * refactor: Remove commented code --------- Co-authored-by: Alec LaLonde <alec@convergencelabs.com> Co-authored-by: Alec LaLonde <alec@boxelderweb.com> Co-authored-by: nitegeist <nitegeist.dev@gmail.com>
161 lines
4.4 KiB
JavaScript
161 lines
4.4 KiB
JavaScript
#!/usr/bin/env -S node --experimental-json-modules
|
||
|
||
import { CeramicClient } from '@ceramicnetwork/http-client'
|
||
import { Caip10Link } from '@ceramicnetwork/stream-caip10-link'
|
||
import {
|
||
model as cryptoAccountsModel
|
||
} from '@datamodels/identity-accounts-crypto'
|
||
import {
|
||
model as basicProfileModel
|
||
} from '@datamodels/identity-profile-basic'
|
||
import { ModelManager } from '@glazed/devtools'
|
||
import { DIDDataStore } from '@glazed/did-datastore'
|
||
import crypto from 'crypto'
|
||
import { DID } from 'dids'
|
||
import { constants } from 'fs'
|
||
import { access, readFile } from 'fs/promises'
|
||
import JSON5 from 'json5'
|
||
import { Ed25519Provider } from 'key-did-provider-ed25519'
|
||
import { getResolver } from 'key-did-resolver'
|
||
import { dirname, join } from 'path'
|
||
import { fromString } from 'uint8arrays'
|
||
import { fileURLToPath } from 'url'
|
||
|
||
const __filename = fileURLToPath(import.meta.url)
|
||
const __dirname = dirname(__filename)
|
||
|
||
let ethAddress = '0x615b044B6Ccb048532bcF99AAdf619d7fdD2Aa01'
|
||
ethAddress = '0xC33290860C1DA6a84195C5cf1575860d3A3ED73d'
|
||
|
||
const daemon = 'https://ceramic.metagame.wtf'
|
||
const ceramic = new CeramicClient(daemon)
|
||
|
||
console.info(`Connecting to: ${daemon}`)
|
||
|
||
const main = async () => {
|
||
const schemaFile = join(__dirname, '../schema/extended-profile.json5')
|
||
|
||
console.debug(`Loading schema from: ${schemaFile}`)
|
||
|
||
const schema = JSON5.parse(
|
||
await readFile(schemaFile, 'utf8')
|
||
)
|
||
const did = await setup(ethAddress)
|
||
if (!did) {
|
||
console.debug(`No CAIP-10 Link For ${ethAddress}`);
|
||
} else {
|
||
console.debug(`DID: ${did}`)
|
||
|
||
const model = await create(schema)
|
||
const store = await storeFor(
|
||
[basicProfileModel, model, cryptoAccountsModel]
|
||
)
|
||
await profiles(store, did)
|
||
// await write(store)
|
||
await profiles(store, undefined)
|
||
await cryptos(store, did)
|
||
}
|
||
console.debug('Completing…')
|
||
}
|
||
|
||
const setup = async (address) => {
|
||
let key = null
|
||
let raw = process.env.DID_KEY
|
||
if (raw) {
|
||
console.debug('Reading private key from $DID_KEY.')
|
||
} else {
|
||
try {
|
||
const keyFile = join(__dirname, '../private.key')
|
||
await access(keyFile, constants.R_OK)
|
||
raw = (await readFile(keyFile, 'utf8')).trim()
|
||
console.debug(`Reading private key from ${keyFile}.`)
|
||
} catch { }
|
||
|
||
if (raw) {
|
||
key = fromString(raw, 'base16')
|
||
}
|
||
}
|
||
|
||
if (!key) {
|
||
key = crypto.randomBytes(32);
|
||
console.debug(`Generated key: ${key.toString('hex')}`)
|
||
}
|
||
const did = new DID({
|
||
provider: new Ed25519Provider(key),
|
||
resolver: getResolver(),
|
||
})
|
||
await did.authenticate()
|
||
ceramic.did = did
|
||
|
||
console.debug(`Retrieving DID for: ${address}`)
|
||
|
||
const caip10 = await Caip10Link.fromAccount(
|
||
ceramic,
|
||
`${address}@eip155:1`,
|
||
);
|
||
|
||
console.debug('Got:', caip10)
|
||
|
||
return caip10.did
|
||
}
|
||
|
||
const create = async (schema) => {
|
||
const manager = new ModelManager(ceramic)
|
||
const schemaId = await manager.createSchema(
|
||
'ExtendedProfile', schema,
|
||
)
|
||
const schemaURI = manager.getSchemaURL(schemaId)
|
||
console.debug(`Wrote schema to "${schemaURI}".`)
|
||
|
||
await manager.createDefinition(
|
||
'extendedProfile',
|
||
{
|
||
name: 'Extended profile information',
|
||
description: 'Profile fields in addition to those found in Ceramic’s `basicProfile`.',
|
||
schema: schemaURI,
|
||
}
|
||
)
|
||
|
||
return manager.toJSON()
|
||
}
|
||
|
||
const storeFor = async (models) => {
|
||
const manager = new ModelManager(ceramic)
|
||
|
||
models.forEach((model) => {
|
||
manager.addJSONModel(model)
|
||
})
|
||
|
||
return new DIDDataStore({
|
||
ceramic,
|
||
model: await manager.toPublished(),
|
||
})
|
||
}
|
||
|
||
const profiles = async (store, did) => {
|
||
const basic = (await store.get('basicProfile', did))
|
||
console.info(`basic(${did})`, JSON5.stringify(basic, null, 2))
|
||
|
||
const extended = (await store.get('extendedProfile', did))
|
||
console.info(`extended(${did})`, JSON5.stringify(extended, null, 2))
|
||
}
|
||
|
||
const cryptos = async (store, did) => {
|
||
const accounts = (await store.get('cryptoAccounts', did))
|
||
console.info(`accounts(${did})`, JSON5.stringify(accounts, null, 2))
|
||
}
|
||
|
||
const write = async (store) => {
|
||
const basic = { gender: 'fluid' }
|
||
const basicRes = await store.merge('basicProfile', basic);
|
||
console.info(`Wrote basicProfile to: ${basicRes.toUrl()}`)
|
||
|
||
const extended = { pronouns: 'many & varied' }
|
||
const extendedRes = await store.merge('extendedProfile', extended);
|
||
console.info(`Wrote extendedProfile to: ${extendedRes.toUrl()}`)
|
||
}
|
||
|
||
main()
|
||
.then(() => process.exit(0))
|
||
.catch(err => console.error(err))
|