---
# System prepended metadata

title: RAFFLE

---

# RAFFLE

```plantuml
!include https://raw.githubusercontent.com/mariusgeorgescu/Project-Sputnik1/main/RaffleDApp-UC.puml
```
# USECASE DIAGRAM - RAFFLE

---
<div hidden>
    
```plantuml
@startuml
left to right direction
Actor User as U
Actor Participant as P
Actor Organizer as O

U <|-- P
U <|-- O

package wallet {
    usecase (construct & sign\n transaction) as tx
}

package website{
    usecase (Initiate raffle) as init
    usecase (View active raffles) as viewactive
    usecase (View raffles I joined) as viewjoin
    usecase (View raffles I created) as viewinit
    usecase (Buy tickets\n to raffle) as  buy
    usecase (Participate\n to raffle) as  join
    usecase (Refund) as refund
    usecase (Redeem) as redeem
    usecase (Close expired) as expired
    usecase (Reveal secret) as reveal
    usecase (Commit secret hash) as commit
    usecase (Re-commit secret hash) as recommit




    init ..> tx : inlcude
    buy ..> tx : inlcude
    join ..> tx : inlcude
    expired ..> tx : inlcude


    buy ..> commit : inlcude

    join ..> reveal : inlcude
    join <.. redeem : extend
    join <.. refund : extend
    join <.. recommit : extend

}

U --> tx
U --> viewactive
U --> init
U --> buy
P --> viewjoin
P --> join
O --> viewinit
O --> expired

@enduml
```
---

</div>

# STATE DIAGRAM - RAFFLE LIFECYCLE

---
```plantuml
@startuml

hide empty description

[*] --> NEW : Initiate Raffle
NEW: Asset
NEW --> [*] : Canceled By Organizer
NEW --> EXPIRED : Commit deadline\n reached
EXPIRED --> [*] : Closed by Organizer \nor by a Participant


NEW --> COMMIT : buyTickets (User, no, [ticketSecretHash] )

state COMMIT {
    state "Accumulate Amount" as acc
    acc : ticketsSold :: [Ticket]
    acc --> acc : buyTickets \n(User, no, [ticketSecretHash])
}
state C <<choice>>
COMMIT --> C : Commit deadline\n reached
C --> EXPIRED : Minimum amount \nNOT reached
C --> REVEAL : Minimum amount \nreached
state REVEAL {
    state "Collect secrets" as rv
    rv: secretsReceived :: [TicketSecret]
    rv --> rv : revealSecrets \n( User, [(secetID, secret)] )
}

REVEAL --> REDEEMABLE :All secrets received

state R <<choice>>
REVEAL --> R : Reveal deadline reached
R --> RECOMMIT : Not all secrets received
R --> REDEEMABLE : All secrets received


state RECOMMIT {
    state "Get new secret hashes \nfrom valid participants" as rc
    rc : ticketsActive :: [Ticket]
    rc --> rc : newSecretHashes \n(User, [(secretID, ticketSecretHash)] )
}
RECOMMIT --> REVEAL : Re-commit deadline\n reached

REDEEMABLE --> [*] : Redeemed by winner

@enduml
```
---


# CLASS DIAGRAM - RAFFLE 

---
```plantuml
@startuml

class Raffle {
    +id :: Int
    +status :: RaffleState
    +organizer :: User
    +asset :: Value
    +minimumAmount :: Value
    +ticketValue :: Value
    +commitDeadline :: Date
    +revealDeadline :: Date
    +ticketsSold :: [Ticket]
    +ticketsActive :: [Ticket]
    +secretsReceived :: [TicketSecret]
    +buyTickets ( User, no, [ticketSecretHash])
    +newSecretHashes (User, [(secretID, ticketSecretHash)] )
    +revealSecrets (User, [(secetID, secret)] )
    +cancel ( User )
    +redeem ( User )

}

User <|-- Organizer
User <|-- Participant

class User {
    +publicKeyHash : PKH :: Hash
}

class Organizer {
    +raffles : [raffleID] :: [Int]
}

class Participant {
    +tickets :: [ Ticket ]
    +secrets :: [ TicketSecret ]
 }

class Ticket {
    +ticketID :: Int
    +ticketSecretHash :: Hash
    +owner :: User
}

class TicketSecret {
    +secretID :: Int
    +secretValue :: Int
    }

TicketSecret "1" -- "1"  Ticket : is for >

Organizer "1" *-- "1..*"  Raffle : initiate >
Raffle "1" *-- "0..1"  Participant : is won by >

Participant "1" *-- "1..*" Ticket : buys >
Raffle "1" *-- "0..*" Ticket : sell >


@enduml
```



