import * as solarium from 'solarium-js' ; import { Channel , Message } from 'solarium-js' ; import { Connection , Keypair , PublicKey } from "@solana/web3.js" ; import Wallet from "@project-serum/sol-wallet-adapter" ; import { DEFAULT_ENDPOINT_INDEX , sign } from "../web3/connection" ; import { Observable } from "rxjs" ; import { ENDPOINTS , MIN_BALANCE } from "../constants" ; const DECRYPTION_KEY_IDENTIFIER = 'browser' ; const cluster = ENDPOINTS [ DEFAULT_ENDPOINT_INDEX ] . name ; export const airdropIfNeeded = async ( connection , wallet ) : Promise < void > => { const balance = await connection . getBalance ( wallet . publicKey ) ; if ( balance < MIN_BALANCE ) { console . log ( "Airdropping..." ) ; await solarium . airdrop ( connection , wallet . publicKey , MIN_BALANCE * 2 ) ; } } ; const withAirdrop = < T extends Array < any > , U > ( fn ) => { return async ( ... args ) : Promise < U > => { await airdropIfNeeded ( args [ 0 ] , args [ 1 ] ) ; return fn ( ... args ) ; } ; } ; export const createChannel = withAirdrop ( ( connection , wallet , name ) : Promise < Channel > => solarium . create ( { name , payer : wallet . publicKey , signCallback : sign ( connection , wallet ) , cluster } ) ) ; export const createDirectChannel = withAirdrop ( ( connection , wallet , inviteeDID ) : Promise < Channel > => solarium . createDirect ( { inviteeDID , payer : wallet . publicKey , signCallback : sign ( connection , wallet ) , cluster } ) ) ; export const getChannel = ( connection , wallet , ownerDID , channelAddress , decryptionKey ? ) : Promise < Channel | null > => solarium . get ( { channel : channelAddress , ownerDID , cluster , decryptionKey : decryptionKey ?. secretKey } ) ; export const getDirectChannel = async ( connection , wallet , partnerDID , decryptionKey ? ) : Promise < Channel | null > => { try { return await solarium . getDirect ( { owner : wallet . publicKey . toBase58 ( ) , partnerDID , cluster , decryptionKey : decryptionKey ?. secretKey } ) ; } catch ( error ) { if ( error . message === 'Channel not found' ) return null ; throw error ; } } ; export const getOrCreateDirectChannel = withAirdrop ( async ( connection , wallet , partnerDID , decryptionKey ? ) : Promise < Channel > => { const channel = await getDirectChannel ( connection , wallet , partnerDID , decryptionKey ) ; if ( channel ) return channel ; return solarium . createDirect ( { inviteeDID : partnerDID , payer : wallet . publicKey , signCallback : sign ( connection , wallet ) , cluster } ) ; } ) ; export const getOrCreateChannel = withAirdrop ( async ( connection , wallet , did , name , address , decryptionKey ? ) : Promise < Channel > => { const channel = await getChannel ( connection , wallet , did , address , decryptionKey ) ; if ( channel ) return channel ; return solarium . create ( { name , payer : wallet . publicKey , signCallback : sign ( connection , wallet ) , cluster } ) ; } ) ; export const addKey = withAirdrop ( async ( connection , wallet , newKey , ownerDID ? , decryptionKey ? , channelsToUpdate = [ ] ) : Promise < void > => { console . log ( "Adding key" , { newKey : newKey . toBase58 ( ) , ownerDID , payer : wallet . publicKey . toBase58 ( ) } ) ; if ( channelsToUpdate . length > 0 && ! decryptionKey ) { throw new Error ( "Decryption key required to update channels with new key" ) ; } const signCallback = decryptionKey ? sign ( connection , wallet , decryptionKey ) : sign ( connection , wallet ) ; await solarium . addKey ( { signer : decryptionKey ?. secretKey || wallet . publicKey , channelsToUpdate : channelsToUpdate . map ( c => c . address . toBase58 ( ) ) , payer : wallet . publicKey , ownerDID , keyIdentifier : DECRYPTION_KEY_IDENTIFIER , newKey : newKey . toBase58 ( ) , signCallback , cluster } ) ; } ) ; export const postToChannel = withAirdrop ( ( connection , wallet , channel , senderDID , signer , message ) : Promise < void > => solarium . post ( { channel : channel . address . toBase58 ( ) , payer : wallet . publicKey , signer : signer . secretKey , message , signCallback : sign ( connection , wallet , signer ) , cluster } ) ) ; export const readChannel = ( did , channel , decryptionKey ) : Observable < Message > => solarium . readStream ( { channel : channel . address . toBase58 ( ) , memberDID : did , decryptionKey : decryptionKey . secretKey , cluster } ) ; export const addToChannel = withAirdrop ( ( connection , wallet , did , channelAddress , inviteAuthority , inviteeDID ) => solarium . addToChannel ( { channel : channelAddress , decryptionKey : inviteAuthority . secretKey , ownerDID : did , inviteeDID , payer : wallet . publicKey , signCallback : sign ( connection , wallet , inviteAuthority ) , cluster } ) ) ; export const createIdentity = withAirdrop ( ( connection , wallet , decryptionKey , alias ? ) => solarium . createDID ( { payer : wallet . publicKey , alias , additionalKeys : [ { identifier : DECRYPTION_KEY_IDENTIFIER , key : decryptionKey . publicKey . toBase58 ( ) } ] , signCallback : sign ( connection , wallet ) , cluster , } ) ) ; export const getUserDetails = ( did ) => solarium . getUserDetails ( { did , cluster } ) ; export const createUserDetails = ( connection , wallet , did , alias ) => { return solarium . createUserDetails ( { payer : wallet . publicKey , signCallback : sign ( connection , wallet ) , ownerDID : did , alias , cluster } ) ; } ; export const updateUserDetails = ( connection , wallet , did , alias ) => { return solarium . updateUserDetails ( { payer : wallet . publicKey , signCallback : sign ( connection , wallet ) , ownerDID : did , alias , cluster } ) ; } ;