Wallet: open ledger channel

This commit is contained in:
Mark Spanbroek 2021-03-15 16:19:29 +01:00
parent d1c580eb91
commit 292a7ec2ac
2 changed files with 64 additions and 23 deletions

View File

@ -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

View File

@ -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]