瀏覽代碼

update to new CLR version, refine deployment script with better log output

master
nitowa 1 年之前
父節點
當前提交
b78464beab

+ 431
- 609
package-lock.json
文件差異過大導致無法顯示
查看文件


+ 3
- 4
package.json 查看文件

@@ -13,7 +13,7 @@
13 13
     "copy-gui": "cp src/frontend/build/index.html gui",
14 14
     "webpack-gateway": "webpack --config webpack.gateway.js --progress && cp build/gateway/main.js gateway",
15 15
     "deploy": "node ./lib/Deploy.js",
16
-    "github": "cp gateway/* ~/caisar.github.io && cd ~/caisar.github.io && git checkout master && git add -A && git commit -m \"update\" --allow-empty && git push origin master --force && git checkout main && git add -A && git commit -m \"update\" --allow-empty && git push origin main --force"
16
+    "github": "cp gateway/index.html ~/caisar.github.io && cp gateway/main.js ~/caisar.github.io && cd ~/caisar.github.io && git checkout master && git add -A && git commit -m \"update\" --allow-empty && git push origin master --force && git checkout main && git add -A && git commit -m \"update\" --allow-empty && git push origin main --force"
17 17
   },
18 18
   "author": "",
19 19
   "license": "ISC",
@@ -36,8 +36,7 @@
36 36
     "typescript": "^4.9.3",
37 37
     "url": "^0.11.0",
38 38
     "utf8": "^3.0.0",
39
-    "webpack": "^5.75.0",
40
-    "webpack-bundle-analyzer": "^4.7.0",
41
-    "webpack-cli": "^5.0.0"
39
+    "webpack": "^5.88.2",
40
+    "webpack-cli": "^5.1.4"
42 41
   }
43 42
 }

+ 4
- 2
src/Deploy.ts 查看文件

@@ -11,9 +11,11 @@ const path = require('path');
11 11
     console.log("Getting html from "+htmlPath)
12 12
     const htmlBuf = await fs.readFile(htmlPath)
13 13
     const html = htmlBuf.toString('ascii')
14
+    console.log(`Writing ${html.length} bytes to blockchain...`)
14 15
     const dataHash = await api.treeWrite(html, config.contractAddress, config.secret)
15 16
     await api.disconnect()
16 17
     console.log("Done. Your upload is at: ", dataHash);
17
-    console.log("Building gateway ...")
18
-    child_process.exec(`DATA_HASH=${dataHash} npm run webpack-gateway`, console.log)
18
+    console.log("Building gateway...")
19
+    child_process.exec(`DATA_HASH=${dataHash} npm run webpack-gateway`, ()=>{})
20
+    console.log(`Success. You can now open the application under ${path.join(__dirname, '..', 'gateway', 'index.html')}`)
19 21
 })()

+ 0
- 17
src/frontend/.browserslistrc 查看文件

@@ -1,17 +0,0 @@
1
-# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
2
-# For additional information regarding the format and rule options, please see:
3
-# https://github.com/browserslist/browserslist#queries
4
-
5
-# For the full list of supported browsers by the Angular framework, please see:
6
-# https://angular.io/guide/browser-support
7
-
8
-# You can see what browsers were selected by your queries by running:
9
-#   npx browserslist
10
-
11
-last 1 Chrome version
12
-last 1 Firefox version
13
-last 2 Edge major versions
14
-last 2 Safari major versions
15
-last 2 iOS major versions
16
-Firefox ESR
17
-not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.

+ 16
- 0
src/frontend/.editorconfig 查看文件

@@ -0,0 +1,16 @@
1
+# Editor configuration, see https://editorconfig.org
2
+root = true
3
+
4
+[*]
5
+charset = utf-8
6
+indent_style = space
7
+indent_size = 2
8
+insert_final_newline = true
9
+trim_trailing_whitespace = true
10
+
11
+[*.ts]
12
+quote_type = single
13
+
14
+[*.md]
15
+max_line_length = off
16
+trim_trailing_whitespace = false

+ 38
- 0
src/frontend/.gitignore 查看文件

@@ -0,0 +1,38 @@
1
+# See http://help.github.com/ignore-files/ for more about ignoring files.
2
+
3
+# Compiled output
4
+/dist
5
+/tmp
6
+/out-tsc
7
+/bazel-out
8
+
9
+# Node
10
+/node_modules
11
+npm-debug.log
12
+yarn-error.log
13
+
14
+# IDEs and editors
15
+.idea/
16
+.project
17
+.classpath
18
+.c9/
19
+*.launch
20
+.settings/
21
+*.sublime-workspace
22
+
23
+# Visual Studio Code
24
+.vscode
25
+.history
26
+
27
+# Miscellaneous
28
+/.angular/cache
29
+.sass-cache/
30
+/connect.lock
31
+/coverage
32
+/libpeerconnection.log
33
+testem.log
34
+/typings
35
+
36
+# System files
37
+.DS_Store
38
+Thumbs.db

