---
# System prepended metadata

title: 'NFTicket, Nigeria Sequence Diagram (V2)'
tags: [NFTicket]

---

# NFTicket, Nigeria Sequence Diagram (V2)

## Smart Contract Architecture

![](https://i.imgur.com/G2t1WBg.png)

-----------
## 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`