# SEQUENCE DIAGRAM - RAFFLE 

---
```plantuml
@startuml


actor Organizer as O
actor Participant as P

entity Raffle as R


O -> R ** : initiate raffle (asset, commitDate, revealDate, minAmnt, ticketVal)
opt cancel
    O -> R !! : Cancel Raffle
end

loop while commitDate not reached
    P -> R : buyTickets (User, no, [ticketSecretHash] )
    R -> R : update
    R --> P : ticketID
end

alt Min amoun reached
    loop while revealDate not reached
        P -> R : revealSecrets ( User, [(secetID, secret)] )
        R -> R: validate \n& update state
        R --> P : ok
    end
    alt All secrets received
        P -> R  : Redeem
        R -> R: validate \n& update state
        R --> P : ok

    else failure : Not all secrets received
        ref over P, R : re-commit process
    end
else failure : Min amount not reached
    alt Canceled by Organizer
        O -> R !! : Cancel Raffle
    else Canceled by any Participant
        P-> R !! : Cancel Raffle
    end
end

```
---

## Userstories (USER)
--- 

### USU-1: View active raffles
As a User, 
I want view active raffles  initiated by other users,
so that I can choose to participate in one of them.

#### Acceptance Criteria.

Scenario: User not logged in / (wallet not connected)
    Given User is not logged in / (wallet not connected)
    When  goes to main page
    Then  the following elements should be available
        -  A section where all active raffles are displayed;
        -  A option to create a raffle;
        -  An option to login (connect wallet);

Scenario: User logged in (wallet connected)
    Given User is already logged  / (wallet connected)
    When  goes to main page
    Then  the following elements should be available
        -  A section where all active raffles are displayed;
        -  A navigation menu;
        -  "logged user info" section;



### USU-2:  Create a raffle
As a User,
I want to create a raffle for one or more digital assets I own,
so that other users can buy chances (tickets) to win the asset/s and I'll get the funds in exchange.

#### Acceptance Criteria.

Scenario: Logged in user wants to create a raffle
    Given User is in the main page and is logged in.
    When User clicks on "Create new raffle"
    Then a new page should be displayed allowing the possibility  to select the digital asset/s which is/are subject of the raffle;

Scenario: Not logged in user wants to create a raffle
    Given User is in the main page and is not logged in.
    When User clicks on "Create new raffle"
    Then a the login page must be displayed for the user to log in  which will redirect "Create new raffle" page.


Scenario: Fill in raffle details
    Given Digital asset/s is/are selected for a given raffle.
    When Confirms selection
    Then a form with the following input fields
            - minimum amount that needs to be collected for the raffle to be valid;
            - the ticket price value;
            - the deadline for participating in the raffle;
            - the deadline for revealing ticket secret hashes;

Scenario: Create raffle
    Given Raffle details form is displayed.
    When All input fields are filled in with valid values.
    Then The "Create Raffle" button should become available.

Scenario: Raffle Created
    Given "Create Raffle" button is available
    When "Create Raffle" is pressed
    Then user must be returned to his "MyRaffles" page, where previously created raffle should be displayed besides his existing raffles.

