Save profile keypackage bundle
This commit is contained in:
@@ -5,45 +5,50 @@ import androidx.room3.RoomDatabase
|
||||
import androidx.room3.TypeConverters
|
||||
import androidx.room3.immediateTransaction
|
||||
import androidx.room3.useWriterConnection
|
||||
import at.torch.compose.database.dao.MarmotKeyPackageBundleDao
|
||||
import at.torch.compose.database.dao.MarmotKeyPackageDao
|
||||
import at.torch.compose.database.model.MarmotKeyPackageBundle
|
||||
import kotlin.time.Instant
|
||||
|
||||
val GENESIS_AT = Instant.fromEpochMilliseconds(1231006505000L)
|
||||
|
||||
@Database(
|
||||
entities = [
|
||||
_root_ide_package_.at.torch.compose.database.model.BroadcastNostrEventReceipt::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.BroadcastNostrEventRequest::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.Connection::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.ChatMessage::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.ChatMessageBroadcastNostrEventRequestRelation::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.ChatMessageBroadcastNostrEventReceiptRelation::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.ChatMessageNostrEventRelation::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.ChatRoom::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.InReplyToRelation::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.GiftWrapMessage::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.GiftWrapSeal::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.GiftWrapPayload::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.Mention::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.NegentropySynchronizeRequest::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.NegentropySynchronizeResult::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.NostrEvent::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.NostrEventRelay::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.Participant::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.Post::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.Profile::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.QuotedRelation::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.Reaction::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.RecentSearch::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.Relay::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.RepostedRelation::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.SynchronizeNostrEventRequest::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.SynchronizeNostrEventResult::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.UnsignedNostrEvent::class,
|
||||
_root_ide_package_.at.torch.compose.database.model.Zap::class
|
||||
at.torch.compose.database.model.BroadcastNostrEventReceipt::class,
|
||||
at.torch.compose.database.model.BroadcastNostrEventRequest::class,
|
||||
at.torch.compose.database.model.Connection::class,
|
||||
at.torch.compose.database.model.ChatMessage::class,
|
||||
at.torch.compose.database.model.ChatMessageBroadcastNostrEventRequestRelation::class,
|
||||
at.torch.compose.database.model.ChatMessageBroadcastNostrEventReceiptRelation::class,
|
||||
at.torch.compose.database.model.ChatMessageNostrEventRelation::class,
|
||||
at.torch.compose.database.model.ChatRoom::class,
|
||||
at.torch.compose.database.model.GiftWrapMessage::class,
|
||||
at.torch.compose.database.model.GiftWrapSeal::class,
|
||||
at.torch.compose.database.model.GiftWrapPayload::class,
|
||||
at.torch.compose.database.model.InReplyToRelation::class,
|
||||
at.torch.compose.database.model.MarmotKeyPackage::class,
|
||||
at.torch.compose.database.model.MarmotKeyPackageBundle::class,
|
||||
at.torch.compose.database.model.Mention::class,
|
||||
at.torch.compose.database.model.NegentropySynchronizeRequest::class,
|
||||
at.torch.compose.database.model.NegentropySynchronizeResult::class,
|
||||
at.torch.compose.database.model.NostrEvent::class,
|
||||
at.torch.compose.database.model.NostrEventRelay::class,
|
||||
at.torch.compose.database.model.Participant::class,
|
||||
at.torch.compose.database.model.Post::class,
|
||||
at.torch.compose.database.model.Profile::class,
|
||||
at.torch.compose.database.model.QuotedRelation::class,
|
||||
at.torch.compose.database.model.Reaction::class,
|
||||
at.torch.compose.database.model.RecentSearch::class,
|
||||
at.torch.compose.database.model.Relay::class,
|
||||
at.torch.compose.database.model.RepostedRelation::class,
|
||||
at.torch.compose.database.model.SynchronizeNostrEventRequest::class,
|
||||
at.torch.compose.database.model.SynchronizeNostrEventResult::class,
|
||||
at.torch.compose.database.model.UnsignedNostrEvent::class,
|
||||
at.torch.compose.database.model.Zap::class
|
||||
],
|
||||
version = 1
|
||||
)
|
||||
@TypeConverters(_root_ide_package_.at.torch.compose.database.converters.AuxConverters::class)
|
||||
@TypeConverters(at.torch.compose.database.converters.AuxConverters::class)
|
||||
abstract class TorchDatabase: RoomDatabase() {
|
||||
abstract fun broadcastNostrEventReceiptDao(): at.torch.compose.database.dao.BroadcastNostrEventReceiptDao
|
||||
abstract fun broadcastNostrEventRequestDao(): at.torch.compose.database.dao.BroadcastNostrEventRequestDao
|
||||
@@ -68,6 +73,10 @@ abstract class TorchDatabase: RoomDatabase() {
|
||||
|
||||
abstract fun inReplyToRelationDao(): at.torch.compose.database.dao.InReplyToRelationDao
|
||||
|
||||
abstract fun marmotKeyPackageDao(): MarmotKeyPackageDao
|
||||
|
||||
abstract fun marmotKeyPackageBundleDao(): MarmotKeyPackageBundleDao
|
||||
|
||||
abstract fun mentionDao(): at.torch.compose.database.dao.MentionDao
|
||||
|
||||
abstract fun negentropySynchronizeRequestDao(): at.torch.compose.database.dao.NegentropySynchronizeRequestDao
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package at.torch.compose.database.dao
|
||||
|
||||
import androidx.room3.Dao
|
||||
import androidx.room3.Insert
|
||||
import androidx.room3.OnConflictStrategy.Companion.IGNORE
|
||||
import androidx.room3.Upsert
|
||||
import at.torch.compose.database.model.MarmotKeyPackage
|
||||
import at.torch.compose.database.model.MarmotKeyPackageBundle
|
||||
import at.torch.compose.database.model.Mention
|
||||
|
||||
@Dao
|
||||
interface MarmotKeyPackageBundleDao {
|
||||
@Upsert
|
||||
suspend fun upsert(marmotKeyPackageBundle: MarmotKeyPackageBundle)
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package at.torch.compose.database.dao
|
||||
|
||||
import androidx.room3.Dao
|
||||
import androidx.room3.Insert
|
||||
import androidx.room3.OnConflictStrategy.Companion.IGNORE
|
||||
import androidx.room3.Upsert
|
||||
import at.torch.compose.database.model.MarmotKeyPackage
|
||||
import at.torch.compose.database.model.Mention
|
||||
|
||||
@Dao
|
||||
interface MarmotKeyPackageDao {
|
||||
|
||||
@Upsert
|
||||
suspend fun upsert(marmotKeyPackage: MarmotKeyPackage)
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package at.torch.compose.database.model
|
||||
|
||||
import androidx.room3.Entity
|
||||
import androidx.room3.ForeignKey
|
||||
import androidx.room3.PrimaryKey
|
||||
import at.torch.compose.database.model.traits.BroadcastableEntity
|
||||
import at.torch.compose.database.model.traits.LocalStoreEntity
|
||||
import at.torch.compose.database.model.traits.SoftDeletableEntity
|
||||
import at.torch.compose.database.model.traits.TimestampedEntity
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Instant
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = Profile::class,
|
||||
parentColumns = ["publicKey"],
|
||||
childColumns = ["publicKey"],
|
||||
onDelete = ForeignKey.CASCADE,
|
||||
),
|
||||
]
|
||||
)
|
||||
data class MarmotKeyPackage(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
val id: Long = 0,
|
||||
|
||||
val publicKey: HexKey,
|
||||
|
||||
val tlsEncodedMarmotKeyPackage: ByteArray,
|
||||
|
||||
override val createdAt: Instant = Clock.System.now(),
|
||||
override val updatedAt: Instant = Clock.System.now(),
|
||||
override val savedAt: Instant = Clock.System.now(),
|
||||
override val deletedAt: Instant? = null,
|
||||
override val broadcastedAt: Instant? = null,
|
||||
): TimestampedEntity, LocalStoreEntity, BroadcastableEntity, SoftDeletableEntity {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || this::class != other::class) return false
|
||||
|
||||
other as MarmotKeyPackage
|
||||
|
||||
if (id != other.id) return false
|
||||
if (publicKey != other.publicKey) return false
|
||||
if (!tlsEncodedMarmotKeyPackage.contentEquals(other.tlsEncodedMarmotKeyPackage)) return false
|
||||
if (createdAt != other.createdAt) return false
|
||||
if (updatedAt != other.updatedAt) return false
|
||||
if (savedAt != other.savedAt) return false
|
||||
if (deletedAt != other.deletedAt) return false
|
||||
if (broadcastedAt != other.broadcastedAt) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = id.hashCode()
|
||||
result = 31 * result + publicKey.hashCode()
|
||||
result = 31 * result + tlsEncodedMarmotKeyPackage.contentHashCode()
|
||||
result = 31 * result + createdAt.hashCode()
|
||||
result = 31 * result + updatedAt.hashCode()
|
||||
result = 31 * result + savedAt.hashCode()
|
||||
result = 31 * result + (deletedAt?.hashCode() ?: 0)
|
||||
result = 31 * result + (broadcastedAt?.hashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package at.torch.compose.database.model
|
||||
|
||||
import androidx.room3.Entity
|
||||
import androidx.room3.ForeignKey
|
||||
import androidx.room3.PrimaryKey
|
||||
import at.torch.compose.database.model.traits.BroadcastableEntity
|
||||
import at.torch.compose.database.model.traits.LocalStoreEntity
|
||||
import at.torch.compose.database.model.traits.SoftDeletableEntity
|
||||
import at.torch.compose.database.model.traits.TimestampedEntity
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Instant
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = Profile::class,
|
||||
parentColumns = ["publicKey"],
|
||||
childColumns = ["publicKey"],
|
||||
onDelete = ForeignKey.CASCADE,
|
||||
),
|
||||
]
|
||||
)
|
||||
data class MarmotKeyPackageBundle(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
val id: Long = 0,
|
||||
|
||||
val publicKey: HexKey,
|
||||
|
||||
val tlsEncodedMarmotKeyPackage: String,
|
||||
val ncryptsecInitPrivateKey: String,
|
||||
val ncryptsecEncryptionPrivateKey: String,
|
||||
val ncryptsecSignaturePrivateKey: String,
|
||||
|
||||
override val createdAt: Instant = Clock.System.now(),
|
||||
override val updatedAt: Instant = Clock.System.now(),
|
||||
override val savedAt: Instant = Clock.System.now(),
|
||||
override val deletedAt: Instant? = null,
|
||||
override val broadcastedAt: Instant? = null,
|
||||
): TimestampedEntity, LocalStoreEntity, BroadcastableEntity, SoftDeletableEntity {
|
||||
|
||||
}
|
||||
@@ -3,6 +3,10 @@ package at.torch.compose.database.model
|
||||
import androidx.room3.Entity
|
||||
import androidx.room3.ForeignKey
|
||||
import androidx.room3.PrimaryKey
|
||||
import at.torch.compose.database.model.traits.BroadcastableEntity
|
||||
import at.torch.compose.database.model.traits.LocalStoreEntity
|
||||
import at.torch.compose.database.model.traits.SoftDeletableEntity
|
||||
import at.torch.compose.database.model.traits.TimestampedEntity
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Instant
|
||||
@@ -37,7 +41,7 @@ data class Mention(
|
||||
override val savedAt: Instant = Clock.System.now(),
|
||||
override val deletedAt: Instant? = null,
|
||||
override val broadcastedAt: Instant? = null,
|
||||
): at.torch.compose.database.model.traits.TimestampedEntity,
|
||||
at.torch.compose.database.model.traits.LocalStoreEntity,
|
||||
at.torch.compose.database.model.traits.BroadcastableEntity,
|
||||
at.torch.compose.database.model.traits.SoftDeletableEntity
|
||||
): TimestampedEntity,
|
||||
LocalStoreEntity,
|
||||
BroadcastableEntity,
|
||||
SoftDeletableEntity
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package at.torch.compose.database.repository
|
||||
|
||||
import at.torch.compose.database.TorchDatabase
|
||||
import at.torch.compose.database.model.MarmotKeyPackageBundle
|
||||
import at.torch.compose.extensions.toHex
|
||||
import at.torch.compose.repository.MarmotRepository
|
||||
import com.vitorpamplona.quartz.marmot.mls.codec.TlsWriter
|
||||
import com.vitorpamplona.quartz.marmot.mls.messages.KeyPackageBundle
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip49PrivKeyEnc.Nip49
|
||||
|
||||
class DatabaseMarmotRepository(
|
||||
val database: TorchDatabase
|
||||
): MarmotRepository {
|
||||
override suspend fun saveMarmotKeyPackageBundle(
|
||||
publicKey: HexKey,
|
||||
keyPackageBundle: KeyPackageBundle,
|
||||
nsecPassword: String
|
||||
) {
|
||||
val tlsWriter = TlsWriter()
|
||||
|
||||
keyPackageBundle.keyPackage.encodeTls(tlsWriter)
|
||||
|
||||
val nip49 = Nip49()
|
||||
|
||||
database.marmotKeyPackageBundleDao().upsert(
|
||||
MarmotKeyPackageBundle(
|
||||
publicKey = publicKey,
|
||||
tlsEncodedMarmotKeyPackage = tlsWriter.toByteArray().toHex(),
|
||||
ncryptsecInitPrivateKey = nip49.encrypt(keyPackageBundle.initPrivateKey.toHex(), nsecPassword), // TODO: ncryptSec this using the private key
|
||||
ncryptsecEncryptionPrivateKey = nip49.encrypt(keyPackageBundle.encryptionPrivateKey.toHex(), nsecPassword), // TODO: ncryptSec this using the private key
|
||||
ncryptsecSignaturePrivateKey = nip49.encrypt(keyPackageBundle.signaturePrivateKey.toHex(), nsecPassword) // TODO: ncryptSec this using the private key
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,6 @@
|
||||
package at.torch.compose.database.repository
|
||||
|
||||
import at.torch.compose.database.GENESIS_AT
|
||||
import at.torch.compose.database.model.BroadcastNostrEventReceipt
|
||||
import at.torch.compose.database.model.ChatMessageBroadcastNostrEventReceiptRelation
|
||||
import at.torch.compose.database.model.RecentSearch
|
||||
import at.torch.compose.database.model.MarmotKeyPackageBundle
|
||||
import at.torch.compose.database.model.UnsignedNostrEvent
|
||||
import at.torch.compose.nostr.Relays
|
||||
import co.touchlab.kermit.Logger
|
||||
@@ -11,6 +8,7 @@ import com.vitorpamplona.quartz.marmot.mip00KeyPackages.KeyPackageEvent
|
||||
import com.vitorpamplona.quartz.marmot.mip00KeyPackages.KeyPackageRelayListEvent
|
||||
import com.vitorpamplona.quartz.marmot.mip00KeyPackages.KeyPackageRotationManager.Companion.KEY_PACKAGE_LIFETIME_SECONDS
|
||||
import com.vitorpamplona.quartz.marmot.mip00KeyPackages.KeyPackageUtils
|
||||
import com.vitorpamplona.quartz.marmot.mls.codec.TlsWriter
|
||||
import com.vitorpamplona.quartz.marmot.mls.crypto.Ed25519
|
||||
import com.vitorpamplona.quartz.marmot.mls.crypto.MlsCryptoProvider
|
||||
import com.vitorpamplona.quartz.marmot.mls.crypto.X25519
|
||||
@@ -48,14 +46,11 @@ import com.vitorpamplona.quartz.nip18Reposts.quotes.QEventTag
|
||||
import com.vitorpamplona.quartz.nip18Reposts.quotes.quotes
|
||||
import com.vitorpamplona.quartz.nip21UriScheme.toNostrUri
|
||||
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
|
||||
import com.vitorpamplona.quartz.nip28PublicChat.list.ChannelListEvent
|
||||
import com.vitorpamplona.quartz.nip31Alts.AltTag
|
||||
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.RelayFeedsListEvent
|
||||
import com.vitorpamplona.quartz.nip51Lists.tags.RelayTag
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
@@ -118,7 +113,7 @@ class DatabaseNostrRepository(
|
||||
publicKey: HexKey,
|
||||
name: String?,
|
||||
biography: String?
|
||||
) {
|
||||
): KeyPackageBundle {
|
||||
val profileEventTemplate = MetadataEvent.createNew(
|
||||
name = name,
|
||||
about = biography,
|
||||
@@ -213,8 +208,6 @@ class DatabaseNostrRepository(
|
||||
val identity = publicKey.hexToByteArray()
|
||||
val bundle = generateKeyPackage(identity, dTag)
|
||||
|
||||
// TODO: Save the bundle?
|
||||
|
||||
val keyPackageBytes = bundle.keyPackage.toTlsBytes()
|
||||
val keyPackageBase64 = Base64.encode(keyPackageBytes)
|
||||
val keyPackageRef = bundle.keyPackage.reference().toHexKey()
|
||||
@@ -236,6 +229,8 @@ class DatabaseNostrRepository(
|
||||
)
|
||||
|
||||
saveUnsignedNostrEvents(unsignedNostrEvents)
|
||||
|
||||
return bundle
|
||||
}
|
||||
|
||||
private fun generateKeyPackage(
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package at.torch.compose.repository
|
||||
|
||||
import com.vitorpamplona.quartz.marmot.mls.messages.KeyPackageBundle
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
|
||||
interface MarmotRepository {
|
||||
|
||||
suspend fun saveMarmotKeyPackageBundle(
|
||||
publicKey: HexKey,
|
||||
keyPackageBundle: KeyPackageBundle,
|
||||
nsecPassword: String
|
||||
)
|
||||
|
||||
companion object {
|
||||
private val NO_OP_MARMOT_KEY_PACKAGE_BUNDLE = object: MarmotRepository {
|
||||
override suspend fun saveMarmotKeyPackageBundle(
|
||||
publicKey: HexKey,
|
||||
keyPackageBundle: KeyPackageBundle,
|
||||
nsecPassword: String
|
||||
) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package at.torch.compose.repository
|
||||
|
||||
import com.vitorpamplona.quartz.marmot.mls.messages.KeyPackageBundle
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Kind
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
@@ -24,7 +25,7 @@ interface NostrRepository {
|
||||
publicKey: HexKey,
|
||||
name: String?,
|
||||
biography: String?
|
||||
)
|
||||
): KeyPackageBundle
|
||||
|
||||
suspend fun signInToProfile(
|
||||
publicKey: HexKey
|
||||
@@ -155,7 +156,8 @@ interface NostrRepository {
|
||||
publicKey: HexKey,
|
||||
name: String?,
|
||||
biography: String?
|
||||
) {
|
||||
): KeyPackageBundle {
|
||||
TODO("")
|
||||
}
|
||||
|
||||
override suspend fun signInToProfile(publicKey: HexKey) {
|
||||
|
||||
@@ -90,6 +90,7 @@ class ChatRoomCreationViewModel(
|
||||
viewModelScope.launch(Dispatchers.Main) {
|
||||
if (localChatRoom != null) {
|
||||
// TODO: Broadcast the thing...
|
||||
|
||||
// TODO: Navigate to invitation screen...
|
||||
onNavigateToChatRoom.invoke(
|
||||
ChatRoomDetailRoute(
|
||||
|
||||
@@ -10,6 +10,7 @@ import androidx.lifecycle.viewmodel.initializer
|
||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||
import at.torch.compose.ui.view.state.form.CreateProfileFormState
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import at.torch.compose.repository.MarmotRepository
|
||||
import co.touchlab.kermit.Logger
|
||||
import fr.acinq.bitcoin.Chain
|
||||
import fr.acinq.bitcoin.MnemonicCode
|
||||
@@ -18,6 +19,7 @@ import fr.acinq.lightning.Lightning
|
||||
import fr.acinq.lightning.crypto.LocalKeyManager
|
||||
import fr.acinq.phoenix.managers.NodeParamsManager
|
||||
import fr.acinq.phoenix.managers.nostrPublicKey
|
||||
import fr.acinq.phoenix.managers.nsecPassword
|
||||
import fr.acinq.phoenix.utils.MnemonicLanguage
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -27,19 +29,22 @@ import kotlinx.coroutines.launch
|
||||
class CreateProfileViewModel(
|
||||
val initialCreateProfileUIState: CreateProfileUIState,
|
||||
val createProfileFormState: CreateProfileFormState = CreateProfileFormState(),
|
||||
val nostrRepository: NostrRepository
|
||||
val nostrRepository: NostrRepository,
|
||||
val marmotRepository: MarmotRepository
|
||||
): ViewModel() {
|
||||
companion object {
|
||||
private const val TAG = "CreateAccountViewModel"
|
||||
|
||||
fun factory(
|
||||
initialCreateProfileUIState: CreateProfileUIState,
|
||||
nostrRepository: NostrRepository
|
||||
nostrRepository: NostrRepository,
|
||||
marmotRepository: MarmotRepository
|
||||
): ViewModelProvider.Factory = viewModelFactory {
|
||||
initializer {
|
||||
CreateProfileViewModel(
|
||||
initialCreateProfileUIState,
|
||||
nostrRepository = nostrRepository
|
||||
nostrRepository = nostrRepository,
|
||||
marmotRepository = marmotRepository
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -100,12 +105,17 @@ class CreateProfileViewModel(
|
||||
)
|
||||
|
||||
val pubkey = localKeyManager.nostrPublicKey()
|
||||
logger.d("NostrKey: $pubkey")
|
||||
nostrRepository.createNewProfile(
|
||||
val keyPackageBundle = nostrRepository.createNewProfile(
|
||||
pubkey,
|
||||
name = createProfileFormState.nameField.textFieldState.text.toString(),
|
||||
biography = createProfileFormState.biographyField.textFieldState.text.toString()
|
||||
)
|
||||
|
||||
marmotRepository.saveMarmotKeyPackageBundle(
|
||||
publicKey = pubkey,
|
||||
keyPackageBundle,
|
||||
nsecPassword = localKeyManager.nsecPassword()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -102,6 +102,12 @@ fun LocalKeyManager.nostrPrivateKey(): PrivateKey {
|
||||
return derivePrivateKey(path).privateKey
|
||||
}
|
||||
|
||||
fun LocalKeyManager.nsecPassword(): String {
|
||||
return Crypto.hash160(
|
||||
nostrPrivateKey().value
|
||||
).byteVector().toHex()
|
||||
}
|
||||
|
||||
fun LocalKeyManager.nostrPublicKey(): HexKey {
|
||||
return KeyPair(
|
||||
privKey = nostrPrivateKey().value.toByteArray()
|
||||
|
||||
Reference in New Issue
Block a user