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
communityTokensService: community_tokens_service.Service
tmpAuthenticationForJoinInProgress: bool
tmpAuthenticationForEditSharedAddresses: bool
tmpRequestToJoinEnsName: string
tmpRequestToJoinAddressesToShare: seq[string]
tmpRequestToJoinAirdropAddress: string
tmpAddressesToShare: seq[string]
tmpAirdropAddress: string
proc newController*(delegate: io_interface.AccessInterface, sectionId: string, isCommunity: bool, events: EventEmitter,
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.communityTokensService = communityTokensService
result.tmpAuthenticationForJoinInProgress = false
result.tmpAuthenticationForEditSharedAddresses = false
result.tmpRequestToJoinEnsName = ""
result.tmpRequestToJoinAirdropAddress = ""
result.tmpRequestToJoinAddressesToShare = @[]
result.tmpAirdropAddress = ""
result.tmpAddressesToShare = @[]
proc delete*(self: Controller) =
self.events.disconnect()
@ -95,17 +97,35 @@ proc setIsCurrentSectionActive*(self: Controller, active: bool) =
proc userAuthenticationCanceled*(self: Controller) =
self.tmpAuthenticationForJoinInProgress = false
self.tmpAuthenticationForEditSharedAddresses = false
self.tmpRequestToJoinEnsName = ""
self.tmpRequestToJoinAirdropAddress = ""
self.tmpRequestToJoinAddressesToShare = @[]
self.tmpAirdropAddress = ""
self.tmpAddressesToShare = @[]
proc requestToJoinCommunityAuthenticated*(self: Controller, password: string) =
self.communityService.asyncRequestToJoinCommunity(self.sectionId, self.tmpRequestToJoinEnsName,
password, self.tmpRequestToJoinAddressesToShare, self.tmpRequestToJoinAirdropAddress)
password, self.tmpAddressesToShare, self.tmpAirdropAddress)
self.tmpAuthenticationForJoinInProgress = false
self.tmpRequestToJoinEnsName = ""
self.tmpRequestToJoinAirdropAddress = ""
self.tmpRequestToJoinAddressesToShare = @[]
self.tmpAirdropAddress = ""
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 = "") =
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) =
self.tmpAuthenticationForJoinInProgress = true
self.tmpRequestToJoinEnsName = ensName
self.tmpRequestToJoinAirdropAddress = airdropAddress
self.tmpRequestToJoinAddressesToShare = addressesToShare
self.tmpAirdropAddress = airdropAddress
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()
proc getMySectionId*(self: Controller): string =
@ -204,7 +230,7 @@ proc init*(self: Controller) =
let args = SharedKeycarModuleArgs(e)
if args.uniqueIdentifier != UNIQUE_MAIN_MODULE_AUTH_IDENTIFIER:
return
if self.tmpAuthenticationForJoinInProgress:
if self.tmpAuthenticationForJoinInProgress or self.tmpAuthenticationForEditSharedAddresses:
self.delegate.onUserAuthenticated(args.pin, args.password, args.keyUid)
if (self.isCommunitySection):

View File

@ -386,6 +386,11 @@ method requestToJoinCommunityWithAuthentication*(self: AccessInterface, ensName:
airdropAddress: string) {.base.} =
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.} =
raise newException(ValueError, "No implementation available")

View File

@ -900,7 +900,7 @@ method onUserAuthenticated*(self: Module, pin: string, password: string, keyUid:
self.controller.userAuthenticationCanceled()
return
self.controller.requestToJoinCommunityAuthenticated(password)
self.controller.userAuthenticated(password)
method onMarkAllMessagesRead*(self: Module, chat: ChatDto) =
self.updateBadgeNotifications(chat, hasUnreadMessages=false, unviewedMentionsCount=0)
@ -1330,6 +1330,9 @@ method requestToJoinCommunityWithAuthentication*(self: Module, ensName: string,
airdropAddress: string) =
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) =
self.view.chatsModel().disableChatLoader(chatId)

View File

@ -251,6 +251,13 @@ QtObject:
except Exception as e:
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.} =
self.delegate.joinGroupChatFromInvitation(groupName, chatId, adminPK)

View File

@ -94,6 +94,14 @@ proc init*(self: Controller) =
let args = CommunityRequestFailedArgs(e)
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):
let args = DiscordCategoriesAndChannelsArgs(e)
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.} =
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.} =
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) =
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) =
self.view.setDownloadingCommunityHistoryArchives(true)

View File

@ -110,6 +110,8 @@ QtObject:
proc discordImportErrorsCountChanged*(self: View) {.signal.}
proc communityAccessRequested*(self: View, communityId: 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 communityTagsChanged*(self: View) {.signal.}

View File

@ -102,8 +102,29 @@ const asyncRequestToJoinCommunityTask: Task = proc(argEncoded: string) {.gcsafe,
arg.finish(%* {
"error": e.msg,
"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

View File

@ -127,6 +127,8 @@ const SIGNAL_COMMUNITY_JOINED* = "communityJoined"
const SIGNAL_COMMUNITY_SPECTATED* = "communitySpectated"
const SIGNAL_COMMUNITY_MY_REQUEST_ADDED* = "communityMyRequestAdded"
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_CREATED* = "communityCreated"
const SIGNAL_COMMUNITY_ADDED* = "communityAdded"
@ -1438,6 +1440,36 @@ QtObject:
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) =
try:
let userKey = self.getUserPubKeyFromPendingRequest(communityId, requestId)

View File

@ -43,7 +43,21 @@ proc requestToJoinCommunity*(
"communityId": communityId,
"ensName": ensName,
"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,
}])