From 292a7ec2acd36230ac96293108906c615d73641a Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Mon, 15 Mar 2021 16:19:29 +0100 Subject: [PATCH] Wallet: open ledger channel --- nitro/wallet.nim | 32 +++++++++++++++------- tests/nitro/testWallet.nim | 55 +++++++++++++++++++++++++++++--------- 2 files changed, 64 insertions(+), 23 deletions(-) diff --git a/nitro/wallet.nim b/nitro/wallet.nim index 275f310..763647d 100644 --- a/nitro/wallet.nim +++ b/nitro/wallet.nim @@ -10,7 +10,7 @@ export keys type Wallet* = object key: PrivateKey - channels: seq[Channel] + channels*: seq[Channel] Channel* = object latest*, upcoming*: ?ChannelUpdate ChannelUpdate* = object @@ -23,13 +23,25 @@ proc init*(_: type Wallet, key: PrivateKey): Wallet = proc address*(wallet: Wallet): EthAddress = wallet.key.toPublicKey.toAddress -proc openLedger*(wallet: Wallet, asset: EthAddress, amount: UInt256): Channel = - let me = wallet.address.toDestination - let outcome = Outcome.init(asset, {me: amount}) - let state = State(outcome: outcome) - let signature = wallet.key.sign(state) - let update = ChannelUpdate( - state: state, - signatures: @{wallet.address: signature} +proc openLedgerChannel*(wallet: var Wallet, + hub: EthAddress, + chainId: UInt256, + nonce: UInt48, + asset: EthAddress, + amount: UInt256): Channel = + let state = State( + channel: ChannelDefinition( + chainId: chainId, + participants: @[wallet.address, hub], + nonce: nonce + ), + outcome: Outcome.init(asset, {wallet.address.toDestination: amount}) ) - Channel(upcoming: update.some) + let channel = Channel( + upcoming: ChannelUpdate( + state: state, + signatures: @{wallet.address: wallet.key.sign(state)} + ).some + ) + wallet.channels.add(channel) + channel diff --git a/tests/nitro/testWallet.nim b/tests/nitro/testWallet.nim index 3883d30..6028a83 100644 --- a/tests/nitro/testWallet.nim +++ b/tests/nitro/testWallet.nim @@ -1,23 +1,52 @@ import ./basics -suite "nitro wallet": +suite "wallet": + + test "wallet can be created from private key": + let key = PrivateKey.random() + let wallet = Wallet.init(key) + check wallet.address == key.toPublicKey.toAddress + +suite "wallet: opening ledger channel": let key = PrivateKey.random() let asset = EthAddress.example let amount = 42.u256 + let hub = EthAddress.example + let chainId = UInt256.example + let nonce = UInt48.example - test "wallet can be created from private key": - let wallet = Wallet.init(key) - check wallet.address == key.toPublicKey.toAddress + var wallet: Wallet + var channel: Channel - test "opens ledger channel": - let wallet = Wallet.init(key) - let me = wallet.address.toDestination - let channel = wallet.openLedger(asset, amount) - let expectedOutcome = Outcome.init(asset, {me: amount}) - let expectedState = State(outcome: expectedOutcome) - let expectedSignatures = @{wallet.address: key.sign(expectedState)} + setup: + wallet = Wallet.init(key) + channel = wallet.openLedgerChannel(hub, chainId, nonce, asset, amount) + + test "creates a new upcoming state": check channel.latest.isNone - check channel.upcoming?.state == expectedState.some - check channel.upcoming?.signatures == expectedSignatures.some + check channel.upcoming.isSome + + test "sets correct channel definition": + let definition = channel.upcoming?.state?.channel + check definition?.chainId == chainId.some + check definition?.nonce == nonce.some + check definition?.participants == @[wallet.address, hub].some + + test "provides correct outcome": + let outcome = channel.upcoming?.state?.outcome + let destination = wallet.address.toDestination + check outcome == Outcome.init(asset, {destination: amount}).some + + test "signs the upcoming state": + let state = channel.upcoming?.state + let signatures = channel.upcoming?.signatures + check signatures == @{wallet.address: key.sign(state.get)}.some + + test "sets app definition and app data to zero": + check channel.upcoming?.state?.appDefinition == EthAddress.zero.some + check channel.upcoming?.state?.appData?.len == 0.some + + test "updates the list of channels": + check wallet.channels == @[channel]