Draft of Rholang Wallet code

    // Creates a coat check service
    contract MakeCoatCheck(ret) = {
      new (portIn, portOut):iopair, hanger in {
        ret!(*portOut) |
        for (@method, ack, ...@rest <= portIn) {
          match method {
            // Initially checks the coat
            case "new" => match rest {
              case (initialCoat) => new ticket in {
                ack!(*ticket) |
                // Hang the coat on the hanger corresponding
                // to the ticket
                @(*ticket | *hanger)!(initialCoat)
              }      
            }
            // Retrieves the coat
            case "get" => match rest {
              case (ticket) => {
                // Find the right hanger
                for (@coat <! @(*ticket | *hanger)) {
                  // Return the coat
                  ack!(coat)
                }
              }
            }
            // Replaces the old coat with a new one.
            case "set" => match rest {
              case (store, @newCoat) => {
                // Throw away the existing coat
                for (_ <- @(*ticket | *hanger)) {
                  // Hang up the new one
                  @(*ticket | *hanger)!(newCoat) |
                  ack!()
                }
              }
            }
          }
        }
      }
    }

    // Attenuation of coat check for sealing and unsealing
    contract MakeSealerUnsealer(ret) =  {
      new (sealerIn, sealerOut):iopair,
          (unsealerIn, unsealerOut):iopair,
          mapRet in {

        ret!(*sealerOut, *unsealerOut) |
        MakeCoatCheck(ccRet) |
        for (cc <- ccRet) {
          for (@value, ret <= sealerIn) {
            cc!("new", *ret, value)
          } |
          for (ticket, ret <= unsealerIn) {
            cc!("get", *ret, *ticket)
          }
        }
      }
    }
    
    // MakeSealerUnsealer usage
    new ret in {
      MakeSealerUnsealer(ret) |
      for (sign, validate <- ret) {
        new signatureRet in {
          sign("Hello", signatureRet) |
          for (signature <- signatureRet) {
            new ack in {
              // Hangs if signature is invalid
              validate(signature, ack) |
              for (_ <- ack) {
                // Act on signed message
              }
            }
          }
        }
      }
    }

    contract MakeMint(ret) = {
      new suRet in {
        MakeSealerUnsealer(suRet) |
        for (sealer, unsealer <- suRet) {
          new (makeWalletIn, makeWalletOut):iopair in {
            for (@initialBalance, walletRet <= makeWalletIn) {
              new (walletIn, walletOut):iopair, balance, 
                  (decrIn, decrOut):iopair in {
                balance!(initialBalance) |
                for (@amount, ack <= decrIn) {
                  for (@currentBalance <- balance) {
                    if (amount <= currentBalance) {
                      balance!(currentBalance - amount)
                      ack!(true)
                    } else {
                      balance!(currentBalance)
                      ack!(false)
                    }
                  }
                } |
                for (@method, methodRet, ...args <= walletIn) {
                  match method {
                    case "getBalance" => {
                      for (@currentBalance <! balance) {
                        methodRet!(currentBalance)
                      }
                    }
                    case "sprout" => {
                      makeWalletOut!(0, methodRet)
                    }
                    case "getDecr" => {
                      sealer!(decrOut, methodRet)
                    }
                    case "deposit" => {
                      args match {
                        (amount, src) => new decrRet in {
                          @src!("getDecr", decrRet) |
                          for (srcDecr <- decrRet) new unsealedRet in {
                            unsealer!(srcDecr, unsealedRet) |
                            for (unsealed <- unsealedRet; 
                                @currentBalance <- balance) new ack in {
                              unsealed(amount, ack) |
                              for (@result <- ack) {
                                if (result) {
                                  balance!(currentBalance + amount)
                                } else {
                                  balance!(currentBalance)
                                } |
                                methodRet!()
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              } |
              walletRet!(walletOut)
            } |
            ret!(*makeWalletOut)
          }
        }
      }
    }
    
    // Usage
    new mintRet in {
      // Create a new currency/token/mint
      MakeMint(mintRet) |
      for (mint <- mintRet) new wallet1Ret, wallet2Ret in {
        // Call mint with an initial balance to mint some money
        // and put it in the wallet
        mint(100, wallet1Ret) |
        mint(200, wallet2Ret) |
        for (wallet1 <- wallet1Ret; wallet2 <- wallet2Ret) {
          // Move 50 tokens from wallet1 to wallet2
          new ack in {
            wallet2!("deposit", 50, wallet1, ack) |
            for (_ <- ack) new balanceRet in {
              wallet2!("getBalance", balanceRet) |
              for (@balance <- balanceRet) {
                // Prints 250
                system!("print", balance)
              }
            }
          }
        }
      }
    }