diff --git a/src/Lib/Serialization.js b/src/Lib/Serialization.js index 7e668b3b7d..ab2385d1b6 100644 --- a/src/Lib/Serialization.js +++ b/src/Lib/Serialization.js @@ -1,5 +1,20 @@ "use strict"; const Buffer = require("buffer/").Buffer; +const serLib = require("@emurgo/cardano-serialization-lib-nodejs"); +// _hexToBytes :: Hex -> Buffer exports._hexToBytes = (hex) => Buffer.from(hex, "hex"); + +// _addrFromBytes :: Buffer -> Address +exports._addrFromBytes = (buf) => { + const addr = serLib.Address.from_bytes(buf); + const baseAddr = serLib.BaseAddress.from_address(addr); + return { + AddrType: { + network: addr.network_id(), + stake: baseAddr.stake_cred(), + payment: baseAddr.payment_cred(), + }, + }; +}; diff --git a/src/Lib/Serialization.purs b/src/Lib/Serialization.purs index 4705dda728..09bce8a414 100644 --- a/src/Lib/Serialization.purs +++ b/src/Lib/Serialization.purs @@ -1,10 +1,11 @@ module Lib.Serialization ( Buffer , Hex(..) + , _addrFromBytes , _hexToBytes ) where -import Prelude +import Types.Transaction (Address) newtype Hex = Hex String @@ -12,3 +13,5 @@ newtype Hex foreign import data Buffer :: Type foreign import _hexToBytes :: Hex -> Buffer + +foreign import _addrFromBytes :: Buffer -> Address diff --git a/src/Types/Transaction.purs b/src/Types/Transaction.purs index fbe6c9f172..c0296fefbe 100644 --- a/src/Types/Transaction.purs +++ b/src/Types/Transaction.purs @@ -76,7 +76,7 @@ newtype PlutusScript = PlutusScript String newtype PlutusData = PlutusData String -- TODO - we need a capability to encode/decode Datum from/to serialized format --- see `makeIsDataIndexed` +-- see `makeIsDataIndexed` newtype Redeemer = Redeemer { tag :: RedeemerTag, -- ScriptPurpose: 'spending' 'minting' etc @@ -122,7 +122,7 @@ newtype BaseAddress = BaseAddress newtype Credential = Credential String -- Addresspub struct Address(AddrType); --- AddrType +-- AddrType -- enum AddrType { -- Base(BaseAddress), -- Ptr(PointerAddress), @@ -135,7 +135,7 @@ newtype Credential = Credential String -- payment: StakeCredential, -- stake: StakeCredential, -- } --- pub struct StakeCredential(StakeCredType); +-- pub struct StakeCredential(StakeCredType); -- Both of these are strings: -- enum StakeCredType { -- Key(Ed25519KeyHash), diff --git a/src/Types/Wallet.js b/src/Types/Wallet.js index 947e50c60a..88b352b8c2 100644 --- a/src/Types/Wallet.js +++ b/src/Types/Wallet.js @@ -11,3 +11,7 @@ exports._mkNamiConnection = (just) => (nothing) => () => { // _enableNami :: NamiConnection -> Effect (Promise NamiConnection) exports._enableNami = (nami) => () => nami.enable(); + +// _getUsedAddress :: NamiConnection -> Effect (Promise Hex) +exports._getUsedAddress = (nami) => () => + nami.getUsedAddresses().then((addrs) => addrs[0]); diff --git a/src/Types/Wallet.purs b/src/Types/Wallet.purs index e696e4d192..c7598c2882 100644 --- a/src/Types/Wallet.purs +++ b/src/Types/Wallet.purs @@ -11,11 +11,14 @@ import Control.Monad.Error.Class (throwError) import Control.Promise (Promise) import Control.Promise as Promise import Data.Maybe (Maybe(..), maybe) +import Data.Typelevel.Undefined (undefined) import Effect (Effect) import Effect.Aff (Aff) import Effect.Class (liftEffect) import Effect.Exception (error) import Effect.Ref as Ref +import Lib.Serialization (Hex, _addrFromBytes, _hexToBytes) +import Types.Transaction (Address(..), BaseAddress(..), Credential(..)) -- At the moment, we only support Nami's wallet. In the future we will expand -- this with more constructors to represent out-of-browser wallets (e.g. WBE) @@ -29,14 +32,15 @@ newtype Wallet w -- connection (e.g. with `window.cardano` as a `NamiConnection`) -- -- TODO --- All of these should eventually return `Aff (Either ...)`s; all of the Nami --- `window.cardano` methods might throw exceptions (e.g. if the user has +-- All of these should eventually return `Aff (Either ...)`s; all of the +-- `window.cardano.nami` methods might throw exceptions (e.g. if the user has -- not granted access to the wallet) type NamiWallet w = { connection :: Ref.Ref w - -- ^ A reference to a connection with Nami, i.e. `window.cardano` + -- ^ A reference to a connection with Nami, i.e. `window.cardano.nami` , enable :: w -> Aff w -- ^ Request that the user grant access to their nami wallet + , getWalletAddress :: w -> Aff Address } -- Make a `Wallet NamiConnection` with a reference to a `window.cardano` object @@ -49,11 +53,17 @@ mkNamiWallet = Ref.new =<< maybe throwConnError pure =<< _mkNamiConnection Just Nothing - pure $ Nami { connection, enable } + pure $ Nami { connection, enable, getWalletAddress } where enable :: NamiConnection -> Aff NamiConnection enable = Promise.toAffE <<< _enableNami + getWalletAddress :: NamiConnection -> Aff Address + getWalletAddress nami = + _addrFromBytes + <<< _hexToBytes + <$> Promise.toAffE (_getUsedAddress nami) + throwConnError :: Effect NamiConnection throwConnError = throwError @@ -71,6 +81,17 @@ mockNamiWallet = $ Nami { connection , enable: const $ pure unit + , getWalletAddress: + const + $ pure + $ Address + { "AddrType": + BaseAddress + { network: 0 + , payment: Credential mempty + , stake: Credential mempty + } + } } foreign import data NamiConnection :: Type @@ -82,3 +103,5 @@ foreign import _mkNamiConnection :: Effect (Maybe NamiConnection) foreign import _enableNami :: NamiConnection -> Effect (Promise NamiConnection) + +foreign import _getUsedAddress :: NamiConnection -> Effect (Promise Hex)