# Wallet Solution for Bunny migration ```plantuml @startuml header Wallet Solution flow diagram title Comparing Flows end title actor CUSTOMER as CUSTOMER order 0 actor OPERATOR as OPERATOR order 1 actor DEV as DEV order 2 participant "Livi APP" as LIVIAPP order 11 participant "Metamask\n(Mobile)" as WALLET order 12 participant "Hardhat\n(CLI)" as cli order 13 participant "Metamask\n(Browser)" as BROWSER_WALLET order 14 control "Operator\nWebConsole(MS)" as CONSOLE order 21 #yellow control "Go-Backend\n(MS)" as GO_BACKEND order 20 #yellow control "Azure AD\n(MS)" as AD order 30 #yellow control "Cdn\n(MS)" as CDN order 33 #yellow control "Moralis\n(Cloud)" as MORALIS order 36 #orange control "Webhook\n(MS)" as WEBHOOK order 37 #yellow database "Metadata DB\n(MS)" as METADATADB order 38 #yellow database "TX DB\n(MS)" as TXDB order 43 #yellow database "CUSTOMERDB\n(Data centre)" as CUSTOMERDB order 44 #purple entity "Router\nContract" as ROUTERCONTRACT order 51 #blue autonumber "[0]" == Conventional Web3 wallet == group Login by metamask in Livi APP [by customer] CUSTOMER->LIVIAPP: launch LIVIAPP->WALLET: Deeplink connect WALLET->WALLET: Confirm connect WALLET--> LIVIAPP: (response) LIVIAPP -> GO_BACKEND: Verify signer address register status / Binding address with CID GO_BACKEND-> CUSTOMERDB: query the address / insert address to db CUSTOMERDB-->GO_BACKEND: (boolean) GO_BACKEND --> LIVIAPP:(boolean)) LIVIAPP-> ROUTERCONTRACT: Connected end group View [by customer] CUSTOMER->LIVIAPP: launch LIVIAPP->WALLET: Deeplink connect WALLET->WALLET: Approve WALLET-> LIVIAPP: Connected LIVIAPP->ROUTERCONTRACT: queryNFTMetaData (WalletAddress) ROUTERCONTRACT-->LIVIAPP: (struct[]) metadata, nftContractAddress, tokenIds LIVIAPP->CDN: getMetadata (??) CDN-->LIVIAPP: (json) LIVIAPP->CDN: fetchImage (uuid) CDN-->LIVIAPP: (jpg, png) end 'group Mint[public chain] [by customer] ' CUSTOMER->LIVIAPP: launch ' LIVIAPP->WALLET: Deeplink connect ' WALLET->WALLET: Approve ' WALLET-> LIVIAPP: Connected ' ' LIVIAPP-> GO_BACKEND:Sign permission for minting ' GO_BACKEND -> METADATADB: Insert arranged tokenID, metadata and image path ' METADATADB-->GO_BACKEND: (void) ' GO_BACKEND --> LIVIAPP: (Signed hash, arranged tokenID) ' LIVIAPP-> LIVIAPP: Pack mint transaction ' LIVIAPP -> WALLET: Send Raw transaction ' WALLET -> WALLET: Sign transaction ' WALLET-> ROUTERCONTRACT: Send out mint transaction ' ROUTERCONTRACT --> WALLET: Return hash ' GO_BACKEND -> TXDB: Insert transaction data ' TXDB --> GO_BACKEND: (boolean) ' WALLET-->LIVIAPP: Return hash ' opt [ok] ' MORALIS->WEBHOOK: emit (txData) ' WEBHOOK->ROUTERCONTRACT: validate (txData) ' ROUTERCONTRACT-->WEBHOOK: (true) ' WEBHOOK->TXDB: update (state) ' TXDB-->WEBHOOK: (void) ' WEBHOOK->METADATADB: query metadata by tokenID ' METADATADB--> WEBHOOK: response ' WEBHOOK->CDN: Upload image and metadata ' CDN-->WEBHOOK:(boolean) ' end 'end group Mint(Airdrop) [public chain] [by operator] OPERATOR-> CONSOLE: launch upload portal CONSOLE -> AD: Verify user role AD --> CONSOLE: Verified (Redirect) CONSOLE --> OPERATOR: Render web page OPERATOR -> BROWSER_WALLET: Connect Metamask BROWSER_WALLET -> OPERATOR: Approve Connect to Console OPERATOR --> BROWSER_WALLET: (boolean) BROWSER_WALLET --> CONSOLE: Connected OPERATOR->CONSOLE: Upload CSV file CONSOLE-> CONSOLE: Extract and verify CSV file CONSOLE -> CONSOLE: Create BatchMint transaction CONSOLE-> BROWSER_WALLET: Send raw transaction to Metamask BROWSER_WALLET -> OPERATOR: Request sign transaction OPERATOR -> BROWSER_WALLET: Sign transaction BROWSER_WALLET --> CONSOLE: (hash) CONSOLE -> GO_BACKEND: Request insert transaction data and metadata record to DB GO_BACKEND -> METADATADB: Insert arranged tokenID, metadata and image path METADATADB-->GO_BACKEND:(boolean) GO_BACKEND -> TXDB: Insert transaction data TXDB --> GO_BACKEND: (boolean) GO_BACKEND --> CONSOLE: Return success to csv portal opt [ok] MORALIS->WEBHOOK: emit (txData) WEBHOOK->ROUTERCONTRACT: validate (txData) ROUTERCONTRACT-->WEBHOOK: (true) WEBHOOK->TXDB: update (state) TXDB-->WEBHOOK: (void) WEBHOOK->METADATADB: query metadata by tokenID METADATADB--> WEBHOOK: response WEBHOOK->CDN: Upload image and metadata CDN-->WEBHOOK:(boolean) end end ' 'group Transfer [by customer] ' CUSTOMER->LIVIAPP: launch ' LIVIAPP->WALLET: Deeplink connect ' WALLET->WALLET: Approve ' WALLET-> LIVIAPP: Connected ' ' LIVIAPP-> LIVIAPP: Select NFT and fill in receiver address ' LIVIAPP-> LIVIAPP: Create transfer transaction ' LIVIAPP -> WALLET: Send Raw transaction ' WALLET -> WALLET: Sign transaction ' WALLET-> ROUTERCONTRACT: Send out mint transaction ' ROUTERCONTRACT --> WALLET:(hash) ' WALLET--> LIVIAPP: (hash) ' LIVIAPP -> GO_BACKEND: request insert transaction data ' GO_BACKEND -> TXDB: Insert transaction data ' TXDB --> GO_BACKEND: (boolean) ' GO_BACKEND --> LIVIAPP: (void) ' opt [ok] ' MORALIS->WEBHOOK: emit (txData) ' WEBHOOK->ROUTERCONTRACT: validate (txData) ' ROUTERCONTRACT-->WEBHOOK: (true) ' WEBHOOK->TXDB: update (state) ' TXDB-->WEBHOOK: (void) ' end 'end 'group Swap [by customer] ' note over CUSTOMER: TODO 'end 'group Whitelist [by operator] ' OPERATOR->GO_BACKEND:launch csv upload panel ' GO_BACKEND-->GO_BACKEND: (void) ' OPERATOR->GO_BACKEND:Upload CSV for whitelist wallet address ' GO_BACKEND->GO_BACKEND: Create Markle tree ' GO_BACKEND->ROUTERCONTRACT:Send setMerkleRoot transaction (hash) ' ROUTERCONTRACT-->GO_BACKEND:hash ' GO_BACKEND --> GO_BACKEND:Success ' opt [ok] ' MORALIS->WEBHOOK: emit (txData) ' WEBHOOK->ROUTERCONTRACT: validate (txData) ' ROUTERCONTRACT-->WEBHOOK: (true) ' WEBHOOK->TXDB: update (state) ' TXDB-->WEBHOOK: (void) ' end 'end group deploy [by dev] note over DEV: TODO end autonumber "[0]" ' 'group Transfer / Swap [by operator] ' CUSTOMER->LIVIAPP: launch ' LIVIAPP->ROUTERCONTRACT: queryCidToAddressBatch (cids) ' ROUTERCONTRACT-->LIVIAPP: (string[]) ' LIVIAPP->GO_BACKEND: transfer or swap (from, to, tokenId) ' GO_BACKEND->GO_BACKEND: retrieve\noperator\nprivatekey ' GO_BACKEND->GO_BACKEND: sign ' GO_BACKEND->ROUTERCONTRACT: sendTransaction ' ROUTERCONTRACT-->GO_BACKEND: (hash) ' loop sync ' opt [ok] ' MORALIS->WEBHOOK: emit (txData) ' WEBHOOK->ROUTERCONTRACT: validate (txData) ' ROUTERCONTRACT-->WEBHOOK: (true) ' WEBHOOK->TXDB: update (state) ' TXDB-->WEBHOOK: (void) ' end ' opt [error] ' MORALIS->WEBHOOK: emit (txData) ' WEBHOOK->ROUTERCONTRACT: validate (txData) ' ROUTERCONTRACT-->WEBHOOK: (false) ' WEBHOOK->TXDB: update (state) ' TXDB-->WEBHOOK: (void) ' WEBHOOK->GO_BACKEND: reportError (hash) ' note over GO_BACKEND: TODO: Error handling strategies ??? ' end ' end 'end group deploy [by dev] end group setupOperator [by dev] end autonumber "[0]" @enduml ```