├── .gitignore ├── mb.png ├── icon.png ├── bin ├── useradd.js ├── echo.js ├── cat.js ├── whoami.js ├── init.js └── route.js ├── README.md ├── package.json ├── lib └── post.js ├── index.js └── 0.1.0.md /.gitignore: -------------------------------------------------------------------------------- 1 | .bit 2 | node_modules 3 | -------------------------------------------------------------------------------- /mb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unwriter/Bitcom/HEAD/mb.png -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unwriter/Bitcom/HEAD/icon.png -------------------------------------------------------------------------------- /bin/useradd.js: -------------------------------------------------------------------------------- 1 | const post = require('../lib/post') 2 | module.exports = function(params) { 3 | post(["$", "useradd", process.env.ADDRESS]) 4 | } 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bitcom 2 | 3 | Universal Bitcoin Computer 4 | 5 | - Decentralized Global Registry of Bitcoin Application Protocols 6 | - Create and Publish Application Protocols with Zero friction. 7 | - Inspired by Unix Filesystem for Future Extensibility 8 | 9 | [Visit the Website](https://bitcom.bitdb.network) 10 | -------------------------------------------------------------------------------- /bin/echo.js: -------------------------------------------------------------------------------- 1 | /********************************** 2 | * 3 | * echo B to name 4 | * 5 | **********************************/ 6 | const post = require('../lib/post') 7 | module.exports = function(params) { 8 | if (params.length === 3 && params[1] && params[1][0] === 'to' && params[2] && params[2].length === 1) { 9 | let content = params[0][1] 10 | let filename = params[2][0] 11 | console.log(content, filename) 12 | post(["$", "echo", content, "to", filename]) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /bin/cat.js: -------------------------------------------------------------------------------- 1 | /********************************** 2 | * 3 | * cat bit://[..]/[...] to filename 4 | * 5 | **********************************/ 6 | const post = require('../lib/post') 7 | module.exports = function(params) { 8 | if (params.length === 3 && params[1] && params[1][0] === 'to' && params[2] && params[2].length === 1) { 9 | let uri = params[0][1] 10 | let filename = params[2][0] 11 | console.log(uri, filename) 12 | post(["$", "cat", uri, "to", filename]) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bitcom", 3 | "version": "0.1.2", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "./node_modules/mocha/bin/mocha" 8 | }, 9 | "bin": { 10 | "bit": "./index.js" 11 | }, 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "axios": "^0.18.0", 16 | "datapay": "0.0.12", 17 | "dotenv": "^6.2.0", 18 | "qrcode-terminal": "^0.12.0" 19 | }, 20 | "devDependencies": { 21 | "mocha": "^5.2.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/post.js: -------------------------------------------------------------------------------- 1 | const datapay = require('datapay') 2 | module.exports = function(pushdata) { 3 | if (process.env.ADDRESS && process.env.PRIVATE) { 4 | let payload = { 5 | data: pushdata, 6 | pay: { key: process.env.PRIVATE } 7 | } 8 | console.log("Publishing payload = ", JSON.stringify(payload, null, 2)) 9 | datapay.send(payload, function(err, tx) { 10 | if (err) console.log(err) 11 | console.log(tx) 12 | }) 13 | } else { 14 | console.log("Please run 'bit init' to generate a keypair") 15 | process.exit() 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const path = require('path') 3 | const fs = require('fs') 4 | require('dotenv').config({path: path.resolve(process.cwd(), '.bit')}) 5 | const bin = {} 6 | const keywords = ['cat', 'echo', 'route', 'useradd', 'to'] 7 | const tokenize = function(tokens) { 8 | let result = [] 9 | let bundle = [] 10 | for(let index=0; index= 3) { 35 | fs.readdir(__dirname + "/bin", async function(err, items) { 36 | for (let i=0; i= 3) { 24 | let cmd = items[1]; 25 | let args = items.slice(2); 26 | if (cmd === 'enable' && args.length === 1) { 27 | post(["$"].concat(items)) 28 | } else if (cmd === 'add') { 29 | if (args.length === 3) { 30 | if (process.env.ADDRESS === args[0]) { 31 | console.log("[Error] It is not recommended for admins to add routes, adding routes are for service providers. If you want to act as a service provider, create a separate account (create a new folder and run 'bit init') and run 'route add' again.") 32 | } else { 33 | // check that the route is enabled 34 | let address = items[2] 35 | let route = items[3] 36 | var query = { 37 | "v": 3, 38 | "q": { 39 | "db": ["c"], 40 | "find": { 41 | "in.e.a": address, 42 | "out.s4": route 43 | }, 44 | "project": { 45 | "out.s1": 1, "out.s2": 1, "out.s3": 1, "out.s4": 1, "out.s5": 1 46 | } 47 | } 48 | }; 49 | var s = JSON.stringify(query); 50 | var b64 = Buffer.from(s).toString('base64'); 51 | var url = endpoint + b64; 52 | var header = { headers: { key: apikey } }; 53 | axios.get(url, header).then(function(r) { 54 | console.log("response = ", r.data) 55 | if (r.data.c && r.data.c.length > 0) { 56 | console.log("route exists:", address, route) 57 | post(["$"].concat(items)) 58 | } else { 59 | console.log("route doesn't exist", address, route) 60 | } 61 | }) 62 | } 63 | } else { 64 | console.log("Syntax: 'bit route add [BITCOM_ADDRESS] [ROUTE] [SERVICE_ENDPOINT]'") 65 | } 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /0.1.0.md: -------------------------------------------------------------------------------- 1 | # 0.1.0 Release Note 2 | 3 | ## Feature Additions 4 | 5 | ### 1. cat 6 | 7 | Add support for `cat`, allowing assignment of files to attributes 8 | 9 | ``` 10 | cat bit://19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut/e55fed7fe709567f7b4191c180c91a7bae8b354b091d9653f2512ca51738734a to readme 11 | ``` 12 | 13 | ### 2. route 14 | 15 | Add support for [bit://](https://bit.planaria.network) 16 | 17 | #### a. enable 18 | 19 | - Enable means effectively opening up the specified protocol route for any service provider to implement. 20 | - Only the admin can enable a route. 21 | 22 | Syntax 23 | 24 | ``` 25 | OP_RETURN $ route enable [ROUTE_MATCHER] 26 | ``` 27 | 28 | Example 29 | 30 | ``` 31 | OP_RETURN $ route enable /tx/:tx 32 | ``` 33 | 34 | #### b. add 35 | 36 | - `add` means plugging in a service endpoint to bitcoin protocols 37 | - Any service provider can add their endpoint to a route. 38 | - But there may be another step to make sure the added endpoint actually is affiliated with the Bitcom address, through schemes such as [Bitcoin Sticker Protocol](https://sticker.planaria.network). 39 | - should block if the admin tries to add a route. A separate account (for service providers) must be created to add a route. The admin should only enable routes. 40 | 41 | Syntax 42 | 43 | ``` 44 | OP_RETURN $ route add [BITCOM_ADDRESS] [ROUTE_MATCHER] [ENDPOINT_TEMPLATE] 45 | ``` 46 | 47 | Example 48 | 49 | ``` 50 | OP_RETURN $ route add 19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut /:tx https://media.bitcoinfiles.org/${tx} 51 | ``` 52 | 53 | #### Route Matcher 54 | 55 | Both the `route enable` and `route add` utilizes the route matcher pattern. Here's what they can look like: 56 | 57 | | Example | Description | 58 | | --------------- | -------------------------------------------------------------------- | 59 | | `:tx` | a param to capture from the route up to `/`, `?`, or end of string | 60 | | `*splat` | a splat to capture from the route up to `?` or end of string | 61 | | `()` | Optional group that doesn't have to be part of the query. Can contain nested optional groups, params, and splats 62 | | anything else | free form literals | 63 | 64 | Eamples: 65 | 66 | * `/some/(optional/):thing` 67 | * `/users/:id/comments/:comment/rating/:rating` 68 | * `/*a/foo/*b` 69 | * `/books/*section/:title` 70 | * `/books?author=:author&subject=:subject` 71 | 72 | > NOTE: The ruleset is from https://github.com/rcs/route-parser/blob/master/README.md 73 | 74 | #### Endpoint Template 75 | 76 | The endpoint template takes the matched variable and instantiates it into the final static URI form. 77 | 78 | For example, the following expression takes the matched variable `tx` from the route matcher, and instantiates the endpoint url template `https://media.bitcoinfiles.org/${tx}`. 79 | 80 | ``` 81 | OP_RETURN $ route add 19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut /:tx https://media.bitcoinfiles.org/${tx} 82 | ``` 83 | 84 | ### 3. Charge with MoneyButton 85 | 86 | In addition to QR code, you can now charge your Bitcom wallet using [ButtonPage](https://button.bitdb.network). 87 | 88 | ![mb](./mb.png) 89 | 90 | ## Refactor 91 | 92 | Organized all commands into `bin` folder. 93 | --------------------------------------------------------------------------------