feat(@desktop/keycard): joining communities using addresses migrated to a keycard
Closes: #12170
This commit is contained in:
parent
0e16a4e2fb
commit
ad7774799a
|
@ -1,26 +1,22 @@
|
|||
import stint, std/strutils
|
||||
import stint, std/strutils, uuids, os
|
||||
import ./io_interface
|
||||
|
||||
import ../../../core/signals/types
|
||||
import ../../../core/eventemitter
|
||||
import ../../../../app_service/service/chat/dto/chat
|
||||
import ../../../../app_service/service/community/service as community_service
|
||||
import ../../../../app_service/service/contacts/service as contacts_service
|
||||
import ../../../../app_service/service/chat/service as chat_service
|
||||
import ../../../../app_service/service/network/service as networks_service
|
||||
import ../../../../app_service/service/community_tokens/service as community_tokens_service
|
||||
import ../../../../app_service/service/token/service as token_service
|
||||
import ../../../../app_service/service/wallet_account/service as wallet_account_service
|
||||
import app/core/signals/types
|
||||
import app/core/eventemitter
|
||||
import app_service/service/chat/dto/chat
|
||||
import app_service/service/community/service as community_service
|
||||
import app_service/service/contacts/service as contacts_service
|
||||
import app_service/service/chat/service as chat_service
|
||||
import app_service/service/network/service as networks_service
|
||||
import app_service/service/community_tokens/service as community_tokens_service
|
||||
import app_service/service/token/service as token_service
|
||||
import app_service/service/wallet_account/service as wallet_account_service
|
||||
import app_service/service/keycard/service as keycard_service
|
||||
import backend/collectibles as backend_collectibles
|
||||
import ../../shared_modules/keycard_popup/io_interface as keycard_shared_module
|
||||
import app/modules/shared_modules/keycard_popup/io_interface as keycard_shared_module
|
||||
|
||||
const UNIQUE_COMMUNITIES_MODULE_AUTH_IDENTIFIER* = "CommunitiesModule-Action-Authentication"
|
||||
|
||||
type
|
||||
AuthenticationAction* {.pure.} = enum
|
||||
None = 0,
|
||||
CommunityJoin = 1,
|
||||
CommunitySharedAddressesJoin = 2,
|
||||
const UNIQUE_COMMUNITIES_MODULE_AUTH_IDENTIFIER* = "CommunitiesModule-Authentication"
|
||||
const UNIQUE_COMMUNITIES_MODULE_SIGNING_IDENTIFIER* = "CommunitiesModule-Signing"
|
||||
|
||||
type
|
||||
Controller* = ref object of RootObj
|
||||
|
@ -32,13 +28,13 @@ type
|
|||
networksService: networks_service.Service
|
||||
tokenService: token_service.Service
|
||||
chatService: chat_service.Service
|
||||
tmpCommunityId: string
|
||||
tmpCommunityIdForChannelsPermisisons: string
|
||||
tmpCommunityIdForRevealedAccounts: string
|
||||
tmpAuthenticationAction: AuthenticationAction
|
||||
tmpRequestToJoinEnsName: string
|
||||
tmpAddressesToShare: seq[string]
|
||||
tmpAirdropAddress: string
|
||||
walletAccountService: wallet_account_service.Service
|
||||
keycardService: keycard_service.Service
|
||||
connectionKeycardResponse: UUID
|
||||
## the following are used for silent signing in case there are more then a single address for the same keypair
|
||||
silentSigningPath: string
|
||||
silentSigningKeyUid: string
|
||||
silentSigningPin: string
|
||||
|
||||
proc newController*(
|
||||
delegate: io_interface.AccessInterface,
|
||||
|
@ -49,6 +45,8 @@ proc newController*(
|
|||
networksService: networks_service.Service,
|
||||
tokenService: token_service.Service,
|
||||
chatService: chat_service.Service,
|
||||
walletAccountService: wallet_account_service.Service,
|
||||
keycardService: keycard_service.Service
|
||||
): Controller =
|
||||
result = Controller()
|
||||
result.delegate = delegate
|
||||
|
@ -59,12 +57,8 @@ proc newController*(
|
|||
result.networksService = networksService
|
||||
result.tokenService = tokenService
|
||||
result.chatService = chatService
|
||||
result.tmpCommunityId = ""
|
||||
result.tmpCommunityIdForChannelsPermisisons = ""
|
||||
result.tmpCommunityIdForRevealedAccounts = ""
|
||||
result.tmpRequestToJoinEnsName = ""
|
||||
result.tmpAirdropAddress = ""
|
||||
result.tmpAddressesToShare = @[]
|
||||
result.walletAccountService = walletAccountService
|
||||
result.keycardService = keycardService
|
||||
|
||||
proc delete*(self: Controller) =
|
||||
discard
|
||||
|
@ -171,28 +165,22 @@ proc init*(self: Controller) =
|
|||
|
||||
self.events.on(SIGNAL_CHECK_PERMISSIONS_TO_JOIN_RESPONSE) do(e: Args):
|
||||
let args = CheckPermissionsToJoinResponseArgs(e)
|
||||
if (args.communityId == self.tmpCommunityId):
|
||||
self.delegate.onCommunityCheckPermissionsToJoinResponse(args.communityId, args.checkPermissionsToJoinResponse)
|
||||
self.tmpCommunityId = ""
|
||||
self.delegate.onCommunityCheckPermissionsToJoinResponse(args.communityId, args.checkPermissionsToJoinResponse)
|
||||
|
||||
self.events.on(SIGNAL_CHECK_ALL_CHANNELS_PERMISSIONS_RESPONSE) do(e: Args):
|
||||
let args = CheckAllChannelsPermissionsResponseArgs(e)
|
||||
if args.communityId == self.tmpCommunityIdForChannelsPermisisons:
|
||||
self.delegate.onCommunityCheckAllChannelsPermissionsResponse(
|
||||
args.communityId,
|
||||
args.checkAllChannelsPermissionsResponse,
|
||||
)
|
||||
self.tmpCommunityIdForChannelsPermisisons = ""
|
||||
self.delegate.onCommunityCheckAllChannelsPermissionsResponse(
|
||||
args.communityId,
|
||||
args.checkAllChannelsPermissionsResponse,
|
||||
)
|
||||
|
||||
self.events.on(SIGNAL_COMMUNITY_MEMBER_REVEALED_ACCOUNTS_LOADED) do(e: Args):
|
||||
let args = CommunityMemberRevealedAccountsArgs(e)
|
||||
if self.tmpCommunityIdForRevealedAccounts == args.communityId:
|
||||
self.delegate.onCommunityMemberRevealedAccountsLoaded(
|
||||
args.communityId,
|
||||
args.memberPubkey,
|
||||
args.memberRevealedAccounts,
|
||||
)
|
||||
self.tmpCommunityIdForRevealedAccounts = ""
|
||||
self.delegate.onCommunityMemberRevealedAccountsLoaded(
|
||||
args.communityId,
|
||||
args.memberPubkey,
|
||||
args.memberRevealedAccounts,
|
||||
)
|
||||
|
||||
self.events.on(SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT) do(e: Args):
|
||||
self.delegate.onWalletAccountTokensRebuilt()
|
||||
|
@ -211,6 +199,12 @@ proc init*(self: Controller) =
|
|||
let args = CheckChannelsPermissionsErrorArgs(e)
|
||||
self.delegate.onCommunityCheckAllChannelPermissionsFailed(args.communityId, args.error)
|
||||
|
||||
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_DATA_SIGNED) do(e: Args):
|
||||
let args = SharedKeycarModuleArgs(e)
|
||||
if args.uniqueIdentifier != UNIQUE_COMMUNITIES_MODULE_SIGNING_IDENTIFIER:
|
||||
return
|
||||
self.delegate.onDataSigned(args.keyUid, args.path, args.r, args.s, args.v, args.pin)
|
||||
|
||||
proc getCommunityTags*(self: Controller): string =
|
||||
result = self.communityService.getCommunityTags()
|
||||
|
||||
|
@ -363,78 +357,92 @@ proc shareCommunityChannelUrlWithChatKey*(self: Controller, communityId: string,
|
|||
proc shareCommunityChannelUrlWithData*(self: Controller, communityId: string, chatId: string): string =
|
||||
return self.communityService.shareCommunityChannelUrlWithData(communityId, chatId)
|
||||
|
||||
proc userAuthenticationCanceled*(self: Controller) =
|
||||
self.tmpAuthenticationAction = AuthenticationAction.None
|
||||
self.tmpCommunityId = ""
|
||||
self.tmpCommunityIdForChannelsPermisisons = ""
|
||||
self.tmpRequestToJoinEnsName = ""
|
||||
self.tmpAirdropAddress = ""
|
||||
self.tmpAddressesToShare = @[]
|
||||
proc asyncRequestToJoinCommunity*(self: Controller, communityId: string, ensName: string, addressesToShare: seq[string],
|
||||
airdropAddress: string, signatures: seq[string]) =
|
||||
self.communityService.asyncRequestToJoinCommunity(communityId, ensName, addressesToShare, airdropAddress,
|
||||
signatures)
|
||||
|
||||
proc requestToJoinCommunityAuthenticated*(self: Controller, password: string) =
|
||||
self.communityService.asyncRequestToJoinCommunity(
|
||||
self.tmpCommunityId,
|
||||
self.tmpRequestToJoinEnsName,
|
||||
password,
|
||||
self.tmpAddressesToShare,
|
||||
self.tmpAirdropAddress
|
||||
)
|
||||
self.tmpAuthenticationAction = AuthenticationAction.None
|
||||
self.tmpCommunityId = ""
|
||||
self.tmpRequestToJoinEnsName = ""
|
||||
self.tmpAirdropAddress = ""
|
||||
self.tmpAddressesToShare = @[]
|
||||
proc asyncEditSharedAddresses*(self: Controller, communityId: string, addressesToShare: seq[string],
|
||||
airdropAddress: string, signatures: seq[string]) =
|
||||
self.communityService.asyncEditSharedAddresses(communityId, addressesToShare, airdropAddress, signatures)
|
||||
|
||||
proc editSharedAddressesAuthenticated*(self: Controller, password: string) =
|
||||
self.communityService.asyncEditSharedAddresses(
|
||||
self.tmpCommunityId,
|
||||
password,
|
||||
self.tmpAddressesToShare,
|
||||
self.tmpAirdropAddress,
|
||||
)
|
||||
self.tmpAuthenticationAction = AuthenticationAction.None
|
||||
self.tmpCommunityId = ""
|
||||
self.tmpAirdropAddress = ""
|
||||
self.tmpAddressesToShare = @[]
|
||||
|
||||
proc userAuthenticated*(self: Controller, password: string) =
|
||||
if self.tmpAuthenticationAction == AuthenticationAction.CommunityJoin:
|
||||
self.requestToJoinCommunityAuthenticated(password)
|
||||
elif self.tmpAuthenticationAction == AuthenticationAction.CommunitySharedAddressesJoin:
|
||||
self.editSharedAddressesAuthenticated(password)
|
||||
|
||||
proc authenticate*(self: Controller, keyUid = "") =
|
||||
let data = SharedKeycarModuleAuthenticationArgs(uniqueIdentifier: UNIQUE_COMMUNITIES_MODULE_AUTH_IDENTIFIER,
|
||||
keyUid: keyUid)
|
||||
proc authenticate*(self: Controller) =
|
||||
let data = SharedKeycarModuleAuthenticationArgs(uniqueIdentifier: UNIQUE_COMMUNITIES_MODULE_AUTH_IDENTIFIER)
|
||||
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data)
|
||||
|
||||
proc authenticateToRequestToJoinCommunity*(self: Controller, communityId: string, ensName: string, addressesToShare: seq[string], airdropAddress: string) =
|
||||
self.tmpCommunityId = communityId
|
||||
self.tmpAuthenticationAction = AuthenticationAction.CommunityJoin
|
||||
self.tmpRequestToJoinEnsName = ensName
|
||||
self.tmpAirdropAddress = airdropAddress
|
||||
self.tmpAddressesToShare = addressesToShare
|
||||
self.authenticate()
|
||||
|
||||
proc authenticateToEditSharedAddresses*(self: Controller, communityId: string, addressesToShare: seq[string], airdropAddress: string) =
|
||||
self.tmpCommunityId = communityId
|
||||
self.tmpAuthenticationAction = AuthenticationAction.CommunitySharedAddressesJoin
|
||||
self.tmpAirdropAddress = airdropAddress
|
||||
self.tmpAddressesToShare = addressesToShare
|
||||
self.authenticate()
|
||||
|
||||
|
||||
proc getCommunityPublicKeyFromPrivateKey*(self: Controller, communityPrivateKey: string): string =
|
||||
result = self.communityService.getCommunityPublicKeyFromPrivateKey(communityPrivateKey)
|
||||
|
||||
proc asyncCheckPermissionsToJoin*(self: Controller, communityId: string, addressesToShare: seq[string]) =
|
||||
self.tmpCommunityId = communityId
|
||||
self.communityService.asyncCheckPermissionsToJoin(communityId, addressesToShare)
|
||||
|
||||
proc asyncCheckAllChannelsPermissions*(self: Controller, communityId: string, sharedAddresses: seq[string]) =
|
||||
self.tmpCommunityIdForChannelsPermisisons = communityId
|
||||
self.chatService.asyncCheckAllChannelsPermissions(communityId, sharedAddresses)
|
||||
|
||||
proc asyncGetRevealedAccountsForMember*(self: Controller, communityId, memberPubkey: string) =
|
||||
self.tmpCommunityIdForRevealedAccounts = communityId
|
||||
self.communityService.asyncGetRevealedAccountsForMember(communityId, memberPubkey)
|
||||
|
||||
proc generateJoiningCommunityRequestsForSigning*(self: Controller, memberPubKey: string, communityId: string,
|
||||
addressesToReveal: seq[string]): seq[SignParamsDto] =
|
||||
return self.communityService.generateJoiningCommunityRequestsForSigning(memberPubKey, communityId, addressesToReveal)
|
||||
|
||||
proc generateEditCommunityRequestsForSigning*(self: Controller, memberPubKey: string, communityId: string,
|
||||
addressesToReveal: seq[string]): seq[SignParamsDto] =
|
||||
return self.communityService.generateEditCommunityRequestsForSigning(memberPubKey, communityId, addressesToReveal)
|
||||
|
||||
proc signCommunityRequests*(self: Controller, communityId: string, signParams: seq[SignParamsDto]): seq[string] =
|
||||
return self.communityService.signCommunityRequests(communityId, signParams)
|
||||
|
||||
proc getKeypairByAccountAddress*(self: Controller, address: string): KeypairDto =
|
||||
return self.walletAccountService.getKeypairByAccountAddress(address)
|
||||
|
||||
proc getKeypairByKeyUid*(self: Controller, keyUid: string): KeypairDto =
|
||||
return self.walletAccountService.getKeypairByKeyUid(keyUid)
|
||||
|
||||
proc getKeypairs*(self: Controller): seq[KeypairDto] =
|
||||
return self.walletAccountService.getKeypairs()
|
||||
|
||||
proc disconnectKeycardReponseSignal(self: Controller) =
|
||||
self.events.disconnect(self.connectionKeycardResponse)
|
||||
|
||||
proc connectKeycardReponseSignal(self: Controller) =
|
||||
self.connectionKeycardResponse = self.events.onWithUUID(SIGNAL_KEYCARD_RESPONSE) do(e: Args):
|
||||
let args = KeycardLibArgs(e)
|
||||
self.disconnectKeycardReponseSignal()
|
||||
let currentFlow = self.keycardService.getCurrentFlow()
|
||||
if currentFlow != KCSFlowType.Sign:
|
||||
return
|
||||
let keyUid = self.silentSigningKeyUid
|
||||
let path = self.silentSigningPath
|
||||
let pin = self.silentSigningPin
|
||||
self.silentSigningKeyUid = ""
|
||||
self.silentSigningPath = ""
|
||||
self.silentSigningPin = ""
|
||||
self.delegate.onDataSigned(keyUid, path, args.flowEvent.txSignature.r, args.flowEvent.txSignature.s, args.flowEvent.txSignature.v, pin)
|
||||
|
||||
proc cancelCurrentFlow*(self: Controller) =
|
||||
self.keycardService.cancelCurrentFlow()
|
||||
# in most cases we're running another flow after canceling the current one,
|
||||
# this way we're giving to the keycard some time to cancel the current flow
|
||||
sleep(200)
|
||||
|
||||
proc runSignFlow(self: Controller, pin, path, dataToSign: string) =
|
||||
self.cancelCurrentFlow()
|
||||
self.connectKeycardReponseSignal()
|
||||
self.keycardService.startSignFlow(path, dataToSign, pin)
|
||||
|
||||
proc runSigningOnKeycard*(self: Controller, keyUid: string, path: string, dataToSign: string, pin: string) =
|
||||
var finalDataToSign = dataToSign
|
||||
if finalDataToSign.startsWith("0x"):
|
||||
finalDataToSign = finalDataToSign[2..^1]
|
||||
if pin.len == 0:
|
||||
let data = SharedKeycarModuleSigningArgs(uniqueIdentifier: UNIQUE_COMMUNITIES_MODULE_SIGNING_IDENTIFIER,
|
||||
keyUid: keyUid,
|
||||
path: path,
|
||||
dataToSign: finalDataToSign)
|
||||
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_SIGN_DATA, data)
|
||||
return
|
||||
self.silentSigningKeyUid = keyUid
|
||||
self.silentSigningPath = path
|
||||
self.silentSigningPin = pin
|
||||
self.runSignFlow(pin, path, finalDataToSign)
|
|
@ -159,10 +159,10 @@ method curatedCommunitiesLoadingFailed*(self: AccessInterface) {.base.} =
|
|||
method curatedCommunitiesLoaded*(self: AccessInterface, curatedCommunities: seq[CommunityDto]) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method communityInfoAlreadyRequested*(self: AccessInterface) {.base.} =
|
||||
method communityInfoAlreadyRequested*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onCommunityTokenMetadataAdded*(self: AccessInterface, communityId: string, tokenMetadata: CommunityTokensMetadataDto) {.base.} =
|
||||
method onCommunityTokenMetadataAdded*(self: AccessInterface, communityId: string, tokenMetadata: CommunityTokensMetadataDto) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onWalletAccountTokensRebuilt*(self: AccessInterface) {.base.} =
|
||||
|
@ -183,12 +183,20 @@ method shareCommunityChannelUrlWithData*(self: AccessInterface, communityId: str
|
|||
method onUserAuthenticated*(self: AccessInterface, pin: string, password: string, keyUid: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method requestToJoinCommunityWithAuthentication*(self: AccessInterface, communityId, ensName: string, addressesToShare: seq[string],
|
||||
airdropAddress: string) {.base.} =
|
||||
method onDataSigned*(self: AccessInterface, keyUid: string, path: string, r: string, s: string, v: string, pin: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method editSharedAddressesWithAuthentication*(self: AccessInterface, communityId: string, addressesToShare: seq[string], airdropAddress: string)
|
||||
{.base.} =
|
||||
method prepareKeypairsForSigning*(self: AccessInterface, communityId: string, ensName: string, addresses: string,
|
||||
airdropAddress: string, editMode: bool) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method signSharedAddressesForAllNonKeycardKeypairs*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method signSharedAddressesForKeypair*(self: AccessInterface, keyUid: string, pin: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method joinCommunityOrEditSharedAddresses*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method prepareTokenModelForCommunity*(self: AccessInterface, communityId: string) {.base.} =
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import NimQml, sequtils, tables, stint, chronicles, json
|
||||
import NimQml, strutils, sequtils, sugar, tables, stint, chronicles, json
|
||||
|
||||
import ./io_interface
|
||||
import ../io_interface as delegate_interface
|
||||
|
@ -12,21 +12,26 @@ import ./models/discord_channels_model
|
|||
import ./models/discord_file_list_model
|
||||
import ./models/discord_import_task_item
|
||||
import ./models/discord_import_tasks_model
|
||||
import ../../shared_models/[member_item, section_model, section_item, token_permissions_model, token_permission_item,
|
||||
token_list_item, token_list_model, token_criteria_item, token_criteria_model, token_permission_chat_list_model]
|
||||
import ../../../global/global_singleton
|
||||
import ../../../core/eventemitter
|
||||
import ../../../../app_service/common/types
|
||||
import ../../../../app_service/service/community/service as community_service
|
||||
import ../../../../app_service/service/contacts/service as contacts_service
|
||||
import ../../../../app_service/service/chat/service as chat_service
|
||||
import ../../../../app_service/service/network/service as networks_service
|
||||
import ../../../../app_service/service/transaction/service as transaction_service
|
||||
import ../../../../app_service/service/community_tokens/service as community_tokens_service
|
||||
import ../../../../app_service/service/token/service as token_service
|
||||
import ../../../../app_service/service/chat/dto/chat
|
||||
import app/modules/shared_models/[member_item, section_model, section_item, token_permissions_model, token_permission_item,
|
||||
token_list_item, token_list_model, token_criteria_item, token_criteria_model, token_permission_chat_list_model, keypair_model]
|
||||
import app/global/global_singleton
|
||||
import app/core/eventemitter
|
||||
import app_service/common/types
|
||||
import app_service/common/utils as common_utils
|
||||
import app_service/service/community/service as community_service
|
||||
import app_service/service/contacts/service as contacts_service
|
||||
import app_service/service/chat/service as chat_service
|
||||
import app_service/service/network/service as networks_service
|
||||
import app_service/service/transaction/service as transaction_service
|
||||
import app_service/service/community_tokens/service as community_tokens_service
|
||||
import app_service/service/token/service as token_service
|
||||
import app_service/service/wallet_account/service as wallet_account_service
|
||||
import app_service/service/chat/dto/chat
|
||||
import app_service/service/keycard/service as keycard_service
|
||||
import ./tokens/module as community_tokens_module
|
||||
|
||||
import app/modules/shared/keypairs
|
||||
|
||||
export io_interface
|
||||
|
||||
type
|
||||
|
@ -35,6 +40,41 @@ type
|
|||
ImportingInProgress
|
||||
ImportingError
|
||||
|
||||
type
|
||||
Action {.pure.} = enum
|
||||
None = 0,
|
||||
JoinCommunity
|
||||
EditSharedAddresses
|
||||
|
||||
type
|
||||
AddressToShareDetails = object
|
||||
keyUid: string
|
||||
address: string
|
||||
path: string
|
||||
isAirdropAddress: bool
|
||||
messageToBeSigned: string
|
||||
signature: string
|
||||
|
||||
type
|
||||
JoiningCommunityDetails = object
|
||||
communityId: string
|
||||
communityIdForChannelsPermisisons: string
|
||||
communityIdForRevealedAccounts: string
|
||||
ensName: string
|
||||
addressesToShare: OrderedTable[string, AddressToShareDetails] ## [address, AddressToShareDetails]
|
||||
profilePassword: string
|
||||
profilePin: string
|
||||
action: Action
|
||||
|
||||
proc clear(self: var JoiningCommunityDetails) =
|
||||
self = JoiningCommunityDetails()
|
||||
|
||||
proc allSigned(self: JoiningCommunityDetails): bool =
|
||||
for _, details in self.addressesToShare.pairs:
|
||||
if details.signature.len == 0:
|
||||
return false
|
||||
return true
|
||||
|
||||
type
|
||||
Module* = ref object of io_interface.AccessInterface
|
||||
delegate: delegate_interface.AccessInterface
|
||||
|
@ -46,6 +86,7 @@ type
|
|||
communityTokensModule: community_tokens_module.AccessInterface
|
||||
checkingPermissionToJoinInProgress: bool
|
||||
checkingAllChannelPermissionsInProgress: bool
|
||||
joiningCommunityDetails: JoiningCommunityDetails
|
||||
|
||||
# Forward declaration
|
||||
method setCommunityTags*(self: Module, communityTags: string)
|
||||
|
@ -62,6 +103,8 @@ proc newModule*(
|
|||
transactionService: transaction_service.Service,
|
||||
tokensService: token_service.Service,
|
||||
chatService: chat_service.Service,
|
||||
walletAccountService: wallet_account_service.Service,
|
||||
keycardService: keycard_service.Service,
|
||||
): Module =
|
||||
result = Module()
|
||||
result.delegate = delegate
|
||||
|
@ -76,6 +119,8 @@ proc newModule*(
|
|||
networksService,
|
||||
tokensService,
|
||||
chatService,
|
||||
walletAccountService,
|
||||
keycardService,
|
||||
)
|
||||
result.communityTokensModule = community_tokens_module.newCommunityTokensModule(result, events, communityTokensService, transactionService, networksService, communityService)
|
||||
result.moduleLoaded = false
|
||||
|
@ -89,6 +134,9 @@ method delete*(self: Module) =
|
|||
self.controller.delete
|
||||
self.communityTokensModule.delete
|
||||
|
||||
proc clean(self: Module) =
|
||||
self.joiningCommunityDetails.clear()
|
||||
|
||||
method load*(self: Module) =
|
||||
singletonInstance.engine.setRootContextProperty("communitiesModule", self.viewVariant)
|
||||
self.controller.init()
|
||||
|
@ -281,22 +329,27 @@ method createCommunity*(self: Module, name: string,
|
|||
pinMessageAllMembersEnabled: bool,
|
||||
bannerJsonStr: string) =
|
||||
self.controller.createCommunity(name, description, introMessage, outroMessage, access, color, tags,
|
||||
imagePath, aX, aY, bX, bY, historyArchiveSupportEnabled, pinMessageAllMembersEnabled,
|
||||
imagePath, aX, aY, bX, bY, historyArchiveSupportEnabled, pinMessageAllMembersEnabled,
|
||||
bannerJsonStr)
|
||||
|
||||
method communityMuted*(self: Module, communityId: string, muted: bool) =
|
||||
self.view.model().setMuted(communityId, muted)
|
||||
|
||||
method communityAccessRequested*(self: Module, communityId: string) =
|
||||
self.clean()
|
||||
self.view.communityAccessRequested(communityId)
|
||||
|
||||
method communityAccessFailed*(self: Module, communityId, error: string) =
|
||||
self.view.communityAccessFailed(communityId, error)
|
||||
method communityAccessFailed*(self: Module, communityId, err: string) =
|
||||
error "communities: ", err
|
||||
self.clean()
|
||||
self.view.communityAccessFailed(communityId, err)
|
||||
|
||||
method communityEditSharedAddressesSucceeded*(self: Module, communityId: string) =
|
||||
self.clean()
|
||||
self.view.communityEditSharedAddressesSucceeded(communityId)
|
||||
|
||||
method communityEditSharedAddressesFailed*(self: Module, communityId, error: string) =
|
||||
self.clean()
|
||||
self.view.communityEditSharedAddressesFailed(communityId, error)
|
||||
|
||||
method communityHistoryArchivesDownloadStarted*(self: Module, communityId: string) =
|
||||
|
@ -344,7 +397,7 @@ method communityImported*(self: Module, community: CommunityDto) =
|
|||
self.view.addOrUpdateItem(self.getCommunityItem(community))
|
||||
self.view.emitImportingCommunityStateChangedSignal(community.id, ImportCommunityState.Imported.int, errorMsg = "")
|
||||
|
||||
method communityDataImported*(self: Module, community: CommunityDto) =
|
||||
method communityDataImported*(self: Module, community: CommunityDto) =
|
||||
self.view.addItem(self.getCommunityItem(community))
|
||||
self.view.emitCommunityInfoRequestCompleted(community.id, "")
|
||||
|
||||
|
@ -364,7 +417,7 @@ method requestExtractDiscordChannelsAndCategories*(self: Module, filesToImport:
|
|||
|
||||
method requestImportDiscordCommunity*(self: Module, name: string, description, introMessage, outroMessage: string, access: int,
|
||||
color: string, tags: string, imagePath: string, aX: int, aY: int, bX: int, bY: int,
|
||||
historyArchiveSupportEnabled: bool, pinMessageAllMembersEnabled: bool, filesToImport: seq[string],
|
||||
historyArchiveSupportEnabled: bool, pinMessageAllMembersEnabled: bool, filesToImport: seq[string],
|
||||
fromTimestamp: int) =
|
||||
self.view.setDiscordImportHasCommunityImage(imagePath != "")
|
||||
self.controller.requestImportDiscordCommunity(name, description, introMessage, outroMessage, access, color, tags, imagePath, aX, aY, bX, bY, historyArchiveSupportEnabled, pinMessageAllMembersEnabled, filesToImport, fromTimestamp)
|
||||
|
@ -534,32 +587,166 @@ method shareCommunityChannelUrlWithChatKey*(self: Module, communityId: string, c
|
|||
method shareCommunityChannelUrlWithData*(self: Module, communityId: string, chatId: string): string =
|
||||
return self.controller.shareCommunityChannelUrlWithData(communityId, chatId)
|
||||
|
||||
method signRevealedAddressesThatBelongToRegularKeypairs(self: Module): bool =
|
||||
var signingParams: seq[SignParamsDto]
|
||||
for address, details in self.joiningCommunityDetails.addressesToShare.pairs:
|
||||
if details.signature.len > 0:
|
||||
continue
|
||||
let keypair = self.controller.getKeypairByAccountAddress(address)
|
||||
if keypair.isNil:
|
||||
self.communityAccessFailed(self.joiningCommunityDetails.communityId, "cannot resolve keypair for address" & address)
|
||||
return false
|
||||
if keypair.migratedToKeycard():
|
||||
continue
|
||||
signingParams.add(
|
||||
SignParamsDto(
|
||||
address: address,
|
||||
data: details.messageToBeSigned,
|
||||
password: common_utils.hashPassword(self.joiningCommunityDetails.profilePassword),
|
||||
)
|
||||
)
|
||||
if signingParams.len == 0:
|
||||
return true
|
||||
# signatures are returned in the same order as signingParams
|
||||
let signatures = self.controller.signCommunityRequests(self.joiningCommunityDetails.communityId, signingParams)
|
||||
for i in 0 ..< len(signingParams):
|
||||
self.joiningCommunityDetails.addressesToShare[signingParams[i].address].signature = signatures[i]
|
||||
return true
|
||||
|
||||
method onUserAuthenticated*(self: Module, pin: string, password: string, keyUid: string) =
|
||||
if password == "" and pin == "":
|
||||
self.view.userAuthenticationCanceled()
|
||||
self.controller.userAuthenticationCanceled()
|
||||
info "unsuccesful authentication"
|
||||
self.clean()
|
||||
return
|
||||
|
||||
self.controller.userAuthenticated(password)
|
||||
self.joiningCommunityDetails.profilePassword = password
|
||||
self.joiningCommunityDetails.profilePin = pin
|
||||
if self.signRevealedAddressesThatBelongToRegularKeypairs():
|
||||
self.view.sendSharedAddressesForAllNonKeycardKeypairsSignedSignal()
|
||||
|
||||
method requestToJoinCommunityWithAuthentication*(self: Module, communityId, ensName: string, addressesToShare: seq[string],
|
||||
airdropAddress: string) =
|
||||
self.controller.authenticateToRequestToJoinCommunity(communityId, ensName, addressesToShare, airdropAddress)
|
||||
method onDataSigned*(self: Module, keyUid: string, path: string, r: string, s: string, v: string, pin: string) =
|
||||
if keyUid.len == 0 or path.len == 0 or r.len == 0 or s.len == 0 or v.len == 0 or pin.len == 0:
|
||||
# being here is not an error
|
||||
return
|
||||
|
||||
method editSharedAddressesWithAuthentication*(self: Module, communityId: string, addressesToShare: seq[string], airdropAddress: string) =
|
||||
self.controller.authenticateToEditSharedAddresses(communityId, addressesToShare, airdropAddress)
|
||||
for address, details in self.joiningCommunityDetails.addressesToShare.pairs:
|
||||
if details.keyUid != keyUid or details.path != path:
|
||||
continue
|
||||
self.joiningCommunityDetails.addressesToShare[address].signature = "0x" & r & s & v
|
||||
break
|
||||
self.signSharedAddressesForKeypair(keyUid, pin)
|
||||
|
||||
method prepareKeypairsForSigning*(self: Module, communityId, ensName: string, addresses: string,
|
||||
airdropAddress: string, editMode: bool) =
|
||||
var addressesToShare: seq[string]
|
||||
try:
|
||||
addressesToShare = map(parseJson(addresses).getElems(), proc(x:JsonNode):string = x.getStr())
|
||||
except Exception as e:
|
||||
self.communityAccessFailed(communityId, "error parsing addresses: " & e.msg)
|
||||
return
|
||||
|
||||
let allKeypairs = keypairs.buildKeyPairsList(self.controller.getKeypairs(), excludeAlreadyMigratedPairs = false,
|
||||
excludePrivateKeyKeypairs = false)
|
||||
for it in allKeypairs:
|
||||
let addressesToRemove = it.getAccountsModel().getItems()
|
||||
.map(x => x.getAddress())
|
||||
.filter(x => addressesToShare.filter(y => cmpIgnoreCase(y, x) == 0).len == 0)
|
||||
for address in addressesToRemove:
|
||||
it.removeAccountByAddress(address)
|
||||
let keypairsForSigning = allKeypairs.filter(x => x.getAccountsModel().getCount() > 0)
|
||||
self.view.setKeypairsSigningModelItems(keypairsForSigning)
|
||||
|
||||
self.joiningCommunityDetails.communityId = communityId
|
||||
|
||||
var signingParams: seq[SignParamsDto]
|
||||
if editMode:
|
||||
self.joiningCommunityDetails.action = Action.EditSharedAddresses
|
||||
signingParams = self.controller.generateEditCommunityRequestsForSigning(
|
||||
singletonInstance.userProfile.getPubKey(), communityId, addressesToShare)
|
||||
else:
|
||||
self.joiningCommunityDetails.action = Action.JoinCommunity
|
||||
self.joiningCommunityDetails.ensName = ensName
|
||||
signingParams = self.controller.generateJoiningCommunityRequestsForSigning(
|
||||
singletonInstance.userProfile.getPubKey(), communityId, addressesToShare)
|
||||
|
||||
let findKeyUidAndPathForAddress = proc (items: seq[KeyPairItem], address: string): tuple[keyUid: string, path: string] =
|
||||
for it in items:
|
||||
for acc in it.getAccountsModel().getItems():
|
||||
if cmpIgnoreCase(acc.getAddress(), address) == 0:
|
||||
return (it.getKeyUid(), acc.getPath())
|
||||
return ("", "")
|
||||
|
||||
for param in signingParams:
|
||||
let (keyUid, path) = findKeyUidAndPathForAddress(keypairsForSigning, param.address)
|
||||
let details = AddressToShareDetails(
|
||||
keyUid: keyUid,
|
||||
address: param.address,
|
||||
path: path,
|
||||
isAirdropAddress: if cmpIgnoreCase(param.address, airdropAddress) == 0: true else: false,
|
||||
messageToBeSigned: param.data
|
||||
)
|
||||
self.joiningCommunityDetails.addressesToShare[param.address] = details
|
||||
|
||||
method signSharedAddressesForAllNonKeycardKeypairs*(self: Module) =
|
||||
self.controller.authenticate()
|
||||
|
||||
# if pin is provided we're signing on a keycard silently
|
||||
method signSharedAddressesForKeypair*(self: Module, keyUid: string, pin: string) =
|
||||
let keypair = self.controller.getKeypairByKeyUid(keyUid)
|
||||
if keypair.isNil:
|
||||
self.communityAccessFailed(self.joiningCommunityDetails.communityId, "cannot resolve keypair for keyUid " & keyUid)
|
||||
return
|
||||
for acc in keypair.accounts:
|
||||
for address, details in self.joiningCommunityDetails.addressesToShare.pairs:
|
||||
if cmpIgnoreCase(address, acc.address) != 0:
|
||||
continue
|
||||
if details.signature.len > 0:
|
||||
continue
|
||||
self.controller.runSigningOnKeycard(keyUid, details.path, details.messageToBeSigned, pin)
|
||||
return
|
||||
self.view.keypairsSigningModel().setOwnershipVerified(keyUid, true)
|
||||
|
||||
method joinCommunityOrEditSharedAddresses*(self: Module) =
|
||||
if not self.joiningCommunityDetails.allSigned():
|
||||
self.communityAccessFailed(self.joiningCommunityDetails.communityId, "unexpected call to join community function before all addresses are signed")
|
||||
return
|
||||
var
|
||||
addressesToShare: seq[string]
|
||||
airdropAddress: string
|
||||
signatures: seq[string]
|
||||
|
||||
for _, details in self.joiningCommunityDetails.addressesToShare.pairs:
|
||||
addressesToShare.add(details.address)
|
||||
if details.isAirdropAddress:
|
||||
airdropAddress = details.address
|
||||
signatures.add(details.signature)
|
||||
|
||||
if self.joiningCommunityDetails.action == Action.JoinCommunity:
|
||||
self.controller.asyncRequestToJoinCommunity(self.joiningCommunityDetails.communityId,
|
||||
self.joiningCommunityDetails.ensName,
|
||||
addressesToShare,
|
||||
airdropAddress,
|
||||
signatures)
|
||||
return
|
||||
if self.joiningCommunityDetails.action == Action.EditSharedAddresses:
|
||||
self.controller.asyncEditSharedAddresses(self.joiningCommunityDetails.communityId,
|
||||
addressesToShare,
|
||||
airdropAddress,
|
||||
signatures)
|
||||
return
|
||||
self.communityAccessFailed(self.joiningCommunityDetails.communityId, "unexpected action")
|
||||
|
||||
method getCommunityPublicKeyFromPrivateKey*(self: Module, communityPrivateKey: string): string =
|
||||
result = self.controller.getCommunityPublicKeyFromPrivateKey(communityPrivateKey)
|
||||
|
||||
method checkPermissions*(self: Module, communityId: string, sharedAddresses: seq[string]) =
|
||||
self.joiningCommunityDetails.communityIdForChannelsPermisisons = communityId
|
||||
self.controller.asyncCheckPermissionsToJoin(communityId, sharedAddresses)
|
||||
self.controller.asyncCheckAllChannelsPermissions(communityId, sharedAddresses)
|
||||
self.view.setCheckingPermissionsInProgress(inProgress = true)
|
||||
|
||||
method prepareTokenModelForCommunity*(self: Module, communityId: string) =
|
||||
self.joiningCommunityDetails.communityIdForRevealedAccounts = communityId
|
||||
self.controller.asyncGetRevealedAccountsForMember(communityId, singletonInstance.userProfile.getPubKey())
|
||||
|
||||
let community = self.controller.getCommunityById(communityId)
|
||||
|
@ -633,12 +820,16 @@ method onCommunityCheckAllChannelPermissionsFailed*(self: Module, communityId: s
|
|||
|
||||
method onCommunityCheckPermissionsToJoinResponse*(self: Module, communityId: string,
|
||||
checkPermissionsToJoinResponse: CheckPermissionsToJoinResponseDto) =
|
||||
if self.joiningCommunityDetails.communityId != communityId:
|
||||
return
|
||||
self.applyPermissionResponse(communityId, checkPermissionsToJoinResponse.permissions)
|
||||
self.checkingPermissionToJoinInProgress = false
|
||||
self.updateCheckingPermissionsInProgressIfNeeded(inProgress = false)
|
||||
|
||||
method onCommunityCheckAllChannelsPermissionsResponse*(self: Module, communityId: string,
|
||||
checkChannelPermissionsResponse: CheckAllChannelsPermissionsResponseDto) =
|
||||
if self.joiningCommunityDetails.communityIdForChannelsPermisisons != communityId:
|
||||
return
|
||||
self.checkingAllChannelPermissionsInProgress = false
|
||||
self.updateCheckingPermissionsInProgressIfNeeded(inProgress = false)
|
||||
for _, channelPermissionResponse in checkChannelPermissionsResponse.channels:
|
||||
|
@ -653,6 +844,8 @@ method onCommunityCheckAllChannelsPermissionsResponse*(self: Module, communityId
|
|||
|
||||
method onCommunityMemberRevealedAccountsLoaded*(self: Module, communityId, memberPubkey: string,
|
||||
revealedAccounts: seq[RevealedAccount]) =
|
||||
if self.joiningCommunityDetails.communityIdForRevealedAccounts != communityId:
|
||||
return
|
||||
if memberPubkey == singletonInstance.userProfile.getPubKey():
|
||||
var addresses: seq[string] = @[]
|
||||
var airdropAddress = ""
|
||||
|
|
|
@ -2,7 +2,7 @@ import NimQml, json, strutils, sequtils
|
|||
|
||||
import ./io_interface
|
||||
import ../../shared_models/[section_model, section_item, token_list_model, token_list_item,
|
||||
token_permissions_model]
|
||||
token_permissions_model, keypair_model]
|
||||
import ./models/curated_community_model
|
||||
import ./models/discord_file_list_model
|
||||
import ./models/discord_file_item
|
||||
|
@ -55,6 +55,8 @@ QtObject:
|
|||
checkingPermissionsInProgress: bool
|
||||
myRevealedAddressesStringForCurrentCommunity: string
|
||||
myRevealedAirdropAddressForCurrentCommunity: string
|
||||
keypairsSigningModel: KeyPairModel
|
||||
keypairsSigningModelVariant: QVariant
|
||||
|
||||
proc delete*(self: View) =
|
||||
self.model.delete
|
||||
|
@ -75,6 +77,10 @@ QtObject:
|
|||
self.tokenListModelVariant.delete
|
||||
self.collectiblesListModel.delete
|
||||
self.collectiblesListModelVariant.delete
|
||||
if not self.keypairsSigningModel.isNil:
|
||||
self.keypairsSigningModel.delete
|
||||
if not self.keypairsSigningModelVariant.isNil:
|
||||
self.keypairsSigningModelVariant.delete
|
||||
|
||||
self.QObject.delete
|
||||
|
||||
|
@ -318,6 +324,15 @@ QtObject:
|
|||
proc prepareTokenModelForCommunity(self: View, communityId: string) {.slot.} =
|
||||
self.delegate.prepareTokenModelForCommunity(communityId)
|
||||
|
||||
proc signSharedAddressesForAllNonKeycardKeypairs*(self: View) {.slot.} =
|
||||
self.delegate.signSharedAddressesForAllNonKeycardKeypairs()
|
||||
|
||||
proc signSharedAddressesForKeypair*(self: View, keyUid: string) {.slot.} =
|
||||
self.delegate.signSharedAddressesForKeypair(keyUid, pin = "")
|
||||
|
||||
proc joinCommunityOrEditSharedAddresses*(self: View) {.slot.} =
|
||||
self.delegate.joinCommunityOrEditSharedAddresses()
|
||||
|
||||
proc checkPermissions*(self: View, communityId: string, addressesToShare: string) {.slot.} =
|
||||
try:
|
||||
let sharedAddresses = map(parseJson(addressesToShare).getElems(), proc(x:JsonNode):string = x.getStr())
|
||||
|
@ -460,7 +475,7 @@ QtObject:
|
|||
historyArchiveSupportEnabled: bool,
|
||||
pinMessageAllMembersEnabled: bool, bannerJsonStr: string) {.slot.} =
|
||||
self.delegate.createCommunity(name, description, introMessage, outroMessage, access, color, tags,
|
||||
imagePath, aX, aY, bX, bY, historyArchiveSupportEnabled, pinMessageAllMembersEnabled,
|
||||
imagePath, aX, aY, bX, bY, historyArchiveSupportEnabled, pinMessageAllMembersEnabled,
|
||||
bannerJsonStr)
|
||||
|
||||
proc clearFileList*(self: View) {.slot.} =
|
||||
|
@ -673,25 +688,9 @@ QtObject:
|
|||
proc shareCommunityChannelUrlWithData*(self: View, communityId: string, chatId: string): string {.slot.} =
|
||||
return self.delegate.shareCommunityChannelUrlWithData(communityId, chatId)
|
||||
|
||||
proc userAuthenticationCanceled*(self: View) {.signal.}
|
||||
|
||||
proc requestToJoinCommunityWithAuthentication*(self: View, communityId: string, ensName: string) {.slot.} =
|
||||
self.delegate.requestToJoinCommunityWithAuthentication(communityId, ensName, @[], "")
|
||||
|
||||
proc requestToJoinCommunityWithAuthenticationWithSharedAddresses*(self: View, communityId: string, ensName: string,
|
||||
addressesToShare: string, airdropAddress: string) {.slot.} =
|
||||
try:
|
||||
let addressesArray = map(parseJson(addressesToShare).getElems(), proc(x:JsonNode):string = x.getStr())
|
||||
self.delegate.requestToJoinCommunityWithAuthentication(communityId, ensName, addressesArray, airdropAddress)
|
||||
except Exception as e:
|
||||
echo "Error requesting to join community with authentication and shared addresses: ", e.msg
|
||||
|
||||
proc editSharedAddressesWithAuthentication*(self: View, communityId: string, addressesToShare: string, airdropAddress: string) {.slot.} =
|
||||
try:
|
||||
let addressesArray = map(parseJson(addressesToShare).getElems(), proc(x:JsonNode):string = x.getStr())
|
||||
self.delegate.editSharedAddressesWithAuthentication(communityId, addressesArray, airdropAddress)
|
||||
except Exception as e:
|
||||
echo "Error editing shared addresses with authentication: ", e.msg
|
||||
proc prepareKeypairsForSigning*(self: View, communityId: string, ensName: string, addresses: string,
|
||||
airdropAddress: string, editMode: bool) {.slot.} =
|
||||
self.delegate.prepareKeypairsForSigning(communityId, ensName, addresses, airdropAddress, editMode)
|
||||
|
||||
proc getCommunityPublicKeyFromPrivateKey*(self: View, communityPrivateKey: string): string {.slot.} =
|
||||
result = self.delegate.getCommunityPublicKeyFromPrivateKey(communityPrivateKey)
|
||||
|
@ -731,3 +730,25 @@ QtObject:
|
|||
QtProperty[bool] requirementsCheckPending:
|
||||
read = getCheckingPermissionsInProgress
|
||||
notify = checkingPermissionsInProgressChanged
|
||||
|
||||
proc keypairsSigningModel*(self: View): KeyPairModel =
|
||||
return self.keypairsSigningModel
|
||||
|
||||
proc keypairsSigningModelChanged*(self: View) {.signal.}
|
||||
proc getKeypairsSigningModel(self: View): QVariant {.slot.} =
|
||||
return newQVariant(self.keypairsSigningModel)
|
||||
QtProperty[QVariant] keypairsSigningModel:
|
||||
read = getKeypairsSigningModel
|
||||
notify = keypairsSigningModelChanged
|
||||
|
||||
proc setKeypairsSigningModelItems*(self: View, items: seq[KeyPairItem]) =
|
||||
if self.keypairsSigningModel.isNil:
|
||||
self.keypairsSigningModel = newKeyPairModel()
|
||||
if self.keypairsSigningModelVariant.isNil:
|
||||
self.keypairsSigningModelVariant = newQVariant(self.keypairsSigningModel)
|
||||
self.keypairsSigningModel.setItems(items)
|
||||
self.keypairsSigningModelChanged()
|
||||
|
||||
proc sharedAddressesForAllNonKeycardKeypairsSigned(self: View) {.signal.}
|
||||
proc sendSharedAddressesForAllNonKeycardKeypairsSignedSignal*(self: View) =
|
||||
self.sharedAddressesForAllNonKeycardKeypairsSigned()
|
|
@ -28,6 +28,7 @@ QtObject:
|
|||
syncedFrom: string
|
||||
accounts: KeyPairAccountModel
|
||||
observedAccount: KeyPairAccountItem
|
||||
ownershipVerified: bool
|
||||
|
||||
proc setup*(self: KeyPairItem,
|
||||
keyUid: string,
|
||||
|
@ -40,7 +41,8 @@ QtObject:
|
|||
derivedFrom: string,
|
||||
lastUsedDerivationIndex: int,
|
||||
migratedToKeycard: bool,
|
||||
syncedFrom: string
|
||||
syncedFrom: string,
|
||||
ownershipVerified: bool
|
||||
) =
|
||||
self.QObject.setup
|
||||
self.keyUid = keyUid
|
||||
|
@ -54,6 +56,7 @@ QtObject:
|
|||
self.lastUsedDerivationIndex = lastUsedDerivationIndex
|
||||
self.migratedToKeycard = migratedToKeycard
|
||||
self.syncedFrom = syncedFrom
|
||||
self.ownershipVerified = ownershipVerified
|
||||
self.accounts = newKeyPairAccountModel()
|
||||
|
||||
proc delete*(self: KeyPairItem) =
|
||||
|
@ -69,10 +72,11 @@ QtObject:
|
|||
derivedFrom = "",
|
||||
lastUsedDerivationIndex = 0,
|
||||
migratedToKeycard = false,
|
||||
syncedFrom = ""): KeyPairItem =
|
||||
syncedFrom = "",
|
||||
ownershipVerified = false): KeyPairItem =
|
||||
new(result, delete)
|
||||
result.setup(keyUid, pubKey, locked, name, image, icon, pairType, derivedFrom, lastUsedDerivationIndex,
|
||||
migratedToKeycard, syncedFrom)
|
||||
migratedToKeycard, syncedFrom, ownershipVerified)
|
||||
|
||||
proc `$`*(self: KeyPairItem): string =
|
||||
result = fmt"""KeyPairItem[
|
||||
|
@ -88,7 +92,8 @@ QtObject:
|
|||
migratedToKeycard: {self.migratedToKeycard},
|
||||
operability: {self.operability},
|
||||
syncedFrom: {self.syncedFrom},
|
||||
accounts: {$self.accounts}
|
||||
ownershipVerified: {$self.ownershipVerified}
|
||||
accounts: {$self.accounts},
|
||||
]"""
|
||||
|
||||
proc keyUidChanged*(self: KeyPairItem) {.signal.}
|
||||
|
@ -224,6 +229,17 @@ QtObject:
|
|||
write = setSyncedFrom
|
||||
notify = syncedFromChanged
|
||||
|
||||
proc ownershipVerifiedChanged*(self: KeyPairItem) {.signal.}
|
||||
proc getOwnershipVerified*(self: KeyPairItem): bool {.slot.} =
|
||||
return self.ownershipVerified
|
||||
proc setOwnershipVerified*(self: KeyPairItem, value: bool) {.slot.} =
|
||||
self.ownershipVerified = value
|
||||
self.ownershipVerifiedChanged()
|
||||
QtProperty[bool] ownershipVerified:
|
||||
read = getOwnershipVerified
|
||||
write = setOwnershipVerified
|
||||
notify = ownershipVerifiedChanged
|
||||
|
||||
proc observedAccountChanged*(self: KeyPairItem) {.signal.}
|
||||
proc getObservedAccountAsVariant*(self: KeyPairItem): QVariant {.slot.} =
|
||||
return newQVariant(self.observedAccount)
|
||||
|
@ -288,4 +304,5 @@ QtObject:
|
|||
self.setMigratedToKeycard(item.getMigratedToKeycard())
|
||||
self.setLastUsedDerivationIndex(item.getLastUsedDerivationIndex())
|
||||
self.setAccounts(item.getAccountsModel().getItems())
|
||||
self.setOwnershipVerified(item.getOwnershipVerified())
|
||||
self.setLastAccountAsObservedAccount()
|
||||
|
|
|
@ -109,6 +109,12 @@ QtObject:
|
|||
return
|
||||
item.setName(name)
|
||||
|
||||
proc setOwnershipVerified*(self: KeyPairModel, keyUid: string, ownershipVerified: bool) =
|
||||
let item = self.findItemByKeyUid(keyUid)
|
||||
if item.isNil:
|
||||
return
|
||||
item.setOwnershipVerified(ownershipVerified)
|
||||
|
||||
proc setBalanceForAddress*(self: KeyPairModel, address: string, balance: CurrencyAmount) =
|
||||
for item in self.items:
|
||||
item.setBalanceForAddress(address, balance)
|
||||
|
|
|
@ -25,7 +25,7 @@ QtObject:
|
|||
): KeycardItem =
|
||||
new(result, delete)
|
||||
result.KeyPairItem.setup(keyUid, pubKey, locked, name, image, icon, pairType, derivedFrom,lastUsedDerivationIndex,
|
||||
migratedToKeycard, syncedFrom = "")
|
||||
migratedToKeycard, syncedFrom = "", ownershipVerified = false)
|
||||
result.keycardUid = keycardUid
|
||||
|
||||
proc `$`*(self: KeycardItem): string =
|
||||
|
|
|
@ -157,15 +157,15 @@ type
|
|||
AsyncRequestToJoinCommunityTaskArg = ref object of QObjectTaskArg
|
||||
communityId: string
|
||||
ensName: string
|
||||
password: string
|
||||
addressesToShare: seq[string]
|
||||
signatures: seq[string]
|
||||
airdropAddress: string
|
||||
|
||||
const asyncRequestToJoinCommunityTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncRequestToJoinCommunityTaskArg](argEncoded)
|
||||
try:
|
||||
let response = status_go.requestToJoinCommunity(arg.communityId, arg.ensName, arg.password, arg.addressesToShare,
|
||||
arg.airdropAddress)
|
||||
let response = status_go.requestToJoinCommunity(arg.communityId, arg.ensName, arg.addressesToShare,
|
||||
arg.signatures, arg.airdropAddress)
|
||||
arg.finish(%* {
|
||||
"response": response,
|
||||
"communityId": arg.communityId,
|
||||
|
@ -180,14 +180,14 @@ const asyncRequestToJoinCommunityTask: Task = proc(argEncoded: string) {.gcsafe,
|
|||
type
|
||||
AsyncEditSharedAddressesTaskArg = ref object of QObjectTaskArg
|
||||
communityId: string
|
||||
password: string
|
||||
addressesToShare: seq[string]
|
||||
signatures: 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,
|
||||
let response = status_go.editSharedAddresses(arg.communityId, arg.addressesToShare, arg.signatures,
|
||||
arg.airdropAddress)
|
||||
arg.finish(%* {
|
||||
"response": response,
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import json
|
||||
|
||||
include app_service/common/json_utils
|
||||
|
||||
type SignParamsDto* = object
|
||||
data*: string
|
||||
address*: string
|
||||
password*: string
|
||||
|
||||
proc toSignParamsDto*(jsonObj: JsonNode): SignParamsDto =
|
||||
result = SignParamsDto()
|
||||
discard jsonObj.getProp("data", result.data)
|
||||
discard jsonObj.getProp("account", result.address)
|
||||
discard jsonObj.getProp("password", result.password)
|
||||
|
||||
proc toJson*(self: SignParamsDto): JsonNode =
|
||||
return %* {
|
||||
"data": $self.data,
|
||||
"account": $self.address,
|
||||
"password": $self.password
|
||||
}
|
|
@ -2,6 +2,7 @@ import NimQml, Tables, json, sequtils, std/sets, std/algorithm, strformat, strut
|
|||
import json_serialization/std/tables as ser_tables
|
||||
|
||||
import ./dto/community as community_dto
|
||||
import ./dto/sign_params as sign_params_dto
|
||||
import ../community_tokens/dto/community_token as community_token_dto
|
||||
|
||||
import ../activity_center/service as activity_center_service
|
||||
|
@ -20,7 +21,7 @@ import ../../../app_service/common/utils
|
|||
|
||||
include ./async_tasks
|
||||
|
||||
export community_dto
|
||||
export community_dto, sign_params_dto
|
||||
|
||||
logScope:
|
||||
topics = "community-service"
|
||||
|
@ -1503,8 +1504,52 @@ QtObject:
|
|||
error: errMsg,
|
||||
))
|
||||
|
||||
proc asyncRequestToJoinCommunity*(self: Service, communityId: string, ensName: string, password: string,
|
||||
addressesToShare: seq[string], airdropAddress: string) =
|
||||
proc generateJoiningCommunityRequestsForSigning*(self: Service, memberPubKey: string, communityId: string,
|
||||
addressesToReveal: seq[string]): seq[SignParamsDto] =
|
||||
try:
|
||||
let response = status_go.generateJoiningCommunityRequestsForSigning(memberPubKey, communityId, addressesToReveal)
|
||||
if not response.error.isNil:
|
||||
raise newException(RpcException, response.error.message)
|
||||
result = map(response.result.getElems(), x => x.toSignParamsDto())
|
||||
except Exception as e:
|
||||
error "Error while generating join community request", msg = e.msg
|
||||
self.events.emit(SIGNAL_COMMUNITY_MY_REQUEST_FAILED, CommunityRequestFailedArgs(
|
||||
communityId: communityId,
|
||||
error: e.msg
|
||||
))
|
||||
|
||||
proc generateEditCommunityRequestsForSigning*(self: Service, memberPubKey: string, communityId: string,
|
||||
addressesToReveal: seq[string]): seq[SignParamsDto] =
|
||||
try:
|
||||
let response = status_go.generateEditCommunityRequestsForSigning(memberPubKey, communityId, addressesToReveal)
|
||||
if not response.error.isNil:
|
||||
raise newException(RpcException, response.error.message)
|
||||
result = map(response.result.getElems(), x => x.toSignParamsDto())
|
||||
except Exception as e:
|
||||
error "Error while generating edit community request", msg = e.msg
|
||||
self.events.emit(SIGNAL_COMMUNITY_EDIT_SHARED_ADDRESSES_FAILED, CommunityRequestFailedArgs(
|
||||
communityId: communityId,
|
||||
error: e.msg
|
||||
))
|
||||
|
||||
proc signCommunityRequests*(self: Service, communityId: string, signParams: seq[SignParamsDto]): seq[string] =
|
||||
try:
|
||||
var data = %* []
|
||||
for param in signParams:
|
||||
data.add(param.toJson())
|
||||
let response = status_go.signData(data)
|
||||
if not response.error.isNil:
|
||||
raise newException(RpcException, response.error.message)
|
||||
result = map(response.result.getElems(), x => x.getStr())
|
||||
except Exception as e:
|
||||
error "Error while signing joining community request", msg = e.msg
|
||||
self.events.emit(SIGNAL_COMMUNITY_MY_REQUEST_FAILED, CommunityRequestFailedArgs(
|
||||
communityId: communityId,
|
||||
error: e.msg
|
||||
))
|
||||
|
||||
proc asyncRequestToJoinCommunity*(self: Service, communityId: string, ensName: string, addressesToShare: seq[string],
|
||||
airdropAddress: string, signatures: seq[string]) =
|
||||
try:
|
||||
let arg = AsyncRequestToJoinCommunityTaskArg(
|
||||
tptr: cast[ByteAddress](asyncRequestToJoinCommunityTask),
|
||||
|
@ -1512,8 +1557,8 @@ QtObject:
|
|||
slot: "onAsyncRequestToJoinCommunityDone",
|
||||
communityId: communityId,
|
||||
ensName: ensName,
|
||||
password: if password != "": utils.hashPassword(password) else: "",
|
||||
addressesToShare: addressesToShare,
|
||||
signatures: signatures,
|
||||
airdropAddress: airdropAddress,
|
||||
)
|
||||
self.threadpool.start(arg)
|
||||
|
@ -1539,15 +1584,15 @@ QtObject:
|
|||
error: e.msg
|
||||
))
|
||||
|
||||
proc asyncEditSharedAddresses*(self: Service, communityId: string, password: string, addressesToShare: seq[string],
|
||||
airdropAddress: string) =
|
||||
proc asyncEditSharedAddresses*(self: Service, communityId: string, addressesToShare: seq[string], airdropAddress: string,
|
||||
signatures: seq[string]) =
|
||||
let arg = AsyncEditSharedAddressesTaskArg(
|
||||
tptr: cast[ByteAddress](asyncEditSharedAddressesTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onAsyncEditSharedAddressesDone",
|
||||
communityId: communityId,
|
||||
password: if password != "": utils.hashPassword(password) else: "",
|
||||
addressesToShare: addressesToShare,
|
||||
signatures: signatures,
|
||||
airdropAddress: airdropAddress,
|
||||
)
|
||||
self.threadpool.start(arg)
|
||||
|
|
|
@ -346,7 +346,7 @@ QtObject:
|
|||
self.currentFlow = KCSFlowType.StoreMetadata
|
||||
self.startFlow(payload)
|
||||
|
||||
proc startSignFlow*(self: Service, bip44Path: string, txHash: string, pin: string) =
|
||||
proc startSignFlow*(self: Service, bip44Path: string, txHash: string, pin: string = "") =
|
||||
var payload = %* {
|
||||
RequestParamTXHash: EmptyTxHash,
|
||||
RequestParamBIP44Path: DefaultBIP44Path
|
||||
|
|
|
@ -31,31 +31,54 @@ proc getAllCommunities*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
|||
proc spectateCommunity*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
result = callPrivateRPC("spectateCommunity".prefix, %*[communityId])
|
||||
|
||||
proc generateJoiningCommunityRequestsForSigning*(
|
||||
memberPubKey: string,
|
||||
communityId: string,
|
||||
addressesToReveal: seq[string]
|
||||
): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %*[memberPubKey, communityId, addressesToReveal]
|
||||
result = callPrivateRPC("generateJoiningCommunityRequestsForSigning".prefix, payload)
|
||||
|
||||
proc generateEditCommunityRequestsForSigning*(
|
||||
memberPubKey: string,
|
||||
communityId: string,
|
||||
addressesToReveal: seq[string]
|
||||
): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let payload = %*[memberPubKey, communityId, addressesToReveal]
|
||||
result = callPrivateRPC("generateEditCommunityRequestsForSigning".prefix, payload)
|
||||
|
||||
## `signParams` represents a json array of SignParamsDto.
|
||||
proc signData*(signParams: JsonNode): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
if signParams.kind != JArray:
|
||||
raise newException(Exception, "signParams must be an array")
|
||||
let payload = %*[signParams]
|
||||
result = callPrivateRPC("signData".prefix, payload)
|
||||
|
||||
proc requestToJoinCommunity*(
|
||||
communityId: string,
|
||||
ensName: string,
|
||||
password: string,
|
||||
addressesToShare: seq[string],
|
||||
signatures: seq[string],
|
||||
airdropAddress: string,
|
||||
): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
result = callPrivateRPC("requestToJoinCommunity".prefix, %*[{
|
||||
"communityId": communityId,
|
||||
"ensName": ensName,
|
||||
"password": password,
|
||||
"addressesToReveal": addressesToShare,
|
||||
"signatures": signatures,
|
||||
"airdropAddress": airdropAddress,
|
||||
}])
|
||||
|
||||
proc editSharedAddresses*(
|
||||
communityId: string,
|
||||
password: string,
|
||||
addressesToShare: seq[string],
|
||||
signatures: seq[string],
|
||||
airdropAddress: string,
|
||||
): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
result = callPrivateRPC("editSharedAddressesForCommunity".prefix, %*[{
|
||||
"communityId": communityId,
|
||||
"password": password,
|
||||
"addressesToReveal": addressesToShare,
|
||||
"signatures": signatures,
|
||||
"airdropAddress": airdropAddress,
|
||||
}])
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ StatusModal {
|
|||
|
||||
property alias stackItems: stackLayout.children
|
||||
property alias currentIndex: stackLayout.currentIndex
|
||||
property alias replaceLoader: replaceLoader
|
||||
property alias replaceItem: replaceLoader.sourceComponent
|
||||
property alias subHeaderItem: subHeaderLoader.sourceComponent
|
||||
|
||||
|
|
|
@ -229,8 +229,22 @@ StackLayout {
|
|||
assetsModel: root.rootStore.assetsModel
|
||||
collectiblesModel: root.rootStore.collectiblesModel
|
||||
|
||||
onJoined: {
|
||||
root.rootStore.requestToJoinCommunityWithAuthentication(communityIntroDialog.communityId, root.rootStore.userProfileInst.name, sharedAddresses, airdropAddress)
|
||||
onPrepareForSigning: {
|
||||
root.rootStore.prepareKeypairsForSigning(sharedAddresses)
|
||||
|
||||
communityIntroDialog.keypairSigningModel = root.rootStore.communitiesModuleInst.keypairsSigningModel
|
||||
}
|
||||
|
||||
onSignSharedAddressesForAllNonKeycardKeypairs: {
|
||||
root.rootStore.signSharedAddressesForAllNonKeycardKeypairs()
|
||||
}
|
||||
|
||||
onSignSharedAddressesForKeypair: {
|
||||
root.rootStore.signSharedAddressesForKeypair(keyUid)
|
||||
}
|
||||
|
||||
onJoinCommunity: {
|
||||
root.rootStore.joinCommunityOrEditSharedAddresses()
|
||||
}
|
||||
|
||||
onCancelMembershipRequest: {
|
||||
|
@ -245,6 +259,16 @@ StackLayout {
|
|||
onClosed: {
|
||||
destroy()
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root.rootStore.communitiesModuleInst
|
||||
|
||||
function onSharedAddressesForAllNonKeycardKeypairsSigned() {
|
||||
if (!!communityIntroDialog.replaceItem) {
|
||||
communityIntroDialog.replaceLoader.item.sharedAddressesForAllNonKeycardKeypairsSigned()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -394,8 +394,20 @@ QtObject {
|
|||
return communitiesModuleInst.spectateCommunity(id, ensName)
|
||||
}
|
||||
|
||||
function requestToJoinCommunityWithAuthentication(communityId, ensName, addressesToShare = [], airdropAddress = "") {
|
||||
communitiesModuleInst.requestToJoinCommunityWithAuthenticationWithSharedAddresses(communityId, ensName, JSON.stringify(addressesToShare), airdropAddress)
|
||||
function prepareKeypairsForSigning(communityId, ensName, addressesToShare = [], airdropAddress = "", editMode = false) {
|
||||
communitiesModuleInst.prepareKeypairsForSigning(communityId, ensName, JSON.stringify(addressesToShare), airdropAddress, editMode)
|
||||
}
|
||||
|
||||
function signSharedAddressesForAllNonKeycardKeypairs() {
|
||||
communitiesModuleInst.signSharedAddressesForAllNonKeycardKeypairs()
|
||||
}
|
||||
|
||||
function signSharedAddressesForKeypair(keyUid) {
|
||||
communitiesModuleInst.signSharedAddressesForKeypair(keyUid)
|
||||
}
|
||||
|
||||
function joinCommunityOrEditSharedAddresses() {
|
||||
communitiesModuleInst.joinCommunityOrEditSharedAddresses()
|
||||
}
|
||||
|
||||
function getChainIdForChat() {
|
||||
|
@ -612,9 +624,9 @@ QtObject {
|
|||
readonly property bool amIMember: chatCommunitySectionModule ? chatCommunitySectionModule.amIMember : false
|
||||
|
||||
property var oneToOneChatContact: undefined
|
||||
readonly property string oneToOneChatContactName: !!_d.oneToOneChatContact ? ProfileUtils.displayName(_d.oneToOneChatContact.localNickname,
|
||||
_d.oneToOneChatContact.name,
|
||||
_d.oneToOneChatContact.displayName,
|
||||
readonly property string oneToOneChatContactName: !!_d.oneToOneChatContact ? ProfileUtils.displayName(_d.oneToOneChatContact.localNickname,
|
||||
_d.oneToOneChatContact.name,
|
||||
_d.oneToOneChatContact.displayName,
|
||||
_d.oneToOneChatContact.alias) : ""
|
||||
|
||||
//Update oneToOneChatContact when the contact is updated
|
||||
|
@ -674,7 +686,7 @@ QtObject {
|
|||
|
||||
//Update oneToOneChatContact when activeChat id changes
|
||||
Binding on oneToOneChatContact {
|
||||
when: _d.activeChatId && _d.activeChatType === Constants.chatType.oneToOne
|
||||
when: _d.activeChatId && _d.activeChatType === Constants.chatType.oneToOne
|
||||
value: Utils.getContactDetailsAsJson(_d.activeChatId, false)
|
||||
restoreMode: Binding.RestoreBindingOrValue
|
||||
}
|
||||
|
|
|
@ -51,13 +51,14 @@ Control {
|
|||
enabled: d.dirty
|
||||
type: d.lostCommunityPermission || d.lostChannelPermissions ? StatusBaseButton.Type.Danger : StatusBaseButton.Type.Normal
|
||||
visible: root.isEditMode
|
||||
icon.name: type === StatusBaseButton.Type.Normal && d.selectedAddressesDirty ? Constants.authenticationIconByType[root.loginType] : ""
|
||||
icon.name: type === StatusBaseButton.Type.Normal && d.selectedAddressesDirty?
|
||||
!root.isEditMode? Constants.authenticationIconByType[root.loginType] : ""
|
||||
: ""
|
||||
text: d.lostCommunityPermission ? qsTr("Save changes & leave %1").arg(root.communityName) :
|
||||
d.lostChannelPermissions ? qsTr("Save changes & update my permissions")
|
||||
: qsTr("Save changes")
|
||||
: qsTr("Prove ownership")
|
||||
onClicked: {
|
||||
root.saveSelectedAddressesClicked(root.selectedAirdropAddress, root.selectedSharedAddresses)
|
||||
root.close()
|
||||
root.prepareForSigning(root.selectedAirdropAddress, root.selectedSharedAddresses)
|
||||
}
|
||||
}
|
||||
StatusButton {
|
||||
|
@ -78,7 +79,7 @@ Control {
|
|||
|
||||
signal sharedAddressesChanged(string airdropAddress, var sharedAddresses)
|
||||
signal shareSelectedAddressesClicked(string airdropAddress, var sharedAddresses)
|
||||
signal saveSelectedAddressesClicked(string airdropAddress, var sharedAddresses)
|
||||
signal prepareForSigning(string airdropAddress, var sharedAddresses)
|
||||
|
||||
signal close()
|
||||
|
||||
|
@ -118,11 +119,14 @@ Control {
|
|||
|
||||
function setOldSharedAddresses(oldSharedAddresses) {
|
||||
d.initialSelectedSharedAddresses = oldSharedAddresses
|
||||
accountSelector.selectedSharedAddresses = Qt.binding(() => d.initialSelectedSharedAddresses)
|
||||
accountSelector.applyChange()
|
||||
}
|
||||
|
||||
function setOldAirdropAddress(oldAirdropAddress) {
|
||||
d.initialSelectedAirdropAddress = oldAirdropAddress
|
||||
accountSelector.selectedAirdropAddress = oldAirdropAddress
|
||||
accountSelector.selectedAirdropAddress = Qt.binding(() => d.initialSelectedAirdropAddress)
|
||||
accountSelector.applyChange()
|
||||
}
|
||||
|
||||
SortFilterProxyModel {
|
||||
|
@ -178,7 +182,8 @@ Control {
|
|||
model: root.walletAccountsModel
|
||||
selectedSharedAddresses: d.initialSelectedSharedAddresses
|
||||
selectedAirdropAddress: d.initialSelectedAirdropAddress
|
||||
onAddressesChanged: {
|
||||
onAddressesChanged: accountSelector.applyChange()
|
||||
function applyChange() {
|
||||
root.selectedSharedAddresses = selectedSharedAddresses
|
||||
root.selectedAirdropAddress = selectedAirdropAddress
|
||||
root.sharedAddressesChanged(selectedAirdropAddress, selectedSharedAddresses)
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
import utils 1.0
|
||||
import shared.popups.keycard.helpers 1.0
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
property var keypairSigningModel
|
||||
|
||||
readonly property string title: qsTr("Prove ownership of keypairs")
|
||||
readonly property var rightButtons: [d.rightBtn]
|
||||
readonly property bool allSigned: regularKeypairs.visible == d.sharedAddressesForAllNonKeycardKeypairsSigned &&
|
||||
keycardKeypairs.visible == d.allKeycardKeypairsSigned
|
||||
|
||||
signal joinCommunity()
|
||||
signal signSharedAddressesForAllNonKeycardKeypairs()
|
||||
signal signSharedAddressesForKeypair(string keyUid)
|
||||
|
||||
function sharedAddressesForAllNonKeycardKeypairsSigned() {
|
||||
d.sharedAddressesForAllNonKeycardKeypairsSigned = true
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
property bool sharedAddressesForAllNonKeycardKeypairsSigned: false
|
||||
property bool allKeycardKeypairsSigned: false
|
||||
|
||||
readonly property var rightBtn: StatusButton {
|
||||
enabled: root.allSigned
|
||||
text: qsTr("Share your addresses to join")
|
||||
onClicked: {
|
||||
root.joinCommunity()
|
||||
}
|
||||
}
|
||||
|
||||
function reEvaluateSignedKeypairs() {
|
||||
let allKeypairsSigned = true
|
||||
for(var i = 0; i< keycardKeypairs.model.count; i++) {
|
||||
if(!keycardKeypairs.model.get(i).keyPair.ownershipVerified) {
|
||||
allKeypairsSigned = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
d.allKeycardKeypairsSigned = allKeypairsSigned
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: Style.current.xlPadding
|
||||
|
||||
spacing: Style.current.padding
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
visible: regularKeypairs.visible
|
||||
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Keypairs we need an authentication for")
|
||||
font.pixelSize: Constants.keycard.general.fontSize2
|
||||
color: Theme.palette.baseColor1
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
text: d.sharedAddressesForAllNonKeycardKeypairsSigned? qsTr("Authenticated") : qsTr("Authenticate")
|
||||
enabled: !d.sharedAddressesForAllNonKeycardKeypairsSigned
|
||||
icon.name: userProfile.usingBiometricLogin? "touch-id" : "password"
|
||||
|
||||
onClicked: {
|
||||
root.signSharedAddressesForAllNonKeycardKeypairs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusListView {
|
||||
id: regularKeypairs
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: regularKeypairs.contentHeight
|
||||
visible: regularKeypairs.model.count > 0
|
||||
spacing: Style.current.padding
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: root.keypairSigningModel
|
||||
filters: ExpressionFilter {
|
||||
expression: !model.keyPair.migratedToKeycard
|
||||
}
|
||||
}
|
||||
delegate: KeyPairItem {
|
||||
width: ListView.view.width
|
||||
sensor.hoverEnabled: false
|
||||
additionalInfoForProfileKeypair: ""
|
||||
|
||||
keyPairType: model.keyPair.pairType
|
||||
keyPairKeyUid: model.keyPair.keyUid
|
||||
keyPairName: model.keyPair.name
|
||||
keyPairIcon: model.keyPair.icon
|
||||
keyPairImage: model.keyPair.image
|
||||
keyPairDerivedFrom: model.keyPair.derivedFrom
|
||||
keyPairAccounts: model.keyPair.accounts
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
visible: regularKeypairs.visible && keycardKeypairs.visible
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: Style.current.xlPadding
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
visible: keycardKeypairs.visible
|
||||
text: qsTr("Keypairs that need to be singed using appropriate Keycard")
|
||||
font.pixelSize: Constants.keycard.general.fontSize2
|
||||
color: Theme.palette.baseColor1
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
StatusListView {
|
||||
id: keycardKeypairs
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: keycardKeypairs.contentHeight
|
||||
visible: keycardKeypairs.model.count > 0
|
||||
spacing: Style.current.padding
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: root.keypairSigningModel
|
||||
filters: ExpressionFilter {
|
||||
expression: model.keyPair.migratedToKeycard
|
||||
}
|
||||
}
|
||||
delegate: KeyPairItem {
|
||||
width: ListView.view.width
|
||||
sensor.hoverEnabled: !model.keyPair.ownershipVerified
|
||||
additionalInfoForProfileKeypair: ""
|
||||
|
||||
keyPairType: model.keyPair.pairType
|
||||
keyPairKeyUid: model.keyPair.keyUid
|
||||
keyPairName: model.keyPair.name
|
||||
keyPairIcon: model.keyPair.icon
|
||||
keyPairImage: model.keyPair.image
|
||||
keyPairDerivedFrom: model.keyPair.derivedFrom
|
||||
keyPairAccounts: model.keyPair.accounts
|
||||
|
||||
components: [
|
||||
StatusBaseText {
|
||||
font.weight: Font.Medium
|
||||
font.underline: mouseArea.containsMouse
|
||||
font.pixelSize: Theme.primaryTextFontSize
|
||||
color: model.keyPair.ownershipVerified? Theme.palette.baseColor1 : Theme.palette.primaryColor1
|
||||
text: model.keyPair.ownershipVerified? qsTr("Signed") : qsTr("Sign")
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
hoverEnabled: !model.keyPair.ownershipVerified
|
||||
enabled: !model.keyPair.ownershipVerified
|
||||
onEnabledChanged: {
|
||||
d.reEvaluateSignedKeypairs()
|
||||
}
|
||||
onClicked: {
|
||||
root.signSharedAddressesForKeypair(model.keyPair.keyUid)
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,6 +30,7 @@ ProfilePopupInviteMessagePanel 1.0 ProfilePopupInviteMessagePanel.qml
|
|||
ProfilePopupOverviewPanel 1.0 ProfilePopupOverviewPanel.qml
|
||||
RequirementsCheckPendingLoader 1.0 RequirementsCheckPendingLoader.qml
|
||||
SharedAddressesPanel 1.0 SharedAddressesPanel.qml
|
||||
SharedAddressesSigningPanel 1.0 SharedAddressesSigningPanel.qml
|
||||
SortableTokenHoldersList 1.0 SortableTokenHoldersList.qml
|
||||
SortableTokenHoldersPanel 1.0 SortableTokenHoldersPanel.qml
|
||||
TagsPanel 1.0 TagsPanel.qml
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import QtQuick 2.15
|
||||
import QtQml.Models 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups.Dialog 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
import AppLayouts.Communities.panels 1.0
|
||||
|
||||
|
@ -12,6 +16,7 @@ StatusDialog {
|
|||
property bool isEditMode
|
||||
|
||||
property bool requirementsCheckPending
|
||||
property var keypairSigningModel
|
||||
|
||||
required property string communityName
|
||||
required property string communityIcon
|
||||
|
@ -22,46 +27,138 @@ StatusDialog {
|
|||
required property var assetsModel
|
||||
required property var collectiblesModel
|
||||
|
||||
property alias selectedSharedAddresses: panel.selectedSharedAddresses
|
||||
property alias selectedAirdropAddress: panel.selectedAirdropAddress
|
||||
|
||||
signal shareSelectedAddressesClicked(string airdropAddress, var sharedAddresses)
|
||||
signal saveSelectedAddressesClicked(string airdropAddress, var sharedAddresses)
|
||||
signal sharedAddressesChanged(string airdropAddress, var sharedAddresses)
|
||||
|
||||
signal prepareForSigning(string airdropAddress, var sharedAddresses)
|
||||
signal editRevealedAddresses()
|
||||
signal signSharedAddressesForAllNonKeycardKeypairs()
|
||||
signal signSharedAddressesForKeypair(string keyUid)
|
||||
|
||||
function setOldSharedAddresses(oldSharedAddresses) {
|
||||
panel.setOldSharedAddresses(oldSharedAddresses)
|
||||
if (!d.displaySigningPanel && !!loader.item) {
|
||||
d.oldSharedAddresses = oldSharedAddresses
|
||||
loader.item.setOldSharedAddresses(oldSharedAddresses)
|
||||
}
|
||||
}
|
||||
|
||||
function setOldAirdropAddress(oldAirdropAddress) {
|
||||
panel.setOldAirdropAddress(oldAirdropAddress)
|
||||
if (!d.displaySigningPanel && !!loader.item) {
|
||||
d.oldAirdropAddress = oldAirdropAddress
|
||||
loader.item.setOldAirdropAddress(oldAirdropAddress)
|
||||
}
|
||||
}
|
||||
|
||||
title: panel.title
|
||||
function sharedAddressesForAllNonKeycardKeypairsSigned() {
|
||||
if (d.displaySigningPanel && !!loader.item) {
|
||||
loader.item.sharedAddressesForAllNonKeycardKeypairsSigned()
|
||||
}
|
||||
}
|
||||
|
||||
title: !!loader.item? loader.item.title : ""
|
||||
implicitWidth: 640 // by design
|
||||
padding: 0
|
||||
|
||||
contentItem: SharedAddressesPanel {
|
||||
id: panel
|
||||
isEditMode: root.isEditMode
|
||||
requirementsCheckPending: root.requirementsCheckPending
|
||||
communityName: root.communityName
|
||||
communityIcon: root.communityIcon
|
||||
loginType: root.loginType
|
||||
walletAccountsModel: root.walletAccountsModel
|
||||
permissionsModel: root.permissionsModel
|
||||
assetsModel: root.assetsModel
|
||||
collectiblesModel: root.collectiblesModel
|
||||
onShareSelectedAddressesClicked: root.shareSelectedAddressesClicked(airdropAddress, sharedAddresses)
|
||||
onSaveSelectedAddressesClicked: root.saveSelectedAddressesClicked(airdropAddress, sharedAddresses)
|
||||
onSharedAddressesChanged: {
|
||||
root.sharedAddressesChanged(airdropAddress, sharedAddresses)
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
property bool displaySigningPanel: false
|
||||
property bool allSigned: false
|
||||
|
||||
property var oldSharedAddresses
|
||||
property string oldAirdropAddress
|
||||
|
||||
property var selectAddressesPanelButtons: ObjectModel {}
|
||||
readonly property var signingPanelButtons: ObjectModel {
|
||||
StatusFlatButton {
|
||||
visible: root.isEditMode
|
||||
borderColor: Theme.palette.baseColor2
|
||||
text: qsTr("Cancel")
|
||||
onClicked: root.close()
|
||||
}
|
||||
StatusButton {
|
||||
text: qsTr("Save changes")
|
||||
enabled: d.allSigned
|
||||
onClicked: {
|
||||
root.editRevealedAddresses()
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
readonly property var signingPanelBackButtons: ObjectModel {
|
||||
StatusBackButton {
|
||||
onClicked: {
|
||||
d.displaySigningPanel = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: Loader {
|
||||
id: loader
|
||||
sourceComponent: d.displaySigningPanel? sharedAddressesSigningPanelComponent : selectSharedAddressesPanelComponent
|
||||
|
||||
onLoaded: {
|
||||
if (!d.displaySigningPanel) {
|
||||
if (!!d.oldSharedAddresses) {
|
||||
root.setOldSharedAddresses(d.oldSharedAddresses)
|
||||
}
|
||||
if (!!d.oldAirdropAddress) {
|
||||
root.setOldAirdropAddress(d.oldAirdropAddress)
|
||||
}
|
||||
d.selectAddressesPanelButtons = loader.item.buttons
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: selectSharedAddressesPanelComponent
|
||||
SharedAddressesPanel {
|
||||
isEditMode: root.isEditMode
|
||||
requirementsCheckPending: root.requirementsCheckPending
|
||||
communityName: root.communityName
|
||||
communityIcon: root.communityIcon
|
||||
loginType: root.loginType
|
||||
walletAccountsModel: root.walletAccountsModel
|
||||
permissionsModel: root.permissionsModel
|
||||
assetsModel: root.assetsModel
|
||||
collectiblesModel: root.collectiblesModel
|
||||
onShareSelectedAddressesClicked: root.shareSelectedAddressesClicked(airdropAddress, sharedAddresses)
|
||||
onPrepareForSigning: {
|
||||
root.prepareForSigning(airdropAddress, sharedAddresses)
|
||||
d.displaySigningPanel = true
|
||||
}
|
||||
onSharedAddressesChanged: {
|
||||
root.sharedAddressesChanged(airdropAddress, sharedAddresses)
|
||||
}
|
||||
onClose: root.close()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: sharedAddressesSigningPanelComponent
|
||||
SharedAddressesSigningPanel {
|
||||
|
||||
keypairSigningModel: root.keypairSigningModel
|
||||
|
||||
onSignSharedAddressesForAllNonKeycardKeypairs: {
|
||||
root.signSharedAddressesForAllNonKeycardKeypairs()
|
||||
}
|
||||
|
||||
onSignSharedAddressesForKeypair: {
|
||||
root.signSharedAddressesForKeypair(keyUid)
|
||||
}
|
||||
|
||||
onAllSignedChanged: {
|
||||
d.allSigned = allSigned
|
||||
}
|
||||
}
|
||||
onClose: root.close()
|
||||
}
|
||||
|
||||
footer: StatusDialogFooter {
|
||||
spacing: Style.current.padding
|
||||
rightButtons: panel.buttons
|
||||
rightButtons: d.displaySigningPanel? d.signingPanelButtons : d.selectAddressesPanelButtons
|
||||
leftButtons: d.displaySigningPanel? d.signingPanelBackButtons : null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,8 @@ Item {
|
|||
|| root.communitiesStore.discordImportInProgress
|
||||
|
||||
property bool invitationPending: root.store.isCommunityRequestPending(communityData.id)
|
||||
property bool isJoinBtnLoading: false
|
||||
|
||||
property bool joiningCommunityInProgress: false
|
||||
}
|
||||
|
||||
ColumnHeaderPanel {
|
||||
|
@ -468,7 +469,7 @@ Item {
|
|||
anchors.bottomMargin: Style.current.halfPadding
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
enabled: !root.communityData.amIBanned
|
||||
loading: d.isJoinBtnLoading
|
||||
loading: d.joiningCommunityInProgress
|
||||
|
||||
text: {
|
||||
if (root.communityData.amIBanned) return qsTr("You were banned from community")
|
||||
|
@ -479,22 +480,23 @@ Item {
|
|||
}
|
||||
|
||||
onClicked: {
|
||||
Global.openPopup(communityIntroDialog);
|
||||
Global.openPopup(communityIntroDialogComponent);
|
||||
}
|
||||
|
||||
Connections {
|
||||
enabled: d.isJoinBtnLoading
|
||||
enabled: d.joiningCommunityInProgress
|
||||
target: root.store.communitiesModuleInst
|
||||
function onCommunityAccessRequested(communityId: string) {
|
||||
if (communityId === communityData.id) {
|
||||
d.invitationPending = root.store.isCommunityRequestPending(communityData.id)
|
||||
d.isJoinBtnLoading = false
|
||||
d.joiningCommunityInProgress = false
|
||||
}
|
||||
}
|
||||
function onCommunityAccessFailed(communityId: string) {
|
||||
|
||||
function onCommunityAccessFailed(communityId: string, error: string) {
|
||||
if (communityId === communityData.id) {
|
||||
d.invitationPending = false
|
||||
d.isJoinBtnLoading = false
|
||||
d.joiningCommunityInProgress = false
|
||||
Global.displayToastMessage(qsTr("Request to join failed"),
|
||||
qsTr("Please try again later"),
|
||||
"",
|
||||
|
@ -503,15 +505,12 @@ Item {
|
|||
"")
|
||||
}
|
||||
}
|
||||
function onUserAuthenticationCanceled() {
|
||||
d.invitationPending = false
|
||||
d.isJoinBtnLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: communityIntroDialog
|
||||
id: communityIntroDialogComponent
|
||||
CommunityIntroDialog {
|
||||
id: communityIntroDialog
|
||||
|
||||
isInvitationPending: d.invitationPending
|
||||
requirementsCheckPending: root.store.requirementsCheckPending
|
||||
|
@ -528,19 +527,47 @@ Item {
|
|||
assetsModel: root.store.assetsModel
|
||||
collectiblesModel: root.store.collectiblesModel
|
||||
|
||||
onJoined: {
|
||||
d.isJoinBtnLoading = true
|
||||
root.store.requestToJoinCommunityWithAuthentication(communityData.id, root.store.userProfileInst.name, sharedAddresses, airdropAddress)
|
||||
onPrepareForSigning: {
|
||||
root.store.prepareKeypairsForSigning(communityData.id, root.store.userProfileInst.name, sharedAddresses, airdropAddress, false)
|
||||
|
||||
communityIntroDialog.keypairSigningModel = root.store.communitiesModuleInst.keypairsSigningModel
|
||||
}
|
||||
|
||||
onSignSharedAddressesForAllNonKeycardKeypairs: {
|
||||
root.store.signSharedAddressesForAllNonKeycardKeypairs()
|
||||
}
|
||||
|
||||
onSignSharedAddressesForKeypair: {
|
||||
root.store.signSharedAddressesForKeypair(keyUid)
|
||||
}
|
||||
|
||||
onJoinCommunity: {
|
||||
d.joiningCommunityInProgress = true
|
||||
root.store.joinCommunityOrEditSharedAddresses()
|
||||
}
|
||||
|
||||
onCancelMembershipRequest: {
|
||||
root.store.cancelPendingRequest(communityData.id)
|
||||
d.invitationPending = root.store.isCommunityRequestPending(communityData.id)
|
||||
}
|
||||
|
||||
onSharedAddressesUpdated: {
|
||||
root.store.updatePermissionsModel(communityData.id, sharedAddresses)
|
||||
}
|
||||
|
||||
onClosed: destroy()
|
||||
onClosed: {
|
||||
destroy()
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root.store.communitiesModuleInst
|
||||
|
||||
function onSharedAddressesForAllNonKeycardKeypairsSigned() {
|
||||
if (!!communityIntroDialog.replaceItem) {
|
||||
communityIntroDialog.replaceLoader.item.sharedAddressesForAllNonKeycardKeypairsSigned()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -242,7 +242,24 @@ SettingsContentBase {
|
|||
assetsModel: chatStore.assetsModel
|
||||
collectiblesModel: chatStore.collectiblesModel
|
||||
|
||||
onJoined: chatStore.requestToJoinCommunityWithAuthentication(communityIntroDialog.communityId, root.rootStore.userProfileInst.name, sharedAddresses, airdropAddress)
|
||||
onPrepareForSigning: {
|
||||
chatStore.prepareKeypairsForSigning(communityIntroDialog.communityId, root.rootStore.userProfileInst.name, sharedAddresses, airdropAddress, false)
|
||||
|
||||
communityIntroDialog.keypairSigningModel = chatStore.communitiesModuleInst.keypairsSigningModel
|
||||
}
|
||||
|
||||
onSignSharedAddressesForAllNonKeycardKeypairs: {
|
||||
chatStore.signSharedAddressesForAllNonKeycardKeypairs()
|
||||
}
|
||||
|
||||
onSignSharedAddressesForKeypair: {
|
||||
chatStore.signSharedAddressesForKeypair(keyUid)
|
||||
}
|
||||
|
||||
onJoinCommunity: {
|
||||
chatStore.joinCommunityOrEditSharedAddresses()
|
||||
}
|
||||
|
||||
onCancelMembershipRequest: root.rootStore.cancelPendingRequest(communityIntroDialog.communityId)
|
||||
|
||||
onSharedAddressesUpdated: {
|
||||
|
@ -250,6 +267,16 @@ SettingsContentBase {
|
|||
}
|
||||
|
||||
onClosed: destroy()
|
||||
|
||||
Connections {
|
||||
target: chatStore.communitiesModuleInst
|
||||
|
||||
function onSharedAddressesForAllNonKeycardKeypairsSigned() {
|
||||
if (!!communityIntroDialog.replaceItem) {
|
||||
communityIntroDialog.replaceLoader.item.sharedAddressesForAllNonKeycardKeypairsSigned()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -241,14 +241,20 @@ QtObject {
|
|||
mainModuleInst.windowDeactivated()
|
||||
}
|
||||
|
||||
function requestToJoinCommunityWithAuthentication(communityId, ensName, addressesToShare = [], airdropAddress = "") {
|
||||
communitiesModuleInst.requestToJoinCommunityWithAuthenticationWithSharedAddresses(
|
||||
communityId, ensName, JSON.stringify(addressesToShare), airdropAddress)
|
||||
function prepareKeypairsForSigning(communityId, ensName, addressesToShare = [], airdropAddress = "", editMode = false) {
|
||||
communitiesModuleInst.prepareKeypairsForSigning(communityId, ensName, JSON.stringify(addressesToShare), airdropAddress, editMode)
|
||||
}
|
||||
|
||||
function editSharedAddressesWithAuthentication(communityId, addressesToShare = [], airdropAddress = "") {
|
||||
communitiesModuleInst.editSharedAddressesWithAuthentication(
|
||||
communityId, JSON.stringify(addressesToShare), airdropAddress)
|
||||
function signSharedAddressesForAllNonKeycardKeypairs() {
|
||||
communitiesModuleInst.signSharedAddressesForAllNonKeycardKeypairs()
|
||||
}
|
||||
|
||||
function signSharedAddressesForKeypair(keyUid) {
|
||||
communitiesModuleInst.signSharedAddressesForKeypair(keyUid)
|
||||
}
|
||||
|
||||
function joinCommunityOrEditSharedAddresses() {
|
||||
communitiesModuleInst.joinCommunityOrEditSharedAddresses()
|
||||
}
|
||||
|
||||
function updatePermissionsModel(communityId, sharedAddresses) {
|
||||
|
|
|
@ -531,7 +531,24 @@ QtObject {
|
|||
}
|
||||
assetsModel: root.rootStore.assetsModel
|
||||
collectiblesModel: root.rootStore.collectiblesModel
|
||||
onJoined: root.rootStore.requestToJoinCommunityWithAuthentication(communityIntroDialog.communityId, communityIntroDialog.name, sharedAddresses, airdropAddress)
|
||||
onPrepareForSigning: {
|
||||
root.rootStore.prepareKeypairsForSigning(communityIntroDialog.communityId, communityIntroDialog.name, sharedAddresses, airdropAddress, false)
|
||||
|
||||
communityIntroDialog.keypairSigningModel = root.rootStore.communitiesModuleInst.keypairsSigningModel
|
||||
}
|
||||
|
||||
onSignSharedAddressesForAllNonKeycardKeypairs: {
|
||||
root.rootStore.signSharedAddressesForAllNonKeycardKeypairs()
|
||||
}
|
||||
|
||||
onSignSharedAddressesForKeypair: {
|
||||
root.rootStore.signSharedAddressesForKeypair(keyUid)
|
||||
}
|
||||
|
||||
onJoinCommunity: {
|
||||
root.rootStore.joinCommunityOrEditSharedAddresses()
|
||||
}
|
||||
|
||||
onCancelMembershipRequest: root.rootStore.cancelPendingRequest(communityIntroDialog.communityId)
|
||||
Connections {
|
||||
target: root.communitiesStore.communitiesModuleInst
|
||||
|
@ -541,20 +558,27 @@ QtObject {
|
|||
root.communitiesStore.spectateCommunity(communityId);
|
||||
communityIntroDialog.close();
|
||||
}
|
||||
function onCommunityAccessFailed(communityId: string) {
|
||||
function onCommunityAccessFailed(communityId: string, error: string) {
|
||||
if (communityId !== communityIntroDialog.communityId)
|
||||
return
|
||||
communityIntroDialog.close();
|
||||
}
|
||||
function onUserAuthenticationCanceled() {
|
||||
communityIntroDialog.close();
|
||||
}
|
||||
}
|
||||
onSharedAddressesUpdated: {
|
||||
root.rootStore.updatePermissionsModel(communityIntroDialog.communityId, sharedAddresses)
|
||||
}
|
||||
onAboutToShow: { root.rootStore.communityKeyToImport = communityIntroDialog.communityId; }
|
||||
onClosed: { root.rootStore.communityKeyToImport = ""; destroy(); }
|
||||
|
||||
Connections {
|
||||
target: root.rootStore.communitiesModuleInst
|
||||
|
||||
function onSharedAddressesForAllNonKeycardKeypairsSigned() {
|
||||
if (!!communityIntroDialog.replaceItem) {
|
||||
communityIntroDialog.replaceLoader.item.sharedAddressesForAllNonKeycardKeypairsSigned()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -738,9 +762,33 @@ QtObject {
|
|||
|
||||
onSharedAddressesChanged: root.rootStore.updatePermissionsModel(
|
||||
editSharedAddressesPopup.communityId, sharedAddresses)
|
||||
onSaveSelectedAddressesClicked: root.rootStore.editSharedAddressesWithAuthentication(
|
||||
editSharedAddressesPopup.communityId, sharedAddresses, airdropAddress)
|
||||
onPrepareForSigning: {
|
||||
root.rootStore.prepareKeypairsForSigning(editSharedAddressesPopup.communityId, "", sharedAddresses, airdropAddress, true)
|
||||
|
||||
editSharedAddressesPopup.keypairSigningModel = root.rootStore.communitiesModuleInst.keypairsSigningModel
|
||||
}
|
||||
|
||||
onSignSharedAddressesForAllNonKeycardKeypairs: {
|
||||
root.rootStore.signSharedAddressesForAllNonKeycardKeypairs()
|
||||
}
|
||||
|
||||
onSignSharedAddressesForKeypair: {
|
||||
root.rootStore.signSharedAddressesForKeypair(keyUid)
|
||||
}
|
||||
|
||||
onEditRevealedAddresses: {
|
||||
root.rootStore.joinCommunityOrEditSharedAddresses()
|
||||
}
|
||||
|
||||
onClosed: destroy()
|
||||
|
||||
Connections {
|
||||
target: root.rootStore.communitiesModuleInst
|
||||
|
||||
function onSharedAddressesForAllNonKeycardKeypairsSigned() {
|
||||
editSharedAddressesPopup.sharedAddressesForAllNonKeycardKeypairsSigned()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 9f69c3259397821483bad722ab92eb52470185de
|
||||
Subproject commit 11a36122901967bc3fac2daf8d2f8bce9b5ed427
|
Loading…
Reference in New Issue