├── .gitignore ├── README.md ├── dist ├── mathwallet.cjs.js └── mathwallet.min.js ├── package-lock.json ├── package.json ├── rollup.config.js ├── src ├── app │ ├── MathApp.js │ ├── PostMessage.js │ └── WalletTypes.js ├── blockchain │ ├── Blockchain.js │ ├── BlockchainRepository.js │ ├── BlockchainTypes.js │ ├── btc │ │ └── btc.js │ ├── eos │ │ ├── Account.js │ │ ├── NodeData.js │ │ ├── NodeDataUrls.js │ │ └── eos.js │ └── neo │ │ └── neo.js ├── mathwallet.js └── util │ ├── Browser.js │ ├── MathError.js │ └── Network.js └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | 4 | node_modules -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # math-js-sdk 2 | Javascript SDK for MathWallet 3 | 4 | ## Demo 5 | [https://medishares-cn.oss-cn-hangzhou.aliyuncs.com/demos/mathwallet-js-sdk/index.html](https://medishares-cn.oss-cn-hangzhou.aliyuncs.com/demos/mathwallet-js-sdk/index.html) 6 | 7 | 此链接用来演示如何使用math-js-sdk,您可以在麦子钱包DAPP浏览器中打开 8 | This link is the demo of how to use the math-js-sdk. You can open it in the MathWallet DAPP Browser. 9 | 10 | ## Installation 11 | #### npm 12 | Install 13 | ```shell 14 | npm install math-js-sdk 15 | ``` 16 | Require module 17 | ```javascript 18 | var mathwallet = require('math-js-sdk'); 19 | ``` 20 | 21 | #### html 22 | Drop the `dist/mathwallet.min.js` bundle into your html project 23 | ```html 24 | 25 | ``` 26 | Get instance 27 | ```javascript 28 | var mathwallet = window.mathwallet; 29 | ``` 30 | 31 | ## Usage 32 | 33 | ### Note 34 | 注意: 此SDK需要在麦子钱包的DAPP浏览器中使用 35 | Note: The SDK needs to be used in the MathWallet DAPP Browser. 36 | 37 | ### Common 38 | 适用于麦子钱包DAPP浏览器的通用方法 39 | Common method for MathWallet DAPP Browser 40 | 41 | #### isMath 42 | ```javascript 43 | mathwallet.isMath(); 44 | ``` 45 | Return 46 | ```javascript 47 | true 48 | ``` 49 | 50 | #### getAppInfo 51 | 获取用户麦子钱包信息 52 | Get user MathWallet info 53 | ```javascript 54 | mathwallet.getAppInfo().then(console.log); 55 | ``` 56 | Return 57 | ```javascript 58 | { 59 | "name": "Math Wallet", 60 | "client": "iOS", 61 | "version": "1.9.3", 62 | "build": "25", 63 | "deviceId": "2FB1AD00-20C7-45FF-AE94-A2F30A02F8F6" 64 | } 65 | ``` 66 | 67 | #### share 68 | 分享图片或链接到社交平台,如微信 69 | Share to third app like Wechat. 70 | ```javascript 71 | // Image 72 | mathwallet.shareTo(1,{ 73 | "imageURL": "https://medishares-cn.oss-cn-hangzhou.aliyuncs.com/dapp/263R1568603688.jpg", 74 | // "text": "Share Text", 75 | // Extra Data 76 | // "activity": { 77 | // "type": "event", 78 | // "app": "app", 79 | // "event": "share", 80 | // "name": params.name, 81 | // "data": params.data 82 | // } 83 | } 84 | ).then(console.log); 85 | // Link 86 | mathwallet.shareTo(2,{ 87 | "title": "Math", 88 | "desc": "Math Wallet", 89 | "link": "https://www.mathwallet.org", 90 | "thumImage": "https://medishares-cn.oss-cn-hangzhou.aliyuncs.com/dapp/263R1568603688.jpg", 91 | // Extra Data 92 | // "activity": { 93 | // "type": "event", 94 | // "app": "app", 95 | // "event": "share", 96 | // "name": params.name, 97 | // "data": params.data 98 | // } 99 | } 100 | ).then(console.log); 101 | // Save to album 102 | mathwallet.shareTo(3,{ 103 | "imageURL": "https://medishares-cn.oss-cn-hangzhou.aliyuncs.com/dapp/263R1568603688.jpg" 104 | } 105 | ).then(console.log); 106 | ``` 107 | Return 108 | ```javascript 109 | { 110 | "result": 1 111 | } 112 | ``` 113 | 114 | #### openUrl 115 | 打开一个新的浏览器窗口 116 | Open a new webview tab 117 | ```javascript 118 | mathwallet.openUrl("http://www.mathwallet.org").then(console.log); 119 | ``` 120 | Return 121 | ```javascript 122 | { 123 | "result": 1 124 | } 125 | ``` 126 | 127 | #### openThirdApp 128 | 打开第三方应用,如微信、KakaoTalk等 129 | Open third app like Wechat, KakaoTalk. 130 | ```javascript 131 | mathwallet.openThirdApp("tel:110").then(console.log); 132 | ``` 133 | Return 134 | ```javascript 135 | { 136 | "result": 1 137 | } 138 | ``` 139 | 140 | #### close 141 | 关闭当前窗口 142 | Close window 143 | ```javascript 144 | mathwallet.close().then(console.log); 145 | ``` 146 | Return 147 | ```javascript 148 | { 149 | "result": 1 150 | } 151 | ``` 152 | 153 | #### back 154 | 后退到上一页 155 | Back to previous page 156 | ```javascript 157 | mathwallet.back().then(console.log); 158 | ``` 159 | Return 160 | ```javascript 161 | { 162 | "result": 1 163 | } 164 | ``` 165 | 166 | #### fullScreen 167 | 设置是否全屏 168 | Set full screen 169 | `0 - normal screen` 170 | `1 - full screen` 171 | ```javascript 172 | mathwallet.fullScreen(1).then(console.log); 173 | ``` 174 | Return 175 | ```javascript 176 | { 177 | "result": 1 178 | } 179 | ``` 180 | 181 | #### orientation 182 | 设置屏幕方向 183 | Set screen orientation 184 | `0 - portrait` 185 | `1 - landscape` 186 | ```javascript 187 | mathwallet.orientation(1).then(console.log); 188 | ``` 189 | Return 190 | ```javascript 191 | { 192 | "result": 1 193 | } 194 | ``` 195 | 196 | #### getLanguage 197 | 获取用户APP语言 198 | Get user app language 199 | ```javascript 200 | mathwallet.getLanguage().then(console.log); 201 | ``` 202 | Return 203 | ```javascript 204 | "cn" 205 | ``` 206 | 207 | #### getCurrentWalletType 208 | 获取用户当前钱包类型 209 | Get user current wallet type 210 | ```javascript 211 | mathwallet.geCurrentWalletType().then(console.log); 212 | ``` 213 | Return 214 | ```javascript 215 | "BTC" 216 | ``` 217 | 218 | #### getCurrentWallet 219 | 获取用户当前钱包信息 220 | Get user current wallet info 221 | ```javascript 222 | mathwallet.getCurrentWallet().then(console.log); 223 | ``` 224 | Return 225 | ```javascript 226 | { 227 | "blockchain":"EOS", 228 | "nickname":"medisharesbp", 229 | "address":"medisharesbp", 230 | "authority":"active" 231 | } 232 | ``` 233 | #### walletPicker 234 | 钱包地址选取器(多地址弹框,由用户授权使用哪个账户) 235 | Wallet Picker 236 | ```javascript 237 | // "BTC"、"ETH"、"EOS"、"TRX"、"POLKADOT"、"ONT" 238 | mathwallet.walletPicker("ETH").then(console.log); 239 | ``` 240 | Return 241 | ```javascript 242 | { 243 | "nickname":"medisharesbp", 244 | "address":"medisharesbp" 245 | } 246 | ``` 247 | 248 | #### getWalletList 249 | 获取用户某类型的钱包列表 250 | Get user wallets of the type 251 | ```javascript 252 | // "BTC"、"ETH"、"EOS"、"TRX"、"POLKADOT"、"ONT" 253 | mathwallet.getWalletList("EOS").then(console.log); 254 | ``` 255 | Return 256 | ```javascript 257 | [ 258 | { 259 | "nickname":"medisharesbp", 260 | "address":"medisharesbp" 261 | }, 262 | { 263 | "nickname":"medisharesbb", 264 | "address":"medisharesbb" 265 | } 266 | ] 267 | ``` 268 | 269 | #### postCustomMessage 270 | 发送其它自定义消息 271 | For other custom action 272 | ```javascript 273 | mathwallet.postCustomMessage(method, payload); 274 | ``` 275 | 276 | 277 | 278 | 279 | ### BTC Wallet 280 | 麦子钱包DAPP浏览器中有关BTC钱包的方法 281 | BTC wallet method for MathWallet DAPP Browser 282 | 283 | #### BTC.transfer 284 | 发起BTC转账交易 285 | Send BTC transaction 286 | ```javascript 287 | mathwallet.BTC.transfer(from, amount, to, memo).then(console.log); 288 | ``` 289 | OR 290 | ```javascript 291 | let transaction = { 292 | from : from, 293 | amount : amount, 294 | to : to, 295 | memo : memo 296 | } 297 | mathwallet.BTC.transfer(transaction).then(console.log); 298 | ``` 299 | Return 300 | ```javascript 301 | { 302 | "result":"trxid" // transaction hash 303 | } 304 | ``` 305 | 306 | 307 | 308 | ### NEO Wallet 309 | 麦子钱包DAPP浏览器中有关NEO钱包的方法 310 | NEO wallet method for MathWallet DAPP Browser 311 | 312 | #### NEO.transfer 313 | 发起NEO转账交易 314 | Send NEO transaction 315 | ```javascript 316 | mathwallet.NEO.transfer(from, amount, to, memo).then(console.log); 317 | ``` 318 | OR 319 | ```javascript 320 | let transaction = { 321 | from : from, 322 | to : to, 323 | amount : amount, 324 | contract : contract, 325 | precision : precision, 326 | symbol : symbol, 327 | memo : memo 328 | } 329 | mathwallet.NEO.transfer(transaction).then(console.log); 330 | ``` 331 | Return 332 | ```javascript 333 | { 334 | "result":"trxid" // transaction hash 335 | } 336 | ``` 337 | 338 | 339 | 340 | ### EOS Wallet 341 | 麦子钱包DAPP浏览器中有关EOS钱包的方法 342 | EOS wallet method for MathWallet DAPP Browser 343 | `注意: 麦子钱包已兼容Scatter,有关EOS的DAPP开发可直接使用Scatter` 344 | `Note: MathWallet is already compatible with Scatter. You can use Scatter to build your EOS DAPP` 345 | 346 | #### EOS.init 347 | 在使用EOS相关方法前需要初始化EOS节点信息 348 | Please initialize BP information before using the other method 349 | ```javascript 350 | let config = { 351 | "nodes":[ 352 | 353 | // 0: testnet-node 354 | { 355 | "jsonRpc":"https:\/\/eostestnet.medishares.net", 356 | "chainID":"cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f" 357 | }, 358 | 359 | // 1: testnet-node 360 | { 361 | "jsonRpc":"https:\/\/eosmainnet.medishares.net", 362 | "chainID":"aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906" 363 | } 364 | 365 | ] 366 | }; 367 | mathwallet.EOS.init(config); //return true 368 | ``` 369 | 370 | #### EOS.getAccount 371 | 获取当前钱包账户信息,在使用与账户相关方法前需要先使用getAccount()方法 372 | Get current account info, must use getAccount() before using the other method. 373 | ```javascript 374 | mathwallet.EOS.getAccount().then(console.log); 375 | ``` 376 | 377 | 378 | #### EOS.get_info 379 | 获取区块信息 380 | Get block info 381 | ```javascript 382 | mathwallet.EOS.get_info().then(console.log); 383 | ``` 384 | 385 | #### EOS.abi_json_to_bin 386 | JSON信息转为二进制数据 387 | JSON to Bin 388 | ```javascript 389 | mathwallet.EOS.abi_json_to_bin(data).then(console.log); 390 | ``` 391 | 392 | #### EOS.signTransaction 393 | 签名交易 394 | Sign transaction 395 | ```javascript 396 | mathwallet.EOS.signTransaction(transaction).then(console.log); 397 | ``` 398 | 399 | #### EOS.push_transaction & EOS.push_transaction_all 400 | 发起交易 401 | Push transaction 402 | ```javascript 403 | mathwallet.EOS.push_transaction(transaction,signatures,compression).then(console.log); 404 | ``` 405 | OR 406 | ```javascript 407 | mathwallet.EOS.push_transaction_all(data).then(console.log); 408 | ``` 409 | 410 | #### EOS.customSignProvider 411 | 自定义签名提供者,用于类eos.js插件 412 | Custom Sign Provider, for plugin like eos.js 413 | ```javascript 414 | // Eos.js 415 | Eos({ 416 | httpEndpoint: "https://path/to/node", 417 | chainId: "aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906", 418 | signProvider: mathwallet.EOS.customSignProvider, 419 | }); 420 | ``` 421 | 422 | #### EOS.getEos 423 | 获取已经初始化节点信息及签名提供者后的Eos.js实例,使用前需要先引入Eos.js插件 424 | Get Eos.js instance which node httpEndpoint and signProvider have been initialized. Please include the eos.js plugin first. 425 | ```html 426 | 427 | 433 | ``` 434 | 435 | 436 | 437 | ### Download Math Wallet 麦子钱包下载 438 | 439 | [http://mathwallet.org](http://mathwallet.org) 440 | 441 | 如果您希望将您开发的DAPP加入麦子钱包,请通过邮箱联系我们 hello@medishares.org 442 | 443 | If you would like to list your DAPP in Math Wallet, please send your DAPP information to hello@medishares.org 444 | -------------------------------------------------------------------------------- /dist/mathwallet.cjs.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const u = typeof navigator != 'undefined' ? navigator.userAgent : ''; 4 | const app = typeof navigator != 'undefined' ? navigator.appVersion : ''; 5 | const browser = { 6 | trident: u.indexOf('Trident') > -1, 7 | presto: u.indexOf('Presto') > -1, 8 | webKit: u.indexOf('AppleWebKit') > -1, 9 | gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, 10 | mobile: !!u.match(/AppleWebKit.*Mobile.*/), 11 | ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), 12 | android: u.indexOf('Android') > -1 || u.indexOf('Adr') > -1, 13 | iPhone: u.indexOf('iPhone') > -1 , 14 | iPad: u.indexOf('iPad') > -1, 15 | mdsApp: u.indexOf('MdsApp') > -1, 16 | mdsVer: u.indexOf('MdsApp') > -1?u.match(/MdsApp\/[^\s]+\s?/)[0].trim().split('/')[1]:'0' //MdsApp版本 17 | }; 18 | 19 | class PostMessage { 20 | constructor(browser$$1) { 21 | if(browser$$1.mdsApp && browser$$1.android) { 22 | this.postMessageHandler = window.mds; 23 | }else if(browser$$1.mdsApp && browser$$1.iPhone && typeof window.webkit != 'undefined'){ 24 | this.postMessageHandler = window.webkit.messageHandlers.mds; 25 | }else{ 26 | // this.postMessageHandler = window; 27 | this.postMessageHandler = { 28 | postMessage : console.log //debug 29 | }; 30 | } 31 | } 32 | 33 | 34 | sign_global_callback(callback){ 35 | if(typeof callback == 'function'){ 36 | let globalCallbackFuncName = 'mdseosappcallback' + new Date().getTime() + Math.floor(Math.random()*100000000+10000000); 37 | window[globalCallbackFuncName] = function(res){ 38 | callback(res); 39 | window[globalCallbackFuncName] = null; 40 | }; 41 | console.log(globalCallbackFuncName); 42 | return globalCallbackFuncName; 43 | }else{ 44 | return callback; 45 | } 46 | } 47 | 48 | 49 | 50 | send(method, payload = {}, returnData = false) { 51 | return new Promise((resolve, reject) => { 52 | const callback = (res) => { 53 | if(returnData){ 54 | return resolve(res); 55 | } 56 | 57 | let result = JSON.parse(res); 58 | if(result.error){ 59 | reject(result.error); 60 | }else{ 61 | resolve(result); 62 | } 63 | return true; 64 | }; 65 | 66 | let message = { 67 | method : method, 68 | params : payload, 69 | callback : this.sign_global_callback(callback) 70 | }; 71 | 72 | try{ 73 | this.postMessageHandler.postMessage(JSON.stringify(message)); 74 | }catch(err){ 75 | reject(err); 76 | } 77 | }); 78 | } 79 | } 80 | 81 | let postMessage = new PostMessage(browser); 82 | 83 | let list = new Map(); 84 | 85 | list.set(1, 'ETH'); 86 | list.set(2, 'NEO'); 87 | list.set(3, 'EOS'); 88 | list.set(4, 'EOSFORCE'); 89 | list.set(5, 'ONT'); 90 | list.set(6, 'BTC'); 91 | list.set(7, 'ESN'); 92 | list.set(8, 'TRX'); 93 | list.set(9, 'NAS'); 94 | list.set(10, 'BOS'); 95 | list.set(11, 'ENU'); 96 | list.set(12, 'TELOS'); 97 | list.set(13, 'ZILLIQA'); 98 | list.set(14, 'BINANCE'); 99 | list.set(15, 'IRIS'); 100 | list.set(16, 'COSMOS'); 101 | list.set(17, 'CHAINX'); 102 | list.set(18, 'CODEX'); 103 | list.set(19, 'POLKADOT'); 104 | list.set(20, 'VECHAIN'); 105 | list.set(21, 'FT'); 106 | list.set(22, 'COINEX'); 107 | list.set(19001, 'KUSAMA'); 108 | 109 | const WalletTypes = { 110 | getType(id) { 111 | return list.has(id) ? list.get(id) : 'UNKNOWN'; 112 | }, 113 | 114 | getID(type) { 115 | type = type.toUpperCase(); 116 | for (const [key, value] of list) { 117 | if (value == type) return key; 118 | } 119 | return 0; 120 | } 121 | }; 122 | 123 | class MathApp { 124 | isMath() { 125 | return browser.mdsApp; 126 | } 127 | 128 | openUrl(url) { 129 | return postMessage.send('openURL', { url: url }); 130 | } 131 | 132 | openThirdApp(url) { 133 | return postMessage.send('openThirdApplication', { appSchemeURL: url }); 134 | } 135 | 136 | close() { 137 | return postMessage.send('close'); 138 | } 139 | 140 | back() { 141 | return postMessage.send('goBack'); 142 | } 143 | 144 | // 0-normal 1-fullScreen 145 | fullScreen(mode = 1) { 146 | return postMessage.send('fullScreen', { mode: mode }); 147 | } 148 | 149 | // 0-portrait 1-landscape 150 | orientation(mode = 0) { 151 | let orientation = 'portrait'; 152 | switch (mode) { 153 | case 1: 154 | orientation = 'landscape'; 155 | break; 156 | default: 157 | orientation = 'portrait'; 158 | } 159 | return postMessage.send('deviceOrientation', { orientation: orientation }); 160 | } 161 | 162 | share(params) { 163 | return postMessage.send('shareAction', { 164 | "type": 1, 165 | "imageURL": params.img, 166 | "activity": { 167 | "type": "event", 168 | "app": "app", 169 | "event": "share", 170 | "name": params.name, 171 | "data": params.data 172 | } 173 | }); 174 | } 175 | // 1-image 2-link 3-album 176 | shareTo(type = 1, params = {}) { 177 | return postMessage.send('shareAction', { 178 | "type": type, 179 | ...params 180 | }); 181 | } 182 | 183 | getAppInfo() { 184 | return postMessage.send('getAppInfo'); 185 | } 186 | 187 | getLanguage() { 188 | return new Promise((resolve, reject) => { 189 | postMessage.send('getLanguage', {}, true).then((language) => { 190 | resolve(language); 191 | }, reject); 192 | }); 193 | } 194 | 195 | getWalletType() { 196 | return new Promise((resolve, reject) => { 197 | postMessage.send('activeWalletType').then((res) => { 198 | resolve(res.blockchain || WalletTypes.getType(res.type)); 199 | }, reject); 200 | }); 201 | } 202 | getCurrentWalletType() { 203 | return this.getWalletType(); 204 | } 205 | getCurrentWallet() { 206 | return postMessage.send('activeWalletAccount'); 207 | } 208 | walletPicker(type) { 209 | return postMessage.send('walletPicker', { blockchain: type }); 210 | } 211 | getWallets() { 212 | return postMessage.send('selectWallets'); 213 | } 214 | getWalletList(type) { 215 | let typeID = WalletTypes.getID(type); 216 | return postMessage.send('getWalletsWithType', { type: typeID, blockchain: type }); 217 | } 218 | 219 | postCustomMessage(method, payload) { 220 | return postMessage.send(method, payload); 221 | } 222 | } 223 | 224 | class Blockchain { 225 | constructor(chain = ''){ 226 | this.chain = chain; 227 | } 228 | } 229 | 230 | const BTC = 'BTC'; 231 | const NEO = 'NEO'; 232 | const EOS = 'EOS'; 233 | 234 | class BTC$1 extends Blockchain { 235 | constructor() { 236 | super(BTC); 237 | } 238 | 239 | /** 240 | * args: from, amount, to, memo 241 | */ 242 | transfer(...args) { 243 | let data = {}; 244 | if(typeof args[0] == 'object'){ 245 | data = args[0]; 246 | }else{ 247 | data = { 248 | from : args[0], 249 | amount : args[1], 250 | to : args[2], 251 | memo : args[3] 252 | }; 253 | } 254 | data.symbol = data.symbol ? data.symbol : "BTC"; 255 | data.precision = data.precision ? data.precision : 6; 256 | return postMessage.send('sendTransaction',{ 257 | blockchain : this.chain, 258 | action : "transfer", 259 | data : data 260 | }); 261 | } 262 | } 263 | 264 | class NEO$1 extends Blockchain { 265 | constructor() { 266 | super(NEO); 267 | } 268 | 269 | transfer(...args) { 270 | let data = {}; 271 | if(typeof args[0] == 'object'){ 272 | data = args[0]; 273 | }else{ 274 | data = { 275 | from : args[0], 276 | amount : args[1], 277 | to : args[2], 278 | memo : args[3] 279 | }; 280 | } 281 | data.symbol = data.symbol ? data.symbol : "NEO"; 282 | data.precision = data.precision ? data.precision : 8; 283 | return postMessage.send('sendTransaction',{ 284 | blockchain : this.chain, 285 | action : "transfer", 286 | data : data 287 | }); 288 | } 289 | } 290 | 291 | class Account { 292 | //初始化 293 | constructor( config ) { 294 | if(config){ 295 | this.account = config.account ? config.account : null; 296 | this.accountPermission = config.accountPermission ? config.accountPermission : 'active'; 297 | } 298 | } 299 | 300 | //设置活跃账号 301 | setAccount( account ) { 302 | this.account = account; 303 | } 304 | 305 | //获取活跃账号 306 | getAccount(){ 307 | return this.account; 308 | } 309 | 310 | //设置活跃账户权限 311 | setAccountPermission( permission ){ 312 | this.accountPermission = permission; 313 | } 314 | 315 | //获取活跃账户权限 316 | getAccountPermission(){ 317 | return this.accountPermission; 318 | } 319 | } 320 | 321 | const get_info = '/v1/chain/get_info'; 322 | const abi_json_to_bin = '/v1/chain/abi_json_to_bin'; 323 | const push_transaction = '/v1/chain/push_transaction'; 324 | const get_table_rows = '/v1/chain/get_table_rows'; 325 | const get_account = '/v1/chain/get_account'; 326 | const get_producers = '/v1/chain/get_producers'; 327 | const get_currency_balance = '/v1/chain/get_currency_balance'; 328 | const get_account_registed = '/v1/chain/get_account'; 329 | const get_actions = '/v1/history/get_actions'; 330 | 331 | var NodeDataUrls = /*#__PURE__*/Object.freeze({ 332 | get_info: get_info, 333 | abi_json_to_bin: abi_json_to_bin, 334 | push_transaction: push_transaction, 335 | get_table_rows: get_table_rows, 336 | get_account: get_account, 337 | get_producers: get_producers, 338 | get_currency_balance: get_currency_balance, 339 | get_account_registed: get_account_registed, 340 | get_actions: get_actions 341 | }); 342 | 343 | class NodeData { 344 | //初始化 345 | constructor( config ) { 346 | if(config){ 347 | this.httpEndpoint = config.httpEndpoint ? config.httpEndpoint : null; 348 | this.chainID = config.chainID ? config.chainID : null; 349 | this.nodes = config.nodes ? config.nodes : []; 350 | } 351 | if(config.defaultNode){ 352 | this.setNode(config.defaultNode); 353 | } 354 | } 355 | 356 | //设置当前社区 357 | setNode(chainID){ 358 | if(this.nodes[chainID] && this.nodes[chainID].jsonRpc){ 359 | this.chainID = chainID; 360 | this.httpEndpoint = this.nodes[chainID].jsonRpc; 361 | this.netChainID = this.nodes[chainID].chainID; 362 | return true; 363 | }else{ 364 | return false; 365 | } 366 | } 367 | 368 | //获取当前社区 369 | getNode(){ 370 | return this.chainID; 371 | } 372 | 373 | //获取当前链ID 374 | getChainID(){ 375 | return this.netChainID; 376 | } 377 | 378 | //获取当前节点地址 379 | getHttpEndPoint(){ 380 | return this.httpEndpoint; 381 | } 382 | 383 | //获取Rpc地址 384 | getRpcUrl(type) 385 | { 386 | if(typeof NodeDataUrls[type] == 'undefined'){ 387 | throw new Error("undefined url"); 388 | } 389 | return this.getHttpEndPoint() + NodeDataUrls[type]; 390 | } 391 | } 392 | 393 | const getResponseData = (response , type = 'JSON') => { 394 | type = type.toLowerCase(); 395 | switch (type) { 396 | case 'json' : 397 | return response.json(); 398 | case 'html' : 399 | return response.text(); 400 | case 'blob' : 401 | return response.blob(); 402 | default : 403 | return new Promise((resolve) => {resolve(response.body);}); 404 | } 405 | }; 406 | 407 | class Network { 408 | 409 | static get(params) { 410 | if(typeof params.dataType == 'undefined') params.dataType = 'JSON'; 411 | return new Promise((resolve, reject) => { 412 | const options = { 413 | method : 'GET', 414 | headers : params.headers 415 | }; 416 | fetch(params.url , options).then((res) => { 417 | if(res.ok){ 418 | getResponseData(res, params.dataType).then(resolve, reject); 419 | }else{ 420 | reject(res.status); 421 | } 422 | }, (err)=>reject(err)); 423 | }); 424 | } 425 | 426 | static post(url , data = {}, headers = {}) { 427 | if(headers['Content-Type']){ 428 | headers['Content-Type'] = 'application/json'; 429 | } 430 | return fetch(url , { 431 | method : 'POST', 432 | headers : headers, 433 | body : JSON.stringify(data) 434 | }); 435 | } 436 | } 437 | 438 | class EOS$1 extends Blockchain { 439 | constructor() { 440 | super(EOS); 441 | this.account = new Account(); 442 | } 443 | 444 | init ( config ) { 445 | this.node = new NodeData(config); 446 | return true; 447 | } 448 | 449 | //获取链信息 450 | get_info(){ 451 | return Network.get({ 452 | url : this.node.getRpcUrl('get_info') 453 | }); 454 | } 455 | 456 | //序列化 457 | abi_json_to_bin( data ){ 458 | return Network.post({ 459 | url : this.node.getRpcUrl('abi_json_to_bin'), 460 | data : data 461 | }); 462 | } 463 | 464 | //发起交易 465 | push_transaction(transaction,signatures,compression){ 466 | if(!compression) compression = "none"; 467 | return Network.post({ 468 | url : this.node.getRpcUrl('push_transaction'), 469 | data : { 470 | compression : compression, 471 | transaction : transaction, 472 | signatures : signatures, 473 | } 474 | }); 475 | } 476 | 477 | //发起交易 - 传入完整数据 478 | push_transaction_all(data){ 479 | return Network.post({ 480 | url : this.node.getRpcUrl('push_transaction'), 481 | data : data 482 | }); 483 | } 484 | 485 | signTransaction(transaction){ 486 | if(!this.node) throw new Error('EOS chain need to initialize.'); 487 | return postMessage.send('eosTransactionSign',{ 488 | transaction:transaction, 489 | network:{ 490 | blockchain : "eos", 491 | chainId : this.node.getChainID(), 492 | } 493 | }); 494 | } 495 | 496 | customSignProvider({buf, sign, transaction}) { 497 | return new Promise((resolve, reject) => { 498 | this.signTransaction(transaction).then((res) => { 499 | if(res.error){ 500 | reject(res.error); 501 | }else{ 502 | resolve(res.result); 503 | } 504 | }); 505 | }); 506 | } 507 | 508 | getEos() { 509 | if(typeof Eos == 'undefined'){ 510 | throw new Error('Eos.js not found!'); 511 | } 512 | if(typeof this.node == 'undefined'){ 513 | throw new Error('EOS chain need to initialize.'); 514 | } 515 | return Eos({ 516 | httpEndpoint: this.node.getHttpEndPoint(), 517 | chainId: this.node.getChainID(), 518 | signProvider: this.customSignProvider, 519 | }); 520 | } 521 | 522 | getAccount() { 523 | return new Promise((resolve, reject) => { 524 | postMessage.send('eosGetAccount').then((accountInfo) => { 525 | this.account.setAccount(accountInfo.account); 526 | this.node.setNode(accountInfo.node); 527 | if(accountInfo.authority){ 528 | this.account.setAccountPermission(accountInfo.authority); 529 | } 530 | resolve(accountInfo); 531 | },reject); 532 | }); 533 | } 534 | } 535 | 536 | class BlockchainRepository { 537 | constructor() { 538 | this.blockchains = [ 539 | new BTC$1(), 540 | new NEO$1(), 541 | new EOS$1(), 542 | ]; 543 | } 544 | 545 | getBlockchain(chain) { 546 | return this.blockchains.find(blockchain => blockchain.chain === chain); 547 | } 548 | 549 | getBlockchains() { 550 | return this.blockchains; 551 | } 552 | } 553 | 554 | const blockchainRepository = new BlockchainRepository(); 555 | 556 | class MathWallet extends MathApp { 557 | constructor(){ 558 | super(); 559 | // load support blockchains 560 | blockchainRepository.getBlockchains(); 561 | blockchainRepository.getBlockchains().map(blockchain => { 562 | this[blockchain.chain] = blockchain; 563 | }); 564 | } 565 | } 566 | 567 | let mathwallet = new MathWallet(); 568 | 569 | // browsers 570 | if(typeof window !== 'undefined'){ 571 | window.mathwallet = mathwallet; 572 | } 573 | 574 | module.exports = mathwallet; 575 | -------------------------------------------------------------------------------- /dist/mathwallet.min.js: -------------------------------------------------------------------------------- 1 | !function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){"use strict";n.r(e);var r={};n.r(r),n.d(r,"get_info",(function(){return b})),n.d(r,"abi_json_to_bin",(function(){return y})),n.d(r,"push_transaction",(function(){return w})),n.d(r,"get_table_rows",(function(){return _})),n.d(r,"get_account",(function(){return v})),n.d(r,"get_producers",(function(){return O})),n.d(r,"get_currency_balance",(function(){return P})),n.d(r,"get_account_registed",(function(){return T})),n.d(r,"get_actions",(function(){return A}));const o="undefined"!=typeof navigator?navigator.userAgent:"";"undefined"!=typeof navigator&&navigator.appVersion;var s={trident:o.indexOf("Trident")>-1,presto:o.indexOf("Presto")>-1,webKit:o.indexOf("AppleWebKit")>-1,gecko:o.indexOf("Gecko")>-1&&-1==o.indexOf("KHTML"),mobile:!!o.match(/AppleWebKit.*Mobile.*/),ios:!!o.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),android:o.indexOf("Android")>-1||o.indexOf("Adr")>-1,iPhone:o.indexOf("iPhone")>-1,iPad:o.indexOf("iPad")>-1,mdsApp:o.indexOf("MdsApp")>-1,mdsVer:o.indexOf("MdsApp")>-1?o.match(/MdsApp\/[^\s]+\s?/)[0].trim().split("/")[1]:"0"};var i=new class{constructor(t){t.mdsApp&&t.android?this.postMessageHandler=window.mds:t.mdsApp&&t.iPhone&&void 0!==window.webkit?this.postMessageHandler=window.webkit.messageHandlers.mds:this.postMessageHandler={postMessage:console.log}}sign_global_callback(t){if("function"==typeof t){let e="mdseosappcallback"+(new Date).getTime()+Math.floor(1e8*Math.random()+1e7);return window[e]=function(n){t(n),window[e]=null},console.log(e),e}return t}send(t,e={},n=!1){return new Promise((r,o)=>{let s={method:t,params:e,callback:this.sign_global_callback(t=>{if(n)return r(t);let e=JSON.parse(t);return e.error?o(e.error):r(e),!0})};try{this.postMessageHandler.postMessage(JSON.stringify(s))}catch(t){o(t)}})}}(s);let a=new Map;a.set(1,"ETH"),a.set(2,"NEO"),a.set(3,"EOS"),a.set(4,"EOSFORCE"),a.set(5,"ONT"),a.set(6,"BTC"),a.set(7,"ESN"),a.set(8,"TRX"),a.set(9,"NAS"),a.set(10,"BOS"),a.set(11,"ENU"),a.set(12,"TELOS"),a.set(13,"ZILLIQA"),a.set(14,"BINANCE"),a.set(15,"IRIS"),a.set(16,"COSMOS"),a.set(17,"CHAINX"),a.set(18,"CODEX"),a.set(19,"POLKADOT"),a.set(20,"VECHAIN"),a.set(21,"FT"),a.set(22,"COINEX"),a.set(19001,"KUSAMA");var c={getType:t=>a.has(t)?a.get(t):"UNKNOWN",getID(t){t=t.toUpperCase();for(const[e,n]of a)if(n==t)return e;return 0}};var u=class{isMath(){return s.mdsApp}openUrl(t){return i.send("openURL",{url:t})}openThirdApp(t){return i.send("openThirdApplication",{appSchemeURL:t})}close(){return i.send("close")}back(){return i.send("goBack")}fullScreen(t=1){return i.send("fullScreen",{mode:t})}orientation(t=0){let e="portrait";switch(t){case 1:e="landscape";break;default:e="portrait"}return i.send("deviceOrientation",{orientation:e})}share(t){return i.send("shareAction",{type:1,imageURL:t.img,activity:{type:"event",app:"app",event:"share",name:t.name,data:t.data}})}shareTo(t=1,e={}){return i.send("shareAction",{type:t,...e})}getAppInfo(){return i.send("getAppInfo")}getLanguage(){return new Promise((t,e)=>{i.send("getLanguage",{},!0).then(e=>{t(e)},e)})}getWalletType(){return new Promise((t,e)=>{i.send("activeWalletType").then(e=>{t(e.blockchain||c.getType(e.type))},e)})}getCurrentWalletType(){return this.getWalletType()}getCurrentWallet(){return i.send("activeWalletAccount")}walletPicker(t){return i.send("walletPicker",{blockchain:t})}getWallets(){return i.send("selectWallets")}getWalletList(t){let e=c.getID(t);return i.send("getWalletsWithType",{type:e,blockchain:t})}postCustomMessage(t,e){return i.send(t,e)}};class d{constructor(t=""){this.chain=t}}const l="BTC",h="NEO",p="EOS";var g=class extends d{constructor(){super(l)}transfer(...t){let e={};return e="object"==typeof t[0]?t[0]:{from:t[0],amount:t[1],to:t[2],memo:t[3]},e.symbol=e.symbol?e.symbol:"BTC",e.precision=e.precision?e.precision:6,i.send("sendTransaction",{blockchain:this.chain,action:"transfer",data:e})}};var f=class extends d{constructor(){super(h)}transfer(...t){let e={};return e="object"==typeof t[0]?t[0]:{from:t[0],amount:t[1],to:t[2],memo:t[3]},e.symbol=e.symbol?e.symbol:"NEO",e.precision=e.precision?e.precision:8,i.send("sendTransaction",{blockchain:this.chain,action:"transfer",data:e})}};var m=class{constructor(t){t&&(this.account=t.account?t.account:null,this.accountPermission=t.accountPermission?t.accountPermission:"active")}setAccount(t){this.account=t}getAccount(){return this.account}setAccountPermission(t){this.accountPermission=t}getAccountPermission(){return this.accountPermission}};const b="/v1/chain/get_info",y="/v1/chain/abi_json_to_bin",w="/v1/chain/push_transaction",_="/v1/chain/get_table_rows",v="/v1/chain/get_account",O="/v1/chain/get_producers",P="/v1/chain/get_currency_balance",T="/v1/chain/get_account",A="/v1/history/get_actions";var E=class{constructor(t){t&&(this.httpEndpoint=t.httpEndpoint?t.httpEndpoint:null,this.chainID=t.chainID?t.chainID:null,this.nodes=t.nodes?t.nodes:[]),t.defaultNode&&this.setNode(t.defaultNode)}setNode(t){return!(!this.nodes[t]||!this.nodes[t].jsonRpc)&&(this.chainID=t,this.httpEndpoint=this.nodes[t].jsonRpc,this.netChainID=this.nodes[t].chainID,!0)}getNode(){return this.chainID}getChainID(){return this.netChainID}getHttpEndPoint(){return this.httpEndpoint}getRpcUrl(t){if(void 0===r[t])throw new Error("undefined url");return this.getHttpEndPoint()+r[t]}};const S=(t,e="JSON")=>{switch(e=e.toLowerCase()){case"json":return t.json();case"html":return t.text();case"blob":return t.blob();default:return new Promise(e=>{e(t.body)})}};var k=class{static get(t){return void 0===t.dataType&&(t.dataType="JSON"),new Promise((e,n)=>{const r={method:"GET",headers:t.headers};fetch(t.url,r).then(r=>{r.ok?S(r,t.dataType).then(e,n):n(r.status)},t=>n(t))})}static post(t,e={},n={}){return n["Content-Type"]&&(n["Content-Type"]="application/json"),fetch(t,{method:"POST",headers:n,body:JSON.stringify(e)})}};var N=class extends d{constructor(){super(p),this.account=new m}init(t){return this.node=new E(t),!0}get_info(){return k.get({url:this.node.getRpcUrl("get_info")})}abi_json_to_bin(t){return k.post({url:this.node.getRpcUrl("abi_json_to_bin"),data:t})}push_transaction(t,e,n){return n||(n="none"),k.post({url:this.node.getRpcUrl("push_transaction"),data:{compression:n,transaction:t,signatures:e}})}push_transaction_all(t){return k.post({url:this.node.getRpcUrl("push_transaction"),data:t})}signTransaction(t){if(!this.node)throw new Error("EOS chain need to initialize.");return i.send("eosTransactionSign",{transaction:t,network:{blockchain:"eos",chainId:this.node.getChainID()}})}customSignProvider({buf:t,sign:e,transaction:n}){return new Promise((t,e)=>{this.signTransaction(n).then(n=>{n.error?e(n.error):t(n.result)})})}getEos(){if("undefined"==typeof Eos)throw new Error("Eos.js not found!");if(void 0===this.node)throw new Error("EOS chain need to initialize.");return Eos({httpEndpoint:this.node.getHttpEndPoint(),chainId:this.node.getChainID(),signProvider:this.customSignProvider})}getAccount(){return new Promise((t,e)=>{i.send("eosGetAccount").then(e=>{this.account.setAccount(e.account),this.node.setNode(e.node),e.authority&&this.account.setAccountPermission(e.authority),t(e)},e)})}};var I=new class{constructor(){this.blockchains=[new g,new f,new N]}getBlockchain(t){return this.blockchains.find(e=>e.chain===t)}getBlockchains(){return this.blockchains}};let C=new class extends u{constructor(){super(),I.getBlockchains(),I.getBlockchains().map(t=>{this[t.chain]=t})}};"undefined"!=typeof window&&(window.mathwallet=C);e.default=C}]); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "math-js-sdk", 3 | "version": "1.0.9", 4 | "description": "Javascript SDK for MathWallet", 5 | "main": "dist/mathwallet.cjs.js", 6 | "scripts": { 7 | "pack": "./node_modules/.bin/webpack", 8 | "build": "rollup -c", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "keywords": [ 12 | "MathWallet" 13 | ], 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/mathwallet/math-js-sdk.git" 17 | }, 18 | "author": "MathWallet Old-Driver-Rollover Team", 19 | "license": "ISC", 20 | "dependencies": { 21 | "webpack": "^4.41.4" 22 | }, 23 | "devDependencies": { 24 | "babel-cli": "^6.26.0", 25 | "babel-preset-es2015": "^6.24.1", 26 | "rollup": "^0.68.2", 27 | "webpack-cli": "^3.3.10" 28 | } 29 | } -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | input: 'src/mathwallet.js', 3 | output: { 4 | file: 'dist/mathwallet.cjs.js', 5 | format: 'cjs' 6 | } 7 | }; -------------------------------------------------------------------------------- /src/app/MathApp.js: -------------------------------------------------------------------------------- 1 | import PostMessage from './PostMessage'; 2 | import WalletTypes from './WalletTypes'; 3 | import browser from '../util/Browser'; 4 | 5 | class MathApp { 6 | isMath() { 7 | return browser.mdsApp; 8 | } 9 | 10 | openUrl(url) { 11 | return PostMessage.send('openURL', { url: url }); 12 | } 13 | 14 | openThirdApp(url) { 15 | return PostMessage.send('openThirdApplication', { appSchemeURL: url }); 16 | } 17 | 18 | close() { 19 | return PostMessage.send('close'); 20 | } 21 | 22 | back() { 23 | return PostMessage.send('goBack'); 24 | } 25 | 26 | // 0-normal 1-fullScreen 27 | fullScreen(mode = 1) { 28 | return PostMessage.send('fullScreen', { mode: mode }); 29 | } 30 | 31 | // 0-portrait 1-landscape 32 | orientation(mode = 0) { 33 | let orientation = 'portrait'; 34 | switch (mode) { 35 | case 1: 36 | orientation = 'landscape'; 37 | break; 38 | default: 39 | orientation = 'portrait'; 40 | } 41 | return PostMessage.send('deviceOrientation', { orientation: orientation }); 42 | } 43 | 44 | share(params) { 45 | return PostMessage.send('shareAction', { 46 | "type": 1, 47 | "imageURL": params.img, 48 | "activity": { 49 | "type": "event", 50 | "app": "app", 51 | "event": "share", 52 | "name": params.name, 53 | "data": params.data 54 | } 55 | }); 56 | } 57 | // 1-image 2-link 3-album 58 | shareTo(type = 1, params = {}) { 59 | return PostMessage.send('shareAction', { 60 | "type": type, 61 | ...params 62 | }); 63 | } 64 | 65 | getAppInfo() { 66 | return PostMessage.send('getAppInfo'); 67 | } 68 | 69 | getLanguage() { 70 | return new Promise((resolve, reject) => { 71 | PostMessage.send('getLanguage', {}, true).then((language) => { 72 | resolve(language); 73 | }, reject); 74 | }); 75 | } 76 | 77 | getWalletType() { 78 | return new Promise((resolve, reject) => { 79 | PostMessage.send('activeWalletType').then((res) => { 80 | resolve(res.blockchain || WalletTypes.getType(res.type)); 81 | }, reject); 82 | }); 83 | } 84 | getCurrentWalletType() { 85 | return this.getWalletType(); 86 | } 87 | getCurrentWallet() { 88 | return PostMessage.send('activeWalletAccount'); 89 | } 90 | walletPicker(type) { 91 | return PostMessage.send('walletPicker', { blockchain: type }); 92 | } 93 | getWallets() { 94 | return PostMessage.send('selectWallets'); 95 | } 96 | getWalletList(type) { 97 | let typeID = WalletTypes.getID(type); 98 | return PostMessage.send('getWalletsWithType', { type: typeID, blockchain: type }); 99 | } 100 | 101 | postCustomMessage(method, payload) { 102 | return PostMessage.send(method, payload); 103 | } 104 | } 105 | 106 | export default MathApp; -------------------------------------------------------------------------------- /src/app/PostMessage.js: -------------------------------------------------------------------------------- 1 | import browser from '../util/Browser'; 2 | 3 | class PostMessage { 4 | constructor(browser) { 5 | if(browser.mdsApp && browser.android) { 6 | this.postMessageHandler = window.mds; 7 | }else if(browser.mdsApp && browser.iPhone && typeof window.webkit != 'undefined'){ 8 | this.postMessageHandler = window.webkit.messageHandlers.mds; 9 | }else{ 10 | // this.postMessageHandler = window; 11 | this.postMessageHandler = { 12 | postMessage : console.log //debug 13 | }; 14 | } 15 | } 16 | 17 | 18 | sign_global_callback(callback){ 19 | if(typeof callback == 'function'){ 20 | let globalCallbackFuncName = 'mdseosappcallback' + new Date().getTime() + Math.floor(Math.random()*100000000+10000000); 21 | window[globalCallbackFuncName] = function(res){ 22 | callback(res); 23 | window[globalCallbackFuncName] = null; 24 | }; 25 | console.log(globalCallbackFuncName); 26 | return globalCallbackFuncName; 27 | }else{ 28 | return callback; 29 | } 30 | } 31 | 32 | 33 | 34 | send(method, payload = {}, returnData = false) { 35 | return new Promise((resolve, reject) => { 36 | const callback = (res) => { 37 | if(returnData){ 38 | return resolve(res); 39 | } 40 | 41 | let result = JSON.parse(res); 42 | if(result.error){ 43 | reject(result.error); 44 | }else{ 45 | resolve(result); 46 | } 47 | return true; 48 | }; 49 | 50 | let message = { 51 | method : method, 52 | params : payload, 53 | callback : this.sign_global_callback(callback) 54 | }; 55 | 56 | try{ 57 | this.postMessageHandler.postMessage(JSON.stringify(message)); 58 | }catch(err){ 59 | reject(err); 60 | } 61 | }); 62 | } 63 | } 64 | 65 | let postMessage = new PostMessage(browser); 66 | 67 | export default postMessage; -------------------------------------------------------------------------------- /src/app/WalletTypes.js: -------------------------------------------------------------------------------- 1 | let list = new Map(); 2 | 3 | list.set(1, 'ETH'); 4 | list.set(2, 'NEO'); 5 | list.set(3, 'EOS'); 6 | list.set(4, 'EOSFORCE'); 7 | list.set(5, 'ONT'); 8 | list.set(6, 'BTC'); 9 | list.set(7, 'ESN'); 10 | list.set(8, 'TRX'); 11 | list.set(9, 'NAS'); 12 | list.set(10, 'BOS'); 13 | list.set(11, 'ENU'); 14 | list.set(12, 'TELOS'); 15 | list.set(13, 'ZILLIQA'); 16 | list.set(14, 'BINANCE'); 17 | list.set(15, 'IRIS'); 18 | list.set(16, 'COSMOS'); 19 | list.set(17, 'CHAINX'); 20 | list.set(18, 'CODEX'); 21 | list.set(19, 'POLKADOT'); 22 | list.set(20, 'VECHAIN'); 23 | list.set(21, 'FT'); 24 | list.set(22, 'COINEX'); 25 | list.set(19001, 'KUSAMA'); 26 | 27 | const WalletTypes = { 28 | getType(id) { 29 | return list.has(id) ? list.get(id) : 'UNKNOWN'; 30 | }, 31 | 32 | getID(type) { 33 | type = type.toUpperCase(); 34 | for (const [key, value] of list) { 35 | if (value == type) return key; 36 | } 37 | return 0; 38 | } 39 | }; 40 | 41 | export default WalletTypes; -------------------------------------------------------------------------------- /src/blockchain/Blockchain.js: -------------------------------------------------------------------------------- 1 | export default class Blockchain { 2 | constructor(chain = ''){ 3 | this.chain = chain; 4 | } 5 | } -------------------------------------------------------------------------------- /src/blockchain/BlockchainRepository.js: -------------------------------------------------------------------------------- 1 | import BTC from './btc/btc'; 2 | import NEO from './neo/neo'; 3 | import EOS from './eos/eos'; 4 | 5 | class BlockchainRepository { 6 | constructor() { 7 | this.blockchains = [ 8 | new BTC(), 9 | new NEO(), 10 | new EOS(), 11 | ]; 12 | } 13 | 14 | getBlockchain(chain) { 15 | return this.blockchains.find(blockchain => blockchain.chain === chain); 16 | } 17 | 18 | getBlockchains() { 19 | return this.blockchains; 20 | } 21 | } 22 | 23 | const blockchainRepository = new BlockchainRepository(); 24 | export default blockchainRepository; -------------------------------------------------------------------------------- /src/blockchain/BlockchainTypes.js: -------------------------------------------------------------------------------- 1 | export const BTC = 'BTC'; 2 | export const NEO = 'NEO'; 3 | export const EOS = 'EOS'; -------------------------------------------------------------------------------- /src/blockchain/btc/btc.js: -------------------------------------------------------------------------------- 1 | import Blockchain from '../Blockchain'; 2 | import * as BlockchainTypes from '../BlockchainTypes'; 3 | import PostMessage from '../../app/PostMessage'; 4 | 5 | class BTC extends Blockchain { 6 | constructor() { 7 | super(BlockchainTypes.BTC); 8 | } 9 | 10 | /** 11 | * args: from, amount, to, memo 12 | */ 13 | transfer(...args) { 14 | let data = {}; 15 | if(typeof args[0] == 'object'){ 16 | data = args[0]; 17 | }else{ 18 | data = { 19 | from : args[0], 20 | amount : args[1], 21 | to : args[2], 22 | memo : args[3] 23 | }; 24 | } 25 | data.symbol = data.symbol ? data.symbol : "BTC"; 26 | data.precision = data.precision ? data.precision : 6; 27 | return PostMessage.send('sendTransaction',{ 28 | blockchain : this.chain, 29 | action : "transfer", 30 | data : data 31 | }); 32 | } 33 | } 34 | 35 | export default BTC; -------------------------------------------------------------------------------- /src/blockchain/eos/Account.js: -------------------------------------------------------------------------------- 1 | class Account { 2 | //初始化 3 | constructor( config ) { 4 | if(config){ 5 | this.account = config.account ? config.account : null; 6 | this.accountPermission = config.accountPermission ? config.accountPermission : 'active'; 7 | } 8 | } 9 | 10 | //设置活跃账号 11 | setAccount( account ) { 12 | this.account = account; 13 | } 14 | 15 | //获取活跃账号 16 | getAccount(){ 17 | return this.account; 18 | } 19 | 20 | //设置活跃账户权限 21 | setAccountPermission( permission ){ 22 | this.accountPermission = permission; 23 | } 24 | 25 | //获取活跃账户权限 26 | getAccountPermission(){ 27 | return this.accountPermission; 28 | } 29 | } 30 | export default Account; -------------------------------------------------------------------------------- /src/blockchain/eos/NodeData.js: -------------------------------------------------------------------------------- 1 | import * as NodeDataUrls from './NodeDataUrls'; 2 | class NodeData { 3 | //初始化 4 | constructor( config ) { 5 | if(config){ 6 | this.httpEndpoint = config.httpEndpoint ? config.httpEndpoint : null; 7 | this.chainID = config.chainID ? config.chainID : null; 8 | this.nodes = config.nodes ? config.nodes : []; 9 | } 10 | if(config.defaultNode){ 11 | this.setNode(config.defaultNode); 12 | } 13 | } 14 | 15 | //设置当前社区 16 | setNode(chainID){ 17 | if(this.nodes[chainID] && this.nodes[chainID].jsonRpc){ 18 | this.chainID = chainID; 19 | this.httpEndpoint = this.nodes[chainID].jsonRpc; 20 | this.netChainID = this.nodes[chainID].chainID; 21 | return true; 22 | }else{ 23 | return false; 24 | } 25 | } 26 | 27 | //获取当前社区 28 | getNode(){ 29 | return this.chainID; 30 | } 31 | 32 | //获取当前链ID 33 | getChainID(){ 34 | return this.netChainID; 35 | } 36 | 37 | //获取当前节点地址 38 | getHttpEndPoint(){ 39 | return this.httpEndpoint; 40 | } 41 | 42 | //获取Rpc地址 43 | getRpcUrl(type) 44 | { 45 | if(typeof NodeDataUrls[type] == 'undefined'){ 46 | throw new Error("undefined url"); 47 | } 48 | return this.getHttpEndPoint() + NodeDataUrls[type]; 49 | } 50 | } 51 | 52 | export default NodeData; -------------------------------------------------------------------------------- /src/blockchain/eos/NodeDataUrls.js: -------------------------------------------------------------------------------- 1 | export const get_info = '/v1/chain/get_info'; 2 | export const abi_json_to_bin = '/v1/chain/abi_json_to_bin'; 3 | export const push_transaction = '/v1/chain/push_transaction'; 4 | export const get_table_rows = '/v1/chain/get_table_rows'; 5 | export const get_account = '/v1/chain/get_account'; 6 | export const get_producers = '/v1/chain/get_producers'; 7 | export const get_currency_balance = '/v1/chain/get_currency_balance'; 8 | export const get_account_registed = '/v1/chain/get_account'; 9 | export const get_actions = '/v1/history/get_actions'; -------------------------------------------------------------------------------- /src/blockchain/eos/eos.js: -------------------------------------------------------------------------------- 1 | import Blockchain from '../Blockchain'; 2 | import * as BlockchainTypes from '../BlockchainTypes'; 3 | import PostMessage from '../../app/PostMessage'; 4 | import Account from './Account'; 5 | import NodeData from './NodeData'; 6 | import Network from '../../util/Network'; 7 | 8 | class EOS extends Blockchain { 9 | constructor() { 10 | super(BlockchainTypes.EOS); 11 | this.account = new Account(); 12 | } 13 | 14 | init ( config ) { 15 | this.node = new NodeData(config); 16 | return true; 17 | } 18 | 19 | //获取链信息 20 | get_info(){ 21 | return Network.get({ 22 | url : this.node.getRpcUrl('get_info') 23 | }); 24 | } 25 | 26 | //序列化 27 | abi_json_to_bin( data ){ 28 | return Network.post({ 29 | url : this.node.getRpcUrl('abi_json_to_bin'), 30 | data : data 31 | }); 32 | } 33 | 34 | //发起交易 35 | push_transaction(transaction,signatures,compression){ 36 | if(!compression) compression = "none"; 37 | return Network.post({ 38 | url : this.node.getRpcUrl('push_transaction'), 39 | data : { 40 | compression : compression, 41 | transaction : transaction, 42 | signatures : signatures, 43 | } 44 | }); 45 | } 46 | 47 | //发起交易 - 传入完整数据 48 | push_transaction_all(data){ 49 | return Network.post({ 50 | url : this.node.getRpcUrl('push_transaction'), 51 | data : data 52 | }); 53 | } 54 | 55 | signTransaction(transaction){ 56 | if(!this.node) throw new Error('EOS chain need to initialize.'); 57 | return PostMessage.send('eosTransactionSign',{ 58 | transaction:transaction, 59 | network:{ 60 | blockchain : "eos", 61 | chainId : this.node.getChainID(), 62 | } 63 | }); 64 | } 65 | 66 | customSignProvider({buf, sign, transaction}) { 67 | return new Promise((resolve, reject) => { 68 | this.signTransaction(transaction).then((res) => { 69 | if(res.error){ 70 | reject(res.error); 71 | }else{ 72 | resolve(res.result); 73 | } 74 | }); 75 | }); 76 | } 77 | 78 | getEos() { 79 | if(typeof Eos == 'undefined'){ 80 | throw new Error('Eos.js not found!'); 81 | } 82 | if(typeof this.node == 'undefined'){ 83 | throw new Error('EOS chain need to initialize.'); 84 | } 85 | return Eos({ 86 | httpEndpoint: this.node.getHttpEndPoint(), 87 | chainId: this.node.getChainID(), 88 | signProvider: this.customSignProvider, 89 | }); 90 | } 91 | 92 | getAccount() { 93 | return new Promise((resolve, reject) => { 94 | PostMessage.send('eosGetAccount').then((accountInfo) => { 95 | this.account.setAccount(accountInfo.account); 96 | this.node.setNode(accountInfo.node); 97 | if(accountInfo.authority){ 98 | this.account.setAccountPermission(accountInfo.authority); 99 | } 100 | resolve(accountInfo); 101 | },reject); 102 | }); 103 | } 104 | } 105 | 106 | export default EOS; -------------------------------------------------------------------------------- /src/blockchain/neo/neo.js: -------------------------------------------------------------------------------- 1 | import Blockchain from '../Blockchain'; 2 | import * as BlockchainTypes from '../BlockchainTypes'; 3 | import PostMessage from '../../app/PostMessage'; 4 | 5 | class NEO extends Blockchain { 6 | constructor() { 7 | super(BlockchainTypes.NEO); 8 | } 9 | 10 | transfer(...args) { 11 | let data = {}; 12 | if(typeof args[0] == 'object'){ 13 | data = args[0]; 14 | }else{ 15 | data = { 16 | from : args[0], 17 | amount : args[1], 18 | to : args[2], 19 | memo : args[3] 20 | }; 21 | } 22 | data.symbol = data.symbol ? data.symbol : "NEO"; 23 | data.precision = data.precision ? data.precision : 8; 24 | return PostMessage.send('sendTransaction',{ 25 | blockchain : this.chain, 26 | action : "transfer", 27 | data : data 28 | }); 29 | } 30 | } 31 | 32 | export default NEO; -------------------------------------------------------------------------------- /src/mathwallet.js: -------------------------------------------------------------------------------- 1 | import MathApp from './app/MathApp'; 2 | import BlockchainRepository from './blockchain/BlockchainRepository'; 3 | 4 | 5 | class MathWallet extends MathApp { 6 | constructor(){ 7 | super(); 8 | // load support blockchains 9 | BlockchainRepository.getBlockchains(); 10 | BlockchainRepository.getBlockchains().map(blockchain => { 11 | this[blockchain.chain] = blockchain; 12 | }); 13 | } 14 | } 15 | 16 | let mathwallet = new MathWallet(); 17 | 18 | // browsers 19 | if(typeof window !== 'undefined'){ 20 | window.mathwallet = mathwallet; 21 | } 22 | 23 | // nodejs 24 | export default mathwallet; -------------------------------------------------------------------------------- /src/util/Browser.js: -------------------------------------------------------------------------------- 1 | const u = typeof navigator != 'undefined' ? navigator.userAgent : ''; 2 | const app = typeof navigator != 'undefined' ? navigator.appVersion : ''; 3 | const browser = { 4 | trident: u.indexOf('Trident') > -1, 5 | presto: u.indexOf('Presto') > -1, 6 | webKit: u.indexOf('AppleWebKit') > -1, 7 | gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, 8 | mobile: !!u.match(/AppleWebKit.*Mobile.*/), 9 | ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), 10 | android: u.indexOf('Android') > -1 || u.indexOf('Adr') > -1, 11 | iPhone: u.indexOf('iPhone') > -1 , 12 | iPad: u.indexOf('iPad') > -1, 13 | mdsApp: u.indexOf('MdsApp') > -1, 14 | mdsVer: u.indexOf('MdsApp') > -1?u.match(/MdsApp\/[^\s]+\s?/)[0].trim().split('/')[1]:'0' //MdsApp版本 15 | }; 16 | 17 | export default browser; -------------------------------------------------------------------------------- /src/util/MathError.js: -------------------------------------------------------------------------------- 1 | class MathError extends Error{ 2 | constructor(msg, code) { 3 | this.msg = msg; 4 | this.code = code; 5 | console.log(this.code + ':' + this.msg); 6 | } 7 | } 8 | 9 | export default MathError; -------------------------------------------------------------------------------- /src/util/Network.js: -------------------------------------------------------------------------------- 1 | const getResponseData = (response , type = 'JSON') => { 2 | type = type.toLowerCase(); 3 | switch (type) { 4 | case 'json' : 5 | return response.json(); 6 | case 'html' : 7 | return response.text(); 8 | case 'blob' : 9 | return response.blob(); 10 | default : 11 | return new Promise((resolve) => {resolve(response.body);}); 12 | } 13 | }; 14 | 15 | class Network { 16 | 17 | static get(params) { 18 | if(typeof params.dataType == 'undefined') params.dataType = 'JSON'; 19 | return new Promise((resolve, reject) => { 20 | const options = { 21 | method : 'GET', 22 | headers : params.headers 23 | }; 24 | fetch(params.url , options).then((res) => { 25 | if(res.ok){ 26 | getResponseData(res, params.dataType).then(resolve, reject); 27 | }else{ 28 | reject(res.status); 29 | } 30 | }, (err)=>reject(err)); 31 | }); 32 | } 33 | 34 | static post(url , data = {}, headers = {}) { 35 | if(headers['Content-Type']){ 36 | headers['Content-Type'] = 'application/json'; 37 | } 38 | return fetch(url , { 39 | method : 'POST', 40 | headers : headers, 41 | body : JSON.stringify(data) 42 | }); 43 | } 44 | } 45 | 46 | export default Network; -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | // const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); 3 | 4 | module.exports = { 5 | entry: { 6 | entry: __dirname + '/src/mathwallet.js' 7 | }, 8 | output: { 9 | path: __dirname + '/dist', 10 | filename: 'mathwallet.min.js' 11 | }, 12 | plugins: [ 13 | // new UglifyJSPlugin() 14 | ] 15 | }; --------------------------------------------------------------------------------