+ 27
- 0
src/frontend/README.md 查看文件

@@ -0,0 +1,27 @@
1
+# AngularClr
2
+
3
+This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 13.3.0.
4
+
5
+## Development server
6
+
7
+Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
8
+
9
+## Code scaffolding
10
+
11
+Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
12
+
13
+## Build
14
+
15
+Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
16
+
17
+## Running unit tests
18
+
19
+Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
20
+
21
+## Running end-to-end tests
22
+
23
+Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
24
+
25
+## Further help
26
+
27
+To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.

+ 24
- 17
src/frontend/angular.json 查看文件

@@ -1,9 +1,12 @@
1 1
 {
2 2
   "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3
+  "cli": {
4
+    "analytics": false
5
+  },
3 6
   "version": 1,
4 7
   "newProjectRoot": "projects",
5 8
   "projects": {
6
-    "angular-cli": {
9
+    "angular-clr": {
7 10
       "projectType": "application",
8 11
       "schematics": {
9 12
         "@schematics/angular:component": {
@@ -20,29 +23,29 @@
20 23
         "build": {
21 24
           "builder": "@angular-devkit/build-angular:browser",
22 25
           "options": {
23
-            "outputPath": "dist/angular-cli",
26
+            "outputPath": "dist/angular-clr",
24 27
             "index": "src/index.html",
25 28
             "main": "src/main.ts",
26 29
             "polyfills": "src/polyfills.ts",
27 30
             "tsConfig": "tsconfig.app.json",
28 31
             "inlineStyleLanguage": "scss",
29
-            "assets": ["src/favicon.ico", "src/assets"],
32
+            "assets": [
33
+              "src/favicon.ico",
34
+              "src/assets"
35
+            ],
30 36
             "styles": [
31
-              "./node_modules/@cds/city/css/bundles/default.min.css",
32
-              "./node_modules/@cds/core/global.min.css",
33
-              "./node_modules/normalize.css/normalize.css",
34
-              "node_modules/@clr/icons/clr-icons.min.css",
35
-              "node_modules/@clr/ui/clr-ui.min.css",
36 37
               "src/styles.scss"
37 38
             ],
38
-            "scripts": []
39
+            "scripts": [
40
+              "node_modules/buffer/index.js"
41
+            ]
39 42
           },
40 43
           "configurations": {
41 44
             "production": {
42 45
               "budgets": [
43 46
                 {
44 47
                   "type": "initial",
45
-                  "maximumWarning": "3mb",
48
+                  "maximumWarning": "500kb",
46 49
                   "maximumError": "10mb"
47 50
                 },
48 51
                 {
@@ -74,10 +77,10 @@
74 77
           "builder": "@angular-devkit/build-angular:dev-server",
75 78
           "configurations": {
76 79
             "production": {
77
-              "browserTarget": "angular-cli:build:production"
80
+              "browserTarget": "angular-clr:build:production"
78 81
             },
79 82
             "development": {
80
-              "browserTarget": "angular-cli:build:development"
83
+              "browserTarget": "angular-clr:build:development"
81 84
             }
82 85
           },
83 86
           "defaultConfiguration": "development"
@@ -85,7 +88,7 @@
85 88
         "extract-i18n": {
86 89
           "builder": "@angular-devkit/build-angular:extract-i18n",
87 90
           "options": {
88
-            "browserTarget": "angular-cli:build"
91
+            "browserTarget": "angular-clr:build"
89 92
           }
90 93
         },
91 94
         "test": {
@@ -96,13 +99,17 @@
96 99
             "tsConfig": "tsconfig.spec.json",
97 100
             "karmaConfig": "karma.conf.js",
98 101
             "inlineStyleLanguage": "scss",
99
-            "assets": ["src/favicon.ico", "src/assets"],
100
-            "styles": ["src/styles.scss"],
102
+            "assets": [
103
+              "src/favicon.ico",
104
+              "src/assets"
105
+            ],
106
+            "styles": [
107
+              "src/styles.scss"
108
+            ],
101 109
             "scripts": []
102 110
           }
103 111
         }
104 112
       }
105 113
     }
106
-  },
107
-  "defaultProject": "angular-cli"
114
+  }
108 115
 }

+ 44
- 0
src/frontend/karma.conf.js 查看文件

@@ -0,0 +1,44 @@
1
+// Karma configuration file, see link for more information
2
+// https://karma-runner.github.io/1.0/config/configuration-file.html
3
+
4
+module.exports = function (config) {
5
+  config.set({
6
+    basePath: '',
7
+    frameworks: ['jasmine', '@angular-devkit/build-angular'],
8
+    plugins: [
9
+      require('karma-jasmine'),
10
+      require('karma-chrome-launcher'),
11
+      require('karma-jasmine-html-reporter'),
12
+      require('karma-coverage'),
13
+      require('@angular-devkit/build-angular/plugins/karma')
14
+    ],
15
+    client: {
16
+      jasmine: {
17
+        // you can add configuration options for Jasmine here
18
+        // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
19
+        // for example, you can disable the random execution with `random: false`
20
+        // or set a specific seed with `seed: 4321`
21
+      },
22
+      clearContext: false // leave Jasmine Spec Runner output visible in browser
23
+    },
24
+    jasmineHtmlReporter: {
25
+      suppressAll: true // removes the duplicated traces
26
+    },
27
+    coverageReporter: {
28
+      dir: require('path').join(__dirname, './coverage/angular-clr'),
29
+      subdir: '.',
30
+      reporters: [
31
+        { type: 'html' },
32
+        { type: 'text-summary' }
33
+      ]
34
+    },
35
+    reporters: ['progress', 'kjhtml'],
36
+    port: 9876,
37
+    colors: true,
38
+    logLevel: config.LOG_INFO,
39
+    autoWatch: true,
40
+    browsers: ['Chrome'],
41
+    singleRun: false,
42
+    restartOnFileChange: true
43
+  });
44
+};

+ 8873
- 7844
src/frontend/package-lock.json
文件差異過大導致無法顯示
查看文件


+ 42
- 34
src/frontend/package.json 查看文件

@@ -1,55 +1,63 @@
1 1
 {
2
-  "name": "angular-cli",
2
+  "name": "angular-clr",
3 3
   "version": "0.0.0",
4 4
   "scripts": {
5 5
     "ng": "ng",
6
-    "postinstall": "npm run start",
7 6
     "start": "ng serve",
8 7
     "build": "npm run build-aot && npm run bundle",
9
-    "watch": "ng build --watch --configuration development",
10
-    "test": "ng test",
11
-    "build-aot": "ng build --aot --optimization --build-optimizer",
12 8
     "bundle": "webpack --config webpack-bundle.config.js --progress",
13
-    "clean": "rm -rf dist/* build/*"
9
+    "build-aot": "ng build --aot --optimization --build-optimizer",
10
+    "watch": "ng build --watch --configuration development",
11
+    "test": "ng test"
14 12
   },
15 13
   "private": true,
16 14
   "dependencies": {
17
-    "@angular/animations": "~14.0.0",
18
-    "@angular/common": "~14.0.0",
19
-    "@angular/compiler": "~14.0.0",
20
-    "@angular/core": "~14.0.0",
21
-    "@angular/forms": "~14.0.0",
22
-    "@angular/platform-browser": "~14.0.0",
23
-    "@angular/platform-browser-dynamic": "~14.0.0",
24
-    "@angular/router": "~14.0.0",
25
-    "@cds/angular": "^6.0.0",
15
+    "@angular/animations": "^15.2.9",
16
+    "@angular/cdk": "^15.2.9",
17
+    "@angular/common": "^15.2.9",
18
+    "@angular/compiler": "^15.2.9",
19
+    "@angular/core": "^15.2.9",
20
+    "@angular/forms": "^15.2.9",
21
+    "@angular/platform-browser": "^15.2.9",
22
+    "@angular/platform-browser-dynamic": "^15.2.9",
23
+    "@angular/router": "^15.2.9",
24
+    "@cds/angular": "6.6.2",
26 25
     "@cds/city": "^1.1.0",
27
-    "@cds/core": "^6.0.0",
28
-    "@clr/angular": "~13.0.0",
29
-    "@clr/icons": "~13.0.0",
30
-    "@clr/ui": "~13.0.0",
31
-    "mini-css-extract-plugin": "^1.6.0",
32
-    "normalize.css": "^8.0.1",
33
-    "rxjs": "~6.6.0",
34
-    "style-loader": "^3.3.1",
35
-    "tslib": "^2.1.0",
26
+    "@cds/core": "6.6.2",
27
+    "@clr/angular": "^15.12.0",
28
+    "@clr/ui": "^15.12.0",
29
+    "buffer": "^6.0.3",
30
+    "modern-normalize": "^1.1.0",
31
+    "process": "^0.11.10",
32
+    "rxjs": "~7.5.0",
33
+    "tslib": "^2.3.0",
34
+    "zod": "^3.22.4",
36 35
     "zone.js": "~0.11.4"
37 36
   },
38 37
   "devDependencies": {
39
-    "@angular-devkit/build-angular": "~14.0.0",
40
-    "@angular/cli": "~14.0.0",
41
-    "@angular/compiler-cli": "~14.0.0",
42
-    "@types/jasmine": "~3.6.0",
38
+    "@angular-devkit/build-angular": "^15.2.9",
39
+    "@angular/cli": "^15.2.9",
40
+    "@angular/compiler-cli": "^15.2.9",
41
+    "@types/jasmine": "~3.10.0",
43 42
     "@types/node": "^12.11.1",
44
-    "css-loader": "^6.7.2",
45
-    "html-webpack-plugin": "^5.5.0",
43
+    "browserify-zlib": "^0.2.0",
44
+    "crypto-browserify": "^3.12.0",
45
+    "glob": "^10.3.10",
46
+    "html-webpack-plugin": "^5.5.3",
47
+    "https-browserify": "^1.0.0",
46 48
     "inline-chunk-html-plugin": "^1.1.1",
47
-    "jasmine-core": "~3.7.0",
49
+    "jasmine-core": "~4.0.0",
48 50
     "karma": "~6.3.0",
49 51
     "karma-chrome-launcher": "~3.1.0",
50
-    "karma-coverage": "~2.0.3",
52
+    "karma-coverage": "~2.1.0",
51 53
     "karma-jasmine": "~4.0.0",
52
-    "karma-jasmine-html-reporter": "^1.5.0",
53
-    "typescript": "~4.7.0"
54
+    "karma-jasmine-html-reporter": "~1.7.0",
55
+    "purgecss-webpack-plugin": "^5.0.0",
56
+    "stream-browserify": "^3.0.0",
57
+    "stream-http": "^3.2.0",
58
+    "style-loader": "^3.3.3",
59
+    "typescript": "~4.9.5",
60
+    "url": "^0.11.3",
61
+    "webpack-cli": "^5.1.4"
54 62
   }
55 63
 }

+ 1
- 1
src/frontend/src/app/app-routing.module.ts 查看文件

@@ -7,4 +7,4 @@ const routes: Routes = [];
7 7
   imports: [RouterModule.forRoot(routes)],
8 8
   exports: [RouterModule]
9 9
 })
10
-export class AppRoutingModule {}
10
+export class AppRoutingModule { }

+ 1
- 1
src/frontend/src/app/app.component.ts 查看文件

@@ -7,7 +7,7 @@ import { ShoutboxDataService } from './services/ShoutboxData.service';
7 7
   styleUrls: ['./app.component.scss'],
8 8
 })
9 9
 export class AppComponent implements OnInit{
10
-  title = 'httXrp';
10
+  title = 'httXrp Shoutbox';
11 11
   shouts: any[] = []
12 12
   sending = false
13 13
   newShout = {

+ 79
- 89
src/frontend/src/app/services/ShoutboxData.service.ts 查看文件

@@ -1,116 +1,106 @@
1 1
 import { Injectable } from "@angular/core";
2
-import { DataParser } from "../util/Dataparser";
3 2
 import { makeTestnetWallet } from "../util/TestnetUtils";
3
+import { z } from 'zod';
4 4
 
5
-declare const xrpIO: any
6
-declare const xrpl: any
5
+declare const RJSVM: any;
6
+declare const RJSVM_Builder: any;
7
+declare const Datawriter: any;
7 8
 
8 9
 const xrpNode = "wss://s.altnet.rippletest.net:51233"
10
+const listeningAddress = "rB4v4taosTUvuup8prxj2wbrBMbmvmxgXx"
9 11
 
10 12
 @Injectable()
11 13
 export class ShoutboxDataService {
12 14
 
13 15
     public history: any[] = []
14
-
15
-    private userWallet1: any
16
-    private userWallet2: any
17
-    private shoutboxAddress = "rBGqUNVzrNJ6CNpTriBts8QCTNi5VqUMnZ"
18
-    private rippleApi: any;
19
-    private xrpio: any;
20
-
21
-    private getTransactions = async () => {
22
-        const resp = await this.rippleApi.request({
23
-            command: "account_tx",
24
-            account: this.shoutboxAddress,
25
-            forward: false,
26
-        })
27
-        return resp.result.transactions.map((entry: any) => entry.tx)
28
-    }
29
-
30
-    private submit = async (shoutHash: string) => {
31
-        const data = { 
32
-            endpoint: 'submit',
33
-            data: shoutHash
34
-        }
35
-
36
-        console.log("Submitting shout root hash", data)
37
-        const submitTx = await this.xrpio.writeRaw({data: JSON.stringify(data)}, this.shoutboxAddress, this.userWallet1.secret)
38
-        
39
-        console.log("submit TX @", submitTx)
40
-        
41
-        return submitTx
42
-    }
16
+    private dataWriter = undefined as any
43 17
 
44 18
     public submitShout = async (shout: any) => {
45
-        console.log("writing shout data", shout)
46
-        const shoutHash = await this.xrpio.treeWrite(JSON.stringify(shout), this.userWallet1.address, this.userWallet2.secret)
47
-        console.log("shout data @ ", shoutHash)
48
-        return await this.submit(shoutHash)
19
+        await this.dataWriter.callEndpoint('submit', shout, 10)
49 20
     }
50 21
 
51
-    private parseMemos = async (memos: any) => {
52
-        const shouts = await Promise.all(memos
53
-            .map((memo: any) => {
54
-                if (!memo.Memo || !memo.Memo.MemoData)
55
-                    return
56
-
57
-                try {
58
-                    return DataParser.parse('TxHash', hex_to_ascii(memo.Memo.MemoData))
59
-                } catch (e) {
60
-                    return
61
-                }
62
-            })
63
-            .filter((hash: string) => hash != undefined)
64
-            .map((root_hash: string) => this.xrpio.treeRead([root_hash]))
65
-        )
66
-        return shouts.map((jsonStr: string) => JSON.parse(jsonStr))
67
-    }
68 22
 
69
-    private loadHistory = async () => {
70
-        const raw_txs = await this.getTransactions()
71
-        return await this.parseMemos(raw_txs.flatMap((htx: any) => htx.Memos))
72
-    }
23
+    initialize = async () => {
73 24
 
74
-    private subscribeTxs = async (callback: Function) => {
75
-        this.rippleApi.on('transaction', (tx: any) => callback(tx))
76
-        await this.rippleApi.connection.request({
77
-            command: 'subscribe',
78
-            accounts: [this.shoutboxAddress]
25
+        const [userWallet, drainWallet] = await Promise.all([makeTestnetWallet(), makeTestnetWallet()])
26
+        this.dataWriter = new Datawriter({
27
+            receiveAddress: drainWallet.address,
28
+            sendWallet: userWallet,
29
+            xrpNode: xrpNode,
30
+            contractAddress: listeningAddress
79 31
         })
80
-    }
81 32
 
82
-    private listen = async () => {
83
-        await this.subscribeTxs(async (raw_tx: any) => {
84
-            const shouts = await this.parseMemos(raw_tx.transaction.Memos)
85
-            this.history.unshift(...shouts)
33
+        const shoutSchema = z.object({
34
+            title: z.string(),
35
+            body: z.string(),
36
+            from: z.string(),
37
+            id: z.optional(z.string())
86 38
         })
87
-    }
88
-
89
-    initialize = async () => {
90
-        this.userWallet1 = await makeTestnetWallet()
91
-        this.userWallet2 = await makeTestnetWallet()
92
-
93
-        this.rippleApi = new xrpl.Client(xrpNode)
94
-        await this.rippleApi.connect()
95
-
96
-        this.xrpio = new xrpIO(xrpNode);
97
-        await this.xrpio.connect()
39
+        //type Shout = z.infer<typeof shoutSchema>
40
+    
41
+        type State = {
42
+            shouts: any[]
43
+        }
44
+    
45
+        // #########################
46
+        // Define endpoints
47
+        // #########################
48
+    
49
+        type RJSVM_Endpoints = {
50
+            submit: (data: any) => void
51
+        }
52
+    
53
+        // #########################
54
+        // Define init state
55
+        // #########################
56
+    
57
+        abstract class RJSVM_Base
58
+            extends RJSVM<State, RJSVM_Endpoints>
59
+            {
60
+            
61
+            owner = userWallet.address
62
+    
63
+            state: State = {
64
+                shouts: []
65
+            }
66
+        }
67
+    
68
+        // #########################
69
+        // Implement logic
70
+        // #########################
71
+    
72
+        const RJSVM_Contract = {
73
+            submit: {
74
+                implementation: function (env:any, shout:any) {
75
+                    (this as any).state.shouts.unshift(shout)
76
+                },
77
+                visibility: 'public',
78
+                fee: 10,
79
+                parameterSchema: shoutSchema
80
+            }
81
+        }
82
+    
83
+        // #########################
84
+        // Build and connect
85
+        // #########################
86
+    
87
+        const Rjsvm = RJSVM_Builder.from(RJSVM_Base, RJSVM_Contract);
88
+    
89
+        const conf = {
90
+            listeningAddress: listeningAddress,
91
+            rippleNode: xrpNode
92
+        }
93
+    
94
+        const rjsvm = new Rjsvm(conf)
95
+        await rjsvm.connect()
98 96
 
99
-        this.history = await this.loadHistory()
97
+        rjsvm.on('error', console.log)
98
+        rjsvm.on('submit', console.log)
100 99
 
101
-        await this.listen();
100
+        this.history = rjsvm.state.shouts
102 101
     }
103 102
 }
104 103
 
105 104
 export function initShoutboxSvc(svc: ShoutboxDataService): () => Promise<any> {
106 105
     return svc.initialize;
107
-}
108
-
109
-function hex_to_ascii(input: any) {
110
-    var hex = input.toString();
111
-    var str = '';
112
-    for (var n = 0; n < hex.length; n += 2) {
113
-        str += String.fromCharCode(parseInt(hex.substr(n, 2), 16));
114
-    }
115
-    return str;
116 106
 }

+ 0
- 116
src/frontend/src/app/services/test.ts 查看文件

@@ -1,116 +0,0 @@
1
-import { Injectable } from "@angular/core";
2
-import { DataParser } from "../util/Dataparser";
3
-import { makeTestnetWallet } from "../util/TestnetUtils";
4
-
5
-declare const xrpIO: any
6
-declare const xrpl: any
7
-
8
-const xrpNode = "wss://s.altnet.rippletest.net:51233"
9
-
10
-@Injectable()
11
-export class ShoutboxDataService {
12
-
13
-    public history: any[] = []
14
-
15
-    private userWallet1: any
16
-    private userWallet2: any
17
-    private shoutboxAddress = "rBGqUNVzrNJ6CNpTriBts8QCTNi5VqUMnZ"
18
-    private rippleApi: any;
19
-    private xrpio: any;
20
-
21
-    private getTransactions = async () => {
22
-        const resp = await this.rippleApi.request({
23
-            command: "account_tx",
24
-            account: this.shoutboxAddress,
25
-            forward: false,
26
-        })
27
-        return resp.result.transactions.map((entry: any) => entry.tx)
28
-    }
29
-
30
-    private submit = async (shoutHash: string) => {
31
-        const data = { 
32
-            endpoint: 'submit',
33
-            data: shoutHash
34
-        }
35
-
36
-        console.log("Submitting shout root hash", data)
37
-        const submitTx = await this.xrpio.writeRaw({data: JSON.stringify(data)}, this.shoutboxAddress, this.userWallet1.secret)
38
-        
39
-        console.log("submit TX @", submitTx)
40
-        
41
-        return submitTx
42
-    }
43
-
44
-    public submitShout = async (shout: any) => {
45
-        console.log("writing shout data", shout)
46
-        const shoutHash = await this.xrpio.treeWrite(JSON.stringify(shout), this.userWallet1.address, this.userWallet2.secret)
47
-        console.log("shout data @ ", shoutHash)
48
-        return await this.submit(shoutHash)
49
-    }
50
-
51
-    private parseMemos = async (memos: any) => {
52
-        const shouts = await Promise.all(memos
53
-            .map((memo: any) => {
54
-                if (!memo.Memo || !memo.Memo.MemoData)
55
-                    return
56
-
57
-                try {
58
-                    return DataParser.parse('TxHash', hex_to_ascii(memo.Memo.MemoData))
59
-                } catch (e) {
60
-                    return
61
-                }
62
-            })
63
-            .filter((hash: string) => hash != undefined)
64
-            .map((root_hash: string) => this.xrpio.treeRead([root_hash]))
65
-        )
66
-        return shouts.map((jsonStr: string) => JSON.parse(jsonStr))
67
-    }
68
-
69
-    private loadHistory = async () => {
70
-        const raw_txs = await this.getTransactions()
71
-        return await this.parseMemos(raw_txs.flatMap((htx: any) => htx.Memos))
72
-    }
73
-
74
-    private subscribeTxs = async (callback: Function) => {
75
-        this.rippleApi.on('transaction', (tx: any) => callback(tx))
76
-        await this.rippleApi.connection.request({
77
-            command: 'subscribe',
78
-            accounts: [this.shoutboxAddress]
79
-        })
80
-    }
81
-
82
-    private listen = async () => {
83
-        await this.subscribeTxs(async (raw_tx: any) => {
84
-            const shouts = await this.parseMemos(raw_tx.transaction.Memos)
85
-            this.history.unshift(...shouts)
86
-        })
87
-    }
88
-
89
-    initialize = async () => {
90
-        this.userWallet1 = await makeTestnetWallet()
91
-        this.userWallet2 = await makeTestnetWallet()
92
-
93
-        this.rippleApi = new xrpl.Client(xrpNode)
94
-        await this.rippleApi.connect()
95
-
96
-        this.xrpio = new xrpIO(xrpNode);
97
-        await this.xrpio.connect()
98
-
99
-        this.history = await this.loadHistory()
100
-
101
-        await this.listen();
102
-    }
103
-}
104
-
105
-export function initShoutboxSvc(svc: ShoutboxDataService): () => Promise<any> {
106
-    return svc.initialize;
107
-}
108
-
109
-function hex_to_ascii(input: any) {
110
-    var hex = input.toString();
111
-    var str = '';
112
-    for (var n = 0; n < hex.length; n += 2) {
113
-        str += String.fromCharCode(parseInt(hex.substr(n, 2), 16));
114
-    }
115
-    return str;
116
-}

+ 1
- 1
src/frontend/src/app/util/Dataparser.ts 查看文件

@@ -66,7 +66,7 @@ export class DataParser {
66 66
 
67 67
     private static parseTxHash(input: any): TxHash{
68 68
         if(typeof input !== 'string' || !NON_ZERO_TX_HASH.test(input)){
69
-            throw new Error('Input is not a trasnaction hash')
69
+            throw new Error(`Input '${input}'is not a trasnaction hash`)
70 70
         }
71 71
         return input
72 72
     }

+ 0
- 0
src/frontend/src/assets/.gitkeep 查看文件


二進制
src/frontend/src/favicon.ico 查看文件


+ 16
- 19
src/frontend/src/index.html 查看文件

@@ -1,22 +1,19 @@
1
-<!DOCTYPE html>
1
+<!doctype html>
2 2
 <html lang="en">
3
-  <head>
4
-    <meta http-equiv='cache-control' content='no-cache'> 
5
-    <meta http-equiv='expires' content='0'> 
6
-    <meta http-equiv='pragma' content='no-cache'>
7
-  
8
-    <meta charset="utf-8" />
9
-    <title>httXrp</title>
10
-    <base href="" />
11
-    <meta name="viewport" content="width=device-width, initial-scale=1" />
12
-    <link rel="icon" type="image/x-icon" href="favicon.ico" />
13
-    <script src="https://cdn.jsdelivr.net/npm/xrpl@2.7.0"></script>
14
-    <script src="https://cdn.jsdelivr.net/npm/xrpio@0.1.8/lib/browser/xrpio.browser.js"></script>
15
-  </head>
3
+<head>
4
+  <script>
5
+    window.process = { env: { NODE_ENV: 'production' } }
6
+  </script>
16 7
 
17
-  <body cds-text="body">
18
-    <app-root>
19
-      <div style="text-align: center;">Loading application state</div>
20
-    </app-root>
21
-  </body>
8
+  <meta charset="utf-8">
9
+  <title>AngularClr</title>
10
+  <base href="/">
11
+  <meta name="viewport" content="width=device-width, initial-scale=1">
12
+  <link rel="icon" type="image/x-icon" href="favicon.ico">
13
+
14
+  <script src="https://cdn.jsdelivr.net/npm/rjsvm@0.2.5/lib/browser/rjsvm.browser.js"></script>
15
+</head>
16
+<body cds-text="body" cds-theme="dark">
17
+  <app-root></app-root>
18
+</body>
22 19
 </html>

+ 1
- 2
src/frontend/src/main.ts 查看文件

@@ -8,6 +8,5 @@ if (environment.production) {
8 8
   enableProdMode();
9 9
 }
10 10
 
11
-platformBrowserDynamic()
12
-  .bootstrapModule(AppModule)
11
+platformBrowserDynamic().bootstrapModule(AppModule)
13 12
   .catch(err => console.error(err));

+ 9
- 15
src/frontend/src/polyfills.ts 查看文件

@@ -8,8 +8,8 @@
8 8
  *      file.
9 9
  *
10 10
  * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11
- * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12
- * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
11
+ * automatically update themselves. This includes recent versions of Safari, Chrome (including
12
+ * Opera), Edge on the desktop, and iOS and Chrome on mobile.
13 13
  *
14 14
  * Learn more in https://angular.io/guide/browser-support
15 15
  */
@@ -18,18 +18,6 @@
18 18
  * BROWSER POLYFILLS
19 19
  */
20 20
 
21
-/**
22
- * IE11 requires the following for NgClass support on SVG elements
23
- */
24
-// import 'classlist.js';  // Run `npm install --save classlist.js`.
25
-
26
-/**
27
- * Web Animations `@angular/platform-browser/animations`
28
- * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
29
- * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
30
- */
31
-// import 'web-animations-js';  // Run `npm install --save web-animations-js`.
32
-
33 21
 /**
34 22
  * By default, zone.js will patch all possible macroTask and DomEvents
35 23
  * user can disable parts of macroTask/DomEvents patch by setting following flags
@@ -57,7 +45,13 @@
57 45
 /***************************************************************************************************
58 46
  * Zone JS is required by default for Angular itself.
59 47
  */
60
-import 'zone.js'; // Included with Angular CLI.
48
+import 'zone.js';  // Included with Angular CLI.
49
+import * as process from 'process';
50
+(window as any)['process'] = process;
51
+(window as any)['buffer'] = (window as any).Buffer || require('buffer').Buffer;
52
+(window as any)['Buffer'] = (window as any).Buffer || require('buffer').Buffer;
53
+(window as any)['global'] = (window as any);
54
+
61 55
 
62 56
 /***************************************************************************************************
63 57
  * APPLICATION IMPORTS

+ 11
- 4
src/frontend/src/styles.scss 查看文件

@@ -1,4 +1,11 @@
1
-@import '~modern-normalize/modern-normalize.css';
2
-@import '~@cds/core/global.min.css';
3
-@import '~@cds/city/css/bundles/default.min.css';
4
-@import '~@cds/core/styles/theme.dark.min.css';
1
+@import 'modern-normalize/modern-normalize.css';
2
+@import '@cds/core/global.min.css';
3
+@import '@cds/core/styles/theme.dark.min.css';
4
+@import '@cds/city/css/bundles/default.css';
5
+
6
+@import '@clr/ui/shim.cds-core.min.css';
7
+@import '@clr/ui/clr-ui.min.css';
8
+
9
+[cds-card-remove-margin] {
10
+  --color: var(--cds-alias-object-container-border-color);
11
+}

+ 14
- 0
src/frontend/src/test.ts 查看文件

@@ -0,0 +1,14 @@
1
+// This file is required by karma.conf.js and loads recursively all the .spec and framework files
2
+
3
+import 'zone.js/testing';
4
+import { getTestBed } from '@angular/core/testing';
5
+import {
6
+  BrowserDynamicTestingModule,
7
+  platformBrowserDynamicTesting
8
+} from '@angular/platform-browser-dynamic/testing';
9
+
10
+// First, initialize the Angular testing environment.
11
+getTestBed().initTestEnvironment(
12
+  BrowserDynamicTestingModule,
13
+  platformBrowserDynamicTesting(),
14
+);

+ 18
- 2
src/frontend/tsconfig.json 查看文件

@@ -6,6 +6,8 @@
6 6
     "outDir": "./dist/out-tsc",
7 7
     "forceConsistentCasingInFileNames": true,
8 8
     "strict": true,
9
+    "noImplicitOverride": true,
10
+    "noPropertyAccessFromIndexSignature": true,
9 11
     "noImplicitReturns": true,
10 12
     "noFallthroughCasesInSwitch": true,
11 13
     "sourceMap": true,
@@ -14,9 +16,23 @@
14 16
     "experimentalDecorators": true,
15 17
     "moduleResolution": "node",
16 18
     "importHelpers": true,
17
-    "target": "ES2020",
19
+    "target": "ES2022",
18 20
     "module": "es2020",
19
-    "lib": ["es2018", "dom"]
21
+    "lib": [
22
+      "es2020",
23
+      "dom"
24
+    ],
25
+    "useDefineForClassFields": false,
26
+    "paths": {
27
+      "stream": ["./node_modules/stream-browserify"],
28
+      "http": ["./node_modules/stream-http"],    
29
+      "crypto": ["./node_modules/crypto-browserify"],
30
+      "zlib": ["./node_modules/browserify-zlib"],
31
+      "https": ["./node_modules/https-browserify"],
32
+      "url": ["./node_modules/url/"],
33
+      "buffer": ["./node_modules/buffer/"],
34
+      "Buffer": ["./node_modules/buffer/"],
35
+    }
20 36
   },
21 37
   "angularCompilerOptions": {
22 38
     "enableI18nLegacyMessageIdFormat": false,

+ 18
- 0
src/frontend/tsconfig.spec.json 查看文件

@@ -0,0 +1,18 @@
1
+/* To learn more about this file see: https://angular.io/config/tsconfig. */
2
+{
3
+  "extends": "./tsconfig.json",
4
+  "compilerOptions": {
5
+    "outDir": "./out-tsc/spec",
6
+    "types": [
7
+      "jasmine"
8
+    ]
9
+  },
10
+  "files": [
11
+    "src/test.ts",
12
+    "src/polyfills.ts"
13
+  ],
14
+  "include": [
15
+    "src/**/*.spec.ts",
16
+    "src/**/*.d.ts"
17
+  ]
18
+}

+ 12
- 4
src/frontend/webpack-bundle.config.js 查看文件

@@ -4,10 +4,11 @@ const webpack = require('webpack')
4 4
 const path = require('path')
5 5
 const fs = require('fs')
6 6
 
7
-const distDir = path.resolve(__dirname, 'dist', 'angular-cli')
7
+const distDir = path.resolve(__dirname, 'dist', 'angular-clr')
8 8
 const buildDir = path.resolve(__dirname, 'build')
9 9
 const srcDir = path.resolve(__dirname, 'src')
10 10
 
11
+
11 12
 module.exports = {
12 13
     mode: 'production',
13 14
     target: 'web',
@@ -21,13 +22,21 @@ module.exports = {
21 22
     },
22 23
     resolve: {
23 24
         extensions: ['', '.js', '.jsx', '.css'],
25
+        fallback: {
26
+        }
24 27
     },
25 28
     plugins: [
29
+        new webpack.ProvidePlugin({
30
+            Buffer: ['buffer', 'Buffer'],
31
+        }),
32
+        new webpack.ProvidePlugin({
33
+            process: 'process/browser',
34
+        }),
26 35
         new HtmlWebpackPlugin({
27 36
             inject: "body",
28 37
             template: path.resolve(srcDir, 'index.html'),
29 38
         }),
30
-        new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/.*/]),
39
+        new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/.*/])
31 40
     ],
32 41
     optimization: {
33 42
     },
@@ -39,6 +48,5 @@ module.exports = {
39 48
             },
40 49
         ],
41 50
     },
42
-    externals: {
43
-    },
51
+    externals: {},
44 52
 }

+ 0
- 1
webpack.gateway.js 查看文件

@@ -1,6 +1,5 @@
1 1
 const path = require('path');
2 2
 const webpack = require('webpack');
3
-const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
4 3
 
5 4
 if(!process.env['DATA_HASH']){
6 5
   console.log("Environment DATA_HASH not set")

Loading…
取消
儲存