├── .dockerignore ├── .eslintrc.js ├── .gitignore ├── .gitmodules ├── .travis.yml ├── Dockerfile ├── LICENSE ├── README.md ├── client ├── client-gen-config.json ├── gen_client.sh └── generated-client │ ├── .gitignore │ ├── .swagger-codegen-ignore │ └── .swagger-codegen │ └── VERSION ├── docker-compose.debug.yml ├── docker-compose.yml ├── gen_all_specs_and_push.sh ├── gen_spec.sh ├── package-lock.json ├── package.json ├── server ├── gen_server_yaml.sh └── nodejs │ ├── .jshintignore │ ├── .swagger-codegen-ignore │ ├── README.md │ ├── api │ └── swagger.yaml │ ├── config.js │ ├── controllers │ ├── Aliases.js │ ├── AliasesService.js │ ├── Asset.js │ ├── AssetService.js │ ├── Blockmarket.js │ ├── BlockmarketService.js │ ├── Certificates.js │ ├── CertificatesService.js │ ├── Escrow.js │ ├── EscrowService.js │ ├── General.js │ ├── GeneralService.js │ ├── Masternodes.js │ ├── MasternodesService.js │ ├── Offers.js │ ├── OffersService.js │ ├── spec │ │ ├── AliasesService.spec.js │ │ ├── BlockmarketService.spec.js │ │ ├── CertificatesService.spec.js │ │ ├── EscrowService.spec.js │ │ ├── GeneralService.spec.js │ │ ├── MessagingService.spec.js │ │ ├── OfferService.spec.js │ │ └── helper │ │ │ ├── authHelper.js │ │ │ ├── dataHelper.js │ │ │ └── verifyHelper.js │ ├── test │ │ ├── AliasesService.test.js │ │ ├── AssetService.test.js │ │ ├── BlockmarketService.test.js │ │ ├── CertificatesService.test.js │ │ ├── EscrowService.test.js │ │ ├── GeneralService.test.js │ │ ├── MasternodesService.test.js │ │ ├── OffersService.test.js │ │ ├── TestRequest.js │ │ ├── config.js │ │ └── electrum_wallet_sample.csv │ └── util │ │ ├── commonUtils.js │ │ ├── generalServiceGetInfoUtils.js │ │ ├── methodGenerator.js │ │ ├── mongoUtils.js │ │ ├── spec │ │ └── varUtils.spec.js │ │ └── varUtils.js │ ├── index.js │ ├── package-lock.json │ ├── package.json │ └── spec │ └── config.js ├── swagger.yaml └── swagger_generated.json /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | Dockerfile* 4 | docker-compose* 5 | .dockerignore 6 | .git 7 | .gitignore 8 | README.md 9 | LICENSE 10 | .vscode 11 | .idea -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "commonjs": true, 4 | "es6": true 5 | }, 6 | "extends": "eslint:recommended", 7 | "parserOptions": { 8 | "ecmaVersion": 2017 9 | }, 10 | "rules": { 11 | "indent": [ 12 | "error", 13 | 2 14 | ], 15 | "linebreak-style": [ 16 | "error", 17 | "unix" 18 | ], 19 | "quotes": [ 20 | "error", 21 | "single" 22 | ], 23 | "semi": [ 24 | "error", 25 | "always" 26 | ], 27 | "no-undef": [ 28 | "off" 29 | ], 30 | "no-console": [ 31 | "off" 32 | ] 33 | } 34 | }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore these 2 | .idea 3 | .DS_Store 4 | api-app.iml 5 | node_modules 6 | syscoin-api.iml 7 | server/nodejs/mongotest.js 8 | .env 9 | *.log 10 | 11 | *.orig 12 | client/generated-client/* 13 | 14 | # except 15 | !/client/generated-client/.swagger-codegen 16 | !/client/generated-client/.swagger-codegen/VERSION 17 | !/client/generated-client/.swagger-codegen-ignore 18 | !/client/generated-client/.gitignore 19 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "swagger-ui"] 2 | path = swagger-ui 3 | url = https://github.com/syscoin/swagger-ui.git 4 | branch = master 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "7.10.1" 4 | - "8.11.4" 5 | cache: 6 | directories: 7 | - node_modules 8 | before_install: 9 | # Update Node.js module 10 | - "test ! -d node_modules || npm prune" 11 | - "test ! -d node_modules || npm rebuild" 12 | - "test ! -d server/nodejs/node_modules || cd server/nodejs && npm rebuild" 13 | - "test ! -d server/nodejs/node_modules || cd server/nodejs && npm prune" 14 | script: 15 | - "cd server/nodejs && rm -rf package-lock.json && npm install" 16 | - "npm run lint" 17 | - "npm run test" 18 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:8.9-alpine 2 | ENV NODE_ENV production 3 | WORKDIR /usr/src/app 4 | COPY ["package.json", "package-lock.json*", "npm-shrinkwrap.json*", "./"] 5 | RUN npm install --production --silent && mv node_modules ../ 6 | COPY . . 7 | EXPOSE 8001 8 | CMD node server.js -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # !!! THIS LIBRARY HAS BEEN DEPRECATED !!! 2 | **To interact with the Syscoin-RPC through a browser or using NodeJS please use the new [Syscoin-JS](https://github.com/syscoin/syscoin-js) library.** 3 | -------------------------------------------------------------------------------- /client/client-gen-config.json: -------------------------------------------------------------------------------- 1 | { "modelPropertyNaming": "original", "ngVersion": "6.0"} 2 | -------------------------------------------------------------------------------- /client/gen_client.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "*** IMPORTANT NOTE ***" 4 | echo "This script assumes you're using the latest version of swagger-codegen 2.3 and have built it locally" 5 | echo "This script does NOT commit or push any code." 6 | 7 | #capture output language 8 | read -p "Enter client language: " LANGUAGE 9 | 10 | #capture output directory 11 | read -p "Enter output directory: " OUTPUTDIR 12 | 13 | #capture path to local swagger codegen 14 | #/Users/dwasyluk/Development/swagger-codegen/modules/swagger-codegen-cli/target/swagger-codegen-cli.jar 15 | read -p "Enter path to swagger-codegen-cli: " CODEGEN 16 | 17 | #verify before generating 18 | echo "Does this look correct:" 19 | echo "Output language: $LANGUAGE" 20 | echo "Output directory: $OUTPUTDIR" 21 | echo "Swagger codegen: $CODEGEN" 22 | 23 | read -p "Continue? (Y/N): " confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]] || exit 1 24 | 25 | echo "Generating client sdk..." 26 | java -jar $CODEGEN generate -i ../swagger.yaml -l $LANGUAGE -c ./client-gen-config.json -o $OUTPUTDIR 27 | echo "Generation complete." 28 | 29 | -------------------------------------------------------------------------------- /client/generated-client/.gitignore: -------------------------------------------------------------------------------- 1 | wwwroot/*.js 2 | node_modules 3 | typings 4 | dist 5 | .idea 6 | -------------------------------------------------------------------------------- /client/generated-client/.swagger-codegen-ignore: -------------------------------------------------------------------------------- 1 | # Swagger Codegen Ignore 2 | # Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen 3 | 4 | # Use this file to prevent files from being overwritten by the generator. 5 | # The patterns follow closely to .gitignore or .dockerignore. 6 | 7 | # As an example, the C# client generator defines ApiClient.cs. 8 | # You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line: 9 | #ApiClient.cs 10 | 11 | # You can match any string of characters against a directory, file or extension with a single asterisk (*): 12 | #foo/*/qux 13 | # The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux 14 | 15 | # You can recursively match patterns against a directory, file or extension with a double asterisk (**): 16 | #foo/**/qux 17 | # This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux 18 | 19 | # You can also negate patterns with an exclamation (!). 20 | # For example, you can ignore all files in a docs folder with the file extension .md: 21 | #docs/*.md 22 | # Then explicitly reverse the ignore rule for a single file: 23 | #!docs/README.md 24 | -------------------------------------------------------------------------------- /client/generated-client/.swagger-codegen/VERSION: -------------------------------------------------------------------------------- 1 | Latest master commit (dbd0a4bb535de0d587c9ccec1465a25c8288ee96) 2 | https://github.com/swagger-api/swagger-codegen/commit/dbd0a4bb535de0d587c9ccec1465a25c8288ee96 -------------------------------------------------------------------------------- /docker-compose.debug.yml: -------------------------------------------------------------------------------- 1 | version: '2.1' 2 | 3 | services: 4 | syscoin-api: 5 | image: syscoin-api 6 | build: . 7 | environment: 8 | NODE_ENV: development 9 | ports: 10 | - 8001:8001 11 | - 9229:9229 12 | command: node --inspect=0.0.0.0:9229 server.js -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2.1' 2 | 3 | services: 4 | syscoin-api: 5 | image: syscoin-api 6 | build: . 7 | environment: 8 | NODE_ENV: production 9 | ports: 10 | - 8001:8001 -------------------------------------------------------------------------------- /gen_all_specs_and_push.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "*** IMPORTANT NOTE ***" 4 | echo "This script assumes you're using the latest version of swagger-codegen 2.3 and have built it locally." 5 | echo "This script will regenerate the JSON definitions ONLY at all levels, also generating the swagger-spec.js updates for swagger-ui." 6 | echo "This script *DOES* COMMIT AND PUSH CODE!" 7 | 8 | #capture path to local swagger codegen 9 | #/Users/dwasyluk/Development/swagger-codegen/modules/swagger-codegen-cli/target/swagger-codegen-cli.jar 10 | read -p "Enter path to swagger-codegen-cli: " CODEGEN 11 | 12 | #capture commit message to be used on swagger-ui 13 | read -p "Enter swagger-ui commit message: " SWAGGER_UI_MSG 14 | 15 | #capture commit message to be used on syscoin-api 16 | read -p "Enter syscoin-api commit message: " SYSCOIN_API_MSG 17 | 18 | #verify before generating 19 | echo "Does this look correct:" 20 | echo "Swagger codegen: ${CODEGEN}" 21 | echo "swagger-ui msg: ${SWAGGER_UI_MSG}" 22 | echo "syscoin-api msg: ${SYSCOIN_API_MSG}" 23 | 24 | read -p "Continue? (Y/N): " confirm && [[ ${confirm} == [yY] || ${confirm} == [yY][eE][sS] ]] || exit 1 25 | 26 | echo "Generating server JSON spec..." 27 | #create a temp folder to hold generated stuff 28 | mkdir ./generated-temp 29 | java -jar ${CODEGEN} generate -i swagger.yaml -l swagger -o ./generated-temp 30 | 31 | #copy the generated .json file to the production code location 32 | cp ./generated-temp/swagger.json ./swagger_generated.json 33 | 34 | #generate the server side YAML version of the definitions 35 | java -jar ${CODEGEN} generate -i swagger.yaml -l nodejs-server -o ./generated-temp 36 | cp ./generated-temp/api/swagger.yaml ./server/nodejs/api/swagger.yaml #move the regenerated YAML to the nodjs dir 37 | 38 | #remove all temp files 39 | rm -rf ./generated-temp 40 | 41 | echo "Server Spec JSON Generation complete." 42 | 43 | #copy the new spec to swagger-ui as a JS var 44 | echo "var swaggerSpec = " > ./swagger-ui/dist/swagger-spec.js 45 | cat swagger_generated.json >> ./swagger-ui/dist/swagger-spec.js 46 | 47 | #commit and push the changes thus far 48 | ( cd swagger-ui && git commit -m "${SWAGGER_UI_MSG}" dist/swagger-spec.js && git push origin dev ) 49 | git add swagger-ui 50 | echo "Swagger-ui successfully updated via GIT" 51 | 52 | #commit the nodejs server 53 | git commit swagger.yaml swagger_generated.json server/nodejs/api/swagger.yaml swagger-ui -m "${SYSCOIN_API_MSG}" 54 | git push 55 | 56 | echo "All spec files regenerated and committed/pushed." 57 | 58 | 59 | -------------------------------------------------------------------------------- /gen_spec.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "*** IMPORTANT NOTE ***" 4 | echo "This script assumes you're using the latest version of swagger-codegen 2.3 and have built it locally." 5 | echo "This script will regenerate the JSON definitions and also generate the swagger-spec.js updates for swagger-ui" 6 | echo "This script does NOT commit or push any code." 7 | 8 | #capture path to local swagger codegen 9 | #/Users/dwasyluk/Development/swagger-codegen/modules/swagger-codegen-cli/target/swagger-codegen-cli.jar 10 | read -p "Enter path to swagger-codegen-cli: " CODEGEN 11 | 12 | #verify before generating 13 | echo "Does this look correct:" 14 | echo "Swagger codegen: $CODEGEN" 15 | 16 | read -p "Continue? (Y/N): " confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]] || exit 1 17 | 18 | echo "Generating server JSON spec..." 19 | #create a temp folder to hold generated stuff 20 | mkdir ./generated-temp 21 | java -jar $CODEGEN generate -i swagger.yaml -l swagger -o ./generated-temp 22 | 23 | #copy the generated .json file to the production code location 24 | cp ./generated-temp/swagger.json ./swagger_generated.json 25 | 26 | #remove temp files 27 | rm -rf ./generated-temp 28 | 29 | #copy the new spec to swagger-ui as a JS var 30 | echo "var swaggerSpec = " > ./swagger-ui/dist/swagger-spec.js 31 | cat swagger_generated.json >> ./swagger-ui/dist/swagger-spec.js 32 | 33 | echo "JSON Generation complete." 34 | 35 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@syscoin/syscoin-api", 3 | "version": "3.0.0-beta", 4 | "lockfileVersion": 1 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@syscoin/syscoin-api", 3 | "description": "A full featured api for interacting with Syscoin commands both at an RPC level, as a REST API, and more.", 4 | "version": "3.0.0-beta", 5 | "main": "server.js", 6 | "keywords": [ 7 | "syscoin", 8 | "rpc", 9 | "api", 10 | "rest", 11 | "json" 12 | ], 13 | "author": { 14 | "name": "Dan Wasyluk", 15 | "email": "dan@syscoin.org", 16 | "url": "syscoin.org" 17 | }, 18 | "contributors": [ 19 | { 20 | "name": "davidgwking", 21 | "email": "na@na.com" 22 | }, 23 | { 24 | "name": "Syscoin Developers", 25 | "email": "syscoin@syscoin.org" 26 | } 27 | ], 28 | "repository": "https://github.com/syscoin/syscoin-api.git", 29 | "dependencies": {}, 30 | "devDependencies": {}, 31 | "bugs": { 32 | "url": "https://github.com/syscoin/syscoin-api/issues" 33 | }, 34 | "homepage": "https://github.com/syscoin/syscoin-api" 35 | } 36 | -------------------------------------------------------------------------------- /server/gen_server_yaml.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "*** IMPORTANT NOTE ***" 4 | echo "This script assumes you're using the latest version of swagger-codegen 2.3 and have built it locally." 5 | echo "This script will only regenerate the YAML definitions for a given language as it assumes business logic is mature and should not be overwritten by generated code." 6 | echo "This script does NOT commit or push any code." 7 | 8 | #capture output language 9 | read -p "Enter client language: " LANGUAGE 10 | 11 | #capture output directory, this is where we will copy the .yaml file 12 | read -p "Enter output directory: " OUTPUTDIR 13 | 14 | #capture path to local swagger codegen 15 | #/Users/dwasyluk/Development/swagger-codegen/modules/swagger-codegen-cli/target/swagger-codegen-cli.jar 16 | read -p "Enter path to swagger-codegen-cli: " CODEGEN 17 | 18 | #verify before generating 19 | echo "Does this look correct:" 20 | echo "Output language: $LANGUAGE" 21 | echo "Output directory: $OUTPUTDIR" 22 | echo "Swagger codegen: $CODEGEN" 23 | 24 | read -p "Continue? (Y/N): " confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]] || exit 1 25 | 26 | echo "Generating server sdk..." 27 | #create a temp folder to hold generated stuff 28 | mkdir ./generated-temp 29 | java -jar $CODEGEN generate -i ../swagger.yaml -l $LANGUAGE -o ./generated-temp 30 | 31 | #copy the generated .yaml file to the production code folder for the given language 32 | cp ./generated-temp/api/swagger.yaml $OUTPUTDIR/api/swagger.yaml 33 | rm -rf ./generated-temp 34 | 35 | echo "YAML Generation complete." 36 | 37 | -------------------------------------------------------------------------------- /server/nodejs/.jshintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | config.js -------------------------------------------------------------------------------- /server/nodejs/.swagger-codegen-ignore: -------------------------------------------------------------------------------- 1 | # Swagger Codegen Ignore 2 | # Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen 3 | 4 | # Use this file to prevent files from being overwritten by the generator. 5 | # The patterns follow closely to .gitignore or .dockerignore. 6 | 7 | # As an example, the C# client generator defines ApiClient.cs. 8 | # You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line: 9 | #ApiClient.cs 10 | 11 | # You can match any string of characters against a directory, file or extension with a single asterisk (*): 12 | #foo/*/qux 13 | # The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux 14 | 15 | # You can recursively match patterns against a directory, file or extension with a double asterisk (**): 16 | #foo/**/qux 17 | # Thsi matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux 18 | 19 | # You can also negate patterns with an exclamation (!). 20 | # For example, you can ignore all files in a docs folder with the file extension .md: 21 | #docs/*.md 22 | # Then explicitly reverse the ignore rule for a single file: 23 | #!docs/README.md 24 | -------------------------------------------------------------------------------- /server/nodejs/README.md: -------------------------------------------------------------------------------- 1 | # Running the Syscoin API NodeJS Server 2 | Prior to running the server a Syscoin node must be installed and properly configured as a JSON-RPC server. After the full node is configured the syscoin-api server 3 | needs to know the location of syscoin.conf using the `SYS_LOCATION` environmental variable, replacing `DATALOCATION` in the examples below 4 | with the path to your Syscoin data directory, including the trailing slash. 5 | 6 | To run the server, follow these simple steps: 7 | 8 | ``` 9 | npm install 10 | SYS_LOCATION=DATALOCATION npm run start 11 | ``` 12 | 13 | ## Running the server in daemon mode 14 | Running the server in daemon mode is dependent on [pm2](https://www.npmjs.com/package/pm2). To run the server as a daemon 15 | use the below command after `npm install` completes: 16 | 17 | ``` 18 | SYS_LOCATION=DATALOCATION npm run startd 19 | ``` 20 | 21 | ## Running unit tests 22 | Syscoin API has a series of "sanity" unit tests written using the Mocha + Chai test framework and assertions library. 23 | Due to the confirmation-based nature of blockchain transactions and for ease of use, you must first create a few Syscoin 24 | services manually and use the data from these to configure the test, before running the tests. 25 | 26 | Follow the steps below before running the test suite: 27 | 28 | 1. First ensure your wallet is running on a working testnet as **the test suite will spend SYS in its execution.** You can do this by 29 | editing `syscoin.conf` and specifying `testnet=1`. 30 | 1. Transfer at least 100 syscoin to the root wallet address (can be acquired by running `getaccountaddress ""` via syscoind 31 | or QT debug console) 32 | 1. Manually create the following entities on the Syscoin network, and populate the result values mentioned below into 33 | [`server/nodejs/spec/config.js`](spec/config.js): 34 | 1. Create an alias with a password. Set `TEST_ALIAS` and `TEST_ALIAS_PASSWORD` to the alias and password. 35 | 1. Create an offer with 100 qty and a price of 1 SYS using `TEST_ALIAS` and set `TEST_OFFER_GUID` to the guid of the new offer. 36 | 1. Create a certificate using `TEST_ALIAS`, and set `TEST_CERT_GUID` to the guid of the new cert. 37 | 1. Create a new message from `TEST_ALIAS` to `TEST_ALIAS`, and set `TEST_MESSAGE_GUID` to the guid of the new message. 38 | 1. Create a new escrow using `TEST_ALIAS` as buyer and arbiter, purchasing `TEST_OFFER_GUID`, and set `TEST_ESCROW_GUID` to the guid of the new escrow. 39 | 1. Run the test suite using the commend below, ensuring both Syscoin API Server and the Syscoin Core RPC Server are running. 40 | 41 | ``` 42 | npm run test 43 | ``` 44 | 45 | **Note**: Depending on network variables some tests may fail due to lack of confirmation on transactions/operations earlier in 46 | the test suite. The test try to accomodate this by waiting 3mins for confirmations around these confirmation-sensitive 47 | transaction types. These are typically `offerAccept` and `offerAcceptFeedback` tests. Additionally if the `TEST_*` identifiers 48 | you're using in `Config.js` have large result lists you may need to modify the specifics tests by adding a `this.timeout(n)` where `n` 49 | represents a time in ms that allows for the full response to be returned. The default is 2000ms. 50 | 51 | # Configuring for Production Use 52 | Before deploying syscoin-api for production use you will need to modify the following files: 53 | 54 | 1. `host` value in [`/api/swagger.yaml`](api/swagger.yaml) 55 | 1. `swaggerSpec.host` value located in [`../../swagger-ui/dist/swagger-spec.js`](https://github.com/syscoin/swagger-ui/blob/858d2b341291fd477dab4e629d93df0b16aea9a6/dist/swagger-spec.js) 56 | 1. `HOST` value in [`/spec/config.js`](spec/config.js) 57 | 58 | In all these files modify the specified value from `localhost:8001` to `SERVERIP:8001`. Replacing `SERVERIP` with your server's 59 | production IP or domain. You can also optionally change the port. 60 | 61 | **It is highly recommended that you allow only HTTPS 62 | access in production deployments and secure all connections with a valid SSL certificate. Failure to do this can expose the wallet to attack.** -------------------------------------------------------------------------------- /server/nodejs/config.js: -------------------------------------------------------------------------------- 1 | let config = {}; 2 | 3 | let defaultSyscoinConfigLocation = "/root/.syscoin/" 4 | 5 | const setupInMode = (envArgument, envArgumentIdentifier, preamble, friendlyModeName) => { 6 | console.log(`Running Syscoin API in '${friendlyModeName}' API run mode.\n${preamble}`); 7 | if (envArgument) { 8 | config.sys_location = envArgument; 9 | console.log(`${envArgumentIdentifier} was set, using syscoin.conf path of '${config.sys_location}'`); 10 | } else { 11 | config.sys_location = defaultSyscoinConfigLocation; 12 | console.log(`Warning: ${envArgumentIdentifier} was not set. Check your .env file!`); 13 | console.log(`Using default syscoin.conf path of '${defaultSyscoinConfigLocation}'`); 14 | } 15 | }; 16 | 17 | if (!process.env.APIRUNMODE) { 18 | console.log(`Running Syscoin API without setting APIRUNMODE (should be 'isolated' or 'integrated'). Attempting to run in integrated mode.`); 19 | setupInMode(process.env.SYSCOIN_CONFIG_INTEGRATED_LOCATION, 20 | "SYSCOIN_CONFIG_INTEGRATED_LOCATION", 21 | `This is intended to be running off of an integrated instance (normally an official release) of syscoin.`, 22 | `integrated`); 23 | } else if (process.env.APIRUNMODE.trim() === 'isolated') { // trimming is done due to windows space issue 24 | setupInMode(process.env.SYSCOIN_CONFIG_ISOLATED_LOCATION, "SYSCOIN_CONFIG_ISOLATED_LOCATION", 25 | `This is intended to be running off of an isolated instance (possibly custom build) of syscoin.`,`isolated`); 26 | } else if (process.env.APIRUNMODE.trim() === 'integrated') { 27 | setupInMode(process.env.SYSCOIN_CONFIG_INTEGRATED_LOCATION, "SYSCOIN_CONFIG_INTEGRATED_LOCATION", 28 | `This is intended to be running off of an integrated instance (normally an official release) of syscoin.`,`integrated`); 29 | } 30 | 31 | config.methodsWithLoggingDisabled = process.env.METHODS_WITH_LOGGING_DISABLED ? process.env.METHODS_WITH_LOGGING_DISABLED.split(',') : []; 32 | console.log("METHODS W LOGGIN DISABLED: ", config.methodsWithLoggingDisabled); 33 | 34 | config.api_secret = "iamapisecret"; 35 | config.secure = process.env.SECURE || true; 36 | config.port = process.env.PORT || 8001; 37 | 38 | config.verbose_debug = process.env.VERBOSE || false; 39 | 40 | //these configs allow the server to be run as an NPM module 41 | config.api_yaml = process.env.API_YAML || './api/swagger.yaml'; 42 | config.api_controllers = process.env.API_CONTROLLERS || './controllers'; 43 | config.run_as_subprocess = process.env.RUN_AS_SUBPROCESS || false; 44 | 45 | //NOTE: SECURE INFO SHOULD NOT BE COMMITTED TO PUBLIC GIT 46 | //mongodb config, offchain_url should include trailing slash! 47 | config.mongodb = { 48 | database_url: process.env.MONGODB_URL || "", 49 | offchain_url: "http://offchain-testnet.syscoin.org/aliasdata/" 50 | }; 51 | 52 | module.exports = config; -------------------------------------------------------------------------------- /server/nodejs/controllers/Aliases.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Aliases = require('./AliasesService'); 4 | 5 | module.exports.aliasbalance = function aliasbalance (req, res, next) { 6 | Aliases.aliasbalance(req.swagger.params, res, next); 7 | }; 8 | 9 | module.exports.aliasinfo = function aliasinfo (req, res, next) { 10 | Aliases.aliasinfo(req.swagger.params, res, next); 11 | }; 12 | 13 | module.exports.aliasexists = function aliasexists (req, res, next) { 14 | Aliases.aliasexists(req.swagger.params, res, next); 15 | } 16 | 17 | module.exports.aliasnew = function aliasnew (req, res, next) { 18 | Aliases.aliasnew(req.swagger.params, res, next); 19 | }; 20 | 21 | module.exports.aliaspay = function aliaspay (req, res, next) { 22 | Aliases.aliaspay(req.swagger.params, res, next); 23 | }; 24 | 25 | module.exports.aliasupdate = function aliasupdate (req, res, next) { 26 | Aliases.aliasupdate(req.swagger.params, res, next); 27 | }; 28 | 29 | module.exports.aliaswhitelist = function aliaswhitelist (req, res, next) { 30 | Aliases.aliaswhitelist(req.swagger.params, res, next); 31 | }; 32 | 33 | module.exports.aliasclearwhitelist = function aliasclearwhitelist (req, res, next) { 34 | Aliases.aliasclearwhitelist(req.swagger.params, res, next); 35 | }; 36 | 37 | module.exports.aliasupdatewhitelist = function aliasupdatewhitelist (req, res, next) { 38 | Aliases.aliasupdatewhitelist(req.swagger.params, res, next); 39 | }; 40 | 41 | module.exports.syscointxfund = function syscointxfund(req, res, next) { 42 | Aliases.syscointxfund(req.swagger.params, res, next); 43 | }; 44 | 45 | module.exports.aliasaddscript = function aliasaddscript (req, res, next) { 46 | Aliases.aliasaddscript(req.swagger.params, res, next); 47 | }; 48 | -------------------------------------------------------------------------------- /server/nodejs/controllers/AliasesService.js: -------------------------------------------------------------------------------- 1 | const syscoinClient = require('../index').syscoinClient; 2 | const methodGenerator = require('./util/methodGenerator'); 3 | const varUtils = require('./util/varUtils'); 4 | const commonUtils = require('./util/commonUtils'); 5 | 6 | 7 | 8 | module.exports = { 9 | aliasbalance: methodGenerator.generateGenericSyscoinMethod([ 10 | { prop: 'alias' } 11 | ], syscoinClient.aliasBalance, 'aliasbalance', 'GET'), 12 | 13 | aliasinfo: methodGenerator.generateGenericSyscoinMethod([ 14 | { prop: 'aliasname' } 15 | ], syscoinClient.aliasInfo, 'aliasinfo', 'GET'), 16 | 17 | 18 | aliasexists: function(args, res) { 19 | var argList = [{ prop: "aliasname" }]; 20 | 21 | var cb = function(err, result) { 22 | res.setHeader('Content-Type', 'application/json'); 23 | 24 | var jsonObject = { 25 | aliasName: args.aliasname.value, 26 | success: false 27 | } 28 | 29 | if (err) { 30 | return res.end(JSON.stringify(jsonObject)); 31 | } 32 | 33 | jsonObject.success = true; 34 | commonUtils.log('Get alias exists value ', result, 'aliasexists'); 35 | res.end(JSON.stringify(jsonObject)); 36 | }; 37 | 38 | var arr = varUtils.getArgsArr(argList, args, 'GET', cb); 39 | syscoinClient.aliasInfo.apply(syscoinClient, arr); 40 | }, 41 | 42 | aliasnew: methodGenerator.generateGenericSyscoinMethod([ 43 | { prop: 'aliasname' }, 44 | { prop: 'publicvalue' }, 45 | { prop: 'accept_transfers_flags', defaultValue: 3 }, 46 | { prop: 'expire_timestamp', defaultValue: 3600 }, 47 | { prop: 'address' }, 48 | { prop: 'encryption_privatekey' }, 49 | { prop: 'encryption_publickey' }, 50 | { prop: 'witness' } 51 | ], syscoinClient.aliasNew, 'aliasnew', 'POST'), 52 | 53 | aliaspay: methodGenerator.generateGenericSyscoinMethod([ 54 | { prop: 'aliasfrom' }, 55 | { prop: 'amounts' }, 56 | { prop: 'instantsend' }, 57 | { prop: 'subtractfeefromamount' } 58 | ], syscoinClient.aliasPay, 'aliaspay', 'POST'), 59 | 60 | aliasupdate: methodGenerator.generateGenericSyscoinMethod([ 61 | { prop: 'aliasname' }, 62 | { prop: 'publicvalue' }, 63 | { prop: 'address' }, 64 | { prop: 'accept_transfers_flags', defaultValue: 3 }, 65 | { prop: 'expire_timestamp', defaultValue: 3600 }, 66 | { prop: 'encryption_privatekey' }, 67 | { prop: 'encryption_publickey' }, 68 | { prop: 'witness' } 69 | ], syscoinClient.aliasUpdate, 'aliasupdate', 'POST'), 70 | 71 | aliaswhitelist: methodGenerator.generateGenericSyscoinMethod([ 72 | { prop: 'aliasname' } 73 | ], syscoinClient.aliasWhitelist, 'aliaswhitelist', 'GET'), 74 | 75 | aliasclearwhitelist: methodGenerator.generateGenericSyscoinMethod([ 76 | { prop: 'owneralias', }, 77 | { prop: 'witness', } 78 | ], syscoinClient.aliasClearWhitelist, 'aliasclearwhitelist', 'POST'), 79 | 80 | aliasupdatewhitelist: methodGenerator.generateGenericSyscoinMethod([ 81 | { prop: 'owneralias' }, 82 | { prop: 'entries' }, 83 | { prop: 'witness', defaultValue: '' } 84 | ], syscoinClient.aliasUpdateWhitelist, 'aliasupdatewhitelist', 'POST'), 85 | 86 | syscointxfund: methodGenerator.generateGenericSyscoinMethod([ 87 | { prop: 'hexstring' }, 88 | { prop: 'addresses', asJsonObject: true } 89 | ], syscoinClient.syscoinTxFund, 'syscointxfund', 'POST'), 90 | 91 | aliasaddscript: methodGenerator.generateGenericSyscoinMethod([ 92 | { prop: 'script' } 93 | ], syscoinClient.aliasAddScript, 'aliasaddscript', 'POST') 94 | }; -------------------------------------------------------------------------------- /server/nodejs/controllers/Asset.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Assets = require('./AssetService'); 4 | 5 | module.exports.assetinfo = function assetinfo (req, res, next) { 6 | Assets.assetinfo(req.swagger.params, res, next); 7 | }; 8 | 9 | module.exports.assetsend = function assetsend (req, res, next) { 10 | Assets.assetsend(req.swagger.params, res, next); 11 | }; 12 | 13 | module.exports.assetnew = function assetnew (req, res, next) { 14 | Assets.assetnew(req.swagger.params, res, next); 15 | }; 16 | 17 | module.exports.assetallocationinfo = function assetallocationinfo (req, res, next) { 18 | Assets.assetallocationinfo(req.swagger.params, res, next); 19 | }; 20 | 21 | module.exports.assetallocationsend = function assetallocationsend (req, res, next) { 22 | Assets.assetallocationsend(req.swagger.params, res, next); 23 | }; 24 | 25 | module.exports.assetallocationsenderstatus = function assetallocationsenderstatus (req, res, next) { 26 | Assets.assetallocationsenderstatus(req.swagger.params, res, next); 27 | }; 28 | 29 | module.exports.assettransfer = function assettransfer (req, res, next) { 30 | Assets.assettransfer(req.swagger.params, res, next); 31 | }; 32 | 33 | module.exports.assetupdate = function assetupdate (req, res, next) { 34 | Assets.assetupdate(req.swagger.params, res, next); 35 | }; 36 | 37 | module.exports.assetallocationcollectinterest = function assetallocationcollectinterest (req, res, next) { 38 | Assets.assetallocationcollectinterest(req.swagger.params, res, next); 39 | }; 40 | -------------------------------------------------------------------------------- /server/nodejs/controllers/AssetService.js: -------------------------------------------------------------------------------- 1 | const syscoinClient = require('../index').syscoinClient; 2 | const DataType = require('./util/varUtils').DataType; 3 | const methodGenerator = require('./util/methodGenerator'); 4 | 5 | module.exports = { 6 | assetallocationcollectinterest: methodGenerator.generateGenericSyscoinMethod([ 7 | { prop: 'asset' }, 8 | { prop: 'alias' }, 9 | { prop: 'witness' } 10 | ], syscoinClient.assetAllocationCollectInterest, 'assetallocationcollectinterest', 'POST'), 11 | 12 | assetinfo: methodGenerator.generateGenericSyscoinMethod([ 13 | { prop: 'asset' }, 14 | { prop: 'getinputs', defaultValue: true } 15 | ], syscoinClient.assetInfo, 'assetinfo', 'GET'), 16 | 17 | assetsend: methodGenerator.generateGenericSyscoinMethod([ 18 | { prop: 'asset' }, 19 | { prop: 'aliasfrom' }, 20 | { prop: 'amounts' }, 21 | { prop: 'memo' }, 22 | { prop: 'witness' } 23 | ], syscoinClient.assetSend, 'assetsend', 'POST'), 24 | 25 | assetallocationinfo: methodGenerator.generateGenericSyscoinMethod([ 26 | { prop: 'asset' }, 27 | { prop: 'alias' }, 28 | { prop: 'getinputs', defaultValue: true } 29 | ], syscoinClient.assetAllocationInfo, 'assetallocationinfo', 'GET'), 30 | 31 | assetallocationsend: methodGenerator.generateGenericSyscoinMethod([ 32 | { prop: 'asset' }, 33 | { prop: 'aliasfrom' }, 34 | { prop: 'amounts' }, 35 | { prop: 'memo' }, 36 | { prop: 'witness' } 37 | ], syscoinClient.assetAllocationSend, 'assetallocationsend', 'POST'), 38 | 39 | assetallocationsenderstatus: methodGenerator.generateGenericSyscoinMethod([ 40 | { prop: 'asset' }, 41 | { prop: 'sender' }, 42 | { prop: 'txid' } 43 | ], syscoinClient.assetAllocationSenderStatus, 'assetallocationsenderstatus', 'GET'), 44 | 45 | assettransfer: methodGenerator.generateGenericSyscoinMethod([ 46 | { prop: 'asset' }, 47 | { prop: 'alias' }, 48 | { prop: 'certkey' }, 49 | { prop: 'witness' } 50 | ], syscoinClient.assetTransfer, 'assettransfer', 'POST'), 51 | 52 | assetupdate: methodGenerator.generateGenericSyscoinMethod([ 53 | { prop: 'asset', }, 54 | { prop: 'publicvalue', }, 55 | { prop: 'category', }, 56 | { prop: 'supply', syscoinType: DataType.STRING }, 57 | { prop: 'interest_rate', }, 58 | { prop: 'witness', } 59 | ], syscoinClient.assetUpdate, 'assetupdate', 'POST'), 60 | 61 | assetnew: methodGenerator.generateGenericSyscoinMethod([ 62 | { prop: 'symbol', }, 63 | { prop: 'alias', }, 64 | { prop: 'publicvalue', }, 65 | { prop: 'category', }, 66 | { prop: 'precision', }, 67 | { prop: 'use_inputranges', }, 68 | { prop: 'supply', }, 69 | { prop: 'max_supply', syscoinType: DataType.STRING }, 70 | { prop: 'interest_rate', }, 71 | { prop: 'can_adjust_interest_rate', }, 72 | { prop: 'witness', } 73 | ], syscoinClient.assetNew, 'assetnew', 'POST') 74 | }; -------------------------------------------------------------------------------- /server/nodejs/controllers/Blockmarket.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Blockmarket = require('./BlockmarketService'); 4 | 5 | module.exports.login = function login (req, res, next) { 6 | Blockmarket.login(req.swagger.params, res, next); 7 | }; 8 | 9 | -------------------------------------------------------------------------------- /server/nodejs/controllers/BlockmarketService.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const jwt = require('jsonwebtoken'); 4 | const Hashes = require('jshashes'); 5 | const config = require('../config'); 6 | const rpcuser = require('../index').rpcuser; 7 | const rpcpass = require('../index').rpcpass; 8 | 9 | exports.login = function (args, res) { 10 | /** 11 | * parameters expected in the args: 12 | * auth (String) 13 | **/ 14 | let response = { 15 | success: false, 16 | message: null, 17 | token: null 18 | }; 19 | 20 | const auth = args.auth ? args.auth.value : null; 21 | const validAuth = new Hashes.SHA1().hex(rpcuser + rpcpass); 22 | 23 | if (auth && auth === validAuth) { 24 | console.info('Login successful!'); 25 | // if user is found and password is right create a token 26 | response.token = jwt.sign({ auth: validAuth }, config.api_secret, { 27 | expiresIn: 60 * 60 * 24 // expires in 24 hours 28 | }); 29 | response.success = true; 30 | response.message = 'Enjoy your token!'; 31 | } else { 32 | console.info('Login attempt failed! Provided credentials don\'t match our records'); 33 | response.message = 'Authentication failed: invalid username/password.'; 34 | res.statusCode = 401; 35 | } 36 | 37 | res.setHeader('Content-Type', 'application/json'); 38 | res.end(JSON.stringify(response)); 39 | }; -------------------------------------------------------------------------------- /server/nodejs/controllers/Certificates.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | 4 | var Certificates = require('./CertificatesService'); 5 | 6 | module.exports.certnew = function certnew (req, res, next) { 7 | Certificates.certnew(req.swagger.params, res, next); 8 | }; 9 | 10 | module.exports.certtransfer = function certtransfer (req, res, next) { 11 | Certificates.certtransfer(req.swagger.params, res, next); 12 | }; 13 | 14 | module.exports.certupdate = function certupdate (req, res, next) { 15 | Certificates.certupdate(req.swagger.params, res, next); 16 | }; 17 | 18 | module.exports.certinfo = function certinfo (req, res, next) { 19 | Certificates.certinfo(req.swagger.params, res, next); 20 | }; -------------------------------------------------------------------------------- /server/nodejs/controllers/CertificatesService.js: -------------------------------------------------------------------------------- 1 | const syscoinClient = require('../index').syscoinClient; 2 | const methodGenerator = require('./util/methodGenerator'); 3 | 4 | module.exports = { 5 | certinfo: methodGenerator.generateGenericSyscoinMethod([ 6 | { prop: 'guid' } 7 | ], syscoinClient.certInfo, 'certinfo', 'GET'), 8 | 9 | certnew: methodGenerator.generateGenericSyscoinMethod([ 10 | { prop: 'alias' }, 11 | { prop: 'title' }, 12 | { prop: 'publicvalue' }, 13 | { prop: 'category', defaultValue: 'certificates' }, 14 | { prop: 'witness' } 15 | ], syscoinClient.certNew, 'certnew', 'POST'), 16 | 17 | certtransfer: methodGenerator.generateGenericSyscoinMethod([ 18 | { prop: 'guid' }, 19 | { prop: 'alias' }, 20 | { prop: 'publicvalue' }, 21 | { prop: 'accessflags', }, 22 | { prop: 'witness' } 23 | ], syscoinClient.certTransfer, 'certtransfer', 'POST'), 24 | 25 | certupdate: methodGenerator.generateGenericSyscoinMethod([ 26 | { prop: 'guid' }, 27 | { prop: 'title' }, 28 | { prop: 'publicvalue' }, 29 | { prop: 'category', defaultValue: 'certificates' }, 30 | { prop: 'witness' } 31 | ], syscoinClient.certUpdate, 'certupdate', 'POST') 32 | }; -------------------------------------------------------------------------------- /server/nodejs/controllers/Escrow.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | 4 | var Escrow = require('./EscrowService'); 5 | 6 | 7 | module.exports.escrowacknowledge = function escrowacknowledge (req, res, next) { 8 | Escrow.escrowacknowledge(req.swagger.params, res, next); 9 | }; 10 | 11 | module.exports.escrowcompleterefund = function escrowcompleterefund (req, res, next) { 12 | Escrow.escrowcompleterefund(req.swagger.params, res, next); 13 | }; 14 | 15 | module.exports.escrowcompleterelease = function escrowcompleterelease (req, res, next) { 16 | Escrow.escrowcompleterelease(req.swagger.params, res, next); 17 | }; 18 | 19 | module.exports.escrowfeedback = function escrowfeedback (req, res, next) { 20 | Escrow.escrowfeedback(req.swagger.params, res, next); 21 | }; 22 | 23 | module.exports.escrowlist = function escrowlist (req, res, next) { 24 | Escrow.escrowlist(req.swagger.params, res, next); 25 | }; 26 | 27 | module.exports.escrownew = function escrownew (req, res, next) { 28 | Escrow.escrownew(req.swagger.params, res, next); 29 | }; 30 | 31 | module.exports.escrowrefund = function escrowrefund (req, res, next) { 32 | Escrow.escrowrefund(req.swagger.params, res, next); 33 | }; 34 | 35 | module.exports.escrowrelease = function escrowrelease (req, res, next) { 36 | Escrow.escrowrelease(req.swagger.params, res, next); 37 | }; 38 | 39 | module.exports.escrowbid = function escrowbid (req, res, next) { 40 | Escrow.escrowbid(req.swagger.params, res, next); 41 | }; 42 | 43 | module.exports.escrowcreaterawtransaction = function escrowcreaterawtransaction (req, res, next) { 44 | Escrow.escrowcreaterawtransaction(req.swagger.params, res, next); 45 | }; 46 | 47 | module.exports.escrowinfo = function escrowinfo (req, res, next) { 48 | Escrow.escrowinfo(req.swagger.params, res, next); 49 | }; -------------------------------------------------------------------------------- /server/nodejs/controllers/EscrowService.js: -------------------------------------------------------------------------------- 1 | const syscoinClient = require('../index').syscoinClient; 2 | const varUtils = require('./util/varUtils'); 3 | const commonUtils = require('./util/commonUtils'); 4 | const methodGenerator = require('./util/methodGenerator'); 5 | 6 | module.exports = { 7 | escrowacknowledge: methodGenerator.generateGenericSyscoinMethod([ 8 | { prop: 'escrowguid' }, 9 | { prop: 'witness' } 10 | ], syscoinClient.escrowAcknowledge, 'escrowacknowledge', 'POST'), 11 | 12 | escrowcompleterefund: methodGenerator.generateGenericSyscoinMethod([ 13 | { prop: 'escrowguid' }, 14 | { prop: 'rawtx' }, 15 | { prop: 'witness' } 16 | ], syscoinClient.escrowCompleteRefund, 'escrowcompleterefund', 'POST'), 17 | 18 | escrowcompleterelease: methodGenerator.generateGenericSyscoinMethod([ 19 | { prop: 'escrowguid' }, 20 | { prop: 'rawtx' }, 21 | { prop: 'witness' } 22 | ], syscoinClient.escrowCompleteRelease, 'escrowcompleterelease', 'POST'), 23 | 24 | escrowfeedback: methodGenerator.generateGenericSyscoinMethod([ 25 | { prop: 'escrowguid' }, 26 | { prop: 'userfrom' }, 27 | { prop: 'feedback' }, 28 | { prop: 'rating' }, 29 | { prop: 'userto' }, 30 | { prop: 'witness' } 31 | ], syscoinClient.escrowFeedback, 'escrowfeedback', 'POST'), 32 | 33 | /* 34 | * This method below (escrowlist) is not part of API specs. All requests to it generate 404 error. 35 | * It's most likely deprecated 36 | */ 37 | escrowlist: function (args, res) { 38 | var argList = [ 39 | { prop: 'buyerAliases', defaultValue: [] }, 40 | { prop: 'sellerAliases', defaultValue: [] }, 41 | { prop: 'arbiterAliases', defaultValue: [] }, 42 | { prop: 'escrow', defaultValue: '' }, 43 | { prop: 'count', defaultValue: '10' }, 44 | { prop: 'from', defaultValue: '0' } 45 | ]; 46 | 47 | args.buyerAliases.value = varUtils.correctTypes(args.buyerAliases.value, varUtils.TYPE_CONVERSION.NUM_TO_STRING); 48 | args.sellerAliases.value = varUtils.correctTypes(args.sellerAliases.value, varUtils.TYPE_CONVERSION.NUM_TO_STRING); 49 | args.arbiterAliases.value = varUtils.correctTypes(args.arbiterAliases.value, varUtils.TYPE_CONVERSION.NUM_TO_STRING); 50 | args.count.value = varUtils.correctTypes(args.count.value, varUtils.TYPE_CONVERSION.NUM_TO_STRING); 51 | args.from.value = varUtils.correctTypes(args.from.value, varUtils.TYPE_CONVERSION.NUM_TO_STRING); 52 | 53 | var cb = function (err, result) { 54 | res.setHeader('Content-Type', 'application/json'); 55 | 56 | if (err) { 57 | return commonUtils.reportError(res, err); 58 | } 59 | 60 | console.log('Escrow list:', result); 61 | res.end(JSON.stringify(result)); 62 | }; 63 | 64 | var arr = varUtils.getArgsArr(argList, args, 'GET', cb); 65 | syscoinClient.escrowList.apply(syscoinClient, arr); 66 | }, 67 | 68 | escrownew: methodGenerator.generateGenericSyscoinMethod([ 69 | { prop: 'getamountandaddress' }, 70 | { prop: 'alias' }, 71 | { prop: 'arbiter_alias' }, 72 | { prop: 'offer' }, 73 | { prop: 'quantity' }, 74 | { prop: 'buynow' }, 75 | { prop: 'price_per_unit_in_payment_option' }, 76 | { prop: 'shipping_amount' }, 77 | { prop: 'network_fee' }, 78 | { prop: 'arbiter_fee', defaultValue: 0.005 }, 79 | { prop: 'witness_fee', defaultValue: 0 }, 80 | { prop: 'extTx' }, 81 | { prop: 'paymentoption', defaultValue: 'SYS' }, 82 | { prop: 'bid_in_payment_option' }, 83 | { prop: 'bid_in_offer_currency' }, 84 | { prop: 'witness' } 85 | ], syscoinClient.escrowNew, 'escrownew', 'POST'), 86 | 87 | escrowrefund: methodGenerator.generateGenericSyscoinMethod([ 88 | { prop: 'escrowguid' }, 89 | { prop: 'userrole' }, 90 | { prop: 'rawtx' }, 91 | { prop: 'witness' } 92 | ], syscoinClient.escrowRefund, 'escrowrefund', 'POST'), 93 | 94 | escrowrelease: methodGenerator.generateGenericSyscoinMethod([ 95 | { prop: 'escrowguid' }, 96 | { prop: 'userrole' }, 97 | { prop: 'rawtx' }, 98 | { prop: 'witness' } 99 | ], syscoinClient.escrowRelease, 'escrowrelease', 'POST'), 100 | 101 | escrowbid: methodGenerator.generateGenericSyscoinMethod([ 102 | { prop: 'alias' }, 103 | { prop: 'escrow' }, 104 | { prop: 'bid_in_offer_currency' }, 105 | { prop: 'bid_in_payment_option' }, 106 | { prop: 'witness' } 107 | ], syscoinClient.escrowBid, 'escrowbid', 'POST'), 108 | 109 | escrowcreaterawtransaction: methodGenerator.generateGenericSyscoinMethod([ 110 | { prop: 'type' }, 111 | { prop: 'escrowguid' }, 112 | { prop: 'inputs' }, 113 | { prop: 'role' } 114 | ], syscoinClient.escrowCreateRawTransaction, 'escrowcreaterawtransaction', 'POST'), 115 | 116 | escrowinfo: methodGenerator.generateGenericSyscoinMethod([ 117 | { prop: 'escrowguid' } 118 | ], syscoinClient.escrowInfo, 'escrowinfo', 'GET') 119 | }; -------------------------------------------------------------------------------- /server/nodejs/controllers/General.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var General = require('./GeneralService'); 4 | 5 | module.exports.addmultisigaddress = function addmultisigaddress (req, res, next) { 6 | General.addmultisigaddress(req.swagger.params, res, next); 7 | }; 8 | 9 | module.exports.dumpprivkey = function dumpprivkey (req, res, next) { 10 | General.dumpprivkey(req.swagger.params, res, next); 11 | }; 12 | 13 | module.exports.dumpwallet = function dumpwallet (req, res, next) { 14 | General.dumpwallet(req.swagger.params, res, next); 15 | }; 16 | 17 | module.exports.encryptwallet = function encryptwallet (req, res, next) { 18 | General.encryptwallet(req.swagger.params, res, next); 19 | }; 20 | 21 | module.exports.generate = function generate (req, res, next) { 22 | General.generate(req.swagger.params, res, next); 23 | }; 24 | 25 | module.exports.generatepublickey = function generatepublickey (req, res, next) { 26 | General.generatepublickey(req.swagger.params, res, next); 27 | }; 28 | 29 | module.exports.getaccount = function getaccount (req, res, next) { 30 | General.getaccount(req.swagger.params, res, next); 31 | }; 32 | 33 | module.exports.getaccountaddress = function getaccountaddress (req, res, next) { 34 | General.getaccountaddress(req.swagger.params, res, next); 35 | }; 36 | 37 | module.exports.getaddressesbyaccount = function getaddressesbyaccount (req, res, next) { 38 | General.getaddressesbyaccount(req.swagger.params, res, next); 39 | }; 40 | 41 | module.exports.getbalance = function getbalance (req, res, next) { 42 | General.getbalance(req.swagger.params, res, next); 43 | }; 44 | 45 | module.exports.getblock = function getblock (req, res, next) { 46 | General.getblock(req.swagger.params, res, next); 47 | }; 48 | 49 | module.exports.getblockchaininfo = function getblockchaininfo (req, res, next) { 50 | General.getblockchaininfo(req.swagger.params, res, next); 51 | }; 52 | 53 | module.exports.getblockcount = function getblockcount (req, res, next) { 54 | General.getblockcount(req.swagger.params, res, next); 55 | }; 56 | 57 | module.exports.getinfo = function getinfo (req, res, next) { 58 | General.getinfo(req.swagger.params, res, next); 59 | }; 60 | 61 | module.exports.getmempoolinfo = function getmempoolinfo (req, res, next) { 62 | General.getmempoolinfo(req.swagger.params, res, next); 63 | } 64 | 65 | module.exports.getdifficulty = function getdifficulty (req, res, next) { 66 | General.getdifficulty(req.swagger.params, res, next); 67 | } 68 | 69 | module.exports.getmininginfo = function getmininginfo (req, res, next) { 70 | General.getmininginfo(req.swagger.params, res, next); 71 | }; 72 | 73 | module.exports.getnetworkinfo = function getnetworkinfo (req, res, next) { 74 | General.getnetworkinfo(req.swagger.params, res, next); 75 | }; 76 | 77 | module.exports.getnewaddress = function getnewaddress (req, res, next) { 78 | General.getnewaddress(req.swagger.params, res, next); 79 | }; 80 | 81 | module.exports.getpeerinfo = function getpeerinfo (req, res, next) { 82 | General.getpeerinfo(req.swagger.params, res, next); 83 | }; 84 | 85 | module.exports.getreceivedbyaccount = function getreceivedbyaccount (req, res, next) { 86 | General.getreceivedbyaccount(req.swagger.params, res, next); 87 | }; 88 | 89 | module.exports.getreceivedbyaddress = function getreceivedbyaddress (req, res, next) { 90 | General.getreceivedbyaddress(req.swagger.params, res, next); 91 | }; 92 | 93 | module.exports.gettransaction = function gettransaction (req, res, next) { 94 | General.gettransaction(req.swagger.params, res, next); 95 | }; 96 | 97 | module.exports.getunconfirmedbalance = function getunconfirmedbalance (req, res, next) { 98 | General.getunconfirmedbalance(req.swagger.params, res, next); 99 | }; 100 | 101 | module.exports.getwalletinfo = function getwalletinfo (req, res, next) { 102 | General.getwalletinfo(req.swagger.params, res, next); 103 | }; 104 | 105 | module.exports.importaddress = function importaddress (req, res, next) { 106 | General.importaddress(req.swagger.params, res, next); 107 | }; 108 | 109 | module.exports.importprivkey = function importprivkey (req, res, next) { 110 | General.importprivkey(req.swagger.params, res, next); 111 | }; 112 | 113 | module.exports.importpubkey = function importpubkey (req, res, next) { 114 | General.importpubkey(req.swagger.params, res, next); 115 | }; 116 | 117 | module.exports.importwallet = function importwallet (req, res, next) { 118 | General.importwallet(req.swagger.params, res, next); 119 | }; 120 | 121 | module.exports.listaccounts = function listaccounts (req, res, next) { 122 | General.listaccounts(req.swagger.params, res, next); 123 | }; 124 | 125 | module.exports.listaddressgroupings = function listaddressgroupings (req, res, next) { 126 | General.listaddressgroupings(req.swagger.params, res, next); 127 | }; 128 | 129 | module.exports.listreceivedbyaccount = function listreceivedbyaccount (req, res, next) { 130 | General.listreceivedbyaccount(req.swagger.params, res, next); 131 | }; 132 | 133 | module.exports.listreceivedbyaddress = function listreceivedbyaddress (req, res, next) { 134 | General.listreceivedbyaddress(req.swagger.params, res, next); 135 | }; 136 | 137 | module.exports.listsinceblock = function listsinceblock (req, res, next) { 138 | General.listsinceblock(req.swagger.params, res, next); 139 | }; 140 | 141 | module.exports.listtransactions = function listtransactions (req, res, next) { 142 | General.listtransactions(req.swagger.params, res, next); 143 | }; 144 | 145 | module.exports.listunspent = function listunspent (req, res, next) { 146 | General.listunspent(req.swagger.params, res, next); 147 | }; 148 | 149 | module.exports.move = function move (req, res, next) { 150 | General.move(req.swagger.params, res, next); 151 | }; 152 | module.exports.sendfrom = function sendfrom (req, res, next) { 153 | General.sendfrom(req.swagger.params, res, next); 154 | }; 155 | 156 | module.exports.sendmany = function sendmany (req, res, next) { 157 | General.sendmany(req.swagger.params, res, next); 158 | }; 159 | 160 | module.exports.sendtoaddress = function sendtoaddress (req, res, next) { 161 | General.sendtoaddress(req.swagger.params, res, next); 162 | }; 163 | 164 | module.exports.signmessage = function signmessage (req, res, next) { 165 | General.signmessage(req.swagger.params, res, next); 166 | }; 167 | 168 | module.exports.syscoindecoderawtransaction = function syscoindecoderawtransaction (req, res, next) { 169 | General.syscoindecoderawtransaction(req.swagger.params, res, next); 170 | }; 171 | 172 | module.exports.validateaddress = function validateaddress (req, res, next) { 173 | General.validateaddress(req.swagger.params, res, next); 174 | }; 175 | 176 | module.exports.verifymessage = function verifymessage (req, res, next) { 177 | General.verifymessage(req.swagger.params, res, next); 178 | }; 179 | 180 | module.exports.walletlock = function walletlock (req, res, next) { 181 | General.walletlock(req.swagger.params, res, next); 182 | }; 183 | 184 | module.exports.walletpassphrase = function walletpassphrase (req, res, next) { 185 | General.walletpassphrase(req.swagger.params, res, next); 186 | }; 187 | 188 | module.exports.walletpassphrasechange = function walletpassphrasechange (req, res, next) { 189 | General.walletpassphrasechange(req.swagger.params, res, next); 190 | }; 191 | 192 | module.exports.syscoinlistreceivedbyaddress = function syscoinlistreceivedbyaddress (req, res, next) { 193 | General.syscoinlistreceivedbyaddress(req.swagger.params, res, next); 194 | }; 195 | 196 | module.exports.getaddressbalance = function getaddressbalance (req, res, next) { 197 | console.log(req.swagger.params); 198 | General.getaddressbalance(req.swagger.params, res, next); 199 | }; 200 | 201 | module.exports.getaddressdeltas = function getaddressdeltas (req, res, next) { 202 | General.getaddressdeltas(req.swagger.params, res, next); 203 | }; 204 | 205 | module.exports.getaddressmempool = function getaddressmempool (req, res, next) { 206 | General.getaddressmempool(req.swagger.params, res, next); 207 | }; 208 | 209 | module.exports.syscoinsendrawtransaction = function getaddressmempool (req, res, next) { 210 | General.syscoinsendrawtransaction(req.swagger.params, res, next); 211 | }; 212 | 213 | module.exports.getgenerate = function getgenerate (req, res, next) { 214 | General.getgenerate(req.swagger.params, res, next); 215 | }; 216 | 217 | module.exports.setgenerate = function setgenerate (req, res, next) { 218 | General.setgenerate(req.swagger.params, res, next); 219 | }; 220 | 221 | module.exports.setnetworkactive = function setnetworkactive (req, res, next) { 222 | General.setnetworkactive(req.swagger.params, res, next); 223 | }; 224 | 225 | module.exports.mnsync = function mnsync (req, res, next) { 226 | General.mnsync(req.swagger.params, res, next); 227 | }; 228 | 229 | module.exports.dumphdinfo = function dumphdinfo (req, res, next) { 230 | General.dumphdinfo(req.swagger.params, res, next); 231 | }; 232 | 233 | module.exports.debug = function debug (req, res, next) { 234 | General.debug(req.swagger.params, res, next); 235 | }; 236 | 237 | module.exports.instantsendtoaddress = function debug (req, res, next) { 238 | General.instantsendtoaddress(req.swagger.params, res, next); 239 | }; 240 | module.exports.getaddresstxids = function getaddresstxids (req, res, next) { 241 | General.getaddresstxids(req.swagger.params, res, next); 242 | }; 243 | 244 | module.exports.getblockhashes = function getblockhashes (req, res, next) { 245 | General.getblockhashes(req.swagger.params, res, next); 246 | }; 247 | 248 | module.exports.getblockhash = function getblockhash (req, res, next) { 249 | General.getblockhash(req.swagger.params, res, next); 250 | } 251 | 252 | module.exports.getblockheaders = function getblockheaders (req, res, next) { 253 | General.getblockheaders(req.swagger.params, res, next); 254 | }; 255 | 256 | module.exports.getchaintips = function getchaintips (req, res, next) { 257 | General.getchaintips(req.swagger.params, res, next); 258 | }; 259 | 260 | module.exports.getspentinfo = function getspentinfo (req, res, next) { 261 | General.getspentinfo(req.swagger.params, res, next); 262 | }; 263 | 264 | module.exports.getgovernanceinfo = function getgovernanceinfo (req, res, next) { 265 | General.getgovernanceinfo(req.swagger.params, res, next); 266 | }; 267 | 268 | module.exports.getpoolinfo = function getpoolinfo (req, res, next) { 269 | General.getpoolinfo(req.swagger.params, res, next); 270 | }; 271 | 272 | module.exports.getsuperblockbudget = function getsuperblockbudget (req, res, next) { 273 | General.getsuperblockbudget(req.swagger.params, res, next); 274 | }; 275 | 276 | module.exports.gobject = function gobject (req, res, next) { 277 | General.gobject(req.swagger.params, res, next); 278 | }; 279 | 280 | module.exports.masternode = function masternode (req, res, next) { 281 | General.masternode(req.swagger.params, res, next); 282 | }; 283 | 284 | module.exports.masternodebroadcast = function masternodebroadcast (req, res, next) { 285 | General.masternodebroadcast(req.swagger.params, res, next); 286 | }; 287 | 288 | module.exports.masternodelist = function masternodelist (req, res, next) { 289 | General.masternodelist(req.swagger.params, res, next); 290 | }; 291 | 292 | module.exports.fundrawtransaction = function masternodelist (req, res, next) { 293 | General.fundrawtransaction(req.swagger.params, res, next); 294 | }; 295 | 296 | module.exports.getblocktemplate = function masternodelist (req, res, next) { 297 | General.getblocktemplate(req.swagger.params, res, next); 298 | }; 299 | 300 | module.exports.signrawtransaction = function masternodelist (req, res, next) { 301 | General.signrawtransaction(req.swagger.params, res, next); 302 | }; 303 | 304 | module.exports.lockunspent = function masternodelist (req, res, next) { 305 | General.lockunspent(req.swagger.params, res, next); 306 | }; 307 | 308 | module.exports.getaddressutxos = function getaddressutxos (req, res, next) { 309 | General.getaddressutxos(req.swagger.params, res, next); 310 | }; 311 | 312 | module.exports.setaccount = function setaccount (req, res, next) { 313 | General.setaccount(req.swagger.params, res, next); 314 | }; 315 | 316 | module.exports.resendwallettransactions = function resendwallettransactions (req, res, next) { 317 | General.resendwallettransactions(req.swagger.params, res, next); 318 | }; -------------------------------------------------------------------------------- /server/nodejs/controllers/GeneralService.js: -------------------------------------------------------------------------------- 1 | const syscoinClient = require('../index').syscoinClient; 2 | const varUtils = require('./util/varUtils'); 3 | const commonUtils = require('./util/commonUtils'); 4 | const generalServiceGetInfoUtils = require('./util/generalServiceGetInfoUtils'); 5 | const methodGenerator = require('./util/methodGenerator'); 6 | 7 | module.exports = { 8 | addmultisigaddress: methodGenerator.generateGenericSyscoinMethod([ 9 | { prop: 'nrequired' }, 10 | { prop: 'keysobject', defaultValue: '' }, 11 | { prop: 'account', defaultValue: '' } 12 | ], syscoinClient.addMultiSigAddress, 'addmultisigaddress', 'POST'), 13 | 14 | dumpprivkey: methodGenerator.generateGenericSyscoinMethod([ 15 | { prop: 'address' } 16 | ], syscoinClient.dumpPrivKey, 'dumpprivkey', 'GET'), 17 | 18 | dumpwallet: methodGenerator.generateGenericSyscoinMethod([ 19 | { prop: 'filename' } 20 | ], syscoinClient.dumpWallet, 'dumpwallet', 'GET'), 21 | 22 | encryptwallet: methodGenerator.generateGenericSyscoinMethod([ 23 | { prop: 'passphrase' } 24 | ], syscoinClient.encryptWallet, 'encryptwallet', 'POST'), 25 | 26 | generate: methodGenerator.generateGenericSyscoinMethod([ 27 | { prop: 'numBlocks' }, 28 | { prop: 'maxtries', defaultValue: 1000000 } 29 | ], syscoinClient.generate, 'generate', 'GET'), 30 | 31 | generatepublickey: methodGenerator.generateGenericSyscoinMethod([], 32 | syscoinClient.generatepublickey, 'generatepublickey', 'GET'), 33 | 34 | getaccount: methodGenerator.generateGenericSyscoinMethod([ 35 | { prop: 'syscoinaddress' } 36 | ], syscoinClient.getAccount, 'getaccount', 'GET'), 37 | 38 | getaccountaddress: methodGenerator.generateGenericSyscoinMethod([ 39 | { prop: 'account' } 40 | ], syscoinClient.getAccountAddress, 'getaccountaddress', 'GET'), 41 | 42 | //Deprecated 43 | getaddressesbyaccount: methodGenerator.generateGenericSyscoinMethod([ 44 | { prop: 'account' } 45 | ], syscoinClient.getAddressesByAccount, 'getaddressesbyaccount', 'GET'), 46 | 47 | getbalance: methodGenerator.generateGenericSyscoinMethod([ 48 | { prop: 'account', defaultValue: '*' }, 49 | { prop: 'minconf', defaultValue: 1 }, 50 | { prop: 'addlockconf', defaultValue: false }, 51 | { prop: 'includeWatchonly', defaultValue: false } 52 | ], syscoinClient.getBalance, 'getbalance', 'GET'), 53 | 54 | getblock: methodGenerator.generateGenericSyscoinMethod([ 55 | { prop: 'hash', }, 56 | { prop: 'verbose', defaultValue: true } 57 | ], syscoinClient.getBlock, 'getblock', 'GET'), 58 | 59 | getblockchaininfo: methodGenerator.generateGenericSyscoinMethod( 60 | [], 61 | syscoinClient.getBlockchainInfo, 'getblockchaininfo', 'GET'), 62 | 63 | getblockcount: methodGenerator.generateGenericSyscoinMethod( 64 | [], 65 | syscoinClient.getBlockCount, 'getblockcount', 'GET'), 66 | 67 | /* 68 | * Leave this (getInfo) method untouched for now due to additional error handling. 69 | * TO-DO: Refactor taking the error handling into account 70 | */ 71 | getinfo: function (args, res) { 72 | var argList = []; 73 | var cb = function (err, result) { 74 | res.setHeader('Content-Type', 'application/json'); 75 | 76 | if (err) { 77 | let jsonError = commonUtils.parseError(err); 78 | if (generalServiceGetInfoUtils.getInfoResponseIsWalletPercentageResponse(jsonError)) { 79 | const walletPercentage = generalServiceGetInfoUtils.extractWalletPercentageFromGetInfoResponseMessage(jsonError.message); 80 | const infoObj = generalServiceGetInfoUtils.createCustomWalletPercentageInfoResponse(walletPercentage); 81 | commonUtils.log('Special Info:', infoObj, 'getinfo'); 82 | res.end(JSON.stringify(infoObj)); 83 | return; 84 | } 85 | else { 86 | return commonUtils.reportError(res, err); 87 | } 88 | } 89 | 90 | commonUtils.log('Info:', result, 'getinfo'); 91 | res.end(JSON.stringify(result)); 92 | }; 93 | 94 | var arr = varUtils.getArgsArr(argList, args, 'GET', cb); 95 | syscoinClient.getInfo.apply(syscoinClient, arr); 96 | }, 97 | 98 | getmempoolinfo: methodGenerator.generateGenericSyscoinMethod([ 99 | { prop: 'size' }, 100 | { prop: 'bytes' }, 101 | { prop: 'usage' }, 102 | { prop: 'maxmempool' }, 103 | { prop: 'mempoolminfee' } 104 | ],syscoinClient.getMemPoolInfo, 'getmempoolinfo','GET'), 105 | 106 | getdifficulty: methodGenerator.generateGenericSyscoinMethod( 107 | [], 108 | syscoinClient.getDifficulty, 'getdifficulty', 'GET'), 109 | 110 | getmininginfo: methodGenerator.generateGenericSyscoinMethod( 111 | [], 112 | syscoinClient.getMiningInfo, 'getmininginfo', 'GET'), 113 | 114 | getnetworkinfo: methodGenerator.generateGenericSyscoinMethod( 115 | [], 116 | syscoinClient.getNetworkInfo, 'getnetworkinfo', 'GET'), 117 | 118 | getnewaddress: methodGenerator.generateGenericSyscoinMethod([ 119 | { prop: 'account' } 120 | ], syscoinClient.getNewAddress, 'getnewaddress', 'POST'), 121 | 122 | getpeerinfo: methodGenerator.generateGenericSyscoinMethod([], 123 | syscoinClient.getPeerInfo, 'getpeerinfo', 'GET'), 124 | 125 | getreceivedbyaccount: methodGenerator.generateGenericSyscoinMethod([ 126 | { prop: 'account' }, 127 | { prop: 'minconf', defaultValue: 1 }, 128 | { prop: 'addlockconf', defaultValue: false } 129 | ], syscoinClient.getReceivedByAccount, 'getreceivedbyaccount', 'GET'), 130 | 131 | getreceivedbyaddress: methodGenerator.generateGenericSyscoinMethod([ 132 | { prop: 'syscoinaddress' }, 133 | { prop: 'minconf', defaultValue: 1 }, 134 | { prop: 'addlockconf', defaultValue: false } 135 | ], syscoinClient.getReceivedByAddress, 'getreceivedbyaddress', 'GET'), 136 | 137 | // gettransaction: methodGenerator.generateGenericSyscoinMethod([ 138 | // { prop: 'txid' }, 139 | // { prop: 'includeWatchonly', defaultValue: false } 140 | // ], syscoinClient.getTransaction, 'gettransaction', 'GET'), 141 | 142 | /* Note: Putting the old method back, as the one needs some update to work properly */ 143 | gettransaction: function(args, res, next) { 144 | /** 145 | * parameters expected in the args: 146 | * txid (String) 147 | * includeWatchonly (Boolean) 148 | **/ 149 | var argList = [ 150 | { prop: "txid" }, 151 | { prop: "includeWatchonly", defaultValue: false }, 152 | ]; 153 | 154 | var cb = function(err, result, resHeaders) { 155 | res.setHeader('Content-Type', 'application/json'); 156 | 157 | if (err) { 158 | //TODO: fix after b1 159 | return res.end(JSON.stringify(err.toString())); 160 | //return commonUtils.reportError(res, err); 161 | } 162 | 163 | commonUtils.log('Get transaction ', result, "gettransaction"); 164 | res.end(JSON.stringify(result)); 165 | }; 166 | 167 | var arr = varUtils.getArgsArr(argList, args, "GET", cb); 168 | syscoinClient.getTransaction.apply(syscoinClient, arr); 169 | }, 170 | 171 | getunconfirmedbalance: methodGenerator.generateGenericSyscoinMethod([], 172 | syscoinClient.getUnconfirmedBalance, 'getunconfirmedbalance', 'GET'), 173 | 174 | getwalletinfo: methodGenerator.generateGenericSyscoinMethod([], 175 | syscoinClient.getWalletInfo, 'getwalletinfo', 'GET'), 176 | 177 | importaddress: methodGenerator.generateGenericSyscoinMethod([ 178 | { prop: 'script' }, 179 | { prop: 'label', defaultValue: '' }, 180 | { prop: 'rescan', defaultValue: true }, 181 | { prop: 'p2sh', defaultValue: false } 182 | ], syscoinClient.importAddress, 'importaddress', 'POST'), 183 | 184 | importprivkey: methodGenerator.generateGenericSyscoinMethod([ 185 | { prop: 'syscoinprivkey' }, 186 | { prop: 'label', defaultValue: '' }, 187 | { prop: 'rescan', defaultValue: true } 188 | ], syscoinClient.importPrivKey, 'importprivkey', 'POST'), 189 | 190 | importpubkey: methodGenerator.generateGenericSyscoinMethod([ 191 | { prop: 'pubkey' }, 192 | { prop: 'label', defaultValue: '' }, 193 | { prop: 'rescan', defaultValue: true } 194 | ], syscoinClient.importPubKey, 'importpubkey', 'POST'), 195 | 196 | importwallet: methodGenerator.generateGenericSyscoinMethod([ 197 | { prop: 'filename' } 198 | ], syscoinClient.importWallet, 'importwallet', 'POST'), 199 | 200 | listaccounts: methodGenerator.generateGenericSyscoinMethod([ 201 | { prop: 'minconf', defaultValue: 1 }, 202 | { prop: 'addlockconf', defaultValue: false }, 203 | { prop: 'includeWatchonly', defaultValue: false } 204 | ], syscoinClient.listAccounts, 'listaccounts', 'GET'), 205 | 206 | listaddressgroupings: methodGenerator.generateGenericSyscoinMethod([], 207 | syscoinClient.listAddressGroupings, 'listaddressgroupings', 'GET'), 208 | 209 | listreceivedbyaccount: methodGenerator.generateGenericSyscoinMethod([ 210 | { prop: 'minconf', defaultValue: 0 }, 211 | { prop: 'addlockconf', defaultValue: false }, 212 | { prop: 'includeempty', defaultValue: false }, 213 | { prop: 'includeWatchonly', defaultValue: false } 214 | ], syscoinClient.listReceivedByAccount, 'listreceivedbyaccount', 'GET'), 215 | 216 | listreceivedbyaddress: methodGenerator.generateGenericSyscoinMethod([ 217 | { prop: 'minconf', defaultValue: 0 }, 218 | { prop: 'addlockconf', defaultValue: false }, 219 | { prop: 'includeempty', defaultValue: false }, 220 | { prop: 'includeWatchonly', defaultValue: false } 221 | ], syscoinClient.listReceivedByAddress, 'listreceivedbyaddress', 'GET'), 222 | 223 | listsinceblock: methodGenerator.generateGenericSyscoinMethod([ 224 | { prop: 'blockhash', defaultValue: '' }, 225 | { prop: 'targetConfirmations', defaultValue: 1 }, 226 | { prop: 'includeWatchonly', defaultValue: false } 227 | ], syscoinClient.listSinceBlock, 'listsinceblock', 'GET'), 228 | 229 | listtransactions: methodGenerator.generateGenericSyscoinMethod([ 230 | { prop: 'account', defaultValue: '*' }, 231 | { prop: 'count', defaultValue: 10 }, 232 | { prop: 'from', defaultValue: 0 }, 233 | { prop: 'includeWatchonly', defaultValue: false } 234 | ], syscoinClient.listTransactions, 'listtransactions', 'GET'), 235 | 236 | listunspent: methodGenerator.generateGenericSyscoinMethod([ 237 | { prop: 'minconf', defaultValue: 1 }, 238 | { prop: 'maxconf', defaultValue: 9999999 }, 239 | { prop: 'adresses', defaultValue: [] } 240 | ], syscoinClient.listUnspent, 'listunspent', 'GET'), 241 | 242 | //Deprecated 243 | move: methodGenerator.generateGenericSyscoinMethod([ 244 | { prop: 'fromaccount' }, 245 | { prop: 'toaccount' }, 246 | { prop: 'amount' }, 247 | { prop: 'minconf', defaultValue: 1 }, 248 | { prop: 'comment', defaultValue: '' } 249 | ], syscoinClient.move, 'move', 'POST'), 250 | 251 | //Deprecated 252 | sendfrom: methodGenerator.generateGenericSyscoinMethod([ 253 | { prop: 'fromaccount' }, 254 | { prop: 'tosyscoinaddress' }, 255 | { prop: 'amount' }, 256 | { prop: 'minconf', defaultValue: 1 }, 257 | { prop: 'addlockconf', defaultValue: false }, 258 | { prop: 'comment', defaultValue: '' }, 259 | { prop: 'commentto', defaultValue: '' } 260 | ], syscoinClient.sendFrom, 'sendfrom', 'POST'), 261 | 262 | sendmany: methodGenerator.generateGenericSyscoinMethod([ 263 | { prop: 'fromaccount' }, 264 | { prop: 'amounts' }, 265 | { prop: 'minconf', defaultValue: 1 }, 266 | { prop: 'addlockconf', defaultValue: false }, 267 | { prop: 'comment', defaultValue: '' }, 268 | { prop: 'subtractfeefromamount', defaultValue: [] }, 269 | { prop: 'use_is', defaultValue: false }, 270 | { prop: 'use_ps', defaultValue: false } 271 | ], syscoinClient.sendMany, 'sendmany', 'POST'), 272 | 273 | sendtoaddress: methodGenerator.generateGenericSyscoinMethod([ 274 | { prop: 'syscoinaddress' }, 275 | { prop: 'amount' }, 276 | { prop: 'comment' }, 277 | { prop: 'commentto' }, 278 | { prop: 'subtractfeefromamount', defaultValue: false }, 279 | { prop: 'use_is', defaultValue: false }, 280 | { prop: 'use_ps', defaultValue: false } 281 | ], syscoinClient.sendToAddress, 'sendtoaddress', 'POST'), 282 | 283 | signmessage: methodGenerator.generateGenericSyscoinMethod([ 284 | { prop: 'syscoinaddress' }, 285 | { prop: 'message' } 286 | ], syscoinClient.signMessage, 'signmessage', 'POST'), 287 | 288 | syscoindecoderawtransaction: methodGenerator.generateGenericSyscoinMethod([ 289 | { prop: 'hexstring' } 290 | ], syscoinClient.syscoinDecodeRawTransaction, 'syscoindecoderawtransaction', 'GET'), 291 | 292 | validateaddress: methodGenerator.generateGenericSyscoinMethod([ 293 | { prop: 'syscoinaddress' } 294 | ], syscoinClient.validateAddress, 'validateaddress', 'GET'), 295 | 296 | verifymessage: methodGenerator.generateGenericSyscoinMethod([ 297 | { prop: 'syscoinaddress' }, 298 | { prop: 'signature' }, 299 | { prop: 'message' } 300 | ], syscoinClient.verifyMessage, 'verifymessage', 'GET'), 301 | 302 | walletlock: methodGenerator.generateGenericSyscoinMethod([], 303 | syscoinClient.walletLock, 'walletlock', 'POST'), 304 | 305 | walletpassphrase: methodGenerator.generateGenericSyscoinMethod([ 306 | { prop: 'passphrase' }, 307 | { prop: 'timeout' } 308 | ], syscoinClient.walletPassphrase, 'walletpassphrase', 'POST'), 309 | 310 | walletpassphrasechange: methodGenerator.generateGenericSyscoinMethod([ 311 | { prop: 'oldpassphrase' }, 312 | { prop: 'newpassphrase' } 313 | ], syscoinClient.walletPassphraseChange, 'walletpassphrasechange', 'POST'), 314 | 315 | getaddressbalance: methodGenerator.generateGenericSyscoinMethod([ 316 | { prop: 'addresses' } 317 | ], syscoinClient.getAddressBalance, 'getaddressbalance', 'GET', true), 318 | 319 | getaddresstxids: methodGenerator.generateGenericSyscoinMethod([ 320 | { prop: 'addresses' }, 321 | { prop: 'start' }, 322 | { prop: 'end' } 323 | ], syscoinClient.getAddressTxids, 'getaddresstxids', 'GET', true), 324 | 325 | getblockhashes: methodGenerator.generateGenericSyscoinMethod([ 326 | { prop: 'high' }, 327 | { prop: 'low' } 328 | ], syscoinClient.getBlockHashes, 'getblockhashes', 'GET'), 329 | 330 | getblockhash: methodGenerator.generateGenericSyscoinMethod([ 331 | { prop: 'height' } 332 | ], syscoinClient.getBlockHash, 'getblockhash', 'GET'), 333 | 334 | getblockheaders: methodGenerator.generateGenericSyscoinMethod([ 335 | { prop: 'hash' }, 336 | { prop: 'count' }, 337 | { prop: 'verbose' } 338 | ], syscoinClient.getBlockHeaders, 'getblockheaders', 'GET'), 339 | 340 | getchaintips: methodGenerator.generateGenericSyscoinMethod([], 341 | syscoinClient.getChainTips, 'getchaintips', 'GET'), 342 | 343 | getspentinfo: methodGenerator.generateGenericSyscoinMethod([ 344 | { prop: 'txid' }, 345 | { prop: 'index' } 346 | ], syscoinClient.getSpentInfo, 'getspentinfo', 'GET', true), 347 | 348 | getgovernanceinfo: methodGenerator.generateGenericSyscoinMethod([], 349 | syscoinClient.getGovernanceInfo, 'getgovernanceinfo', 'GET'), 350 | 351 | getpoolinfo: methodGenerator.generateGenericSyscoinMethod([], 352 | syscoinClient.getPoolInfo, 'getpoolinfo', 'GET'), 353 | 354 | getsuperblockbudget: methodGenerator.generateGenericSyscoinMethod([ 355 | { prop: 'index' } 356 | ], syscoinClient.getSuperBlockBudget, 'getsuperblockbudget', 'GET'), 357 | 358 | gobject: methodGenerator.generateGenericSyscoinMethod([ 359 | { prop: 'command' } 360 | ], syscoinClient.gObject, 'gobject', 'GET'), 361 | 362 | masternode: methodGenerator.generateGenericSyscoinMethod([ 363 | { prop: 'command' } 364 | ], syscoinClient.masternode, 'masternode', 'GET'), 365 | 366 | masternodebroadcast: methodGenerator.generateGenericSyscoinMethod([ 367 | { prop: 'command' } 368 | ], syscoinClient.masternodeBroadcast, 'masternodebroadcast', 'GET'), 369 | 370 | masternodelist: methodGenerator.generateGenericSyscoinMethod([ 371 | { prop: 'mode' } 372 | ], syscoinClient.masternodeList, 'masternodelist', 'GET'), 373 | 374 | getaddressdeltas: methodGenerator.generateGenericSyscoinMethod([ 375 | { prop: 'addresses' }, 376 | { prop: 'start' }, 377 | { prop: 'end' } 378 | ], syscoinClient.getAddressDeltas, 'getaddressdeltas', 'GET', true), 379 | 380 | getaddressmempool: methodGenerator.generateGenericSyscoinMethod([ 381 | { prop: 'addresses' }, 382 | { prop: 'start' }, 383 | { prop: 'end' } 384 | ], syscoinClient.getAddressMempool, 'getaddressmempool', 'GET', true), 385 | 386 | syscoinsendrawtransaction: methodGenerator.generateGenericSyscoinMethod([ 387 | { prop: 'hexstring' }, 388 | { prop: 'allowhighfees' }, 389 | { prop: 'instantsend' } 390 | ], syscoinClient.syscoinSendRawTransaction, 'syscoinsendrawtransaction', 'POST'), 391 | 392 | getgenerate: methodGenerator.generateGenericSyscoinMethod([], 393 | syscoinClient.getGenerate, 'getgenerate', 'GET'), 394 | 395 | setgenerate: methodGenerator.generateGenericSyscoinMethod([ 396 | { prop: 'generate' }, 397 | { prop: 'genproclimit' } 398 | ], syscoinClient.setGenerate, 'setgenerate', 'GET'), 399 | 400 | setnetworkactive: methodGenerator.generateGenericSyscoinMethod([ 401 | { prop: 'state' } 402 | ], syscoinClient.setNetworkActive, 'setnetworkactive', 'GET'), 403 | 404 | mnsync: methodGenerator.generateGenericSyscoinMethod([ 405 | { prop: 'command' } 406 | ], syscoinClient.mnSync, 'mnsync', 'GET'), 407 | 408 | dumphdinfo: methodGenerator.generateGenericSyscoinMethod([], 409 | syscoinClient.dumpHdInfo, 'dumphdinfo', 'GET'), 410 | 411 | debug: methodGenerator.generateGenericSyscoinMethod([ 412 | { prop: 'command' } 413 | ], syscoinClient.debug, 'debug', 'GET'), 414 | 415 | instantsendtoaddress: methodGenerator.generateGenericSyscoinMethod([ 416 | { prop: 'syscoinaddress' }, 417 | { prop: 'amount' }, 418 | { prop: 'comment' }, 419 | { prop: 'comment-to' }, 420 | { prop: 'subtractfeefromamount' } 421 | ], syscoinClient.instantSendToAddress, 'instantsendtoaddress', 'POST'), 422 | 423 | fundrawtransaction: methodGenerator.generateGenericSyscoinMethod([ 424 | { prop: 'hexstring' }, 425 | { prop: 'watching' } 426 | ], syscoinClient.fundRawTransaction, 'fundrawtransaction', 'POST'), 427 | 428 | getblocktemplate: methodGenerator.generateGenericSyscoinMethod([], 429 | syscoinClient.getBlockTemplate, 'getblocktemplate', 'GET'), 430 | 431 | signrawtransaction: methodGenerator.generateGenericSyscoinMethod([ 432 | { prop: 'hexstring' } 433 | ], syscoinClient.signRawTransaction, 'signrawtransaction', 'POST'), 434 | 435 | lockunspent: methodGenerator.generateGenericSyscoinMethod([ 436 | { prop: 'unlock' }, 437 | { prop: 'transactions' } 438 | ], syscoinClient.lockUnspent, 'lockunspent', 'POST'), 439 | 440 | syscoinlistreceivedbyaddress: methodGenerator.generateGenericSyscoinMethod([], 441 | syscoinClient.syscoinListReceivedByAddress, 'syscoinlistreceivedbyaddress', 'GET'), 442 | 443 | getaddressutxos: methodGenerator.generateGenericSyscoinMethod([ 444 | { prop: 'addresses' } 445 | ], syscoinClient.getAddressUtxos, 'getaddressutxos', 'GET'), 446 | 447 | setaccount: methodGenerator.generateGenericSyscoinMethod([ 448 | { prop: 'address'}, 449 | { prop: 'account'} 450 | ], syscoinClient.setAccount, 'setaccount', 'POST'), 451 | 452 | resendwallettransactions: methodGenerator.generateGenericSyscoinMethod([], 453 | syscoinClient.resendWalletTransactions, 'resendwallettransactions', 'GET') 454 | }; -------------------------------------------------------------------------------- /server/nodejs/controllers/Masternodes.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var MasterNode = require('./MasternodesService'); 4 | 5 | module.exports.sentinelping = function sentinelping (req, res, next) { 6 | MasterNode.sentinelping(req.swagger.params, res, next); 7 | }; 8 | 9 | module.exports.voteraw = function voteraw (req, res, next) { 10 | MasterNode.voteraw(req.swagger.params, res, next); 11 | }; 12 | 13 | module.exports.privatesend = function privatesend (req, res, next) { 14 | MasterNode.privatesend(req.swagger.params, res, next); 15 | }; 16 | 17 | module.exports.importelectrumwallet = function importelectrumwallet (req, res, next) { 18 | MasterNode.importelectrumwallet(req.swagger.params, res, next); 19 | }; 20 | -------------------------------------------------------------------------------- /server/nodejs/controllers/MasternodesService.js: -------------------------------------------------------------------------------- 1 | const syscoinClient = require('../index').syscoinClient; 2 | const methodGenerator = require('./util/methodGenerator'); 3 | 4 | module.exports = { 5 | sentinelping: methodGenerator.generateGenericSyscoinMethod([ 6 | { prop: "version" } 7 | ], syscoinClient.sentinelPing, 'sentinelping', 'GET'), 8 | 9 | voteraw: methodGenerator.generateGenericSyscoinMethod([ 10 | { prop: "masternode-tx-hash" }, 11 | { prop: "masternode-tx-index" }, 12 | { prop: "governance-hash" }, 13 | { prop: "vote-signal" }, 14 | { prop: "vote-outcome" }, 15 | { prop: "time" }, 16 | { prop: "vote-sig" } 17 | ], syscoinClient.voteRaw, 'voteraw', 'POST'), 18 | 19 | privatesend: methodGenerator.generateGenericSyscoinMethod([ 20 | { prop: "command" } 21 | ], syscoinClient.privateSend, 'privatesend', 'GET'), 22 | 23 | 24 | importelectrumwallet: methodGenerator.generateGenericSyscoinMethod([ 25 | { prop: "filename" }, 26 | { prop: "index", defaultValue: 0 } 27 | ], syscoinClient.importElectrumWallet, 'importelectrumwallet', 'GET') 28 | } -------------------------------------------------------------------------------- /server/nodejs/controllers/Offers.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | 4 | var Offers = require('./OffersService'); 5 | 6 | module.exports.offerinfo = function offerinfo (req, res, next) { 7 | Offers.offerinfo(req.swagger.params, res, next); 8 | }; 9 | 10 | module.exports.offerlink = function offerlink (req, res, next) { 11 | Offers.offerlink(req.swagger.params, res, next); 12 | }; 13 | 14 | module.exports.offernew = function offernew (req, res, next) { 15 | Offers.offernew(req.swagger.params, res, next); 16 | }; 17 | 18 | module.exports.offerupdate = function offerupdate (req, res, next) { 19 | Offers.offerupdate(req.swagger.params, res, next); 20 | }; 21 | -------------------------------------------------------------------------------- /server/nodejs/controllers/OffersService.js: -------------------------------------------------------------------------------- 1 | const syscoinClient = require('../index').syscoinClient; 2 | const methodGenerator = require('./util/methodGenerator'); 3 | 4 | module.exports = { 5 | 6 | offerinfo: methodGenerator.generateGenericSyscoinMethod([ 7 | { prop: 'guid' } 8 | ], syscoinClient.offerInfo, 'offerinfo', 'GET'), 9 | 10 | offerlink: methodGenerator.generateGenericSyscoinMethod([ 11 | { prop: 'alias' }, 12 | { prop: 'guid' }, 13 | { prop: 'commission' }, 14 | { prop: 'description' }, 15 | { prop: 'witness' } 16 | ], syscoinClient.offerLink, 'offerlink', 'POST'), 17 | 18 | offernew: methodGenerator.generateGenericSyscoinMethod([ 19 | { prop: 'alias' }, 20 | { prop: 'category' }, 21 | { prop: 'title' }, 22 | { prop: 'quantity' }, 23 | { prop: 'price' }, 24 | { prop: 'description' }, 25 | { prop: 'currency' }, 26 | { prop: 'cert_guid' }, 27 | { prop: 'payment_options' }, 28 | { prop: 'privatevalue' }, 29 | { prop: 'units' }, 30 | { prop: 'offertype' }, 31 | { prop: 'auction_expires' }, 32 | { prop: 'auction_reserve' }, 33 | { prop: 'auction_require_witness' }, 34 | { prop: 'auction_deposit' }, 35 | { prop: 'witness' } 36 | ], syscoinClient.offerNew, 'offernew', 'POST'), 37 | 38 | offerupdate: methodGenerator.generateGenericSyscoinMethod([ 39 | { prop: 'alias' }, 40 | { prop: 'guid' }, 41 | { prop: 'category' }, 42 | { prop: 'title' }, 43 | { prop: 'quantity' }, 44 | { prop: 'price' }, 45 | { prop: 'description' }, 46 | { prop: 'currency' }, 47 | { prop: 'privatevalue' }, 48 | { prop: 'cert_guid' }, 49 | { prop: 'commission' }, 50 | { prop: 'payment_options' }, 51 | { prop: 'offer_type' }, 52 | { prop: 'auction_expires' }, 53 | { prop: 'auction_reserve' }, 54 | { prop: 'auction_require_witness' }, 55 | { prop: 'auction_deposit' }, 56 | { prop: 'witness' } 57 | ], syscoinClient.offerUpdate, 'offerupdate', 'POST') 58 | 59 | }; -------------------------------------------------------------------------------- /server/nodejs/controllers/spec/AliasesService.spec.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect; 2 | var rp = require('request-promise'); 3 | 4 | var AuthHelper = require('./helper/authHelper'); 5 | var VerifyHelper = require('./helper/verifyHelper'); 6 | var Config = require('../../spec/config'); 7 | 8 | describe('Aliases Service API', function() { 9 | 10 | describe('aliasauthenticate', function () { 11 | it('Returns privkey when authenticating with valid alias and password', function (done) { 12 | var url = Config.HOST + 'aliasauthenticate'; 13 | var requestOptions = AuthHelper.requestOptions(); 14 | requestOptions.qs = { 15 | 'alias': Config.TEST_ALIAS, 16 | 'password': Config.TEST_ALIAS_PASSWORD 17 | }; 18 | 19 | rp(url, requestOptions).then(function (result) { 20 | expect(result.statusCode).to.equal(200); 21 | 22 | var privkey = JSON.parse(result.body); 23 | expect(privkey.privatekey).to.exist; 24 | done(); 25 | }); 26 | }); 27 | }); 28 | 29 | describe('aliashistory', function () { 30 | it('Returns history information for a given alias', function (done) { 31 | this.timeout(8000); 32 | var url = Config.HOST + 'aliashistory'; 33 | var requestOptions = AuthHelper.requestOptions(); 34 | requestOptions.qs = { 35 | 'aliasname': Config.TEST_ALIAS 36 | }; 37 | 38 | rp(url, requestOptions).then(function (result) { 39 | expect(result.statusCode).to.equal(200); 40 | 41 | var aliasHistoryList = JSON.parse(result.body); 42 | for(var i = 0; i < aliasHistoryList.length; i++) { 43 | expect(aliasHistoryList[i].type).to.exist; 44 | expect(aliasHistoryList[i].balance).to.be.at.least(0); 45 | } 46 | done(); 47 | }); 48 | }); 49 | }); 50 | 51 | describe('aliasinfo', function () { 52 | it('Returns info for alias', function (done) { 53 | var url = Config.HOST + 'aliasinfo'; 54 | var requestOptions = AuthHelper.requestOptions(); 55 | requestOptions.qs = { 56 | 'aliasname': Config.TEST_ALIAS 57 | }; 58 | 59 | rp(url, requestOptions).then(function (result) { 60 | expect(result.statusCode).to.equal(200); 61 | 62 | var alias = JSON.parse(result.body); 63 | expect(alias.name).to.exist; 64 | expect(alias.balance).to.be.at.least(0); 65 | done(); 66 | }); 67 | }); 68 | }); 69 | 70 | describe('aliasexists', function() { 71 | it('Returns boolean whether alias exists', function (done) { 72 | var url = Config.HOST + 'aliasexists'; 73 | var requestOptions = AuthHelper.requestOptions(); 74 | requestOptions.qs = { 75 | 'aliasname': Config.TEST_ALIAS 76 | }; 77 | 78 | rp(url, requestOPtions).then(function (result) { 79 | expect(result.statusCode).to.equal(200); 80 | 81 | var alias = JSON.parse(result.body); 82 | expect(alias.name).to.exist; 83 | expect(alias.balance).to.be.at.least(0); 84 | done(); 85 | }); 86 | }); 87 | }); 88 | 89 | describe('aliaslist', function () { 90 | it('Returns all aliases this wallet controls', function (done) { 91 | var url = Config.HOST + 'aliaslist'; 92 | var requestOptions = AuthHelper.requestOptions(); 93 | 94 | rp(url, requestOptions).then(function (result) { 95 | expect(result.statusCode).to.equal(200); 96 | 97 | var aliasList = JSON.parse(result.body); 98 | for(var i = 0; i < aliasList.length; i++) { 99 | expect(aliasList[i].name).to.exist; 100 | expect(aliasList[i].balance).to.be.at.least(0); 101 | } 102 | done(); 103 | }); 104 | }); 105 | }); 106 | 107 | describe('aliasnew', function () { 108 | it('Returns alias tx id and guid', function (done) { 109 | var url = Config.HOST + 'aliasnew'; 110 | var requestOptions = AuthHelper.requestOptions(); 111 | requestOptions.method = 'POST'; 112 | requestOptions.json = { 113 | 'aliaspeg': Config.TEST_ALIAS_PEG, 114 | 'aliasname': Config.TEST_ALIAS + Date.now().toString() + '.test', 115 | 'publicvalue': 'test public value', 116 | 'privatevalue': 'test private value', 117 | 'password': '', 118 | 'safesearch': 'Yes', 119 | 'accepttransfers': 'Yes', 120 | 'expire': '10000', 121 | 'nrequired': 0, 122 | 'aliases': [] 123 | }; 124 | 125 | rp(url, requestOptions).then(function (result) { 126 | expect(result.statusCode).to.equal(200); 127 | var newAliasInfo = result.body; 128 | VerifyHelper.verifyTransactionId(newAliasInfo[0]); 129 | VerifyHelper.verifyAliasNewTransactionId(newAliasInfo[1]); 130 | done(); 131 | }); 132 | }); 133 | }); 134 | 135 | describe('aliasupdate', function () { 136 | it('Returns update txid', function (done) { 137 | var url = Config.HOST + 'aliasupdate'; 138 | var requestOptions = AuthHelper.requestOptions(); 139 | requestOptions.method = 'POST'; 140 | requestOptions.json = { 141 | 'aliaspeg': Config.TEST_ALIAS_PEG, 142 | 'aliasname': Config.TEST_ALIAS, 143 | 'publicvalue': 'test public value ' + Date.now().toString() 144 | }; 145 | 146 | rp(url, requestOptions).then(function (result) { 147 | expect(result.statusCode).to.equal(200); 148 | var txid = result.body[0]; 149 | VerifyHelper.verifyTransactionId(txid); 150 | done(); 151 | }); 152 | }); 153 | }); 154 | }); -------------------------------------------------------------------------------- /server/nodejs/controllers/spec/BlockmarketService.spec.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect; 2 | var rp = require('request-promise'); 3 | var Hashes = require('jshashes'); 4 | 5 | var AuthHelper = require('./helper/authHelper'); 6 | var Config = require('../../spec/config'); 7 | 8 | describe('Blockmarket Service API', function() { 9 | 10 | describe('login', function () { 11 | it('Returns a token when proper user/pass supplied', function (done) { 12 | var url = Config.HOST + 'login'; 13 | var auth = new Hashes.SHA1().hex('u' + 'p'); 14 | var requestOptions = AuthHelper.requestOptions(); 15 | requestOptions.qs = { 16 | 'auth': auth 17 | }; 18 | 19 | rp(url, requestOptions).then(function (result) { 20 | expect(result.statusCode).to.equal(200); 21 | 22 | var authResult = JSON.parse(result.body); 23 | expect(authResult.token).to.exist; 24 | done(); 25 | }); 26 | }); 27 | 28 | it('Returns an error when invalid user/pass supplied', function (done) { 29 | var url = Config.HOST + 'login'; 30 | var auth = new Hashes.SHA1().hex('WRONGUSER' + 'WRONGPASS'); 31 | var requestOptions = AuthHelper.requestOptions(); 32 | requestOptions.qs = { 33 | 'auth': auth 34 | }; 35 | 36 | rp(url, requestOptions) 37 | .then(function () {}, 38 | function(error) { 39 | expect(error.statusCode).to.equal(401); 40 | 41 | var authResult = JSON.parse(error.response.body); 42 | expect(authResult.success).to.equal(false); 43 | done(); 44 | }); 45 | }); 46 | }); 47 | }); -------------------------------------------------------------------------------- /server/nodejs/controllers/spec/CertificatesService.spec.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect; 2 | var rp = require('request-promise'); 3 | 4 | var AuthHelper = require('./helper/authHelper'); 5 | var VerifyHelper = require('./helper/verifyHelper'); 6 | var Config = require('../../spec/config'); 7 | 8 | describe('Certificate Service API', function() { 9 | 10 | describe('certhistory', function () { 11 | it('Returns history info for certificate', function (done) { 12 | var url = Config.HOST + 'certhistory'; 13 | var requestOptions = AuthHelper.requestOptions(); 14 | requestOptions.qs = { 15 | 'certname': Config.TEST_CERT_GUID 16 | }; 17 | 18 | rp(url, requestOptions).then(function (result) { 19 | expect(result.statusCode).to.equal(200); 20 | 21 | var certHistoryList = JSON.parse(result.body); 22 | for(var i = 0; i < certHistoryList.length; i++) { 23 | expect(certHistoryList[i].certtype).to.exist; 24 | expect(certHistoryList[i].height).to.be.at.least(1); 25 | } 26 | done(); 27 | }); 28 | }); 29 | }); 30 | 31 | describe('certinfo', function () { 32 | it('Returns info about certificate', function (done) { 33 | var url = Config.HOST + 'certinfo'; 34 | var requestOptions = AuthHelper.requestOptions(); 35 | requestOptions.qs = { 36 | 'guid': Config.TEST_CERT_GUID 37 | }; 38 | 39 | rp(url, requestOptions).then(function (result) { 40 | expect(result.statusCode).to.equal(200); 41 | 42 | var cert = JSON.parse(result.body); 43 | expect(cert.title).to.exist; 44 | expect(cert.height).to.be.at.least(1); 45 | done(); 46 | }); 47 | }); 48 | }); 49 | 50 | describe('certlist', function () { 51 | it('Returns list of all certificates this wallet owns', function (done) { 52 | var url = Config.HOST + 'certlist'; 53 | var requestOptions = AuthHelper.requestOptions(); 54 | requestOptions.qs = { 55 | 'aliases': [Config.TEST_ALIAS] 56 | }; 57 | 58 | rp(url, requestOptions).then(function (result) { 59 | expect(result.statusCode).to.equal(200); 60 | 61 | var certList = JSON.parse(result.body); 62 | expect(certList.length).to.be.at.least(1); 63 | for(var i = 0; i < certList.length; i++) { 64 | expect(certList[i].title).to.exist; 65 | expect(certList[i].height).to.be.at.least(1); 66 | } 67 | done(); 68 | }); 69 | }); 70 | }); 71 | 72 | describe('certnew', function () { 73 | it('Returns tx id and guid of new certificate', function (done) { 74 | var url = Config.HOST + 'certnew'; 75 | var requestOptions = AuthHelper.requestOptions(); 76 | requestOptions.method = 'POST'; 77 | requestOptions.json = { 78 | 'alias': Config.TEST_ALIAS, 79 | 'title': 'Unit Test Cert ' + Date.now().toString(), 80 | 'private': 'Some private date', 81 | 'public': 'Some public data', 82 | 'safesearch': 'Yes', 83 | 'category': 'certificates' 84 | }; 85 | 86 | rp(url, requestOptions).then(function (result) { 87 | expect(result.statusCode).to.equal(200); 88 | var newCertInfo = result.body; 89 | VerifyHelper.verifyTransactionId(newCertInfo[0]); 90 | VerifyHelper.verifySyscoinGUID(newCertInfo[1]); 91 | done(); 92 | }); 93 | }); 94 | }); 95 | 96 | describe('certupdate', function () { 97 | it('Returns certificate update tx id', function (done) { 98 | var url = Config.HOST + 'certupdate'; 99 | var requestOptions = AuthHelper.requestOptions(); 100 | requestOptions.method = 'POST'; 101 | requestOptions.json = { 102 | 'guid': Config.TEST_CERT_GUID, 103 | 'alias': Config.TEST_ALIAS, 104 | 'title': 'Unit Test Cert', 105 | 'private': 'Private date ' + Date.now().toString(), 106 | 'public': 'Public data' + Date.now().toString(), 107 | 'safesearch': 'Yes', 108 | 'category': 'certificates' /* MUST BE THIS STRING! */ 109 | }; 110 | 111 | rp(url, requestOptions).then(function (result) { 112 | expect(result.statusCode).to.equal(200); 113 | var txid = result.body[0]; 114 | VerifyHelper.verifyTransactionId(txid); 115 | done(); 116 | }); 117 | }); 118 | }); 119 | }); -------------------------------------------------------------------------------- /server/nodejs/controllers/spec/EscrowService.spec.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect; 2 | var rp = require('request-promise'); 3 | 4 | var AuthHelper = require('./helper/authHelper'); 5 | var DataHelper = require('./helper/dataHelper'); 6 | var Config = require('../../spec/config'); 7 | 8 | describe('Escrow Service API', function() { 9 | 10 | describe('escrowhistory', function () { 11 | this.timeout(60 * 1000); //increase timeout in the case of long escrow history 12 | it('Returns history of given escrow', function (done) { 13 | var url = Config.HOST + 'escrowhistory'; 14 | var requestOptions = AuthHelper.requestOptions(); 15 | requestOptions.qs = { 16 | 'escrow': Config.TEST_ESCROW_GUID 17 | }; 18 | 19 | rp(url, requestOptions).then(function (result) { 20 | expect(result.statusCode).to.equal(200); 21 | 22 | var escrowHistoryList = JSON.parse(result.body); 23 | expect(escrowHistoryList.length).to.be.at.least(1); 24 | for(var i = 0; i < escrowHistoryList.length; i++) { 25 | expect(escrowHistoryList[i].escrowtype).to.exist; 26 | expect(escrowHistoryList[i].quantity).to.be.at.least(1); 27 | expect(escrowHistoryList[i].price).to.be.at.least(0); 28 | } 29 | done(); 30 | }); 31 | }); 32 | }); 33 | 34 | describe('escrowinfo', function () { 35 | it('Returns info about escrow', function (done) { 36 | var url = Config.HOST + 'escrowinfo'; 37 | var requestOptions = AuthHelper.requestOptions(); 38 | requestOptions.qs = { 39 | 'escrow': Config.TEST_ESCROW_GUID 40 | }; 41 | 42 | rp(url, requestOptions).then(function (result) { 43 | expect(result.statusCode).to.equal(200); 44 | 45 | var escrow = JSON.parse(result.body); 46 | expect(escrow.escrowtype).to.exist; 47 | expect(escrow.height).to.be.at.least(1); 48 | done(); 49 | }); 50 | }); 51 | }); 52 | 53 | describe('escrowlist', function () { 54 | this.timeout(60 * 1000); //increase timeout in the case of long escrow history 55 | it('Returns list of all escrows', function (done) { 56 | var url = Config.HOST + 'escrowlist'; 57 | var requestOptions = AuthHelper.requestOptions(); 58 | requestOptions.qs = { 59 | 'aliases': [Config.TEST_ALIAS] 60 | }; 61 | 62 | rp(url, requestOptions).then(function (result) { 63 | expect(result.statusCode).to.equal(200); 64 | 65 | var escrowList = JSON.parse(result.body); 66 | expect(escrowList.length).to.be.at.least(1); 67 | for(var i = 0; i < escrowList.length; i++) { 68 | expect(escrowList[i].escrow).to.exist; 69 | expect(escrowList[i].total).to.be.at.least(0); 70 | } 71 | done(); 72 | }); 73 | }); 74 | }); 75 | 76 | describe('escrownew', function () { 77 | it('Returns a tx id and guid of new escrow', function (done) { 78 | DataHelper.escrowNew(Config.TEST_ALIAS, Config.TEST_OFFER_GUID, 1, 'buying with escrow via unit test', Config.TEST_ALIAS).then(function(result){ 79 | expect(result.response.statusCode).to.equal(200); 80 | expect(result.tx.length).to.equal(2); 81 | expect(result.tx[0].length).to.equal(64); //tx id 82 | expect(result.tx[1].length).to.equal(16); //escrow guid 83 | done(); 84 | }); 85 | }); 86 | }); 87 | }); -------------------------------------------------------------------------------- /server/nodejs/controllers/spec/GeneralService.spec.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect; 2 | var rp = require('request-promise'); 3 | 4 | var AuthHelper = require('./helper/authHelper'); 5 | var DataHelper = require('./helper/dataHelper'); 6 | var VerifyHelper = require('./helper/verifyHelper'); 7 | var Config = require('../../spec/config'); 8 | 9 | describe('General Service API', function() { 10 | 11 | describe('getaccount', function() { 12 | it('Returns account name', function(done) { 13 | DataHelper.getAccountAddress('').then(function(getAddressResult) { 14 | url = Config.HOST + 'getaccount'; 15 | requestOptions = AuthHelper.requestOptions(); 16 | requestOptions.qs = { 17 | 'syscoinaddress': getAddressResult.address 18 | }; 19 | 20 | rp(url, requestOptions).then(function(result) { 21 | expect(result.statusCode).to.equal(200); 22 | expect(result.body).to.equal('""'); 23 | done(); 24 | }); 25 | }); 26 | }); 27 | }); 28 | 29 | describe('getaccountaddress', function() { 30 | it('Returns syscoin address', function(done) { 31 | DataHelper.getAccountAddress('').then(function(getAddressResult) { 32 | console.info('Got root account address: ' + getAddressResult.address); 33 | VerifyHelper.verifySyscoinAddress(getAddressResult.address); 34 | done(); 35 | }); 36 | }); 37 | }); 38 | 39 | describe('getaddressesbyaccount', function() { 40 | it('Returns list of addresses', function(done) { 41 | var url = Config.HOST + 'getaddressesbyaccount'; 42 | var requestOptions = AuthHelper.requestOptions(); 43 | requestOptions.qs = { 44 | 'account': '' 45 | }; 46 | 47 | rp(url, requestOptions).then(function (result) { 48 | expect(result.statusCode).to.equal(200); 49 | 50 | var addresslist = JSON.parse(result.body); 51 | expect(addresslist.length).to.be.at.least(1); 52 | done(); 53 | }); 54 | }); 55 | }); 56 | 57 | describe('getbalance', function() { 58 | it('Returns balance', function(done) { 59 | url = Config.HOST + 'getbalance'; 60 | var requestOptions = AuthHelper.requestOptions(); 61 | requestOptions.qs = { 62 | 'account': '*' 63 | }; 64 | 65 | rp(url, requestOptions).then(function(result) { 66 | expect(result.statusCode).to.equal(200); 67 | expect(result.body).to.be.at.least(0); 68 | done(); 69 | }); 70 | }); 71 | }); 72 | 73 | describe('getinfo', function() { 74 | it('Returns an object with the version property defined', function(done) { 75 | var url = Config.HOST + 'getinfo'; 76 | rp(url, AuthHelper.requestOptions()).then(function(result) { 77 | var info = JSON.parse(result.body); 78 | expect(result.statusCode).to.equal(200); 79 | expect(info.sysversion).to.not.equal(undefined); 80 | done(); 81 | }); 82 | }); 83 | }); 84 | 85 | describe('getmininginfo', function() { 86 | it('Returns object with hashrate', function(done) { 87 | var url = Config.HOST + 'getmininginfo'; 88 | rp(url, AuthHelper.requestOptions()).then(function(result) { 89 | var info = JSON.parse(result.body); 90 | expect(result.statusCode).to.equal(200); 91 | expect(info.networkhashps).to.not.equal(undefined); 92 | done(); 93 | }); 94 | }); 95 | }); 96 | 97 | describe('getnewaddress', function() { 98 | it('Returns new address for default account', function(done) { 99 | var url = Config.HOST + 'getnewaddress'; 100 | var requestOptions = AuthHelper.requestOptions(); 101 | requestOptions.method = 'POST'; 102 | requestOptions.json = { 103 | 'account': '' 104 | }; 105 | 106 | rp(url, requestOptions).then(function(result) { 107 | expect(result.statusCode).to.equal(200); 108 | VerifyHelper.verifySyscoinAddress(result.body); 109 | done(); 110 | }); 111 | }); 112 | }); 113 | 114 | describe('getreceivedbyaddress', function() { 115 | it('Returns total received by a syscoin address', function(done) { 116 | DataHelper.getAccountAddress('').then(function(getAddressResult) { 117 | var url = Config.HOST + 'getreceivedbyaddress'; 118 | var requestOptions = AuthHelper.requestOptions(); 119 | requestOptions.qs = { 120 | 'syscoinaddress': getAddressResult.address 121 | }; 122 | 123 | rp(url, requestOptions).then(function(result) { 124 | expect(result.statusCode).to.equal(200); 125 | expect(result.body).to.be.at.least(0); 126 | done(); 127 | }); 128 | }); 129 | }); 130 | }); 131 | 132 | describe('gettransaction', function() { 133 | it('Returns a transaction object', function(done) { 134 | DataHelper.getAccountAddress('').then(function(getAddressResult) { 135 | DataHelper.sendSyscoin(getAddressResult.address, 1).then(function(sendResult) { 136 | console.info('Transaction id: ' + sendResult.txid); 137 | VerifyHelper.verifyTransactionId(sendResult.txid); 138 | done(); 139 | }); 140 | }); 141 | }); 142 | }); 143 | 144 | describe('getwalletinfo', function() { 145 | it('Returns wallet info', function(done) { 146 | var url = Config.HOST + 'getwalletinfo'; 147 | rp(url, AuthHelper.requestOptions()).then(function(result) { 148 | var info = JSON.parse(result.body); 149 | expect(result.statusCode).to.equal(200); 150 | expect(info.walletversion).to.equal(130000); 151 | expect(info.balance).to.be.at.least(0); 152 | done(); 153 | }); 154 | }); 155 | }); 156 | 157 | describe('listaccounts', function() { 158 | it('Returns a list of accounts', function(done) { 159 | var url = Config.HOST + 'listaccounts'; 160 | rp(url, AuthHelper.requestOptions()).then(function(result) { 161 | var accountList = JSON.parse(result.body); 162 | var accountCount = 0; 163 | expect(result.statusCode).to.equal(200); 164 | 165 | for(var account in accountList) { 166 | expect(accountList[account]).to.exist; //bitcoin account sucks and is being deprecated so just make sure this exists, its value can be negative. 167 | accountCount++; 168 | } 169 | 170 | expect(accountCount).to.be.at.least(1); 171 | done(); 172 | }); 173 | }); 174 | }); 175 | 176 | describe('listreceivedbyaddress', function() { 177 | it('Returns a list of object with balances per address', function(done) { 178 | var url = Config.HOST + 'listreceivedbyaddress'; 179 | rp(url, AuthHelper.requestOptions()).then(function(result) { 180 | var addressList = JSON.parse(result.body); 181 | var addressCount = 0; 182 | expect(result.statusCode).to.equal(200); 183 | 184 | for(var address in addressList) { 185 | expect(addressList[address].amount).to.be.at.least(0); 186 | addressCount++; 187 | } 188 | 189 | expect(addressCount).to.be.at.least(1); 190 | done(); 191 | }); 192 | }); 193 | }); 194 | 195 | 196 | describe('listtransactions', function() { 197 | it('Returns a list of transactions', function(done) { 198 | var url = Config.HOST + 'listtransactions'; 199 | var requestOptions = AuthHelper.requestOptions(); 200 | var account = ''; 201 | requestOptions.qs = { 202 | account: account 203 | }; 204 | 205 | rp(url, requestOptions).then(function(result) { 206 | var txList = JSON.parse(result.body); 207 | var txCount = 0; 208 | expect(result.statusCode).to.equal(200); 209 | 210 | for(var tx in txList) { 211 | expect(txList[tx].account).to.equal(account); 212 | txCount++; 213 | } 214 | 215 | expect(txCount).to.be.at.least(1); 216 | done(); 217 | }); 218 | }); 219 | }); 220 | 221 | describe('sendtoaddress', function() { 222 | it('Returns a transaction id for sending to an address', function(done) { 223 | DataHelper.getAccountAddress('').then(function(getAddressResult) { 224 | DataHelper.sendSyscoin(getAddressResult.address, 1).then(function(sendResult) { 225 | expect(sendResult.response.statusCode).to.equal(200); 226 | VerifyHelper.verifyTransactionId(sendResult.txid); 227 | done(); 228 | }); 229 | }); 230 | }); 231 | }); 232 | 233 | describe('signmessage', function() { 234 | it('Returns a message signature', function(done) { 235 | DataHelper.getAccountAddress('').then(function(getAddressResult) { 236 | DataHelper.signMessage(getAddressResult.address, 'test').then(function(signResult) { 237 | expect(signResult.response.statusCode).to.equal(200); 238 | expect(signResult.signature[signResult.signature.length-1]).to.equal('='); 239 | done(); 240 | }); 241 | }); 242 | }); 243 | }); 244 | 245 | describe('verifymessage', function() { 246 | it('Returns whether a message signature is valid', function(done) { 247 | var message = 'test'; 248 | 249 | DataHelper.getAccountAddress('').then(function(getAddressResult) { 250 | DataHelper.signMessage(getAddressResult.address, message).then(function(signResult) { 251 | expect(signResult.signature[signResult.signature.length-1]).to.equal('='); 252 | 253 | var url = Config.HOST + 'verifymessage'; 254 | var requestOptions = AuthHelper.requestOptions(); 255 | requestOptions.qs = { 256 | 'syscoinaddress': getAddressResult.address, 257 | 'signature': signResult.signature, 258 | 'message': message 259 | }; 260 | 261 | rp(url, requestOptions).then(function(result) { 262 | expect(result.statusCode).to.equal(200); 263 | expect(JSON.parse(result.body)).to.equal(true); 264 | done(); 265 | }); 266 | }); 267 | }); 268 | }); 269 | }); 270 | 271 | }); -------------------------------------------------------------------------------- /server/nodejs/controllers/spec/MessagingService.spec.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect; 2 | var rp = require('request-promise'); 3 | 4 | var AuthHelper = require('./helper/authHelper'); 5 | var VerifyHelper = require('./helper/verifyHelper'); 6 | var Config = require('../../spec/config'); 7 | 8 | describe('Messaging Service API', function() { 9 | 10 | describe('messageinfo', function () { 11 | it('Returns info about a message', function (done) { 12 | var url = Config.HOST + 'messageinfo'; 13 | var requestOptions = AuthHelper.requestOptions(); 14 | requestOptions.qs = { 15 | 'guid': Config.TEST_MESSAGE_GUID 16 | }; 17 | 18 | rp(url, requestOptions).then(function (result) { 19 | expect(result.statusCode).to.equal(200); 20 | 21 | var messageInfo = JSON.parse(result.body); 22 | expect(messageInfo.subject).to.exist; 23 | expect(messageInfo.message).to.exist; 24 | VerifyHelper.verifySyscoinGUID(messageInfo.GUID); 25 | done(); 26 | }); 27 | }); 28 | }); 29 | 30 | describe('messagenew', function () { 31 | it('Returns txid of new message tx', function (done) { 32 | var url = Config.HOST + 'messagenew'; 33 | var requestOptions = AuthHelper.requestOptions(); 34 | requestOptions.method = 'POST'; 35 | requestOptions.json = { 36 | 'subject': 'testing', 37 | 'message': 'testing unit testing', 38 | 'fromalias': Config.TEST_ALIAS, 39 | 'toalias': Config.TEST_ALIAS 40 | }; 41 | 42 | rp(url, requestOptions).then(function (result) { 43 | expect(result.statusCode).to.equal(200); 44 | 45 | var messageInfo = result.body; 46 | VerifyHelper.verifyTransactionId(messageInfo[0]); 47 | VerifyHelper.verifySyscoinGUID(messageInfo[1]); 48 | done(); 49 | }); 50 | }); 51 | }); 52 | 53 | describe('messagereceivelist', function () { 54 | it('Returns list of all recieved messages', function (done) { 55 | var url = Config.HOST + 'messagereceivelist'; 56 | var requestOptions = AuthHelper.requestOptions(); 57 | 58 | rp(url, requestOptions).then(function (result) { 59 | expect(result.statusCode).to.equal(200); 60 | 61 | var messageList = JSON.parse(result.body); 62 | expect(messageList.length).to.be.at.least(0); 63 | for(var i = 0; i < messageList.length; i++) { 64 | expect(messageList[i].message).to.exist; 65 | VerifyHelper.verifySyscoinGUID(messageList[i].GUID); 66 | } 67 | done(); 68 | }); 69 | }); 70 | }); 71 | 72 | describe('messagesentlist', function () { 73 | it('Returns list of all sent messages', function (done) { 74 | var url = Config.HOST + 'messagesentlist'; 75 | var requestOptions = AuthHelper.requestOptions(); 76 | 77 | rp(url, requestOptions).then(function (result) { 78 | expect(result.statusCode).to.equal(200); 79 | 80 | var messageList = JSON.parse(result.body); 81 | expect(messageList.length).to.be.at.least(0); 82 | for(var i = 0; i < messageList.length; i++) { 83 | expect(messageList[i].message).to.exist; 84 | VerifyHelper.verifySyscoinGUID(messageList[i].GUID); 85 | } 86 | done(); 87 | }); 88 | }); 89 | }); 90 | }); -------------------------------------------------------------------------------- /server/nodejs/controllers/spec/OfferService.spec.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect; 2 | var rp = require('request-promise'); 3 | 4 | var AuthHelper = require('./helper/authHelper'); 5 | var VerifyHelper = require('./helper/verifyHelper'); 6 | var DataHelper = require('./helper/dataHelper'); 7 | var Config = require('../../spec/config'); 8 | 9 | describe('Offer Service API', function() { 10 | 11 | describe('offeraccept', function () { 12 | it('Returns txid and guid of offeraccept', function (done) { 13 | //because this test may run after Alias tests, wait for confirmation on prev 14 | // txs 15 | this.timeout(60 * 3 * 1000); 16 | setTimeout(function() { 17 | DataHelper.offerAccept(Config.TEST_ALIAS, Config.TEST_OFFER_GUID, 1, 18 | 'test accept ' + Date.now().toString(), '', '').then(function(acceptResult) { 19 | expect(acceptResult.response.statusCode).to.equal(200); 20 | 21 | var acceptInfo = acceptResult.tx; 22 | VerifyHelper.verifyTransactionId(acceptInfo[0]); 23 | VerifyHelper.verifySyscoinGUID(acceptInfo[1]); 24 | done(); 25 | }); 26 | }, 60 * 2 * 1000); 27 | }); 28 | }); 29 | 30 | describe('offeracceptfeedback', function () { 31 | it('Returns txid of feedback tx (dependent on confirmations, which may result in false failures)', function (done) { 32 | //because this test may run after Alias tests AND after Offer accept tests, 33 | // wait for confirmation on prev txs 34 | this.timeout(60 * 8 * 1000); 35 | setTimeout(function() { 36 | DataHelper.offerAccept(Config.TEST_ALIAS, Config.TEST_OFFER_GUID, 1, 37 | 'test accept ' + Date.now().toString(), '', '').then(function(acceptResult) { 38 | console.log('Waiting for confimations on offerAccept...'); 39 | setTimeout(function() { 40 | var url = Config.HOST + 'offeracceptfeedback'; 41 | var requestOptions = AuthHelper.requestOptions(); 42 | requestOptions.method = 'POST'; 43 | requestOptions.qs = { 44 | 'offerguid': Config.TEST_OFFER_GUID, 45 | 'offeracceptguid': acceptResult.tx[1], 46 | 'feedback': 'Unit test feedback', 47 | 'rating': 5 48 | }; 49 | 50 | rp(url, requestOptions).then(function(result) { 51 | expect(result.statusCode).to.equal(200); 52 | expect(result.body.length).to.equal(68); //accept feedback tx id 53 | done(); 54 | }); 55 | }, 60 * 3 * 1000); //wait 2min for a confirm on the offeraccept before attempting to place feedback 56 | }); 57 | }, 60 * 3 * 1000); //wait 2min for any prev txs to confirm 58 | }); 59 | }); 60 | 61 | describe('offeracceptlist', function () { 62 | this.timeout(60 * 1000); //increase timeout in the case of long escrow history 63 | it('Returns list of accepted offers', function (done) { 64 | var url = Config.HOST + 'offeracceptlist'; 65 | var requestOptions = AuthHelper.requestOptions(); 66 | requestOptions.qs = { 67 | 'aliases': [Config.TEST_ALIAS] 68 | }; 69 | 70 | rp(url, requestOptions).then(function (result) { 71 | expect(result.statusCode).to.equal(200); 72 | 73 | var offerList = JSON.parse(result.body); 74 | expect(offerList.length).to.be.at.least(1); 75 | for(var i = 0; i < offerList.length; i++) { 76 | expect(offerList[i].offer).to.exist; 77 | expect(offerList[i].total).to.be.at.least(0); 78 | } 79 | done(); 80 | }); 81 | }); 82 | }); 83 | 84 | describe('offerhistory', function () { 85 | this.timeout(60 * 1000); //increase timeout in the case of long escrow history 86 | it('Returns history of offer', function (done) { 87 | var url = Config.HOST + 'offerhistory'; 88 | var requestOptions = AuthHelper.requestOptions(); 89 | requestOptions.qs = { 90 | 'offer': Config.TEST_OFFER_GUID 91 | }; 92 | 93 | rp(url, requestOptions).then(function (result) { 94 | expect(result.statusCode).to.equal(200); 95 | 96 | var offerHistoryList = JSON.parse(result.body); 97 | expect(offerHistoryList.length).to.be.at.least(1); 98 | for(var i = 0; i < offerHistoryList.length; i++) { 99 | expect(offerHistoryList[i].offertype).to.exist; 100 | expect(offerHistoryList[i].height).to.be.at.least(1); 101 | expect(offerHistoryList[i].price).to.be.at.least(0); 102 | } 103 | done(); 104 | }); 105 | }); 106 | }); 107 | 108 | describe('offerinfo', function () { 109 | it('Returns offer details', function (done) { 110 | var url = Config.HOST + 'offerinfo'; 111 | var requestOptions = AuthHelper.requestOptions(); 112 | requestOptions.qs = { 113 | 'guid': Config.TEST_OFFER_GUID 114 | }; 115 | 116 | rp(url, requestOptions).then(function (result) { 117 | expect(result.statusCode).to.equal(200); 118 | 119 | var offer = JSON.parse(result.body); 120 | expect(offer.title).to.exist; 121 | expect(offer.height).to.be.at.least(1); 122 | done(); 123 | }); 124 | }); 125 | }); 126 | 127 | describe('offerlist', function () { 128 | it('Returns list of offers owned by wallet', function (done) { 129 | var url = Config.HOST + 'offerlist'; 130 | var requestOptions = AuthHelper.requestOptions(); 131 | requestOptions.qs = { 132 | 'aliases': [Config.TEST_ALIAS] 133 | }; 134 | 135 | rp(url, requestOptions).then(function (result) { 136 | expect(result.statusCode).to.equal(200); 137 | 138 | var offerList = JSON.parse(result.body); 139 | expect(offerList.length).to.be.at.least(1); 140 | for(var i = 0; i < offerList.length; i++) { 141 | expect(offerList[i].title).to.exist; 142 | expect(offerList[i].height).to.be.at.least(1); 143 | expect(offerList[i].price).to.be.at.least(0); 144 | } 145 | done(); 146 | }); 147 | }); 148 | }); 149 | 150 | describe('offernew', function() { 151 | var url = 'http://localhost:8001/offernew'; 152 | 153 | it('Returns an array with the tx id and offer guid', function(done) { 154 | var requestOptions = AuthHelper.requestOptions(); 155 | requestOptions.method = 'POST'; 156 | requestOptions.json = { 157 | 'alias': 'testuser', 158 | 'category': 'unit testing', 159 | 'title': 'title here', 160 | 'quantity': 10, 161 | 'price': 1, 162 | 'description': 'Description goes here', 163 | 'currency': 'SYS', 164 | 'certguid': '', 165 | 'paymentoptions': 'SYS', 166 | 'geolocation': '', 167 | 'safesearch': 'Yes', 168 | 'private': true 169 | }; 170 | 171 | rp(url, requestOptions).then(function(result) { 172 | expect(result.statusCode).to.equal(200); 173 | expect(result.body.length).to.equal(2); 174 | expect(result.body[0].length).to.equal(64); //tx id 175 | expect(result.body[1].length).to.equal(16); //offer guid 176 | done(); 177 | }); 178 | }); 179 | }); 180 | 181 | describe('offerupdate', function() { 182 | var url = 'http://localhost:8001/offerupdate'; 183 | 184 | it('Returns an array with the tx id', function(done) { 185 | var requestOptions = AuthHelper.requestOptions(); 186 | requestOptions.method = 'POST'; 187 | requestOptions.json = { 188 | 'alias': 'testuser', 189 | 'guid': '1c3889997c39e979', 190 | 'category': 'unit testing', 191 | 'title': 'title here updated', 192 | 'quantity': 10, 193 | 'price': 1, 194 | 'description': 'Description goes here updated', 195 | 'currency': 'SYS', 196 | 'certguid': '', 197 | 'paymentoptions': 'SYS', 198 | 'geolocation': '', 199 | 'safesearch': 'Yes', 200 | 'private': true, 201 | 'commission': 0 202 | }; 203 | 204 | rp(url, requestOptions).then(function(result) { 205 | expect(result.statusCode).to.equal(200); 206 | expect(result.body.length).to.equal(1); 207 | expect(result.body[0].length).to.equal(64); //tx id 208 | done(); 209 | }); 210 | }); 211 | }); 212 | 213 | describe('offerwhitelist', function () { 214 | it('Returns whitelist info for an offer', function (done) { 215 | var url = Config.HOST + 'offerwhitelist'; 216 | var requestOptions = AuthHelper.requestOptions(); 217 | requestOptions.qs = { 218 | 'offerguid': [Config.TEST_OFFER_GUID] 219 | }; 220 | 221 | rp(url, requestOptions).then(function (result) { 222 | expect(result.statusCode).to.equal(200); 223 | 224 | var offerWhitelist = JSON.parse(result.body); 225 | expect(offerWhitelist.length).to.be.at.least(0); 226 | done(); 227 | }); 228 | }); 229 | }); 230 | }); -------------------------------------------------------------------------------- /server/nodejs/controllers/spec/helper/authHelper.js: -------------------------------------------------------------------------------- 1 | var jwt = require('jsonwebtoken'); 2 | var Hashes = require('jshashes'); 3 | var config = require('../../../config'); 4 | 5 | var _requestOptions = {}; 6 | 7 | function _doAuth() { 8 | var hash = new Hashes.SHA1().hex('u' + 'p'); 9 | var token = jwt.sign({ auth: hash }, config.api_secret, { 10 | expiresIn: 60 * 60 * 24 // expires in 24 hours 11 | }); 12 | 13 | _requestOptions.headers = { 14 | 'token': token, 15 | 'content-type': 'application/json' 16 | }; 17 | 18 | _requestOptions.resolveWithFullResponse = true; 19 | } 20 | 21 | function _reset() { 22 | var newRequestOptions = {}; 23 | if(!_requestOptions.headers) { 24 | _doAuth(); 25 | } 26 | 27 | newRequestOptions.headers = { 28 | 'token': _requestOptions.headers.token, 29 | 'content-type': 'application/json' 30 | }; 31 | 32 | newRequestOptions.resolveWithFullResponse = true; 33 | 34 | _requestOptions = newRequestOptions; 35 | } 36 | 37 | function requestOptions() { 38 | _reset(); 39 | 40 | return _requestOptions; 41 | } 42 | 43 | module.exports.requestOptions = requestOptions; 44 | 45 | -------------------------------------------------------------------------------- /server/nodejs/controllers/spec/helper/dataHelper.js: -------------------------------------------------------------------------------- 1 | var Q = require('q'); 2 | var rp = require('request-promise'); 3 | 4 | var AuthHelper = require('./authHelper'); 5 | var Config = require('../../../spec/config'); 6 | 7 | function getAccountAddress(account) { 8 | var deferred = Q.defer(); 9 | var url = Config.HOST + 'getaccountaddress'; 10 | var requestOptions = AuthHelper.requestOptions(); 11 | requestOptions.qs = { 12 | 'account': account 13 | }; 14 | 15 | rp(url, requestOptions) 16 | .then(function(result) { 17 | var syscoinaddress = JSON.parse(result.body); 18 | deferred.resolve({ address: syscoinaddress, response: result }); 19 | }) 20 | .catch(function(error) { 21 | console.log('Error fetching syscoin address: ' + JSON.stringify(error)); 22 | deferred.reject(error); 23 | }); 24 | 25 | return deferred.promise; 26 | } 27 | 28 | function sendSyscoin(toAddress, amount, comment, commentto, subtractFeeFromAmount) { 29 | var deferred = Q.defer(); 30 | var url = Config.HOST + 'sendtoaddress'; 31 | var requestOptions = AuthHelper.requestOptions(); 32 | requestOptions.method = 'POST'; 33 | requestOptions.json = { 34 | 'syscoinaddress': toAddress, 35 | 'amount': amount, 36 | 'comment': comment, 37 | 'commentto': commentto, 38 | 'subtractfeefromamount': subtractFeeFromAmount 39 | }; 40 | 41 | rp(url, requestOptions) 42 | .then(function(result) { 43 | var txid = result.body; 44 | deferred.resolve({ txid: txid, response: result }); 45 | }) 46 | .catch(function(error) { 47 | console.log('Error sending syscoin: ' + JSON.stringify(error)); 48 | deferred.reject(error); 49 | }); 50 | 51 | return deferred.promise; 52 | } 53 | 54 | function signMessage(address, message) { 55 | var deferred = Q.defer(); 56 | var url = Config.HOST + 'signmessage'; 57 | var requestOptions = AuthHelper.requestOptions(); 58 | requestOptions.method = 'POST'; 59 | requestOptions.json = { 60 | 'syscoinaddress': address, 61 | 'message': message 62 | }; 63 | 64 | rp(url, requestOptions) 65 | .then(function(result) { 66 | var signature = result.body; 67 | deferred.resolve({ signature: signature, response: result }); 68 | }) 69 | .catch(function(error) { 70 | console.log('Error fetching syscoin address: ' + JSON.stringify(error)); 71 | deferred.reject(error); 72 | }); 73 | 74 | return deferred.promise; 75 | } 76 | 77 | function offerAccept(alias, guid, quantity, message, exttxid, paymentoption) { 78 | var deferred = Q.defer(); 79 | var url = Config.HOST + 'offeraccept'; 80 | var requestOptions = AuthHelper.requestOptions(); 81 | requestOptions.method = 'POST'; 82 | requestOptions.json = { 83 | 'alias': alias, 84 | 'guid': guid, 85 | 'quantity': quantity, 86 | 'message': message, 87 | 'exttxid': exttxid, 88 | 'paymentoption': paymentoption 89 | }; 90 | 91 | rp(url, requestOptions) 92 | .then(function(result) { 93 | var tx = result.body; 94 | deferred.resolve({ tx: tx, response: result }); 95 | }) 96 | .catch(function(error) { 97 | console.log('Error accepting offer: ' + JSON.stringify(error)); 98 | deferred.reject(error); 99 | }); 100 | 101 | return deferred.promise; 102 | } 103 | 104 | function escrowNew(alias, offer, quantity, message, arbiterAlias, extTx, paymentOption, redeemScript, height) { 105 | var deferred = Q.defer(); 106 | var url = Config.HOST + 'escrownew'; 107 | var requestOptions = AuthHelper.requestOptions(); 108 | requestOptions.method = 'POST'; 109 | requestOptions.json = { 110 | 'alias': alias, 111 | 'offer': offer, 112 | 'quantity': quantity, 113 | 'message': message, 114 | 'arbiter': arbiterAlias, 115 | 'exttx': extTx, 116 | 'paymentoption': paymentOption, 117 | 'redeemscript': redeemScript, 118 | 'height': height 119 | }; 120 | 121 | rp(url, requestOptions) 122 | .then(function(result) { 123 | var tx = result.body; 124 | deferred.resolve({ tx: tx, response: result }); 125 | }) 126 | .catch(function(error) { 127 | console.log('Error creating new escrow: ' + JSON.stringify(error)); 128 | deferred.reject(error); 129 | }); 130 | 131 | return deferred.promise; 132 | } 133 | 134 | module.exports = { 135 | getAccountAddress: getAccountAddress, 136 | sendSyscoin: sendSyscoin, 137 | signMessage: signMessage, 138 | offerAccept: offerAccept, 139 | escrowNew: escrowNew 140 | }; -------------------------------------------------------------------------------- /server/nodejs/controllers/spec/helper/verifyHelper.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect; 2 | 3 | function verifySyscoinAddress(address) { 4 | expect(address.length).to.equal(34); 5 | } 6 | 7 | function verifyTransactionId(txid) { 8 | expect(txid.length).to.equal(64); 9 | } 10 | 11 | function verifyAliasNewTransactionId(txid) { 12 | expect(txid.length).to.equal(66); 13 | } 14 | 15 | function verifySyscoinGUID(msgId) { 16 | expect(msgId.length).to.equal(16); 17 | } 18 | 19 | module.exports.verifySyscoinAddress = verifySyscoinAddress; 20 | module.exports.verifyTransactionId = verifyTransactionId; 21 | module.exports.verifyAliasNewTransactionId = verifyAliasNewTransactionId; 22 | module.exports.verifySyscoinGUID = verifySyscoinGUID; -------------------------------------------------------------------------------- /server/nodejs/controllers/test/AliasesService.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const expect = require('chai').expect; 3 | const request = require('./TestRequest').request; 4 | const AuthHelper = require('../spec/helper/authHelper'); 5 | const Config = require('./config'); 6 | 7 | let testAuthToken; 8 | 9 | describe('Tests for Aliases Service API', function () { 10 | 11 | before(function (done) { 12 | let requestOptions = AuthHelper.requestOptions(); 13 | if (requestOptions) { 14 | testAuthToken = requestOptions.headers.token; 15 | } 16 | done(); 17 | }); 18 | 19 | describe('aliasbalance', function () { 20 | it('Returns balance for alias', function (done) { 21 | 22 | const params = { 'alias': Config.TEST_EXISTING_ALIAS1 }; 23 | 24 | request('GET', 'aliasbalance', params, testAuthToken) 25 | .end(function (err, res) { 26 | expect(err).to.be.null; 27 | expect(res).to.have.status(200); 28 | expect(res).to.have.header('content-type', 'application/json'); 29 | expect(res).to.be.json; 30 | //TO-DO: response schema validation 31 | done(); 32 | }); 33 | }); 34 | }); 35 | 36 | describe('aliasinfo', function () { 37 | it('Returns information about an alias', function (done) { 38 | 39 | const params = { 'aliasname': Config.TEST_EXISTING_ALIAS1 }; 40 | 41 | request('GET', 'aliasinfo', params, testAuthToken) 42 | .end(function (err, res) { 43 | expect(err).to.be.null; 44 | expect(res).to.have.status(200); 45 | expect(res).to.have.header('content-type', 'application/json'); 46 | expect(res).to.be.json; 47 | //TO-DO: response schema validation 48 | done(); 49 | }); 50 | }); 51 | }); 52 | 53 | describe('aliasexists', function () { 54 | it('Should return JSON object containing query argument and the success of query', function (done) { 55 | const params = { 'aliasexists': Config.TEST_EXISTING_ALIAS1 }; 56 | 57 | request('GET', 'aliasexists', params, testAuthToken) 58 | .end(function (err, res) { 59 | expect(err).to.be.null; 60 | expect(res).to.have.status(200); 61 | expect(res).to.have.header('content-type', 'application/json'); 62 | expect(res).to.be.json; 63 | done(); 64 | }); 65 | }); 66 | }); 67 | 68 | describe('aliasnew', function () { 69 | it('Creates a new Syscoin alias', function (done) { 70 | 71 | const body = { 72 | 'aliasname': 'testalias', 73 | 'publicvalue': 'public value', 74 | 'accept_transfers_flags': 1, 75 | 'expire_timestamp': 1560902147, 76 | 'address': Config.TEST_EXISTING_ADDRESS1, 77 | 'encryption_privatekey': '12345', 78 | 'encryption_publickey': '12345', 79 | 'witness': '' 80 | }; 81 | 82 | request('POST', 'aliasnew', null, testAuthToken, body) 83 | .end(function (err, res) { 84 | expect(err).to.be.null; 85 | expect(res).to.have.status(200); 86 | expect(res).to.have.header('content-type', 'application/json'); 87 | expect(res).to.be.json; 88 | //TO-DO: response schema validation 89 | done(); 90 | }); 91 | }); 92 | }); 93 | 94 | describe('aliaspay', function () { 95 | it('Send from an alias', function (done) { 96 | 97 | const body = { 98 | 'aliasfrom': Config.TEST_EXISTING_ALIAS1, 99 | 'amounts': 100 | { 101 | [Config.TEST_EXISTING_ADDRESS1]: 0.001 102 | }, 103 | 'instantsend': true, 104 | 'subtractfeefromamount': [] 105 | }; 106 | 107 | request('POST', 'aliaspay', null, testAuthToken, body) 108 | .end(function (err, res) { 109 | expect(err).to.be.null; 110 | expect(res).to.have.status(200); 111 | expect(res).to.have.header('content-type', 'application/json'); 112 | expect(res).to.be.json; 113 | //TO-DO: response schema validation 114 | done(); 115 | }); 116 | }); 117 | }); 118 | 119 | describe('aliasupdate', function () { 120 | it('Updates alias', function (done) { 121 | 122 | const body = { 123 | 'aliasname': Config.TEST_EXISTING_ALIAS1, 124 | 'publicvalue': 'updated public value', 125 | 'address': Config.TEST_EXISTING_ADDRESS1, 126 | 'accept_transfers_flags': 1, 127 | 'expire_timestamp': 1560902147, 128 | 'encryption_privatekey': '12345', 129 | 'encryption_publickey': '12345', 130 | 'witness': '' 131 | }; 132 | 133 | request('POST', 'aliasupdate', null, testAuthToken, body) 134 | .end(function (err, res) { 135 | expect(err).to.be.null; 136 | expect(res).to.have.status(200); 137 | expect(res).to.have.header('content-type', 'application/json'); 138 | expect(res).to.be.json; 139 | //TO-DO: response schema validation 140 | done(); 141 | }); 142 | }); 143 | }); 144 | 145 | describe('aliaswhitelist', function () { 146 | it('List all affiliates for this alias (white list)', function (done) { 147 | 148 | const params = { 'aliasname': Config.TEST_EXISTING_ALIAS1 }; 149 | 150 | request('GET', 'aliaswhitelist', params, testAuthToken, null) 151 | .end(function (err, res) { 152 | expect(err).to.be.null; 153 | expect(res).to.have.status(200); 154 | expect(res).to.have.header('content-type', 'application/json'); 155 | expect(res).to.be.json; 156 | //TO-DO: response schema validation 157 | done(); 158 | }); 159 | }); 160 | }); 161 | 162 | describe('aliasclearwhitelist', function () { 163 | it('Clear aliases\' whitelist', function (done) { 164 | 165 | const body = { 166 | 'owneralias': Config.TEST_EXISTING_ALIAS1, 167 | 'witness': '' 168 | }; 169 | 170 | request('POST', 'aliasclearwhitelist', null, testAuthToken, body) 171 | .end(function (err, res) { 172 | expect(err).to.be.null; 173 | expect(res).to.have.header('content-type', 'application/json'); 174 | expect(res).to.be.json; 175 | if (res.status == 500 && res.text.includes('ERRCODE: 5026')) { 176 | //this is ok for testing the api. End-to-end integration testing is supposed to cover the whole workflow. 177 | console.error(res.text); 178 | } else { 179 | expect(res).to.have.status(200); 180 | } 181 | done(); 182 | }); 183 | }); 184 | }); 185 | 186 | describe('aliasupdatewhitelist', function () { 187 | it('Update to the whitelist', function (done) { 188 | 189 | const body = { 190 | 'owneralias': Config.TEST_EXISTING_ALIAS1, 191 | 'entries': [ 192 | { 193 | 'alias': 'test', 194 | 'discount_percentage': 1 195 | } 196 | ], 197 | 'witness': '' 198 | }; 199 | 200 | request('POST', 'aliasupdatewhitelist', null, testAuthToken, body) 201 | .end(function (err, res) { 202 | expect(err).to.be.null; 203 | expect(res).to.have.status(200); 204 | expect(res).to.have.header('content-type', 'application/json'); 205 | expect(res).to.be.json; 206 | //TO-DO: response schema validation 207 | done(); 208 | }); 209 | }); 210 | }); 211 | 212 | /* not clear yet how the request looks like*/ 213 | describe('syscointxfund', function () { 214 | it('Funds a new syscoin transaction', function (done) { 215 | 216 | const body = { 217 | "hexstring": Config.TEST_TRX_HEX_STRING, 218 | "addresses": [Config.TEST_EXISTING_ADDRESS1, Config.TEST_EXISTING_ADDRESS2] 219 | }; 220 | 221 | request('POST', 'syscointxfund', null, testAuthToken, body) 222 | .end(function (err, res) { 223 | expect(err).to.be.null; 224 | expect(res).to.have.status(200); 225 | expect(res).to.have.header('content-type', 'application/json'); 226 | expect(res).to.be.json; 227 | //TO-DO: response schema validation 228 | done(); 229 | }); 230 | }); 231 | }); 232 | 233 | describe('aliasaddscript', function () { 234 | it('Add redeemscript to alias', function (done) { 235 | 236 | const body = { 237 | 'script': '12345' 238 | }; 239 | 240 | request('POST', 'aliasaddscript', null, testAuthToken, body) 241 | .end(function (err, res) { 242 | expect(err).to.be.null; 243 | expect(res).to.have.status(200); 244 | expect(res).to.have.header('content-type', 'application/json'); 245 | expect(res).to.be.json; 246 | //TO-DO: response schema validation 247 | done(); 248 | }); 249 | }); 250 | }); 251 | }); -------------------------------------------------------------------------------- /server/nodejs/controllers/test/AssetService.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const expect = require('chai').expect; 3 | const request = require('./TestRequest').request; 4 | const AuthHelper = require('../spec/helper/authHelper'); 5 | const Config = require('./config'); 6 | 7 | let testAuthToken; 8 | 9 | describe('Tests for Asset Service API', function () { 10 | 11 | before(function (done) { 12 | let requestOptions = AuthHelper.requestOptions(); 13 | if (requestOptions) { 14 | testAuthToken = requestOptions.headers.token; 15 | } 16 | done(); 17 | }); 18 | 19 | describe('assetallocationcollectinterest', function () { 20 | it('Collect interest on this asset', function (done) { 21 | 22 | const body = { 23 | 'asset': Config.TEST_EXISTING_ASSET_AMOUNTS_GUID, 24 | 'alias': Config.TEST_EXISTING_ALIAS2, 25 | 'witness': '' 26 | }; 27 | 28 | request('POST', 'assetallocationcollectinterest', null, testAuthToken, body) 29 | .end(function (err, res) { 30 | expect(err).to.be.null; 31 | expect(res).to.have.header('content-type', 'application/json'); 32 | expect(res).to.be.json; 33 | if (res.status == 500 && res.text.includes('ERRCODE: 1013')) { 34 | //this is ok for testing the api. End-to-end integration testing is supposed to cover the whole workflow. 35 | console.error(res.text); 36 | } else { 37 | expect(res).to.have.status(200); 38 | } 39 | done(); 40 | }); 41 | }); 42 | }); 43 | 44 | describe('assetinfo', function () { 45 | it('Show stored values of a single asset', function (done) { 46 | 47 | const params = { 48 | 'asset': Config.TEST_EXISTING_ASSET_RANGES_GUID, 49 | 'getinputs': true, 50 | }; 51 | 52 | request('GET', 'assetinfo', params, testAuthToken) 53 | .end(function (err, res) { 54 | expect(err).to.be.null; 55 | expect(res).to.have.status(200); 56 | expect(res).to.have.header('content-type', 'application/json'); 57 | expect(res).to.be.json; 58 | //TO-DO: response schema validation 59 | done(); 60 | }); 61 | }); 62 | }); 63 | 64 | describe('assetsend ranges', function () { 65 | it('Send an asset you own to another alias as an asset allocation (use ranges)', function (done) { 66 | 67 | const body = { 68 | 'asset': Config.TEST_EXISTING_ASSET_RANGES_GUID, 69 | 'aliasfrom': Config.TEST_EXISTING_ALIAS1, 70 | 'memo': 'sending asset to ' + Config.TEST_EXISTING_ALIAS2, 71 | 'witness': '', 72 | 'amounts': [ 73 | { 74 | 'aliasto': Config.TEST_EXISTING_ALIAS2, 75 | 'ranges': [ 76 | { 77 | 'start': 55, 78 | 'end': 55 79 | } 80 | ] 81 | } 82 | ] 83 | }; 84 | 85 | request('POST', 'assetsend', null, testAuthToken, body) 86 | .end(function (err, res) { 87 | expect(err).to.be.null; 88 | expect(res).to.have.status(200); 89 | expect(res).to.have.header('content-type', 'application/json'); 90 | expect(res).to.be.json; 91 | //TO-DO: response schema validation 92 | done(); 93 | }); 94 | }); 95 | }); 96 | 97 | describe('assetsend amounts', function () { 98 | it('Send an asset you own to another alias as an asset allocation (use amounts)', function (done) { 99 | 100 | const body = { 101 | 'asset': Config.TEST_EXISTING_ASSET_AMOUNTS_GUID, 102 | 'aliasfrom': Config.TEST_EXISTING_ALIAS1, 103 | 'memo': 'sending asset to ' + Config.TEST_EXISTING_ALIAS2, 104 | 'witness': '', 105 | 'amounts': [ 106 | { 107 | 'aliasto': Config.TEST_EXISTING_ALIAS2, 108 | 'amount': 3 109 | } 110 | ] 111 | }; 112 | 113 | request('POST', 'assetsend', null, testAuthToken, body) 114 | .end(function (err, res) { 115 | expect(err).to.be.null; 116 | expect(res).to.have.status(200); 117 | expect(res).to.have.header('content-type', 'application/json'); 118 | expect(res).to.be.json; 119 | //TO-DO: response schema validation 120 | done(); 121 | }); 122 | }); 123 | }); 124 | 125 | describe('assetallocationinfo', function () { 126 | it('Show stored values of a single asset allocation', function (done) { 127 | 128 | const params = { 129 | 'asset': Config.TEST_EXISTING_ASSET_AMOUNTS_GUID, 130 | 'alias': Config.TEST_EXISTING_ALIAS2, 131 | 'getinputs': true 132 | }; 133 | 134 | request('GET', 'assetallocationinfo', params, testAuthToken) 135 | .end(function (err, res) { 136 | expect(err).to.be.null; 137 | expect(res).to.have.status(200); 138 | expect(res).to.have.header('content-type', 'application/json'); 139 | expect(res).to.be.json; 140 | //TO-DO: response schema validation 141 | done(); 142 | }); 143 | }); 144 | }); 145 | 146 | describe('assetallocationsend', function () { 147 | it('Send an asset allocation you own to another alias (use amounts)', function (done) { 148 | 149 | const body = { 150 | 'asset': Config.TEST_EXISTING_ASSET_AMOUNTS_GUID, 151 | 'aliasfrom': Config.TEST_EXISTING_ALIAS2, 152 | 'amounts': [ 153 | { 154 | 'aliasto': Config.TEST_EXISTING_ALIAS1, 155 | 'amount': 1 156 | } 157 | ], 158 | 'memo': 'sending asset to ' + Config.TEST_EXISTING_ALIAS1, 159 | 'witness': '' 160 | }; 161 | 162 | request('POST', 'assetallocationsend', null, testAuthToken, body) 163 | .end(function (err, res) { 164 | expect(err).to.be.null; 165 | expect(res).to.have.status(200); 166 | expect(res).to.have.header('content-type', 'application/json'); 167 | expect(res).to.be.json; 168 | //TO-DO: response schema validation 169 | done(); 170 | }); 171 | }); 172 | 173 | it('Send an asset allocation you own to another alias (use ranges)', function (done) { 174 | 175 | const body = { 176 | 'asset': Config.TEST_EXISTING_ASSET_RANGES_GUID, 177 | 'aliasfrom': Config.TEST_EXISTING_ALIAS2, 178 | 'memo': 'sending asset to ' + Config.TEST_EXISTING_ALIAS1, 179 | 'witness': '', 180 | 'amounts': [ 181 | { 182 | 'aliasto': Config.TEST_EXISTING_ALIAS1, 183 | 'ranges': [ 184 | { 185 | 'start': 2, 186 | 'end': 2 187 | } 188 | ] 189 | } 190 | ] 191 | }; 192 | 193 | request('POST', 'assetallocationsend', null, testAuthToken, body) 194 | .end(function (err, res) { 195 | expect(err).to.be.null; 196 | expect(res).to.have.status(200); 197 | expect(res).to.have.header('content-type', 'application/json'); 198 | expect(res).to.be.json; 199 | //TO-DO: response schema validation 200 | done(); 201 | }); 202 | }); 203 | }); 204 | 205 | describe('assetallocationsenderstatus', function () { 206 | it('Show status as it pertains to any current Z-DAG conflicts...', function (done) { 207 | 208 | const params = { 209 | 'asset': Config.TEST_EXISTING_ASSET_RANGES_GUID, 210 | 'sender': Config.TEST_EXISTING_ALIAS1, 211 | 'txid': Config.TEST_EXISTING_TXID 212 | }; 213 | 214 | request('GET', 'assetallocationsenderstatus', params, testAuthToken, null) 215 | .end(function (err, res) { 216 | expect(err).to.be.null; 217 | expect(res).to.have.status(200); 218 | expect(res).to.have.header('content-type', 'application/json'); 219 | expect(res).to.be.json; 220 | //TO-DO: response schema validation 221 | done(); 222 | }); 223 | }); 224 | }); 225 | 226 | describe('assettransfer', function () { 227 | it('Transfer a asset allocation you own to another alias', function (done) { 228 | 229 | const body = { 230 | 'asset': Config.TEST_EXISTING_ASSET_AMOUNTS_GUID, 231 | 'alias': Config.TEST_EXISTING_ALIAS1, 232 | 'witness': '' 233 | }; 234 | 235 | request('POST', 'assettransfer', null, testAuthToken, body) 236 | .end(function (err, res) { 237 | expect(err).to.be.null; 238 | expect(res).to.have.status(200); 239 | expect(res).to.have.header('content-type', 'application/json'); 240 | expect(res).to.be.json; 241 | //TO-DO: response schema validation 242 | done(); 243 | }); 244 | }); 245 | }); 246 | 247 | describe('assetupdate', function () { 248 | it('Perform an update on an asset you control', function (done) { 249 | 250 | const body = { 251 | 'asset': Config.TEST_EXISTING_ASSET_RANGES_GUID, 252 | 'supply': 10, 253 | 'category': 'assets > assets', 254 | 'publicvalue': 'updated asset', 255 | 'interest_rate': 0, 256 | 'witness': '', 257 | 'test': 123 258 | }; 259 | 260 | request('POST', 'assetupdate', null, testAuthToken, body) 261 | .end(function (err, res) { 262 | expect(err).to.be.null; 263 | expect(res).to.have.status(200); 264 | expect(res).to.have.header('content-type', 'application/json'); 265 | expect(res).to.be.json; 266 | //TO-DO: response schema validation 267 | done(); 268 | }); 269 | }); 270 | }); 271 | 272 | describe('assetnew', function () { 273 | it('Creating a new asset', function (done) { 274 | 275 | const body = { 276 | 'symbol': 'SYMBOL1', 277 | 'alias': Config.TEST_EXISTING_ALIAS1, 278 | 'category': 'assets > assets', 279 | 'supply': 500000, 280 | 'max_supply': 1000000000, 281 | 'use_inputranges': false, 282 | 'interest_rate': 0.039900000000000005, 283 | 'can_adjust_interest_rate': true, 284 | 'publicvalue': 'precious', 285 | 'witness': '', 286 | 'precision': 0 287 | }; 288 | 289 | request('POST', 'assetnew', null, testAuthToken, body) 290 | .end(function (err, res) { 291 | expect(err).to.be.null; 292 | expect(res).to.have.status(200); 293 | expect(res).to.have.header('content-type', 'application/json'); 294 | expect(res).to.be.json; 295 | //TO-DO: response schema validation 296 | done(); 297 | }); 298 | }); 299 | }); 300 | }); -------------------------------------------------------------------------------- /server/nodejs/controllers/test/BlockmarketService.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const expect = require('chai').expect; 3 | const request = require('./TestRequest').request; 4 | const Hashes = require('jshashes'); 5 | const Config = require('./config'); 6 | 7 | describe('Tests for Blockmarket Service API', function () { 8 | 9 | describe('login', function () { 10 | it('Successful login', function (done) { 11 | const params = { 12 | auth: new Hashes.SHA1().hex(Config.TEST_CREDENTIALS_USERNAME + Config.TEST_CREDENTIALS_PASSWORD) 13 | }; 14 | 15 | request('GET', 'login', params, null).end(function (err, res) { 16 | expect(err).to.be.null; 17 | expect(res).to.have.status(200); 18 | expect(res).to.have.header('content-type', 'application/json'); 19 | expect(res).to.be.json; 20 | let r = JSON.parse(res.text); 21 | expect(r.token).to.exist; 22 | done(); 23 | }); 24 | }); 25 | 26 | it('Login attempt with invalid credentials', function (done) { 27 | const params = { 28 | auth: new Hashes.SHA1().hex('invalid' + 'invalid') 29 | }; 30 | 31 | request('GET', 'login', params, null).end(function (err, res) { 32 | expect(err).to.be.null; 33 | expect(res).to.have.status(401); 34 | expect(res).to.have.header('content-type', 'application/json'); 35 | expect(res).to.be.json; 36 | done(); 37 | }); 38 | }); 39 | 40 | it('Login attempt with no auth hash provided', function (done) { 41 | request('GET', 'login', null, null).end(function (err, res) { 42 | expect(err).to.be.null; 43 | expect(res).to.have.status(400); 44 | done(); 45 | }); 46 | }); 47 | }); 48 | 49 | }); 50 | -------------------------------------------------------------------------------- /server/nodejs/controllers/test/CertificatesService.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const expect = require('chai').expect; 3 | const request = require('./TestRequest').request; 4 | const AuthHelper = require('../spec/helper/authHelper'); 5 | const Config = require('./config'); 6 | 7 | let testAuthToken; 8 | 9 | describe('Tests for Certificates Service API', function () { 10 | before(function (done) { 11 | let requestOptions = AuthHelper.requestOptions(); 12 | if (requestOptions) { 13 | testAuthToken = requestOptions.headers.token; 14 | } 15 | done(); 16 | }); 17 | 18 | describe('certinfo', function () { 19 | it('Show stored values of a single certificate', function (done) { 20 | const params = { 21 | guid: Config.TEST_EXISTING_CERTIFICATE_GUID 22 | }; 23 | 24 | request('GET', 'certinfo', params, testAuthToken).end(function (err, res) { 25 | expect(err).to.be.null; 26 | expect(res).to.have.status(200); 27 | expect(res).to.have.header('content-type', 'application/json'); 28 | expect(res).to.be.json; 29 | //TO-DO: response schema validation 30 | done(); 31 | }); 32 | }); 33 | }); 34 | 35 | describe('certnew', function () { 36 | it('Creating a new certificate', function (done) { 37 | const body = { 38 | alias: Config.TEST_EXISTING_ALIAS1, 39 | title: 'test cert 1', 40 | publicvalue: 'test cert 1 public value', 41 | category: 'certificates > company shares', 42 | witness: '' 43 | }; 44 | 45 | request('POST', 'certnew', null, testAuthToken, body).end(function (err, res) { 46 | expect(err).to.be.null; 47 | expect(res).to.have.status(200); 48 | expect(res).to.have.header('content-type', 'application/json'); 49 | expect(res).to.be.json; 50 | //TO-DO: response schema validation 51 | done(); 52 | }); 53 | }); 54 | }); 55 | 56 | describe('certtransfer', function () { 57 | it('Transfer a certificate you own to another alias', function (done) { 58 | const body = { 59 | 'guid': Config.TEST_EXISTING_CERTIFICATE_GUID, 60 | 'alias': Config.TEST_EXISTING_ALIAS2, 61 | 'accessflags': 2, 62 | 'publicvalue': '', 63 | 'witness': '' 64 | }; 65 | 66 | request('POST', 'certtransfer', null, testAuthToken, body).end(function (err, res) { 67 | expect(err).to.be.null; 68 | expect(res).to.have.status(200); 69 | expect(res).to.have.header('content-type', 'application/json'); 70 | expect(res).to.be.json; 71 | //TO-DO: response schema validation 72 | done(); 73 | }); 74 | }); 75 | }); 76 | 77 | describe('certupdate', function () { 78 | it('Transfer a certificate you own to another alias', function (done) { 79 | const body = { 80 | 'guid': Config.TEST_EXISTING_CERTIFICATE_GUID, 81 | 'title': 'updated test cert 1 title', 82 | 'publicvalue': 'updated public value', 83 | 'category': 'certificates > company shares', 84 | 'witness': '' 85 | }; 86 | 87 | request('POST', 'certupdate', null, testAuthToken, body).end(function (err, res) { 88 | expect(err).to.be.null; 89 | expect(res).to.have.status(200); 90 | expect(res).to.have.header('content-type', 'application/json'); 91 | expect(res).to.be.json; 92 | //TO-DO: response schema validation 93 | done(); 94 | }); 95 | }); 96 | }); 97 | 98 | 99 | 100 | }); 101 | -------------------------------------------------------------------------------- /server/nodejs/controllers/test/EscrowService.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const expect = require('chai').expect; 3 | const request = require('./TestRequest').request; 4 | const AuthHelper = require('../spec/helper/authHelper'); 5 | const Config = require('./config'); 6 | 7 | let testAuthToken; 8 | 9 | describe('Tests for Escrow Service API', function () { 10 | before(function (done) { 11 | let requestOptions = AuthHelper.requestOptions(); 12 | if (requestOptions) { 13 | testAuthToken = requestOptions.headers.token; 14 | } 15 | done(); 16 | }); 17 | 18 | describe('escrowacknowledge', function () { 19 | it('Acknowledge escrow payment as seller of offer', function (done) { 20 | const body = { 21 | escrowguid: Config.TEST_EXISTING_ESCROW_GUID, 22 | witness: '' 23 | }; 24 | request('POST', 'escrowacknowledge', null, testAuthToken, body).end(function (err, res) { 25 | expect(err).to.be.null; 26 | expect(res).to.have.header('content-type', 'application/json'); 27 | expect(res).to.be.json; 28 | if (res.status == 500 && res.text.includes('ERRCODE: 4044')) { 29 | //this is ok for testing the api. End-to-end integration testing is supposed to cover the whole workflow. 30 | console.error(res.text); 31 | } else { 32 | expect(res).to.have.status(200); 33 | } 34 | done(); 35 | }); 36 | }); 37 | }); 38 | 39 | describe('escrowcompleterefund', function () { 40 | it('Completes an escrow refund', function (done) { 41 | const body = { 42 | 'witness': '', 43 | 'escrowguid': Config.TEST_EXISTING_ESCROW_GUID, 44 | 'rawtx': '12345' 45 | }; 46 | 47 | request('POST', 'escrowcompleterefund', null, testAuthToken, body).end(function (err, res) { 48 | expect(err).to.be.null; 49 | expect(res).to.have.header('content-type', 'application/json'); 50 | expect(res).to.be.json; 51 | if (res.status == 500 && res.text.includes('ERRCODE: 4055')) { 52 | //this is ok for testing the api. End-to-end integration testing is supposed to cover the whole workflow. 53 | console.error(res.text); 54 | } else { 55 | expect(res).to.have.status(200); 56 | } 57 | done(); 58 | }); 59 | }); 60 | }); 61 | 62 | describe('escrowcompleterelease', function () { 63 | it('Completes an escrow release', function (done) { 64 | const body = { 65 | 'witness': '', 66 | 'escrowguid': Config.TEST_EXISTING_ESCROW_GUID, 67 | 'rawtx': '12345' 68 | }; 69 | request('POST', 'escrowcompleterelease', null, testAuthToken, body).end(function (err, res) { 70 | expect(err).to.be.null; 71 | expect(res).to.have.header('content-type', 'application/json'); 72 | expect(res).to.be.json; 73 | if (res.status == 500 && res.text.includes('ERRCODE: 4065')) { 74 | //this is ok for testing the api. End-to-end integration testing is supposed to cover the whole workflow. 75 | console.error(res.text); 76 | } else { 77 | expect(res).to.have.status(200); 78 | } 79 | done(); 80 | }); 81 | }); 82 | }); 83 | 84 | describe('escrowfeedback', function () { 85 | it('Send feedback for primary and secondary users in escrow', function (done) { 86 | const body = { 87 | 'feedback': 'feedback', 88 | 'witness': '', 89 | 'userfrom': 'seller', 90 | 'escrowguid': Config.TEST_EXISTING_ESCROW_GUID, 91 | 'rating': 5, 92 | 'userto': 'buyer' 93 | }; 94 | 95 | request('POST', 'escrowfeedback', null, testAuthToken, body).end(function (err, res) { 96 | expect(err).to.be.null; 97 | expect(res).to.have.status(200); 98 | expect(res).to.have.header('content-type', 'application/json'); 99 | expect(res).to.be.json; 100 | //TO-DO: response schema validation 101 | done(); 102 | }); 103 | }); 104 | }); 105 | 106 | describe('escrownew', function () { 107 | it('Creating a new escrow', function (done) { 108 | const body = { 109 | 'alias': Config.TEST_EXISTING_ALIAS1, 110 | 'offer': Config.TEST_EXISTING_OFFER_GUID, 111 | 'quantity': 1, 112 | 'arbiter_alias': Config.TEST_EXISTING_ARBITER_ALIAS, 113 | 'getamountandaddress': false, 114 | 'buynow': true, 115 | 'total_in_payment_option': 1, 116 | 'shipping_amount': 0, 117 | 'network_fee': 100, 118 | 'arbiter_fee': 0.05, 119 | 'witness': '', 120 | 'extTx': '', 121 | 'paymentoption': 'SYS', 122 | 'bid_in_offer_currency': 0, 123 | 'bid_in_payment_option': 0, 124 | 'witness_fee': 0 125 | }; 126 | request('POST', 'escrownew', null, testAuthToken, body).end(function (err, res) { 127 | expect(err).to.be.null; 128 | expect(res).to.have.status(200); 129 | expect(res).to.have.header('content-type', 'application/json'); 130 | expect(res).to.be.json; 131 | done(); 132 | }); 133 | }); 134 | }); 135 | 136 | describe('escrowrefund', function () { 137 | it('Refunds escrow funds to buyer', function (done) { 138 | const body = { 139 | 'witness': '', 140 | 'escrowguid': Config.TEST_EXISTING_ESCROW_GUID, 141 | 'rawtx': '12345', 142 | 'userrole': 'seller' 143 | }; 144 | 145 | request('POST', 'escrowrefund', null, testAuthToken, body).end(function (err, res) { 146 | expect(err).to.be.null; 147 | expect(res).to.have.header('content-type', 'application/json'); 148 | expect(res).to.be.json; 149 | if (res.status == 500 && res.text.includes('ERRCODE: 5012')) { 150 | //this is ok for testing the api. End-to-end integration testing is supposed to cover the whole workflow. 151 | console.error(res.text); 152 | } else { 153 | expect(res).to.have.status(200); 154 | } 155 | done(); 156 | }); 157 | }); 158 | }); 159 | 160 | describe('escrowrelease', function () { 161 | it('Releases escrow funds to seller', function (done) { 162 | const body = { 163 | 'witness': '', 164 | 'escrowguid': Config.TEST_EXISTING_ESCROW_GUID, 165 | 'rawtx': '12345', 166 | 'userrole': 'buyer' 167 | }; 168 | 169 | request('POST', 'escrowrelease', null, testAuthToken, body).end(function (err, res) { 170 | expect(err).to.be.null; 171 | expect(res).to.have.header('content-type', 'application/json'); 172 | expect(res).to.be.json; 173 | if (res.status == 500 && res.text.includes('ERRCODE: 4057')) { 174 | //this is ok for testing the api. End-to-end integration testing is supposed to cover the whole workflow. 175 | console.error(res.text); 176 | } else { 177 | expect(res).to.have.status(200); 178 | } 179 | done(); 180 | }); 181 | }); 182 | }); 183 | 184 | describe('escrowbid', function () { 185 | it('Place a bid on an offer', function (done) { 186 | const body = { 187 | 'bid_in_offer_currency': 1.1, 188 | 'witness': '', 189 | 'bid_in_payment_option': 1, 190 | 'alias': Config.TEST_EXISTING_ALIAS1, 191 | 'escrow': Config.TEST_EXISTING_ESCROW_GUID 192 | }; 193 | 194 | request('POST', 'escrowbid', null, testAuthToken, body).end(function (err, res) { 195 | expect(err).to.be.null; 196 | expect(res).to.have.header('content-type', 'application/json'); 197 | expect(res).to.be.json; 198 | if (res.status == 500 && res.text.includes('ERRCODE: 4027')) { 199 | //this is ok for testing the api. End-to-end integration testing is supposed to cover the whole workflow. 200 | console.error(res.text); 201 | } else { 202 | expect(res).to.have.status(200); 203 | } 204 | done(); 205 | }); 206 | }); 207 | }); 208 | 209 | describe('escrowcreaterawtransaction', function () { 210 | it('Creates raw transaction for escrow refund or release', function (done) { 211 | const body = { 212 | 'role': 'buyer', 213 | 'inputs': [ 214 | { 215 | 'txid': Config.TEST_EXISTING_TXID, 216 | 'vout': 1, 217 | 'satoshis': 10000000 218 | } 219 | ], 220 | 'escrowguid': Config.TEST_EXISTING_ESCROW_GUID, 221 | 'type': 'release' 222 | }; 223 | 224 | request('POST', 'escrowcreaterawtransaction', null, testAuthToken, body).end(function (err, res) { 225 | expect(err).to.be.null; 226 | expect(res).to.have.status(200); 227 | expect(res).to.have.header('content-type', 'application/json'); 228 | expect(res).to.be.json; 229 | done(); 230 | }); 231 | }); 232 | }); 233 | 234 | describe('escrowinfo', function () { 235 | it('Show stored values of a single escrow', function (done) { 236 | const params = { 237 | escrowguid: Config.TEST_EXISTING_ESCROW_GUID 238 | }; 239 | 240 | request('GET', 'escrowinfo', params, testAuthToken).end(function (err, res) { 241 | expect(err).to.be.null; 242 | expect(res).to.have.status(200); 243 | expect(res).to.have.header('content-type', 'application/json'); 244 | expect(res).to.be.json; 245 | done(); 246 | }); 247 | }); 248 | }); 249 | 250 | }); 251 | -------------------------------------------------------------------------------- /server/nodejs/controllers/test/MasternodesService.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const expect = require("chai").expect; 3 | const request = require("./TestRequest").request; 4 | const AuthHelper = require("../spec/helper/authHelper"); 5 | const Config = require("./config"); 6 | 7 | let testAuthToken; 8 | 9 | describe("Tests for Masternodes Service API", function () { 10 | 11 | before(function (done) { 12 | let requestOptions = AuthHelper.requestOptions(); 13 | if (requestOptions) { 14 | testAuthToken = requestOptions.headers.token 15 | } 16 | done(); 17 | }); 18 | 19 | /*Need to run 'walletlock' and 'walletpassphrase' first for the following tests to pass*/ 20 | describe("walletlock", function () { 21 | it("Removes the wallet encryption key from memory, locking the wallet", function (done) { 22 | request("POST", "walletlock", null, testAuthToken, null).end(function (err, res) { 23 | expect(err).to.be.null; 24 | expect(res).to.have.status(200); 25 | expect(res).to.have.header("content-type", "application/json"); 26 | expect(res).to.be.json; 27 | done(); 28 | }); 29 | }); 30 | }); 31 | 32 | describe("walletpassphrase", function () { 33 | it("Stores the wallet decryption key in memory for ‘timeout’ seconds", function (done) { 34 | const body = { 35 | "passphrase": Config.TEST_ENCRYPT_WALLET_PASSPHRASE, 36 | "timeout": 60 37 | }; 38 | request("POST", "walletpassphrase", null, testAuthToken, body).end(function (err, res) { 39 | expect(err).to.be.null; 40 | expect(res).to.have.status(200); 41 | expect(res).to.have.header("content-type", "application/json"); 42 | expect(res).to.be.json; 43 | done(); 44 | }); 45 | }); 46 | }); 47 | 48 | describe('sentinelping', function () { 49 | it("Keep-alive message for masternode via TCP ping requests", function (done) { 50 | 51 | const params = { 52 | 'version': Config.TEST_SENTINEL_VERSION 53 | }; 54 | 55 | request('GET', 'sentinelping', params, testAuthToken) 56 | .end(function (err, res) { 57 | expect(err).to.be.null; 58 | expect(res).to.have.status(200); 59 | expect(res).to.have.header('content-type', 'application/json'); 60 | expect(res).to.be.json; 61 | done(); 62 | }); 63 | }); 64 | }); 65 | 66 | describe('voteraw', function () { 67 | it("Returns error: 'Failure to find masternode in list'", function (done) { 68 | 69 | const body = { 70 | "masternode-tx-index": 0, 71 | "vote-signal": "valid", 72 | "masternode-tx-hash": Config.TEST_EXISTING_TXID, 73 | "governance-hash": Config.TEST_EXISTING_TXID, 74 | "time": 1530802418, 75 | "vote-sig": "vote-sig", 76 | "vote-outcome": "abstain" 77 | }; 78 | 79 | request('POST', 'voteraw', null, testAuthToken, body) 80 | .end(function (err, res) { 81 | expect(err).to.be.null; 82 | expect(res).to.have.header('content-type', 'application/json'); 83 | expect(res).to.be.json; 84 | if (res.status == 500 && res.text.includes('Failure to find masternode in list')) { 85 | console.error(res.text) 86 | } else { 87 | expect(res).to.have.status(200); 88 | } 89 | done(); 90 | }); 91 | }); 92 | }); 93 | 94 | describe('privatesend', function () { 95 | it("Anonymous mixing and sending coins: reset", function (done) { 96 | 97 | const params = { 98 | 'command': "reset" 99 | }; 100 | 101 | request('GET', 'privatesend', params, testAuthToken) 102 | .end(function (err, res) { 103 | expect(err).to.be.null; 104 | expect(res).to.have.status(200); 105 | expect(res).to.have.header('content-type', 'application/json'); 106 | expect(res).to.be.json; 107 | done(); 108 | }); 109 | }); 110 | }); 111 | 112 | describe('importelectrumwallet', function () { 113 | it("importelectrumwallet", function (done) { 114 | const params = { 115 | 'filename': process.cwd() + Config.TEST_ELECTRUM_WALLET_PATH, 116 | 'index': 0 117 | }; 118 | request('GET', 'importelectrumwallet', params, testAuthToken) 119 | .end(function (err, res) { 120 | expect(err).to.be.null; 121 | expect(res).to.have.status(200); 122 | expect(res).to.have.header('content-type', 'application/json'); 123 | expect(res).to.be.json; 124 | done(); 125 | }); 126 | }); 127 | }); 128 | 129 | }); -------------------------------------------------------------------------------- /server/nodejs/controllers/test/OffersService.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const expect = require('chai').expect; 3 | const request = require('./TestRequest').request; 4 | const AuthHelper = require('../spec/helper/authHelper'); 5 | const Config = require('./config'); 6 | 7 | let testAuthToken; 8 | 9 | describe('Tests for Offers Service API', function () { 10 | before(function (done) { 11 | let requestOptions = AuthHelper.requestOptions(); 12 | if (requestOptions) { 13 | testAuthToken = requestOptions.headers.token; 14 | } 15 | done(); 16 | }); 17 | 18 | describe('offerinfo', function () { 19 | it('Show offer details', function (done) { 20 | const params = { 21 | guid: Config.TEST_EXISTING_OFFER_GUID 22 | }; 23 | 24 | request('GET', 'offerinfo', params, testAuthToken).end(function (err, res) { 25 | expect(err).to.be.null; 26 | expect(res).to.have.status(200); 27 | expect(res).to.have.header('content-type', 'application/json'); 28 | expect(res).to.be.json; 29 | done(); 30 | }); 31 | }); 32 | }); 33 | 34 | // describe("offerlink", function () { 35 | // it("Link offer", function (done) { 36 | // const body = { 37 | // alias: Config.TEST_EXISTING_ALIAS3, 38 | // guid: Config.TEST_EXISTING_OFFER_GUID, 39 | // commission: 0, 40 | // description: "link offer description", 41 | // witness: "" 42 | // }; 43 | 44 | // request("POST", "offerlink", null, testAuthToken, body).end(function (err, res) { 45 | // expect(err).to.be.null; 46 | // expect(res).to.have.status(200); 47 | // expect(res).to.have.header("content-type", "application/json"); 48 | // expect(res).to.be.json; 49 | // //TO-DO: response schema validation 50 | // done(); 51 | // }); 52 | // }); 53 | // }); 54 | 55 | describe('offernew', function () { 56 | it('Creating new offer', function (done) { 57 | const body = { 58 | 'alias': Config.TEST_EXISTING_ALIAS1, 59 | 'category': 'For Sale > Auto/Vehicle', 60 | 'title': 'Fast racing car', 61 | 'quantity': 1, 62 | 'price': 1999, 63 | 'description': '{"description":"Fast racing car detailed description","images":["https://i.imgur.com/BHmFf07.jpg"]}', 64 | 'currency': 'SYS', 65 | 'offertype': 'BUYNOW', 66 | 'privatevalue': false, 67 | 'auction_expires': 0, 68 | 'units': 1, 69 | 'auction_reserve': 0, 70 | 'auction_deposit': 0, 71 | 'cert_guid': '', 72 | 'auction_require_witness': false, 73 | 'payment_options': 'SYS', 74 | 'witness': '' 75 | }; 76 | 77 | request('POST', 'offernew', null, testAuthToken, body).end(function (err, res) { 78 | expect(err).to.be.null; 79 | expect(res).to.have.status(200); 80 | expect(res).to.have.header('content-type', 'application/json'); 81 | expect(res).to.be.json; 82 | //TO-DO: response schema validation 83 | done(); 84 | }); 85 | }); 86 | }); 87 | 88 | describe('offerupdate', function () { 89 | it('Creating new offer', function (done) { 90 | const body = { 91 | 'alias': Config.TEST_EXISTING_ALIAS1, 92 | 'guid': Config.TEST_EXISTING_OFFER_GUID, 93 | 'category': 'For Sale > Auto/Vehicle', 94 | 'title': 'Updated Fast racing car', 95 | 'quantity': 1, 96 | 'price': 1999, 97 | 'description': '{"description":"Fast racing car detailed updated description","images":["https://i.imgur.com/BHmFf07.jpg"]}', 98 | 'currency': 'SYS', 99 | 'offer_type': 'BUYNOW', 100 | 'privatevalue': false, 101 | 'auction_expires': 0, 102 | 'units': 1, 103 | 'auction_reserve': 0, 104 | 'auction_deposit': 0, 105 | 'cert_guid': '', 106 | 'auction_require_witness': false, 107 | 'payment_options': 'SYS', 108 | 'witness': '', 109 | 'commission': 0 110 | }; 111 | 112 | request('POST', 'offerupdate', null, testAuthToken, body).end(function (err, res) { 113 | expect(err).to.be.null; 114 | expect(res).to.have.status(200); 115 | expect(res).to.have.header('content-type', 'application/json'); 116 | expect(res).to.be.json; 117 | //TO-DO: response schema validation 118 | done(); 119 | }); 120 | }); 121 | }); 122 | 123 | 124 | 125 | }); 126 | -------------------------------------------------------------------------------- /server/nodejs/controllers/test/TestRequest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const app = require('../../index').app; 3 | const chai = require('chai'), chaiHttp = require('chai-http'); 4 | chai.use(chaiHttp); 5 | 6 | const requester = chai.request(app).keepOpen(); 7 | 8 | module.exports = { 9 | request: function (httpMethod, path, queryParams, authToken, body = null) { 10 | let request; 11 | switch (httpMethod) { 12 | case 'GET': 13 | request = requester.get('/' + path); 14 | break; 15 | case 'POST': 16 | request = requester.post('/' + path); 17 | break; 18 | case 'PUT': 19 | request = requester.put('/' + path); 20 | break; 21 | } 22 | if (queryParams) { 23 | request.query(queryParams); 24 | } 25 | 26 | if (body) { 27 | request.send(body); 28 | } 29 | 30 | if (authToken) { 31 | request.set({ 'token': authToken }); 32 | } 33 | 34 | request.set({ 'content-type': 'application/json' }); 35 | 36 | return request; 37 | } 38 | }; -------------------------------------------------------------------------------- /server/nodejs/controllers/test/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | DEBUG_ENABLED: false, 3 | 4 | //LOGIN 5 | TEST_CREDENTIALS_USERNAME: "u", 6 | TEST_CREDENTIALS_PASSWORD: "p", 7 | 8 | //ALIAS 9 | TEST_ALIAS_PEG: "sysrates.peg", 10 | TEST_EXISTING_ALIAS1: "daemon1", 11 | TEST_EXISTING_ALIAS2: "daemon2", 12 | TEST_TRX_HEX_STRING: "0200000003280217c09851808ff0c0ea0756200c77201b42771ab8c7eeb50dda3bd4c84f8b000000006b483045022100c9e5f4af4da78821f3fa9213f94b3b037165e3abf1113fa45e95655acbd3f670022069464298444664c91ca21bfbeea9b7747e45bdc7c444cbdc41dee1f4819e6e7c0121037e2840e1c8f799f9a9e5c9fbb36f760d1beaa8a4d4298ef31d1f4e90d952737bffffffff280217c09851808ff0c0ea0756200c77201b42771ab8c7eeb50dda3bd4c84f8b020000006b483045022100a918493440037102477fb4f78e6a64a5d0275ecf95fdc4b4641f314475f4b3a002205310a69b95bd64cec8efde53949a32d9c6e853979ef219c3392d6439456d63bc0121037e2840e1c8f799f9a9e5c9fbb36f760d1beaa8a4d4298ef31d1f4e90d952737bffffffffa33cefe44e8ea206f85839d0b47ff4f99dd41df2207b2987626966fedcc85b710c0000006a4730440220585bcc842a3492e8cc21d32ae65bcd8576c04d6dababf327d99d33d18844961b02206f1ed52628eaa4b13841dccc88594a9835837832062d2a6cc48f5989961433410121037e2840e1c8f799f9a9e5c9fbb36f760d1beaa8a4d4298ef31d1f4e90d952737bffffffff0240420f00000000001976a9145cfe620d5ecfe95a879c1be83a8c1a1dae8b296a88ac8671c9ac000000001976a91422264034d4ce25b009b0c052f6c522f291d89c2f88ac00000000", 13 | TEST_EXISTING_ADDRESS1: "TD5moHzipeYXkTzN74TGtQFcDmabxhTbAS", 14 | TEST_EXISTING_ADDRESS2: "TN2cpCVJLCpQT2xSJdLZd9BgJmom45hqCi", 15 | TEST_EXISTING_TXID: "2e23f4b123143bc27f9a925ace3f6a6cdc9a2a1ec666f9b6138e91c81ab56fb4", 16 | TEST_EXISTING_PUBKEY: "03944094ab076fb536d37c9ec951c1d0823fe31456a4f3f1c62b930b41201ced98", 17 | 18 | //ASSET 19 | TEST_EXISTING_ASSET_RANGES_GUID: "ef9a1e6128eb8040", 20 | TEST_EXISTING_ASSET_INTEREST_GUID: "9f1a5ba4f5d24c1d", 21 | TEST_EXISTING_ASSET_AMOUNTS_GUID: "4b2d286e31733315", 22 | 23 | //CERTIFICATE 24 | TEST_EXISTING_CERTIFICATE_GUID: "8309c38cfa85762b", 25 | 26 | //OFFER 27 | TEST_EXISTING_OFFER_GUID: "f914ef944510753d", 28 | 29 | //ESCROW 30 | TEST_EXISTING_ARBITER_ALIAS: "bcf-arbiter", 31 | TEST_EXISTING_ESCROW_GUID: "b8a1e6ec0b588b0e", 32 | TEST_EXISTING_ESCROW_ADDRESS: "2MveLjgeYsu28eWXazqsRQtuxWDwYD6c9Ci", 33 | 34 | //GENERAL 35 | TEST_EXISTING_BLOCK_HASH1: "2bf25cecda4ea8483c0efcf835bb70ac146c4e52e92c039b1298f18c40fe660a", 36 | TEST_EXISTING_BLOCK_NUMBER: "85200", 37 | TEST_DUMP_WALLET_PATH: "c:/temp/walletdump.dat", 38 | TEST_EXISTING_DUMP_PRIVKEY: "cTr5Y3dCjgTea146bLc9hG6rJxcX5aWdC5phhmBHEfmkKqvvHkSu", 39 | TEST_ENCRYPT_WALLET_PASSPHRASE: "encryptme", 40 | 41 | //MASTERNODES 42 | TEST_SENTINEL_VERSION: "0.0.1", 43 | TEST_ELECTRUM_WALLET_PATH: "/controllers/test/electrum_wallet_sample.csv", 44 | 45 | }; 46 | -------------------------------------------------------------------------------- /server/nodejs/controllers/test/electrum_wallet_sample.csv: -------------------------------------------------------------------------------- 1 | address,private_key 2 | TD5moHzipeYXkTzN74TGtQFcDmabxhTbAS,cTr5Y3dCjgTea146bLc9hG6rJxcX5aWdC5phhmBHEfmkKqvvHkSu 3 | -------------------------------------------------------------------------------- /server/nodejs/controllers/util/commonUtils.js: -------------------------------------------------------------------------------- 1 | const config = require('../../config'); 2 | 3 | function reportError(response, errorStr) { 4 | response.statusCode = 500; 5 | let responseString; 6 | 7 | const errObj = parseError(errorStr); 8 | if(errObj) { 9 | responseString = JSON.stringify(errObj); 10 | }else{ 11 | responseString = JSON.stringify(JSON.stringify(errorStr.toString())); 12 | } 13 | console.error('Error: ' + responseString); 14 | return response.end(responseString); 15 | } 16 | 17 | function parseError(errorStr) { 18 | let errObj = null; 19 | 20 | //transform the RPC Error into a more Syscoin-specific error while maintaining the 500 status 21 | const rpcErrorStr = 'RpcError: 500 '; //with trailing space! 22 | let errObjStartIndex = errorStr.toString().indexOf(rpcErrorStr); 23 | 24 | if (errObjStartIndex >= 0) { 25 | let errObjStr = errorStr.toString().substr(rpcErrorStr.length-1); 26 | errObj = JSON.parse(errObjStr); 27 | } 28 | 29 | return errObj; 30 | } 31 | 32 | /** 33 | * 34 | * @param args Values to be logged, last value should be the reporting method name (string) 35 | */ 36 | function log(...args) { 37 | // Temporary fix for the original logging so that in absence of config we exit. 38 | if (!config) { 39 | console.log(args); 40 | return; 41 | } 42 | if (!config.methodsWithLoggingDisabled) { 43 | console.log(args); 44 | return; 45 | } 46 | const reportingMethod = args[args.length-1]; 47 | if(config.methodsWithLoggingDisabled.length > 0 && config.methodsWithLoggingDisabled.filter((item) => { 48 | return item == reportingMethod; 49 | }).length > 0) { 50 | console.log(reportingMethod + ' not logged because disabled'); 51 | return; //if the reportingMethod is in the array of methods w logging disabled, dont log it! 52 | } 53 | 54 | console.log(args); 55 | } 56 | 57 | module.exports.reportError = reportError; 58 | module.exports.parseError = parseError; 59 | module.exports.log = log; -------------------------------------------------------------------------------- /server/nodejs/controllers/util/generalServiceGetInfoUtils.js: -------------------------------------------------------------------------------- 1 | function createCustomWalletPercentageInfoResponse(walletPercentage) { 2 | const infoObj = { 3 | version: -1, 4 | protocolversion: -1, 5 | walletversion: -1, 6 | balance: walletPercentage, 7 | blocks: 0, 8 | timeoffset: 0, 9 | connections: 0, 10 | proxy: 'WalletPercentage', 11 | difficulty: 0, 12 | testnet: false, 13 | keypoololdest: 0, 14 | keypoolsize: 0, 15 | unlocked_until: 0, 16 | paytxfee: 0, 17 | relayfee: 0, 18 | errors: 'WalletPercentageMessage' 19 | }; 20 | return infoObj; 21 | } 22 | 23 | function extractWalletPercentageFromGetInfoResponseMessage(jsonErrorMessage) { 24 | if (!jsonErrorMessage) { 25 | return '0'; 26 | } 27 | 28 | const firstBracketIndex = jsonErrorMessage.indexOf('('); 29 | const endIndex = jsonErrorMessage.indexOf(' %)'); 30 | if (firstBracketIndex === -1 || endIndex === -1) { 31 | return '0'; 32 | } 33 | return jsonErrorMessage.substring(firstBracketIndex+1,endIndex-1); 34 | } 35 | 36 | function getInfoResponseIsWalletPercentageResponse(jsonError) { 37 | return jsonError 38 | && jsonError.code === -28 39 | && jsonError.message 40 | && jsonError.message.indexOf('(') !== -1 41 | && jsonError.message.indexOf(' %)') !== -1; 42 | } 43 | 44 | module.exports.createCustomWalletPercentageInfoResponse = createCustomWalletPercentageInfoResponse; 45 | module.exports.extractWalletPercentageFromGetInfoResponseMessage = extractWalletPercentageFromGetInfoResponseMessage; 46 | module.exports.getInfoResponseIsWalletPercentageResponse = getInfoResponseIsWalletPercentageResponse; -------------------------------------------------------------------------------- /server/nodejs/controllers/util/methodGenerator.js: -------------------------------------------------------------------------------- 1 | const syscoinClient = require('../../index').syscoinClient; 2 | const varUtils = require('./varUtils'); 3 | const commonUtils = require('./commonUtils'); 4 | 5 | function generateGenericSyscoinMethod(argList, syscoinMethod, syscoinMethodName, httpMethod, asJsonObject = false) { 6 | return function (args, res) { 7 | if (!syscoinMethod) { 8 | throw Error(`${syscoinMethodName} was called but not present. 9 | Check your syscoin-core definitions to see whether it exists.`); 10 | } 11 | let callback = function (err, result) { 12 | res.setHeader('Content-Type', 'application/json'); 13 | 14 | if (err) { 15 | return commonUtils.reportError(res, err); 16 | } 17 | 18 | console.log(); 19 | commonUtils.log(syscoinMethodName, result, syscoinMethodName); 20 | res.end(JSON.stringify(result)); 21 | }; 22 | 23 | let arr = varUtils.getArgsArr(argList, args, httpMethod, callback, asJsonObject); 24 | syscoinMethod.apply(syscoinClient, arr); 25 | }; 26 | } 27 | 28 | module.exports.generateGenericSyscoinMethod = generateGenericSyscoinMethod; 29 | -------------------------------------------------------------------------------- /server/nodejs/controllers/util/mongoUtils.js: -------------------------------------------------------------------------------- 1 | 2 | const insertDocuments = async (collection, docs) => { 3 | try { 4 | let result = await collection.insertMany(docs); 5 | if (docs.length == result.result.n && docs.length == result.ops.length) { 6 | console.log(`Inserted ${docs.length} documents into the document collection`); 7 | return result; 8 | } 9 | }catch(e) { 10 | throw new Error(e); 11 | } 12 | }; 13 | 14 | const upsertDocument = async (collection, filter, upsertDoc) => { 15 | try { 16 | let result = await collection.updateOne(filter, upsertDoc, { upsert: true}); 17 | console.log('r:' + JSON.stringify(result)); 18 | console.log(`Upserted ${result.matchedCount} documents into the document collection. Upserted ID is ${filter._id}.`); 19 | return { upsertedId: filter._id, dbResult: result }; 20 | }catch(e) { 21 | throw new Error(e); 22 | } 23 | }; 24 | 25 | module.exports.insertDocuments = insertDocuments; 26 | module.exports.upsertDocument = upsertDocument; -------------------------------------------------------------------------------- /server/nodejs/controllers/util/spec/varUtils.spec.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect; 2 | 3 | var varUtils = require('../varUtils'); 4 | 5 | describe('VerUtils Helper', function() { 6 | 7 | describe('setArgsArr', function () { 8 | it('Creates and array out of the arguments passed, in order via GET', function (done) { 9 | var args = { 10 | title: { value: 'test' }, 11 | description: { value: 'hello' } 12 | }; 13 | 14 | var requiredArgs = [ 15 | { prop: 'title' }, 16 | { prop: 'description' } 17 | ]; 18 | 19 | var argList = varUtils.getArgsArr(requiredArgs, args); 20 | 21 | expect(argList.length).to.equal(2); 22 | expect(argList[0]).to.equal('test'); 23 | expect(argList[1]).to.equal('hello'); 24 | done(); 25 | }); 26 | 27 | it('Creates and array out of the arguments passed, in order via POST', function (done) { 28 | var args = { 29 | request: { 30 | value: { 31 | title: 'test', 32 | description: 'hello' 33 | } 34 | } 35 | }; 36 | 37 | var requiredArgs = [ 38 | { prop: 'title' }, 39 | { prop: 'description' } 40 | ]; 41 | 42 | var argList = varUtils.getArgsArr(requiredArgs, args, 'POST'); 43 | 44 | expect(argList.length).to.equal(2); 45 | expect(argList[0]).to.equal('test'); 46 | expect(argList[1]).to.equal('hello'); 47 | done(); 48 | }); 49 | 50 | it('Creates and array out of the arguments passed and adds the callback last, in order via POST', function (done) { 51 | var args = { 52 | request: { 53 | value: { 54 | title: 'test', 55 | description: 'hello' 56 | } 57 | } 58 | }; 59 | var cb = function() { }; 60 | 61 | var requiredArgs = [ 62 | { prop: 'title' }, 63 | { prop: 'description' } 64 | ]; 65 | 66 | var argList = varUtils.getArgsArr(requiredArgs, args, 'POST', cb); 67 | 68 | expect(argList.length).to.equal(3); 69 | expect(argList[0]).to.equal('test'); 70 | expect(argList[1]).to.equal('hello'); 71 | expect(argList[2]).to.equal(cb); 72 | done(); 73 | }); 74 | 75 | it('Creates and array out of the arguments passed and fills in gap-arguements w default values', function (done) { 76 | var args = { 77 | request: { 78 | value: { 79 | title: 'test', 80 | description: 'hello', 81 | private: false 82 | } 83 | } 84 | }; 85 | var cb = function() { }; 86 | 87 | var requiredArgs = [ 88 | { prop: 'title' }, 89 | { prop: 'description' }, 90 | { prop: 'quantity', defaultValue: 1 }, 91 | { prop: 'private', defaultValue: true } 92 | ]; 93 | 94 | var argList = varUtils.getArgsArr(requiredArgs, args, 'POST', cb); 95 | 96 | expect(argList.length).to.equal(5); 97 | expect(argList[0]).to.equal('test'); 98 | expect(argList[1]).to.equal('hello'); 99 | expect(argList[2]).to.equal(1); 100 | expect(argList[3]).to.equal(false); 101 | 102 | expect(argList[4]).to.equal(cb); 103 | done(); 104 | }); 105 | }); 106 | 107 | describe('correctTypes', function () { 108 | it('Converts a number to a string', function (done) { 109 | var args = { 110 | title: { value: 1 } 111 | }; 112 | 113 | args.title.value = varUtils.correctTypes(args.title.value, varUtils.TYPE_CONVERSION.NUM_TO_STRING); 114 | 115 | expect(args.title.value ).to.equal('1'); 116 | done(); 117 | }); 118 | 119 | it('Converts a series of number nested in a mixed array to a string', function (done) { 120 | var args = { 121 | title: { value: [1, '2', 3, '4'] } 122 | }; 123 | 124 | args.title.value = varUtils.correctTypes(args.title.value, varUtils.TYPE_CONVERSION.NUM_TO_STRING); 125 | 126 | //for more info on this solution: https://medium.com/@victorleungtw/testing-with-mocha-array-comparison-e9a45b57df27 127 | expect(args.title.value.toString()).to.equal(['1', '2', '3', '4'].toString()); 128 | done(); 129 | }); 130 | 131 | it('Converts a boolean to a string', function (done) { 132 | var args = { 133 | title: { value: true } 134 | }; 135 | 136 | args.title.value = varUtils.correctTypes(args.title.value, varUtils.TYPE_CONVERSION.BOOL_TO_STRING); 137 | 138 | expect(args.title.value ).to.equal('true'); 139 | done(); 140 | }); 141 | 142 | it('Creates and array out of the arguments passed and adds the callback last, in order via POST', function (done) { 143 | var args = { 144 | title: { value: true } 145 | }; 146 | 147 | args.title.value = varUtils.correctTypes(args.title.value, varUtils.TYPE_CONVERSION.BOOL_TO_NUM_STRING); 148 | 149 | expect(args.title.value ).to.equal('1'); 150 | done(); 151 | }); 152 | }); 153 | 154 | }); -------------------------------------------------------------------------------- /server/nodejs/controllers/util/varUtils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Takes an object which describes the required AND optional properties expected to be on an object, and if that value is defined 3 | * it is added to the array of params to be returned, order matters here. Order is based on the order of fullArgList. 4 | * @param fullArgList Array with the full list of arguments, required and optional 5 | * @param requestArgs Actual args past in the request, structure varies dependent on request type 6 | */ 7 | function getArgsArr(fullArgList, requestArgs, httpMethod, callback, asJsonObject = false) { 8 | let arr = []; 9 | let jsonObject = {}; 10 | 11 | for (var i = 0; i < fullArgList.length; i++) { 12 | let paramValue = null; 13 | let argObj = fullArgList[i]; 14 | 15 | switch (httpMethod) { 16 | case 'GET': 17 | if (notNullOrUndefined(requestArgs) && notNullOrUndefined(requestArgs[argObj.prop]) && notNullOrUndefined(requestArgs[argObj.prop].value)) { 18 | paramValue = requestArgs[argObj.prop].value; 19 | } 20 | break; 21 | case 'POST': 22 | case 'PUT': 23 | if (notNullOrUndefined(requestArgs) && notNullOrUndefined(requestArgs.request) && notNullOrUndefined(requestArgs.request.value) && notNullOrUndefined(requestArgs.request.value[argObj.prop])) { 24 | paramValue = requestArgs.request.value[argObj.prop]; 25 | } 26 | break; 27 | } 28 | 29 | if (argObj && !notNullOrUndefined(paramValue) && notNullOrUndefined(argObj.defaultValue)) { 30 | paramValue = argObj.defaultValue; 31 | } 32 | 33 | if (notNullOrUndefined(paramValue)) { 34 | if (argObj && notNullOrUndefined(argObj.syscoinType)) { 35 | console.info('Need to convert value of "' + [argObj.prop] + '" to a ' + argObj.syscoinType + ' type...'); 36 | paramValue = correctTypes(paramValue, getConversionMethod(typeof paramValue, argObj.syscoinType)); 37 | } 38 | 39 | if (argObj && notNullOrUndefined(argObj.asJsonObject) && argObj.asJsonObject && !asJsonObject) { 40 | console.info('Need to convert value of "' + [argObj.prop] + '" to JSON object...'); 41 | let obj = {} 42 | obj[argObj.prop] = paramValue; 43 | paramValue = obj; 44 | } 45 | 46 | if (asJsonObject) { 47 | // in case Syscoin expects the request provided as JSON object 48 | jsonObject[argObj.prop] = paramValue; 49 | } else { 50 | // in case Syscoin expects the request provided as array of values 51 | arr.push(paramValue); 52 | } 53 | 54 | } else { 55 | console.error('ERROR: No value defined in request for ' + argObj.prop + ' and no defaultValue specified. Is this a required param?'); 56 | } 57 | 58 | } 59 | 60 | if (asJsonObject) { 61 | arr.push(jsonObject); 62 | } 63 | 64 | //add callback last 65 | if (callback) 66 | arr.push(callback); 67 | 68 | console.log('Request parameters: ' + JSON.stringify(arr)); 69 | 70 | return arr; 71 | } 72 | 73 | function getConversionMethod(typeFrom, typeTo) { 74 | 75 | let conversionMethod; 76 | 77 | switch (typeFrom) { 78 | case 'number': 79 | if (typeTo === DataType.STRING) 80 | conversionMethod = TYPE_CONVERSION.NUM_TO_STRING; 81 | else if (typeTo === DataType.NUMBER) 82 | conversionMethod = TYPE_CONVERSION.COPY; 83 | break; 84 | case 'boolean': 85 | if (typeTo === DataType.STRING) 86 | conversionMethod = TYPE_CONVERSION.BOOL_TO_STRING; 87 | else if (typeTo === DataType.NUMBER) 88 | conversionMethod = TYPE_CONVERSION.BOOL_TO_NUM_STRING; 89 | else if (typeTo === DataType.BOOLEAN) 90 | conversionMethod = TYPE_CONVERSION.COPY; 91 | break; 92 | case 'string': 93 | if (typeTo === DataType.STRING) 94 | conversionMethod = TYPE_CONVERSION.COPY; 95 | break; 96 | default: 97 | console.error('No matching pairs for data type conversion are configured'); 98 | break; 99 | } 100 | 101 | return conversionMethod; 102 | } 103 | 104 | const DataType = Object.freeze( 105 | { 106 | STRING: 'string', 107 | NUMBER: 'number', 108 | BOOLEAN: 'boolean' 109 | } 110 | ); 111 | 112 | /** 113 | * More predictable method for determining empty values 114 | * @param param A value that should be non-null, non-undefined 115 | * @returns {boolean} Whether the value is non-null, non-undefined 116 | */ 117 | function notNullOrUndefined(param) { 118 | return !(param === null || param === undefined); 119 | } 120 | 121 | var TYPE_CONVERSION = Object.freeze( 122 | { 123 | NUM_TO_STRING: 'numToString', //1 to "1" 124 | BOOL_TO_STRING: 'boolToString', //true to "true" 125 | BOOL_TO_NUM_STRING: 'boolToNumString', //true to "1" 126 | COPY: 'copy' 127 | }); 128 | 129 | function correctTypes(param, conversionType) { 130 | 131 | console.info('Converting', param, 'using', conversionType, 'method...'); 132 | let newValue; 133 | 134 | if (notNullOrUndefined(param) && notNullOrUndefined(conversionType)) { 135 | switch (conversionType) { 136 | case TYPE_CONVERSION.NUM_TO_STRING: 137 | if (Array.isArray(param)) { //if param is an array, walk it and convert all elements to strings 138 | newValue = param.map((item) => { 139 | return item.toString(); 140 | }); 141 | } else { 142 | newValue = param.toString(); 143 | } 144 | break; 145 | case TYPE_CONVERSION.BOOL_TO_STRING: 146 | newValue = param ? 'true' : 'false'; 147 | break; 148 | case TYPE_CONVERSION.BOOL_TO_NUM_STRING: 149 | newValue = param ? '1' : '0'; 150 | break; 151 | case TYPE_CONVERSION.COPY: 152 | newValue = param; 153 | break; 154 | default: 155 | throw new Error('No matching TYPE_CONVERSION found for ' + conversionType); 156 | } 157 | } else { 158 | console.warn('Either parameter is undefined! Cannot convert type.'); 159 | } 160 | 161 | return newValue; 162 | } 163 | 164 | module.exports.getArgsArr = getArgsArr; 165 | module.exports.notNullOrUndefined = notNullOrUndefined; 166 | module.exports.TYPE_CONVERSION = TYPE_CONVERSION; 167 | module.exports.correctTypes = correctTypes; 168 | module.exports.DataType = DataType; -------------------------------------------------------------------------------- /server/nodejs/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('dotenv').config(); 4 | 5 | const app = require('connect')(); 6 | const http = require('http'); 7 | const swaggerTools = require('swagger-tools'); 8 | const jsyaml = require('js-yaml'); 9 | const fs = require('fs'); 10 | const jwt = require('jsonwebtoken'); 11 | const cors = require('cors'); 12 | 13 | //load external config 14 | const config = require('./config'); 15 | const SyscoinClient = require('@syscoin/syscoin-core'); 16 | 17 | let syscoinClient, 18 | rpcuser = 'u', 19 | rpcpass = 'p', 20 | rpcport = 8336; 21 | 22 | let swaggerDoc, options; 23 | 24 | //CORS 25 | app.use(cors({ 26 | 'origin': '*', 27 | 'methods': 'GET,HEAD,PUT,PATCH,POST,DELETE', 28 | 'preflightContinue': false //critical for proper swagger cors operations 29 | })); 30 | 31 | const verboseLog = (msg) => { 32 | if(config.verbose_debug) 33 | console.log(`>> ${msg}`); 34 | }; 35 | 36 | const startServer = async () => { 37 | verboseLog('startServer'); 38 | await readConfig(); 39 | initSyscoin(); 40 | initSwaggerUI(); 41 | await initMiddleware(); 42 | initHttp(); 43 | }; 44 | 45 | const readConfig = async () => { 46 | verboseLog('readConfig'); 47 | 48 | let lineReader = require('readline').createInterface({ 49 | input: inputStream 50 | }); 51 | 52 | //read syscoin.conf for login creds, if it doesn't exist use defaults. 53 | lineReader.on('line', function (line) { 54 | if (line.indexOf('rpcuser=') === 0) { 55 | rpcuser = line.substr(line.indexOf('=') + 1); 56 | } 57 | 58 | if (line.indexOf('rpcpassword=') === 0) { 59 | rpcpass = line.substr(line.indexOf('=') + 1); 60 | } 61 | 62 | if (line.indexOf('rpcport=') === 0) { 63 | rpcport = line.substr(line.indexOf('=') + 1); 64 | } 65 | }); 66 | 67 | //init SYS API on close of config file read 68 | return new Promise(resolve => { 69 | lineReader.on('close', function () { 70 | verboseLog('readConfig :: Done'); 71 | resolve(true); 72 | }); 73 | }); 74 | }; 75 | 76 | const initSyscoin = () => { 77 | verboseLog('initSyscoin'); 78 | console.log('RPCUSER:', rpcuser); 79 | console.log('RPCPASS:', rpcpass); 80 | console.log('RPCPORT:', rpcport); 81 | 82 | syscoinClient = new SyscoinClient({ 83 | host: 'localhost', 84 | port: rpcport, 85 | username: rpcuser, 86 | password: rpcpass, 87 | timeout: 30000 88 | }); 89 | 90 | exports.syscoinClient = syscoinClient; 91 | exports.rpcuser = rpcuser; 92 | exports.rpcpass = rpcpass; 93 | }; 94 | 95 | const initSwaggerUI = () => { 96 | verboseLog('initSwaggerUI'); 97 | // swaggerRouter configuration 98 | if(config.run_as_subprocess) { 99 | options = { 100 | controllers: config.api_controllers, 101 | useStubs: process.env.NODE_ENV === 'development' ? true : false // Conditionally turn on stubs (mock mode) 102 | }; 103 | }else { 104 | options = { 105 | swaggerUiDir: '../../swagger-ui/dist', 106 | controllers: config.api_controllers, 107 | useStubs: process.env.NODE_ENV === 'development' ? true : false // Conditionally turn on stubs (mock mode) 108 | }; 109 | } 110 | 111 | // The Swagger document (require it, build it programmatically, fetch it from a URL, ...) 112 | let spec = fs.readFileSync(config.api_yaml, 'utf8'); 113 | swaggerDoc = jsyaml.safeLoad(spec); 114 | }; 115 | 116 | const initMiddleware = async () => { 117 | verboseLog('initMiddleware'); 118 | // Initialize the Swagger middleware 119 | return new Promise(resolve => { 120 | swaggerTools.initializeMiddleware(swaggerDoc, function (middleware) { 121 | // Interpret Swagger resources and attach metadata to request - must be first in swagger-tools middleware chain 122 | app.use(middleware.swaggerMetadata()); 123 | 124 | // Route security 125 | let securityOptions = { 126 | token: authCheck 127 | }; 128 | 129 | app.use(middleware.swaggerSecurity(securityOptions)); 130 | 131 | // Validate Swagger requests 132 | app.use(middleware.swaggerValidator()); 133 | 134 | // Route validated requests to appropriate controller 135 | app.use(middleware.swaggerRouter(options)); 136 | 137 | // Serve the Swagger documents and Swagger UI 138 | app.use(middleware.swaggerUi(options)); 139 | 140 | verboseLog('initMiddleware :: Done'); 141 | resolve(true); 142 | }); 143 | }); 144 | }; 145 | 146 | const initHttp = () => { 147 | verboseLog('initHttp'); 148 | // Start the server 149 | http.createServer(app).listen(config.port, function () { 150 | console.log('Your server is listening on port %d (http://localhost:%d)', config.port, config.port); 151 | console.log('Swagger-ui is available on http://localhost:%d/docs', config.port); 152 | }); 153 | }; 154 | 155 | const authCheck = (req, authOrSecDef, scopesOrApiKey, callback) => { 156 | let authToken = req.headers.token || (req.token ? req.token.value : null); 157 | 158 | console.log('Performing security check for TOKEN:', authToken); 159 | 160 | if (authToken) { 161 | // verifies secret and checks exp 162 | jwt.verify(authToken, config.api_secret, function(err) { 163 | if (err) { 164 | console.log('VERIFY ERROR: ' + err); 165 | return callback({ 166 | message: 'Invalid token.', 167 | code: 'InvalidToken', 168 | statusCode: 401, 169 | headers: [] 170 | }); 171 | } else { 172 | // if everything is good, save to request for use in other routes 173 | callback(); 174 | } 175 | }); 176 | }else{ 177 | callback({ 178 | message: 'No token provided.', 179 | code: 'NoTokenProvided', 180 | statusCode: 401, 181 | headers: [] 182 | }); 183 | } 184 | }; 185 | 186 | //app startup based on syscoin.conf read 187 | let inputStreamError = false; 188 | let inputStream = fs.createReadStream(config.sys_location + 'syscoin.conf'); 189 | inputStream.on('error', function (e) { 190 | console.log('Error reading syscoin.conf specified at ' + config.sys_location + ' falling back to defaults. Exact error is:' + JSON.stringify(e)); 191 | console.log('Syscoin.conf must be present, with rpcuser, rpcpass, and rpcport set in order to run the Syscoin API Server.'); 192 | process.exit(); 193 | }); 194 | 195 | if(!inputStreamError && !config.run_as_subprocess) { 196 | startServer(); 197 | } 198 | 199 | module.exports.startServer = startServer; 200 | module.exports.app = app; 201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /server/nodejs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@syscoin/syscoin-nodejs", 3 | "version": "3.0.0-beta", 4 | "description": "", 5 | "scripts": { 6 | "start": "node .", 7 | "startd": "pm2 start node . $CONFIG --name 'sys-api-server'", 8 | "test": "mocha **/test/*.test.js --reporter spec --timeout 10000 --colors --exit", 9 | "isolated": "APIRUNMODE=isolated node .", 10 | "integrated": "APIRUNMODE=integrated node .", 11 | "windows-isolated": "set APIRUNMODE=isolated&& node .", 12 | "windows-integrated": "set APIRUNMODE=integrated&& node .", 13 | "lint": "eslint --ignore-path .jshintignore *.js", 14 | "lint-fix": "eslint --fix . --ignore-path .jshintignore", 15 | "precommit": "npm run lint", 16 | "prepush": "npm run lint" 17 | }, 18 | "main": "index.js", 19 | "keywords": [ 20 | "swagger" 21 | ], 22 | "license": "MIT", 23 | "private": false, 24 | "dependencies": { 25 | "@syscoin/syscoin-core": "^3.1.1", 26 | "assert": "^1.4.1", 27 | "chai": "^4.1.2", 28 | "chai-http": "^4.0.0", 29 | "connect": "^3.6.5", 30 | "cors": "^2.8.4", 31 | "dotenv": "^4.0.0", 32 | "finalhandler": "^1.1.0", 33 | "he": "^1.1.1", 34 | "js-yaml": "^3.10.0", 35 | "jshashes": "^1.0.7", 36 | "jsonwebtoken": "^7.4.3", 37 | "mocha": "^5.2.0", 38 | "mongodb": "^2.2.33", 39 | "q": "^1.5.1", 40 | "request": "^2.83.0", 41 | "request-promise": "^4.2.2", 42 | "serve-static": "^1.13.1", 43 | "swagger-tools": "0.10.1" 44 | }, 45 | "bugs": { 46 | "url": "https://github.com/syscoin/syscoin-api/issues" 47 | }, 48 | "homepage": "https://github.com/syscoin/syscoin-api", 49 | "devDependencies": { 50 | "husky": "^0.10.1", 51 | "eslint": "^5.0.1" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /server/nodejs/spec/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | HOST: "http://localhost:8001/", //include trailing slash 3 | DEBUG_ENABLED: false, 4 | 5 | TEST_ALIAS_PEG: "sysrates.peg", 6 | TEST_ALIAS: "lucifer", 7 | TEST_ALIAS_PASSWORD: "testpassword", 8 | 9 | TEST_OFFER_GUID: "02ac590247af2d48", 10 | TEST_ESCROW_GUID: "a965c649fc25f902", 11 | 12 | TEST_CERT_GUID: "cc8c85f466a2e054", 13 | 14 | TEST_MESSAGE_GUID: "303e8986016b142c", 15 | 16 | TEST_ADDRESS: "TT9LtA6xD2vM99992zpYieQGw1GTJoT1hM", 17 | }; 18 | --------------------------------------------------------------------------------