diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..2b5de01c989a4cfab60d17af82888d27bd14f606
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+.bloop
+.metals
+target
+project/project
+metals.sbt
+.bsp
+.vscode
\ No newline at end of file
diff --git a/bank-actors/Account.scala b/bank-actors/Account.scala
new file mode 100644
index 0000000000000000000000000000000000000000..f915dab285fc29f2650f1ff6d76b07cf767f5433
--- /dev/null
+++ b/bank-actors/Account.scala
@@ -0,0 +1,32 @@
+import akka.actor.typed.ActorRef
+import akka.actor.typed.Behavior
+import akka.actor.typed.scaladsl.Behaviors
+
+object Account:
+  enum Message:
+    case GetBalance(sender: ActorRef[Balance])
+    case Deposit(amount: Int, client: ActorRef[MovementResponse])
+    case Withdraw(amount: Int, client: ActorRef[MovementResponse])
+
+  
+  
+  case class Balance(balance: Int)
+  enum MovementResponse:
+    case Ok
+    case NotOk
+
+  def behavior(number: Int, balance: Int): Behavior[Message] = Behaviors.receiveMessage {
+    case Message.GetBalance(sender) =>
+      sender ! Balance(balance)
+      Behaviors.same
+    case Message.Deposit(amount, client) =>
+      client ! MovementResponse.Ok
+      behavior(number,balance + amount)
+    case Message.Withdraw(amount, client) => 
+      if balance >= amount then
+        client ! MovementResponse.Ok
+        behavior(number,balance - amount)
+      else 
+        client ! MovementResponse.NotOk
+        Behaviors.same
+  }
\ No newline at end of file
diff --git a/bank-actors/Bank.scala b/bank-actors/Bank.scala
new file mode 100644
index 0000000000000000000000000000000000000000..7f40b1be5132b473668ff98a060954b7010ca7ed
--- /dev/null
+++ b/bank-actors/Bank.scala
@@ -0,0 +1,64 @@
+import akka.actor.typed.ActorSystem
+import akka.actor.typed.{ActorRef,Behavior}
+import akka.actor.typed.scaladsl.Behaviors
+
+object Bank:
+  enum Message:
+    case CreateAccount(sender: ActorRef[Response.AccountCreated])
+    case AccountMessage(account: Int, msg: Account.Message)
+    case Transfer(from: Int, to: Int, amount: Int, client: ActorRef[Account.MovementResponse])
+
+  enum Response:
+    case AccountCreated(number: Int)
+
+  def behavior(accounts: Map[Int,ActorRef[Account.Message]]): Behavior[Message] = Behaviors.setup { context =>
+    Behaviors.receiveMessage {
+      case Message.CreateAccount(sender) =>
+        val number = accounts.size
+        val accountActor = context.spawn(Account.behavior(number, 0), s"account-$number")
+        sender ! Response.AccountCreated(number)
+        behavior(accounts + (number -> accountActor))
+      case Message.AccountMessage(account, msg) => 
+        accounts.get(account).foreach(_ ! msg)
+        Behaviors.same
+      case Message.Transfer(fromId,toId,amount,client) =>
+        val transferActor = for {
+          from <- accounts.get(fromId)
+          to <- accounts.get(toId)
+        } yield context.spawnAnonymous(WireTransfer.init(from,to,amount,client))                       
+        transferActor.getOrElse(client ! Account.MovementResponse.NotOk)
+        Behaviors.same
+      }
+  }
+    
+    
+
+@main def main = 
+  val testBehavior = Behaviors.setup[Bank.Response | Account.Balance | Account.MovementResponse] { ctx =>
+    val bank = ctx.spawn(Bank.behavior(Map.empty), "bank")
+    bank ! Bank.Message.CreateAccount(ctx.self)
+    Behaviors.receiveMessage {
+      case Bank.Response.AccountCreated(x) => 
+        ctx.log.info(s"account $x was created")
+        bank ! Bank.Message.CreateAccount(ctx.self)
+        Behaviors.receiveMessage {
+          case Bank.Response.AccountCreated(y) =>
+            ctx.log.info(s"account $y was created")
+            bank ! Bank.Message.AccountMessage(x, Account.Message.Deposit(1000, ctx.self))            
+            bank ! Bank.Message.AccountMessage(y, Account.Message.Withdraw(500, ctx.self))            
+            bank ! Bank.Message.Transfer(x,y,5,ctx.self)            
+            Behaviors.same
+          case Account.Balance(x) =>
+            ctx.log.info(s"the balance is $x")
+            Behaviors.same
+          case Account.MovementResponse.Ok =>
+            ctx.log.info(s"ok")
+            bank ! Bank.Message.AccountMessage(x, Account.Message.GetBalance(ctx.self))             
+            Behaviors.same
+          case Account.MovementResponse.NotOk =>
+            ctx.log.info(s"not ok")
+            Behaviors.same
+        }        
+    }
+  }
+  val bank = ActorSystem(testBehavior, "test-system")
\ No newline at end of file
diff --git a/bank-actors/WireTransfer.scala b/bank-actors/WireTransfer.scala
new file mode 100644
index 0000000000000000000000000000000000000000..5cb62e061d81f7ea6eda928cae02fc9e1f89f280
--- /dev/null
+++ b/bank-actors/WireTransfer.scala
@@ -0,0 +1,37 @@
+import akka.actor.typed.Behavior
+import akka.actor.typed.ActorRef
+import akka.actor.typed.scaladsl.Behaviors
+
+object WireTransfer:
+  def init(
+    from: ActorRef[Account.Message],
+    to: ActorRef[Account.Message],
+    amount: Int,
+    client: ActorRef[Account.MovementResponse]
+  ): Behavior[Account.MovementResponse] = Behaviors.setup { ctx =>      
+      def waitForWithdrawal: Behavior[Account.MovementResponse] = Behaviors.receiveMessage { 
+        case Account.MovementResponse.Ok =>
+          to ! Account.Message.Deposit(amount, ctx.self)
+          waitForDeposit
+        case Account.MovementResponse.NotOk =>
+          client ! Account.MovementResponse.NotOk
+          Behaviors.stopped
+      }
+      def waitForDeposit: Behavior[Account.MovementResponse] = Behaviors.receiveMessage {
+        case Account.MovementResponse.Ok => 
+          client ! Account.MovementResponse.Ok
+          Behaviors.stopped
+        case Account.MovementResponse.NotOk =>
+          from ! Account.Message.Deposit(amount, ctx.self)       
+          client ! Account.MovementResponse.NotOk
+          waitForCancel
+      }
+      def waitForCancel: Behavior[Account.MovementResponse] = Behaviors.receiveMessage {
+        case Account.MovementResponse.Ok =>
+          Behaviors.stopped
+        case Account.MovementResponse.NotOk =>
+          sys.error("wire transfer did not succeed. money stuck in transient state.")
+      }
+      from ! Account.Message.Withdraw(amount, ctx.self)
+      waitForWithdrawal
+    }
diff --git a/bank-actors/build.sbt b/bank-actors/build.sbt
new file mode 100644
index 0000000000000000000000000000000000000000..4d8b552c339c3ba46efe03e257fb3ee47159cb42
--- /dev/null
+++ b/bank-actors/build.sbt
@@ -0,0 +1,11 @@
+name := "lecture-04.5"
+scalaVersion := "3.1.1"
+val AkkaVersion = "2.6.19"
+val Slf4jVersion = "1.7.36"
+libraryDependencies ++= Seq(
+  "com.typesafe.akka" %% "akka-actor-typed" % AkkaVersion,
+  "com.typesafe.akka" %% "akka-actor-testkit-typed" % AkkaVersion,
+  "org.slf4j" % "slf4j-api" % Slf4jVersion,
+  "org.slf4j" % "slf4j-simple" % Slf4jVersion
+)
+Compile / scalaSource := baseDirectory.value
\ No newline at end of file
diff --git a/bank-actors/project/build.properties b/bank-actors/project/build.properties
new file mode 100644
index 0000000000000000000000000000000000000000..c8fcab543a9cfc5c5c21bb0b6cc80414275625ef
--- /dev/null
+++ b/bank-actors/project/build.properties
@@ -0,0 +1 @@
+sbt.version=1.6.2