From 52e6c01782e0858eac5cef950b78be7d1ded18d1 Mon Sep 17 00:00:00 2001 From: Ilya Ostrovskiy Date: Mon, 28 Aug 2023 22:09:36 -0400 Subject: [PATCH] Purs 0.15 (#32) * wip * remove unused deps * refactor FFI to use CommonJS imports * Remove foreign-generic De-/Encode in favor of simple-json Read-/WriteForeign * run travis on ubuntu jammy as its latest lts * bump tidy version, always run tidy-check * run tidy * add .tidyrc.json for purs-tidy consistency * remove named instances * README * Forcing an empty commit. * Forcing an empty commit. --------- Co-authored-by: martyall --- .gitignore | 1 + .tidyrc.json | 8 ++++ .travis.yml | 4 +- README.md | 3 -- package.json | 9 ++-- packages.dhall | 36 +++++++++++++++- spago.dhall | 3 -- src/Network/Ethereum/Core/BigNumber.js | 34 +++++++-------- src/Network/Ethereum/Core/BigNumber.purs | 41 ++++++++---------- src/Network/Ethereum/Core/HexString.js | 7 ++- src/Network/Ethereum/Core/HexString.purs | 39 +++++++---------- src/Network/Ethereum/Core/Keccak256.js | 4 +- src/Network/Ethereum/Core/Keccak256.purs | 6 +-- src/Network/Ethereum/Core/RLP.js | 6 +-- src/Network/Ethereum/Core/RLP.purs | 2 +- src/Network/Ethereum/Core/Signatures.js | 17 ++++---- src/Network/Ethereum/Core/Signatures.purs | 52 +++++++++++------------ test/Common.purs | 6 +-- test/Spec/BigNumber.purs | 17 +++----- test/Spec/Hex.purs | 17 +++----- 20 files changed, 161 insertions(+), 151 deletions(-) create mode 100644 .tidyrc.json diff --git a/.gitignore b/.gitignore index ad77cd3..c7f029e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ package-lock.json yarn.lock /.spago/ +.vscode diff --git a/.tidyrc.json b/.tidyrc.json new file mode 100644 index 0000000..e7de9f0 --- /dev/null +++ b/.tidyrc.json @@ -0,0 +1,8 @@ +{ + "indent": 2, + "operatorsFile": null, + "ribbon": 1, + "typeArrowPlacement": "first", + "unicode": "never", + "width": null +} diff --git a/.travis.yml b/.travis.yml index 2e78550..234a196 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: node_js -dist: focal +dist: jammy sudo: required node_js: stable install: @@ -8,7 +8,7 @@ install: - spago build script: - npm run test - - if [ "$TRAVIS_BRANCH" == "master" ]; then npm run tidy-check; fi + - npm run tidy-check after_success: - >- test $TRAVIS_TAG && diff --git a/README.md b/README.md index de37350..0fe7e1f 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,3 @@ [![Build Status](https://travis-ci.com/f-o-a-m/purescript-eth-core.svg?branch=master)](https://travis-ci.com/f-o-a-m/purescript-eth-core) Common types and utility functions for all web3 libraries - - -⚠️ You will also need to install additional **npm** dependencies specified [here](https://github.com/f-o-a-m/purescript-eth-core/blob/master/package.json#L7-L10) diff --git a/package.json b/package.json index 8b56479..42185ba 100644 --- a/package.json +++ b/package.json @@ -4,18 +4,17 @@ "dependencies": { "bn.js": "^4.11.0", "keccak": "^1.0.2", - "pulp": "^15.0.0", "rlp": "^2.0.0", "secp256k1": "^3.0.1" }, "devDependencies": { - "purescript": "^0.14.2", + "purescript": "^0.15.8", "purescript-psa": "^0.8.2", - "purs-tidy": "^0.8.0", - "spago": "^0.20.3" + "purs-tidy": "^0.10.0", + "spago": "^0.20.9" }, "scripts": { - "build-strict": "spago build", + "build": "spago build", "tidy": "purs-tidy format-in-place \"src/**/*.purs\" \"test/**/*.purs\"", "tidy-check": "purs-tidy check \"src/**/*.purs\" \"test/**/*.purs\"", "test": "spago -x test.dhall test" diff --git a/packages.dhall b/packages.dhall index 84fb1e8..b7b6a7c 100644 --- a/packages.dhall +++ b/packages.dhall @@ -1,4 +1,36 @@ let upstream = - https://github.com/purescript/package-sets/releases/download/psc-0.14.2-20210629/packages.dhall sha256:534c490bb73cae75adb5a39871142fd8db5c2d74c90509797a80b8bb0d5c3f7b + https://github.com/purescript/package-sets/releases/download/psc-0.15.7-20230306/packages.dhall + sha256:0757626c7422b8b5b5b1d0df3d3628e5deac755d7f89c433a9bf89009787dcbd -in upstream +let additions = + { bytestrings = + { dependencies = + [ "arrays" + , "console" + , "effect" + , "exceptions" + , "foldable-traversable" + , "integers" + , "leibniz" + , "maybe" + , "newtype" + , "node-buffer" + , "partial" + , "prelude" + , "quickcheck" + , "quickcheck-laws" + , "quotient" + , "unsafe-coerce" + ] + , repo = + "https://github.com/rightfold/purescript-bytestrings" + , version = "6733a32fca306015b3428e9985ffac65325a9864" + } + , quotient = + { dependencies = [ "prelude", "quickcheck" ] + , repo = "https://github.com/rightfold/purescript-quotient.git" + , version = "v3.0.0" + } + } + +in upstream // additions diff --git a/spago.dhall b/spago.dhall index aee3908..a3034c1 100644 --- a/spago.dhall +++ b/spago.dhall @@ -6,16 +6,13 @@ , "effect" , "either" , "foreign" - , "foreign-generic" , "functions" , "integers" , "maybe" , "node-buffer" , "ordered-collections" - , "parsing" , "partial" , "prelude" - , "psci-support" , "quotient" , "ring-modules" , "simple-json" diff --git a/src/Network/Ethereum/Core/BigNumber.js b/src/Network/Ethereum/Core/BigNumber.js index 9a89063..224c830 100644 --- a/src/Network/Ethereum/Core/BigNumber.js +++ b/src/Network/Ethereum/Core/BigNumber.js @@ -1,48 +1,48 @@ "use strict"; -var BigNumber = require('bn.js'); +import BigNumber from "bn.js"; //NOTE: According to the documentation, many binary operators can take a normal js Number //by suffixing the version for BN with 'n'. -exports._intToBigNumber = function(value) { +export const _intToBigNumber = function(value) { return new BigNumber(value.toString(10), 10); }; -exports._numberToBigNumber = function(value) { +export const _numberToBigNumber = function(value) { return new BigNumber(value); }; -exports._eqBigNumber = function(n) { +export const _eqBigNumber = function(n) { return function(m) { return m.eq(n); }; }; -exports._addBigNumber = function(n) { +export const _addBigNumber = function(n) { return function (m) { return n.add(m); }; }; -exports._mulBigNumber = function(n) { +export const _mulBigNumber = function(n) { return function (m) { return n.mul(m); }; }; -exports._subBigNumber = function(n) { +export const _subBigNumber = function(n) { return function (m) { return n.sub(m); }; }; -exports._divBigNumber = function(n) { +export const _divBigNumber = function(n) { return function (m) { return n.div(m); } } -exports._modBigNumber = function(n) { +export const _modBigNumber = function(n) { return function(m) { return n.mod(m); } } -exports.comparedTo = function (a) { +export const comparedTo = function (a) { return function (b) { return a.cmp(b); }; }; -exports.fromStringAsImpl = function (just) { +export const fromStringAsImpl = function (just) { return function (nothing) { return function (radix) { var digits; @@ -72,11 +72,11 @@ exports.fromStringAsImpl = function (just) { }; }; -exports.toString = function (radix) { +export const toString = function (radix) { return function (bn) { return bn.toString(radix); }; }; -exports.toTwosComplement = function (bn) { +export const toTwosComplement = function (bn) { if (bn.ltn(0)) { return new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).add(bn).addn(1); } else { @@ -84,20 +84,20 @@ exports.toTwosComplement = function (bn) { } }; -exports.floorBigNumber = function(bn) { +export const floorBigNumber = function(bn) { var bnStr = bn.toString(10); var newBn = new BigNumber(bnStr, 10); return newBn; }; -exports.pow = function(n) { +export const pow = function(n) { return function (m) { var exp = new BigNumber(m, 10); return n.pow(exp); }; }; -exports.toNumber = function (n) { +export const toNumber = function (n) { var newN = new BigNumber(n); return newN.toNumber(); }; @@ -112,7 +112,7 @@ var isString = function (object) { (object && object.constructor && object.constructor.name === 'String'); }; -exports.divide = function (n) { +export const divide = function (n) { return function (d) { var newN = n.div(d); return newN; diff --git a/src/Network/Ethereum/Core/BigNumber.purs b/src/Network/Ethereum/Core/BigNumber.purs index b818716..b21ac08 100644 --- a/src/Network/Ethereum/Core/BigNumber.purs +++ b/src/Network/Ethereum/Core/BigNumber.purs @@ -21,8 +21,7 @@ import Data.Int (Radix, binary, decimal, hexadecimal, floor) as Int import Data.Maybe (Maybe(..)) import Data.Ring.Module (class LeftModule, class RightModule) import Foreign (ForeignError(..), readString, fail) -import Foreign.Class (class Decode, class Encode, decode, encode) -import Simple.JSON (class ReadForeign, class WriteForeign) +import Simple.JSON (class ReadForeign, class WriteForeign, writeImpl) -------------------------------------------------------------------------------- -- * BigNumber @@ -34,17 +33,17 @@ foreign import data BigNumber :: Type -- | Convert a Big number into a string in the given base foreign import toString :: Int.Radix -> BigNumber -> String -instance showBigNumber :: Show BigNumber where +instance Show BigNumber where show = toString Int.decimal foreign import _eqBigNumber :: BigNumber -> BigNumber -> Boolean -instance eqBigNumber :: Eq BigNumber where +instance Eq BigNumber where eq = _eqBigNumber foreign import comparedTo :: BigNumber -> BigNumber -> Int -instance ordBigNumber :: Ord BigNumber where +instance Ord BigNumber where compare bn1 bn2 = let n = comparedTo bn1 bn2 @@ -65,7 +64,7 @@ embedInt = _intToBigNumber foreign import _numberToBigNumber :: Number -> BigNumber -instance semiringBigNumber :: Semiring BigNumber where +instance Semiring BigNumber where add = _addBigNumber mul = _mulBigNumber zero = embedInt 0 @@ -73,27 +72,27 @@ instance semiringBigNumber :: Semiring BigNumber where foreign import _subBigNumber :: BigNumber -> BigNumber -> BigNumber -instance ringBigNumber :: Ring BigNumber where +instance Ring BigNumber where sub = _subBigNumber -instance commutativeRingBigNumber :: CommutativeRing BigNumber +instance CommutativeRing BigNumber foreign import _divBigNumber :: BigNumber -> BigNumber -> BigNumber foreign import _modBigNumber :: BigNumber -> BigNumber -> BigNumber -instance euclidianRingBigNumber :: EuclideanRing BigNumber where +instance EuclideanRing BigNumber where degree _ = 1 div = _divBigNumber mod = _modBigNumber -instance bigNumberLModule :: LeftModule BigNumber Int where +instance LeftModule BigNumber Int where mzeroL = embedInt 0 maddL = add msubL = sub mmulL a b = embedInt a * b -instance bigNumberRModule :: RightModule BigNumber Int where +instance RightModule BigNumber Int where mzeroR = embedInt 0 maddR = add msubR = sub @@ -102,7 +101,7 @@ instance bigNumberRModule :: RightModule BigNumber Int where class (Ring r, Ring a, LeftModule a r, RightModule a r) <= Algebra a r where embed :: r -> a -instance embedInt' :: Algebra BigNumber Int where +instance Algebra BigNumber Int where embed = embedInt foreign import divide :: BigNumber -> BigNumber -> BigNumber @@ -141,24 +140,18 @@ _decode str = case parseBigNumber Int.hexadecimal str of Nothing -> Left $ "Failed to parse as BigNumber: " <> str Just n -> Right n -instance decodeBigNumber :: Decode BigNumber where - decode x = do +instance ReadForeign BigNumber where + readImpl x = do str <- readString x either (fail <<< ForeignError) pure $ _decode str -instance readFBigNumber :: ReadForeign BigNumber where - readImpl = decode +instance WriteForeign BigNumber where + writeImpl = writeImpl <<< _encode -instance writeFBigNumber :: WriteForeign BigNumber where - writeImpl = encode - -instance encodeBigNumber :: Encode BigNumber where - encode = encode <<< _encode - -instance decodeJsonBigNumber :: A.DecodeJson BigNumber where +instance A.DecodeJson BigNumber where decodeJson json = do str <- A.decodeJson json either (const <<< Left $ UnexpectedValue json) Right $ _decode str -instance encodeJsonBigNumber :: A.EncodeJson BigNumber where +instance A.EncodeJson BigNumber where encodeJson = A.encodeJson <<< _encode diff --git a/src/Network/Ethereum/Core/HexString.js b/src/Network/Ethereum/Core/HexString.js index cc8efe1..e1d5651 100644 --- a/src/Network/Ethereum/Core/HexString.js +++ b/src/Network/Ethereum/Core/HexString.js @@ -1,8 +1,7 @@ "use strict"; +import BigNumber from "bn.js"; -var BigNumber = require('bn.js'); - -exports.toBigNumber = function(str) { +export const toBigNumber = function(str) { return new BigNumber(str, 16); }; @@ -17,7 +16,7 @@ var signedIsNegative = function (value) { return msb === '1'; }; -exports.toBigNumberFromSignedHexString = function (value) { +export const toBigNumberFromSignedHexString = function (value) { if (signedIsNegative(value)) { return new BigNumber(value, 16).sub(new BigNumber('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16)).subn(1); } diff --git a/src/Network/Ethereum/Core/HexString.purs b/src/Network/Ethereum/Core/HexString.purs index fd333b8..4ce0c7c 100644 --- a/src/Network/Ethereum/Core/HexString.purs +++ b/src/Network/Ethereum/Core/HexString.purs @@ -40,11 +40,10 @@ import Data.String (Pattern(..), split, stripPrefix) import Data.String as S import Data.String.CodeUnits (fromCharArray, toCharArray) import Foreign (ForeignError(..), fail) -import Foreign.Class (class Decode, class Encode, decode, encode) import Network.Ethereum.Core.BigNumber (BigNumber, toString, hexadecimal) import Node.Encoding (Encoding(Hex, UTF8, ASCII)) import Partial.Unsafe (unsafePartial) -import Simple.JSON (class ReadForeign, class WriteForeign) +import Simple.JSON (class ReadForeign, readImpl, class WriteForeign, writeImpl) -------------------------------------------------------------------------------- -- * Signed Values @@ -52,15 +51,15 @@ import Simple.JSON (class ReadForeign, class WriteForeign) data Sign = Pos | Neg -derive instance eqSign :: Eq Sign +derive instance Eq Sign -- | Represents values that can be either positive or negative. data Signed a = Signed Sign a -instance eqSigned :: Eq a => Eq (Signed a) where +instance Eq a => Eq (Signed a) where eq (Signed s a) (Signed s' a') = (s `eq` s') && (a `eq` a') -instance mapSigned :: Functor Signed where +instance Functor Signed where map f (Signed s a) = Signed s (f a) -- | Coerce a value into a positive signed value @@ -74,13 +73,13 @@ asSigned a = Signed Pos a -- | Represents a base16, utf8 encoded bytestring newtype HexString = HexString String -instance showHexString :: Show HexString where +instance Show HexString where show (HexString s) = "0x" <> s -derive newtype instance hexStringEq :: Eq HexString -derive newtype instance hexStringOrd :: Ord HexString -derive newtype instance semigpStringEq :: Semigroup HexString -derive newtype instance monoidStringEq :: Monoid HexString +derive newtype instance Eq HexString +derive newtype instance Ord HexString +derive newtype instance Semigroup HexString +derive newtype instance Monoid HexString _encode :: HexString -> String _encode = append "0x" <<< unHex @@ -90,26 +89,20 @@ _decode str = case mkHexString str of Just res -> Right res Nothing -> Left $ "Failed to parse as HexString: " <> str -instance decodeHexString :: Decode HexString where - decode s = do - str <- decode s +instance ReadForeign HexString where + readImpl f = do + str <- readImpl f either (fail <<< ForeignError) pure $ _decode str -instance readFHexString :: ReadForeign HexString where - readImpl = decode +instance WriteForeign HexString where + writeImpl = writeImpl <<< _encode -instance writeFHexString :: WriteForeign HexString where - writeImpl = encode - -instance encodeHexString :: Encode HexString where - encode = encode <<< _encode - -instance decodeJsonHexString :: A.DecodeJson HexString where +instance A.DecodeJson HexString where decodeJson json = do str <- A.decodeJson json either (const <<< Left $ UnexpectedValue json) Right $ _decode str -instance encodeJsonHexString :: A.EncodeJson HexString where +instance A.EncodeJson HexString where encodeJson = A.encodeJson <<< _encode unHex :: HexString -> String diff --git a/src/Network/Ethereum/Core/Keccak256.js b/src/Network/Ethereum/Core/Keccak256.js index 7bb480d..fc1cfd8 100644 --- a/src/Network/Ethereum/Core/Keccak256.js +++ b/src/Network/Ethereum/Core/Keccak256.js @@ -1,6 +1,6 @@ "use strict"; -var keccak = require('keccak'); +import keccak from "keccak"; -exports._keccak256 = function (a) { +export const _keccak256 = function (a) { return keccak('keccak256').update(a).digest(); }; diff --git a/src/Network/Ethereum/Core/Keccak256.purs b/src/Network/Ethereum/Core/Keccak256.purs index ae2eadf..5665ed3 100644 --- a/src/Network/Ethereum/Core/Keccak256.purs +++ b/src/Network/Ethereum/Core/Keccak256.purs @@ -21,13 +21,13 @@ class Keccak256 a where foreign import _keccak256 :: ByteString -> ByteString -instance keccak256ByteString :: Keccak256 ByteString where +instance Keccak256 ByteString where keccak256 = _keccak256 -instance keccak256String :: Keccak256 String where +instance Keccak256 String where keccak256 = keccak256 <<< unsafePartial fromJust <<< flip fromString UTF8 -instance keccak256HexString :: Keccak256 HexString where +instance Keccak256 HexString where keccak256 = keccak256 <<< toByteString -- | convert a string representing a type signature into a selector diff --git a/src/Network/Ethereum/Core/RLP.js b/src/Network/Ethereum/Core/RLP.js index fe06635..554cb18 100644 --- a/src/Network/Ethereum/Core/RLP.js +++ b/src/Network/Ethereum/Core/RLP.js @@ -1,5 +1,5 @@ -var rlp = require('rlp'); +import { encode } from "rlp"; -exports._rlpEncode = rlp.encode; +export const _rlpEncode = encode; -exports._rlpNull = null; +export const _rlpNull = null; diff --git a/src/Network/Ethereum/Core/RLP.purs b/src/Network/Ethereum/Core/RLP.purs index 3904970..4509112 100644 --- a/src/Network/Ethereum/Core/RLP.purs +++ b/src/Network/Ethereum/Core/RLP.purs @@ -46,5 +46,5 @@ transRLP obj = case obj of foreign import _rlpEncode :: RLPVal -> ByteString -instance rlpEncodeObject :: RLPEncode RLPObject where +instance RLPEncode RLPObject where rlpEncode = _rlpEncode <<< transRLP diff --git a/src/Network/Ethereum/Core/Signatures.js b/src/Network/Ethereum/Core/Signatures.js index f8ff2fe..b70641c 100644 --- a/src/Network/Ethereum/Core/Signatures.js +++ b/src/Network/Ethereum/Core/Signatures.js @@ -1,5 +1,6 @@ -const crypto = require('crypto'); -const secp256k1 = require('secp256k1'); +"use strict"; +import crypto from "crypto"; +import secp256k1 from "secp256k1"; const apiVer = ((typeof secp256k1.ecdsaSign === 'function') && (typeof secp256k1.ecdsaRecover === 'function')) ? 4 : 3; @@ -11,7 +12,7 @@ if (signFn === undefined || recoverFn === undefined) { } // copied from ethereumjs-util -exports.isValidPublic = function (publicKey) { +export const isValidPublic = function (publicKey) { if (publicKey.length === 64) { // Convert to SEC1 for secp256k1 return secp256k1.publicKeyVerify(Buffer.concat([Buffer.from([4]), publicKey])); @@ -21,12 +22,12 @@ exports.isValidPublic = function (publicKey) { }; // copied from ethereumjs-util -exports.isValidPrivate = function (privateKey) { +export const isValidPrivate = function (privateKey) { return secp256k1.privateKeyVerify(privateKey); }; // copied from ethereumjs-util, but more flexible with chainId -exports.ecSign = function (privateKey, msgHash) { +export const ecSign = function (privateKey, msgHash) { var sig = signFn(msgHash, privateKey); var ret = {}; ret.r = Buffer.from(sig.signature.slice(0, 32)); @@ -42,18 +43,18 @@ exports.ecSign = function (privateKey, msgHash) { }; // copied from ethereumjs-util, but more flexible with chainId -exports.ecRecover = function (msgHash, signature, v) { +export const ecRecover = function (msgHash, signature, v) { var senderPubKey = recoverFn(msgHash, signature, v); return Buffer.from(secp256k1.publicKeyConvert(senderPubKey, false).slice(1)); }; // copied from ethereumjs-util -exports.privateToPublic = function (privateKey) { +export const privateToPublic = function (privateKey) { // skip the type flag and use the X, Y points return Buffer.from(secp256k1.publicKeyCreate(privateKey, false).slice(1)); }; -exports.generatePrivateKey = function () { +export const generatePrivateKey = function () { var prv; do { prv = crypto.randomBytes(32); diff --git a/src/Network/Ethereum/Core/Signatures.purs b/src/Network/Ethereum/Core/Signatures.purs index 682a6af..c6a71cc 100644 --- a/src/Network/Ethereum/Core/Signatures.purs +++ b/src/Network/Ethereum/Core/Signatures.purs @@ -34,28 +34,28 @@ import Data.Show.Generic (genericShow) import Data.Maybe (Maybe(..), fromJust) import Effect (Effect) import Foreign (ForeignError(..), fail) -import Foreign.Class (class Decode, class Encode, decode, encode) +-- import Foreign.Class (class Decode, class Encode, decode, encode) import Network.Ethereum.Core.HexString (HexString, takeBytes, nullWord, dropBytes, numberOfBytes, toByteString, fromByteString) import Network.Ethereum.Core.Keccak256 (keccak256) import Partial.Unsafe (unsafePartial) -import Simple.JSON (class ReadForeign, class WriteForeign) +import Simple.JSON (class ReadForeign, readImpl, class WriteForeign, writeImpl) import Type.Quotient (mkQuotient) -- | Opaque PrivateKey type newtype PrivateKey = PrivateKey BS.ByteString -instance showPrivateKey :: Show PrivateKey where +instance Show PrivateKey where show (PrivateKey pk) = show $ fromByteString pk -derive instance eqPrivateKey :: Eq PrivateKey +derive instance Eq PrivateKey -- | Opaque PublicKey type newtype PublicKey = PublicKey BS.ByteString -instance showPublicKey :: Show PublicKey where +instance Show PublicKey where show (PublicKey pk) = show $ fromByteString pk -derive instance eqPublicKey :: Eq PublicKey +derive instance Eq PublicKey foreign import isValidPublic :: BS.ByteString @@ -109,35 +109,31 @@ foreign import generatePrivateKey :: Effect PrivateKey -- | Represents and Ethereum address, which is a 20 byte `HexString` newtype Address = Address HexString -derive newtype instance addressShow :: Show Address -derive newtype instance addressEq :: Eq Address -derive newtype instance addressOrd :: Ord Address -derive newtype instance encodeAddress :: Encode Address +derive newtype instance Show Address +derive newtype instance Eq Address +derive newtype instance Ord Address _decode :: HexString -> Either String Address _decode hx = case mkAddress hx of Nothing -> Left $ "Address must be 20 bytes long: " <> show hx Just res -> Right res -instance decodeAddress :: Decode Address where - decode a = do - hxString <- decode a - either (fail <<< ForeignError) pure $ _decode hxString +instance ReadForeign Address where + readImpl a = do + hexString <- readImpl a + either (fail <<< ForeignError) pure $ _decode hexString -instance decodeJsonAddress :: A.DecodeJson Address where +instance WriteForeign Address where + writeImpl = writeImpl <<< unAddress + +instance A.DecodeJson Address where decodeJson json = do hxString <- A.decodeJson json either (const <<< Left $ UnexpectedValue json) Right $ _decode hxString -instance encodeJsonAddress :: A.EncodeJson Address where +instance A.EncodeJson Address where encodeJson = A.encodeJson <<< unAddress -instance readFAddress :: ReadForeign Address where - readImpl = decode - -instance writeFAddress :: WriteForeign Address where - writeImpl = encode - unAddress :: Address -> HexString unAddress (Address a) = a @@ -170,10 +166,10 @@ newtype Signature = , v :: Int } -derive instance genericSignature :: Generic Signature _ -derive instance eqSignature :: Eq Signature +derive instance Generic Signature _ +derive instance Eq Signature -instance showSignature :: Show Signature where +instance Show Signature where show = genericShow foreign import ecSign :: Fn2 PrivateKey BS.ByteString { r :: BS.ByteString, s :: BS.ByteString, v :: Int } @@ -214,10 +210,10 @@ recoverSender messageHash (Signature { v, r, s }) = -- | Used in Ethereum to prevent replay attacks newtype ChainId = ChainId Int -derive instance genericChainId :: Generic ChainId _ -derive instance eqChainId :: Eq ChainId +derive instance Generic ChainId _ +derive instance Eq ChainId -instance showChainId :: Show ChainId where +instance Show ChainId where show = genericShow -- | Add the ChainId offset to the `Signature` `v` parameter. diff --git a/test/Common.purs b/test/Common.purs index bf45068..f1cc8b9 100644 --- a/test/Common.purs +++ b/test/Common.purs @@ -44,10 +44,10 @@ newtype RawTransaction = , nonce :: BigNumber } -derive instance genericRawTransaction :: Generic RawTransaction _ -derive instance eqRawTransaction :: Eq RawTransaction +derive instance Generic RawTransaction _ +derive instance Eq RawTransaction -instance showRawTransaction :: Show RawTransaction where +instance Show RawTransaction where show = genericShow makeTransactionMessage diff --git a/test/Spec/BigNumber.purs b/test/Spec/BigNumber.purs index 483ef98..b9238cc 100644 --- a/test/Spec/BigNumber.purs +++ b/test/Spec/BigNumber.purs @@ -6,11 +6,10 @@ import Control.Monad.Except (runExcept) import Data.Argonaut as A import Data.Either (Either(..), hush) import Foreign (unsafeToForeign) -import Foreign.Class (decode, encode) import Data.Maybe (Maybe(..), fromJust) import Network.Ethereum.Core.BigNumber (BigNumber, decimal, embed, hexadecimal, parseBigNumber, divide) import Partial.Unsafe (unsafePartial) -import Simple.JSON (readImpl) +import Simple.JSON (readImpl, writeImpl) import Test.Spec (Spec, describe, it) import Test.Spec.Assertions (shouldEqual) @@ -74,11 +73,9 @@ bigNumberSpec = describe "BigNumber-spec" do let bnString = "f43" d1 = unsafePartial $ fromJust $ hush $ runExcept $ readImpl (unsafeToForeign bnString) - d2 = unsafePartial $ fromJust $ hush $ runExcept $ decode (unsafeToForeign bnString) - d3 = unsafePartial $ fromJust $ hush $ A.decodeJson (A.fromString bnString) - d4 = unsafePartial $ fromJust $ parseBigNumber hexadecimal bnString - d4 `shouldEqual` d1 - d4 `shouldEqual` d2 - d4 `shouldEqual` d3 - runExcept (decode (encode d1)) `shouldEqual` Right d4 - (A.decodeJson (A.encodeJson d1)) `shouldEqual` Right d4 + d2 = unsafePartial $ fromJust $ hush $ A.decodeJson (A.fromString bnString) + d3 = unsafePartial $ fromJust $ parseBigNumber hexadecimal bnString + d3 `shouldEqual` d1 + d3 `shouldEqual` d2 + runExcept (readImpl (writeImpl d1)) `shouldEqual` Right d3 + (A.decodeJson (A.encodeJson d1)) `shouldEqual` Right d3 diff --git a/test/Spec/Hex.purs b/test/Spec/Hex.purs index 67a8a20..9918d18 100644 --- a/test/Spec/Hex.purs +++ b/test/Spec/Hex.purs @@ -9,11 +9,10 @@ import Data.ByteString as BS import Data.Either (Either(..), hush) import Data.Maybe (Maybe(Just), fromJust) import Foreign (unsafeToForeign) -import Foreign.Class (encode, decode) import Network.Ethereum.Core.HexString (HexString, mkHexString, toByteString, toUtf8, toAscii, fromUtf8, fromAscii) import Node.Encoding (Encoding(Hex)) import Partial.Unsafe (unsafePartial) -import Simple.JSON (readImpl) +import Simple.JSON (readImpl, writeImpl) import Test.Spec (Spec, describe, it) import Test.Spec.Assertions (shouldEqual) @@ -69,11 +68,9 @@ hexSpec = describe "hex-spec" do let hxString = "0f43" d1 = unsafePartial $ fromJust $ hush $ runExcept $ readImpl (unsafeToForeign hxString) - d2 = unsafePartial $ fromJust $ hush $ runExcept $ decode (unsafeToForeign hxString) - d3 = unsafePartial $ fromJust $ hush $ A.decodeJson (A.fromString hxString) - d4 = unsafePartial $ fromJust $ mkHexString hxString - d4 `shouldEqual` d1 - d4 `shouldEqual` d2 - d4 `shouldEqual` d3 - runExcept (decode (encode d1)) `shouldEqual` Right d4 - (A.decodeJson (A.encodeJson d1)) `shouldEqual` Right d4 + d2 = unsafePartial $ fromJust $ hush $ A.decodeJson (A.fromString hxString) + d3 = unsafePartial $ fromJust $ mkHexString hxString + d3 `shouldEqual` d1 + d3 `shouldEqual` d2 + runExcept (readImpl (writeImpl d1)) `shouldEqual` Right d3 + (A.decodeJson (A.encodeJson d1)) `shouldEqual` Right d3