feat(communities): add API to edit shared addresses

Fixes #11153

Adds `editSharedAddressesWithAuthentication` in the chat_section view to be called from QML.

Also adds the `communityEditSharedAddressesSucceeded` and `communityEditSharedAddressesFailed` signals in the communities module to be used by QML to know if it worked.
This commit is contained in:
Jonathan Rainville 2023-07-17 14:52:46 -04:00
parent 2807f77dff
commit 8a97c0ca3a
11 changed files with 146 additions and 16 deletions

View File

@ -45,9 +45,10 @@ type
collectibleService: collectible_service.Service collectibleService: collectible_service.Service
communityTokensService: community_tokens_service.Service communityTokensService: community_tokens_service.Service
tmpAuthenticationForJoinInProgress: bool tmpAuthenticationForJoinInProgress: bool
tmpAuthenticationForEditSharedAddresses: bool
tmpRequestToJoinEnsName: string tmpRequestToJoinEnsName: string
tmpRequestToJoinAddressesToShare: seq[string] tmpAddressesToShare: seq[string]
tmpRequestToJoinAirdropAddress: string tmpAirdropAddress: string
proc newController*(delegate: io_interface.AccessInterface, sectionId: string, isCommunity: bool, events: EventEmitter, proc newController*(delegate: io_interface.AccessInterface, sectionId: string, isCommunity: bool, events: EventEmitter,
settingsService: settings_service.Service, nodeConfigurationService: node_configuration_service.Service, settingsService: settings_service.Service, nodeConfigurationService: node_configuration_service.Service,
@ -77,9 +78,10 @@ proc newController*(delegate: io_interface.AccessInterface, sectionId: string, i
result.collectibleService = collectibleService result.collectibleService = collectibleService
result.communityTokensService = communityTokensService result.communityTokensService = communityTokensService
result.tmpAuthenticationForJoinInProgress = false result.tmpAuthenticationForJoinInProgress = false
result.tmpAuthenticationForEditSharedAddresses = false
result.tmpRequestToJoinEnsName = "" result.tmpRequestToJoinEnsName = ""
result.tmpRequestToJoinAirdropAddress = "" result.tmpAirdropAddress = ""
result.tmpRequestToJoinAddressesToShare = @[] result.tmpAddressesToShare = @[]
proc delete*(self: Controller) = proc delete*(self: Controller) =
self.events.disconnect() self.events.disconnect()
@ -95,17 +97,35 @@ proc setIsCurrentSectionActive*(self: Controller, active: bool) =
proc userAuthenticationCanceled*(self: Controller) = proc userAuthenticationCanceled*(self: Controller) =
self.tmpAuthenticationForJoinInProgress = false self.tmpAuthenticationForJoinInProgress = false
self.tmpAuthenticationForEditSharedAddresses = false
self.tmpRequestToJoinEnsName = "" self.tmpRequestToJoinEnsName = ""
self.tmpRequestToJoinAirdropAddress = "" self.tmpAirdropAddress = ""
self.tmpRequestToJoinAddressesToShare = @[] self.tmpAddressesToShare = @[]
proc requestToJoinCommunityAuthenticated*(self: Controller, password: string) = proc requestToJoinCommunityAuthenticated*(self: Controller, password: string) =
self.communityService.asyncRequestToJoinCommunity(self.sectionId, self.tmpRequestToJoinEnsName, self.communityService.asyncRequestToJoinCommunity(self.sectionId, self.tmpRequestToJoinEnsName,
password, self.tmpRequestToJoinAddressesToShare, self.tmpRequestToJoinAirdropAddress) password, self.tmpAddressesToShare, self.tmpAirdropAddress)
self.tmpAuthenticationForJoinInProgress = false self.tmpAuthenticationForJoinInProgress = false
self.tmpRequestToJoinEnsName = "" self.tmpRequestToJoinEnsName = ""
self.tmpRequestToJoinAirdropAddress = "" self.tmpAirdropAddress = ""
self.tmpRequestToJoinAddressesToShare = @[] self.tmpAddressesToShare = @[]
proc editSharedAddressesAuthenticated*(self: Controller, password: string) =
self.communityService.asyncEditSharedAddresses(
self.sectionId,
password,
self.tmpAddressesToShare,
self.tmpAirdropAddress,
)
self.tmpAuthenticationForEditSharedAddresses = false
self.tmpAirdropAddress = ""
self.tmpAddressesToShare = @[]
proc userAuthenticated*(self: Controller, password: string) =
if self.tmpAuthenticationForJoinInProgress:
self.requestToJoinCommunityAuthenticated(password)
elif self.tmpAuthenticationForEditSharedAddresses:
self.editSharedAddressesAuthenticated(password)
proc authenticate*(self: Controller, keyUid = "") = proc authenticate*(self: Controller, keyUid = "") =
let data = SharedKeycarModuleAuthenticationArgs(uniqueIdentifier: UNIQUE_MAIN_MODULE_AUTH_IDENTIFIER, let data = SharedKeycarModuleAuthenticationArgs(uniqueIdentifier: UNIQUE_MAIN_MODULE_AUTH_IDENTIFIER,
@ -115,8 +135,14 @@ proc authenticate*(self: Controller, keyUid = "") =
proc authenticateToRequestToJoinCommunity*(self: Controller, ensName: string, addressesToShare: seq[string], airdropAddress: string) = proc authenticateToRequestToJoinCommunity*(self: Controller, ensName: string, addressesToShare: seq[string], airdropAddress: string) =
self.tmpAuthenticationForJoinInProgress = true self.tmpAuthenticationForJoinInProgress = true
self.tmpRequestToJoinEnsName = ensName self.tmpRequestToJoinEnsName = ensName
self.tmpRequestToJoinAirdropAddress = airdropAddress self.tmpAirdropAddress = airdropAddress
self.tmpRequestToJoinAddressesToShare = addressesToShare self.tmpAddressesToShare = addressesToShare
self.authenticate()
proc authenticateToEditSharedAddresses*(self: Controller, addressesToShare: seq[string], airdropAddress: string) =
self.tmpAuthenticationForEditSharedAddresses = true
self.tmpAirdropAddress = airdropAddress
self.tmpAddressesToShare = addressesToShare
self.authenticate() self.authenticate()
proc getMySectionId*(self: Controller): string = proc getMySectionId*(self: Controller): string =
@ -204,7 +230,7 @@ proc init*(self: Controller) =
let args = SharedKeycarModuleArgs(e) let args = SharedKeycarModuleArgs(e)
if args.uniqueIdentifier != UNIQUE_MAIN_MODULE_AUTH_IDENTIFIER: if args.uniqueIdentifier != UNIQUE_MAIN_MODULE_AUTH_IDENTIFIER:
return return
if self.tmpAuthenticationForJoinInProgress: if self.tmpAuthenticationForJoinInProgress or self.tmpAuthenticationForEditSharedAddresses:
self.delegate.onUserAuthenticated(args.pin, args.password, args.keyUid) self.delegate.onUserAuthenticated(args.pin, args.password, args.keyUid)
if (self.isCommunitySection): if (self.isCommunitySection):

View File

@ -386,6 +386,11 @@ method requestToJoinCommunityWithAuthentication*(self: AccessInterface, ensName:
airdropAddress: string) {.base.} = airdropAddress: string) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method editSharedAddressesWithAuthentication*(self: AccessInterface, addressesToShare: seq[string], airdropAddress: string)
{.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityCheckPermissionsToJoinResponse*(self: AccessInterface, checkPermissionsToJoinResponse: CheckPermissionsToJoinResponseDto) {.base.} = method onCommunityCheckPermissionsToJoinResponse*(self: AccessInterface, checkPermissionsToJoinResponse: CheckPermissionsToJoinResponseDto) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")

View File

@ -900,7 +900,7 @@ method onUserAuthenticated*(self: Module, pin: string, password: string, keyUid:
self.controller.userAuthenticationCanceled() self.controller.userAuthenticationCanceled()
return return
self.controller.requestToJoinCommunityAuthenticated(password) self.controller.userAuthenticated(password)
method onMarkAllMessagesRead*(self: Module, chat: ChatDto) = method onMarkAllMessagesRead*(self: Module, chat: ChatDto) =
self.updateBadgeNotifications(chat, hasUnreadMessages=false, unviewedMentionsCount=0) self.updateBadgeNotifications(chat, hasUnreadMessages=false, unviewedMentionsCount=0)
@ -1330,6 +1330,9 @@ method requestToJoinCommunityWithAuthentication*(self: Module, ensName: string,
airdropAddress: string) = airdropAddress: string) =
self.controller.authenticateToRequestToJoinCommunity(ensName, addressesToShare, airdropAddress) self.controller.authenticateToRequestToJoinCommunity(ensName, addressesToShare, airdropAddress)
method editSharedAddressesWithAuthentication*(self: Module, addressesToShare: seq[string], airdropAddress: string) =
self.controller.authenticateToEditSharedAddresses(addressesToShare, airdropAddress)
method onDeactivateChatLoader*(self: Module, chatId: string) = method onDeactivateChatLoader*(self: Module, chatId: string) =
self.view.chatsModel().disableChatLoader(chatId) self.view.chatsModel().disableChatLoader(chatId)

View File

@ -251,6 +251,13 @@ QtObject:
except Exception as e: except Exception as e:
echo "Error requesting to join community with authentication and shared addresses: ", e.msg echo "Error requesting to join community with authentication and shared addresses: ", e.msg
proc editSharedAddressesWithAuthentication*(self: View, addressesToShare: string, airdropAddress: string) {.slot.} =
try:
let addressesArray = map(parseJson(addressesToShare).getElems(), proc(x:JsonNode):string = x.getStr())
self.delegate.editSharedAddressesWithAuthentication(addressesArray, airdropAddress)
except Exception as e:
echo "Error editing shared addresses with authentication: ", e.msg
proc joinGroupChatFromInvitation*(self: View, groupName: string, chatId: string, adminPK: string) {.slot.} = proc joinGroupChatFromInvitation*(self: View, groupName: string, chatId: string, adminPK: string) {.slot.} =
self.delegate.joinGroupChatFromInvitation(groupName, chatId, adminPK) self.delegate.joinGroupChatFromInvitation(groupName, chatId, adminPK)

View File

@ -94,6 +94,14 @@ proc init*(self: Controller) =
let args = CommunityRequestFailedArgs(e) let args = CommunityRequestFailedArgs(e)
self.delegate.communityAccessFailed(args.communityId, args.error) self.delegate.communityAccessFailed(args.communityId, args.error)
self.events.on(SIGNAL_COMMUNITY_EDIT_SHARED_ADDRESSES_SUCCEEDED) do(e:Args):
let args = CommunityIdArgs(e)
self.delegate.communityEditSharedAddressesSucceeded(args.communityId)
self.events.on(SIGNAL_COMMUNITY_EDIT_SHARED_ADDRESSES_FAILED) do(e:Args):
let args = CommunityRequestFailedArgs(e)
self.delegate.communityEditSharedAddressesFailed(args.communityId, args.error)
self.events.on(SIGNAL_DISCORD_CATEGORIES_AND_CHANNELS_EXTRACTED) do(e:Args): self.events.on(SIGNAL_DISCORD_CATEGORIES_AND_CHANNELS_EXTRACTED) do(e:Args):
let args = DiscordCategoriesAndChannelsArgs(e) let args = DiscordCategoriesAndChannelsArgs(e)
self.delegate.discordCategoriesAndChannelsExtracted(args.categories, args.channels, args.oldestMessageTimestamp, args.errors, args.errorsCount) self.delegate.discordCategoriesAndChannelsExtracted(args.categories, args.channels, args.oldestMessageTimestamp, args.errors, args.errorsCount)

View File

@ -121,6 +121,12 @@ method communityAccessRequested*(self: AccessInterface, communityId: string) {.b
method communityAccessFailed*(self: AccessInterface, communityId: string, error: string) {.base.} = method communityAccessFailed*(self: AccessInterface, communityId: string, error: string) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method communityEditSharedAddressesSucceeded*(self: AccessInterface, communityId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method communityEditSharedAddressesFailed*(self: AccessInterface, communityId: string, error: string) {.base.} =
raise newException(ValueError, "No implementation available")
method requestExtractDiscordChannelsAndCategories*(self: AccessInterface, filesToImport: seq[string]) {.base.} = method requestExtractDiscordChannelsAndCategories*(self: AccessInterface, filesToImport: seq[string]) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")

View File

@ -274,6 +274,12 @@ method communityAccessRequested*(self: Module, communityId: string) =
method communityAccessFailed*(self: Module, communityId, error: string) = method communityAccessFailed*(self: Module, communityId, error: string) =
self.view.communityAccessFailed(communityId, error) self.view.communityAccessFailed(communityId, error)
method communityEditSharedAddressesSucceeded*(self: Module, communityId: string) =
self.view.communityEditSharedAddressesSucceeded(communityId)
method communityEditSharedAddressesFailed*(self: Module, communityId, error: string) =
self.view.communityEditSharedAddressesFailed(communityId, error)
method communityHistoryArchivesDownloadStarted*(self: Module, communityId: string) = method communityHistoryArchivesDownloadStarted*(self: Module, communityId: string) =
self.view.setDownloadingCommunityHistoryArchives(true) self.view.setDownloadingCommunityHistoryArchives(true)

View File

@ -110,6 +110,8 @@ QtObject:
proc discordImportErrorsCountChanged*(self: View) {.signal.} proc discordImportErrorsCountChanged*(self: View) {.signal.}
proc communityAccessRequested*(self: View, communityId: string) {.signal.} proc communityAccessRequested*(self: View, communityId: string) {.signal.}
proc communityAccessFailed*(self: View, communityId: string, error: string) {.signal.} proc communityAccessFailed*(self: View, communityId: string, error: string) {.signal.}
proc communityEditSharedAddressesSucceeded*(self: View, communityId: string) {.signal.}
proc communityEditSharedAddressesFailed*(self: View, communityId: string, error: string) {.signal.}
proc communityInfoAlreadyRequested*(self: View) {.signal.} proc communityInfoAlreadyRequested*(self: View) {.signal.}
proc communityTagsChanged*(self: View) {.signal.} proc communityTagsChanged*(self: View) {.signal.}

View File

@ -102,8 +102,29 @@ const asyncRequestToJoinCommunityTask: Task = proc(argEncoded: string) {.gcsafe,
arg.finish(%* { arg.finish(%* {
"error": e.msg, "error": e.msg,
"communityId": arg.communityId, "communityId": arg.communityId,
"ensName": arg.ensName, })
"password": arg.password
type
AsyncEditSharedAddressesTaskArg = ref object of QObjectTaskArg
communityId: string
password: string
addressesToShare: seq[string]
airdropAddress: string
const asyncEditSharedAddressesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncEditSharedAddressesTaskArg](argEncoded)
try:
let response = status_go.editSharedAddresses(arg.communityId, arg.password, arg.addressesToShare,
arg.airdropAddress)
arg.finish(%* {
"response": response,
"communityId": arg.communityId,
"error": "",
})
except Exception as e:
arg.finish(%* {
"error": e.msg,
"communityId": arg.communityId,
}) })
type type

View File

@ -127,6 +127,8 @@ const SIGNAL_COMMUNITY_JOINED* = "communityJoined"
const SIGNAL_COMMUNITY_SPECTATED* = "communitySpectated" const SIGNAL_COMMUNITY_SPECTATED* = "communitySpectated"
const SIGNAL_COMMUNITY_MY_REQUEST_ADDED* = "communityMyRequestAdded" const SIGNAL_COMMUNITY_MY_REQUEST_ADDED* = "communityMyRequestAdded"
const SIGNAL_COMMUNITY_MY_REQUEST_FAILED* = "communityMyRequestFailed" const SIGNAL_COMMUNITY_MY_REQUEST_FAILED* = "communityMyRequestFailed"
const SIGNAL_COMMUNITY_EDIT_SHARED_ADDRESSES_SUCCEEDED* = "communityEditSharedAddressesSucceded"
const SIGNAL_COMMUNITY_EDIT_SHARED_ADDRESSES_FAILED* = "communityEditSharedAddressesFailed"
const SIGNAL_COMMUNITY_LEFT* = "communityLeft" const SIGNAL_COMMUNITY_LEFT* = "communityLeft"
const SIGNAL_COMMUNITY_CREATED* = "communityCreated" const SIGNAL_COMMUNITY_CREATED* = "communityCreated"
const SIGNAL_COMMUNITY_ADDED* = "communityAdded" const SIGNAL_COMMUNITY_ADDED* = "communityAdded"
@ -1438,6 +1440,36 @@ QtObject:
error: e.msg error: e.msg
)) ))
proc asyncEditSharedAddresses*(self: Service, communityId: string, password: string, addressesToShare: seq[string],
airdropAddress: string) =
let arg = AsyncEditSharedAddressesTaskArg(
tptr: cast[ByteAddress](asyncEditSharedAddressesTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onAsyncEditSharedAddressesDone",
communityId: communityId,
password: password,
addressesToShare: addressesToShare,
airdropAddress: airdropAddress,
)
self.threadpool.start(arg)
proc onAsyncEditSharedAddressesDone*(self: Service, communityIdAndRpcResponse: string) {.slot.} =
let rpcResponseObj = communityIdAndRpcResponse.parseJson
try:
if (rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != ""):
raise newException(CatchableError, rpcResponseObj{"error"}.getStr)
# If we need the returned shared addresses, use the value in members.revealed_accounts of the response
self.events.emit(SIGNAL_COMMUNITY_EDIT_SHARED_ADDRESSES_SUCCEEDED, CommunityIdArgs(
communityId: rpcResponseObj["communityId"].getStr,
))
except Exception as e:
error "Error editing shared addresses", msg = e.msg
self.events.emit(SIGNAL_COMMUNITY_EDIT_SHARED_ADDRESSES_FAILED, CommunityRequestFailedArgs(
communityId: rpcResponseObj["communityId"].getStr,
error: e.msg
))
proc asyncAcceptRequestToJoinCommunity*(self: Service, communityId: string, requestId: string) = proc asyncAcceptRequestToJoinCommunity*(self: Service, communityId: string, requestId: string) =
try: try:
let userKey = self.getUserPubKeyFromPendingRequest(communityId, requestId) let userKey = self.getUserPubKeyFromPendingRequest(communityId, requestId)

View File

@ -43,7 +43,21 @@ proc requestToJoinCommunity*(
"communityId": communityId, "communityId": communityId,
"ensName": ensName, "ensName": ensName,
"password": if passwordToSend != "": utils.hashPassword(password) else: "", "password": if passwordToSend != "": utils.hashPassword(password) else: "",
"addressesToShare": addressesToShare, "addressesToReveal": addressesToShare,
"airdropAddress": airdropAddress,
}])
proc editSharedAddresses*(
communityId: string,
password: string,
addressesToShare: seq[string],
airdropAddress: string,
): RpcResponse[JsonNode] {.raises: [Exception].} =
var passwordToSend = password
result = callPrivateRPC("editSharedAddressesForCommunity".prefix, %*[{
"communityId": communityId,
"password": if passwordToSend != "": utils.hashPassword(password) else: "",
"addressesToReveal": addressesToShare,
"airdropAddress": airdropAddress, "airdropAddress": airdropAddress,
}]) }])