# NFTicket, Nigeria Sequence Diagram (V2)
## Smart Contract Architecture

-----------
## Smart Contract Specification
### Nigeria Service Contract
**storage**
:::info
* mapping: NFTicketId & credit
* mapping: NFTicketId & presenter
:::
**function (Presenter Related)**
:::info
* getPresenter(NFTicket_id) return (presenter_address)
* **[internal]** setPresenter(NFTicket_id, presenter_address)
:::
**function (Ticket Related)**
:::info
* createNewNFTicket(recipient_wallet_address)
* presentTicket(NFTicket_id, presenter_address)
* refundTicket(NFTicket_id, credit_amount, refund_receiver_address) return (token_amount)
* verifyTicketOwner(verify_address, NFTicket_id)
* request IERC721.ownerOf(NFTicket_id)
* return NFTicket owner address
* verify verify_address is the NFTicket owner address
* verifyIsGetApproved(verify_address, NFTicket_id)
* request IERC721.getApproved(NFTicket_id)
* return approver address
* verify approver address is verify_address
:::
**function (Service Related)**
:::info
* **[Ticket Master(Backend) only]**
cancelService(NFTicket_id, deduct_credit)
* endService(Driver_wallet_address, Passenger_NFTicket_id, credit)
:::
**function (Credit Related)**
:::info
* topUp(NFTicket_id, credit)
* getCreditBalance(NFTicket_id) return (credit_balance)
* **[admin & this contract only]**
setCreditBalance(NFTicket_id, credit)
* **[admin & this contract only]**
addCredit(NFTicket_id, credit)
* getCreditBalance(NFTicketid)
* calculate credit balance after add credit
* setCreditBalance(NFTicket_id, credit balance after addition)
* **[admin & this contract only]**
deductCredit(NFTicket_id, credit)
* getCreditBalance(NFTicket_id)
* calculate credit balance after deduct credit
* setCreditBalance(NFTicket_id, credit balance after deduction)
:::
### Ticket Master Contract
**storage**
:::info
* service contract whitelist
:::
**modifier**
:::info
* inServiceContractWhitelist
:::
**function**
:::info
* **[Owner only]**
setServiceContractWhitelist(contract_address)
* **[Owner only]**
removeServiceContractWhitelist(contract_address)
* **[whitelist service contract only]**
mintNFTicket(recipient_wallet_address) return (NFTicket_id)
* **[whitelist service contract only]**
transferERC20TokenToWallet(wallet_address, ERC20_address, ERC20_token_amount)
* **[whitelist service contract only]**
transferNFTicketToOriginalOwner(original_owner_wallet_address, NFTicket_id)
* **[whitelist service contract only]**
distributeRevenueToPool(pool_owner_address, ERC20_address, ERC20_token_amount)
:::
**Used OpenZeppelin function**
:::info
* ownerOf(NFTicket_id) return (owner_address)
* approve(approver_address, NFTicket_id)
msg.sender approve approver to transfer his/her NFT
* transferFrom(from_address, to_address, NFTicket_id)
* _transfer(from_address, to_address, NFTicket_id)
* getApproved(NFTicket_id) return (approver_address)
:::
### ERC20 Token Contract
**Used OpenZeppelin function**
:::info
* approve(spender_address, token_amount) return (bool)
msg.sender approve spender to manage his/her token in certain amount
* allowance(token_owner_address, spender_address) return (allowance_amount)
the amount token owner allow spender to manage
* transferFrom(from_address, to_address, token_amount) return (bool)
* transfer(to_address, token_amount) return (bool)
:::
-----------
## Smart Contract Configuration (config when deploy)
**Nigeria Service Contract**
:::info
* Price per credit
* ERC20 token address (allow only one token)
:::
**Ticket Master Contract**
:::info
* Base fee
:::
-----------
## Sequence Diagram
### passenger first register and get NFTicket
:::success
*correspond to Nigeria sequence diagram **01.sequence-diagram-passenger-connect-wallet***
:::
:::danger
不確定 passenger 是否要付 base fee,先以不用付 base fee 的情境設計
:::
```mermaid
sequenceDiagram
participant BE as Backend
participant SCSC as Nigeria Service Contract
participant TMSC as Ticket Master Contract
actor P as Passenger
BE->>SCSC: request createNewNFTicket(wallet_address)
SCSC->>TMSC: request mintNFTicket(wallet_address)
TMSC->>TMSC: verify caller is inServiceContractWhitelist
TMSC->>TMSC: verify payment >= base fee
TMSC-->>P: mint NFTicket
TMSC-->>SCSC: return NFTicket_id
SCSC->>SCSC: setCreditBalance(NFTicket_id, 0)
SCSC-->>BE: return success
```
### passenger start journey (get Credit Balance)
:::success
*correspond to Nigeria sequence diagram **03.sequence-diagram-passenger-create-journey***
:::
```mermaid
sequenceDiagram
participant FE as Frontend
participant SCSC as Nigeria Service Contract
participant TMSC as Ticket Master Contract
FE->>TMSC: request ownerOf(NFTicket_id)
TMSC-->>FE: return NFTicket owner address
FE->>FE: verify passenger wallet address is the NFTicket owner address
FE->>SCSC: request getCreditBalance(NFTicket_id)
SCSC-->>FE: return NFTicket credit balance
FE->>FE: verify NFTicket credit balance is sufficient
```
### passenger start journey (present Ticket)
:::success
*correspond to Nigeria sequence diagram **03.sequence-diagram-passenger-create-journey***
:::
:::danger
如果是 passenger 自己 sign 的 transaction,不用帶 presenter 參數也沒關係, set meg.sender 當 presenter 也可以
:::
```mermaid
sequenceDiagram
participant FE as Frontend
participant SCSC as Nigeria Service Contract
participant TMSC as Ticket Master Contract
FE->>TMSC: request approve(Nigeria Service Contract address, NFTicket_id)
TMSC-->>FE: return success
FE->>SCSC: request presentTicket(NFTicket_id, passenger wallet address)
SCSC->>SCSC: verifyIsGetApproved(Nigeria Service Contract address, NFTicket_id)
SCSC->>SCSC: setPresenter(NFTicket_id, passenger wallet address)
SCSC->>TMSC: request transferFrom(passenger wallet address, Ticket Master Contract address, NFTicket_id)
SCSC->>SCSC: verifyTicketOwner(Nigeria Service Contract address, NFTicket_id)
SCSC-->>FE: return success
```
### passenger start journey cancellation (driver not found)
:::success
*correspond to Nigeria sequence diagram **03.sequence-diagram-passenger-create-journey***
:::
```mermaid
sequenceDiagram
participant BE as Backend
participant SCSC as Nigeria Service Contract
participant TMSC as Ticket Master Contract
BE->>SCSC: request cancelService(NFTicket_id, 0)
SCSC->>SCSC: getPresenter(NFTicket_id)
SCSC->>TMSC: request transferNFTicketToOriginalOwner(presenter address, NFTicket_id)
TMSC->>TMSC: verify caller is inServiceContractWhitelist
TMSC->>TMSC: _transfer(Ticket Master contract addrress, presenter address, NFTicket_id)
SCSC->>SCSC: verifyTicketOwner(presenter address, NFTicket_id)
SCSC-->>BE: return success
```
### passenger start journey cancellation (cancel by passenger)
:::success
*correspond to Nigeria sequence diagram **03.sequence-diagram-passenger-create-journey***
:::
:::danger
cancel fee 要給誰?
:::
```mermaid
sequenceDiagram
participant BE as Backend
participant SCSC as Nigeria Service Contract
participant TMSC as Ticket Master Contract
BE->>SCSC: request cancelService(NFTicket_id, deduct_cancel_fee)
SCSC->>SCSC: deductCredit(NFTicket_id, deduct_cancel_fee)
SCSC->>SCSC: getPresenter(NFTicket_id)
SCSC->>TMSC: request transferNFTicketToOriginalOwner(presenter address, NFTicket_id)
TMSC->>TMSC: verify caller is inServiceContractWhitelist
TMSC->>TMSC: _transfer(Ticket Master contract addrress, presenter addres, NFTicket_id)
SCSC->>SCSC: verifyTicketOwner(presenter, NFTicket_id)
SCSC-->>BE: return success
```
### driver end journey
:::success
*correspond to Nigeria sequence diagram **06.sequence-diagram-driver-end-journey***
:::
```mermaid
sequenceDiagram
participant FE as Frontend
participant SCSC as Nigeria Service Contract
participant TMSC as Ticket Master Contract
participant ETSC as ERC20 token Contract
FE->>SCSC: request endService(Driver_wallet_address, Passenger_NFTicket_id, credit)
SCSC->>SCSC: deductCredit(Passenger_NFTicket_id, credit)
SCSC->>SCSC: get Price per credit and ERC20 token address
SCSC->>TMSC: distributeRevenueToPool(Driver_wallet_address, ERC20_token_address, credit * price per credit)
TMSC->>TMSC: verify caller is inServiceContractWhitelist
TMSC->>ETSC: approve(Driver_wallet_address, Original allowance + credit * price per credit)
SCSC->>SCSC: getPresenter(NFTicket_id)
SCSC->>TMSC: request transferNFTicketToOriginalOwner(presenter address, NFTicket_id)
TMSC->>TMSC: verify caller is inServiceContractWhitelist
TMSC->>TMSC: _transfer(Ticket Master contract addrress, presenter addres, NFTicket_id)
SCSC->>SCSC: verifyTicketOwner(presenter address, NFTicket_id)
SCSC-->>FE: return success
```
### driver withdraw ticket(withdraw ERC20 token)
:::success
*correspond to Nigeria sequence diagram **10.sequence-diagram-driver-withdraw***
:::
```mermaid
sequenceDiagram
participant FE as Frontend
participant ETSC as ERC20 token Contract
FE->>ETSC: request allowance(Ticket Master contract address, Driver wallet address)
ETSC-->>FE: return allowance amount
FE->>ETSC: request transferfrom(Ticket Master contract address, Driver wallet address, allowance amount)
```
### passenger top up
:::success
*correspond to Nigeria sequence diagram **07.sequence-diagram-top-up***
:::
```mermaid
sequenceDiagram
participant FE as Frontend
participant SCSC as Nigeria Service Contract
participant ETSC as ERC20 token Contract
FE->>ETSC: request approve(Nigeria Service Contract address, token_amount)
ETSC-->>FE: return success
FE->>SCSC: request topUp(NFTicket_id, credit)
SCSC->>SCSC: verify allowance >= credit * price per credit
SCSC->>ETSC: request transferFrom(msg.sender, Ticket Master Contract, credit * price per credit)
SCSC->>SCSC: addCredit(NFTicket_id, credit)
SCSC-->>FE: return success
FE->>SCSC: request getCreditBalance(NFTicket_id)
SCSC-->>FE: return NFTicket credit balance
```
### passenger refund ticket (get credit balance)
:::success
*correspond to Nigeria sequence diagram **08.sequence-diagram-passenger-refund***
:::
```mermaid
sequenceDiagram
participant FE as Frontend
participant SCSC as Nigeria Service Contract
FE->>SCSC: request getCreditBalance(NFTicket_id)
SCSC-->>FE: return NFTicket credit balance
```
### passenger refund ticket (refund Ticket)
:::success
*correspond to Nigeria sequence diagram **08.sequence-diagram-passenger-refund***
:::
```mermaid
sequenceDiagram
participant FE as Frontend
participant BE as Backend
participant SCSC as Nigeria Service Contract
participant TMSC as Ticket Master Contract
participant ETSC as ERC20 token Contract
FE->>TMSC: request approve(Nigeria Service Contract address, NFTicket_id)
TMSC-->>FE: return success
BE->>SCSC: refundTicket(NFTicket_id, refund_credit_amount, passenger_wallet_address)
SCSC->>SCSC: verify NFTicket credit balance >= refund_credit_amount
SCSC->>SCSC: verifyIsGetApproved(Nigeria Service Contract address, NFTicket_id)
SCSC->>TMSC: request transferFrom(passenger wallet address, Ticket Master contract addrress, NFTicket_id)
SCSC->>SCSC: deductCredit(NFTicket_id, refund_credit_amount)
SCSC->>SCSC: get Price per credit and ERC20 token address
SCSC->>TMSC: request transferERC20TokenToWallet(msg.sender[Backend_wallet_address], ERC20 token address, refund_credit_amount * price per credit)
TMSC->>TMSC: verify caller is inServiceContractWhitelist
TMSC->>ETSC: transfer(msg.sender[Backend_wallet_address], refund_credit_amount * price per credit)
SCSC->>TMSC: request transferNFTicketToOriginalOwner(passenger wallet address, NFTicket_id)
TMSC->>TMSC: verify caller is inServiceContractWhitelist
TMSC->>TMSC: _transfer(Ticket Master contract addrress, passenger wallet addres, NFTicket_id)
SCSC->>SCSC: verifyTicketOwner(passenger wallet address, NFTicket_id)
SCSC-->>BE: return refund_credit_amount * price per credit
```
Backend will then exchange ERC20 token (to other crypto or cash) and transfer refund to passenger
### passenger complain
待規劃
###### tags: `NFTicket`