Compare commits

...
39 Commits
Author SHA1 Message Date
Chris Troutner bdb4de0353 Merge pull request #80 from Permissionless-Software-Foundation/ct-unstable
Converting dependencies targeting GitHub repos to npm libraries.
2021-01-01 17:15:43 -08:00
Chris Troutner 1de0bdcf14 Updating bitcoincashjs-lib 2021-01-01 17:12:35 -08:00
Chris Troutner 3a9e4f64b5 Updating bitcoincashjs-lib 2021-01-01 16:50:02 -08:00
Chris Troutner ea57f52b20 fixing dependency in test 2021-01-01 16:39:03 -08:00
Chris Troutner 903aae1091 Fixing references to npm libs 2021-01-01 16:36:12 -08:00
Chris Troutner 1af766cbda fix(coininfo): Switching to forked npm library 2021-01-01 16:29:50 -08:00
Chris Troutner 60ee10ef4d fix(bip21): Switching to npm lib 2021-01-01 16:14:55 -08:00
Chris Troutner 2d4bc6127e fix(bitcoincashjs-lib): Using npm package rather than github repo 2021-01-01 14:30:57 -08:00
Chris Troutner a2c2d41833 fix(bitcoincash-ops): Switching to PSF fork of library 2021-01-01 12:51:54 -08:00
Chris Troutner 0e7db7bf39 fix(bip32-utils): Replacing bip32-utils with PSF maintained fork 2021-01-01 12:39:19 -08:00
Chris Troutner 46de4f6a25 feat(BITBOX Shim): Removing Shim support for BITBOX 2021-01-01 11:56:09 -08:00
Chris Troutner 2acf47a550 feat(wallet): Removing wallet library 2021-01-01 11:45:34 -08:00
Chris Troutner 7fea5c2630 Merge pull request #79 from Permissionless-Software-Foundation/ct-test-joey-slp
Testing Joey's Updates to SLP Handling
2020-12-30 08:52:52 -08:00
Chris Troutner b297743521 feat(SLP): Improved SLP calculation to fix small burns 2020-12-30 08:24:18 -08:00
Chris Troutner 6c33222172 Merge pull request #60 from josephroyking/slp-utils-patch
Resolving correct decimal precision for slp token qty
2020-12-28 05:01:59 -08:00
Chris Troutner 9a36a8261a Merge pull request #54 from josephroyking/generateSendOpReturn-rounding-patch
Generate send op return rounding patch
2020-12-28 04:57:53 -08:00
Chris Troutner 1433c77fcc Merge pull request #78 from Permissionless-Software-Foundation/ct-unstable
feat(Blockbook): Removing support for Blockbook indexer
2020-12-24 10:18:55 -08:00
Chris Troutner b1c3311d50 feat(Blockbook): Removing support for Blockbook indexer 2020-12-24 10:16:41 -08:00
Chris Troutner b3e224e481 Cleaned up integration tests 2020-12-24 10:06:39 -08:00
Chris Troutner 06e2dad45c Ran npm audit fix 2020-12-24 09:26:36 -08:00
Chris Troutner d475f2220f feat(SLPDB status): Created bchjs.SLP.Utils.getStatus() to get health status of SLPDB 2020-12-24 09:25:35 -08:00
Chris Troutner 10520a2e08 Merge pull request #75 from Permissionless-Software-Foundation/ct-unstable
fix(tokenUtxoDetails): Renabling local caching of tx validation
2020-12-13 09:16:17 -08:00
Chris Troutner 05b654d54a fix(tokenUtxoDetails): Renabling local caching of tx validation 2020-12-13 09:14:06 -08:00
Chris Troutner 3c4051c3a5 Merge pull request #74 from Permissionless-Software-Foundation/ct-unstable
fix(tokenUtxoDetails): Updating to handle alternative output from SLPDB
2020-12-13 09:00:48 -08:00
Chris Troutner 0f3cc1e9e8 Merge branch 'master' into ct-unstable 2020-12-13 08:56:28 -08:00
Chris Troutner b9873f7ed8 Added additional corner case unit test for tokenUtxoDetails() 2020-12-13 08:56:09 -08:00
Chris Troutner 82cd9270fa fix(tokenUtxoDetails): Updating to handle alternative output from SLPDB 2020-12-13 08:51:58 -08:00
Chris Troutner ac6b45b162 Merge pull request #73 from Permissionless-Software-Foundation/ct-unstable
fix(debugging): Additional debugging
2020-12-13 07:26:07 -08:00
Chris Troutner 66a99c0560 Merge branch 'master' into ct-unstable 2020-12-13 07:20:08 -08:00
Chris Troutner 17e4a32ff4 fix(debugging): Additional debugging 2020-12-13 07:19:24 -08:00
Joey King ad5fabf2e6 Remove stub test 2020-12-03 06:57:44 -08:00
Joey King f8f6db069b Implementing BigNumber for all tokenQty calcs 2020-12-03 06:56:05 -08:00
Joey King df620e0302 stub test method 2020-12-02 16:06:10 -08:00
Joey King 19f2e87528 Resolving correct decimal precision for slp token qty 2020-12-02 16:02:07 -08:00
Joey King b512b222dd Adding large test tx 2020-11-10 14:28:10 -08:00
Joey King 650e3b53fc Adding tests and checks 2020-11-10 13:38:41 -08:00
Joey King 905658ca28 format changes take two 2020-11-10 06:19:36 -08:00
Joey King b0c91c407d matching original formatting 2020-11-10 06:13:53 -08:00
Joey King d2c68efc0c Use BigNumber to eliminate rounding error token burns 2020-11-10 06:10:38 -08:00
23 changed files with 1669 additions and 1117 deletions
+117 -161
View File
@@ -116,28 +116,28 @@
}
},
"@nodelib/fs.scandir": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
"integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
"integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==",
"dev": true,
"requires": {
"@nodelib/fs.stat": "2.0.3",
"@nodelib/fs.stat": "2.0.4",
"run-parallel": "^1.1.9"
}
},
"@nodelib/fs.stat": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
"integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz",
"integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==",
"dev": true
},
"@nodelib/fs.walk": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
"integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz",
"integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==",
"dev": true,
"requires": {
"@nodelib/fs.scandir": "2.1.3",
"@nodelib/fs.scandir": "2.1.4",
"fastq": "^1.6.0"
}
},
@@ -187,9 +187,9 @@
}
},
"@octokit/openapi-types": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-2.0.0.tgz",
"integrity": "sha512-J4bfM7lf8oZvEAdpS71oTvC1ofKxfEZgU5vKVwzZKi4QPiL82udjpseJwxPid9Pu2FNmyRQOX4iEj6W1iOSnPw==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-2.0.1.tgz",
"integrity": "sha512-9AuC04PUnZrjoLiw3uPtwGh9FE4Q3rTqs51oNlQ0rkwgE8ftYsOC+lsrQyvCvWm85smBbSc0FNRKKumvGyb44Q==",
"dev": true
},
"@octokit/plugin-paginate-rest": {
@@ -257,15 +257,77 @@
}
},
"@octokit/types": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.1.1.tgz",
"integrity": "sha512-btm3D6S7VkRrgyYF31etUtVY/eQ1KzrNRqhFt25KSe2mKlXuLXJilglRC6eDA2P6ou94BUnk/Kz5MPEolXgoiw==",
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.1.2.tgz",
"integrity": "sha512-LPCpcLbcky7fWfHCTuc7tMiSHFpFlrThJqVdaHgowBTMS0ijlZFfonQC/C1PrZOjD4xRCYgBqH9yttEATGE/nw==",
"dev": true,
"requires": {
"@octokit/openapi-types": "^2.0.0",
"@octokit/openapi-types": "^2.0.1",
"@types/node": ">= 8"
}
},
"@psf/bip21": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@psf/bip21/-/bip21-2.0.1.tgz",
"integrity": "sha512-U9c8xBV31n+D7qxOPBO0vQ015DNvKskWCUbVgoMfH5AUNHLYrSDWIrCx4P7v9etfdu6LpPdsYr53KDSAIk0b7Q==",
"requires": {
"qs": "^6.3.0"
}
},
"@psf/bip32-utils": {
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/@psf/bip32-utils/-/bip32-utils-0.13.1.tgz",
"integrity": "sha512-5yM2o4TXW3gWKI3zxUFj9eeYqMYbA4Q1w+ptcfb+XnGpSZLrmwGtX48q8rApIKtikRceMEFXp1Jq6ed+bS+1nA==",
"requires": {
"keccak": "^1.3.0",
"nyc": "*",
"standard": "^11.0.1",
"tape": "*"
}
},
"@psf/bitcoincash-ops": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@psf/bitcoincash-ops/-/bitcoincash-ops-2.0.0.tgz",
"integrity": "sha512-M3PWqRpeJq6rli2NqWGbas76z9TrdGOmNuDFACBWBMctPucEAsFQY2AmyFHRSa7hEwythwvrPh9AG/n6ehmEog=="
},
"@psf/bitcoincashjs-lib": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@psf/bitcoincashjs-lib/-/bitcoincashjs-lib-4.0.2.tgz",
"integrity": "sha512-fTy9mW4H0NkQ+dojGtf+nPduA27F3V2YpBi5licYUVjdVRD/xpUCTgEN1cYRAupOaeDH/AYOWT0MWLkbQSTxAQ==",
"requires": {
"@psf/bitcoincash-ops": "^2.0.0",
"@psf/pushdata-bitcoin": "^1.2.2",
"bech32": "^1.1.2",
"bigi": "^1.4.0",
"bip66": "^1.1.0",
"bs58check": "^2.0.0",
"create-hash": "^1.1.0",
"create-hmac": "^1.1.3",
"ecurve": "^1.0.0",
"merkle-lib": "^2.0.10",
"randombytes": "^2.0.1",
"safe-buffer": "^5.0.1",
"typeforce": "^1.18.0",
"varuint-bitcoin": "^1.0.4",
"wif": "^2.0.1"
}
},
"@psf/coininfo": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@psf/coininfo/-/coininfo-4.0.0.tgz",
"integrity": "sha512-RwBc09790kbaOt8uZJMyvLqf1UziTd20FXu78bM8bMlkClnZQTJyNDdLCsFSBkJQYAJtGMkjdQ/o3/UaSC7c2Q==",
"requires": {
"safe-buffer": "^5.1.1"
}
},
"@psf/pushdata-bitcoin": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@psf/pushdata-bitcoin/-/pushdata-bitcoin-1.2.2.tgz",
"integrity": "sha512-e1qkZLJFU6Ldg7TMBgSkiR5U1NfpRgSIr2ppk8BeED/Q9wUc9DEVAjXfPMD65xgXdqnlyFEtLbpPMWwyydMVUQ==",
"requires": {
"@psf/bitcoincash-ops": "^2.0.0"
}
},
"@semantic-release/commit-analyzer": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-8.0.1.tgz",
@@ -362,9 +424,9 @@
}
},
"mime": {
"version": "2.4.6",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
"integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==",
"version": "2.4.7",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.7.tgz",
"integrity": "sha512-dhNd1uA2u397uQk3Nv5LM4lm93WYDUXFn3Fu291FJerns4jyTudqhIWe4W04YLy7Uk1tm1Ore04NpjRvQp/NPA==",
"dev": true
},
"universalify": {
@@ -1154,39 +1216,6 @@
"resolved": "https://registry.npmjs.org/bc-bip68/-/bc-bip68-1.0.5.tgz",
"integrity": "sha512-GzaMlN7pNthrY5BhReVhnfr4Ixx+GUSfyNRHYh0QiMUF0d0+0YaD8MpEdv6AjFBksg/zlqL1fVCBBm6PpTt2Rg=="
},
"bch-wallet-bridge-provider-interface": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/bch-wallet-bridge-provider-interface/-/bch-wallet-bridge-provider-interface-0.1.1.tgz",
"integrity": "sha512-m8Mq/aJhZN11aoa91YyYs/B1GxWfpT5IIp64IU5VRgNxGXBuUiIfvybk4XQR+zrHaMW4SLrD1tI9n59ogmEw/A=="
},
"bch-wallet-bridge.js": {
"version": "github:web3bch/bch-wallet-bridge.js#f73558eaf3a98ba2a23de3c9cbbd582b30ff19eb",
"from": "github:web3bch/bch-wallet-bridge.js#master",
"requires": {
"bch-wallet-bridge-provider-interface": "^0.1.1",
"bchaddrjs": "^0.2.2",
"bitcoincashjs": "^0.1.10"
}
},
"bchaddrjs": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/bchaddrjs/-/bchaddrjs-0.2.3.tgz",
"integrity": "sha512-0DVW8q3UFQFhrvt8Fowpkk+WvkYTZTSD1vGCQHrtMHZjRL6G/SoW0mgrREmgO1F/8TJ+Julri4UBWA8Gr7C5Yw==",
"requires": {
"bs58check": "^2.1.2",
"cashaddrjs": "^0.2.9"
},
"dependencies": {
"cashaddrjs": {
"version": "0.2.9",
"resolved": "https://registry.npmjs.org/cashaddrjs/-/cashaddrjs-0.2.9.tgz",
"integrity": "sha512-DhJF4iAH0/RM3UjHDHKRxzs09YGL9px+oTyizzydanhC7jTyM2aJ+aLKA96vZGTTWayvvr2iDF2l13lpqXiRFg==",
"requires": {
"big-integer": "^1.6.34"
}
}
}
},
"bchaddrjs-slp": {
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/bchaddrjs-slp/-/bchaddrjs-slp-0.2.8.tgz",
@@ -1263,23 +1292,6 @@
"safe-buffer": "^5.0.1"
}
},
"bip21": {
"version": "github:Bitcoin-com/bip21#28f8d03a3a16ed11eb5b963248ed1be8c46c6d6f",
"from": "github:Bitcoin-com/bip21",
"requires": {
"qs": "^6.3.0"
}
},
"bip32-utils": {
"version": "github:Bitcoin-com/bip32-utils#b8a33ebd0a0ac39de7cd987e5c3f77a8c5d84e58",
"from": "github:Bitcoin-com/bip32-utils#0.13.1",
"requires": {
"keccak": "^1.3.0",
"nyc": "*",
"standard": "^11.0.1",
"tape": "*"
}
},
"bip38": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/bip38/-/bip38-2.0.3.tgz",
@@ -1313,42 +1325,6 @@
"safe-buffer": "^5.0.1"
}
},
"bitcoincash-ops": {
"version": "github:christroutner/bitcoincash-ops#0041f2d945aa0e893fbbb5c2ebdf6254f6ff0555",
"from": "github:christroutner/bitcoincash-ops"
},
"bitcoincashjs": {
"version": "0.1.14",
"resolved": "https://registry.npmjs.org/bitcoincashjs/-/bitcoincashjs-0.1.14.tgz",
"integrity": "sha512-x0wMVSCZ56ZQnSQ+Xim7XfS0IYiOyOwo0pdMCmR+cDNB7zRhICFuH5i3lNdLSgUw1e7Pc3FmUlC9wruQNlYMnA=="
},
"bitcoincashjs-lib": {
"version": "github:christroutner/bitcoincashjs-lib#84dbcbce600af727a6f8b3eb23ebf6571651f367",
"from": "github:christroutner/bitcoincashjs-lib#master",
"requires": {
"bech32": "^1.1.2",
"bigi": "^1.4.0",
"bip66": "^1.1.0",
"bitcoincash-ops": "github:christroutner/bitcoincash-ops",
"bs58check": "^2.0.0",
"create-hash": "^1.1.0",
"create-hmac": "^1.1.3",
"ecurve": "^1.0.0",
"merkle-lib": "^2.0.10",
"pushdata-bitcoin": "github:Bitcoin-com/pushdata-bitcoin#1.2.1",
"randombytes": "^2.0.1",
"safe-buffer": "^5.0.1",
"typeforce": "^1.18.0",
"varuint-bitcoin": "^1.0.4",
"wif": "^2.0.1"
},
"dependencies": {
"bitcoincash-ops": {
"version": "github:christroutner/bitcoincash-ops#0041f2d945aa0e893fbbb5c2ebdf6254f6ff0555",
"from": "github:christroutner/bitcoincash-ops"
}
}
},
"bitcoinjs-message": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/bitcoinjs-message/-/bitcoinjs-message-2.1.0.tgz",
@@ -1658,13 +1634,6 @@
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
},
"coininfo": {
"version": "github:Bitcoin-com/coininfo#eece2c6141d08c3e7783929f2a1e1e681aa1a82c",
"from": "github:Bitcoin-com/coininfo",
"requires": {
"safe-buffer": "^5.1.1"
}
},
"color": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz",
@@ -1834,9 +1803,9 @@
}
},
"conventional-changelog-writer": {
"version": "4.0.18",
"resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.18.tgz",
"integrity": "sha512-mAQDCKyB9HsE8Ko5cCM1Jn1AWxXPYV0v8dFPabZRkvsiWUul2YyAqbIaoMKF88Zf2ffnOPSvKhboLf3fnjo5/A==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.1.0.tgz",
"integrity": "sha512-WwKcUp7WyXYGQmkLsX4QmU42AZ1lqlvRW9mqoyiQzdD+rJWbTepdWoKJuwXTS+yq79XKnQNa93/roViPQrAQgw==",
"dev": true,
"requires": {
"compare-func": "^2.0.0",
@@ -3269,9 +3238,9 @@
"integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA=="
},
"fastq": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz",
"integrity": "sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w==",
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.0.tgz",
"integrity": "sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA==",
"dev": true,
"requires": {
"reusify": "^1.0.4"
@@ -3334,12 +3303,12 @@
}
},
"find-versions": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz",
"integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz",
"integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==",
"dev": true,
"requires": {
"semver-regex": "^2.0.0"
"semver-regex": "^3.1.2"
}
},
"flat": {
@@ -3962,9 +3931,9 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
},
"inquirer": {
"version": "3.3.0",
@@ -4637,9 +4606,9 @@
}
},
"marked": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/marked/-/marked-1.2.5.tgz",
"integrity": "sha512-2AlqgYnVPOc9WDyWu7S5DJaEZsfk6dNh/neatQ3IHUW4QLutM/VPSH9lG7bif+XjFWc9K9XR3QvR+fXuECmfdA==",
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/marked/-/marked-1.2.7.tgz",
"integrity": "sha512-No11hFYcXr/zkBvL6qFmAp1z6BKY3zqLMHny/JN/ey+al7qwCM2+CMBL9BOgqMxZU36fz4cCWfn2poWIf7QRXA==",
"dev": true
},
"marked-terminal": {
@@ -4744,9 +4713,9 @@
"dev": true
},
"meow": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/meow/-/meow-8.0.0.tgz",
"integrity": "sha512-nbsTRz2fwniJBFgUkcdISq8y/q9n9VbiHYbfwklFh5V4V2uAcxtKQkDc0yCLPM/kP0d+inZBewn3zJqewHE7kg==",
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/meow/-/meow-8.1.0.tgz",
"integrity": "sha512-fNWkgM1UVMey2kf24yLiccxLihc5W+6zVus3/N0b+VfnJgxV99E9u04X6NAiKdg6ED7DAQBX5sy36NM0QJZkWA==",
"dev": true,
"requires": {
"@types/minimist": "^1.2.0",
@@ -5450,9 +5419,9 @@
"dev": true
},
"npm": {
"version": "6.14.9",
"resolved": "https://registry.npmjs.org/npm/-/npm-6.14.9.tgz",
"integrity": "sha512-yHi1+i9LyAZF1gAmgyYtVk+HdABlLy94PMIDoK1TRKWvmFQAt5z3bodqVwKvzY0s6dLqQPVsRLiwhJfNtiHeCg==",
"version": "6.14.10",
"resolved": "https://registry.npmjs.org/npm/-/npm-6.14.10.tgz",
"integrity": "sha512-FT23Qy/JMA+qxEYReMOr1MY7642fKn8Onn+72LASPi872Owvmw0svm+/DXTHOC3yO9CheEO+EslyXEpdBdRtIA==",
"dev": true,
"requires": {
"JSONStream": "^1.3.5",
@@ -5538,7 +5507,7 @@
"npm-user-validate": "^1.0.1",
"npmlog": "~4.1.2",
"once": "~1.4.0",
"opener": "^1.5.1",
"opener": "^1.5.2",
"osenv": "^0.1.5",
"pacote": "^9.5.12",
"path-is-inside": "~1.0.2",
@@ -7718,7 +7687,7 @@
}
},
"opener": {
"version": "1.5.1",
"version": "1.5.2",
"bundled": true,
"dev": true
},
@@ -10021,19 +9990,6 @@
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
},
"pushdata-bitcoin": {
"version": "github:Bitcoin-com/pushdata-bitcoin#9b75eebe597853c6eeaec3e6c44b6d9c9cd7ee86",
"from": "github:Bitcoin-com/pushdata-bitcoin#1.2.1",
"requires": {
"bitcoincash-ops": "github:Bitcoin-com/bitcoincash-ops#2.0.0"
},
"dependencies": {
"bitcoincash-ops": {
"version": "github:Bitcoin-com/bitcoincash-ops#6ab82cc7326c67236f3b2d9d0457258ac2ef48e3",
"from": "github:Bitcoin-com/bitcoincash-ops#2.0.0"
}
}
},
"q": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
@@ -10554,9 +10510,9 @@
}
},
"semantic-release": {
"version": "17.3.0",
"resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-17.3.0.tgz",
"integrity": "sha512-enhDayMZRP4nWcWAMBFHHB7THRaIcRdUAZv3lxd65pXs2ttzay7IeCvRRrGayRWExtnY0ulwRz5Ycp88Dv/UeQ==",
"version": "17.3.1",
"resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-17.3.1.tgz",
"integrity": "sha512-NSdxvnBTklrRBYRexVUx44Hri9sTu9b8x+1HfWDGIWemDTFQfWOTbT1N3oy5l8WcZHodhRvtyI7gm50SfAa3Fg==",
"dev": true,
"requires": {
"@semantic-release/commit-analyzer": "^8.0.0",
@@ -10570,7 +10526,7 @@
"env-ci": "^5.0.0",
"execa": "^4.0.0",
"figures": "^3.0.0",
"find-versions": "^3.0.0",
"find-versions": "^4.0.0",
"get-stream": "^5.0.0",
"git-log-parser": "^1.2.0",
"hook-std": "^2.0.0",
@@ -10714,9 +10670,9 @@
}
},
"semver-regex": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz",
"integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==",
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.2.tgz",
"integrity": "sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA==",
"dev": true
},
"set-blocking": {
@@ -11664,9 +11620,9 @@
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
},
"uglify-js": {
"version": "3.12.1",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.1.tgz",
"integrity": "sha512-o8lHP20KjIiQe5b/67Rh68xEGRrc2SRsCuuoYclXXoC74AfSRGblU1HKzJWH3HxPZ+Ort85fWHpSX7KwBUC9CQ==",
"version": "3.12.4",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.4.tgz",
"integrity": "sha512-L5i5jg/SHkEqzN18gQMTWsZk3KelRsfD1wUVNqtq0kzqWQqcJjyL8yc1o8hJgRrWqrAl2mUFbhfznEIoi7zi2A==",
"dev": true,
"optional": true
},
+9 -9
View File
@@ -16,7 +16,8 @@
"test:integration:local": "RESTURL=http://localhost:3000/v4/ mocha --timeout 30000 test/integration",
"test:integration:local:bchn": "RESTURL=http://localhost:3000/v4/ bash test/integration/test-bchn-integration.sh",
"test:integration:local:testnet": "RESTURL=http://localhost:4000/v4/ mocha --timeout 30000 test/integration/testnet",
"test:temp": "export RESTURL=http://localhost:3000/v4/ && mocha --timeout 30000 -g '#hydrateUtxos' test/integration/",
"test:temp": "export RESTURL=https://bchn.fullstack.cash/v4/ && mocha --timeout 30000 -g '#getStatus' test/integration/",
"test:temp2": "mocha --timeout 30000 -g '#getStatus' test/unit/",
"coverage": "nyc report --reporter=text-lcov | coveralls",
"coverage:report": "nyc --reporter=html mocha --timeout 25000 test/unit/",
"docs": "./node_modules/.bin/apidoc -i src/ -o docs"
@@ -34,31 +35,30 @@
"assert": "^2.0.0",
"axios": "^0.19.0",
"bc-bip68": "^1.0.5",
"bch-wallet-bridge.js": "github:web3bch/bch-wallet-bridge.js#master",
"bchaddrjs-slp": "^0.2.5",
"bigi": "^1.4.2",
"bignumber.js": "^9.0.0",
"bip-schnorr": "^0.3.0",
"bip21": "Bitcoin-com/bip21",
"bip32-utils": "Bitcoin-com/bip32-utils#0.13.1",
"@psf/bip21": "^2.0.1",
"@psf/bip32-utils": "^0.13.1",
"bip38": "^2.0.2",
"bip39": "^3.0.2",
"bip66": "^1.1.5",
"bitcoincash-ops": "christroutner/bitcoincash-ops",
"bitcoincashjs-lib": "christroutner/bitcoincashjs-lib#master",
"@psf/bitcoincash-ops": "^2.0.0",
"@psf/bitcoincashjs-lib": "^4.0.2",
"bitcoinjs-message": "^2.0.0",
"bs58": "^4.0.1",
"buffer": "^5.1.0",
"cashaddrjs": "^0.3.3",
"chalk": "^2.3.0",
"clear": "0.1.0",
"coininfo": "Bitcoin-com/coininfo",
"@psf/coininfo": "^4.0.0",
"commander": "^3.0.0",
"cp-file": "^7.0.0",
"ecurve": "^1.0.6",
"figlet": "^1.2.0",
"git-clone": "^0.1.0",
"ini": "^1.3.5",
"ini": "^1.3.8",
"mkdirp": "^0.5.1",
"node-cmd": "^3.0.0",
"node-emoji": "^1.8.1",
@@ -87,7 +87,7 @@
"node-mocks-http": "^1.7.0",
"nyc": "^14.1.0",
"prettier": "^1.18.2",
"semantic-release": "^17.3.0",
"semantic-release": "^17.3.1",
"sinon": "^7.3.2"
},
"apidoc": {
+2 -2
View File
@@ -1,7 +1,7 @@
//const axios = require("axios")
const Bitcoin = require("bitcoincashjs-lib")
const Bitcoin = require("@psf/bitcoincashjs-lib")
const cashaddr = require("cashaddrjs")
const coininfo = require("coininfo")
const coininfo = require("@psf/coininfo")
class Address {
constructor(config) {
-88
View File
@@ -27,14 +27,12 @@ const ECPair = require("./ecpair")
const Script = require("./script")
const Price = require("./price")
const Socket = require("./socket")
const Wallet = require("./wallet")
const Schnorr = require("./schnorr")
const SLP = require("./slp/slp")
const IPFS = require("./ipfs")
const Encryption = require("./encryption")
// Indexers
const Blockbook = require("./blockbook")
const OpenBazaar = require("./openbazaar")
const Ninsight = require("./ninsight")
const Electrumx = require("./electrumx")
@@ -80,9 +78,6 @@ class BCHJS {
// console.log(`apiToken: ${this.apiToken}`)
// Populate Blockbook endpoints.
this.Blockbook = new Blockbook(libConfig)
// Populate OpenBazaar endpoints
this.OpenBazaar = new OpenBazaar(libConfig)
@@ -114,7 +109,6 @@ class BCHJS {
this.TransactionBuilder.setAddress(this.Address)
this.Util = new Util(libConfig)
this.Socket = Socket
this.Wallet = Wallet
this.Schnorr = new Schnorr(libConfig)
this.SLP = new SLP(libConfig)
@@ -122,88 +116,6 @@ class BCHJS {
this.IPFS = new IPFS()
}
static BitboxShim() {
return BitboxShim
}
}
// Creat a shim so that all the endpoints match BITBOX SDK and this library
// can be used as a drop-in replacement for BITBOX.
class BitboxShim {
constructor(config) {
// Try to retrieve the REST API URL from different sources.
if (config && config.restURL && config.restURL !== "")
this.restURL = config.restURL
else if (process.env.RESTURL && process.env.RESTURL !== "")
this.restURL = process.env.RESTURL
else this.restURL = DEFAULT_REST_API
// Retrieve the apiToken
this.apiToken = "" // default value.
if (config && config.apiToken && config.apiToken !== "")
this.apiToken = config.apiToken
else if (process.env.BCHJSTOKEN && process.env.BCHJSTOKEN !== "")
this.apiToken = process.env.BCHJSTOKEN
const libConfig = {
restURL: this.restURL,
apiToken: this.apiToken
}
// Populate utility functions
this.Address = new Address(libConfig)
this.BitcoinCash = new BitcoinCash(this.Address)
this.Blockchain = new Blockchain(libConfig)
this.Crypto = Crypto
this.ECPair = ECPair
this.ECPair.setAddress(this.Address)
this.Generating = new Generating(libConfig)
this.HDNode = new HDNode(this.Address)
this.Mnemonic = new Mnemonic(this.Address)
this.Price = new Price()
this.Script = new Script()
this.TransactionBuilder = TransactionBuilder
this.TransactionBuilder.setAddress(this.Address)
this.Util = new Util(libConfig)
this.Socket = Socket
this.Wallet = Wallet
this.Schnorr = new Schnorr(libConfig)
// Populate the SLP endpoints.
this.SLP = new SLP(libConfig)
this.Address = this.SLP.Address
this.ECPair.toSLPAddress = this.SLP.ECPair.toSLPAddress
this.Util.list = this.SLP.Utils.list
this.Util.balancesForAddress = this.SLP.Utils.balancesForAddress
this.Util.balancesForToken = this.SLP.Utils.balancesForToken
this.Util.balance = this.SLP.Utils.balance
this.Util.validateTxid = this.SLP.Utils.validateTxid
this.Util.tokenStats = this.SLP.Utils.tokenStats
this.Util.transactions = this.SLP.Utils.transactions
this.Util.burnTotal = this.SLP.Utils.burnTotal
this.Util.decodeOpReturn = this.SLP.Utils.decodeOpReturn
this.Util.isTokenUtxo = this.SLP.Utils.isTokenUtxo
this.Util.tokenUtxoDetails = this.SLP.Utils.tokenUtxoDetails
this.Util.txDetails = this.SLP.Utils.txDetails
// Populate Full Node
this.Control = new Control(libConfig)
this.Mining = new Mining(libConfig)
this.RawTransactions = new RawTransactions(libConfig)
// Populate Blockbook endpoints.
this.Blockbook = new Blockbook(libConfig)
// Populate OpenBazaar endpoints
this.OpenBazaar = new OpenBazaar(libConfig)
// Bitcoin.com Ninsight indexer
this.Ninsight = new Ninsight()
this.Electrumx = new Electrumx(libConfig)
}
}
module.exports = BCHJS
+3 -3
View File
@@ -1,9 +1,9 @@
const Bitcoin = require("bitcoincashjs-lib")
const Bitcoin = require("@psf/bitcoincashjs-lib")
const sb = require("satoshi-bitcoin")
const bitcoinMessage = require("bitcoinjs-message")
const bs58 = require("bs58")
const bip21 = require("bip21")
const coininfo = require("coininfo")
const bip21 = require("@psf/bip21")
const coininfo = require("@psf/coininfo")
const bip38 = require("bip38")
const wif = require("wif")
-132
View File
@@ -1,132 +0,0 @@
/*
This library interacts with the REST API endpoints in bch-api that communicate
with the Blockbook API.
CT 11/10/20
These endpoints will be soon be deprecated. Blockbook is being fazed out in
favor of Fulcrum.
*/
const axios = require("axios")
let _this
class Blockbook {
constructor(config) {
this.restURL = config.restURL
this.apiToken = config.apiToken
this.authToken = config.authToken
// console.log(`Blockbook apiToken: ${this.apiToken}`)
if (this.authToken) {
// Add Basic Authentication token to the authorization header.
this.axiosOptions = {
headers: {
authorization: this.authToken
}
}
} else {
// Add JWT token to the authorization header.
this.axiosOptions = {
headers: {
authorization: `Token ${this.apiToken}`
}
}
}
_this = this
}
async balance(address) {
try {
// Handle single address.
if (typeof address === "string") {
const response = await axios.get(
`${this.restURL}blockbook/balance/${address}`,
_this.axiosOptions
)
return response.data
// Handle array of addresses.
} else if (Array.isArray(address)) {
const response = await axios.post(
`${this.restURL}blockbook/balance`,
{
addresses: address
},
_this.axiosOptions
)
return response.data
}
throw new Error(`Input address must be a string or array of strings.`)
} catch (error) {
if (error.response && error.response.data) throw error.response.data
else throw error
}
}
async utxo(address) {
try {
// Handle single address.
if (typeof address === "string") {
const response = await axios.get(
`${this.restURL}blockbook/utxos/${address}`,
_this.axiosOptions
)
return response.data
// Handle array of addresses.
} else if (Array.isArray(address)) {
const response = await axios.post(
`${this.restURL}blockbook/utxos`,
{
addresses: address
},
_this.axiosOptions
)
return response.data
}
throw new Error(`Input address must be a string or array of strings.`)
} catch (error) {
if (error.response && error.response.data) throw error.response.data
else throw error
}
}
async tx(txid) {
try {
// Handle single txid.
if (typeof txid === "string") {
const response = await axios.get(
`${this.restURL}blockbook/tx/${txid}`,
_this.axiosOptions
)
return response.data
// Handle array of addresses.
} else if (Array.isArray(txid)) {
const response = await axios.post(
`${this.restURL}blockbook/tx`,
{
txids: txid
},
_this.axiosOptions
)
return response.data
}
throw new Error(`Input txid must be a string or array of strings.`)
} catch (error) {
if (error.response && error.response.data) throw error.response.data
else throw error
}
}
}
module.exports = Blockbook
+1 -1
View File
@@ -1,5 +1,5 @@
const randomBytes = require("randombytes")
const Bitcoin = require("bitcoincashjs-lib")
const Bitcoin = require("@psf/bitcoincashjs-lib")
class Crypto {
/**
+2 -2
View File
@@ -1,5 +1,5 @@
const Bitcoin = require("bitcoincashjs-lib")
const coininfo = require("coininfo")
const Bitcoin = require("@psf/bitcoincashjs-lib")
const coininfo = require("@psf/coininfo")
class ECPair {
static setAddress(address) {
+3 -3
View File
@@ -1,6 +1,6 @@
const Bitcoin = require("bitcoincashjs-lib")
const coininfo = require("coininfo")
const bip32utils = require("bip32-utils")
const Bitcoin = require("@psf/bitcoincashjs-lib")
const coininfo = require("@psf/coininfo")
const bip32utils = require("@psf/bip32-utils")
const bchaddrjs = require("bchaddrjs-slp")
class HDNode {
+1 -1
View File
@@ -1,6 +1,6 @@
const BIP39 = require("bip39")
const randomBytes = require("randombytes")
const Bitcoin = require("bitcoincashjs-lib")
const Bitcoin = require("@psf/bitcoincashjs-lib")
const Buffer = require("safe-buffer").Buffer
const wif = require("wif")
+2 -2
View File
@@ -1,5 +1,5 @@
const Bitcoin = require("bitcoincashjs-lib")
const opcodes = require("bitcoincash-ops")
const Bitcoin = require("@psf/bitcoincashjs-lib")
const opcodes = require("@psf/bitcoincash-ops")
class Script {
constructor() {
+30 -18
View File
@@ -1,3 +1,7 @@
/*
This library handles the OP_RETURN of SLP TokenType1 transactions.
*/
//const BCHJS = require("../bch-js")
//const bchjs = new BCHJS()
@@ -93,12 +97,16 @@ class TokenType1 {
const tokenId = tokenUtxos[0].tokenId
const decimals = tokenUtxos[0].decimals
// Calculate the total amount of tokens owned by the wallet.
let totalTokens = 0
for (let i = 0; i < tokenUtxos.length; i++)
totalTokens += tokenUtxos[i].tokenQty
const sendQtyBig = new BigNumber(sendQty).times(10 ** decimals)
const change = totalTokens - sendQty
// Calculate the total amount of tokens owned by the wallet.
const totalTokens = tokenUtxos.reduce(
(tot, txo) =>
tot.plus(new BigNumber(txo.tokenQty).times(10 ** decimals)),
new BigNumber(0)
)
const change = totalTokens.minus(sendQtyBig)
// console.log(`change: ${change}`)
let script
@@ -109,19 +117,20 @@ class TokenType1 {
outputs = 2
// Convert the send quantity to the format expected by slp-mdm.
let baseQty = new BigNumber(sendQty).times(10 ** decimals)
baseQty = baseQty.absoluteValue()
baseQty = Math.floor(baseQty)
baseQty = baseQty.toString()
const baseQty = sendQtyBig.toString()
// console.log(`baseQty: `, baseQty)
// Convert the change quantity to the format expected by slp-mdm.
let baseChange = new BigNumber(change).times(10 ** decimals)
baseChange = baseChange.absoluteValue()
baseChange = Math.floor(baseChange)
baseChange = baseChange.toString()
const baseChange = change.toString()
// console.log(`baseChange: `, baseChange)
// Check for potential burns
const outputQty = new BigNumber(baseChange).plus(new BigNumber(baseQty))
const inputQty = new BigNumber(totalTokens)
const tokenOutputDelta = outputQty.minus(inputQty).toString() !== "0"
if (tokenOutputDelta)
throw "Token transaction inputs do not match outputs, cannot send transaction"
// Generate the OP_RETURN as a Buffer.
script = slpMdm.TokenType1.send(tokenId, [
new slpMdm.BN(baseQty),
@@ -131,13 +140,16 @@ class TokenType1 {
// Corner case, when there is no token change to send back.
} else {
let baseQty = new BigNumber(sendQty).times(10 ** decimals)
baseQty = baseQty.absoluteValue()
baseQty = Math.floor(baseQty)
baseQty = baseQty.toString()
const baseQty = sendQtyBig.toString()
// console.log(`baseQty: `, baseQty)
// console.log(`baseQty: ${baseQty.toString()}`)
// Check for potential burns
const noChangeOutputQty = new BigNumber(baseQty)
const noChangeInputQty = new BigNumber(totalTokens)
const tokenSingleOutputError =
noChangeOutputQty.minus(noChangeInputQty).toString() !== "0"
if (tokenSingleOutputError)
throw "Token transaction inputs do not match outputs, cannot send transaction"
// Generate the OP_RETURN as a Buffer.
script = slpMdm.TokenType1.send(tokenId, [new slpMdm.BN(baseQty)])
+118 -23
View File
@@ -1,6 +1,7 @@
// Public npm libraries
const axios = require("axios")
const slpParser = require("slp-parser")
const BigNumber = require("bignumber.js")
// const Script = require("../script")
// const scriptLib = new Script()
@@ -431,6 +432,10 @@ class Utils {
* '00ea27261196a411776f81029c0ebe34362936b4a9847deb1f7a40a02b3a1476',
* valid: true } ]
*/
// This function has two responses. If SLPDB is working correctly, the output
// will be like the examples above. If SLPDB has fallen behind real-time
// processing, it will return this output:
// [ null ]
async validateTxid(txid) {
const path = `${this.restURL}slp/validateTxid`
@@ -449,7 +454,9 @@ class Utils {
},
_this.axiosOptions
)
// console.log(`response.data: ${JSON.stringify(response.data, null, 2)}`)
// console.log(
// `validateTxid response.data: ${JSON.stringify(response.data, null, 2)}`
// )
const validatedTxids = response.data
@@ -1172,7 +1179,9 @@ class Utils {
// Tokens
else {
utxo.utxoType = "token"
utxo.tokenQty = slpData.qty / Math.pow(10, slpData.decimals)
utxo.tokenQty = new BigNumber(slpData.qty)
.div(Math.pow(10, slpData.decimals))
.toString()
}
utxo.tokenId = utxo.txid
@@ -1215,7 +1224,9 @@ class Utils {
// Tokens
else {
utxo.utxoType = "token"
utxo.tokenQty = slpData.qty / Math.pow(10, genesisData.decimals)
utxo.tokenQty = new BigNumber(slpData.qty)
.div(Math.pow(10, genesisData.decimals))
.toString()
}
// Hydrate the UTXO object with information about the SLP token.
@@ -1273,7 +1284,12 @@ class Utils {
utxo.tokenType = slpData.tokenType
// Calculate the real token quantity.
utxo.tokenQty = tokenQty / Math.pow(10, genesisData.decimals)
const tokenQtyBig = new BigNumber(tokenQty).div(
Math.pow(10, genesisData.decimals)
)
//console.log(`tokenQtyBig`, tokenQtyBig.toString())
utxo.tokenQty = tokenQtyBig.toString()
// console.log(`utxo: ${JSON.stringify(utxo, null, 2)}`)
@@ -1288,24 +1304,53 @@ class Utils {
// property. i.e. it has been successfully hydrated with SLP
// information.
// CT 12/13/2020: Disabling the cache until I get processing of tokens
// to be more stable.
// If the value has been cached, use the cached version first.
let isValid = cachedTxValidation[utxo.txid]
if (!isValid) isValid = null
// let isValid = null
// There are two possible responses from SLPDB. If SLPDB is functioning
// correctly, then validateTxid() will return this:
// isValid: [
// {
// "txid": "ff0c0354f8d3ddb34fa36f73494eb58ea24f8b8da6904aa8ed43b7a74886c583",
// "valid": true
// }
// ]
//
// If SLPDB has fallen behind real-time processing, it will return this:
// isValid: [
// null
// ]
//
// Note: validateTxid3() has the same output as validateTxid().
// validateTxid2() uses slp-validate, which has a different output format.
// If not in the cache, try the general SLPDB.
if (isValid == null) {
console.log(`utxo: ${JSON.stringify(utxo, null, 2)}`)
if (isValid === null) {
// console.log(`utxo: ${JSON.stringify(utxo, null, 2)}`)
isValid = await this.validateTxid(utxo.txid)
console.log(`isValid: ${JSON.stringify(isValid, null, 2)}`)
// console.log(
// `validateTxid() isValid: ${JSON.stringify(isValid, null, 2)}`
// )
if (isValid !== null) {
isValid = isValid[0].valid
// Handle corner case where SLPDB returns an array with a null element.
if (isValid[0] === null)
isValid = [{ txid: utxo.txid, valid: null }]
// Save the result to the local cache.
cachedTxValidation[utxo.txid] = isValid
}
isValid = isValid[0].valid
// Save the result to the local cache.
// cachedTxValidation[utxo.txid] = isValid
}
// console.log(`isValid: ${JSON.stringify(isValid, null, 2)}`)
// console.log(
// `pre-validateTxid3() isValid: ${JSON.stringify(isValid, null, 2)}`
// )
// If still null, check the whitelist SLPDB
if (isValid === null) {
// console.log(
@@ -1339,32 +1384,40 @@ class Utils {
// )}`
// )
if (isValid !== null) {
isValid = isValid[0].valid
if (isValid[0] !== null) isValid = isValid[0].valid
// Save the result to the local cache.
cachedTxValidation[utxo.txid] = isValid
}
// Save the result to the local cache.
// cachedTxValidation[utxo.txid] = isValid
}
}
// console.log(
// `pre-validateTxid2() isValid: ${JSON.stringify(isValid, null, 2)}`
// )
// If still null, as a last resort, check it against slp-validate
if (isValid === null) {
isValid = await this.validateTxid2(utxo.txid)
try {
isValid = await this.validateTxid2(utxo.txid)
} catch (err) {
// Mark as invalid if validateTxid2() throws an error.
isValid = null
}
// console.log(
// `slp-validate isValid: ${JSON.stringify(isValid, null, 2)}`
// )
if (isValid !== null) {
isValid = isValid.isValid
if (isValid !== null) isValid = isValid.isValid
// Save the result to the local cache.
cachedTxValidation[utxo.txid] = isValid
}
// Save the result to the local cache.
// cachedTxValidation[utxo.txid] = isValid
}
// console.log(`isValid: ${JSON.stringify(isValid, null, 2)}`)
outAry[i].isValid = isValid
// Save the txid to the local cache to reduce API calls.
cachedTxValidation[utxo.txid] = isValid
}
}
@@ -1559,6 +1612,48 @@ class Utils {
else throw error
}
}
/**
* @api SLP.Utils.getStatus() getStatus()
* @apiName getStatus
* @apiGroup SLP Utils
* @apiDescription Get the status and health of the SLPDB connected to bch-api.
*
* @apiExample Example usage:
*
* // Get the current blockheight of the SLPDB indexer.
* (async () => {
* try {
* let validated = await bchjs.SLP.Utils.validateTxid(
* "df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb"
* );
* console.log(validated);
* } catch (error) {
* console.error(error);
* }
* })();
*
* // returns
* [ { txid:
* 'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb',
* valid: true } ]
*
*/
async getStatus(txid) {
const path = `${this.restURL}slp/status`
try {
const response = await _this.axios.get(path, _this.axiosOptions)
// console.log(
// `getStatus response.data: ${JSON.stringify(response.data, null, 2)}`
// )
return response.data
} catch (error) {
if (error.response && error.response.data) throw error.response.data
throw error
}
}
}
module.exports = Utils
+2 -2
View File
@@ -1,5 +1,5 @@
const Bitcoin = require("bitcoincashjs-lib")
const coininfo = require("coininfo")
const Bitcoin = require("@psf/bitcoincashjs-lib")
const coininfo = require("@psf/coininfo")
const bip66 = require("bip66")
const bip68 = require("bc-bip68")
-77
View File
@@ -1,77 +0,0 @@
// import BCHWalletBridge from "bch-wallet-bridge.js"
class Wallet {
constructor(walletProvider) {
// this.bchWalletBridge = new BCHWalletBridge(walletProvider)
}
setWalletProvider(walletProvider) {
this.bchWalletBridge.walletProvider = walletProvider
}
getAddress(changeType, index, dAppId) {
return this.bchWalletBridge.getAddress(changeType, index, dAppId)
}
getAddressIndex(changeType, dAppId) {
return this.bchWalletBridge.getAddressIndex(changeType, dAppId)
}
getAddresses(changeType, startIndex, size, dAppId) {
return this.bchWalletBridge.getAddresses(
changeType,
startIndex,
size,
dAppId
)
}
getRedeemScript(p2shAddress, dAppId) {
return this.bchWalletBridge.getRedeemScript(p2shAddress, dAppId)
}
getRedeemScripts(dAppId) {
return this.bchWalletBridge.getRedeemScripts(dAppId)
}
addRedeemScript(redeemScript, dAppId) {
return this.bchWalletBridge.addRedeemScript(redeemScript, dAppId)
}
getUtxos(dAppId) {
return this.bchWalletBridge.getUtxos(dAppId)
}
getBalance(dAppId) {
return this.bchWalletBridge.getBalance(dAppId)
}
sign(address, dataToSign) {
return this.bchWalletBridge.sign(address, dataToSign)
}
buildTransaction(outputs, dAppId) {
return this.bchWalletBridge.buildTransaction(outputs, dAppId)
}
getProtocolVersion() {
return this.bchWalletBridge.getProtocolVersion()
}
getNetwork() {
return this.bchWalletBridge.getNetwork()
}
getFeePerByte() {
return this.bchWalletBridge.getFeePerByte()
}
getDefaultDAppId() {
return this.bchWalletBridge.getDefaultDAppId()
}
setDefaultDAppId(dAppId) {
return this.bchWalletBridge.setDefaultDAppId(dAppId)
}
}
module.exports = Wallet
-148
View File
@@ -1,148 +0,0 @@
/*
Integration tests for the Blockbook library.
*/
const chai = require("chai")
const assert = chai.assert
const BCHJS = require("../../src/bch-js")
const bchjs = new BCHJS()
//const axios = require("axios")
// Inspect utility used for debugging.
const util = require("util")
util.inspect.defaultOptions = {
showHidden: true,
colors: true,
depth: 3
}
describe(`#Blockbook`, () => {
beforeEach(async () => {
if (process.env.IS_USING_FREE_TIER) await sleep(1000)
})
describe(`#Balance`, () => {
it(`should GET balance for a single address`, async () => {
const addr = "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf"
const result = await bchjs.Blockbook.balance(addr)
//console.log(`result: ${util.inspect(result)}`)
assert.hasAnyKeys(result, [
"page",
"totalPages",
"itemsOnPage",
"address",
"balance",
"totalReceived",
"totalSent",
"unconfirmedBalance",
"unconfirmedTxs",
"txs",
"txids"
])
assert.isArray(result.txids)
})
it(`should POST request balances for an array of addresses`, async () => {
const addr = [
"bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf",
"bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v"
]
const result = await bchjs.Blockbook.balance(addr)
//console.log(`result: ${util.inspect(result)}`)
assert.isArray(result)
assert.hasAnyKeys(result[0], [
"page",
"totalPages",
"itemsOnPage",
"address",
"balance",
"totalReceived",
"totalSent",
"unconfirmedBalance",
"unconfirmedTxs",
"txs",
"txids"
])
assert.isArray(result[0].txids)
})
it(`should throw error on array size rate limit`, async () => {
try {
const addr = []
for (let i = 0; i < 25; i++)
addr.push("bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf")
const result = await bchjs.Blockbook.balance(addr)
console.log(`result: ${util.inspect(result)}`)
assert.equal(true, false, "Unexpected result!")
} catch (err) {
assert.hasAnyKeys(err, ["error"])
assert.include(err.error, "Array too large")
}
})
})
describe(`#utxo`, () => {
it(`should GET utxos for a single address`, async () => {
const addr = "bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7"
const result = await bchjs.Blockbook.utxo(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.hasAnyKeys(result[0], [
"txid",
"vout",
"value",
"height",
"confirmations"
])
})
it(`should POST utxo details for an array of addresses`, async () => {
const addr = [
"bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7",
"bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr"
]
const result = await bchjs.Blockbook.utxo(addr)
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.isArray(result[0])
assert.hasAnyKeys(result[0][0], [
"txid",
"vout",
"value",
"height",
"confirmations"
])
})
it(`should throw error on array size rate limit`, async () => {
try {
const addr = []
for (let i = 0; i < 25; i++)
addr.push("bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr")
const result = await bchjs.Blockbook.utxo(addr)
//console.log(`result: ${util.inspect(result)}`)
assert.equal(true, false, "Unexpected result!")
} catch (err) {
assert.hasAnyKeys(err, ["error"])
assert.include(err.error, "Array too large")
}
})
})
})
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
+86 -103
View File
@@ -464,20 +464,30 @@ describe(`#SLP`, () => {
assert.equal(data[0].isValid, false)
})
// it("should handle null SLPDB validations", async () => {
// const utxos = [
// {
// height: 665577,
// tx_hash:
// "4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419",
// tx_pos: 1,
// value: 546
// }
// ]
//
// const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
// })
it("should handle null SLPDB validations", async () => {
const utxos = [
{
height: 665577,
tx_hash:
"4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419",
tx_pos: 1,
value: 546
},
{
height: 665577,
tx_hash:
"3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488",
tx_pos: 1,
value: 546
}
]
const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
assert.isArray(data)
// assert.equal(data[0].isValid, null)
})
})
describe("#balancesForAddress", () => {
@@ -619,20 +629,59 @@ describe(`#SLP`, () => {
}
})
// it("should handle null SLPDB validations", async () => {
// const utxos = [
// {
// height: 665577,
// tx_hash:
// "4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419",
// tx_pos: 1,
// value: 546
// }
// ]
//
// const data = await bchjs.SLP.Utils.hydrateUtxos([{ utxos: utxos }])
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
// })
it("should handle null SLPDB validations", async () => {
const utxos = [
{
height: 665577,
tx_hash:
"4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419",
tx_pos: 1,
value: 546
},
{
height: 665577,
tx_hash:
"f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a",
tx_pos: 1,
value: 546
}
]
const data = await bchjs.SLP.Utils.hydrateUtxos([{ utxos: utxos }])
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
assert.isArray(data.slpUtxos)
assert.equal(data.slpUtxos[0].isValid, null)
})
})
describe("#validateTxid", () => {
// This test is not necessary.
it("should handle a null response from SLPDB", async () => {
const txid =
"4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419"
const result = await bchjs.SLP.Utils.validateTxid(txid)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.equal(result[0].txid, txid)
// assert.equal(result[0].valid, null)
})
it("should handle a null response from SLPDB", async () => {
const txid = [
"4b89405c54d1c0bde8aa476a47561a42a6e7a5e927daa2ec69d428810eae3419",
"3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488"
]
const result = await bchjs.SLP.Utils.validateTxid(txid)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.equal(result[0].txid, txid[0])
// assert.equal(result[0].valid, null)
})
})
describe("#validateTxid2", () => {
@@ -676,82 +725,16 @@ describe(`#SLP`, () => {
})
})
// describe("#validateTxid3", () => {
// it("should invalidate a known invalid TXID", async () => {
// const txid =
// "f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a"
//
// const result = await bchjs.SLP.Utils.validateTxid3(txid)
// // console.log(`result: ${JSON.stringify(result, null, 2)}`)
//
// assert.isArray(result)
//
// assert.property(result[0], "txid")
// assert.equal(result[0].txid, txid)
//
// assert.property(result[0], "valid")
// assert.equal(result[0].valid, null)
// })
//
// it("should validate a known valid TXID", async () => {
// const txid =
// "daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd"
//
// const result = await bchjs.SLP.Utils.validateTxid3(txid)
// // console.log(`result: ${JSON.stringify(result, null, 2)}`)
//
// assert.isArray(result)
//
// assert.property(result[0], "txid")
// assert.equal(result[0].txid, txid)
//
// assert.property(result[0], "valid")
// assert.equal(result[0].valid, true)
// })
//
// it("should handle a mix of valid, invalid, and non-SLP txs", async () => {
// const txids = [
// // Malformed SLP tx
// "f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a",
// // Normal TX (non-SLP)
// "01cdaec2f8b311fc2d6ecc930247bd45fa696dc204ab684596e281fe1b06c1f0",
// // Valid PSF SLP tx
// "daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd",
// // Valid SLP token not in whitelist
// "3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488",
// // Unprocessed SLP TX
// // "a0d6406eecfd8634158efa9314ff15b4cbf451938e9dc7b5678c46b41eabc6ed" // Mint baton
// "402c663379d9699b6e2dd38737061e5888c5a49fca77c97ab98e79e08959e019"
// ]
//
// const result = await bchjs.SLP.Utils.validateTxid3(txids)
// // console.log(`result: ${JSON.stringify(result, null, 2)}`)
// })
// })
describe("#getStatus", () => {
it("should return the current block height of the SLPDB indexer", async () => {
const result = await bchjs.SLP.Utils.getStatus()
// describe("#validateTxid", () => {
// it("should handle a mix of valid, invalid, and non-SLP txs", async () => {
// const txids = [
// // Malformed SLP tx
// "f7e5199ef6669ad4d078093b3ad56e355b6ab84567e59ad0f08a5ad0244f783a",
// // Normal TX (non-SLP)
// "01cdaec2f8b311fc2d6ecc930247bd45fa696dc204ab684596e281fe1b06c1f0",
// // Valid PSF SLP tx
// "daf4d8b8045e7a90b7af81bfe2370178f687da0e545511bce1c9ae539eba5ffd",
// // Valid SLP token not in whitelist
// "3a4b628cbcc183ab376d44ce5252325f042268307ffa4a53443e92b6d24fb488",
// // Unprocessed SLP TX
// // "a0d6406eecfd8634158efa9314ff15b4cbf451938e9dc7b5678c46b41eabc6ed"
// // Token send on BCHN network.
// "402c663379d9699b6e2dd38737061e5888c5a49fca77c97ab98e79e08959e019",
// // Token send on ABC network.
// "336bfe2168aac4c3303508a9e8548a0d33797a83b85b76a12d845c8d6674f79d"
// ]
//
// const result = await bchjs.SLP.Utils.validateTxid(txids)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
// })
// })
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, "bchBlockHeight")
assert.property(result, "slpProcessedBlockHeight")
})
})
})
describe("#tokentype1", () => {
+1 -1
View File
@@ -1,6 +1,6 @@
// Public npm libraries.
const assert = require("assert")
const Bitcoin = require("bitcoincashjs-lib")
const Bitcoin = require("@psf/bitcoincashjs-lib")
// Mocks
const fixtures = require("./fixtures/address.json")
-275
View File
@@ -1,275 +0,0 @@
const chai = require("chai")
const assert = chai.assert
const BCHJS = require("../../src/bch-js")
const bchjs = new BCHJS()
const axios = require("axios")
const sinon = require("sinon")
const mockData = require("./fixtures/blockbook-mock")
describe(`#Blockbook`, () => {
let sandbox
beforeEach(() => (sandbox = sinon.createSandbox()))
afterEach(() => sandbox.restore())
describe(`#Balance`, () => {
it(`should GET balance for a single address`, async () => {
// Stub the network call.
sandbox.stub(axios, "get").resolves({ data: mockData.balance })
const addr = "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf"
const result = await bchjs.Blockbook.balance(addr)
//console.log(`result: ${util.inspect(result)}`)
assert.hasAnyKeys(result, [
"page",
"totalPages",
"itemsOnPage",
"address",
"balance",
"totalReceived",
"totalSent",
"unconfirmedBalance",
"unconfirmedTxs",
"txs",
"txids"
])
assert.isArray(result.txids)
})
it(`should POST request balances for an array of addresses`, async () => {
// Stub the network call.
sandbox
.stub(axios, "post")
.resolves({ data: [mockData.balance, mockData.balance] })
const addr = [
"bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf",
"bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v"
]
const result = await bchjs.Blockbook.balance(addr)
//console.log(`result: ${util.inspect(result)}`)
assert.isArray(result)
assert.hasAnyKeys(result[0], [
"page",
"totalPages",
"itemsOnPage",
"address",
"balance",
"totalReceived",
"totalSent",
"unconfirmedBalance",
"unconfirmedTxs",
"txs",
"txids"
])
assert.isArray(result[0].txids)
})
it(`should throw an error for improper input`, async () => {
try {
// Stub the network call.
sandbox
.stub(axios, "post")
.throws(`Input address must be a string or array of strings`)
const addr = 12345
await bchjs.Blockbook.balance(addr)
assert.equal(true, false, "Unexpected result!")
} catch (err) {
//console.log(`err: `, err)
assert.include(
err.message,
`Input address must be a string or array of strings`
)
}
})
/*
it(`should throw error on array size rate limit`, async () => {
try {
// Stub the network call.
sandbox.stub(axios, "post").throws(`Array too large`)
const addr = []
for (let i = 0; i < 25; i++)
addr.push("bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf")
const result = await bchjs.Blockbook.balance(addr)
console.log(`result: ${util.inspect(result)}`)
assert.equal(true, false, "Unexpected result!")
} catch (err) {
assert.hasAnyKeys(err, ["error"])
assert.include(err.error, "Array too large")
}
})
*/
})
describe(`#utxo`, () => {
it(`should GET utxos for a single address`, async () => {
// Stub the network call.
sandbox.stub(axios, "get").resolves({ data: mockData.utxo })
const addr = "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf"
const result = await bchjs.Blockbook.utxo(addr)
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.hasAnyKeys(result[0], [
"txid",
"vout",
"value",
"height",
"confirmations"
])
})
it(`should POST utxo details for an array of addresses`, async () => {
// Stub the network call.
sandbox.stub(axios, "post").resolves({ data: mockData.utxos })
const addr = [
"bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf",
"bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v"
]
const result = await bchjs.Blockbook.utxo(addr)
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.isArray(result[0])
assert.hasAnyKeys(result[0][0], [
"txid",
"vout",
"value",
"height",
"confirmations"
])
})
it(`should throw an error for improper input`, async () => {
try {
// Stub the network call.
sandbox
.stub(axios, "post")
.throws(`Input address must be a string or array of strings`)
const addr = 12345
await bchjs.Blockbook.utxo(addr)
assert.equal(true, false, "Unexpected result!")
} catch (err) {
//console.log(`err: `, err)
assert.include(
err.message,
`Input address must be a string or array of strings`
)
}
})
/*
it(`should throw error on array size rate limit`, async () => {
try {
const addr = []
for (let i = 0; i < 25; i++)
addr.push("bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf")
const result = await bchjs.Blockbook.utxo(addr)
console.log(`result: ${util.inspect(result)}`)
assert.equal(true, false, "Unexpected result!")
} catch (err) {
assert.hasAnyKeys(err, ["error"])
assert.include(err.error, "Array too large")
}
})
*/
})
describe(`#tx`, () => {
it(`should GET tx details for a single txid`, async () => {
// Stub the network call.
sandbox.stub(axios, "get").resolves({ data: mockData.utxo })
const addr = "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf"
const result = await bchjs.Blockbook.utxo(addr)
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.hasAnyKeys(result[0], [
"txid",
"vout",
"value",
"height",
"confirmations"
])
})
// it(`should POST utxo details for an array of addresses`, async () => {
// // Stub the network call.
// sandbox.stub(axios, "post").resolves({ data: mockData.utxos })
//
// const addr = [
// "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf",
// "bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v"
// ]
//
// const result = await bchjs.Blockbook.utxo(addr)
// //console.log(`result: ${JSON.stringify(result, null, 2)}`)
//
// assert.isArray(result)
// assert.isArray(result[0])
// assert.hasAnyKeys(result[0][0], [
// "txid",
// "vout",
// "value",
// "height",
// "confirmations"
// ])
// })
// it(`should throw an error for improper input`, async () => {
// try {
// // Stub the network call.
// sandbox
// .stub(axios, "post")
// .throws(`Input address must be a string or array of strings`)
//
// const addr = 12345
//
// await bchjs.Blockbook.utxo(addr)
// assert.equal(true, false, "Unexpected result!")
// } catch (err) {
// //console.log(`err: `, err)
// assert.include(
// err.message,
// `Input address must be a string or array of strings`
// )
// }
// })
/*
it(`should throw error on array size rate limit`, async () => {
try {
const addr = []
for (let i = 0; i < 25; i++)
addr.push("bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf")
const result = await bchjs.Blockbook.utxo(addr)
console.log(`result: ${util.inspect(result)}`)
assert.equal(true, false, "Unexpected result!")
} catch (err) {
assert.hasAnyKeys(err, ["error"])
assert.include(err.error, "Array too large")
}
})
*/
})
})
-64
View File
@@ -1,64 +0,0 @@
/*
Unit test mocks for Blockbook endpoints.
*/
const balance = {
page: 1,
totalPages: 1,
itemsOnPage: 1000,
address: "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf",
balance: "230000",
totalReceived: "6194528752",
totalSent: "6194298752",
unconfirmedBalance: "0",
unconfirmedTxs: 0,
txs: 3,
txids: [
"27ec8512c1a9ee9e9ae9b98eb60375f1d2bd60e2e76a1eff5a45afdbc517cf9c",
"6e1ae1bf7db6de799ec1c05ab2816ac65549bd80141567af088e6f291385b07d",
"5d95f4e6047901fc1502a9758bbdb14ce73f24662b1784d13e0217b3d37bb7a2"
]
}
const utxo = [
{
txid: "27ec8512c1a9ee9e9ae9b98eb60375f1d2bd60e2e76a1eff5a45afdbc517cf9c",
vout: 0,
value: "100000",
height: 560430,
confirmations: 29321
},
{
txid: "6e1ae1bf7db6de799ec1c05ab2816ac65549bd80141567af088e6f291385b07d",
vout: 0,
value: "130000",
height: 560039,
confirmations: 29712
}
]
const utxos = [
[
{
txid: "27ec8512c1a9ee9e9ae9b98eb60375f1d2bd60e2e76a1eff5a45afdbc517cf9c",
vout: 0,
value: "100000",
height: 560430,
confirmations: 29868
},
{
txid: "6e1ae1bf7db6de799ec1c05ab2816ac65549bd80141567af088e6f291385b07d",
vout: 0,
value: "130000",
height: 560039,
confirmations: 30259
}
],
[]
]
module.exports = {
balance,
utxo,
utxos
}
+102 -1
View File
@@ -1190,6 +1190,106 @@ const whitelist = [
}
]
const slpdbStatus = {
_id: "5fe4cd90cd2bd2000f7fe46c",
version: "1.0.0-beta-rc13",
versionHash: "bb4a805610b9e4d67c1595b716df36190c75e8b1",
deplVersionHash: null,
startCmd: "node index run",
context: "SLPDB",
lastStatusUpdate: {
utc: "Thu, 24 Dec 2020 17:19:12 GMT",
unix: 1608830352
},
lastIncomingTxnZmq: {
utc: "Thu, 24 Dec 2020 17:19:12 GMT",
unix: 1608830352
},
lastIncomingBlockZmq: {
utc: "Thu, 24 Dec 2020 16:43:38 GMT",
unix: 1608828218
},
lastOutgoingTxnZmq: null,
lastOutgoingBlockZmq: null,
state: "RUNNING",
stateHistory: [
{
utc: "Mon, 07 Dec 2020 15:26:23 GMT",
state: "STARTUP_BLOCK_SYNC"
},
{
utc: "Tue, 08 Dec 2020 19:53:04 GMT",
state: "RUNNING"
}
],
network: "mainnet",
bchBlockHeight: 667270,
bchBlockHash:
"000000000000000003d57b35b1b6b8073c8311974e2b9a473e1bd6daa98fde53",
slpProcessedBlockHeight: 667270,
mempoolInfoBch: {
loaded: true,
size: 534,
bytes: 320552,
usage: 956384,
maxmempool: 300000000,
mempoolminfee: 0.00001,
minrelaytxfee: 0.00001
},
mempoolSizeSlp: 78,
tokensCount: 77976,
pastStackTraces: [
"[Tue, 08 Dec 2020 19:35:36 GMT] MongoServerSelectionError: connection <monitor> to 172.17.0.1:12301 timed out\n at Timeout._onTimeout (/home/safeuser/SLPDB/node_modules/mongodb/lib/core/sdam/topology.js:438:30)\n at listOnTimeout (internal/timers.js:554:17)\n at processTimers (internal/timers.js:497:7)",
"[Tue, 08 Dec 2020 19:35:36 GMT] MongoServerSelectionError: connection <monitor> to 172.17.0.1:12301 timed out\n at Timeout._onTimeout (/home/safeuser/SLPDB/node_modules/mongodb/lib/core/sdam/topology.js:438:30)\n at listOnTimeout (internal/timers.js:554:17)\n at processTimers (internal/timers.js:497:7)"
],
doubleSpends: [
{
txo:
"3e377f67e9d065f02e47633d847cdb04b0679d51baccdc0feea5297529e330b5:820",
details: {
originalTxid:
"dc148149d25a546fffe0b207c62b192811c288481df5f43f1f76f67b6004f98c",
current:
"de12db60e253c378eeebb1df85153168a998db8267ec54b38589cc31348b2b8d",
time: {
utc: "Sat, 19 Dec 2020 02:25:37 GMT",
unix: 1608344737
}
}
}
],
reorgs: [],
mongoDbStats: {
db: "slpdb",
collections: 5,
views: 0,
objects: 2497140,
avgObjSize: 3188.778575890819,
dataSize: 7593.943150520325,
storageSize: 3357.74609375,
indexes: 71,
indexSize: 1490.14453125,
totalSize: 4847.890625,
scaleFactor: 1048576,
fsUsedSize: 74424.46484375,
fsTotalSize: 153676.98046875,
ok: 1
},
publicUrl: "fullstack--bchn-02",
telemetryHash: null,
system: {
loadAvg1: 0.16,
loadAvg5: 0.11,
loadAvg15: 0.04,
platform: "linux",
cpuCount: 8,
freeMem: 5780.51953125,
totalMem: 31360.8828125,
uptime: 1654085,
processUptime: 1374204.613560816
}
}
module.exports = {
mockList,
mockToken,
@@ -1218,5 +1318,6 @@ module.exports = {
mockWhitelist,
mockValidateTxid3Valid,
mockValidateTxid3Invalid,
whitelist
whitelist,
slpdbStatus
}
File diff suppressed because it is too large Load Diff
+73
View File
@@ -1771,6 +1771,64 @@ describe("#SLP Utils", () => {
// The UTXO should have been validated by the third validation source.
assert.equal(data[0].isValid, true)
})
it("should handle SLPDB returning null corner case", async () => {
// Mock the call to REST API
// Stub the calls to decodeOpReturn.
sandbox
.stub(uut.Utils, "decodeOpReturn")
.onCall(0)
.resolves({
tokenType: 1,
txType: "SEND",
tokenId:
"497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7",
amounts: ["200000000", "99887500000000"]
})
.onCall(1)
.resolves({
tokenType: 1,
txType: "GENESIS",
ticker: "TOK-CH",
name: "TokyoCash",
tokenId:
"497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7",
documentUri: "",
documentHash: "",
decimals: 8,
mintBatonVout: 0,
qty: "2100000000000000"
})
// Force default SLPDB to return 'null' corner case.
sandbox.stub(uut.Utils, "validateTxid").resolves([null])
// Mock the response from slp-api
sandbox.stub(uut.Utils, "validateTxid2").resolves({
txid:
"fde117b1f176b231e2fa9a6cb022e0f7c31c288221df6bcb05f8b7d040ca87cb",
isValid: true,
msg: ""
})
const utxos = [
{
txid:
"fde117b1f176b231e2fa9a6cb022e0f7c31c288221df6bcb05f8b7d040ca87cb",
vout: 1,
amount: 0.00000546,
satoshis: 546,
height: 596089,
confirmations: 748
}
]
const data = await uut.Utils.tokenUtxoDetails(utxos)
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
// The UTXO should have been validated by the third validation source.
assert.equal(data[0].isValid, true)
})
})
describe("#txDetails", () => {
@@ -2103,4 +2161,19 @@ describe("#SLP Utils", () => {
}
})
})
describe("#getStatus", () => {
it("should return the current block height of the SLPDB indexer", async () => {
sandbox
.stub(uut.Utils.axios, "get")
.resolves({ data: mockData.slpdbStatus })
const result = await uut.Utils.getStatus()
// console.log(`result: `, result)
assert.property(result, "bchBlockHeight")
assert.property(result, "slpProcessedBlockHeight")
})
})
})