From c42e362d404001373b005d46f674ff5b8383a6bf Mon Sep 17 00:00:00 2001 From: WhoSoup <34172041+WhoSoup@users.noreply.github.com> Date: Thu, 20 Aug 2020 04:21:43 +0200 Subject: [PATCH] remove wallet + add go mod (#144) --- glide.lock | 266 ----- glide.yaml | 32 - go.mod | 21 + go.sum | 50 + transaction_test.go | 42 - wallet/VERSION | 1 - wallet/database.go | 177 --- wallet/database_test.go | 352 ------ wallet/importexport.go | 70 -- wallet/importexport_test.go | 25 - wallet/importexportenc.go | 70 -- wallet/importexportenc_test.go | 5 - wallet/importexportldb.go | 70 -- wallet/sign.go | 28 - wallet/transaction.go | 427 -------- wallet/transaction_test.go | 245 ----- wallet/txdatabase.go | 444 -------- wallet/txdatabase_test.go | 105 -- wallet/util.go | 71 -- wallet/util_test.go | 19 - wallet/v1conversion.go | 154 --- wallet/v1conversion_test.go | 39 - wallet/walletDBO.go | 626 ----------- wallet/walletDBO_test.go | 109 -- wallet/wsapi/10000addressesTest.sh | 30 - wallet/wsapi/errors.go | 79 -- wallet/wsapi/structs.go | 221 ---- wallet/wsapi/wsapi.go | 1594 ---------------------------- wallet/wsapi/wsapi_test.gox | 144 --- wallet_test.go | 139 --- 30 files changed, 71 insertions(+), 5584 deletions(-) delete mode 100644 glide.lock delete mode 100644 glide.yaml create mode 100644 go.mod create mode 100644 go.sum delete mode 100644 wallet/VERSION delete mode 100644 wallet/database.go delete mode 100644 wallet/database_test.go delete mode 100644 wallet/importexport.go delete mode 100644 wallet/importexport_test.go delete mode 100644 wallet/importexportenc.go delete mode 100644 wallet/importexportenc_test.go delete mode 100644 wallet/importexportldb.go delete mode 100644 wallet/sign.go delete mode 100644 wallet/transaction.go delete mode 100644 wallet/transaction_test.go delete mode 100644 wallet/txdatabase.go delete mode 100644 wallet/txdatabase_test.go delete mode 100644 wallet/util.go delete mode 100644 wallet/util_test.go delete mode 100644 wallet/v1conversion.go delete mode 100644 wallet/v1conversion_test.go delete mode 100644 wallet/walletDBO.go delete mode 100644 wallet/walletDBO_test.go delete mode 100755 wallet/wsapi/10000addressesTest.sh delete mode 100644 wallet/wsapi/errors.go delete mode 100644 wallet/wsapi/structs.go delete mode 100644 wallet/wsapi/wsapi.go delete mode 100644 wallet/wsapi/wsapi_test.gox diff --git a/glide.lock b/glide.lock deleted file mode 100644 index 77c3a15..0000000 --- a/glide.lock +++ /dev/null @@ -1,266 +0,0 @@ -hash: 713151aa273eee2903d840e4b627c53d660de4d347a8a3e3a741bda0f5a0a193 -updated: 2019-07-08T12:30:27.753120923-05:00 -imports: -- name: github.com/beorn7/perks - version: 3a771d992973f24aa725d07868b467d1ddfceafb - subpackages: - - quantile -- name: github.com/btcsuitereleases/btcutil - version: f2b1058a82554c0c7c3b8809c5956c38374604d8 - subpackages: - - base58 -- name: github.com/FactomProject/basen - version: fe3947df716ebfda9847eb1b9a48f9592e06478c -- name: github.com/FactomProject/bolt - version: 952a1b4e9a55f458d536cf703bce25a4e9c99841 -- name: github.com/FactomProject/btcutil - version: 43986820ccd50b2b02b83e575cb3a39c87457482 - subpackages: - - base58 - - certs -- name: github.com/FactomProject/btcutilecc - version: d3a63a5752ecf3fbc06bd97365da752111c263df -- name: github.com/FactomProject/ed25519 - version: 38002c4fe7b609c2fa3144a3cc29b997b756bb4c - subpackages: - - edwards25519 -- name: github.com/FactomProject/factoid - version: 3ee9763f86849036723d1b059216e08a6d34b184 - subpackages: - - block - - database - - state - - state/stateinit - - wallet -- name: github.com/FactomProject/FactomCode - version: d7e03150a9d5d8672e52a0769a4c6376f5c12631 - subpackages: - - controlpanel -- name: github.com/FactomProject/factomd - version: 7fd7716f5af4f8962ef9390adb0f4e4416eb22da - subpackages: - - Utilities/CorrectChainHeads/correctChainHeads - - Utilities/tools - - activations - - anchor - - common/adminBlock - - common/constants - - common/directoryBlock - - common/directoryBlock/dbInfo - - common/entryBlock - - common/entryBlock/specialEntries - - common/entryCreditBlock - - common/factoid - - common/globals - - common/identity - - common/identityEntries - - common/interfaces - - common/messages - - common/messages/electionMsgs - - common/messages/msgbase - - common/messages/msgsupport - - common/primitives - - common/primitives/random - - controlPanel - - controlPanel/dataDumpFormatting - - controlPanel/files - - controlPanel/files/statics - - controlPanel/files/templates - - database/blockExtractor - - database/boltdb - - database/databaseOverlay - - database/hybridDB - - database/leveldb - - database/mapdb - - database/securedb - - elections - - electionsCore/election - - electionsCore/election/volunteercontrol - - electionsCore/errorhandling - - electionsCore/imessage - - electionsCore/messages - - electionsCore/primitives - - engine - - log - - p2p - - receipts - - state - - testHelper - - util - - util/atomic - - wsapi -- name: github.com/FactomProject/go-bip32 - version: 3b593af1c415abc1017648e4eb24a88c32fee0f3 -- name: github.com/FactomProject/go-bip39 - version: d1007fb78d9a7ec65314dad412973e63caf4c527 -- name: github.com/FactomProject/go-bip44 - version: b541a96d8da98567af7610ef96105a834e6ed46c -- name: github.com/FactomProject/go-simplejson - version: aabad6e819789e569bd6aabf444c935aa9ba1e44 -- name: github.com/FactomProject/go-spew - version: ddfaec9b42f58fc8172b0cbb03b21c6668dd0a46 - subpackages: - - spew -- name: github.com/FactomProject/goleveldb - version: e7800c6976c5d75f0a9c5e9e0e2ff8086940e58f - subpackages: - - leveldb - - leveldb/cache - - leveldb/comparer - - leveldb/errors - - leveldb/filter - - leveldb/iterator - - leveldb/journal - - leveldb/memdb - - leveldb/opt - - leveldb/storage - - leveldb/table - - leveldb/util -- name: github.com/FactomProject/logrustash - version: 9c7278ede46e1ccc03f0b17d6663730c340acb81 -- name: github.com/FactomProject/netki-go-partner-client - version: 426acb535e66cc2f9e6226ae254555e3572fd142 -- name: github.com/FactomProject/serveridentity - version: cf42d2aa8debbe9a690e8c12b7a9fcda127d3f2c - subpackages: - - identity - - utils -- name: github.com/FactomProject/snappy-go - version: f2f83b22c29e5abc60e3a95062ce1491d3b95371 -- name: github.com/FactomProject/web - version: 951cacf54656419dbaf444bc69b82799660ff521 -- name: github.com/golang/protobuf - version: 1918e1ff6ffd2be7bed0553df8650672c3bfe80d - subpackages: - - proto - - ptypes - - ptypes/any - - ptypes/duration - - ptypes/timestamp -- name: github.com/hashicorp/go-hclog - version: f1d61ad5398ffe4f2eb61eacb088340d44e99672 -- name: github.com/hashicorp/go-plugin - version: a1bc61569a26c0f65865932c0d55743b0567c494 - subpackages: - - internal/plugin -- name: github.com/hashicorp/yamux - version: 2f1d1f20f75d5404f53b9edf6b53ed5505508675 -- name: github.com/konsorten/go-windows-terminal-sequences - version: 5c8c8bd35d3832f5d134ae1e1e375b69a4d25242 -- name: github.com/matttproud/golang_protobuf_extensions - version: c12348ce28de40eed0136aa2b644d0ee0650e56c - subpackages: - - pbutil -- name: github.com/mitchellh/go-testing-interface - version: 6d0b8010fcc857872e42fc6c931227569016843c -- name: github.com/oklog/run - version: 6934b124db28979da51d3470dadfa34d73d72652 -- name: github.com/prometheus/client_golang - version: f30f428035633da15d00d3dfefb0128c5e569ef4 - subpackages: - - prometheus - - prometheus/internal -- name: github.com/prometheus/client_model - version: 5c3871d89910bfb32f5fcab2aa4b9ec68e65a99f - subpackages: - - go -- name: github.com/prometheus/common - version: 7e9e6cabbd393fc208072eedef99188d0ce788b6 - subpackages: - - expfmt - - internal/bitbucket.org/ww/goautoneg - - model -- name: github.com/prometheus/procfs - version: 185b4288413d2a0dd0806f78c90dde719829e5ae - subpackages: - - internal/util - - nfs - - xfs -- name: github.com/rs/cors - version: a3460e445dd310dbefee993fe449f2ff9c08ae71 -- name: github.com/sirupsen/logrus - version: 566a5f690849162ff53cf98f3c42135389d63f95 -- name: github.com/stretchr/testify - version: 34c6fa2dc70986bccbbffcc6130f6920a924b075 - subpackages: - - assert -- name: golang.org/x/crypto - version: 4d3f4d9ffa16a13f451c3b2999e9c49e9750bf06 - subpackages: - - pbkdf2 - - ripemd160 - - scrypt - - ssh/terminal -- name: golang.org/x/net - version: c44066c5c816ec500d459a2a324a753f78531ae0 - subpackages: - - context - - http/httpguts - - http2 - - http2/hpack - - idna - - internal/timeseries - - trace - - websocket -- name: golang.org/x/sys - version: 7e31e0c00fa05cb5fbf4347b585621d6709e19a4 - subpackages: - - unix - - windows -- name: golang.org/x/text - version: 342b2e1fbaa52c93f31447ad2c6abc048c63e475 - subpackages: - - secure/bidirule - - transform - - unicode/bidi - - unicode/norm -- name: google.golang.org/genproto - version: 32ee49c4dd805befd833990acba36cb75042378c - subpackages: - - googleapis/rpc/status -- name: google.golang.org/grpc - version: 684ef046099f3f1c4b1fe762e5826a2f7bc6e27f - subpackages: - - balancer - - balancer/base - - balancer/roundrobin - - binarylog/grpc_binarylog_v1 - - codes - - connectivity - - credentials - - credentials/internal - - encoding - - encoding/proto - - grpclog - - health - - health/grpc_health_v1 - - internal - - internal/backoff - - internal/balancerload - - internal/binarylog - - internal/channelz - - internal/envconfig - - internal/grpcrand - - internal/grpcsync - - internal/syscall - - internal/transport - - keepalive - - metadata - - naming - - peer - - resolver - - resolver/dns - - resolver/passthrough - - serviceconfig - - stats - - status - - tap -- name: gopkg.in/gcfg.v1 - version: 61b2c08bc8f6068f7c5ca684372f9a6cb1c45ebe - subpackages: - - scanner - - token - - types -- name: gopkg.in/warnings.v0 - version: ec4a0fea49c7b46c2aeb0b51aac55779c607e52b -testImports: [] diff --git a/glide.yaml b/glide.yaml deleted file mode 100644 index 72e6e85..0000000 --- a/glide.yaml +++ /dev/null @@ -1,32 +0,0 @@ -package: github.com/FactomProject/factom -import: -- package: github.com/FactomProject/btcutil - subpackages: - - base58 - - certs -- package: github.com/FactomProject/ed25519 -- package: github.com/FactomProject/factoid - subpackages: - - state/stateinit - - wallet -- package: github.com/FactomProject/factomd - subpackages: - - common/directoryBlock - - common/factoid - - common/interfaces - - common/primitives - - database/databaseOverlay - - database/hybridDB - - database/mapdb - - database/securedb -- package: github.com/FactomProject/go-bip32 -- package: github.com/FactomProject/go-bip39 -- package: github.com/FactomProject/go-bip44 -- package: github.com/FactomProject/goleveldb - subpackages: - - leveldb -- package: github.com/FactomProject/netki-go-partner-client -- package: github.com/FactomProject/web -- package: github.com/stretchr/testify - subpackages: - - assert \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..d828ebe --- /dev/null +++ b/go.mod @@ -0,0 +1,21 @@ +module github.com/FactomProject/factom + +go 1.14 + +require ( + github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect + github.com/FactomProject/btcutil v0.0.0-20160826074221-43986820ccd5 + github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect + github.com/FactomProject/ed25519 v0.0.0-20150814230546-38002c4fe7b6 + github.com/FactomProject/go-bip32 v0.3.5 + github.com/FactomProject/go-bip39 v0.3.5 + github.com/FactomProject/go-bip44 v0.0.0-20190306062959-b541a96d8da9 + github.com/FactomProject/go-simplejson v0.5.0 // indirect + github.com/FactomProject/netki-go-partner-client v0.0.0-20160324224126-426acb535e66 + github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect + github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e // indirect + github.com/kr/pretty v0.2.1 // indirect + github.com/stretchr/testify v1.6.1 // indirect + golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc + launchpad.net/gocheck v0.0.0-20140225173054-000000000087 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..2607c34 --- /dev/null +++ b/go.sum @@ -0,0 +1,50 @@ +github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc= +github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw= +github.com/FactomProject/btcutil v0.0.0-20160826074221-43986820ccd5 h1:cysv7OcQYt+P7IH1ZQAE1akzlwm+EXvxG6/0jYlJIE4= +github.com/FactomProject/btcutil v0.0.0-20160826074221-43986820ccd5/go.mod h1:vneMtVKjkLz6PtiXS/HB0UJXAF77wndeJwZiqaVrN84= +github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc= +github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U= +github.com/FactomProject/ed25519 v0.0.0-20150814230546-38002c4fe7b6 h1:e2tpL8IfImGBR8qODlnb/hnwPhS4wWzoOUKoFrA3RFQ= +github.com/FactomProject/ed25519 v0.0.0-20150814230546-38002c4fe7b6/go.mod h1:x54uxtF9AnHAvx2kRoIxKYLuUV+bRjUQ6u/3FhfmO5g= +github.com/FactomProject/go-bip32 v0.3.5 h1:etsJ4Y/wA7spZl/WG830ogTHQivGcV/8sCrrmkQICNQ= +github.com/FactomProject/go-bip32 v0.3.5/go.mod h1:efm/M7J/CGmQ5dPtGM0GWod5LuyShuFET6oY13168w4= +github.com/FactomProject/go-bip39 v0.3.5 h1:l9g92TeqCkC5NZhm72igTpf5yaYDp3Sy4CvnPYknp6U= +github.com/FactomProject/go-bip39 v0.3.5/go.mod h1:ygPVOtW424QxnJMze9XYDeh4wT19V3iVDOqVUl/USkE= +github.com/FactomProject/go-bip44 v0.0.0-20190306062959-b541a96d8da9 h1:Wprj9FTxqhjgl7e8ZHScGwF5Wc2WrHTbEDoQKciBdhw= +github.com/FactomProject/go-bip44 v0.0.0-20190306062959-b541a96d8da9/go.mod h1:4H/Y1yLgSJvRV4iqilsVhYlqXkPgf1QonpKyt6sdP+Q= +github.com/FactomProject/go-simplejson v0.5.0 h1:gO5Z2gV3+kqWcu8/TrjAbim0yFqUcFll7HzAhdxah7s= +github.com/FactomProject/go-simplejson v0.5.0/go.mod h1:P6XXHV5dI0hIZte+dQ4G8tzNIiyuF/UMVuInbQd036g= +github.com/FactomProject/netki-go-partner-client v0.0.0-20160324224126-426acb535e66 h1:H4nFZnW3EpbcefxbJAJxWCl7niO07QpKt8KeHtLwHoc= +github.com/FactomProject/netki-go-partner-client v0.0.0-20160324224126-426acb535e66/go.mod h1:L+Od0CCfb8IzUbPM4UxLaERB1I6Bw/lD2UtzRM90pIw= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= +github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc h1:zK/HqS5bZxDptfPJNq8v7vJfXtkU7r9TLIoSr1bXaP4= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= diff --git a/transaction_test.go b/transaction_test.go index 0690605..1d250ca 100644 --- a/transaction_test.go +++ b/transaction_test.go @@ -29,48 +29,6 @@ func TestJSONTransactions(t *testing.T) { t.Log("Unmarshaled:", tx2) } -func TestTransactions(t *testing.T) { - // start the test wallet - done, err := StartTestWallet() - if err != nil { - t.Error(err) - } - defer func() { done <- 1 }() - - // make sure the wallet is empty - if txs, err := ListTransactionsTmp(); err != nil { - t.Error(err) - } else if len(txs) > 0 { - t.Error("Unexpected transactions returned from the wallet:", txs) - } - - // create a new transaction - tx1, err := NewTransaction("tx1") - if err != nil { - t.Error(err) - } - if tx1 == nil { - t.Error("No transaction was returned") - } - - if tx, err := GetTmpTransaction("tx1"); err != nil { - t.Error(err) - } else if tx == nil { - t.Error("Temporary transaction was not saved in the wallet") - } - - // delete a transaction - if err := DeleteTransaction("tx1"); err != nil { - t.Error(err) - } - - if txs, err := ListTransactionsTmp(); err != nil { - t.Error(err) - } else if len(txs) > 0 { - t.Error("Unexpected transactions returned from the wallet:", txs) - } -} - // helper functions for testing func mkdummytx() *Transaction { diff --git a/wallet/VERSION b/wallet/VERSION deleted file mode 100644 index ed1fc35..0000000 --- a/wallet/VERSION +++ /dev/null @@ -1 +0,0 @@ -2.2.16 diff --git a/wallet/database.go b/wallet/database.go deleted file mode 100644 index 6add155..0000000 --- a/wallet/database.go +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wallet - -import ( - "fmt" - "sync" - - "github.com/FactomProject/factom" - "github.com/FactomProject/factomd/common/factoid" -) - -// Wallet is a connection to a Factom Wallet Database -type Wallet struct { - *WalletDatabaseOverlay - Encrypted bool - DBPath string - txlock sync.Mutex - transactions map[string]*factoid.Transaction - txdb *TXDatabaseOverlay -} - -func (w *Wallet) InitWallet() error { - dbSeed, err := w.GetOrCreateDBSeed() - if err != nil { - return err - } - if dbSeed == nil { - return fmt.Errorf("dbSeed not present in DB") - } - return nil -} - -func NewOrOpenLevelDBWallet(path string) (*Wallet, error) { - w := new(Wallet) - w.transactions = make(map[string]*factoid.Transaction) - - db, err := NewLevelDB(path) - if err != nil { - return nil, err - } - w.WalletDatabaseOverlay = db - - if err = w.InitWallet(); err != nil { - return nil, err - } - - return w, nil -} - -func NewOrOpenBoltDBWallet(path string) (*Wallet, error) { - w := new(Wallet) - w.transactions = make(map[string]*factoid.Transaction) - - db, err := NewBoltDB(path) - if err != nil { - return nil, err - } - w.WalletDatabaseOverlay = db - - if err = w.InitWallet(); err != nil { - return nil, err - } - - return w, nil -} - -func NewEncryptedBoltDBWallet(path, password string) (*Wallet, error) { - w := new(Wallet) - w.transactions = make(map[string]*factoid.Transaction) - - db, err := NewEncryptedBoltDB(path, password) - if err != nil { - return nil, err - } - w.WalletDatabaseOverlay = db - - if err = w.InitWallet(); err != nil { - return nil, err - } - - return w, nil -} - -func NewEncryptedBoltDBWalletAwaitingPassphrase(path string) (*Wallet, error) { - w := new(Wallet) - w.transactions = make(map[string]*factoid.Transaction) - w.Encrypted = true - w.DBPath = path - return w, nil -} - -func NewMapDBWallet() (*Wallet, error) { - w := new(Wallet) - w.transactions = make(map[string]*factoid.Transaction) - w.WalletDatabaseOverlay = NewMapDB() - - if err := w.InitWallet(); err != nil { - return nil, err - } - - return w, nil -} - -// Close closes a Factom Wallet Database -func (w *Wallet) Close() error { - if w.WalletDatabaseOverlay == nil { - return nil - } - return w.DBO.Close() -} - -// AddTXDB allows the wallet api to read from a local transaction cashe. -func (w *Wallet) AddTXDB(t *TXDatabaseOverlay) { - w.txdb = t -} - -// TXDB returns a handle for the Transaction Database. -func (w *Wallet) TXDB() *TXDatabaseOverlay { - return w.txdb -} - -// GenerateECAddress creates and stores a new Entry Credit Address in the -// Wallet. The address can be reproduced in the future using the Wallet Seed. -func (w *Wallet) GenerateECAddress() (*factom.ECAddress, error) { - return w.GetNextECAddress() -} - -// GenerateFCTAddress creates and stores a new Factoid Address in the Wallet. -// The address can be reproduced in the future using the Wallet Seed. -func (w *Wallet) GenerateFCTAddress() (*factom.FactoidAddress, error) { - return w.GetNextFCTAddress() -} - -// GenerateIdentityKey creates and stores a new Identity Key in the Wallet. -func (w *Wallet) GenerateIdentityKey() (*factom.IdentityKey, error) { - return w.GetNextIdentityKey() -} - -// GetAllAddresses retrieves all Entry Credit and Factoid Addresses from the -// Wallet Database. -func (w *Wallet) GetAllAddresses() ([]*factom.FactoidAddress, []*factom.ECAddress, error) { - fcs, err := w.GetAllFCTAddresses() - if err != nil { - return nil, nil, err - } - - ecs, err := w.GetAllECAddresses() - if err != nil { - return nil, nil, err - } - - return fcs, ecs, nil -} - -// GetSeed returns the string representaion of the Wallet Seed. The Wallet Seed -// can be used to regenerate the Factoid and Entry Credit Addresses previously -// generated by the wallet. Note that Addresses that are imported into the -// Wallet cannot be regenerated using the Wallet Seed. -func (w *Wallet) GetSeed() (string, error) { - seed, err := w.GetDBSeed() - if err != nil { - return "", err - } - - return seed.MnemonicSeed, nil -} - -func (w *Wallet) GetVersion() string { - return WalletVersion -} - -func (w *Wallet) GetApiVersion() string { - return ApiVersion -} diff --git a/wallet/database_test.go b/wallet/database_test.go deleted file mode 100644 index 0533c4f..0000000 --- a/wallet/database_test.go +++ /dev/null @@ -1,352 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wallet_test - -import ( - "os" - "testing" - - "github.com/FactomProject/factom" - . "github.com/FactomProject/factom/wallet" -) - -func TestNewWallet(t *testing.T) { - // create a new database - w1, err := NewMapDBWallet() - if err != nil { - t.Error(err) - } - - // check that the seed got written - seed, err := w1.GetDBSeed() - if err != nil { - t.Error(err) - } - if len(seed.MnemonicSeed) == 0 { - t.Errorf("stored db seed is empty") - } - - if err := w1.Close(); err != nil { - t.Error(err) - } -} - -func TestOpenWallet(t *testing.T) { - dbpath := os.TempDir() + "/test_wallet-01" - - // create a new database - w1, err := NewOrOpenLevelDBWallet(dbpath) - if err != nil { - t.Error(err) - } - w1.Close() - - // make sure we can open the db - w2, err := NewOrOpenLevelDBWallet(dbpath) - if err != nil { - t.Error(err) - } - - // check that the seed is there - seed, err := w1.GetDBSeed() - if len(seed.MnemonicSeed) == 0 { - t.Errorf("stored db seed is empty") - } - - if err := w2.Close(); err != nil { - t.Error(err) - } - - // remove the testing db - if err := os.RemoveAll(dbpath); err != nil { - t.Error(err) - } -} - -func TestPutECAddress(t *testing.T) { - zSec := "Es2Rf7iM6PdsqfYCo3D1tnAR65SkLENyWJG1deUzpRMQmbh9F3eG" - - // create a new database - w, err := NewMapDBWallet() - if err != nil { - t.Error(err) - } - - // write a new ec address to the db - e, err := factom.GetECAddress(zSec) - if err != nil { - t.Error(err) - } - if err := w.InsertECAddress(e); err != nil { - t.Error(err) - } - - // Check that the address was written into the db - if _, err := w.GetECAddress(e.PubString()); err != nil { - t.Error(err) - } - - // close and remove the testing db - if err := w.Close(); err != nil { - t.Error(err) - } -} - -func TestPutFCTAddress(t *testing.T) { - zSec := "Fs1KWJrpLdfucvmYwN2nWrwepLn8ercpMbzXshd1g8zyhKXLVLWj" - - // create a new database - w, err := NewMapDBWallet() - if err != nil { - t.Error(err) - } - - // write a new fct address to the db - f, err := factom.GetFactoidAddress(zSec) - if err != nil { - t.Error(err) - } - if err := w.InsertFCTAddress(f); err != nil { - t.Error(err) - } - - // Check that the address was written into the db - if _, err := w.GetFCTAddress(f.String()); err != nil { - t.Error(err) - } - - // close and remove the testing db - if err := w.Close(); err != nil { - t.Error(err) - } -} - -func TestGenerateECAddress(t *testing.T) { - // create a new database - w, err := NewMapDBWallet() - if err != nil { - t.Error(err) - } - - // Generate a new ec address - e, err := w.GenerateECAddress() - if err != nil { - t.Error(err) - } - - // Check that the address was written into the db - if _, err := w.GetECAddress(e.PubString()); err != nil { - t.Error(err) - } - - // close and remove the testing db - if err := w.Close(); err != nil { - t.Error(err) - } -} - -func TestGenerateFCTAddress(t *testing.T) { - // create a new database - w, err := NewMapDBWallet() - if err != nil { - t.Error(err) - } - - // Generate a new fct address - f, err := w.GenerateFCTAddress() - if err != nil { - t.Error(err) - } - - // Check that the address was written into the db - if _, err := w.GetFCTAddress(f.String()); err != nil { - t.Error(err) - } - - // close and remove the testing db - if err := w.Close(); err != nil { - t.Error(err) - } -} - -func TestGetAllAddresses(t *testing.T) { - e1Sec := "Es2Rf7iM6PdsqfYCo3D1tnAR65SkLENyWJG1deUzpRMQmbh9F3eG" - f1Sec := "Fs1KWJrpLdfucvmYwN2nWrwepLn8ercpMbzXshd1g8zyhKXLVLWj" - e2Sec := "Es4NQHwo8F4Z4oMnVwndtjV1rzZN3t5pP5u5jtdgiR1RA6FH4Tmc" - f2Sec := "Fs3GFV6GNV6ar4b8eGcQWpGFbFtkNWKfEPdbywmha8ez5p7XMJyk" - correctLen := 2 - - // create a new database - w, err := NewMapDBWallet() - if err != nil { - t.Error(err) - } - - // write a new ec address to the db - e1, err := factom.GetECAddress(e1Sec) - if err != nil { - t.Error(err) - } - if err := w.InsertECAddress(e1); err != nil { - t.Error(err) - } - e2, err := factom.GetECAddress(e2Sec) - if err != nil { - t.Error(err) - } - if err := w.InsertECAddress(e2); err != nil { - t.Error(err) - } - - // write a new fct address to the db - f1, err := factom.GetFactoidAddress(f1Sec) - if err != nil { - t.Error(err) - } - if err := w.InsertFCTAddress(f1); err != nil { - t.Error(err) - } - f2, err := factom.GetFactoidAddress(f2Sec) - if err != nil { - t.Error(err) - } - if err := w.InsertFCTAddress(f2); err != nil { - t.Error(err) - } - - // get all addresses out of db - fs, es, err := w.GetAllAddresses() - if err != nil { - t.Error(err) - } else if fs == nil { - t.Errorf("No Factoid address was retrived") - } else if es == nil { - t.Errorf("No EC address was retrived") - } - // check that all the addresses are there - if len(fs) != correctLen { - t.Errorf("Wrong number of factoid addesses were retrived: %v", fs) - } - if len(es) != correctLen { - t.Errorf("Wrong number of ec addesses were retrived: %v", es) - } - - // print the addresses - for _, f := range fs { - t.Logf("%s %s", f, f.SecString()) - } - for _, e := range es { - t.Logf("%s %s", e, e.SecString()) - } - - // close and remove the testing db - if err := w.Close(); err != nil { - t.Error(err) - } -} - -func TestPutIdentityKey(t *testing.T) { - sec := "idsec2J3nNoqdiyboCBKDGauqN9Jb33dyFSqaJKZqTs6i5FmztsTn5f" - - // create a new database - w, err := NewMapDBWallet() - if err != nil { - t.Error(err) - } - - // write a new identity key to the db - k, err := factom.GetIdentityKey(sec) - if err != nil { - t.Error(err) - } - if err := w.InsertIdentityKey(k); err != nil { - t.Error(err) - } - - // Check that the key was written into the db - if _, err := w.GetIdentityKey(k.PubString()); err != nil { - t.Error(err) - } - - // close and remove the testing db - if err := w.Close(); err != nil { - t.Error(err) - } -} - -func TestGenerateIdentityKey(t *testing.T) { - // create a new database - w, err := NewMapDBWallet() - if err != nil { - t.Error(err) - } - - // Generate a new identity key - k, err := w.GenerateIdentityKey() - if err != nil { - t.Error(err) - } - - // Check that the key was written into the db - if _, err := w.GetIdentityKey(k.PubString()); err != nil { - t.Error(err) - } - - // close and remove the testing db - if err := w.Close(); err != nil { - t.Error(err) - } -} - -func TestGetAllIdentityKeys(t *testing.T) { - sec1 := "idsec2J3nNoqdiyboCBKDGauqN9Jb33dyFSqaJKZqTs6i5FmztsTn5f" - sec2 := "idsec1xuUyeCCrJhsojf2wLAZqRxPzPFR8Gidd9DRRid1yGy8ncAJG3" - - correctLen := 2 - - // create a new database - w, err := NewMapDBWallet() - if err != nil { - t.Error(err) - } - - // write a new identity keys to the db - k1, err := factom.GetIdentityKey(sec1) - if err != nil { - t.Error(err) - } - if err := w.InsertIdentityKey(k1); err != nil { - t.Error(err) - } - k2, err := factom.GetIdentityKey(sec2) - if err != nil { - t.Error(err) - } - if err := w.InsertIdentityKey(k2); err != nil { - t.Error(err) - } - - // get all identity keys out of db - ks, err := w.GetAllIdentityKeys() - if err != nil { - t.Error(err) - } else if ks == nil { - t.Errorf("No Identity key was retrived") - } - // check that all the keys are there - if len(ks) != correctLen { - t.Errorf("Wrong number of identity keys were retrived: %v", ks) - } - - // print the keys - for _, k := range ks { - t.Logf("%s %s", k, k.SecString()) - } - - // close and remove the testing db - if err := w.Close(); err != nil { - t.Error(err) - } -} diff --git a/wallet/importexport.go b/wallet/importexport.go deleted file mode 100644 index 81d1a9a..0000000 --- a/wallet/importexport.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wallet - -import ( - "fmt" - "os" - - "github.com/FactomProject/factom" - "github.com/FactomProject/factomd/common/factoid" -) - -// ImportWalletFromMnemonic creates a new wallet with a provided Mnemonic seed -// defined in bip-0039. -func ImportWalletFromMnemonic(mnemonic, path string) (*Wallet, error) { - mnemonic, err := factom.ParseMnemonic(mnemonic) - if err != nil { - return nil, err - } - - // check if the file exists - _, err = os.Stat(path) - if err == nil { - return nil, fmt.Errorf("%s: file already exists", path) - } - - db, err := NewBoltDB(path) - if err != nil { - return nil, err - } - - seed := new(DBSeed) - seed.MnemonicSeed = mnemonic - if err := db.InsertDBSeed(seed); err != nil { - return nil, err - } - - w := new(Wallet) - w.transactions = make(map[string]*factoid.Transaction) - w.WalletDatabaseOverlay = db - - return w, nil -} - -// ExportWallet writes all the secret/publilc key pairs from a wallet and the -// wallet seed in a pritable format. -func ExportWallet(path string) (string, []*factom.FactoidAddress, []*factom.ECAddress, error) { - // check if the file exists - _, err := os.Stat(path) - if err != nil { - return "", nil, nil, err - } - - w, err := NewOrOpenBoltDBWallet(path) - if err != nil { - return "", nil, nil, err - } - - m, err := w.GetSeed() - if err != nil { - return "", nil, nil, err - } - fs, es, err := w.GetAllAddresses() - if err != nil { - return "", nil, nil, err - } - return m, fs, es, nil -} diff --git a/wallet/importexport_test.go b/wallet/importexport_test.go deleted file mode 100644 index 29b1723..0000000 --- a/wallet/importexport_test.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wallet_test - -import ( - "testing" - - //"github.com/FactomProject/factom" - . "github.com/FactomProject/factom/wallet" -) - -func TestImportWithSpaces(t *testing.T) { - w, err := ImportWalletFromMnemonic("yellow yellow yellow yellow yellow yellow yellow yellow yellow yellow yellow yellow", "") - if err != nil { - t.Error(err) - t.FailNow() - } - _, err = w.GenerateFCTAddress() - if err != nil { - t.Error(err) - t.FailNow() - } -} diff --git a/wallet/importexportenc.go b/wallet/importexportenc.go deleted file mode 100644 index c66035f..0000000 --- a/wallet/importexportenc.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wallet - -import ( - "fmt" - "os" - - "github.com/FactomProject/factom" - "github.com/FactomProject/factomd/common/factoid" -) - -// ImportEncryptedWalletFromMnemonic creates a new wallet with a provided Mnemonic seed -// defined in bip-0039. -func ImportEncryptedWalletFromMnemonic(mnemonic, path, password string) (*Wallet, error) { - mnemonic, err := factom.ParseMnemonic(mnemonic) - if err != nil { - return nil, err - } - - // check if the file exists - _, err = os.Stat(path) - if err == nil { - return nil, fmt.Errorf("%s: file already exists", path) - } - - db, err := NewEncryptedBoltDB(path, password) - if err != nil { - return nil, err - } - - seed := new(DBSeed) - seed.MnemonicSeed = mnemonic - if err := db.InsertDBSeed(seed); err != nil { - return nil, err - } - - w := new(Wallet) - w.transactions = make(map[string]*factoid.Transaction) - w.WalletDatabaseOverlay = db - - return w, nil -} - -// ExportEncryptedWallet writes all the secret/publilc key pairs from a wallet and the -// wallet seed in a pritable format. -func ExportEncryptedWallet(path, password string) (string, []*factom.FactoidAddress, []*factom.ECAddress, error) { - // check if the file exists - _, err := os.Stat(path) - if err != nil { - return "", nil, nil, err - } - - w, err := NewEncryptedBoltDBWallet(path, password) - if err != nil { - return "", nil, nil, err - } - - m, err := w.GetSeed() - if err != nil { - return "", nil, nil, err - } - fs, es, err := w.GetAllAddresses() - if err != nil { - return "", nil, nil, err - } - return m, fs, es, nil -} diff --git a/wallet/importexportenc_test.go b/wallet/importexportenc_test.go deleted file mode 100644 index 328d647..0000000 --- a/wallet/importexportenc_test.go +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wallet_test diff --git a/wallet/importexportldb.go b/wallet/importexportldb.go deleted file mode 100644 index 3859fd0..0000000 --- a/wallet/importexportldb.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wallet - -import ( - "fmt" - "os" - - "github.com/FactomProject/factom" - "github.com/FactomProject/factomd/common/factoid" -) - -// ImportWalletFromMnemonic creates a new wallet with a provided Mnemonic seed -// defined in bip-0039. -func ImportLDBWalletFromMnemonic(mnemonic, path string) (*Wallet, error) { - mnemonic, err := factom.ParseMnemonic(mnemonic) - if err != nil { - return nil, err - } - - // check if the file exists - _, err = os.Stat(path) - if err == nil { - return nil, fmt.Errorf("%s: file already exists", path) - } - - db, err := NewLevelDB(path) - if err != nil { - return nil, err - } - - seed := new(DBSeed) - seed.MnemonicSeed = mnemonic - if err := db.InsertDBSeed(seed); err != nil { - return nil, err - } - - w := new(Wallet) - w.transactions = make(map[string]*factoid.Transaction) - w.WalletDatabaseOverlay = db - - return w, nil -} - -// ExportLDBWallet writes all the secret/publilc key pairs from a wallet and the -// wallet seed in a pritable format. -func ExportLDBWallet(path string) (string, []*factom.FactoidAddress, []*factom.ECAddress, error) { - // check if the file exists - _, err := os.Stat(path) - if err != nil { - return "", nil, nil, err - } - - w, err := NewOrOpenLevelDBWallet(path) - if err != nil { - return "", nil, nil, err - } - - m, err := w.GetSeed() - if err != nil { - return "", nil, nil, err - } - fs, es, err := w.GetAllAddresses() - if err != nil { - return "", nil, nil, err - } - return m, fs, es, nil -} diff --git a/wallet/sign.go b/wallet/sign.go deleted file mode 100644 index cc5bb96..0000000 --- a/wallet/sign.go +++ /dev/null @@ -1,28 +0,0 @@ -package wallet - -import ( - "github.com/FactomProject/factomd/common/primitives" -) - -// SignData signs arbitrary data -func (w *Wallet) SignData(signer string, data []byte) ([]byte, []byte, error) { - - var priv []byte - var pub []byte - - if fa, err := w.GetFCTAddress(signer); err == nil { - priv = fa.SecBytes() - pub = fa.PubBytes() - } else if ec, err := w.GetECAddress(signer); err == nil { - priv = ec.SecBytes() - pub = ec.PubBytes() - } else if id, err := w.GetIdentityKey(signer); err == nil { - priv = id.SecBytes() - pub = id.PubBytes() - } else { - return nil, nil, ErrNoSuchAddress - } - - sig := primitives.Sign(priv, data) - return pub, sig, nil -} diff --git a/wallet/transaction.go b/wallet/transaction.go deleted file mode 100644 index 086c5f8..0000000 --- a/wallet/transaction.go +++ /dev/null @@ -1,427 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wallet - -import ( - "encoding/hex" - "errors" - "fmt" - "regexp" - - "github.com/FactomProject/btcutil/base58" - "github.com/FactomProject/factom" - "github.com/FactomProject/factomd/common/factoid" - "github.com/FactomProject/factomd/common/primitives" - "github.com/FactomProject/goleveldb/leveldb" -) - -var ( - ErrFeeTooLow = errors.New("wallet: Insufficient Fee") - ErrNoSuchAddress = errors.New("wallet: No such address") - ErrNoSuchIdentityKey = errors.New("wallet: No such identity key") - ErrTXExists = errors.New("wallet: Transaction name already exists") - ErrTXNotExists = errors.New("wallet: Transaction name was not found") - ErrTXNoInputs = errors.New("wallet: Transaction has no inputs") - ErrTXInvalidName = errors.New("wallet: Transaction name is not valid") -) - -func (w *Wallet) NewTransaction(name string) error { - if w.TransactionExists(name) { - return ErrTXExists - } - - // check that the transaction name is valid - if name == "" { - return ErrTXInvalidName - } - if len(name) > 32 { - return ErrTXInvalidName - } - if match, err := regexp.MatchString("[^a-zA-Z0-9_-]", name); err != nil { - return err - } else if match { - return ErrTXInvalidName - } - - tx := new(factoid.Transaction) - tx.SetTimestamp(primitives.NewTimestampNow()) - - w.txlock.Lock() - defer w.txlock.Unlock() - - w.transactions[name] = tx - return nil -} - -func (w *Wallet) DeleteTransaction(name string) error { - if !w.TransactionExists(name) { - return ErrTXNotExists - } - - w.txlock.Lock() - defer w.txlock.Unlock() - delete(w.transactions, name) - return nil -} - -func (w *Wallet) AddInput(name, address string, amount uint64) error { - tx, err := w.GetTransaction(name) - if err != nil { - return err - } - - a, err := w.GetFCTAddress(address) - if err == leveldb.ErrNotFound { - return ErrNoSuchAddress - } else if err != nil { - return err - } - adr := factoid.NewAddress(a.RCDHash()) - - // First look if this is really an update - for _, input := range tx.GetInputs() { - if input.GetAddress().IsSameAs(adr) { - input.SetAmount(amount) - return nil - } - } - - // Add our new input - tx.AddInput(adr, amount) - tx.AddRCD(factoid.NewRCD_1(a.PubBytes())) - - return nil -} - -func (w *Wallet) AddOutput(name, address string, amount uint64) error { - tx, err := w.GetTransaction(name) - if err != nil { - return err - } - - // Make sure that this is a valid Factoid output - if factom.AddressStringType(address) != factom.FactoidPub { - return errors.New("Invalid Factoid Address") - } - - adr := factoid.NewAddress(base58.Decode(address)[2:34]) - - // First look if this is really an update - for _, output := range tx.GetOutputs() { - if output.GetAddress().IsSameAs(adr) { - output.SetAmount(amount) - return nil - } - } - - tx.AddOutput(adr, amount) - - return nil -} - -func (w *Wallet) AddECOutput(name, address string, amount uint64) error { - tx, err := w.GetTransaction(name) - if err != nil { - return err - } - - // Make sure that this is a valid Entry Credit output - if factom.AddressStringType(address) != factom.ECPub { - return errors.New("Invalid Entry Credit Address") - } - - adr := factoid.NewAddress(base58.Decode(address)[2:34]) - - // First look if this is really an update - for _, output := range tx.GetECOutputs() { - if output.GetAddress().IsSameAs(adr) { - output.SetAmount(amount) - return nil - } - } - - tx.AddECOutput(adr, amount) - - return nil -} - -func (w *Wallet) AddFee(name, address string, rate uint64) error { - tx, err := w.GetTransaction(name) - if err != nil { - return err - } - - { - ins, err := tx.TotalInputs() - if err != nil { - return err - } - outs, err := tx.TotalOutputs() - if err != nil { - return err - } - ecs, err := tx.TotalECs() - if err != nil { - return err - } - - if ins != outs+ecs { - return fmt.Errorf("Inputs and outputs don't add up") - } - } - - txfee, err := tx.CalculateFee(rate) - if err != nil { - return err - } - - a, err := w.GetFCTAddress(address) - if err != nil { - return err - } - adr := factoid.NewAddress(a.RCDHash()) - - for _, input := range tx.GetInputs() { - if input.GetAddress().IsSameAs(adr) { - amt, err := factoid.ValidateAmounts(input.GetAmount(), txfee) - if err != nil { - return err - } - input.SetAmount(amt) - return nil - } - } - return fmt.Errorf("%s is not an input to the transaction.", address) -} - -func (w *Wallet) SubFee(name, address string, rate uint64) error { - tx, err := w.GetTransaction(name) - if err != nil { - return err - } - - if !factom.IsValidAddress(address) { - return errors.New("Invalid Address") - } - - { - ins, err := tx.TotalInputs() - if err != nil { - return err - } - outs, err := tx.TotalOutputs() - if err != nil { - return err - } - ecs, err := tx.TotalECs() - if err != nil { - return err - } - - if ins != outs+ecs { - return fmt.Errorf("Inputs and outputs don't add up") - } - } - - txfee, err := tx.CalculateFee(rate) - if err != nil { - return err - } - - adr := factoid.NewAddress(base58.Decode(address)[2:34]) - - for _, output := range tx.GetOutputs() { - if output.GetAddress().IsSameAs(adr) { - output.SetAmount(output.GetAmount() - txfee) - return nil - } - } - return fmt.Errorf("%s is not an output to the transaction.", address) -} - -// SignTransaction signs a tmp transaction in the wallet with the appropriate -// keys from the wallet db -// force=true ignores the existing balance and fee overpayment checks. -func (w *Wallet) SignTransaction(name string, force bool) error { - tx, err := w.GetTransaction(name) - if err != nil { - return err - } - - if force == false { - // check that the address balances are sufficient for the transaction - if err := checkCovered(tx); err != nil { - return err - } - - // check that the fee is being paid (and not overpaid) - if err := checkFee(tx); err != nil { - return err - } - } - - data, err := tx.MarshalBinarySig() - if err != nil { - return err - } - - rcds := tx.GetRCDs() - if len(rcds) == 0 { - return ErrTXNoInputs - } - for i, rcd := range rcds { - a, err := rcd.GetAddress() - if err != nil { - return err - } - - f, err := w.GetFCTAddress(primitives.ConvertFctAddressToUserStr(a)) - if err != nil { - return err - } - sig := factoid.NewSingleSignatureBlock(f.SecBytes(), data) - tx.SetSignatureBlock(i, sig) - } - - return nil -} - -func (w *Wallet) GetTransaction(name string) (*factoid.Transaction, error) { - if !w.TransactionExists(name) { - return nil, ErrTXNotExists - } - - w.txlock.Lock() - defer w.txlock.Unlock() - - return w.transactions[name], nil -} - -func (w *Wallet) GetTransactions() map[string]*factoid.Transaction { - return w.transactions -} - -func (w *Wallet) TransactionExists(name string) bool { - w.txlock.Lock() - defer w.txlock.Unlock() - - if _, exists := w.transactions[name]; exists { - return true - } - return false -} - -func (w *Wallet) ComposeTransaction(name string) (*factom.JSON2Request, error) { - tx, err := w.GetTransaction(name) - if err != nil { - return nil, err - } - - type txreq struct { - Transaction string `json:"transaction"` - } - - param := new(txreq) - if p, err := tx.MarshalBinary(); err != nil { - return nil, err - } else { - param.Transaction = hex.EncodeToString(p) - } - - req := factom.NewJSON2Request("factoid-submit", APICounter(), param) - - return req, nil -} - -// Hexencoded transaction -func (w *Wallet) ImportComposedTransaction(name string, hexEncoded string) error { - tx := new(factoid.Transaction) - data, err := hex.DecodeString(hexEncoded) - if err != nil { - return err - } - - err = tx.UnmarshalBinary(data) - if err != nil { - return err - } - - w.txlock.Lock() - w.transactions[name] = tx - w.txlock.Unlock() - - return nil -} - -func checkCovered(tx *factoid.Transaction) error { - for _, in := range tx.GetInputs() { - balance, err := factom.GetFactoidBalance(in.GetUserAddress()) - if err != nil { - return err - } - if uint64(balance) < in.GetAmount() { - return fmt.Errorf( - "Address %s balance is too low. Available: %s Needed: %s", - in.GetUserAddress(), - factom.FactoshiToFactoid(uint64(balance)), - factom.FactoshiToFactoid(in.GetAmount()), - ) - } - } - return nil -} - -func checkFee(tx *factoid.Transaction) error { - ins, err := tx.TotalInputs() - if err != nil { - return err - } - outs, err := tx.TotalOutputs() - if err != nil { - return err - } - ecs, err := tx.TotalECs() - if err != nil { - return err - } - - // fee is the fee that will be paid - fee := int64(ins) - int64(outs) - int64(ecs) - - if fee <= 0 { - return ErrFeeTooLow - } - - rate, err := factom.GetECRate() - if err != nil { - return err - } - - // cfee is the fee calculated for the transaction - var cfee int64 - if c, err := tx.CalculateFee(rate); err != nil { - return err - } else if c == 0 { - return errors.New("wallet: Could not calculate fee") - } else { - cfee = int64(c) - } - - // fee is too low - if fee < cfee { - return ErrFeeTooLow - } - - // fee is too high (over 10x cfee) - if fee >= cfee*10 { - return fmt.Errorf( - "wallet: Overpaying fee by >10x. Paying: %v Requires: %v", - factom.FactoshiToFactoid(uint64(fee)), - factom.FactoshiToFactoid(uint64(cfee)), - ) - } - - return nil -} diff --git a/wallet/transaction_test.go b/wallet/transaction_test.go deleted file mode 100644 index ca729bf..0000000 --- a/wallet/transaction_test.go +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wallet_test - -import ( - "testing" - - "github.com/FactomProject/factom" - . "github.com/FactomProject/factom/wallet" - "github.com/FactomProject/factomd/common/primitives" -) - -func TestNewTransaction(t *testing.T) { - // create a new database - w1, err := NewMapDBWallet() - if err != nil { - t.Error(err) - } - - // create a new transaction - if err := w1.NewTransaction("test_tx-01"); err != nil { - t.Error(err) - } - if err := w1.NewTransaction("test_tx-02"); err != nil { - t.Error(err) - } - - if len(w1.GetTransactions()) != 2 { - t.Errorf("wrong number of transactions %v", w1.GetTransactions()) - } - - if err := w1.DeleteTransaction("test_tx-02"); err != nil { - t.Error(err) - } - - if len(w1.GetTransactions()) != 1 { - t.Errorf("wrong number of transactions %v", w1.GetTransactions()) - } - - // close and remove the testing db - if err := w1.Close(); err != nil { - t.Error(err) - } -} - -func TestAddInput(t *testing.T) { - zSec := "Fs1KWJrpLdfucvmYwN2nWrwepLn8ercpMbzXshd1g8zyhKXLVLWj" - - // create a new database - w1, err := NewMapDBWallet() - if err != nil { - t.Error(err) - } - - // write a new fct address to the db - f, err := factom.GetFactoidAddress(zSec) - if err != nil { - t.Error(err) - t.FailNow() - } - if err := w1.InsertFCTAddress(f); err != nil { - t.Error(err) - } - // Get the address back out of the db - adr, err := w1.GetFCTAddress(f.String()) - if err != nil { - t.Error(err) - } - - // create a new transaction - if err := w1.NewTransaction("tx-01"); err != nil { - t.Error(err) - } - - if err := w1.AddInput("tx-01", adr.String(), 5); err != nil { - t.Error(err) - } - if len(w1.GetTransactions()) != 1 { - t.Errorf("wrong number of transactions %v", w1.GetTransactions()) - } - t.Log(w1.GetTransactions()) - - // close and remove the testing db - if err := w1.Close(); err != nil { - t.Error(err) - } -} - -func TestComposeTrasnaction(t *testing.T) { - f1Sec := "Fs3E9gV6DXsYzf7Fqx1fVBQPQXV695eP3k5XbmHEZVRLkMdD9qCK" - // f1Sec := "Fs1KWJrpLdfucvmYwN2nWrwepLn8ercpMbzXshd1g8zyhKXLVLWj" - f2Sec := "Fs3GFV6GNV6ar4b8eGcQWpGFbFtkNWKfEPdbywmha8ez5p7XMJyk" - e1Sec := "Es2Rf7iM6PdsqfYCo3D1tnAR65SkLENyWJG1deUzpRMQmbh9F3eG" - - // create a new database - w1, err := NewMapDBWallet() - if err != nil { - t.Error(err) - } - - // write a new fct address to the db - if in, err := factom.GetFactoidAddress(f1Sec); err != nil { - t.Error(err) - } else { - if err := w1.InsertFCTAddress(in); err != nil { - t.Error(err) - } - } - - // Get the address back out of the db - f1 := factom.NewFactoidAddress() - if out, err := factom.GetFactoidAddress(f1Sec); err != nil { - t.Error(err) - } else { - if f, err := w1.GetFCTAddress(out.String()); err != nil { - t.Error(err) - } else { - f1 = f - } - } - - // setup a factoid address for receving - f2, err := factom.GetFactoidAddress(f2Sec) - if err != nil { - t.Error(err) - } - - // setup an ec address for receving - e1, err := factom.GetECAddress(e1Sec) - if err != nil { - t.FailNow() - t.Error(err) - } - - // create a new transaction - if err := w1.NewTransaction("tx-01"); err != nil { - t.Error(err) - } - if err := w1.AddInput("tx-01", f1.String(), 5e8); err != nil { - t.Error(err) - } - if err := w1.AddOutput("tx-01", f2.String(), 3e8); err != nil { - t.Error(err) - } - if err := w1.AddECOutput("tx-01", e1.PubString(), 2e8); err != nil { - t.Error(err) - } - if err := w1.AddFee("tx-01", f1.String(), 10000); err != nil { - t.Error(err) - } - if err := w1.SignTransaction("tx-01", true); err != nil { - t.Error(err) - } - - if j, err := w1.ComposeTransaction("tx-01"); err != nil { - t.Error(err) - } else { - t.Log(factom.EncodeJSONString(j)) - } - - // close and remove the testing db - if err := w1.Close(); err != nil { - t.Error(err) - } -} - -func TestImportComposedTransaction(t *testing.T) { - transSig := "020158fe8efb78010100afd89f60646f3e8750c550e4582eca5047546ffef89c13a175985e320232" + - "bacac81cc428afd7c20001ed0da7057f80dfeb596e6c72c4550c7c7694661dfee2c4a6ba1b903b6ec3e201718b" + - "5edd2914acc2e4677f336c1a32736e5e9bde13663e6413894f57ec272e28015183427204adbc50623d09ea5a76" + - "947b4c742e5b56d1483483d5d4336ac12872891be0afae50ce916639dd6db6200e3816d8bd73025b79b7af4de11fcd2105" - - transNoSig := "020158feae8aff010100afd89f60646f3e8750c550e4582eca5047546ffef89c13a175985e320232ba" + - "cac81cc428afd7c20001ed0da7057f80dfeb596e6c72c4550c7c7694661dfee2c4a6ba1b903b6ec3e201718b5e" + - "dd2914acc2e4677f336c1a32736e5e9bde13663e6413894f57ec272e2800000000000000000000000000000000" + - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - - _ = transSig - w1, err := NewMapDBWallet() - if err != nil { - t.Error(err) - } - - err = w1.ImportComposedTransaction("txImported", transNoSig) - if err != nil { - t.Error(err) - } - - trans := w1.GetTransactions()["txImported"] - if trans == nil { - t.Error("Transaction not found") - } - - ins := trans.GetInputs() - if len(ins) != 1 { - t.Error("Transaction only has 1 input") - } - - inAddr := primitives.ConvertFctAddressToUserStr(ins[0].GetAddress()) - if inAddr != "FA2jK2HcLnRdS94dEcU27rF3meoJfpUcZPSinpb7AwQvPRY6RL1Q" { - t.Error("Input does not match address") - } - - outs := trans.GetOutputs() - if len(outs) != 1 { - t.Error("Transaction only has 1 input") - } - - outAddr := primitives.ConvertFctAddressToUserStr(outs[0].GetAddress()) - if outAddr != "FA1yvkgzxMigVDU1WRnpHXhAE3e5zQpE6KKyf5EF76Y34TSg6m8X" { - t.Error("Ouput does not match address") - } - - sum, err := trans.TotalOutputs() - if err != nil { - t.Error(err) - } - - if sum != 1e8 { - t.Error("Output amount is incorrect") - } - - err = trans.ValidateSignatures() - if err == nil { - t.Error("Should be an error") - } - - // With sig - err = w1.ImportComposedTransaction("txImportedSig", transSig) - if err != nil { - t.Error(err) - } - - transStructSig := w1.GetTransactions()["txImportedSig"] - if transStructSig == nil { - t.Error("Transaction not found") - } - - err = transStructSig.ValidateSignatures() - if err != nil { - t.Error(err) - } -} diff --git a/wallet/txdatabase.go b/wallet/txdatabase.go deleted file mode 100644 index 903d53b..0000000 --- a/wallet/txdatabase.go +++ /dev/null @@ -1,444 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wallet - -import ( - "encoding/hex" - "fmt" - "os" - - "github.com/FactomProject/factom" - "github.com/FactomProject/factomd/common/directoryBlock" - "github.com/FactomProject/factomd/common/factoid" - "github.com/FactomProject/factomd/common/interfaces" - "github.com/FactomProject/factomd/common/primitives" - "github.com/FactomProject/factomd/database/databaseOverlay" - "github.com/FactomProject/factomd/database/hybridDB" - "github.com/FactomProject/factomd/database/mapdb" -) - -// Database keys and key prefixes -var ( - fblockDBPrefix = []byte("FBlock") -) - -type TXDatabaseOverlay struct { - DBO databaseOverlay.Overlay - - // To indicate to sub processes to quit - quit bool -} - -func NewTXOverlay(db interfaces.IDatabase) *TXDatabaseOverlay { - answer := new(TXDatabaseOverlay) - answer.DBO.DB = db - return answer -} - -func NewTXMapDB() *TXDatabaseOverlay { - return NewTXOverlay(new(mapdb.MapDB)) -} - -func NewTXLevelDB(ldbpath string) (*TXDatabaseOverlay, error) { - db, err := hybridDB.NewLevelMapHybridDB(ldbpath, false) - if err != nil { - fmt.Printf("err opening transaction db: %v\n", err) - } - - if db == nil { - fmt.Println("Creating new transaction db ...") - db, err = hybridDB.NewLevelMapHybridDB(ldbpath, true) - - if err != nil { - return nil, err - } - } - fmt.Println("Transaction database started from: " + ldbpath) - return NewTXOverlay(db), nil -} - -func NewTXBoltDB(boltPath string) (*TXDatabaseOverlay, error) { - fileInfo, err := os.Stat(boltPath) - if err == nil { - if fileInfo.IsDir() { - return nil, fmt.Errorf("%s is not a Bolt databse file", boltPath) - } - } - if err != nil && !os.IsNotExist(err) { - fmt.Printf("database error %s\n", err) - return nil, err - } - - defer func() { - if r := recover(); r != nil { - fmt.Printf("Could not use wallet cache database file \"%s\"\n%v\n", boltPath, r) - os.Exit(1) - } - }() - db := hybridDB.NewBoltMapHybridDB(nil, boltPath) - - fmt.Println("Database started from: " + boltPath) - return NewTXOverlay(db), nil -} - -func (db *TXDatabaseOverlay) Close() error { - db.quit = true - return db.DBO.Close() -} - -// GetAllTXs returns a list of all transactions in the history of Factom. A -// local database is used to cache the factoid blocks. -func (db *TXDatabaseOverlay) GetAllTXs() ([]interfaces.ITransaction, error) { - // update the database and get the newest fblock - _, err := db.Update() - if err != nil { - return nil, err - } - fblock, err := db.DBO.FetchFBlockHead() - if err != nil { - return nil, err - } - if fblock == nil { - return nil, fmt.Errorf("FBlock Chain has not finished syncing") - } - txs := make([]interfaces.ITransaction, 0) - - for { - // get all of the txs from the block - height := fblock.GetDatabaseHeight() - for _, tx := range fblock.GetTransactions() { - ins, err := tx.TotalInputs() - if err != nil { - return nil, err - } - outs, err := tx.TotalOutputs() - if err != nil { - return nil, err - } - - if ins != 0 || outs != 0 { - tx.SetBlockHeight(height) - txs = append(txs, tx) - } - } - - if pre := fblock.GetPrevKeyMR().String(); pre != factom.ZeroHash { - // get the previous block - fblock, err = db.GetFBlock(pre) - if err != nil { - return nil, err - } else if fblock == nil { - return nil, fmt.Errorf("Missing fblock in database: %s", pre) - } - } else { - break - } - } - - return txs, nil -} - -// GetTX gets a transaction by the transaction id -func (db *TXDatabaseOverlay) GetTX(txid string) (interfaces.ITransaction, error) { - txs, err := db.GetAllTXs() - if err != nil { - return nil, err - } - - for _, tx := range txs { - if tx.GetSigHash().String() == txid { - return tx, nil - } - } - - return nil, fmt.Errorf("Transaction not found") -} - -// GetTXAddress returns a list of all transactions in the history of Factom that -// include a specific address. -func (db *TXDatabaseOverlay) GetTXAddress(adr string) ( - []interfaces.ITransaction, error) { - filtered := make([]interfaces.ITransaction, 0) - - txs, err := db.GetAllTXs() - if err != nil { - return nil, err - } - - if factom.AddressStringType(adr) == factom.FactoidPub { - for _, tx := range txs { - for _, in := range tx.GetInputs() { - if primitives.ConvertFctAddressToUserStr(in.GetAddress()) == adr { - filtered = append(filtered, tx) - } - } - for _, out := range tx.GetOutputs() { - if primitives.ConvertFctAddressToUserStr(out.GetAddress()) == adr { - filtered = append(filtered, tx) - } - } - } - } else if factom.AddressStringType(adr) == factom.ECPub { - for _, tx := range txs { - for _, out := range tx.GetECOutputs() { - if primitives.ConvertECAddressToUserStr(out.GetAddress()) == adr { - filtered = append(filtered, tx) - } - } - } - } else { - return nil, fmt.Errorf("not a valid address") - } - - return filtered, nil -} - -func (db *TXDatabaseOverlay) GetTXRange(start, end int) ( - []interfaces.ITransaction, error) { - if start < 0 || end < 0 || end < start { - return nil, fmt.Errorf("Range cannot have negative numbers") - } - - // update the database and get the newest fblock - _, err := db.Update() - if err != nil { - return nil, err - } - fblock, err := db.DBO.FetchFBlockHead() - if err != nil { - return nil, err - } - if fblock == nil { - return nil, fmt.Errorf("FBlock Chain has not finished syncing") - } - txs := make([]interfaces.ITransaction, 0) - - s, e := uint32(start), uint32(end) - - for { - // get all of the txs from the block - height := fblock.GetDatabaseHeight() - - if s <= height && height <= e { - for _, tx := range fblock.GetTransactions() { - ins, err := tx.TotalInputs() - if err != nil { - return nil, err - } - outs, err := tx.TotalOutputs() - if err != nil { - return nil, err - } - - if ins != 0 || outs != 0 { - tx.SetBlockHeight(height) - txs = append(txs, tx) - } - } - } - - precedessor := fblock.GetPrevKeyMR().String() - if height <= s || precedessor == factom.ZeroHash { - break - } - - // get the previous block - fblock, err = db.GetFBlock(precedessor) - if err != nil { - return nil, err - } else if fblock == nil { - return nil, fmt.Errorf("Missing fblock in database: %s", precedessor) - } - } - - return txs, nil -} - -// GetFBlock retrives a Factoid Block from Factom -func (db *TXDatabaseOverlay) GetFBlock(keymr string) (interfaces.IFBlock, error) { - h, err := primitives.NewShaHashFromStr(keymr) - if err != nil { - return nil, err - } - - fBlock, err := db.DBO.FetchFBlock(h) - if err != nil { - return nil, err - } - return fBlock, nil -} - -func (db *TXDatabaseOverlay) FetchNextFBlockHeight() (uint32, error) { - block, err := db.DBO.FetchFBlockHead() - if err != nil { - return 0, err - } - if block == nil { - return 0, nil - } - return block.GetDBHeight() + 1, nil -} - -func (db *TXDatabaseOverlay) InsertFBlockHead(fblock interfaces.IFBlock) error { - return db.DBO.SaveFactoidBlockHead(fblock) -} - -// Update gets all fblocks written since the database was last updated, and -// returns the most recent fblock keymr. -func (db *TXDatabaseOverlay) Update() (string, error) { - newestFBlock, err := fblockHead() - if err != nil { - return "", err - } - - start, err := db.FetchNextFBlockHeight() - if err != nil { - return "", err - } - - // Make sure we didn't switch networks - genesis, err := db.DBO.FetchFBlockByHeight(0) - if err != nil { - return "", err - } - if genesis != nil { - genesis2, err := getdblockbyheight(0) - if err != nil { - return "", err - } - - var gensisFBlockKeyMr interfaces.IHash - for _, e := range genesis2.GetDBEntries() { - if e.GetChainID().String() == "000000000000000000000000000000000000000000000000000000000000000f" { - gensisFBlockKeyMr = e.GetKeyMR() - break - } - } - - if gensisFBlockKeyMr == nil { - return "", fmt.Errorf("unable to fetch the genesis block via the api") - } - - if !gensisFBlockKeyMr.IsSameAs(genesis.GetKeyMR()) { - start = 0 - } - } - - newestHeight := newestFBlock.GetDatabaseHeight() - - // If the newest block in the tx cashe has a greater height than the newest - // fblock then clear the cashe and start from 0. - if start >= newestHeight { - db.DBO.Clear(databaseOverlay.FACTOIDBLOCK) - return newestFBlock.GetKeyMR().String(), nil - } - - // If the latest block from the database is not available from the blockchain - // then clear the cashe and start from 0. - if f, err := getfblockbyheight(start); err != nil { - db.DBO.Clear(databaseOverlay.FACTOIDBLOCK) - return f.GetKeyMR().String(), err - } - - db.DBO.StartMultiBatch() - for i := start; i <= newestHeight; i++ { - if i%1000 == 0 { - if newestHeight-start > 1000 { - fmt.Printf("Fetching block %v/%v\n", i, newestHeight) - } - } - fblock, err := getfblockbyheight(i) - if err != nil { - db.DBO.ExecuteMultiBatch() - return "", err - } - db.DBO.ProcessFBlockMultiBatch(fblock) - - // Save to DB every 500 blocks - if i%500 == 0 { - db.DBO.ExecuteMultiBatch() - db.DBO.StartMultiBatch() - } - - // If the wallet is stopped, this process becomes hard to kill. Have it exit - if db.quit { - break - } - } - - if !db.quit { - fmt.Printf("Fetching block %v/%v\n", newestHeight, newestHeight) - } - - // Save the remaining blocks - if err = db.DBO.ExecuteMultiBatch(); err != nil { - return "", err - } - - return newestFBlock.GetKeyMR().String(), nil -} - -// fblockHead gets the most recent fblock. -func fblockHead() (interfaces.IFBlock, error) { - fblockID := "000000000000000000000000000000000000000000000000000000000000000f" - - dbhead, err := factom.GetDBlockHead() - if err != nil { - return nil, err - } - dblock, err := factom.GetDBlock(dbhead) - if err != nil { - return nil, err - } - - var fblockmr string - for _, eblock := range dblock.DBEntries { - if eblock.ChainID == fblockID { - fblockmr = eblock.KeyMR - } - } - if fblockmr == "" { - return nil, err - } - - return getfblock(fblockmr) -} - -func getfblock(keymr string) (interfaces.IFBlock, error) { - raw, err := factom.GetRaw(keymr) - if err != nil { - return nil, err - } - - return factoid.UnmarshalFBlock(raw) -} - -func getfblockbyheight(height uint32) (interfaces.IFBlock, error) { - resp, err := factom.GetBlockByHeightRaw("fblock", int64(height)) - if err != nil { - return nil, err - } - - raw, err := hex.DecodeString(resp.RawData) - if err != nil { - return nil, err - } - - return factoid.UnmarshalFBlock(raw) -} - -func getdblockbyheight(height uint32) (interfaces.IDirectoryBlock, error) { - resp, err := factom.GetBlockByHeightRaw("dblock", int64(height)) - if err != nil { - return nil, err - } - - raw, err := hex.DecodeString(resp.RawData) - if err != nil { - return nil, err - } - - return directoryBlock.UnmarshalDBlock(raw) -} diff --git a/wallet/txdatabase_test.go b/wallet/txdatabase_test.go deleted file mode 100644 index 7692262..0000000 --- a/wallet/txdatabase_test.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wallet_test - -import ( - "testing" - - . "github.com/FactomProject/factom/wallet" - "github.com/FactomProject/factomd/common/interfaces" - "github.com/FactomProject/factomd/testHelper" -) - -func TestTXDatabaseOverlay(t *testing.T) { - db1 := NewTXMapDB() - - fblock := fblockHead() - if err := db1.InsertFBlockHead(fblock); err != nil { - t.Error(err) - } - if f, err := db1.GetFBlock(fblock.GetKeyMR().String()); err != nil { - t.Error(err) - } else if f == nil { - t.Errorf("Fblock not found in db") - } -} - -/* -func TestGetAllTXs(t *testing.T) { - db1 := NewTXMapDB() - - txs, err := db1.GetAllTXs() - if err != nil { - t.Error(err) - } - t.Logf("got %d txs", len(txs)) -} - -func TestGetTXAddress(t *testing.T) { - db1 := NewTXMapDB() - - adr := "FA2jK2HcLnRdS94dEcU27rF3meoJfpUcZPSinpb7AwQvPRY6RL1Q" - txs, err := db1.GetTXAddress(adr) - if err != nil { - t.Error(err) - } - t.Logf("got %d txs", len(txs)) -} -*/ -//func TestGetAllTXs(t *testing.T) { -// dbpath := os.TempDir() + "/test_txdb-01" -// db1, err := NewTXLevelDB(dbpath) -// if err != nil { -// t.Error(err) -// } -// defer db1.Close() -// -// txs := make(chan interfaces.ITransaction, 500) -// errs := make(chan error) -// output := make(chan string) -// -// go db1.GetAllTXs(txs, errs) -// -// go func() { -// for tx := range txs { -// output <- fmt.Sprint("Got TX:", tx) -// } -// output <- fmt.Sprint("end of txs") -// }() -// -// go func() { -// for err := range errs { -// output <- fmt.Sprintln("Got error:", err) -// } -// output <- fmt.Sprint("end of errs") -// }() -// -// for { -// fmt.Println(<-output) -// } -// -//// for { -//// select { -//// case tx, ok := <-txs: -//// fmt.Println("Got TX:", tx) -//// if !ok { -//// txs = nil -//// } -//// case err, ok := <-errs: -//// if !ok { -//// errs = nil -//// } -//// } -//// -//// if txs == nil && errs == nil { -//// break -//// } -//// } -//} - -// fblockHead gets the most recent fblock. -func fblockHead() interfaces.IFBlock { - return testHelper.CreateTestFactoidBlock(nil) -} diff --git a/wallet/util.go b/wallet/util.go deleted file mode 100644 index e50a98a..0000000 --- a/wallet/util.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wallet - -import ( - "bytes" - "crypto/sha256" - - "github.com/FactomProject/btcutil/base58" -) - -const ( - SeedLength = 64 - ApiVersion = "2.0" -) - -// WalletVersion sets the semantic version number of the build -// if using the standard vendor directory build process for factom-walletd in the factom-walletd repo is -// $ go install -ldflags "-X github.com/FactomProject/factom/wallet.WalletVersion=`cat ./vendor/github.com/FactomProject/factom/wallet/VERSION`" -v - -//if doing development and modifying the factom repo, in factom-walletd run -// $ go install -ldflags "-X github.com/FactomProject/factom/wallet.WalletVersion=`cat $GOPATH/src/github.com/FactomProject/factom/wallet/VERSION`" -v - -// It also seems to need to have the previous binary deleted if recompiling to have this message show up if no code has changed. - -var WalletVersion string = "BuiltWithoutVersion" - -// seed address prefix -var seedPrefix = []byte{0x13, 0xdd} - -// SeedString returnes the string representation of a raw Wallet Seed or Next -// Wallet Seed. -func SeedString(seed []byte) string { - if len(seed) != SeedLength { - return "" - } - - buf := new(bytes.Buffer) - - // 2 byte Seed Address Prefix - buf.Write(seedPrefix) - - // 64 byte Seed - buf.Write(seed) - - // 4 byte Checksum - check := shad(buf.Bytes())[:4] - buf.Write(check) - - return base58.Encode(buf.Bytes()) -} - -// shad Double Sha256 Hash; sha256(sha256(data)) -func shad(data []byte) []byte { - h1 := sha256.Sum256(data) - h2 := sha256.Sum256(h1[:]) - return h2[:] -} - -// newCounter is used to generate the ID field for the JSON2Request -func newCounter() func() int { - count := 0 - return func() int { - count += 1 - return count - } -} - -var APICounter = newCounter() diff --git a/wallet/util_test.go b/wallet/util_test.go deleted file mode 100644 index dd8f459..0000000 --- a/wallet/util_test.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wallet_test - -import ( - . "github.com/FactomProject/factom/wallet" - "testing" -) - -func TestSeedString(t *testing.T) { - zSeedStr := "sdLGjhUDxGpiBEPRhTwysRYmxNQD6V48Aa84oVzfHvy6suim6qB6m3MCp8aHu1k1CNVLJdB8N9HtGR4NZTtFfp3mj591eA3" - - seed := make([]byte, 64) - if SeedString(seed) != zSeedStr { - t.Errorf("seed string does not match") - } -} diff --git a/wallet/v1conversion.go b/wallet/v1conversion.go deleted file mode 100644 index 017df78..0000000 --- a/wallet/v1conversion.go +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wallet - -import ( - "fmt" - - "github.com/FactomProject/factoid" - "github.com/FactomProject/factoid/state/stateinit" - "github.com/FactomProject/factoid/wallet" - "github.com/FactomProject/factom" -) - -// This file is a dirty hack to to get the keys out of a version 1 wallet. - -// ImportV1Wallet takes a version 1 wallet bolt.db file and imports all of its -// addresses into a factom wallet. -func ImportV1Wallet(v1path, v2path string) (*Wallet, error) { - w, err := NewOrOpenBoltDBWallet(v2path) - if err != nil { - return nil, err - } - - fstate := stateinit.NewFactoidState(v1path) - - _, values := fstate.GetDB().GetKeysValues([]byte(factoid.W_NAME)) - for _, v := range values { - we, ok := v.(wallet.IWalletEntry) - if !ok { - w.Close() - return nil, fmt.Errorf("Cannot retrieve addresses from version 1 database") - } - - switch we.GetType() { - case "fct": - f, err := factom.MakeFactoidAddress(we.GetPrivKey(0)[:32]) - if err != nil { - w.Close() - return nil, err - } - if err := w.InsertFCTAddress(f); err != nil { - w.Close() - return nil, err - } - case "ec": - e, err := factom.MakeECAddress(we.GetPrivKey(0)[:32]) - if err != nil { - w.Close() - return nil, err - } - if err := w.InsertECAddress(e); err != nil { - w.Close() - return nil, err - } - default: - return nil, fmt.Errorf("version 1 database returned unknown address type %s %#v", we.GetType(), we) - } - } - return w, err -} - -// ImportV1WalletToLDB takes a version 1 wallet bolt.db file and imports all of its -// addresses into a factom wallet. -func ImportV1WalletToLDB(v1path, v2path string) (*Wallet, error) { - w, err := NewOrOpenBoltDBWallet(v2path) - if err != nil { - return nil, err - } - - fstate := stateinit.NewFactoidState(v1path) - - _, values := fstate.GetDB().GetKeysValues([]byte(factoid.W_NAME)) - for _, v := range values { - we, ok := v.(wallet.IWalletEntry) - if !ok { - w.Close() - return nil, fmt.Errorf("Cannot retrieve addresses from version 1 database") - } - - switch we.GetType() { - case "fct": - f, err := factom.MakeFactoidAddress(we.GetPrivKey(0)[:32]) - if err != nil { - w.Close() - return nil, err - } - if err := w.InsertFCTAddress(f); err != nil { - w.Close() - return nil, err - } - case "ec": - e, err := factom.MakeECAddress(we.GetPrivKey(0)[:32]) - if err != nil { - w.Close() - return nil, err - } - if err := w.InsertECAddress(e); err != nil { - w.Close() - return nil, err - } - default: - return nil, fmt.Errorf("version 1 database returned unknown address type %s %#v", we.GetType(), we) - } - } - return w, err -} - -// ImportV1WalletToEncryptedDB takes a version 1 wallet bolt.db file and imports all of its -// addresses into a factom wallet. -func ImportV1WalletToEncryptedDB(v1path, v2path, password string) (*Wallet, error) { - w, err := NewEncryptedBoltDBWallet(v2path, password) - if err != nil { - return nil, err - } - - fstate := stateinit.NewFactoidState(v1path) - - _, values := fstate.GetDB().GetKeysValues([]byte(factoid.W_NAME)) - for _, v := range values { - we, ok := v.(wallet.IWalletEntry) - if !ok { - w.Close() - return nil, fmt.Errorf("Cannot retrieve addresses from version 1 database") - } - - switch we.GetType() { - case "fct": - f, err := factom.MakeFactoidAddress(we.GetPrivKey(0)[:32]) - if err != nil { - w.Close() - return nil, err - } - if err := w.InsertFCTAddress(f); err != nil { - w.Close() - return nil, err - } - case "ec": - e, err := factom.MakeECAddress(we.GetPrivKey(0)[:32]) - if err != nil { - w.Close() - return nil, err - } - if err := w.InsertECAddress(e); err != nil { - w.Close() - return nil, err - } - default: - return nil, fmt.Errorf("version 1 database returned unknown address type %s %#v", we.GetType(), we) - } - } - return w, err -} diff --git a/wallet/v1conversion_test.go b/wallet/v1conversion_test.go deleted file mode 100644 index 2b1054d..0000000 --- a/wallet/v1conversion_test.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wallet_test - -import ( - "os" - "testing" - - . "github.com/FactomProject/factom/wallet" -) - -func TestImportV1Wallet(t *testing.T) { - v1path := os.TempDir() + "/factoid_wallet_bolt.db" - v2path := os.TempDir() + "/test_wallet-01" - - w, err := ImportV1Wallet(v1path, v2path) - if err != nil { - t.Error(err) - } - - fs, es, err := w.GetAllAddresses() - // print the addresses - for _, f := range fs { - t.Logf("%s %s", f, f.SecString()) - } - for _, e := range es { - t.Logf("%s %s", e, e.SecString()) - } - - // close and remove the testing db - if err := w.Close(); err != nil { - t.Error(err) - } - if err := os.RemoveAll(v2path); err != nil { - t.Error(err) - } -} diff --git a/wallet/walletDBO.go b/wallet/walletDBO.go deleted file mode 100644 index e5d354c..0000000 --- a/wallet/walletDBO.go +++ /dev/null @@ -1,626 +0,0 @@ -package wallet - -import ( - "bytes" - "crypto/rand" - "encoding/gob" - "fmt" - "os" - "path/filepath" - "sort" - "strings" - - "github.com/FactomProject/factom" - "github.com/FactomProject/factomd/common/interfaces" - "github.com/FactomProject/factomd/common/primitives" - "github.com/FactomProject/factomd/database/databaseOverlay" - "github.com/FactomProject/factomd/database/hybridDB" - "github.com/FactomProject/factomd/database/mapdb" - "github.com/FactomProject/factomd/database/securedb" - "github.com/FactomProject/go-bip32" - "github.com/FactomProject/go-bip39" -) - -// Database keys and key prefixes -var ( - fcDBPrefix = []byte("Factoids") - ecDBPrefix = []byte("Entry Credits") - seedDBKey = []byte("DB Seed") - identityDBPrefix = []byte("Identities") -) - -type WalletDatabaseOverlay struct { - DBO databaseOverlay.Overlay -} - -func NewWalletOverlay(db interfaces.IDatabase) *WalletDatabaseOverlay { - answer := new(WalletDatabaseOverlay) - answer.DBO.DB = db - return answer -} - -func NewMapDB() *WalletDatabaseOverlay { - return NewWalletOverlay(new(mapdb.MapDB)) -} - -func NewLevelDB(ldbpath string) (*WalletDatabaseOverlay, error) { - db, err := hybridDB.NewLevelMapHybridDB(ldbpath, false) - if err != nil { - fmt.Printf("err opening db: %v\n", err) - } - - if db == nil { - fmt.Println("Creating new db ...") - db, err = hybridDB.NewLevelMapHybridDB(ldbpath, true) - - if err != nil { - return nil, err - } - } - fmt.Println("Database started from: " + ldbpath) - return NewWalletOverlay(db), nil -} - -func NewBoltDB(boltPath string) (*WalletDatabaseOverlay, error) { - // setup panic recovery - defer func() { - if r := recover(); r != nil { - fmt.Printf("Could not use wallet file \"%s\"\n%v\n", boltPath, r) - os.Exit(1) - } - }() - - // check if the file exists or if it is a directory - fileInfo, err := os.Stat(boltPath) - if err == nil { - if fileInfo.IsDir() { - return nil, fmt.Errorf("The path %s is a directory. Please specify a file name.", boltPath) - } - } - - // create the wallet directory if it doesn't already exist - if os.IsNotExist(err) { - if err := os.MkdirAll(filepath.Dir(boltPath), 0700); err != nil { - fmt.Printf("database error %s\n", err) - } - } - - // check for other errors besides the file not existing - if err != nil && !os.IsNotExist(err) { - fmt.Printf("database error %s\n", err) - return nil, err - } - - db := hybridDB.NewBoltMapHybridDB(nil, boltPath) - fmt.Println("Database started from: " + boltPath) - return NewWalletOverlay(db), nil -} - -func NewEncryptedBoltDB(boltPath, password string) (*WalletDatabaseOverlay, error) { - err := CreateEncryptedBoltDB(boltPath) - if err != nil { - return nil, err - } - wOverlay, err := OpenEncryptedBoltDB(boltPath, password) - if err != nil { - return nil, err - } - return wOverlay, nil -} - -func CreateEncryptedBoltDB(boltPath string) error { - // check if the file exists or if it is a directory - fileInfo, err := os.Stat(boltPath) - if err == nil { - if fileInfo.IsDir() { - return fmt.Errorf("The path %s is a directory. Please specify a file name.", boltPath) - } - } - - // create the wallet directory if it doesn't already exist - if os.IsNotExist(err) { - if err := os.MkdirAll(filepath.Dir(boltPath), 0700); err != nil { - fmt.Printf("database error %s\n", err) - } - } - - if err != nil && !os.IsNotExist(err) { //some other error, besides the file not existing - fmt.Printf("database error %s\n", err) - return err - } - return nil -} - -func OpenEncryptedBoltDB(boltPath, password string) (*WalletDatabaseOverlay, error) { - defer func() { - if r := recover(); r != nil { - fmt.Printf("Could not use wallet file \"%s\"\n%v\n", boltPath, r) - os.Exit(1) - } - }() - db, err := securedb.NewEncryptedDB(boltPath, "Bolt", password) - if err != nil { - return nil, err - } - - fmt.Println("Encrypted Database started from: " + boltPath) - return NewWalletOverlay(db), nil -} - -type DBSeedBase struct { - MnemonicSeed string - NextFactoidAddressIndex uint32 - NextECAddressIndex uint32 - NextIdentityKeyIndex uint32 -} - -type DBSeed struct { - DBSeedBase -} - -var _ interfaces.BinaryMarshallable = (*DBSeed)(nil) - -func (e *DBSeed) MarshalBinary() ([]byte, error) { - var data primitives.Buffer - - enc := gob.NewEncoder(&data) - - err := enc.Encode(e.DBSeedBase) - if err != nil { - return nil, err - } - return data.DeepCopyBytes(), nil -} - -func (e *DBSeed) UnmarshalBinaryData(data []byte) (newData []byte, err error) { - dec := gob.NewDecoder(primitives.NewBuffer(data)) - dbsb := DBSeedBase{} - err = dec.Decode(&dbsb) - if err != nil { - return nil, err - } - e.DBSeedBase = dbsb - return nil, nil -} - -func (e *DBSeed) UnmarshalBinary(data []byte) (err error) { - _, err = e.UnmarshalBinaryData(data) - return -} - -func (e *DBSeed) JSONByte() ([]byte, error) { - return primitives.EncodeJSON(e) -} - -func (e *DBSeed) JSONString() (string, error) { - return primitives.EncodeJSONString(e) -} - -func (e *DBSeed) JSONBuffer(b *bytes.Buffer) error { - return primitives.EncodeJSONToBuffer(e, b) -} - -func (e *DBSeed) String() string { - str, _ := e.JSONString() - return str -} - -func (e *DBSeed) NextFCTAddress() (*factom.FactoidAddress, error) { - add, err := factom.MakeBIP44FactoidAddress( - e.MnemonicSeed, - bip32.FirstHardenedChild, - 0, - e.NextFactoidAddressIndex, - ) - if err != nil { - return nil, err - } - e.NextFactoidAddressIndex++ - return add, nil -} - -func (e *DBSeed) NextECAddress() (*factom.ECAddress, error) { - add, err := factom.MakeBIP44ECAddress( - e.MnemonicSeed, - bip32.FirstHardenedChild, - 0, - e.NextECAddressIndex, - ) - if err != nil { - return nil, err - } - e.NextECAddressIndex++ - return add, nil -} - -func (e *DBSeed) NextIdentityKey() (*factom.IdentityKey, error) { - add, err := factom.MakeBIP44IdentityKey( - e.MnemonicSeed, - bip32.FirstHardenedChild, - 0, - e.NextIdentityKeyIndex, - ) - if err != nil { - return nil, err - } - e.NextIdentityKeyIndex++ - return add, nil -} - -func NewRandomSeed() (*DBSeed, error) { - seed := make([]byte, 16) - if n, err := rand.Read(seed); err != nil { - panic(err) - return nil, err - } else if n != 16 { - return nil, fmt.Errorf("Wrong number of bytes read: %d", n) - } - - mnemonic, err := bip39.NewMnemonic(seed) - if err != nil { - panic(err) - return nil, err - } - - dbSeed := new(DBSeed) - dbSeed.MnemonicSeed = mnemonic - - return dbSeed, nil -} - -func (db *WalletDatabaseOverlay) InsertDBSeed(seed *DBSeed) error { - if seed == nil { - return nil - } - - batch := []interfaces.Record{} - batch = append(batch, interfaces.Record{seedDBKey, seedDBKey, seed}) - - return db.DBO.PutInBatch(batch) -} - -func (db *WalletDatabaseOverlay) GetDBSeed() (*DBSeed, error) { - data, err := db.DBO.Get(seedDBKey, seedDBKey, new(DBSeed)) - if err != nil { - return nil, err - } - if data == nil { - return nil, nil - } - return data.(*DBSeed), nil -} - -func (db *WalletDatabaseOverlay) GetOrCreateDBSeed() (*DBSeed, error) { - data, err := db.DBO.Get(seedDBKey, seedDBKey, new(DBSeed)) - if err != nil { - return nil, err - } - if data == nil { - seed, err := NewRandomSeed() - if err != nil { - return nil, err - } - err = db.InsertDBSeed(seed) - if err != nil { - return nil, err - } - return seed, nil - } - return data.(*DBSeed), nil -} - -func (db *WalletDatabaseOverlay) GetNextECAddress() (*factom.ECAddress, error) { - seed, err := db.GetOrCreateDBSeed() - if err != nil { - return nil, err - } - add, err := seed.NextECAddress() - if err != nil { - return nil, err - } - err = db.InsertDBSeed(seed) - if err != nil { - return nil, err - } - err = db.InsertECAddress(add) - if err != nil { - return nil, err - } - return add, nil -} - -func (db *WalletDatabaseOverlay) GetNextFCTAddress() (*factom.FactoidAddress, error) { - seed, err := db.GetOrCreateDBSeed() - if err != nil { - return nil, err - } - add, err := seed.NextFCTAddress() - if err != nil { - return nil, err - } - err = db.InsertDBSeed(seed) - if err != nil { - return nil, err - } - err = db.InsertFCTAddress(add) - if err != nil { - return nil, err - } - return add, nil -} - -func (db *WalletDatabaseOverlay) InsertECAddress(e *factom.ECAddress) error { - if e == nil { - return nil - } - - batch := []interfaces.Record{} - batch = append(batch, interfaces.Record{ecDBPrefix, []byte(e.PubString()), e}) - - return db.DBO.PutInBatch(batch) -} - -func (db *WalletDatabaseOverlay) GetECAddress(pubString string) (*factom.ECAddress, error) { - data, err := db.DBO.Get(ecDBPrefix, []byte(pubString), new(factom.ECAddress)) - if err != nil { - return nil, err - } - if data == nil { - return nil, ErrNoSuchAddress - } - return data.(*factom.ECAddress), nil -} - -func (db *WalletDatabaseOverlay) GetAllECAddresses() ([]*factom.ECAddress, error) { - list, err := db.DBO.FetchAllBlocksFromBucket(ecDBPrefix, new(ECA)) - if err != nil { - return nil, err - } - return toECList(list), nil -} - -func toECList(source []interfaces.BinaryMarshallableAndCopyable) []*factom.ECAddress { - answer := make([]*factom.ECAddress, len(source)) - for i, v := range source { - answer[i] = v.(*ECA).ECAddress - } - sort.Sort(byECName(answer)) - return answer -} - -type byECName []*factom.ECAddress - -func (f byECName) Len() int { - return len(f) -} -func (f byECName) Less(i, j int) bool { - a := strings.Compare(f[i].PubString(), f[j].PubString()) - return a < 0 -} -func (f byECName) Swap(i, j int) { - f[i], f[j] = f[j], f[i] -} - -func (db *WalletDatabaseOverlay) InsertFCTAddress(e *factom.FactoidAddress) error { - if e == nil { - return nil - } - - batch := []interfaces.Record{} - batch = append(batch, interfaces.Record{fcDBPrefix, []byte(e.String()), e}) - - return db.DBO.PutInBatch(batch) -} - -func (db *WalletDatabaseOverlay) GetFCTAddress(str string) (*factom.FactoidAddress, error) { - data, err := db.DBO.Get(fcDBPrefix, []byte(str), new(factom.FactoidAddress)) - if err != nil { - return nil, err - } - if data == nil { - return nil, ErrNoSuchAddress - } - return data.(*factom.FactoidAddress), nil -} - -func (db *WalletDatabaseOverlay) GetAllFCTAddresses() ([]*factom.FactoidAddress, error) { - list, err := db.DBO.FetchAllBlocksFromBucket(fcDBPrefix, new(FA)) - if err != nil { - return nil, err - } - return toFList(list), nil -} - -func toFList(source []interfaces.BinaryMarshallableAndCopyable) []*factom.FactoidAddress { - answer := make([]*factom.FactoidAddress, len(source)) - for i, v := range source { - answer[i] = v.(*FA).FactoidAddress - } - sort.Sort(byFName(answer)) - return answer -} - -func (db *WalletDatabaseOverlay) RemoveAddress(pubString string) error { - if len(pubString) == 0 { - return nil - } - if pubString[:1] == "F" { - data, err := db.DBO.Get(fcDBPrefix, []byte(pubString), new(factom.FactoidAddress)) - if err != nil { - return err - } - if data == nil { - return ErrNoSuchAddress - } - err = db.DBO.Delete(fcDBPrefix, []byte(pubString)) - if err == nil { - err := db.DBO.Delete(fcDBPrefix, []byte(pubString)) //delete twice to flush the db file - return err - } else { - return err - } - } else if pubString[:1] == "E" { - data, err := db.DBO.Get(ecDBPrefix, []byte(pubString), new(factom.ECAddress)) - if err != nil { - return err - } - if data == nil { - return ErrNoSuchAddress - } - err = db.DBO.Delete(ecDBPrefix, []byte(pubString)) - if err == nil { - err := db.DBO.Delete(ecDBPrefix, []byte(pubString)) //delete twice to flush the db file - return err - } else { - return err - } - } else { - return fmt.Errorf("Unknown address type") - } - - return nil -} - -type byFName []*factom.FactoidAddress - -func (f byFName) Len() int { - return len(f) -} -func (f byFName) Less(i, j int) bool { - a := strings.Compare(f[i].String(), f[j].String()) - return a < 0 -} -func (f byFName) Swap(i, j int) { - f[i], f[j] = f[j], f[i] -} - -type ECA struct { - *factom.ECAddress -} - -var _ interfaces.BinaryMarshallableAndCopyable = (*ECA)(nil) - -func (t *ECA) New() interfaces.BinaryMarshallableAndCopyable { - e := new(ECA) - e.ECAddress = factom.NewECAddress() - return e -} - -type FA struct { - *factom.FactoidAddress -} - -var _ interfaces.BinaryMarshallableAndCopyable = (*FA)(nil) - -func (t *FA) New() interfaces.BinaryMarshallableAndCopyable { - e := new(FA) - e.FactoidAddress = factom.NewFactoidAddress() - return e -} - -func (db *WalletDatabaseOverlay) GetNextIdentityKey() (*factom.IdentityKey, error) { - seed, err := db.GetOrCreateDBSeed() - if err != nil { - return nil, err - } - add, err := seed.NextIdentityKey() - if err != nil { - return nil, err - } - err = db.InsertDBSeed(seed) - if err != nil { - return nil, err - } - err = db.InsertIdentityKey(add) - if err != nil { - return nil, err - } - return add, nil -} - -func (db *WalletDatabaseOverlay) InsertIdentityKey(e *factom.IdentityKey) error { - if e == nil { - return nil - } - - batch := []interfaces.Record{} - batch = append(batch, interfaces.Record{identityDBPrefix, []byte(e.String()), e}) - - return db.DBO.PutInBatch(batch) -} - -func (db *WalletDatabaseOverlay) GetIdentityKey(str string) (*factom.IdentityKey, error) { - data, err := db.DBO.Get(identityDBPrefix, []byte(str), new(factom.IdentityKey)) - if err != nil { - return nil, err - } - if data == nil { - return nil, ErrNoSuchIdentityKey - } - return data.(*factom.IdentityKey), nil -} - -func (db *WalletDatabaseOverlay) GetAllIdentityKeys() ([]*factom.IdentityKey, error) { - list, err := db.DBO.FetchAllBlocksFromBucket(identityDBPrefix, new(ID)) - if err != nil { - return nil, err - } - return toIdentityKeyList(list), nil -} - -func toIdentityKeyList(source []interfaces.BinaryMarshallableAndCopyable) []*factom.IdentityKey { - answer := make([]*factom.IdentityKey, len(source)) - for i, v := range source { - answer[i] = v.(*ID).IdentityKey - } - sort.Sort(byKeyName(answer)) - return answer -} - -func (db *WalletDatabaseOverlay) RemoveIdentityKey(pubString string) error { - if len(pubString) == 0 { - return nil - } - - data, err := db.DBO.Get(identityDBPrefix, []byte(pubString), new(factom.IdentityKey)) - if err != nil { - return err - } - if data == nil { - return ErrNoSuchIdentityKey - } - err = db.DBO.Delete(identityDBPrefix, []byte(pubString)) - if err == nil { - err := db.DBO.Delete(identityDBPrefix, []byte(pubString)) //delete twice to flush the db file - return err - } else { - return err - } - - return nil -} - -type byKeyName []*factom.IdentityKey - -func (f byKeyName) Len() int { - return len(f) -} -func (f byKeyName) Less(i, j int) bool { - a := strings.Compare(f[i].String(), f[j].String()) - return a < 0 -} -func (f byKeyName) Swap(i, j int) { - f[i], f[j] = f[j], f[i] -} - -type ID struct { - *factom.IdentityKey -} - -var _ interfaces.BinaryMarshallableAndCopyable = (*ID)(nil) - -func (t *ID) New() interfaces.BinaryMarshallableAndCopyable { - e := new(ID) - e.IdentityKey = factom.NewIdentityKey() - return e -} diff --git a/wallet/walletDBO_test.go b/wallet/walletDBO_test.go deleted file mode 100644 index 9e42dd8..0000000 --- a/wallet/walletDBO_test.go +++ /dev/null @@ -1,109 +0,0 @@ -package wallet_test - -import ( - "strings" - "testing" - - . "github.com/FactomProject/factom/wallet" -) - -func TestWalletDBO(t *testing.T) { - db := NewMapDB() - seed, err := db.GetOrCreateDBSeed() - if err != nil { - t.Errorf("%v", err) - } - - seed.MnemonicSeed = "yellow yellow yellow yellow yellow yellow yellow yellow yellow yellow yellow yellow" - - err = db.InsertDBSeed(seed) - if err != nil { - t.Errorf("%v", err) - } - - ec, err := db.GetNextECAddress() - if err != nil { - t.Errorf("%v", err) - } - if ec.String() != "EC2KnJQN86MYq4pQyeSGTHSiVdkhRCPXS3udzD4im6BXRBjZFMmR" { - t.Errorf("%v", ec.String()) - } - ec, err = db.GetNextECAddress() - if err != nil { - t.Errorf("%v", err) - } - if ec.String() != "EC2UNG5LztGN3BNiVMEgkBP8ra8ud3HjjWWXKjrQozJ98rTvXKYy" { - t.Errorf("%v", ec.String()) - } - - f, err := db.GetNextFCTAddress() - if err != nil { - t.Errorf("%v", err) - } - if f.String() != "FA22de5NSG2FA2HmMaD4h8qSAZAJyztmmnwgLPghCQKoSekwYYct" { - t.Errorf("%v", f.String()) - } - f, err = db.GetNextFCTAddress() - if err != nil { - t.Errorf("%v", err) - } - if f.String() != "FA3heCmxKCk1tCCfiAMDmX8Ctg6XTQjRRaJrF5Jagc9rbo7wqQLV" { - t.Errorf("%v", f.String()) - } -} - -func TestDBSeed(t *testing.T) { - seed, err := NewRandomSeed() - if err != nil { - t.Errorf("%v", err) - } - if seed.MnemonicSeed == "" { - t.Errorf("Empty mnemonic seed returned") - } - l := len(strings.Fields(seed.MnemonicSeed)) - if l < 12 { - t.Errorf("Not enough words in mnemonic. Expecitng 12, found %d", l) - } - if l > 12 { - t.Errorf("Too many words in mnemonic. Expecitng 12, found %d", l) - } - - seed.MnemonicSeed = "yellow yellow yellow yellow yellow yellow yellow yellow yellow yellow yellow yellow" - - ec, err := seed.NextECAddress() - if err != nil { - t.Errorf("%v", err) - } - if ec.String() != "EC2KnJQN86MYq4pQyeSGTHSiVdkhRCPXS3udzD4im6BXRBjZFMmR" { - t.Errorf("%v", ec.String()) - } - ec, err = seed.NextECAddress() - if err != nil { - t.Errorf("%v", err) - } - if ec.String() != "EC2UNG5LztGN3BNiVMEgkBP8ra8ud3HjjWWXKjrQozJ98rTvXKYy" { - t.Errorf("%v", ec.String()) - } - - f, err := seed.NextFCTAddress() - if err != nil { - t.Errorf("%v", err) - } - if f.String() != "FA22de5NSG2FA2HmMaD4h8qSAZAJyztmmnwgLPghCQKoSekwYYct" { - t.Errorf("%v", f.String()) - } - f, err = seed.NextFCTAddress() - if err != nil { - t.Errorf("%v", err) - } - if f.String() != "FA3heCmxKCk1tCCfiAMDmX8Ctg6XTQjRRaJrF5Jagc9rbo7wqQLV" { - t.Errorf("%v", f.String()) - } - - if seed.NextFactoidAddressIndex != 2 { - t.Errorf("Wrong NextFactoidAddressIndex") - } - if seed.NextECAddressIndex != 2 { - t.Errorf("Wrong NextECAddressIndex") - } -} diff --git a/wallet/wsapi/10000addressesTest.sh b/wallet/wsapi/10000addressesTest.sh deleted file mode 100755 index a3da8da..0000000 --- a/wallet/wsapi/10000addressesTest.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -#set -x - -# This is to test the the load that wallet-balances can handle. - -FCTADDWFACTOIDS="FA3EPZYqodgyEGXNMbiZKE5TS2x2J9wF8J9MvPZb52iGR78xMgCb" - -# This takes makes 10,000 factoid addresses and funds all of them with a random factoshi balance - -COUNTFCT=10000 -OUTPUTFCT="" - -while [ $COUNT -gt 0 ]; do - OUTPUTFCT="$(echo `factom-cli newfctaddress`)" - AMOUNTFCT="1.$((RANDOM % 10000))" - factom-cli sendfct FA3EPZYqodgyEGXNMbiZKE5TS2x2J9wF8J9MvPZb52iGR78xMgCb "$OUTPUTFCT" "$AMOUNTFCT" >> factomcli.log & - let COUNTFCT=COUNTFCT-1 -done - -# This creates 1000 entry credit addesses and funds them - -COUNTEC=1000 -OUTPUTEC="" - -while [ $COUNTEC -gt 0 ]; do - OUTPUTEC="$(echo `factom-cli newecaddress`)" - AMOUNTEC="$((1 + RANDOM % 15))" - factom-cli buyec "$FCTADDWFACTOIDS" "$OUTPUTEC" "$AMOUNTEC" >> factomcliec.log & - let COUNTEC=COUNTEC-1 -done diff --git a/wallet/wsapi/errors.go b/wallet/wsapi/errors.go deleted file mode 100644 index 6404e2a..0000000 --- a/wallet/wsapi/errors.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wsapi - -import ( - "github.com/FactomProject/factom" - "github.com/FactomProject/web" -) - -const httpBad = 200 - -// handleV2Error handles the error responses to RPC calls -func handleV2Error(ctx *web.Context, j *factom.JSON2Request, err *factom.JSONError) { - resp := factom.NewJSON2Response() - if j != nil { - resp.ID = j.ID - } else { - resp.ID = nil - } - resp.Error = err - - ctx.WriteHeader(httpBad) - ctx.Write([]byte(resp.String())) -} - -/* -The error codes from and including -32768 to -32000 are reserved for pre-defined errors. Any code within this range, but not defined explicitly below is reserved for future use. The error codes are nearly the same as those suggested for XML-RPC at the following url: http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php - -code message meaning --32700 Parse error Invalid JSON was received by the server. - An error occurred on the server while parsing the JSON text. --32600 Invalid Request The JSON sent is not a valid Request object. --32601 Method not found The method does not exist / is not available. --32602 Invalid params Invalid method parameter(s). --32603 Internal error Internal JSON-RPC error. --32000 to -32099 Server error Reserved for implementation-defined server-errors. -*/ - -// RPC Errors - -func newParseError() *factom.JSONError { - return factom.NewJSONError(-32700, "Parse error", nil) -} - -func newInvalidRequestError() *factom.JSONError { - return factom.NewJSONError(-32600, "Invalid Request", nil) -} - -func newMethodNotFoundError() *factom.JSONError { - return factom.NewJSONError(-32601, "Method not found", nil) -} - -func newInvalidParamsError() *factom.JSONError { - return factom.NewJSONError(-32602, "Invalid params", nil) -} - -func newInternalError() *factom.JSONError { - return factom.NewJSONError(-32603, "Internal error", nil) -} - -func newWalletIsLockedError() *factom.JSONError { - return factom.NewJSONError(-32001, "Wallet is locked", nil) -} - -func newIncorrectPassphraseError() *factom.JSONError { - return factom.NewJSONError(-32003, "Incorrect passphrase", nil) -} - -// Custom Errors - -func newCustomInternalError(data interface{}) *factom.JSONError { - return factom.NewJSONError(-32603, "Internal error", data) -} - -func newCustomInvalidParamsError(data interface{}) *factom.JSONError { - return factom.NewJSONError(-32602, "Invalid params", data) -} diff --git a/wallet/wsapi/structs.go b/wallet/wsapi/structs.go deleted file mode 100644 index a0de86c..0000000 --- a/wallet/wsapi/structs.go +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wsapi - -import ( - "github.com/FactomProject/factom" -) - -type TLSConfig struct { - TLSEnable bool - TLSKeyFile string - TLSCertFile string -} - -// requests - -type passphraseRequest struct { - Password string `json:"passphrase"` - Timeout int64 `json:"timeout"` -} - -type addressRequest struct { - Address string `json:"address"` -} - -type addressesRequest struct { - Addresses []string `json:"addresses"` -} - -type importRequest struct { - Addresses []struct { - Secret string `json:"secret"` - } `json:"addresses"` -} - -type importKoinifyRequest struct { - Words string `json:"words"` -} - -type transactionRequest struct { - Name string `json:"tx-name"` - Force bool `json:"force"` -} - -type signDataRequest struct { - Signer string `json:"signer"` - Data []byte `json:"data"` -} - -type transactionValueRequest struct { - Name string `json:"tx-name"` - Address string `json:"address"` - Amount uint64 `json:"amount"` -} - -type transactionAddressRequest struct { - Name string `json:"tx-name"` - Address string `json:"address"` -} - -type txdbRequest struct { - TxID string `json:"txid,omitempty"` - Address string `json:"address,omitempty"` - Range struct { - Start int `json:"start"` - End int `json:"end"` - } `json:"range,omitempty"` -} - -type entryRequest struct { - Entry factom.Entry `json:"entry"` - ECPub string `json:"ecpub"` - Force bool `json:"force"` -} - -type chainRequest struct { - Chain factom.Chain `json:"chain"` - ECPub string `json:"ecpub"` - Force bool `json:"force"` -} - -type identityKeyRequest struct { - Public string `json:"public"` -} - -type importIdentityKeysRequest struct { - Keys []struct { - Secret string `json:"secret"` - } `json:keys` -} - -type activeIdentityKeysRequest struct { - ChainID string `json:"chainid"` - Height *int64 `json:"height"` -} - -type identityChainRequest struct { - Name []string `json:"name"` - PubKeys []string `json:"pubkeys"` - ECPub string `json:"ecpub"` - Force bool `json:"force"` -} - -type identityKeyReplacementRequest struct { - ChainID string `json:"chainid"` - OldKey string `json:"oldkey"` - NewKey string `json:"newkey"` - SignerKey string `json:"signerkey"` - ECPub string `json:"ecpub"` - Force bool `json:"force"` -} - -type identityAttributeRequest struct { - ReceiverChainID string `json:"receiver-chainid"` - DestinationChainID string `json:"destination-chainid"` - Attributes []factom.IdentityAttribute `json:"attributes"` - SignerKey string `json:"signerkey"` - SignerChainID string `json:"signer-chainid"` - ECPub string `json:"ecpub"` - Force bool `json:"force"` -} - -type identityAttributeEndorsementRequest struct { - DestinationChainID string `json:"destination-chainid"` - EntryHash string `json:"entry-hash"` - SignerKey string `json:"signerkey"` - SignerChainID string `json:"signer-chainid"` - ECPub string `json:"ecpub"` - Force bool `json:"force"` -} - -// responses - -type addressResponse struct { - Public string `json:"public"` - Secret string `json:"secret"` -} - -type multiAddressResponse struct { - Addresses []*addressResponse `json:"addresses"` -} - -type balanceResponse struct { - CurrentHeight uint32 `json:"current-height"` - LastSavedHeight uint `json:"last-saved-height"` - Balances []interface{} `json:"balances"` -} - -type multiBalanceResponse struct { - FactoidAccountBalances struct { - Ack int64 `json:"ack"` - Saved int64 `json:"saved"` - } `json:"fctaccountbalances"` - EntryCreditAccountBalances struct { - Ack int64 `json:"ack"` - Saved int64 `json:"saved"` - } `json:"ecaccountbalances"` -} - -type walletBackupResponse struct { - Seed string `json:"wallet-seed"` - Addresses []*addressResponse `json:"addresses"` - IdentityKeys []*identityKeyResponse `json:"identity-keys"` -} - -type multiTransactionResponse struct { - Transactions []*factom.Transaction `json:"transactions"` -} - -type propertiesResponse struct { - WalletVersion string `json:"walletversion"` - WalletApiVersion string `json:"walletapiversion"` -} - -type simpleResponse struct { - Success bool `json:"success"` -} - -type unlockResponse struct { - Success bool `json:"success"` - UnlockedUntil int64 `json:"unlockeduntil"` -} - -type entryResponse struct { - Commit *factom.JSON2Request `json:"commit"` - Reveal *factom.JSON2Request `json:"reveal"` -} - -type heightResponse struct { - Height int64 `json:"height"` -} - -type identityKeyResponse struct { - Public string `json:"public"` - Secret string `json:"secret,omitempty"` -} - -type multiIdentityKeyResponse struct { - Keys []*identityKeyResponse `json:"keys"` -} - -type activeIdentityKeysResponse struct { - ChainID string `json:"chainid"` - Height int64 `json:"height"` - Keys []string `json:"keys"` -} - -type signDataResponse struct { - PubKey []byte `json:"pubkey"` - Signature []byte `json:"signature"` -} - -// Helper structs - -type UnmarBody struct { - Jsonrpc string `json:"jsonrps"` - Id int `json:"id"` - Result balanceResponse `json:"result"` -} diff --git a/wallet/wsapi/wsapi.go b/wallet/wsapi/wsapi.go deleted file mode 100644 index bb4adbe..0000000 --- a/wallet/wsapi/wsapi.go +++ /dev/null @@ -1,1594 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -package wsapi - -import ( - "bytes" - "crypto/sha256" - "crypto/subtle" - "crypto/tls" - "encoding/base64" - "encoding/hex" - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "log" - "net/http" - "os" - "reflect" - "strings" - "time" - - "github.com/FactomProject/btcutil/certs" - "github.com/FactomProject/factom" - "github.com/FactomProject/factom/wallet" - "github.com/FactomProject/factomd/common/factoid" - "github.com/FactomProject/factomd/common/interfaces" - "github.com/FactomProject/factomd/common/primitives" - "github.com/FactomProject/factomd/database/securedb" - "github.com/FactomProject/web" -) - -const APIVersion string = "2.0" - -var ( - webServer *web.Server - fctWallet *wallet.Wallet - rpcUser string - rpcPass string - authsha []byte -) - -// httpBasicAuth returns the UTF-8 bytes of the HTTP Basic authentication -// string: -// -// "Basic " + base64(username + ":" + password) -func httpBasicAuth(username, password string) []byte { - const header = "Basic " - base64 := base64.StdEncoding - - b64InputLen := len(username) + len(":") + len(password) - b64Input := make([]byte, 0, b64InputLen) - b64Input = append(b64Input, username...) - b64Input = append(b64Input, ':') - b64Input = append(b64Input, password...) - - output := make([]byte, len(header)+base64.EncodedLen(b64InputLen)) - copy(output, header) - base64.Encode(output[len(header):], b64Input) - return output -} - -func genCertPair(certFile string, keyFile string, extraAddress string) error { - fmt.Println("Generating TLS certificates...") - - org := "factom autogenerated cert" - validUntil := time.Now().Add(10 * 365 * 24 * time.Hour) - - var externalAddresses []string - if extraAddress != "" { - externalAddresses = strings.Split(extraAddress, ",") - for _, i := range externalAddresses { - fmt.Printf("adding %s to certificate\n", i) - } - } - - cert, key, err := certs.NewTLSCertPair(org, validUntil, externalAddresses) - if err != nil { - return err - } - - // Write cert and key files. - if err = ioutil.WriteFile(certFile, cert, 0666); err != nil { - return err - } - if err = ioutil.WriteFile(keyFile, key, 0600); err != nil { - os.Remove(certFile) - return err - } - - fmt.Println("Done generating TLS certificates") - return nil -} - -// filesExists reports whether the named file or directory exists. -func fileExists(name string) bool { - if _, err := os.Stat(name); err != nil { - if os.IsNotExist(err) { - return false - } - } - return true -} - -func Start(w *wallet.Wallet, net string, c factom.RPCConfig) { - webServer = web.NewServer() - fctWallet = w - - if len(c.WalletCORSDomains) > 0 { - domains := strings.Split(c.WalletCORSDomains, ",") - var cors []string - for _, domain := range domains { - cors = append(cors, strings.Trim(domain, " ")) - } - webServer.Config.CorsDomains = cors - } - - rpcUser = c.WalletRPCUser - rpcPass = c.WalletRPCPassword - - h := sha256.New() - h.Write(httpBasicAuth(rpcUser, rpcPass)) - authsha = h.Sum(nil) //set this in the beginning to prevent timing attacks - - webServer.Post("/v2", handleV2) - webServer.Get("/v2", handleV2) - - if c.WalletTLSEnable == false { - webServer.Run(net) - } else { - if !fileExists(c.WalletTLSKeyFile) && !fileExists(c.WalletTLSCertFile) { - err := genCertPair(c.WalletTLSCertFile, c.WalletTLSKeyFile, c.WalletServer) - if err != nil { - log.Fatal(err) - } - } - keypair, err := tls.LoadX509KeyPair(c.WalletTLSCertFile, c.WalletTLSKeyFile) - if err != nil { - log.Fatal(err) - } - tlsConfig := &tls.Config{ - Certificates: []tls.Certificate{keypair}, - MinVersion: tls.VersionTLS12, - } - webServer.RunTLS(net, tlsConfig) - } -} - -func Stop() { - fctWallet.Close() - webServer.Close() -} - -func checkAuthHeader(r *http.Request) error { - // Don't bother to check the autorization if the rpc user/pass is not - // specified. - if rpcUser == "" { - return nil - } - - authhdr := r.Header["Authorization"] - if len(authhdr) == 0 { - fmt.Println("Username and Password expected, but none were received") - return errors.New("no auth") - } - - h := sha256.New() - h.Write([]byte(authhdr[0])) - presentedPassHash := h.Sum(nil) - cmp := subtle.ConstantTimeCompare(presentedPassHash, authsha) //compare hashes because ConstantTimeCompare takes a constant time based on the slice size. hashing gives a constant slice size. - if cmp != 1 { - fmt.Println("Incorrect Username and/or Password were received") - return errors.New("bad auth") - } - return nil -} - -func handleV2(ctx *web.Context) { - if err := checkAuthHeader(ctx.Request); err != nil { - remoteIP := "" - remoteIP += strings.Split(ctx.Request.RemoteAddr, ":")[0] - fmt.Printf("Unauthorized API client connection attempt from %s\n", remoteIP) - ctx.ResponseWriter.Header().Add("WWW-Authenticate", `Basic realm="factomd RPC"`) - http.Error(ctx.ResponseWriter, "401 Unauthorized.", http.StatusUnauthorized) - return - } - body, err := ioutil.ReadAll(ctx.Request.Body) - if err != nil { - handleV2Error(ctx, nil, newInvalidRequestError()) - return - } - - j, err := factom.ParseJSON2Request(string(body)) - if err != nil { - handleV2Error(ctx, nil, newInvalidRequestError()) - return - } - - jsonResp, jsonError := handleV2Request(j) - - if jsonError != nil { - handleV2Error(ctx, j, jsonError) - return - } - - ctx.Write([]byte(jsonResp.String())) -} - -func handleV2Request(j *factom.JSON2Request) (*factom.JSON2Response, *factom.JSONError) { - var resp interface{} - var jsonError *factom.JSONError - params := []byte(j.Params) - - // Only expose a subset of endpoints if the wallet is still waiting to be unlocked - if fctWallet.Encrypted && (fctWallet.WalletDatabaseOverlay == nil || fctWallet.DBO.DB.(*securedb.EncryptedDB).UnlockedUntil.Unix() < time.Now().Unix()) { - switch j.Method { - case "get-height": - resp, jsonError = handleGetHeight(params) - case "properties": - resp, jsonError = handleProperties(params) - case "transactions": - resp, jsonError = handleAllTransactions(params) - case "unlock-wallet": - resp, jsonError = handleWalletPassphrase(params) - default: - jsonError = newWalletIsLockedError() - } - } else { - switch j.Method { - case "address": - resp, jsonError = handleAddress(params) - case "all-addresses": - resp, jsonError = handleAllAddresses(params) - case "generate-ec-address": - resp, jsonError = handleGenerateECAddress(params) - case "generate-factoid-address": - resp, jsonError = handleGenerateFactoidAddress(params) - case "import-addresses": - resp, jsonError = handleImportAddresses(params) - case "import-koinify": - resp, jsonError = handleImportKoinify(params) - case "wallet-backup": - resp, jsonError = handleWalletBackup(params) - case "transactions": - resp, jsonError = handleAllTransactions(params) - case "new-transaction": - resp, jsonError = handleNewTransaction(params) - case "delete-transaction": - resp, jsonError = handleDeleteTransaction(params) - case "tmp-transactions": - resp, jsonError = handleTmpTransactions(params) - case "transaction-hash": - resp, jsonError = handleTransactionHash(params) - case "add-input": - resp, jsonError = handleAddInput(params) - case "add-output": - resp, jsonError = handleAddOutput(params) - case "add-ec-output": - resp, jsonError = handleAddECOutput(params) - case "add-fee": - resp, jsonError = handleAddFee(params) - case "sub-fee": - resp, jsonError = handleSubFee(params) - case "sign-transaction": - resp, jsonError = handleSignTransaction(params) - case "sign-data": - resp, jsonError = handleSignData(params) - case "compose-transaction": - resp, jsonError = handleComposeTransaction(params) - case "remove-address": - resp, jsonError = handleRemoveAddress(params) - case "properties": - resp, jsonError = handleProperties(params) - case "compose-chain": - resp, jsonError = handleComposeChain(params) - case "compose-entry": - resp, jsonError = handleComposeEntry(params) - case "get-height": - resp, jsonError = handleGetHeight(params) - case "wallet-balances": - resp, jsonError = handleWalletBalances(params) - case "identity-key": - resp, jsonError = handleIdentityKey(params) - case "all-identity-keys": - resp, jsonError = handleAllIdentityKeys(params) - case "import-identity-keys": - resp, jsonError = handleImportIdentityKeys(params) - case "generate-identity-key": - resp, jsonError = handleGenerateIdentityKey(params) - case "remove-identity-key": - resp, jsonError = handleRemoveIdentityKey(params) - case "active-identity-keys": - resp, jsonError = handleActiveIdentityKeys(params) - case "compose-identity-chain": - resp, jsonError = handleComposeIdentityChain(params) - case "compose-identity-key-replacement": - resp, jsonError = handleComposeIdentityKeyReplacement(params) - case "compose-identity-attribute": - resp, jsonError = handleComposeIdentityAttribute(params) - case "compose-identity-attribute-endorsement": - resp, jsonError = handleComposeIdentityAttributeEndorsement(params) - case "unlock-wallet": - resp, jsonError = handleWalletPassphrase(params) - default: - jsonError = newMethodNotFoundError() - } - } - - if jsonError != nil { - return nil, jsonError - } - - // don't print password attempts or private keys to output - switch j.Method { - case "import-addresses", "import-koinify", "unlock-wallet": - fmt.Printf("API V2 method: <%v>\n", j.Method) - default: - fmt.Printf("API V2 method: <%v> parameters: %s\n", j.Method, params) - } - - jsonResp := factom.NewJSON2Response() - jsonResp.ID = j.ID - if b, err := json.Marshal(resp); err != nil { - return nil, newCustomInternalError(err.Error()) - } else { - jsonResp.Result = b - } - - return jsonResp, nil -} - -func handleWalletBalances(params []byte) (interface{}, *factom.JSONError) { - //Get all of the addresses in the wallet - fs, es, err := fctWallet.GetAllAddresses() - if err != nil { - return nil, newCustomInternalError(err.Error() + " Wallet empty") - } - - fctAccounts := make([]string, 0) - ecAccounts := make([]string, 0) - - for _, f := range fs { - if len(mkAddressResponse(f).Secret) > 0 { - fctAccounts = append(fctAccounts, mkAddressResponse(f).Public) - } - } - for _, e := range es { - if len(mkAddressResponse(e).Secret) > 0 { - ecAccounts = append(ecAccounts, mkAddressResponse(e).Public) - } - } - - var stringOfAccountsEC string - if len(ecAccounts) != 0 { - stringOfAccountsEC = strings.Join(ecAccounts, `", "`) - } - - url := "http://" + factom.FactomdServer() + "/v2" - if url == "http:///v2" { - url = "http://localhost:8088/v2" - } - // Get Entry Credit balances from multiple-ec-balances API in factomd - jsonStrEC := []byte(`{"jsonrpc": "2.0", "id": 0, "method": "multiple-ec-balances", "params":{"addresses":["` + stringOfAccountsEC + `"]}} `) - reqEC, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStrEC)) - reqEC.Header.Set("content-type", "text/plain;") - reqEC.SetBasicAuth(factom.GetFactomdRpcConfig()) - - clientEC := &http.Client{} - callRespEC, err := clientEC.Do(reqEC) - if err != nil { - panic(err) - } - - defer callRespEC.Body.Close() - bodyEC, _ := ioutil.ReadAll(callRespEC.Body) - - respEC := new(UnmarBody) - errEC := json.Unmarshal([]byte(bodyEC), &respEC) - if errEC != nil { - return nil, newInvalidParamsError() - } - - //Total up the balances - var ( - ackBalTotalEC int64 - savedBalTotalEC int64 - badErrorEC string - ) - - var floatType = reflect.TypeOf(int64(0)) - - for i := range respEC.Result.Balances { - x, ok := respEC.Result.Balances[i].(map[string]interface{}) - if ok != true { - fmt.Println(x) - } - v := reflect.ValueOf(x["ack"]) - covneredAck := v.Convert(floatType) - ackBalTotalEC = ackBalTotalEC + covneredAck.Int() - - rawr := reflect.ValueOf(x["saved"]) - convertedSaved := rawr.Convert(floatType) - savedBalTotalEC = savedBalTotalEC + convertedSaved.Int() - - errors := x["err"] - if errors == "Not fully booted" { - badErrorEC = "Not fully booted" - } else if errors == "Error decoding address" { - badErrorEC = "Error decoding address" - } - } - - stringOfAccountsFCT := "" - if len(fctAccounts) != 0 { - stringOfAccountsFCT = strings.Join(fctAccounts, `", "`) - } - - // Get Factoid balances from multiple-fct-balances API in factomd - jsonStrFCT := []byte(`{"jsonrpc": "2.0", "id": 0, "method": "multiple-fct-balances", "params":{"addresses":["` + stringOfAccountsFCT + `"]}} `) - reqFCT, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStrFCT)) - reqFCT.Header.Set("content-type", "text/plain;") - reqFCT.SetBasicAuth(factom.GetFactomdRpcConfig()) - - clientFCT := &http.Client{} - callRespFCT, errFCT := clientFCT.Do(reqFCT) - if errFCT != nil { - panic(errFCT) - } - - defer callRespFCT.Body.Close() - bodyFCT, _ := ioutil.ReadAll(callRespFCT.Body) - - respFCT := new(UnmarBody) - errFCT2 := json.Unmarshal([]byte(bodyFCT), &respFCT) - if errFCT2 != nil { - return nil, newInvalidParamsError() - } - - // Total up the balances - var ( - ackBalTotalFCT int64 - savedBalTotalFCT int64 - badErrorFCT string - ) - - for i := range respFCT.Result.Balances { - x, ok := respFCT.Result.Balances[i].(map[string]interface{}) - if ok != true { - fmt.Println(x) - } - v := reflect.ValueOf(x["ack"]) - covneredAck := v.Convert(floatType) - ackBalTotalFCT = ackBalTotalFCT + covneredAck.Int() - - rawr := reflect.ValueOf(x["saved"]) - convertedSaved := rawr.Convert(floatType) - savedBalTotalFCT = savedBalTotalFCT + convertedSaved.Int() - - errors := x["err"] - if errors == "Not fully booted" { - badErrorFCT = "Not fully booted" - } else if errors == "Error decoding address" { - badErrorFCT = "Error decoding address" - } - - } - - if badErrorFCT == "Not fully booted" || badErrorEC == "Not fully booted" { - type nfb struct { - NotFullyBooted string `json:"Factomd Error"` - } - nfbstatus := new(nfb) - nfbstatus.NotFullyBooted = "Factomd is not fully booted, please wait and try again." - return nfbstatus, nil - } else if badErrorFCT == "Error decoding address" || badErrorEC == "Error decoding address" { - type errorDecoding struct { - NotFullyBooted string `json:"Factomd Error"` - } - errDecReturn := new(errorDecoding) - errDecReturn.NotFullyBooted = "There was an error decoding an address" - return errDecReturn, nil - } - - resp := new(multiBalanceResponse) - resp.FactoidAccountBalances.Ack = ackBalTotalFCT - resp.FactoidAccountBalances.Saved = savedBalTotalFCT - resp.EntryCreditAccountBalances.Ack = ackBalTotalEC - resp.EntryCreditAccountBalances.Saved = savedBalTotalEC - - return resp, nil -} - -func handleRemoveAddress(params []byte) (interface{}, *factom.JSONError) { - req := new(addressRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - err := fctWallet.WalletDatabaseOverlay.RemoveAddress(req.Address) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - resp := new(simpleResponse) - resp.Success = true - - return resp, nil -} - -func handleAddress(params []byte) (interface{}, *factom.JSONError) { - req := new(addressRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - resp := new(addressResponse) - switch factom.AddressStringType(req.Address) { - case factom.ECPub: - e, err := fctWallet.GetECAddress(req.Address) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if e == nil { - return nil, newCustomInternalError("Wallet: address not found") - } - resp = mkAddressResponse(e) - case factom.FactoidPub: - f, err := fctWallet.GetFCTAddress(req.Address) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - resp = mkAddressResponse(f) - default: - return nil, newCustomInternalError("Invalid address type") - } - - return resp, nil -} - -func handleAllAddresses(params []byte) (interface{}, *factom.JSONError) { - resp := new(multiAddressResponse) - - fs, es, err := fctWallet.GetAllAddresses() - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - for _, f := range fs { - resp.Addresses = append(resp.Addresses, mkAddressResponse(f)) - } - for _, e := range es { - resp.Addresses = append(resp.Addresses, mkAddressResponse(e)) - } - - return resp, nil -} - -func handleGenerateFactoidAddress(params []byte) (interface{}, *factom.JSONError) { - a, err := fctWallet.GenerateFCTAddress() - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - resp := mkAddressResponse(a) - - return resp, nil -} - -func handleGenerateECAddress(params []byte) (interface{}, *factom.JSONError) { - a, err := fctWallet.GenerateECAddress() - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - resp := mkAddressResponse(a) - - return resp, nil -} - -func handleImportAddresses(params []byte) (interface{}, *factom.JSONError) { - req := new(importRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - resp := new(multiAddressResponse) - for _, v := range req.Addresses { - switch factom.AddressStringType(v.Secret) { - case factom.FactoidSec: - f, err := factom.GetFactoidAddress(v.Secret) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if err := fctWallet.InsertFCTAddress(f); err != nil { - return nil, newCustomInternalError(err.Error()) - } - a := mkAddressResponse(f) - resp.Addresses = append(resp.Addresses, a) - case factom.ECSec: - e, err := factom.GetECAddress(v.Secret) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if err := fctWallet.InsertECAddress(e); err != nil { - return nil, newCustomInternalError(err.Error()) - } - a := mkAddressResponse(e) - resp.Addresses = append(resp.Addresses, a) - default: - return nil, newCustomInternalError("address could not be imported") - } - } - return resp, nil -} - -func handleImportKoinify(params []byte) (interface{}, *factom.JSONError) { - req := new(importKoinifyRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - f, err := factom.MakeFactoidAddressFromKoinify(req.Words) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if err := fctWallet.InsertFCTAddress(f); err != nil { - return nil, newCustomInternalError(err.Error()) - } - - return mkAddressResponse(f), nil -} - -func handleWalletBackup(params []byte) (interface{}, *factom.JSONError) { - resp := new(walletBackupResponse) - - if seed, err := fctWallet.GetSeed(); err != nil { - return nil, newCustomInternalError(err.Error()) - } else { - resp.Seed = seed - } - - fs, es, err := fctWallet.GetAllAddresses() - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - for _, f := range fs { - a := mkAddressResponse(f) - resp.Addresses = append(resp.Addresses, a) - } - for _, e := range es { - a := mkAddressResponse(e) - resp.Addresses = append(resp.Addresses, a) - } - - idKeys, err := fctWallet.GetAllIdentityKeys() - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - for _, k := range idKeys { - keyResp := new(identityKeyResponse) - keyResp.Public = k.PubString() - keyResp.Secret = k.SecString() - resp.IdentityKeys = append(resp.IdentityKeys, keyResp) - } - - return resp, nil -} - -func handleAllTransactions(params []byte) (interface{}, *factom.JSONError) { - if fctWallet.TXDB() == nil { - return nil, newCustomInternalError( - "Wallet does not have a transaction database") - } - req := new(txdbRequest) - if params != nil { - err := json.Unmarshal(params, req) - if err != nil { - return nil, newInvalidParamsError() - } - } - - resp := new(multiTransactionResponse) - - switch { - case req == nil: - txs, err := fctWallet.TXDB().GetAllTXs() - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - for _, tx := range txs { - r, err := factoidTxToTransaction(tx) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - resp.Transactions = append(resp.Transactions, r) - } - case req.TxID != "": - p, err := factom.GetRaw(req.TxID) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - tx := new(factoid.Transaction) - if err := tx.UnmarshalBinary(p); err != nil { - return nil, newCustomInternalError(err.Error()) - } - - r, err := factoidTxToTransaction(tx) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - resp.Transactions = append(resp.Transactions, r) - case req.Address != "": - txs, err := fctWallet.TXDB().GetTXAddress(req.Address) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - for _, tx := range txs { - r, err := factoidTxToTransaction(tx) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - resp.Transactions = append(resp.Transactions, r) - } - case req.Range.End != 0: - txs, err := fctWallet.TXDB().GetTXRange(req.Range.Start, req.Range.End) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - for _, tx := range txs { - r, err := factoidTxToTransaction(tx) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - resp.Transactions = append(resp.Transactions, r) - } - default: - txs, err := fctWallet.TXDB().GetAllTXs() - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - for _, tx := range txs { - r, err := factoidTxToTransaction(tx) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - resp.Transactions = append(resp.Transactions, r) - } - } - - return resp, nil -} - -// transaction handlers - -func handleNewTransaction(params []byte) (interface{}, *factom.JSONError) { - req := new(transactionRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - if err := fctWallet.NewTransaction(req.Name); err != nil { - return nil, newCustomInternalError(err.Error()) - } - - tx := fctWallet.GetTransactions()[req.Name] - resp, err := factoidTxToTransaction(tx) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - resp.Name = req.Name - resp.FeesRequired = feesRequired(tx) - - return resp, nil -} - -func handleDeleteTransaction(params []byte) (interface{}, *factom.JSONError) { - req := new(transactionRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - if err := fctWallet.DeleteTransaction(req.Name); err != nil { - return nil, newCustomInternalError(err.Error()) - } - resp := &factom.Transaction{Name: req.Name} - return resp, nil -} - -func handleTmpTransactions(params []byte) (interface{}, *factom.JSONError) { - resp := new(multiTransactionResponse) - txs := fctWallet.GetTransactions() - - for name, tx := range txs { - r, err := factoidTxToTransaction(tx) - if err != nil { - continue - } - r.Name = name - r.FeesRequired = feesRequired(tx) - resp.Transactions = append(resp.Transactions, r) - } - - return resp, nil -} - -func handleTransactionHash(params []byte) (interface{}, *factom.JSONError) { - req := new(transactionRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - resp := new(factom.Transaction) - txs := fctWallet.GetTransactions() - - for name, tx := range txs { - if name == req.Name { - resp.Name = name - resp.TxID = tx.GetSigHash().String() - return resp, nil - } - } - - return nil, newCustomInternalError("Transaction not found") -} - -func handleAddInput(params []byte) (interface{}, *factom.JSONError) { - req := new(transactionValueRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - if err := fctWallet.AddInput(req.Name, req.Address, req.Amount); err != nil { - return nil, newCustomInternalError(err.Error()) - } - tx := fctWallet.GetTransactions()[req.Name] - resp, err := factoidTxToTransaction(tx) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - resp.Name = req.Name - resp.FeesRequired = feesRequired(tx) - - return resp, nil -} - -func handleAddOutput(params []byte) (interface{}, *factom.JSONError) { - req := new(transactionValueRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - if err := fctWallet.AddOutput(req.Name, req.Address, req.Amount); err != nil { - return nil, newCustomInternalError(err.Error()) - } - tx := fctWallet.GetTransactions()[req.Name] - resp, err := factoidTxToTransaction(tx) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - resp.Name = req.Name - resp.FeesRequired = feesRequired(tx) - - return resp, nil -} - -func handleAddECOutput(params []byte) (interface{}, *factom.JSONError) { - req := new(transactionValueRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - if err := fctWallet.AddECOutput(req.Name, req.Address, req.Amount); err != nil { - return nil, newCustomInternalError(err.Error()) - } - tx := fctWallet.GetTransactions()[req.Name] - resp, err := factoidTxToTransaction(tx) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - resp.Name = req.Name - resp.FeesRequired = feesRequired(tx) - - return resp, nil -} - -func handleAddFee(params []byte) (interface{}, *factom.JSONError) { - req := new(transactionAddressRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - rate, err := factom.GetECRate() - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if err := fctWallet.AddFee(req.Name, req.Address, rate); err != nil { - return nil, newCustomInternalError(err.Error()) - } - tx := fctWallet.GetTransactions()[req.Name] - resp, err := factoidTxToTransaction(tx) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - resp.Name = req.Name - resp.FeesRequired = feesRequired(tx) - - return resp, nil -} - -func handleSubFee(params []byte) (interface{}, *factom.JSONError) { - req := new(transactionAddressRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - rate, err := factom.GetECRate() - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if err := fctWallet.SubFee(req.Name, req.Address, rate); err != nil { - return nil, newCustomInternalError(err.Error()) - } - tx := fctWallet.GetTransactions()[req.Name] - resp, err := factoidTxToTransaction(tx) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - resp.Name = req.Name - resp.FeesRequired = feesRequired(tx) - - return resp, nil -} - -func handleSignTransaction(params []byte) (interface{}, *factom.JSONError) { - req := new(transactionRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - force := req.Force - - if err := fctWallet.SignTransaction(req.Name, force); err != nil { - return nil, newCustomInternalError(err.Error()) - } - tx := fctWallet.GetTransactions()[req.Name] - resp, err := factoidTxToTransaction(tx) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - resp.Name = req.Name - resp.FeesRequired = feesRequired(tx) - - return resp, nil -} - -func handleSignData(params []byte) (interface{}, *factom.JSONError) { - req := new(signDataRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - pub, sig, err := fctWallet.SignData(req.Signer, req.Data) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - return signDataResponse{PubKey: pub, Signature: sig}, nil -} - -func handleComposeTransaction(params []byte) (interface{}, *factom.JSONError) { - req := new(transactionRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - t, err := fctWallet.ComposeTransaction(req.Name) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - return t, nil -} - -func handleComposeChain(params []byte) (interface{}, *factom.JSONError) { - req := new(chainRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - c := factom.NewChain(req.Chain.FirstEntry) - ecpub := req.ECPub - force := req.Force - - ec, err := fctWallet.GetECAddress(ecpub) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if ec == nil { - return nil, newCustomInternalError("Wallet: address not found") - } - - if !force { - // check ec address balance - balance, err := factom.GetECBalance(ecpub) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - if cost, err := factom.EntryCost(c.FirstEntry); err != nil { - return nil, newCustomInternalError(err.Error()) - } else if balance < int64(cost)+10 { - return nil, newCustomInternalError("Not enough Entry Credits") - } - - if factom.ChainExists(c.ChainID) { - return nil, newCustomInvalidParamsError("Chain " + c.ChainID + " already exists") - } - } - - commit, err := factom.ComposeChainCommit(c, ec) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - reveal, err := factom.ComposeChainReveal(c) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - resp := new(entryResponse) - resp.Commit = commit - resp.Reveal = reveal - return resp, nil -} - -func handleComposeEntry(params []byte) (interface{}, *factom.JSONError) { - req := new(entryRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - e := req.Entry - ecpub := req.ECPub - force := req.Force - - ec, err := fctWallet.GetECAddress(ecpub) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if ec == nil { - return nil, newCustomInternalError("Wallet: address not found") - } - if !force { - // check ec address balance - balance, err := factom.GetECBalance(ecpub) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - if cost, err := factom.EntryCost(&e); err != nil { - newCustomInternalError(err.Error()) - } else if balance < int64(cost) { - newCustomInternalError("Not enough Entry Credits") - } - - if !factom.ChainExists(e.ChainID) { - return nil, newCustomInvalidParamsError("Chain " + e.ChainID + " was not found") - } - } - - commit, err := factom.ComposeEntryCommit(&e, ec) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - reveal, err := factom.ComposeEntryReveal(&e) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - resp := new(entryResponse) - resp.Commit = commit - resp.Reveal = reveal - return resp, nil -} - -func handleProperties(params []byte) (interface{}, *factom.JSONError) { - props := new(propertiesResponse) - props.WalletVersion = fctWallet.GetVersion() - props.WalletApiVersion = fctWallet.GetApiVersion() - return props, nil -} - -func handleGetHeight(params []byte) (interface{}, *factom.JSONError) { - resp := new(heightResponse) - - block, err := fctWallet.TXDB().DBO.FetchFBlockHead() - - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if block == nil { - resp.Height = 0 - return resp, nil - } - - resp.Height = int64(block.GetDBHeight()) - return resp, nil -} - -// Identity handlers - -func handleIdentityKey(params []byte) (interface{}, *factom.JSONError) { - req := new(identityKeyRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - e, err := fctWallet.GetIdentityKey(req.Public) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if e == nil { - return nil, newCustomInternalError("Wallet: identity key not found") - } - resp := new(identityKeyResponse) - resp.Public = e.PubString() - resp.Secret = e.SecString() - return resp, nil -} - -func handleAllIdentityKeys(params []byte) (interface{}, *factom.JSONError) { - resp := new(multiIdentityKeyResponse) - - keys, err := fctWallet.GetAllIdentityKeys() - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - for _, v := range keys { - key := new(identityKeyResponse) - key.Public = v.PubString() - key.Secret = v.SecString() - resp.Keys = append(resp.Keys, key) - } - - return resp, nil -} - -func handleImportIdentityKeys(params []byte) (interface{}, *factom.JSONError) { - req := new(importIdentityKeysRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - resp := new(multiIdentityKeyResponse) - for _, v := range req.Keys { - key, err := factom.GetIdentityKey(v.Secret) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if err := fctWallet.InsertIdentityKey(key); err != nil { - return nil, newCustomInternalError(err.Error()) - } - keyResp := new(identityKeyResponse) - keyResp.Public = key.PubString() - keyResp.Secret = v.Secret - resp.Keys = append(resp.Keys, keyResp) - } - return resp, nil -} - -func handleGenerateIdentityKey(params []byte) (interface{}, *factom.JSONError) { - k, err := fctWallet.GenerateIdentityKey() - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - resp := identityKeyResponse{} - resp.Public = k.PubString() - resp.Secret = k.SecString() - return resp, nil -} - -func handleRemoveIdentityKey(params []byte) (interface{}, *factom.JSONError) { - req := new(identityKeyRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - err := fctWallet.WalletDatabaseOverlay.RemoveIdentityKey(req.Public) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - resp := new(simpleResponse) - resp.Success = true - - return resp, nil -} - -func handleActiveIdentityKeys(params []byte) (interface{}, *factom.JSONError) { - req := new(activeIdentityKeysRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - resp := new(activeIdentityKeysResponse) - resp.ChainID = req.ChainID - - if req.Height == nil { - keys, currentHeight, err := factom.GetActiveIdentityKeys(req.ChainID) - if err != nil { - return nil, newCustomInternalError(fmt.Sprintf("ActiveIdentityKeys: %s", err.Error())) - } - resp.Keys = keys - resp.Height = currentHeight - return resp, nil - } - - keys, err := factom.GetActiveIdentityKeysAtHeight(req.ChainID, *req.Height) - if err != nil { - return nil, newCustomInternalError(fmt.Sprintf("ActiveIdentityKeys: %s", err.Error())) - } - resp.Keys = keys - resp.Height = *req.Height - return resp, nil -} - -func handleComposeIdentityChain(params []byte) (interface{}, *factom.JSONError) { - req := new(identityChainRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - ecpub := req.ECPub - ec, err := fctWallet.GetECAddress(ecpub) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if ec == nil { - return nil, newCustomInternalError("Wallet: entry credit address not found") - } - - c, err := factom.NewIdentityChain(req.Name, req.PubKeys) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if !req.Force { - // check ec address balance - balance, err := factom.GetECBalance(ecpub) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - if cost, err := factom.EntryCost(c.FirstEntry); err != nil { - return nil, newCustomInternalError(err.Error()) - } else if balance < int64(cost)+10 { - return nil, newCustomInternalError("Not enough Entry Credits") - } - - if factom.ChainExists(c.ChainID) { - return nil, newCustomInvalidParamsError("Chain " + c.ChainID + " already exists") - } - } - - commit, err := factom.ComposeChainCommit(c, ec) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - reveal, err := factom.ComposeChainReveal(c) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - resp := new(entryResponse) - resp.Commit = commit - resp.Reveal = reveal - return resp, nil -} - -func handleComposeIdentityKeyReplacement(params []byte) (interface{}, *factom.JSONError) { - req := new(identityKeyReplacementRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - signerKey, err := fctWallet.GetIdentityKey(req.SignerKey) - if err != nil || signerKey == nil { - return nil, newCustomInternalError("Wallet: failed to fetch signerkey from given identity public key") - } - - ecpub := req.ECPub - ec, err := fctWallet.GetECAddress(ecpub) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if ec == nil { - return nil, newCustomInternalError("Wallet: entry credit address not found") - } - - e, err := factom.NewIdentityKeyReplacementEntry(req.ChainID, req.OldKey, req.NewKey, signerKey) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if !req.Force { - // check ec address balance - balance, err := factom.GetECBalance(ecpub) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - if cost, err := factom.EntryCost(e); err != nil { - newCustomInternalError(err.Error()) - } else if balance < int64(cost) { - newCustomInternalError("Not enough Entry Credits") - } - - if !factom.ChainExists(e.ChainID) { - return nil, newCustomInvalidParamsError("Chain " + e.ChainID + " was not found") - } - } - - commit, err := factom.ComposeEntryCommit(e, ec) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - reveal, err := factom.ComposeEntryReveal(e) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - resp := new(entryResponse) - resp.Commit = commit - resp.Reveal = reveal - return resp, nil -} - -func handleComposeIdentityAttribute(params []byte) (interface{}, *factom.JSONError) { - req := new(identityAttributeRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - signerKey, err := fctWallet.GetIdentityKey(req.SignerKey) - if err != nil || signerKey == nil { - return nil, newCustomInternalError("Wallet: failed to fetch signerkey from given identity public key") - } - - for _, attribute := range req.Attributes { - if attribute.Key == nil { - return nil, newCustomInternalError("Attribute key must not be nil") - } - if attribute.Value == nil { - return nil, newCustomInternalError("Attribute value must not be nil") - } - } - attributesJSON, err := json.Marshal(req.Attributes) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - e := factom.NewIdentityAttributeEntry(req.ReceiverChainID, req.DestinationChainID, string(attributesJSON), signerKey, req.SignerChainID) - ecpub := req.ECPub - force := req.Force - - ec, err := fctWallet.GetECAddress(ecpub) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if ec == nil { - return nil, newCustomInternalError("Wallet: address not found") - } - if !force { - // check ec address balance - balance, err := factom.GetECBalance(ecpub) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - if cost, err := factom.EntryCost(e); err != nil { - newCustomInternalError(err.Error()) - } else if balance < int64(cost) { - newCustomInternalError("Not enough Entry Credits") - } - - if !factom.ChainExists(e.ChainID) { - return nil, newCustomInvalidParamsError("Chain " + e.ChainID + " was not found") - } - } - - commit, err := factom.ComposeEntryCommit(e, ec) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - reveal, err := factom.ComposeEntryReveal(e) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - resp := new(entryResponse) - resp.Commit = commit - resp.Reveal = reveal - return resp, nil -} - -func handleComposeIdentityAttributeEndorsement(params []byte) (interface{}, *factom.JSONError) { - req := new(identityAttributeEndorsementRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - signerKey, err := fctWallet.GetIdentityKey(req.SignerKey) - if err != nil || signerKey == nil { - return nil, newCustomInternalError("Wallet: failed to fetch signerkey from given identity public key") - } - - e := factom.NewIdentityAttributeEndorsementEntry(req.DestinationChainID, req.EntryHash, signerKey, req.SignerChainID) - ecpub := req.ECPub - force := req.Force - - ec, err := fctWallet.GetECAddress(ecpub) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - if ec == nil { - return nil, newCustomInternalError("Wallet: address not found") - } - if !force { - // check ec address balance - balance, err := factom.GetECBalance(ecpub) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - if cost, err := factom.EntryCost(e); err != nil { - newCustomInternalError(err.Error()) - } else if balance < int64(cost) { - newCustomInternalError("Not enough Entry Credits") - } - - if !factom.ChainExists(e.ChainID) { - return nil, newCustomInvalidParamsError("Chain " + e.ChainID + " was not found") - } - } - - commit, err := factom.ComposeEntryCommit(e, ec) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - reveal, err := factom.ComposeEntryReveal(e) - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - - resp := new(entryResponse) - resp.Commit = commit - resp.Reveal = reveal - return resp, nil -} - -func handleWalletPassphrase(params []byte) (interface{}, *factom.JSONError) { - req := new(passphraseRequest) - if err := json.Unmarshal(params, req); err != nil { - return nil, newInvalidParamsError() - } - - // If timeout is > 2^30, set to 2^30 - if req.Timeout > 1073741824 { - req.Timeout = 1073741824 - } - - // If this isn't the first time booting an encrypted wallet, we postpone creating the database until now - if fctWallet.WalletDatabaseOverlay == nil { - db, err := wallet.NewEncryptedBoltDB(fctWallet.DBPath, req.Password) - if err != nil { - return nil, newIncorrectPassphraseError() - } - fctWallet.WalletDatabaseOverlay = db - - err = fctWallet.InitWallet() - if err != nil { - return nil, newCustomInternalError(err.Error()) - } - fctWallet.DBO.DB.(*securedb.EncryptedDB).Lock() - } - - encdb, ok := fctWallet.DBO.DB.(*securedb.EncryptedDB) - if !ok { - return nil, newCustomInternalError("Cannot unlock non-encrypted wallet. This database is always unlocked") - } - - err := encdb.UnlockFor(req.Password, time.Second*time.Duration(req.Timeout)) - if err != nil { - return nil, newIncorrectPassphraseError() - } - - return &unlockResponse{Success: true, UnlockedUntil: encdb.UnlockedUntil.Unix()}, nil -} - -// utility functions - -type addressResponder interface { - String() string - SecString() string -} - -func mkAddressResponse(a addressResponder) *addressResponse { - r := new(addressResponse) - r.Public = a.String() - r.Secret = a.SecString() - return r -} - -func factoidTxToTransaction(t interfaces.ITransaction) ( - *factom.Transaction, - error, -) { - r := new(factom.Transaction) - r.TxID = hex.EncodeToString(t.GetSigHash().Bytes()) - - r.BlockHeight = t.GetBlockHeight() - r.Timestamp = t.GetTimestamp().GetTime() - - if len(t.GetSignatureBlocks()) > 0 { - if err := t.ValidateSignatures(); err == nil { - r.IsSigned = true - } - } - - if i, err := t.TotalInputs(); err != nil { - return nil, err - } else { - r.TotalInputs = i - } - - if i, err := t.TotalOutputs(); err != nil { - return nil, err - } else { - r.TotalOutputs = i - } - - if i, err := t.TotalECs(); err != nil { - return nil, err - } else { - r.TotalECOutputs = i - } - - for _, v := range t.GetInputs() { - tmp := new(factom.TransAddress) - tmp.Address = primitives.ConvertFctAddressToUserStr(v.GetAddress()) - tmp.Amount = v.GetAmount() - r.Inputs = append(r.Inputs, tmp) - } - - for _, v := range t.GetOutputs() { - tmp := new(factom.TransAddress) - tmp.Address = primitives.ConvertFctAddressToUserStr(v.GetAddress()) - tmp.Amount = v.GetAmount() - r.Outputs = append(r.Outputs, tmp) - } - - for _, v := range t.GetECOutputs() { - tmp := new(factom.TransAddress) - tmp.Address = primitives.ConvertECAddressToUserStr(v.GetAddress()) - tmp.Amount = v.GetAmount() - r.ECOutputs = append(r.ECOutputs, tmp) - } - - if r.TotalInputs <= r.TotalOutputs+r.TotalECOutputs { - r.FeesPaid = 0 - r.FeesRequired = r.FeesRequired - } else { - r.FeesPaid = r.TotalInputs - (r.TotalOutputs + r.TotalECOutputs) - } - - return r, nil -} - -func feesRequired(t interfaces.ITransaction) uint64 { - rate, err := factom.GetECRate() - if err != nil { - rate = 0 - } - - fee, err := t.CalculateFee(rate) - if err != nil { - return 0 - } - - return fee -} diff --git a/wallet/wsapi/wsapi_test.gox b/wallet/wsapi/wsapi_test.gox deleted file mode 100644 index 2b8e7ed..0000000 --- a/wallet/wsapi/wsapi_test.gox +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright 2016 Factom Foundation -// Use of this source code is governed by the MIT -// license that can be found in the LICENSE file. - -// run ``factom-walletd -w /tmp/test_wallet-01 -p 8889`` and ``factomd`` to test the wsapi calls. - -package wsapi_test - -import ( - "bytes" - "io/ioutil" - "net/http" - "testing" -) - -var testnet = "localhost:8889" - -func TesthhandleWalletBalances(t *testing.T) { - // Replace the accounts will accounts in your wallet - req := `{"jsonrpc": "2.0", "id": 0, "method": "wallet-balances"}` - - resp, err := apiCall(req) - if err != nil { - t.Error(err) - } - t.Log(resp) -} - -func TestAllAddresses(t *testing.T) { - req := `{"jsonrpc":"2.0","id":0,"method":"all-addresses"}` - - resp, err := apiCall(req) - if err != nil { - t.Error(err) - } - t.Log(resp) -} - -func TestGenerateECAddress(t *testing.T) { - req := `{"jsonrpc":"2.0","id":0,"method":"generate-ec-address"}` - - resp, err := apiCall(req) - if err != nil { - t.Error(err) - } - t.Log(resp) -} - -func TestGenerateFCTAddress(t *testing.T) { - req := `{"jsonrpc":"2.0","id":0,"method":"generate-factoid-address"}` - - resp, err := apiCall(req) - if err != nil { - t.Error(err) - } - t.Log(resp) -} - -func TestImportAddresses(t *testing.T) { - req := `{"jsonrpc":"2.0","id":0,"method":"import-addresses","params":{"addresses":[{"secret":"Fs3E9gV6DXsYzf7Fqx1fVBQPQXV695eP3k5XbmHEZVRLkMdD9qCK"}]}}` - - resp, err := apiCall(req) - if err != nil { - t.Error(err) - } - t.Log(resp) -} - -func TestAddress(t *testing.T) { - req := `{"jsonrpc":"2.0","id":0,"method":"address","params":{"address":"FA2jK2HcLnRdS94dEcU27rF3meoJfpUcZPSinpb7AwQvPRY6RL1Q"}}` - - resp, err := apiCall(req) - if err != nil { - t.Error(err) - } - t.Log(resp) -} - -func TestTransaction(t *testing.T) { - new := `{"jsonrpc":"2.0","id":0,"method":"new-transaction","params":{"tx-name":"a"}}` - - if resp, err := apiCall(new); err != nil { - t.Error(err) - } else { - t.Log(resp) - } - - addin := `{"jsonrpc":"2.0","id":0,"method":"add-input","params":{"tx-name":"a","address":"FA2jK2HcLnRdS94dEcU27rF3meoJfpUcZPSinpb7AwQvPRY6RL1Q","amount":1000000000}}` - if resp, err := apiCall(addin); err != nil { - t.Error(err) - } else { - t.Log(resp) - } - - addout := `{"jsonrpc":"2.0","id":0,"method":"add-output","params":{"tx-name":"a","address":"FA2xWmGckzbACp7LR43bfnViCyN4uNhugBxiaYPtWGVZVSn1y2m6","amount":1000000000}}` - if resp, err := apiCall(addout); err != nil { - t.Error(err) - } else { - t.Log(resp) - } - - addfee := `{"jsonrpc":"2.0","id":0,"method":"add-fee","params":{"tx-name":"a","address":"FA2jK2HcLnRdS94dEcU27rF3meoJfpUcZPSinpb7AwQvPRY6RL1Q"}}` - if resp, err := apiCall(addfee); err != nil { - t.Error(err) - } else { - t.Log(resp) - } - - sign := `{"jsonrpc":"2.0","id":0,"method":"sign-transaction","params":{"tx-name":"a"}}` - if resp, err := apiCall(sign); err != nil { - t.Error(err) - } else { - t.Log(resp) - } - - compose := `{"jsonrpc":"2.0","id":0,"method":"compose-transaction","params":{"tx-name":"a"}}` - if resp, err := apiCall(compose); err != nil { - t.Error(err) - } else { - t.Log(resp) - } -} - -func apiCall(req string) (string, error) { - client := &http.Client{} - buf := bytes.NewBuffer([]byte(req)) - re, err := http.NewRequest("POST", "http://"+testnet+"/v2", buf) - if err != nil { - return "", err - } - re.SetBasicAuth(RpcUser, RpcPass) - resp, err := client.Do(re) - if err != nil { - return "", err - } - defer resp.Body.Close() - - p, err := ioutil.ReadAll(resp.Body) - if err != nil { - return "", err - } - - return string(p), nil -} diff --git a/wallet_test.go b/wallet_test.go index 34d7c77..4d36f44 100644 --- a/wallet_test.go +++ b/wallet_test.go @@ -10,66 +10,12 @@ import ( "fmt" "io/ioutil" "net/http" - "os" . "github.com/FactomProject/factom" - "github.com/FactomProject/factom/wallet" - "github.com/FactomProject/factom/wallet/wsapi" "testing" ) -func TestImportAddress(t *testing.T) { - var ( - fs1 = "Fs2TCa7Mo4XGy9FQSoZS8JPnDfv7SjwUSGqrjMWvc1RJ9sKbJeXA" - fa1 = "FA3T1gTkuKGG2MWpAkskSoTnfjxZDKVaAYwziNTC1pAYH5B9A1rh" - es1 = "Es4KmwK65t9HCsibYzVDFrijvkgTFZKdEaEAgfMtYTPSVtM3NDSx" - ec1 = "EC2CyGKaNddLFxrjkFgiaRZnk77b8iQia3Zj6h5fxFReAcDwCo3i" - - bads = []string{ - "Fs2TCa7Mo4XGy9FQSoZS8JPnDfv7SjwUSGqrjMWvc1RJ9sKbJeX", //short - "Fs2TCa7Mo4XGy9FQSoZS8JPnDfv7SjwUSGqrjMWvc1RJ9sKbJeeA", //check - "", //empty - "Fc2TCa7Mo4XGy9FQSoZS8JPnDfv7SjwUSGqrjMWvc1RJ9sKbJeXA", //prefix - } - ) - - // start the test wallet - done, err := StartTestWallet() - if err != nil { - t.Error(err) - } - defer func() { done <- 1 }() - - // import the good addresses - if _, _, err := ImportAddresses(fs1, es1); err != nil { - t.Error(err) - } - - if f, err := FetchFactoidAddress(fa1); err != nil { - t.Error(err) - } else if f == nil { - t.Error("Wallet returned nil factoid address") - } else if f.SecString() != fs1 { - t.Error("Wallet returned incorrect address", fs1, f.SecString()) - } - - if e, err := FetchECAddress(ec1); err != nil { - t.Error(err) - } else if e == nil { - t.Error("Wallet returned nil ec address") - } else if e.SecString() != es1 { - t.Error("Wallet returned incorrect address", es1, e.SecString()) - } - - // try to import the bad addresses - for _, bad := range bads { - if _, _, err := ImportAddresses(bad); err == nil { - t.Error("Bad address was imported without error", bad) - } - } -} - // // TODO: revisit this test and try to fix the problem // @@ -149,44 +95,6 @@ func helper(t *testing.T, addr []string) (*walletcall, string) { return respEC, "" } -func TestImportKoinify(t *testing.T) { - var ( - good_mnemonic = "yellow yellow yellow yellow yellow yellow yellow" + - " yellow yellow yellow yellow yellow" // good - koinifyexpect = "FA3cih2o2tjEUsnnFR4jX1tQXPpSXFwsp3rhVp6odL5PNCHWvZV1" - - bad_mnemonic = []string{ - "", // bad empty - "yellow yellow yellow yellow yellow yellow yellow yellow yellow" + - " yellow yellow", // bad short - "yellow yellow yellow yellow yellow yellow yellow yellow yellow" + - " yellow yellow asdfasdf", // bad word - } - ) - - // start the test wallet - done, err := StartTestWallet() - if err != nil { - t.Error(err) - } - defer func() { done <- 1 }() - - // check the import for koinify names - fa, err := ImportKoinify(good_mnemonic) - if err != nil { - t.Error(err) - } - if fa.String() != koinifyexpect { - t.Error("Incorrect address from Koinify mnemonic", fa, koinifyexpect) - } - - for _, m := range bad_mnemonic { - if _, err := ImportKoinify(m); err == nil { - t.Error("No error for bad address:", m) - } - } -} - // helper functions for testing func populateTestWallet() error { @@ -214,50 +122,3 @@ func populateTestWallet() error { return nil } - -// StartTestWallet runs a test wallet and serves the wallet api. The caller -// must write an int to the chan when compleate to stop the wallet api and -// remove the test db. -func StartTestWallet() (chan int, error) { - var ( - walletdbfile = os.TempDir() + "/testingwallet.bolt" - txdbfile = os.TempDir() + "/testingtxdb.bolt" - ) - - // make a chan to signal when the test is finished with the wallet - done := make(chan int, 1) - - // setup a testing wallet - fctWallet, err := wallet.NewOrOpenBoltDBWallet(walletdbfile) - if err != nil { - return nil, err - } - defer os.Remove(walletdbfile) - - txdb, err := wallet.NewTXBoltDB(txdbfile) - if err != nil { - return nil, err - } else { - fctWallet.AddTXDB(txdb) - } - defer os.Remove(txdbfile) - - RpcConfig = &RPCConfig{ - WalletTLSEnable: false, - WalletTLSKeyFile: "", - WalletTLSCertFile: "", - WalletRPCUser: "", - WalletRPCPassword: "", - WalletServer: "localhost:8089", - } - - go wsapi.Start(fctWallet, ":8089", *RpcConfig) - go func() { - <-done - wsapi.Stop() - fctWallet.Close() - txdb.Close() - }() - - return done, nil -}