Scenario: User exists/refresh the page before creating the raffle 
    Given Given User is in the "Create Raffle" page. 
          AND selected the digital assets .
          AND filled 0 or many raffle info fields.
    When exits the page.
    Then previous input is lost.
       


### USU-3: Buy ticket to raffle
As a User, 
I want to participate to a raffle,
so that I have a chance to win the prize.

#### Acceptance Criteria.

Scenario: Logged in user picks a raffle and wants to buy tickets
    Given User is logged in
    When user clicks on the "Buy Ticket" button next to the raffle he chose.
    Then a new page should be displayed containing the following elements:
            - Raffle info (tbd);
            - an input numeric field  ("No of tickets") for user to select the no. of tickets he wants to buy, by default filled with value 0;
            - the total cost of the tickets ("no of tickets" value * raffle's ticket price);
            - website navigation menu;

Scenario: Not logged in user picks a raffle and wants to buy tickets
    Given User is not logged in
    When user clicks on the "Buy Ticket" button next to the raffle he chose.
    Then a the login page must be displayed for the user to log in  which will redirect "Buy tickets" page of the slected raffle.

Scenario: User updates the value of the no of tickets 
    Given  User is in the "Buy tickets" page for a specific raffle. 
    When he changes the value in the "No of tickets" field.
    Then 
        1. the value of "Total cost" should be updated with the new "no of tickets" value multiplied by raffle's ticket price;
        2. for each ticket an empty input field (for ticket secret hash) should be displayed;

Scenario: Provide ticket secret hash\hashes
    Given User selected the "No of tickets" and input fields for secret hashes are displayed.
    When all fields are filled in.
    Then a "Payment" button should become available.


Scenario: Payment successful
    Given No of tickets selected and secret hashes provided.
    When  User successfully payed for tickets.
    Then  user must be returned to his "MyTickets" page, where previously bought tickets should be displayed besides his existing tickets.

Scenario: Payment unsuccessful -  TBD
    Given No of tickets selected and secret hashes provided.
    When  User payment was unsuccessful.
    Then  the following message should be displayed ...
        

Scenario: User exists/refresh the page before completing payment 
    Given Given User is in the "Buy tickets" page for a specific raffle. 
          AND selected the "No of tickets" value.
          AND filled 0 or many secret hash input fields.
    When exits the page.
    Then previous input is lost.


---
## Userstories (PARTICIPANT)
--- 
### USP-1: View joined raffles 
**As a** Participant, 
**I want** visualize raffles I joined,
**so that** I can follow the progress  

#### Acceptance Criteria.
1. For each raffle I joined, I should be able to see the following details
    - raffle status (active/closed)
    - for active raffles
      - the *minimum amount* that needs to be collected (or min. # of tickets) for the raffle to be valid.
      - amount collected so far
      - the *deadline for participating* in the raffle.
      - the  *deadline for claiming* the prize.
   - for closed raffles
     - if I am the winner
 - 
### USP-2: Redeem 
**As a** Participant, 
**I want** redeem my prize from raffles I won,
**so that** I'll be happy :-).

#### Acceptance Criteria.
TBD

### US-5: Refund 
**As a** Participant, 
**I want** get refunded for tickets bought to raffles that were not executed correctly,
**so that** I won't get frustrated.

#### Acceptance Criteria.
TBD

---
## Userstories (ORGANISER)
--- 
### USO-1: Close expired raffle 
**As an** Organizer, 
**I want** close an expired raffled created by me
**so that** I can unlock my asset/s.

#### Acceptance Criteria

### USO-2: View created raffles  
**As an** Organizer, 
**I want** visualize raffles I initiated,
**so that** I can follow the progress  

#### Acceptance Criteria.
1. For each raffle I initiated, I should be able to see the following details
    - raffle status (active/closed)
    - for active raffles
      - the *minimum amount* that needs to be collected (or min. # of tickets) for the raffle to be valid.
      - amount collected so far
      - the *deadline for participating* in the raffle.
      - the  *deadline for claiming* the prize.

---- 






