Compare commits

...
18 Commits
Author SHA1 Message Date
Chris Troutner 739bdf1f34 Merge pull request #17 from Permissionless-Software-Foundation/ct-unstable
fix(docs): Adding deploy script to automatically update documentation
2020-08-07 18:17:44 -07:00
Chris Troutner b207a1639e Removing unit test for SLP.Utils.balance() 2020-08-07 18:13:52 -07:00
Chris Troutner a169c0f7d0 fix(docs): Adding deploy script to automatically update documentation 2020-08-07 18:03:55 -07:00
Chris Troutner 65cf49adf0 Merge pull request #16 from Permissionless-Software-Foundation/zh
fix(electrumx): Added unconfirmed endpoint for Electrumx library.
2020-08-05 09:02:29 -07:00
Chris Troutner 65104d60ad Commented out failing integration tests 2020-08-05 08:54:54 -07:00
Chris Troutner fd0a1a6af2 editing api docs for electrumx 2020-08-05 08:47:04 -07:00
Chris Troutner 25299e2f6e Merge pull request #14 from zh/add-electrumx-unconfirmed-utxo
Access to unconfirmed UTXOs API endpoints
2020-08-05 08:42:14 -07:00
Stoyan Zhekov b184c080f1 Access to unconfirmed UTXOs API endpoints 2020-08-04 22:58:22 +09:00
Chris Troutner d2c999f739 Merge pull request #9 from Permissionless-Software-Foundation/ct-unstable
fix(Ninsight): Using POST endpoint only
2020-07-31 14:07:28 -07:00
Chris Troutner 4d2d8d0e5a fix(Ninsight): Using POST endpoint only 2020-07-31 14:04:22 -07:00
Chris Troutner fec9d371af Merge pull request #8 from Permissionless-Software-Foundation/ct-unstable
Ninsight UTXO Bulk call
2020-07-31 13:33:11 -07:00
Chris Troutner b3c74b4a8b fixing integration test 2020-07-31 13:19:21 -07:00
Chris Troutner 1aa99a820a fix(Ninsight utxo): Added call to POST bulk endpoint 2020-07-31 12:58:06 -07:00
Chris Troutner 6652e1e4af ran npm audit fix 2020-07-31 12:35:10 -07:00
Chris Troutner b70e0a16c0 Merge pull request #3 from Permissionless-Software-Foundation/ct-unstable
feat(upload): Expanded IPFS Class for uploading files to the web
2020-07-29 10:19:55 -07:00
Chris Troutner a94392c4a5 Merge branch 'master' of https://github.com/christroutner/bch-js into ct-unstable 2020-07-29 10:16:06 -07:00
Chris Troutner ba02724d54 Merge pull request #54 from christroutner/dh-upload-files
feat(upload): Expanded IPFS Class for uploading files to the web
2020-07-29 10:14:37 -07:00
Daniel Gonzalez b12110a617 feat(upload): Expanded IPFS Class for uploading files to the web 2020-07-29 01:18:33 -04:00
20 changed files with 1135 additions and 349 deletions
+1 -1
View File
@@ -27,4 +27,4 @@ deploy:
provider: script
skip_cleanup: true
script:
- npx semantic-release
- npx semantic-release && ./deploy-production.sh
+14
View File
@@ -0,0 +1,14 @@
# Triggers a webhook to update the staging server at staging.fullstack.cash.
#!/bin/bash
#echo $DEPLOY_SECRET
echo "Deploy to production...."
export DATA="{\"ref\":\"$DEPLOY_SECRET\"}"
#echo $DATA
curl -X POST http://fullstack.cash:9000/hooks/bch-js -H "Content-Type: application/json" -d $DATA
echo "...Finished deploying to production."
+213 -220
View File
@@ -1,6 +1,6 @@
{
"name": "@chris.troutner/bch-js",
"version": "3.0.0",
"name": "@psf/bch-js",
"version": "3.4.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -1697,13 +1697,13 @@
"integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs="
},
"compare-func": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.4.tgz",
"integrity": "sha512-sq2sWtrqKPkEXAC8tEJA1+BqAH9GbFkGBtUOqrUX57VSfwp8xyktctk+uLoRy5eccTdxzDcVIztlYDpKs3Jv1Q==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz",
"integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==",
"dev": true,
"requires": {
"array-ify": "^1.0.0",
"dot-prop": "^3.0.0"
"dot-prop": "^5.1.0"
}
},
"component-bind": {
@@ -1777,22 +1777,49 @@
"integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo="
},
"conventional-changelog-angular": {
"version": "5.0.10",
"resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.10.tgz",
"integrity": "sha512-k7RPPRs0vp8+BtPsM9uDxRl6KcgqtCJmzRD1wRtgqmhQ96g8ifBGo9O/TZBG23jqlXS/rg8BKRDELxfnQQGiaA==",
"version": "5.0.11",
"resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.11.tgz",
"integrity": "sha512-nSLypht/1yEflhuTogC03i7DX7sOrXGsRn14g131Potqi6cbGbGEE9PSDEHKldabB6N76HiSyw9Ph+kLmC04Qw==",
"dev": true,
"requires": {
"compare-func": "^1.3.1",
"compare-func": "^2.0.0",
"q": "^1.5.1"
},
"dependencies": {
"compare-func": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz",
"integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==",
"dev": true,
"requires": {
"array-ify": "^1.0.0",
"dot-prop": "^5.1.0"
}
},
"dot-prop": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz",
"integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==",
"dev": true,
"requires": {
"is-obj": "^2.0.0"
}
},
"is-obj": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
"integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
"dev": true
}
}
},
"conventional-changelog-writer": {
"version": "4.0.16",
"resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.16.tgz",
"integrity": "sha512-jmU1sDJDZpm/dkuFxBeRXvyNcJQeKhGtVcFFkwTphUAzyYWcwz2j36Wcv+Mv2hU3tpvLMkysOPXJTLO55AUrYQ==",
"version": "4.0.17",
"resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.17.tgz",
"integrity": "sha512-IKQuK3bib/n032KWaSb8YlBFds+aLmzENtnKtxJy3+HqDq5kohu3g/UdNbIHeJWygfnEbZjnCKFxAW0y7ArZAw==",
"dev": true,
"requires": {
"compare-func": "^1.3.1",
"compare-func": "^2.0.0",
"conventional-commits-filter": "^2.0.6",
"dateformat": "^3.0.0",
"handlebars": "^4.7.6",
@@ -2168,12 +2195,12 @@
}
},
"dot-prop": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz",
"integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz",
"integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==",
"dev": true,
"requires": {
"is-obj": "^1.0.0"
"is-obj": "^2.0.0"
}
},
"dotignore": {
@@ -2255,9 +2282,9 @@
}
},
"elliptic": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz",
"integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==",
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
"integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
"requires": {
"bn.js": "^4.4.0",
"brorand": "^1.0.1",
@@ -4041,9 +4068,9 @@
"integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw=="
},
"is-obj": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
"integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
"dev": true
},
"is-plain-obj": {
@@ -5100,9 +5127,9 @@
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
},
"neo-async": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
"nerf-dart": {
@@ -5274,9 +5301,9 @@
"dev": true
},
"npm": {
"version": "6.14.6",
"resolved": "https://registry.npmjs.org/npm/-/npm-6.14.6.tgz",
"integrity": "sha512-axnz6iHFK6WPE0js/+mRp+4IOwpHn5tJEw5KB6FiCU764zmffrhsYHbSHi2kKqNkRBt53XasXjngZfBD3FQzrQ==",
"version": "6.14.7",
"resolved": "https://registry.npmjs.org/npm/-/npm-6.14.7.tgz",
"integrity": "sha512-swhsdpNpyXg4GbM6LpOQ6qaloQuIKizZ+Zh6JPXJQc59ka49100Js0WvZx594iaKSoFgkFq2s8uXFHS3/Xy2WQ==",
"dev": true,
"requires": {
"JSONStream": "^1.3.5",
@@ -5285,7 +5312,7 @@
"ansistyles": "~0.1.3",
"aproba": "^2.0.0",
"archy": "~1.0.0",
"bin-links": "^1.1.7",
"bin-links": "^1.1.8",
"bluebird": "^3.5.5",
"byte-size": "^5.0.1",
"cacache": "^12.0.3",
@@ -5306,7 +5333,7 @@
"find-npm-prefix": "^1.0.2",
"fs-vacuum": "~1.2.10",
"fs-write-stream-atomic": "~1.0.10",
"gentle-fs": "^2.3.0",
"gentle-fs": "^2.3.1",
"glob": "^7.1.6",
"graceful-fs": "^4.2.4",
"has-unicode": "~2.0.1",
@@ -5321,14 +5348,14 @@
"is-cidr": "^3.0.0",
"json-parse-better-errors": "^1.0.2",
"lazy-property": "~1.0.0",
"libcipm": "^4.0.7",
"libcipm": "^4.0.8",
"libnpm": "^3.0.1",
"libnpmaccess": "^3.0.2",
"libnpmhook": "^5.0.3",
"libnpmorg": "^1.0.1",
"libnpmsearch": "^2.0.2",
"libnpmteam": "^1.0.2",
"libnpx": "^10.2.2",
"libnpx": "^10.2.4",
"lock-verify": "^2.1.0",
"lockfile": "^1.0.4",
"lodash._baseindexof": "*",
@@ -5350,10 +5377,10 @@
"node-gyp": "^5.1.0",
"nopt": "^4.0.3",
"normalize-package-data": "^2.5.0",
"npm-audit-report": "^1.3.2",
"npm-audit-report": "^1.3.3",
"npm-cache-filename": "~1.0.2",
"npm-install-checks": "^3.0.2",
"npm-lifecycle": "^3.1.4",
"npm-lifecycle": "^3.1.5",
"npm-package-arg": "^6.1.1",
"npm-packlist": "^1.4.8",
"npm-pick-manifest": "^3.0.2",
@@ -5567,7 +5594,7 @@
}
},
"bin-links": {
"version": "1.1.7",
"version": "1.1.8",
"bundled": true,
"dev": true,
"requires": {
@@ -5722,26 +5749,41 @@
}
},
"cliui": {
"version": "4.1.0",
"version": "5.0.0",
"bundled": true,
"dev": true,
"requires": {
"string-width": "^2.1.1",
"strip-ansi": "^4.0.0",
"wrap-ansi": "^2.0.0"
"string-width": "^3.1.0",
"strip-ansi": "^5.2.0",
"wrap-ansi": "^5.1.0"
},
"dependencies": {
"ansi-regex": {
"version": "3.0.0",
"version": "4.1.0",
"bundled": true,
"dev": true
},
"strip-ansi": {
"version": "4.0.0",
"is-fullwidth-code-point": {
"version": "2.0.0",
"bundled": true,
"dev": true
},
"string-width": {
"version": "3.1.0",
"bundled": true,
"dev": true,
"requires": {
"ansi-regex": "^3.0.0"
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
}
},
"strip-ansi": {
"version": "5.2.0",
"bundled": true,
"dev": true,
"requires": {
"ansi-regex": "^4.1.0"
}
}
}
@@ -6103,6 +6145,11 @@
"bundled": true,
"dev": true
},
"emoji-regex": {
"version": "7.0.3",
"bundled": true,
"dev": true
},
"encoding": {
"version": "0.1.12",
"bundled": true,
@@ -6228,14 +6275,6 @@
"bundled": true,
"dev": true
},
"find-up": {
"version": "2.1.0",
"bundled": true,
"dev": true,
"requires": {
"locate-path": "^2.0.0"
}
},
"flush-write-stream": {
"version": "1.0.3",
"bundled": true,
@@ -6434,7 +6473,7 @@
"dev": true
},
"gentle-fs": {
"version": "2.3.0",
"version": "2.3.1",
"bundled": true,
"dev": true,
"requires": {
@@ -6464,7 +6503,7 @@
}
},
"get-caller-file": {
"version": "1.0.3",
"version": "2.0.5",
"bundled": true,
"dev": true
},
@@ -6688,11 +6727,6 @@
"validate-npm-package-name": "^3.0.0"
}
},
"invert-kv": {
"version": "2.0.0",
"bundled": true,
"dev": true
},
"ip": {
"version": "1.1.5",
"bundled": true,
@@ -6877,16 +6911,8 @@
"bundled": true,
"dev": true
},
"lcid": {
"version": "2.0.0",
"bundled": true,
"dev": true,
"requires": {
"invert-kv": "^2.0.0"
}
},
"libcipm": {
"version": "4.0.7",
"version": "4.0.8",
"bundled": true,
"dev": true,
"requires": {
@@ -6896,7 +6922,7 @@
"find-npm-prefix": "^1.0.2",
"graceful-fs": "^4.1.11",
"ini": "^1.3.5",
"lock-verify": "^2.0.2",
"lock-verify": "^2.1.0",
"mkdirp": "^0.5.1",
"npm-lifecycle": "^3.0.0",
"npm-logical-tree": "^1.2.1",
@@ -7055,7 +7081,7 @@
}
},
"libnpx": {
"version": "10.2.2",
"version": "10.2.4",
"bundled": true,
"dev": true,
"requires": {
@@ -7066,16 +7092,7 @@
"update-notifier": "^2.3.0",
"which": "^1.3.0",
"y18n": "^4.0.0",
"yargs": "^11.0.0"
}
},
"locate-path": {
"version": "2.0.0",
"bundled": true,
"dev": true,
"requires": {
"p-locate": "^2.0.0",
"path-exists": "^3.0.0"
"yargs": "^14.2.3"
}
},
"lock-verify": {
@@ -7206,36 +7223,11 @@
"ssri": "^6.0.0"
}
},
"map-age-cleaner": {
"version": "0.1.3",
"bundled": true,
"dev": true,
"requires": {
"p-defer": "^1.0.0"
}
},
"meant": {
"version": "1.0.1",
"bundled": true,
"dev": true
},
"mem": {
"version": "4.3.0",
"bundled": true,
"dev": true,
"requires": {
"map-age-cleaner": "^0.1.1",
"mimic-fn": "^2.0.0",
"p-is-promise": "^2.0.0"
},
"dependencies": {
"mimic-fn": {
"version": "2.1.0",
"bundled": true,
"dev": true
}
}
},
"mime-db": {
"version": "1.35.0",
"bundled": true,
@@ -7338,11 +7330,6 @@
"bundled": true,
"dev": true
},
"nice-try": {
"version": "1.0.5",
"bundled": true,
"dev": true
},
"node-fetch-npm": {
"version": "2.0.2",
"bundled": true,
@@ -7402,7 +7389,7 @@
}
},
"npm-audit-report": {
"version": "1.3.2",
"version": "1.3.3",
"bundled": true,
"dev": true,
"requires": {
@@ -7432,7 +7419,7 @@
}
},
"npm-lifecycle": {
"version": "3.1.4",
"version": "3.1.5",
"bundled": true,
"dev": true,
"requires": {
@@ -7589,44 +7576,6 @@
"bundled": true,
"dev": true
},
"os-locale": {
"version": "3.1.0",
"bundled": true,
"dev": true,
"requires": {
"execa": "^1.0.0",
"lcid": "^2.0.0",
"mem": "^4.0.0"
},
"dependencies": {
"cross-spawn": {
"version": "6.0.5",
"bundled": true,
"dev": true,
"requires": {
"nice-try": "^1.0.4",
"path-key": "^2.0.1",
"semver": "^5.5.0",
"shebang-command": "^1.2.0",
"which": "^1.2.9"
}
},
"execa": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"requires": {
"cross-spawn": "^6.0.0",
"get-stream": "^4.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
"signal-exit": "^3.0.0",
"strip-eof": "^1.0.0"
}
}
}
},
"os-tmpdir": {
"version": "1.0.2",
"bundled": true,
@@ -7641,42 +7590,11 @@
"os-tmpdir": "^1.0.0"
}
},
"p-defer": {
"version": "1.0.0",
"bundled": true,
"dev": true
},
"p-finally": {
"version": "1.0.0",
"bundled": true,
"dev": true
},
"p-is-promise": {
"version": "2.1.0",
"bundled": true,
"dev": true
},
"p-limit": {
"version": "1.2.0",
"bundled": true,
"dev": true,
"requires": {
"p-try": "^1.0.0"
}
},
"p-locate": {
"version": "2.0.0",
"bundled": true,
"dev": true,
"requires": {
"p-limit": "^1.1.0"
}
},
"p-try": {
"version": "1.0.0",
"bundled": true,
"dev": true
},
"package-json": {
"version": "4.0.1",
"bundled": true,
@@ -8073,7 +7991,7 @@
"dev": true
},
"require-main-filename": {
"version": "1.0.1",
"version": "2.0.0",
"bundled": true,
"dev": true
},
@@ -8723,22 +8641,41 @@
}
},
"wrap-ansi": {
"version": "2.1.0",
"version": "5.1.0",
"bundled": true,
"dev": true,
"requires": {
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1"
"ansi-styles": "^3.2.0",
"string-width": "^3.0.0",
"strip-ansi": "^5.0.0"
},
"dependencies": {
"ansi-regex": {
"version": "4.1.0",
"bundled": true,
"dev": true
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"bundled": true,
"dev": true
},
"string-width": {
"version": "1.0.2",
"version": "3.1.0",
"bundled": true,
"dev": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
}
},
"strip-ansi": {
"version": "5.2.0",
"bundled": true,
"dev": true,
"requires": {
"ansi-regex": "^4.1.0"
}
}
}
@@ -8779,37 +8716,105 @@
"dev": true
},
"yargs": {
"version": "11.1.1",
"version": "14.2.3",
"bundled": true,
"dev": true,
"requires": {
"cliui": "^4.0.0",
"decamelize": "^1.1.1",
"find-up": "^2.1.0",
"get-caller-file": "^1.0.1",
"os-locale": "^3.1.0",
"cliui": "^5.0.0",
"decamelize": "^1.2.0",
"find-up": "^3.0.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^1.0.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^2.0.0",
"string-width": "^3.0.0",
"which-module": "^2.0.0",
"y18n": "^3.2.1",
"yargs-parser": "^9.0.2"
"y18n": "^4.0.0",
"yargs-parser": "^15.0.1"
},
"dependencies": {
"y18n": {
"version": "3.2.1",
"ansi-regex": {
"version": "4.1.0",
"bundled": true,
"dev": true
},
"find-up": {
"version": "3.0.0",
"bundled": true,
"dev": true,
"requires": {
"locate-path": "^3.0.0"
}
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"bundled": true,
"dev": true
},
"locate-path": {
"version": "3.0.0",
"bundled": true,
"dev": true,
"requires": {
"p-locate": "^3.0.0",
"path-exists": "^3.0.0"
}
},
"p-limit": {
"version": "2.3.0",
"bundled": true,
"dev": true,
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": {
"version": "3.0.0",
"bundled": true,
"dev": true,
"requires": {
"p-limit": "^2.0.0"
}
},
"p-try": {
"version": "2.2.0",
"bundled": true,
"dev": true
},
"string-width": {
"version": "3.1.0",
"bundled": true,
"dev": true,
"requires": {
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
}
},
"strip-ansi": {
"version": "5.2.0",
"bundled": true,
"dev": true,
"requires": {
"ansi-regex": "^4.1.0"
}
}
}
},
"yargs-parser": {
"version": "9.0.2",
"version": "15.0.1",
"bundled": true,
"dev": true,
"requires": {
"camelcase": "^4.1.0"
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
},
"dependencies": {
"camelcase": {
"version": "5.3.1",
"bundled": true,
"dev": true
}
}
}
}
@@ -11481,23 +11486,11 @@
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
},
"uglify-js": {
"version": "3.9.4",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.9.4.tgz",
"integrity": "sha512-8RZBJq5smLOa7KslsNsVcSH+KOXf1uDU8yqLeNuVKwmT0T3FA0ZoXlinQfRad7SDcbZZRZE4ov+2v71EnxNyCA==",
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.0.tgz",
"integrity": "sha512-Esj5HG5WAyrLIdYU74Z3JdG2PxdIusvj6IWHMtlyESxc7kcDz7zYlYjpnSokn1UbpV0d/QX9fan7gkCNd/9BQA==",
"dev": true,
"optional": true,
"requires": {
"commander": "~2.20.3"
},
"dependencies": {
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true,
"optional": true
}
}
"optional": true
},
"uniq": {
"version": "1.0.1",
+1 -1
View File
@@ -15,7 +15,7 @@
"test:integration:testnet:local": "RESTURL=http://localhost:4000/v3/ mocha --timeout 30000 test/integration/testnet",
"test:integration:free": "bash test/integration/test-free-tier.sh",
"test:integration:free:testnet": "bash test/integration/testnet/test-free-tier.sh",
"test:temp": "nyc mocha --timeout 30000 test/unit/ipfs.js",
"test:temp": "mocha --timeout 30000 test/integration/testnet/ninsight.js",
"test:integration:api": "RESTURL=https://api.fullstack.cash/v3/ mocha --timeout 30000 test/integration",
"coverage": "nyc report --reporter=text-lcov | coveralls",
"coverage:report": "nyc --reporter=html mocha --timeout 25000 test/unit/",
+1 -1
View File
@@ -69,7 +69,7 @@ class BCHJS {
this.OpenBazaar = new OpenBazaar(libConfig)
// Bitcoin.com Ninsight indexer
this.Ninsight = new Ninsight()
this.Ninsight = new Ninsight(config)
// ElectrumX indexer
this.Electrumx = new Electrumx(libConfig)
+95 -3
View File
@@ -24,7 +24,7 @@ class ElectrumX {
}
/**
* @api Electrumx.utxo() utxo() - Get a list of uxto for an address.
* @api Electrumx.utxo() utxo()
* @apiName ElectrumX Utxo
* @apiGroup ElectrumX
* @apiDescription Return a list of uxtos for an address.
@@ -119,7 +119,7 @@ class ElectrumX {
}
/**
* @api Electrumx.balance() balance() - Get the balance for an address.
* @api Electrumx.balance() balance()
* @apiName ElectrumX Balance
* @apiGroup ElectrumX
* @apiDescription Return a list of balances for an address.
@@ -203,7 +203,7 @@ class ElectrumX {
}
/**
* @api Electrumx.transactions() transactions() - Get the transaction history for an address.
* @api Electrumx.transactions() transactions()
* @apiName ElectrumX Transactions
* @apiGroup ElectrumX
* @apiDescription Return a transaction history for an address.
@@ -299,6 +299,98 @@ class ElectrumX {
else throw error
}
}
/**
* @api Electrumx.unconfirmed() unconfirmed()
* @apiName ElectrumX Unconfirmed
* @apiGroup ElectrumX
* @apiDescription Return a list of unconfirmed uxtos (mempool) for an address.
*
* @apiExample Example usage:
* (async () => {
* try {
* let mempool = await bchjs.Electrumx.unconfirmed('bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9');
* console.log(mempool);
* } catch(error) {
* console.error(error)
* }
* })()
*
* mempool = {
* "success": true,
* "utxos": [
* {
* "height": 602405,
* "tx_hash": "2b37bdb3b63dd0bca720437754a36671431a950e684b64c44ea910ea9d5297c7",
* "fee": 24310
* }
* ]
* }
*
* (async () => {
* try {
* let mempool = await bchjs.Electrumx.unconfirmed(['bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf', 'bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v']);
* console.log(mempool);
* } catch(error) {
* console.error(error)
* }
* })()
*
* mempool = {
* "success": true,
* "utxos": [
* {
* "utxos": [
* {
* "height": 604392,
* "tx_hash": "7774e449c5a3065144cefbc4c0c21e6b69c987f095856778ef9f45ddd8ae1a41",
* "fee": 24310
* },
* {
* "height": 630834,
* "tx_hash": "4fe60a51e0d8f5134bfd8e5f872d6e502d7f01b28a6afebb27f4438a4f638d53",
* "fee": 3000
* }
* ],
* "address": "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf"
* },
* {
* "utxos": [],
* "address": "bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v"
* }
* ]
* }
*
*/
async unconfirmed(address) {
try {
// Handle single address.
if (typeof address === "string") {
const response = await axios.get(
`${this.restURL}electrumx/unconfirmed/${address}`,
_this.axiosOptions
)
return response.data
// Handle array of addresses.
} else if (Array.isArray(address)) {
const response = await axios.post(
`${this.restURL}electrumx/unconfirmed`,
{
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
}
}
}
module.exports = ElectrumX
+176 -7
View File
@@ -53,8 +53,8 @@ class IPFS {
}
/**
* @api IPFS.createFileModel() createFileModel() - Create a file model
* @apiName createFileModel()
* @api IPFS.createFileModelServer() createFileModelServer() - Create a file model
* @apiName createFileModelServer()
* @apiGroup IPFS
* @apiDescription Creates a new model on the server. If successful, will
* return an object with file data. That object contains a BCH address,
@@ -64,7 +64,7 @@ class IPFS {
* (async () => {
* try {
* const path = `${__dirname}/ipfs.js`
* let fileData = await bchjs.IPFS.uploadFile(path);
* let fileData = await bchjs.IPFS.createFileModelServer(path);
* console.log(fileData);
* } catch(error) {
* console.error(error)
@@ -90,7 +90,7 @@ class IPFS {
* "__v": 0
* }
*/
async createFileModel(path) {
async createFileModelServer(path) {
try {
// Ensure the file exists.
if (!_this.fs.existsSync(path))
@@ -131,7 +131,7 @@ class IPFS {
}
/**
* @api IPFS.uploadFile() uploadFile() - Upload a file to IPFS
* @api IPFS.uploadFileServer() uploadFileServer() - Upload a file to IPFS
* @apiName uploadFile()
* @apiGroup IPFS
* @apiDescription Upload a file to the FullStack.cash IPFS server. If
@@ -142,7 +142,7 @@ class IPFS {
* (async () => {
* try {
* const path = `${__dirname}/ipfs.js`
* let fileData = await bchjs.IPFS.uploadFile(path, "5ec562319bfacc745e8d8a52");
* let fileData = await bchjs.IPFS.uploadFileServer(path, "5ec562319bfacc745e8d8a52");
* console.log(fileData);
* } catch(error) {
* console.error(error)
@@ -157,7 +157,7 @@ class IPFS {
* "fileExtension": "js"
* }
*/
async uploadFile(path, modelId) {
async uploadFileServer(path, modelId) {
try {
// Ensure the file exists.
if (!_this.fs.existsSync(path))
@@ -270,6 +270,175 @@ class IPFS {
throw err
}
}
/**
* @api IPFS.createFileModelWeb() createFileModelWeb() - Create a file model
* @apiName createFileModelWeb()
* @apiGroup IPFS
* @apiDescription Creates a new model on the server. If successful, will
* return an object with file data. That object contains a BCH address,
* payment amount, and _id required to be able to upload a file.
*
* @apiExample Example usage:
* (async () => {
* try {
* const content = ['PSF']
* const name = 'psf.txt' // Content can be Array , ArrayBuffer , Blob
* const options = { type: "text/plain" }
* const file = new File(content,name,options)
* let fileData = await bchjs.IPFS.createFileModelWeb(file);
* console.log(fileData);
* } catch(error) {
* console.error(error)
* }
* })()
*
* {
* "success": true,
* "hostingCostBCH": 0.00004197,
* "hostingCostUSD": 0.01,
* "file": {
* "payloadLink": "",
* "hasBeenPaid": false,
* "_id": "5ec562319bfacc745e8d8a52",
* "schemaVersion": 1,
* "size": 4458,
* "fileName": "ipfs.js",
* "fileExtension": "js",
* "createdTimestamp": "1589994033.655",
* "hostingCost": 4196,
* "walletIndex": 49,
* "bchAddr": "bchtest:qzrpkevu7h2ayfa4rjx08r5elvpfu72dg567x3mh3c",
* "__v": 0
* }
*/
async createFileModelWeb(file) {
try {
if (!file) throw new Error(`File is required`)
const { name, size } = file
if (!name || typeof name !== "string")
throw new Error(`File should have the property 'name' of string type`)
if (!size || typeof size !== "number")
throw new Error(`File should have the property 'size' of number type`)
// Get the file extension.
const splitExt = name.split(".")
const fileExt = splitExt[splitExt.length - 1]
const fileObj = {
schemaVersion: 1,
size: size,
fileName: name,
fileExtension: fileExt
}
// console.log(`fileObj: ${JSON.stringify(fileObj, null, 2)}`)
const fileData = await _this.axios.post(`${this.IPFS_API}/files`, {
file: fileObj
})
// console.log(`fileData.data: ${JSON.stringify(fileData.data, null, 2)}`)
return fileData.data
} catch (err) {
console.error(`Error in createFileModelWeb()`)
throw err
}
}
/**
* @api IPFS.uploadFileWeb() uploadFileWeb() - Upload a file to IPFS
* @apiName uploadFileWeb()
* @apiGroup IPFS
* @apiDescription Upload a file to the FullStack.cash IPFS server. If
* successful, it will return an object with an ID, a BCH address, and an
* amount of BCH to pay.
*
* @apiExample Example usage:
* (async () => {
* try {
* * const content = ['PSF']
* const name = 'psf.txt' // Content can be Array , ArrayBuffer , Blob
* const options = { type: "text/plain" }
* const file = new File(content,name,options)
* let fileData = await bchjs.IPFS.uploadFile(file, "5ec562319bfacc745e8d8a52");
* console.log(fileData);
* } catch(error) {
* console.error(error)
* }
* })()
*
* {
* "schemaVersion": 1,
* "size": 2374,
* "fileId": "5ec562319bfacc745e8d8a52",
* "fileName": "ipfs.js",
* "fileExtension": "js"
* }
*/
async uploadFileWeb(file, modelId) {
try {
if (!file) throw new Error(`File is required`)
const { name, type, size } = file
if (!name || typeof name !== "string")
throw new Error(`File should have the property 'name' of string type`)
if (!type || typeof type !== "string")
throw new Error(`File should have the property 'type' of string type`)
if (!size || typeof size !== "number")
throw new Error(`File should have the property 'size' of number type`)
if (!modelId) {
throw new Error(
`Must include a file model ID in order to upload a file.`
)
}
// Prepare the upload object. Get a file ID from Uppy.
const id = _this.uppy.addFile({
name: name,
data: file,
source: "Local",
isRemote: false
})
// console.log(`id: ${JSON.stringify(id, null, 2)}`)
// Add the model ID, required to be allowed to upload the file.
_this.uppy.setFileMeta(id, { fileModelId: modelId })
// Upload the file to the server.
const upData = await _this.uppy.upload()
if (upData.failed.length)
throw new Error("The file could not be uploaded")
if (upData.successful.length) {
delete upData.successful[0].data
// console.log(`upData: ${JSON.stringify(upData, null, 2)}`)
const fileObj = {
schemaVersion: 1,
size: upData.successful[0].progress.bytesTotal,
fileId: upData.successful[0].meta.fileModelId,
fileName: upData.successful[0].name,
fileExtension: upData.successful[0].extension
}
// console.log(`fileObj: ${JSON.stringify(fileObj, null, 2)}`)
return fileObj
// return true
}
return false
} catch (err) {
console.error(`Error in bch-js/src/ipfs.js/uploadFileWeb(): `)
throw err
}
}
}
module.exports = IPFS
+28 -8
View File
@@ -13,7 +13,11 @@ class Ninsight {
// this.apiToken = config.apiToken
// this.ninsightURL = `https://bch-explorer.api.bitcoin.com/v1/`
this.ninsightURL = `https://rest.bitcoin.com/v2`
if (config) {
this.ninsightURL = config.ninsightURL
? config.ninsightURL
: `https://rest.bitcoin.com/v2`
}
// Add JWT token to the authorization header.
this.axiosOptions = {
@@ -62,15 +66,31 @@ class Ninsight {
*/
async utxo(address) {
try {
if (typeof address !== "string")
throw new Error(`address needs to be a string.`)
// Handle single address.
if (typeof address === "string") {
const response = await axios.post(
`${this.ninsightURL}/address/utxo/${address}`,
{
addresses: [address]
},
_this.axiosOptions
)
return response.data
const response = await axios.get(
`${this.ninsightURL}/address/utxo/${address}`,
_this.axiosOptions
)
// Handle array of addresses.
} else if (Array.isArray(address)) {
const response = await axios.post(
`${this.ninsightURL}/address/utxo`,
{
addresses: address
},
_this.axiosOptions
)
return response.data
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
-78
View File
@@ -370,84 +370,6 @@ class Utils {
}
}
/**
* @api SLP.Utils.balance() balance()
* @apiName balance
* @apiGroup SLP Utils
* @apiDescription Return single balance for an address by token id.
*
* @apiExample Example usage:
*
* // single balance for SLP Address
* (async () => {
* try {
* let balance = await bchjs.SLP.Utils.balance(
* "simpleledger:qr5agtachyxvrwxu76vzszan5pnvuzy8duhv4lxrsk",
* "df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb"
* );
* console.log(balance);
* } catch (error) {
* console.error(error);
* }
* })();
*
* // returns
* // { tokenId:
* // 'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb',
* // balance: '617',
* // decimalCount: 8 }
*
* // single balance for Cash Address
* (async () => {
* try {
* let balance = await bchjs.SLP.Utils.balance(
* "bitcoincash:qr5agtachyxvrwxu76vzszan5pnvuzy8dumh7ynrwg",
* "df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb"
* );
* console.log(balance);
* } catch (error) {
* console.error(error);
* }
* })();
*
* // returns
* // { tokenId:
* // 'df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb',
* // balance: '617',
* // decimalCount: 8 }
*
* // single balance for Legacy Address
* (async () => {
* try {
* let balance = await bchjs.SLP.Utils.balance(
* "1DwQqpWc8pzaRydCmiJsPdoqCzmjSQQbp8",
* "467969e067f5612863d0bf2daaa70dede2c6be03abb6fd401c5ef6e1e1f1f5c5"
* );
* console.log(balance);
* } catch (error) {
* console.error(error);
* }
* })();
*
* // returns
* // { tokenId:
* // '467969e067f5612863d0bf2daaa70dede2c6be03abb6fd401c5ef6e1e1f1f5c5',
* // balance: '1234',
* // decimalCount: 2 }
*/
// Retrieve a balance for a specific address and token ID
async balance(address, tokenId) {
const path = `${this.restURL}slp/balance/${address}/${tokenId}`
try {
const response = await axios.get(path, _this.axiosOptions)
return response.data
} catch (error) {
if (error.response && error.response.data) throw error.response.data
throw error
}
}
/**
* @api SLP.Utils.validateTxid() validateTxid()
* @apiName validateTxid
+62
View File
@@ -178,4 +178,66 @@ describe(`#ElectrumX`, () => {
}
})
})
describe(`#unconfirmed`, () => {
// These tests won't work because unconfirmed transactions are transient in nature.
/*
it(`should GET unconfirmed UTXOs (mempool) for a single address`, async () => {
const addr = "bitcoincash:qqy6qwk3wpne95hhv8uzwr4cn8m7c06cqgchl77dnv"
const result = await bchjs.Electrumx.unconfirmed(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, "success")
assert.equal(result.success, true)
assert.property(result, "utxos")
assert.isArray(result.utxos)
assert.property(result.utxos[0], "height")
assert.property(result.utxos[0], "tx_hash")
assert.property(result.utxos[0], "fee")
})
it(`should POST request for unconfirmed UTXOs (mempool) for an array of addresses`, async () => {
const addr = [
"bitcoincash:qqy6qwk3wpne95hhv8uzwr4cn8m7c06cqgchl77dnv",
"bitcoincash:qpyrtsl9msdu2klgfpcmn2v5r22w9rk24g8pal74ts"
]
const result = await bchjs.Electrumx.unconfirmed(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, "success")
assert.equal(result.success, true)
assert.property(result, "utxos")
assert.isArray(result.utxos)
assert.property(result.utxos[0], "utxos")
assert.isArray(result.utxos[0].utxos)
assert.property(result.utxos[0], "address")
assert.property(result.utxos[0].utxos[0], "height")
assert.property(result.utxos[0].utxos[0], "tx_hash")
assert.property(result.utxos[0].utxos[0], "fee")
})
*/
it(`should throw error on array size rate limit`, async () => {
try {
const addr = []
for (let i = 0; i < 25; i++)
addr.push("bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf")
await bchjs.Electrumx.unconfirmed(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")
}
})
})
})
+21 -1
View File
@@ -3,7 +3,7 @@ const assert = chai.assert
const sinon = require("sinon")
const BCHJS = require("../../src/bch-js")
const bchjs = new BCHJS()
const bchjs = new BCHJS({ ninsightURL: "https://rest.bitcoin.com/v2" })
describe(`#Ninsight`, () => {
let sandbox
@@ -33,5 +33,25 @@ describe(`#Ninsight`, () => {
assert.property(result.utxos[0], "height")
assert.property(result.utxos[0], "confirmations")
})
it(`should POST utxo details for an array of addresses`, async () => {
const addr = [
"bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7",
"bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr"
]
const result = await bchjs.Ninsight.utxo(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.isArray(result[0].utxos)
assert.property(result[0], "utxos")
assert.property(result[0], "legacyAddress")
assert.property(result[0], "cashAddress")
assert.property(result[0], "slpAddress")
assert.property(result[0], "scriptPubKey")
assert.property(result[0], "asm")
})
})
})
+62
View File
@@ -182,4 +182,66 @@ describe(`#ElectrumX`, () => {
}
})
})
describe(`#unconfirmed`, () => {
// These tests won't work because unconfirmed transactions are transient in nature.
/*
it(`should GET unconfirmed UTXOs (mempool) for a single address`, async () => {
const addr = "bchtest:qp25k20dgcljrz4hkdz43partam3j5httyprjp23qd"
const result = await bchjs.Electrumx.unconfirmed(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, "success")
assert.equal(result.success, true)
assert.property(result, "utxos")
assert.isArray(result.utxos)
assert.property(result.utxos[0], "height")
assert.property(result.utxos[0], "tx_hash")
assert.property(result.utxos[0], "fee")
})
it(`should POST unconfirmed UTXO details for an array of addresses`, async () => {
const addr = [
"bchtest:qp25k20dgcljrz4hkdz43partam3j5httyprjp23qd",
"bchtest:qpkl3xylrjx4jup6m66e7zg7whlaucsxeudxeqawdj"
]
const result = await bchjs.Electrumx.unconfirmed(addr)
//console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, "success")
assert.equal(result.success, true)
assert.property(result, "utxos")
assert.isArray(result.utxos)
assert.property(result.utxos[0], "utxos")
assert.isArray(result.utxos[0].utxos)
assert.property(result.utxos[0], "address")
assert.property(result.utxos[0].utxos[0], "height")
assert.property(result.utxos[0].utxos[0], "tx_hash")
assert.property(result.utxos[0].utxos[0], "fee")
})
*/
it(`should throw error on array size rate limit`, async () => {
try {
const addr = []
for (let i = 0; i < 25; i++)
addr.push("bchtest:qrvn2n228aa39xupcw9jw0d3fj8axxky656e4j62z2")
await bchjs.Electrumx.unconfirmed(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")
}
})
})
})
+65
View File
@@ -0,0 +1,65 @@
const chai = require("chai")
const assert = chai.assert
const sinon = require("sinon")
const BCHJS = require("../../../src/bch-js")
const bchjs = new BCHJS({ ninsightURL: "https://trest.bitcoin.com/v2" })
describe(`#Ninsight`, () => {
let sandbox
beforeEach(() => (sandbox = sinon.createSandbox()))
afterEach(() => sandbox.restore())
describe(`#utxo`, () => {
it(`should GET utxos for a single address`, async () => {
const addr = "bchtest:qzjtnzcvzxx7s0na88yrg3zl28wwvfp97538sgrrmr"
const result = await bchjs.Ninsight.utxo(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, "utxos")
assert.property(result, "legacyAddress")
assert.property(result, "cashAddress")
assert.property(result, "slpAddress")
assert.property(result, "scriptPubKey")
assert.property(result, "asm")
assert.isArray(result.utxos)
assert.property(result.utxos[0], "txid")
assert.property(result.utxos[0], "vout")
assert.property(result.utxos[0], "amount")
assert.property(result.utxos[0], "satoshis")
assert.property(result.utxos[0], "height")
assert.property(result.utxos[0], "confirmations")
})
it(`should POST utxo details for an array of addresses`, async () => {
const addr = [
"bchtest:qzjtnzcvzxx7s0na88yrg3zl28wwvfp97538sgrrmr",
"bchtest:qp6hgvevf4gzz6l7pgcte3gaaud9km0l459fa23dul"
]
const result = await bchjs.Ninsight.utxo(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.isArray(result[0].utxos)
assert.property(result[0], "utxos")
assert.property(result[0], "legacyAddress")
assert.property(result[0], "cashAddress")
assert.property(result[0], "slpAddress")
assert.property(result[0], "scriptPubKey")
assert.property(result[0], "asm")
// assert.hasAnyKeys(result[0][0], [
// "txid",
// "vout",
// "value",
// "height",
// "confirmations"
// ])
})
})
})
@@ -6,3 +6,4 @@ export NETWORK=testnet
cd test/integration/testnet/
mocha --timeout 30000 blockchain.js control.js electrumx.js openbazaar.js rawtransaction.js slp.js util.js
#mocha --timeout 30000 blockchain.js
+64
View File
@@ -196,4 +196,68 @@ describe(`#ElectrumX`, () => {
assert.property(result.transactions[0].transactions[0], "tx_hash")
})
})
describe(`#unconfirmed`, () => {
it(`should throw an error for improper input`, async () => {
try {
const addr = 12345
await bchjs.Electrumx.unconfirmed(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 GET unconfirmed utxos for a single address`, async () => {
// Stub the network call.
sandbox.stub(axios, "get").resolves({ data: mockData.unconfirmed })
const addr = "bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9"
const result = await bchjs.Electrumx.unconfirmed(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, "success")
assert.equal(result.success, true)
assert.property(result, "utxos")
assert.isArray(result.utxos)
assert.property(result.utxos[0], "height")
assert.property(result.utxos[0], "tx_hash")
assert.property(result.utxos[0], "fee")
})
it(`should POST unconfirmed utxo details for an array of addresses`, async () => {
// Stub the network call.
sandbox.stub(axios, "post").resolves({ data: mockData.unconfirmedArray })
const addr = [
"bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf",
"bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v"
]
const result = await bchjs.Electrumx.unconfirmed(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, "success")
assert.equal(result.success, true)
assert.property(result, "utxos")
assert.isArray(result.utxos)
assert.property(result.utxos[0], "utxos")
assert.isArray(result.utxos[0].utxos)
assert.property(result.utxos[0], "address")
assert.property(result.utxos[0].utxos[0], "height")
assert.property(result.utxos[0].utxos[0], "tx_hash")
assert.property(result.utxos[0].utxos[0], "fee")
})
})
})
+42 -1
View File
@@ -119,11 +119,52 @@ const transactions = {
]
}
const unconfirmed = {
success: true,
utxos: [
{
height: 602405,
tx_hash:
"2b37bdb3b63dd0bca720437754a36671431a950e684b64c44ea910ea9d5297c7",
fee: 34100
}
]
}
const unconfirmedArray = {
success: true,
utxos: [
{
utxos: [
{
height: 604392,
tx_hash:
"7774e449c5a3065144cefbc4c0c21e6b69c987f095856778ef9f45ddd8ae1a41",
fee: 34210
},
{
height: 630834,
tx_hash:
"4fe60a51e0d8f5134bfd8e5f872d6e502d7f01b28a6afebb27f4438a4f638d53",
value: 3000
}
],
address: "bitcoincash:qrdka2205f4hyukutc2g0s6lykperc8nsu5u2ddpqf"
},
{
utxos: [],
address: "bitcoincash:qpdh9s677ya8tnx7zdhfrn8qfyvy22wj4qa7nwqa5v"
}
]
}
module.exports = {
utxo,
utxos,
balance,
balances,
transaction,
transactions
transactions,
unconfirmed,
unconfirmedArray
}
+4 -1
View File
@@ -21,6 +21,9 @@ const utxo = {
"OP_DUP OP_HASH160 2fe2c4c5ef359bb2fe1a849f891cecffbcfb4f77 OP_EQUALVERIFY OP_CHECKSIG"
}
const utxoPost = [utxo, utxo]
module.exports = {
utxo
utxo,
utxoPost
}
+257 -9
View File
@@ -4,7 +4,6 @@
const assert = require("chai").assert
const sinon = require("sinon")
const BCHJS = require("../../src/bch-js")
let bchjs
@@ -27,12 +26,12 @@ describe(`#IPFS`, () => {
})
})
describe("#createFileModel", () => {
describe("#createFileModelServer", () => {
it("should throw an error if file does not exist", async () => {
try {
const path = "/non-existant-file"
await bchjs.IPFS.createFileModel(path)
await bchjs.IPFS.createFileModelServer(path)
assert.equal(true, false, "Unexpected result")
} catch (err) {
@@ -48,7 +47,7 @@ describe(`#IPFS`, () => {
.stub(bchjs.IPFS.axios, "post")
.resolves({ data: mockData.mockNewFileModel })
const result = await bchjs.IPFS.createFileModel(path)
const result = await bchjs.IPFS.createFileModelServer(path)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, "success")
@@ -72,12 +71,12 @@ describe(`#IPFS`, () => {
})
})
describe("#uploadFile", () => {
describe("#uploadFileServer", () => {
it("should throw an error if file does not exist", async () => {
try {
const path = "/non-existant-file"
await bchjs.IPFS.uploadFile(path)
await bchjs.IPFS.uploadFileServer(path)
assert.equal(true, false, "Unexpected result")
} catch (err) {
@@ -90,7 +89,7 @@ describe(`#IPFS`, () => {
try {
const path = `${__dirname}/ipfs.js`
await bchjs.IPFS.uploadFile(path)
await bchjs.IPFS.uploadFileServer(path)
assert.equal(true, false, "Unexpected result")
} catch (err) {
@@ -112,7 +111,7 @@ describe(`#IPFS`, () => {
sandbox.stub(bchjs.IPFS.uppy, "upload").resolves(mock)
const path = `${__dirname}/ipfs.js`
await bchjs.IPFS.uploadFile(path, "5ec562319bfacc745e8d8a52")
await bchjs.IPFS.uploadFileServer(path, "5ec562319bfacc745e8d8a52")
assert.equal(true, false, "Unexpected result")
} catch (err) {
@@ -126,7 +125,7 @@ describe(`#IPFS`, () => {
sandbox.stub(bchjs.IPFS.uppy, "upload").resolves(mockData.uploadData)
const path = `${__dirname}/ipfs.js`
const result = await bchjs.IPFS.uploadFile(
const result = await bchjs.IPFS.uploadFileServer(
path,
"5ec562319bfacc745e8d8a52"
)
@@ -192,4 +191,253 @@ describe(`#IPFS`, () => {
assert.property(result, "fileName")
})
})
describe("#createFileModelWeb", () => {
it("should throw an error if file is undefined", async () => {
try {
let file
await bchjs.IPFS.createFileModelWeb(file)
assert.equal(true, false, "Unexpected result")
} catch (err) {
//console.log(`err.message: ${err.message}`)
assert.include(err.message, `File is required`)
}
})
it("should throw an error if file is empty", async () => {
try {
const file = {}
await bchjs.IPFS.createFileModelWeb(file)
assert.equal(true, false, "Unexpected result")
} catch (err) {
//console.log(`err.message: ${err.message}`)
assert.include(
err.message,
`File should have the property 'name' of string type`
)
}
})
it("should throw an error if 'name' property is not included", async () => {
try {
const file = {
size: 5000
}
await bchjs.IPFS.createFileModelWeb(file)
assert.equal(true, false, "Unexpected result")
} catch (err) {
//console.log(`err.message: ${err.message}`)
assert.include(
err.message,
`File should have the property 'name' of string type`
)
}
})
it("should throw an error if 'size' property is not included", async () => {
try {
const file = {
name: "ipfs.js"
}
await bchjs.IPFS.createFileModelWeb(file)
assert.equal(true, false, "Unexpected result")
} catch (err) {
//console.log(`err.message: ${err.message}`)
assert.include(
err.message,
`File should have the property 'size' of number type`
)
}
})
it("should create a new file model", async () => {
const file = {
name: "ipfs.js",
size: 5000,
type: "text/plain"
}
sandbox
.stub(bchjs.IPFS.axios, "post")
.resolves({ data: mockData.mockNewFileModel })
const result = await bchjs.IPFS.createFileModelWeb(file)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, "success")
assert.equal(result.success, true)
assert.property(result, "hostingCostBCH")
assert.property(result, "hostingCostUSD")
assert.property(result, "file")
assert.property(result.file, "payloadLink")
assert.property(result.file, "hasBeenPaid")
assert.property(result.file, "_id")
assert.property(result.file, "schemaVersion")
assert.property(result.file, "size")
assert.property(result.file, "fileName")
assert.property(result.file, "fileExtension")
assert.property(result.file, "createdTimestamp")
assert.property(result.file, "hostingCost")
assert.property(result.file, "walletIndex")
assert.property(result.file, "bchAddr")
})
})
describe("#uploadFileWeb", () => {
it("should throw an error if file is undefined", async () => {
try {
let file
await bchjs.IPFS.uploadFileWeb(file)
assert.equal(true, false, "Unexpected result")
} catch (err) {
//console.log(`err.message: ${err.message}`)
assert.include(err.message, `File is required`)
}
})
it("should throw an error if file is empty", async () => {
try {
const file = {}
await bchjs.IPFS.uploadFileWeb(file)
assert.equal(true, false, "Unexpected result")
} catch (err) {
//console.log(`err.message: ${err.message}`)
assert.include(
err.message,
`File should have the property 'name' of string type`
)
}
})
it("should throw an error if 'name' property is not included", async () => {
try {
const file = {
size: 5000,
type: "text/plain"
}
await bchjs.IPFS.uploadFileWeb(file)
assert.equal(true, false, "Unexpected result")
} catch (err) {
//console.log(`err.message: ${err.message}`)
assert.include(
err.message,
`File should have the property 'name' of string type`
)
}
})
it("should throw an error if 'size' property is not included", async () => {
try {
const file = {
name: "ipfs.js",
type: "text/plain"
}
await bchjs.IPFS.uploadFileWeb(file)
assert.equal(true, false, "Unexpected result")
} catch (err) {
//console.log(`err.message: ${err.message}`)
assert.include(
err.message,
`File should have the property 'size' of number type`
)
}
})
it("should throw an error if 'type' property is not included", async () => {
try {
const file = {
name: "ipfs.js",
size: 5000
}
await bchjs.IPFS.uploadFileWeb(file)
assert.equal(true, false, "Unexpected result")
} catch (err) {
//console.log(`err.message: ${err.message}`)
assert.include(
err.message,
`File should have the property 'type' of string type`
)
}
})
it("should throw an error if modelId is not included", async () => {
try {
const file = {
name: "ipfs.js",
size: 5000,
type: "text/plain"
}
await bchjs.IPFS.uploadFileWeb(file)
assert.equal(true, false, "Unexpected result")
} catch (err) {
//console.log(`err.message: ${err.message}`)
assert.include(err.message, `Must include a file model ID`)
}
})
it("Should throw error if the file was not uploaded", async () => {
try {
const mock = {
successful: [],
failed: [
{
id: "file id"
}
]
}
sandbox.stub(bchjs.IPFS.uppy, "upload").resolves(mock)
const file = {
name: "ipfs.js",
size: 5000,
type: "text/plain"
}
await bchjs.IPFS.uploadFileWeb(file, "5ec562319bfacc745e8d8a52")
assert.equal(true, false, "Unexpected result")
} catch (err) {
//console.log(err)
assert.include(err.message, `The file could not be uploaded`)
}
})
it("should return file object if the file is uploaded", async () => {
try {
sandbox.stub(bchjs.IPFS.uppy, "upload").resolves(mockData.uploadData)
const file = {
name: "ipfs.js",
size: 5000,
type: "text/plain"
}
const result = await bchjs.IPFS.uploadFileWeb(
file,
"5ec562319bfacc745e8d8a52"
)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.property(result, "schemaVersion")
assert.property(result, "size")
assert.property(result, "fileId")
assert.property(result, "fileName")
assert.property(result, "fileExtension")
} catch (err) {
//console.log(err)
assert.equal(true, false, "Unexpected result")
}
})
})
})
+28 -2
View File
@@ -22,13 +22,16 @@ describe(`#Ninsight`, () => {
assert.equal(true, false, "Unexpected result!")
} catch (err) {
//console.log(`err: `, err)
assert.include(err.message, `address needs to be a string`)
assert.include(
err.message,
`Input address must be a string or array of strings.`
)
}
})
it(`should GET utxos for a single address`, async () => {
// Stub the network call.
sandbox.stub(axios, "get").resolves({ data: mockData.utxo })
sandbox.stub(axios, "post").resolves({ data: mockData.utxo })
const addr = "bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9"
@@ -51,5 +54,28 @@ describe(`#Ninsight`, () => {
assert.property(result.utxos[0], "height")
assert.property(result.utxos[0], "confirmations")
})
it(`should POST utxo details for an array of addresses`, async () => {
// Mock the network call.
sandbox.stub(axios, "post").resolves({ data: mockData.utxoPost })
const addr = [
"bitcoincash:qp3sn6vlwz28ntmf3wmyra7jqttfx7z6zgtkygjhc7",
"bitcoincash:qz0us0z6ucpqt07jgpad0shgh7xmwxyr3ynlcsq0wr"
]
const result = await bchjs.Ninsight.utxo(addr)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
assert.isArray(result)
assert.isArray(result[0].utxos)
assert.property(result[0], "utxos")
assert.property(result[0], "legacyAddress")
assert.property(result[0], "cashAddress")
assert.property(result[0], "slpAddress")
assert.property(result[0], "scriptPubKey")
assert.property(result[0], "asm")
})
})
})
-16
View File
@@ -231,22 +231,6 @@ describe("#SLP Utils", () => {
})
})
describe("#balance", () => {
it(`should fetch balance of single token for address: simpleledger:qzv3zz2trz0xgp6a96lu4m6vp2nkwag0kvyucjzqt9`, async () => {
// Mock the call to the REST API
if (process.env.TEST === "unit")
sandbox.stub(axios, "get").resolves({ data: mockData.mockBalance })
const balance = await slp.Utils.balance(
"simpleledger:qzv3zz2trz0xgp6a96lu4m6vp2nkwag0kvyucjzqt9",
"df808a41672a0a0ae6475b44f272a107bc9961b90f29dc918d71301f24fe92fb"
)
//console.log(`balance: ${JSON.stringify(balance, null, 2)}`)
assert2.hasAllKeys(balance, ["tokenId", "balance", "balanceString"])
})
})
describe("#validateTxid", () => {
it(`should validate slp txid`, async () => {
// Mock the call to the REST API