-
Notifications
You must be signed in to change notification settings - Fork 214
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
146 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
{-# LANGUAGE DataKinds #-} | ||
{-# LANGUAGE TypeApplications #-} | ||
module Cardano.Wallet.Primitive.Signing where | ||
|
||
import Prelude | ||
|
||
import Cardano.Wallet.Binary | ||
( TxWitness (..), encodeTx, toByteString ) | ||
import Cardano.Wallet.Primitive.AddressDerivation | ||
( ChangeChain (ExternalChain) | ||
, Depth (AddressK, RootK) | ||
, Key | ||
, Passphrase | ||
, SignTag (SignTx) | ||
, XPrv | ||
, deriveAccountPrivateKey | ||
, deriveAddressPrivateKey | ||
, encodeXPub | ||
, publicKey | ||
, sign | ||
) | ||
import Cardano.Wallet.Primitive.AddressDiscovery | ||
( SeqState (externalPool), lookupAddress ) | ||
import Cardano.Wallet.Primitive.Types | ||
( Address, Hash (..), Tx (..), TxIn, TxOut (..) ) | ||
import Control.Monad | ||
( forM ) | ||
import Crypto.Hash | ||
( Blake2b_256, hash ) | ||
import Data.ByteArray | ||
( convert ) | ||
import Data.ByteString | ||
( ByteString ) | ||
|
||
-- | Build a transaction | ||
|
||
-- | Construct a standard transaction | ||
-- | ||
-- " Standard " here refers to the fact that we do not deal with redemption, | ||
-- multisignature transactions, etc. | ||
-- | ||
-- TODO: re-add shuffle | ||
-- TODO: I removed FakeSigner/SafeSigner. Might be wrong. | ||
mkStdTx :: SeqState | ||
-> (Key 'RootK XPrv, Passphrase "encryption") | ||
-> [(TxIn, TxOut)] | ||
-- ^ Selected inputs | ||
-> [TxOut] | ||
-- ^ Selected outputs (including change) | ||
-> Maybe (Tx, [TxWitness]) | ||
mkStdTx seqState (rootPrv, pwd) ownedIns outs = do | ||
|
||
let ins = (fmap fst ownedIns) | ||
tx = Tx ins outs | ||
txSigData = hashTx tx | ||
|
||
txWitness <- forM ownedIns (\(_in, TxOut addr _c) -> mkWitness txSigData <$> keyFrom addr) | ||
|
||
return (tx, txWitness) | ||
|
||
where | ||
hashTx :: Tx -> Hash "tx" | ||
hashTx tx = Hash | ||
$ convert | ||
$ (hash @ByteString @Blake2b_256) | ||
$ toByteString | ||
$ encodeTx tx | ||
|
||
keyFrom :: Address -> (Maybe (Key 'AddressK XPrv)) | ||
keyFrom addr = do | ||
-- We are assuming there is only one account | ||
let account = minBound | ||
let accountPrv = deriveAccountPrivateKey pwd rootPrv account | ||
|
||
-- We are ignoring the new state/pool. We won't discover any new | ||
-- addresses when submitting transactions. | ||
index <- fst $ lookupAddress addr (externalPool seqState) | ||
|
||
return $ deriveAddressPrivateKey pwd accountPrv ExternalChain index | ||
|
||
mkWitness :: Hash "tx" -> Key 'AddressK XPrv -> TxWitness | ||
mkWitness tx xPrv = | ||
PublicKeyWitness $ | ||
encodeXPub (publicKey xPrv) <> | ||
getHash (sign (SignTx tx) (xPrv, pwd)) |