mirror of
https://github.com/logos-messaging/OpChan.git
synced 2026-01-03 05:13:09 +00:00
92 lines
2.8 KiB
TypeScript
92 lines
2.8 KiB
TypeScript
import React from 'react';
|
|
import { OpChanClient, type OpChanClientConfig } from '@opchan/core';
|
|
import { ClientProvider } from '../context/ClientContext';
|
|
import { StoreWiring } from './StoreWiring';
|
|
import { setOpchanState } from '../store/opchanStore';
|
|
import { EVerificationStatus } from '@opchan/core';
|
|
import type { EDisplayPreference, User } from '@opchan/core';
|
|
|
|
export interface WalletAdapterAccount {
|
|
address: string;
|
|
walletType: 'bitcoin' | 'ethereum';
|
|
}
|
|
|
|
export interface WalletAdapter {
|
|
getAccount(): WalletAdapterAccount | null;
|
|
onChange(callback: (account: WalletAdapterAccount | null) => void): () => void;
|
|
}
|
|
|
|
export interface NewOpChanProviderProps {
|
|
config: OpChanClientConfig;
|
|
walletAdapter?: WalletAdapter;
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
/**
|
|
* New provider that constructs the OpChanClient and sets up DI.
|
|
* Event wiring and store hydration will be handled in a separate effect layer.
|
|
*/
|
|
export const OpChanProvider: React.FC<NewOpChanProviderProps> = ({ config, walletAdapter, children }) => {
|
|
const [client] = React.useState(() => new OpChanClient(config));
|
|
|
|
// Bridge wallet adapter to session state
|
|
React.useEffect(() => {
|
|
if (!walletAdapter) return;
|
|
|
|
const syncFromAdapter = async (account: WalletAdapterAccount | null) => {
|
|
if (account) {
|
|
// Persist base user and update session
|
|
const baseUser: User = {
|
|
address: account.address,
|
|
walletType: account.walletType,
|
|
displayPreference: 'wallet-address' as EDisplayPreference,
|
|
verificationStatus: EVerificationStatus.WALLET_CONNECTED,
|
|
displayName: account.address,
|
|
lastChecked: Date.now(),
|
|
};
|
|
try {
|
|
await client.database.storeUser(baseUser);
|
|
} catch (err) {
|
|
console.warn('OpChanProvider: failed to persist base user', err);
|
|
}
|
|
setOpchanState(prev => ({
|
|
...prev,
|
|
session: {
|
|
currentUser: baseUser,
|
|
verificationStatus: baseUser.verificationStatus,
|
|
delegation: prev.session.delegation,
|
|
},
|
|
}));
|
|
} else {
|
|
// Clear session on disconnect
|
|
try { await client.database.clearUser(); } catch (err) {
|
|
console.warn('OpChanProvider: failed to clear user on disconnect', err);
|
|
}
|
|
setOpchanState(prev => ({
|
|
...prev,
|
|
session: {
|
|
currentUser: null,
|
|
verificationStatus: EVerificationStatus.WALLET_UNCONNECTED,
|
|
delegation: null,
|
|
},
|
|
}));
|
|
}
|
|
};
|
|
|
|
// Initial sync
|
|
syncFromAdapter(walletAdapter.getAccount());
|
|
// Subscribe
|
|
const off = walletAdapter.onChange(syncFromAdapter);
|
|
return () => { try { off(); } catch { /* noop */ } };
|
|
}, [walletAdapter, client]);
|
|
|
|
return (
|
|
<ClientProvider client={client}>
|
|
<StoreWiring />
|
|
{children}
|
|
</ClientProvider>
|
|
);
|
|
};
|
|
|
|
|