diff --git a/__tests__/client.test.js b/__tests__/client.test.js
index 805232a..3ce5796 100644
--- a/__tests__/client.test.js
+++ b/__tests__/client.test.js
@@ -4,11 +4,14 @@ import * as crypto from "../src/crypto"
const mnemonic = "total lottery arena when pudding best candy until army spoil drill pool"
-const privateKey = "29892b64003fc5c8c89dc795a2ae82aa84353bb4352f28707c2ed32aa1011884"
-const fromAddress = "okexchain1pt7xrmxul7sx54ml44lvv403r06clrdkgmvr9g"
-const serverUrl = "http://localhost:8545"
+const privateKey_996 = "29892b64003fc5c8c89dc795a2ae82aa84353bb4352f28707c2ed32aa1011884"
+const privateKey = "828e61f969a7369f3340b07dd2080740d8445d7f802899ddacf9bc4db8608997"
+const from_996 = "okexchain1pt7xrmxul7sx54ml44lvv403r06clrdkgmvr9g"
+const from = "okexchain1ya7dn2rr8nx07tx9ksq8gvz5utvarrh03cen3l"
+const serverUrl = "https://exchaintest.okexcn.com"
+// const serverUrl = "https://exchaintest.okexcn.com"
const userAddress = "okexchain1jjvpmgwwgs99nhlje3aag0lackunqgj7xnrnwe"
-const chainId = "okexchain-1" // -testnet1
+const chainId = "okexchain-65" // -testnet1
const baseCoin = "okt"
const testCoin = "xxb-781"
const testProduct = testCoin + "_" + baseCoin
@@ -21,11 +24,14 @@ describe("OKEXChainClient test", async () => {
it("get balance", async () => {
const client = new OKEXChainClient(serverUrl, {
- chainId: chainId
+ chainId: chainId,
+ relativePath: "/okexchain-test/v1",
+ isMainnet: false
})
- const privateKey = crypto.getPrivateKeyFromMnemonic(mnemonic)
+ const privateKey = crypto.getPrivateKeyFromMnemonic(mnemonic, '60')
await client.setAccountInfo(privateKey)
- const res = await client.getBalance(fromAddress)
+ const res = await client.getBalance(from)
+ console.log(res)
expect(res.length).toBeGreaterThanOrEqual(0)
})
diff --git a/docs/okexchain-jssdk-doc-crypto.md b/docs/okexchain-jssdk-doc-crypto.md
index c9e0609..6c73db4 100644
--- a/docs/okexchain-jssdk-doc-crypto.md
+++ b/docs/okexchain-jssdk-doc-crypto.md
@@ -8,6 +8,8 @@
* [.decodeAddressToBuffer](#module_crypto.decodeAddressToBuffer)
* [.validateAddress](#module_crypto.validateAddress) ⇒ boolean
* [.encodeAddressToBech32](#module_crypto.encodeAddressToBech32) ⇒ string
+ * [.convertBech32ToHex](#module_crypto.convertBech32ToHex) ⇒ String
+ * [.convertHexToBech32](#module_crypto.convertHexToBech32) ⇒ string
* [.generatePrivateKey](#module_crypto.generatePrivateKey) ⇒ string
* [.getPubKeyFromHex](#module_crypto.getPubKeyFromHex) ⇒ Elliptic.PublicKey
* [.encodePubKeyToCompressedBuffer](#module_crypto.encodePubKeyToCompressedBuffer) ⇒ Buffer
@@ -76,6 +78,28 @@ Encodes address from hex to bech32 format.
| hexAddr | string | address in hex string |
| prefix | string | address prefix |
+
+
+### crypto.convertBech32ToHex ⇒ String
+covert okexchain address to 0x address
+
+**Kind**: static constant of [crypto](#module_crypto)
+
+| Param |
+| --- |
+| bech32Address |
+
+
+
+### crypto.convertHexToBech32 ⇒ string
+covert 0x address to okexchain address
+
+**Kind**: static constant of [crypto](#module_crypto)
+
+| Param |
+| --- |
+| hexAddress |
+
### crypto.generatePrivateKey ⇒ string
diff --git a/package-lock.json b/package-lock.json
index 3ff539a..a765b9a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -774,6 +774,22 @@
"to-fast-properties": "^2.0.0"
}
},
+ "@json-rpc-tools/types": {
+ "version": "1.6.4",
+ "resolved": "https://registry.npmjs.org/@json-rpc-tools/types/-/types-1.6.4.tgz",
+ "integrity": "sha512-DHtnvlIFN8YUun38Sy9SaRdV/BsUMFM5bAABDsb/iPGLfPHOMKoAyuPOwEqQ2vgtc9ayTcQ2546OPTQ92IzJ/g==",
+ "requires": {
+ "keyvaluestorage-interface": "^1.0.0"
+ }
+ },
+ "@json-rpc-tools/utils": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@json-rpc-tools/utils/-/utils-1.6.1.tgz",
+ "integrity": "sha512-cNwP4QapAls+xATU8zLLqPYa9qCbgwEyWEK7vE1oH91b3LfbUYwHtiWZ1+rv0X/mh/9cWNTo2Oi2Sah/QX0WwA==",
+ "requires": {
+ "@json-rpc-tools/types": "^1.6.1"
+ }
+ },
"@json-schema-spec/json-pointer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@json-schema-spec/json-pointer/-/json-pointer-0.1.2.tgz",
@@ -792,6 +808,26 @@
"uri-js": "^4.2.2"
}
},
+ "@pedrouid/iso-crypto": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@pedrouid/iso-crypto/-/iso-crypto-1.1.0.tgz",
+ "integrity": "sha512-twi+tW67XT0BSOv4rsegnGo4TQMhfFswS/GY3KhrjFiNw3z9x+cMkfO+itNe1JZghQxsxHuhifvfsnG814g1hQ==",
+ "requires": {
+ "@pedrouid/iso-random": "^1.1.0",
+ "aes-js": "^3.1.2",
+ "enc-utils": "^3.0.0",
+ "hash.js": "^1.1.7"
+ }
+ },
+ "@pedrouid/iso-random": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@pedrouid/iso-random/-/iso-random-1.1.0.tgz",
+ "integrity": "sha512-U8P2qdbvyU5aom0036dkpp0C9c8pgW1SNhAo8+zPDzgmKA58Hl6dc+ZkQXkE9aHrzN6v/0w+409JMjSYwx5tVw==",
+ "requires": {
+ "enc-utils": "^3.0.0",
+ "randombytes": "^2.1.0"
+ }
+ },
"@types/deep-equal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/deep-equal/-/deep-equal-1.0.1.tgz",
@@ -804,6 +840,93 @@
"integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
"dev": true
},
+ "@walletconnect/client": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@walletconnect/client/-/client-1.3.3.tgz",
+ "integrity": "sha512-aHwsX2lvdEhb2OutHr0cKKRNMOAhaE/Xejbk6stbUozeh0MKAWwhVW5g16xd+wX07Mictq4JFQrg3dSsabRJlg==",
+ "requires": {
+ "@walletconnect/core": "^1.3.3",
+ "@walletconnect/iso-crypto": "^1.3.3",
+ "@walletconnect/types": "^1.3.3",
+ "@walletconnect/utils": "^1.3.3"
+ }
+ },
+ "@walletconnect/core": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/@walletconnect/core/-/core-1.3.6.tgz",
+ "integrity": "sha512-1HHP2xZI6b88WQgszs3gP5xkkCwwlWgDJz+J6ADGzVXhQP21p1mZhKezUtx27rOtQimMIrPDfgPyAHwQBZkkSw==",
+ "requires": {
+ "@walletconnect/socket-transport": "^1.3.6",
+ "@walletconnect/types": "^1.3.6",
+ "@walletconnect/utils": "^1.3.6"
+ }
+ },
+ "@walletconnect/iso-crypto": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/@walletconnect/iso-crypto/-/iso-crypto-1.3.6.tgz",
+ "integrity": "sha512-HypXNSmMAuEvNhllXWsCHtCVK4JfFFcZqPijurcXmOtWanjZV+8NuiYnKG11qAllSbYRwqKchb7GTDp33n0g0Q==",
+ "requires": {
+ "@pedrouid/iso-crypto": "^1.0.0",
+ "@walletconnect/types": "^1.3.6",
+ "@walletconnect/utils": "^1.3.6"
+ }
+ },
+ "@walletconnect/socket-transport": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/@walletconnect/socket-transport/-/socket-transport-1.3.6.tgz",
+ "integrity": "sha512-dvO8mRECU4I6FpoQX9GMh9BNzR2/g6vcj9LEIjgApW6Rfx0mCKUgoVBSi2W7NHC94zfdYiJdaH950oismj5gNw==",
+ "requires": {
+ "@walletconnect/types": "^1.3.6",
+ "@walletconnect/utils": "^1.3.6",
+ "ws": "7.3.0"
+ },
+ "dependencies": {
+ "ws": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz",
+ "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w=="
+ }
+ }
+ },
+ "@walletconnect/types": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/@walletconnect/types/-/types-1.3.6.tgz",
+ "integrity": "sha512-fNir3Pi1ZpuVlgNr8qtP2LOSsV9rNgJGHmBnHHqKNmpuRpPxG1mhmKFdDHNGyVIP5bM5CWIXmlULDTax63UJbg=="
+ },
+ "@walletconnect/utils": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/@walletconnect/utils/-/utils-1.3.6.tgz",
+ "integrity": "sha512-nzTO5A3Ltjrsu6u8SR/KqdHTH03848KIj5MQlOCUjwxW1fXOvuri8+kwFKqlMn0bk1Qvlt6rrOptbt14PW8kSA==",
+ "requires": {
+ "@json-rpc-tools/utils": "1.6.1",
+ "@walletconnect/types": "^1.3.6",
+ "bn.js": "4.11.8",
+ "detect-browser": "5.1.0",
+ "enc-utils": "3.0.0",
+ "js-sha3": "0.8.0",
+ "query-string": "6.13.5",
+ "safe-json-utils": "1.0.0",
+ "window-getters": "1.0.0",
+ "window-metadata": "1.0.0"
+ },
+ "dependencies": {
+ "query-string": {
+ "version": "6.13.5",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.13.5.tgz",
+ "integrity": "sha512-svk3xg9qHR39P3JlHuD7g3nRnyay5mHbrPctEBDUxUkHRifPHXJDhBUycdCC0NBjXoDf44Gb+IsOZL1Uwn8M/Q==",
+ "requires": {
+ "decode-uri-component": "^0.2.0",
+ "split-on-first": "^1.0.0",
+ "strict-uri-encode": "^2.0.0"
+ }
+ },
+ "strict-uri-encode": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
+ "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
+ }
+ }
+ },
"JSONStream": {
"version": "1.3.5",
"resolved": "http://registry.npm.taobao.org/JSONStream/download/JSONStream-1.3.5.tgz",
@@ -890,6 +1013,11 @@
"integrity": "sha1-02O2b1+sXwGP+cOh57b44xDMORM=",
"dev": true
},
+ "aes-js": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz",
+ "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ=="
+ },
"ajv": {
"version": "6.10.0",
"resolved": "http://registry.npm.taobao.org/ajv/download/ajv-6.10.0.tgz",
@@ -3026,6 +3154,11 @@
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
+ "detect-browser": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.1.0.tgz",
+ "integrity": "sha512-WKa9p+/MNwmTiS+V2AS6eGxic+807qvnV3hC+4z2GTY+F42h1n8AynVTMMc4EJBC32qMs6yjOTpeDEQQt/AVqQ=="
+ },
"detect-indent": {
"version": "4.0.0",
"resolved": "http://registry.npm.taobao.org/detect-indent/download/detect-indent-4.0.0.tgz",
@@ -3189,6 +3322,15 @@
"integrity": "sha1-kzoEBShgyF6DwSJHnEdIqOTHIVY=",
"dev": true
},
+ "enc-utils": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/enc-utils/-/enc-utils-3.0.0.tgz",
+ "integrity": "sha512-e57t/Z2HzWOLwOp7DZcV0VMEY8t7ptWwsxyp6kM2b2zrk6JqIpXxzkruHAMiBsy5wg9jp/183GdiRXCvBtzsYg==",
+ "requires": {
+ "is-typedarray": "1.0.0",
+ "typedarray-to-buffer": "3.1.5"
+ }
+ },
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@@ -6780,6 +6922,11 @@
"integrity": "sha1-+IxgjjJKM3OpW8xFrTBeXJecRZs=",
"dev": true
},
+ "js-sha3": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+ "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q=="
+ },
"js-tokens": {
"version": "4.0.0",
"resolved": "http://registry.npm.taobao.org/js-tokens/download/js-tokens-4.0.0.tgz",
@@ -7015,6 +7162,11 @@
"node-gyp-build": "^4.2.0"
}
},
+ "keyvaluestorage-interface": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/keyvaluestorage-interface/-/keyvaluestorage-interface-1.0.0.tgz",
+ "integrity": "sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g=="
+ },
"kind-of": {
"version": "6.0.2",
"resolved": "http://registry.npm.taobao.org/kind-of/download/kind-of-6.0.2.tgz",
@@ -8808,6 +8960,11 @@
"resolved": "http://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz",
"integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0="
},
+ "safe-json-utils": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-json-utils/-/safe-json-utils-1.0.0.tgz",
+ "integrity": "sha512-n0hJm6BgX8wk3G+AS8MOQnfcA8dfE6ZMUfwkHUNx69YxPlU3HDaZTHXWto35Z+C4mOjK1odlT95WutkGC+0Idw=="
+ },
"safe-regex": {
"version": "1.1.0",
"resolved": "http://registry.npm.taobao.org/safe-regex/download/safe-regex-1.1.0.tgz",
@@ -9309,6 +9466,11 @@
"integrity": "sha1-dezRqI3owYTvAV6vtRtbSL/RG7E=",
"dev": true
},
+ "split-on-first": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
+ "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
+ },
"split-string": {
"version": "3.1.0",
"resolved": "http://registry.npm.taobao.org/split-string/download/split-string-3.1.0.tgz",
@@ -10006,6 +10168,14 @@
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
"dev": true
},
+ "typedarray-to-buffer": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+ "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+ "requires": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
"typeforce": {
"version": "1.18.0",
"resolved": "http://registry.npm.taobao.org/typeforce/download/typeforce-1.18.0.tgz",
@@ -10454,6 +10624,19 @@
"bs58check": "<3.0.0"
}
},
+ "window-getters": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/window-getters/-/window-getters-1.0.0.tgz",
+ "integrity": "sha512-xyvEFq3x+7dCA7NFhqOmTMk0fPmmAzCUYL2svkw2LGBaXXQLRP0lFnfXHzysri9WZNMkzp/FD1u0w2Qc7Co+JA=="
+ },
+ "window-metadata": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/window-metadata/-/window-metadata-1.0.0.tgz",
+ "integrity": "sha512-eYoXsZ9X4J+6xZgbHhNAatSR5bCtT409q8B+2Ol9ySx7qsdtgVZcNfox4qszFmKlGsFtT2b1Tcmcy69bRMObcg==",
+ "requires": {
+ "window-getters": "^1.0.0"
+ }
+ },
"wordwrap": {
"version": "1.0.0",
"resolved": "http://registry.npm.taobao.org/wordwrap/download/wordwrap-1.0.0.tgz",
diff --git a/package.json b/package.json
index 0ab3e25..fc2627f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@okexchain/javascript-sdk",
- "version": "0.0.31",
+ "version": "0.0.32",
"license": "Apache-2.0",
"main": "lib/index.js",
"scripts": {
@@ -13,6 +13,7 @@
"sdk": "webpack-dev-server --config build/webpack.config.sdk.js"
},
"dependencies": {
+ "@walletconnect/client": "1.3.3",
"axios": "^0.18.0",
"babel-polyfill": "^6.26.0",
"base32-encode": "^1.1.0",
diff --git a/src/client.js b/src/client.js
index 92d8a97..3dbd421 100644
--- a/src/client.js
+++ b/src/client.js
@@ -7,6 +7,7 @@
import * as crypto from "./crypto"
import Transaction from "./transaction"
import HttpProxy from "./httpProxy"
+import * as wallet from './wallet'
const defaultChainId = "okexchain-66"
const defaultRelativePath = "/okexchain/v1"
@@ -107,6 +108,12 @@ export class OKEXChainClient {
* @return {OKEXChainClient}
*/
async setAccountInfo(privateKey) {
+ if(!privateKey) {
+ const address = await wallet.getAddress();
+ if (!address) throw new Error("invalid privateKey: " + privateKey)
+ await this.setAccountInfoByWallet(address);
+ return this;
+ }
if (privateKey !== this.privateKey) {
const address = crypto.getAddressFromPrivateKey(privateKey, bech32Head)
if (!address) throw new Error("invalid privateKey: " + privateKey)
@@ -119,6 +126,17 @@ export class OKEXChainClient {
return this
}
+ /**
+ * @return {OKEXChainClient}
+ */
+ async setAccountInfoByWallet(address) {
+ if (!address) throw new Error("invalid wallet connect address: " + address);
+ if (address === this.address) return this
+ this.address = address
+ const data = await this.getAccount(address)
+ this.account_number = this.getAccountNumberFromAccountInfo(data)
+ return this
+ }
/**
* Send SendTransaction.
@@ -283,7 +301,7 @@ export class OKEXChainClient {
return await tx.sign(this.signer, signMsg, this.address);
}
else {
- return tx.sign(this.privateKey, signMsg)
+ return this.privateKey ? tx.sign(this.privateKey, signMsg) : tx.signByWallet(signMsg)
}
}
diff --git a/src/crypto/index.js b/src/crypto/index.js
index b758fdb..4d0337f 100644
--- a/src/crypto/index.js
+++ b/src/crypto/index.js
@@ -77,11 +77,21 @@ export const encodeAddressToBech32 = (hexAddr, prefix = "okexchain") => {
function buf2hex(buffer) { // buffer is an ArrayBuffer
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}
+
+/**
+ * covert okexchain address to 0x address
+ * @param bech32Address
+ * @returns {String}
+ */
export const convertBech32ToHex = (bech32Address) => {
const address = decodeAddressToBuffer(bech32Address)
return toChecksumAddress("0x"+buf2hex(address))
}
-
+/**
+ * covert 0x address to okexchain address
+ * @param hexAddress
+ * @returns {string}
+ */
export const convertHexToBech32 = (hexAddress) => {
return encodeAddressToBech32(hexAddress.toLowerCase())
}
diff --git a/src/index.js b/src/index.js
index 583b1ab..fa7c6df 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,8 +1,11 @@
import "babel-polyfill"
import * as client from "./client"
import * as crypto from "./crypto"
+import * as wallet from "./wallet"
const { OKEXChainClient } = client
module.exports = OKEXChainClient
-module.exports.crypto = crypto
+module.exports.crypto = crypto;
+module.exports.wallet = wallet;
+
diff --git a/src/transaction.js b/src/transaction.js
index 3081ed2..799acf1 100644
--- a/src/transaction.js
+++ b/src/transaction.js
@@ -1,5 +1,5 @@
import * as crypto from "./crypto/"
-
+import * as wallet from "./wallet"
/**
* Transaction
@@ -67,6 +67,33 @@ class Transaction {
return this
}
+ /**
+ * @param {Object} msg
+ * @return {Transaction}
+ **/
+ async signByWallet(msg) {
+
+ const signMsg = {
+ to: '',
+ symbol: 'OKT',
+ memo: this.memo,
+ // contractAddress:'',
+ decimalNum: '0',
+ accountNumber:this.account_number.toString(),
+ sequenceNumber:this.sequence.toString(),
+ value: '0',
+ gasLimit: this.fee.gas,
+ gasPrice: this.fee.amount[0].amount,
+ data: JSON.stringify(msg)
+ }
+
+ console.log("signmsg: ",JSON.stringify(signMsg))
+
+ this.signatures = await wallet.sign(signMsg);
+
+ return this
+ }
+
/**
* @param {string} mode
* @return {Object}
diff --git a/src/wallet/connector.js b/src/wallet/connector.js
new file mode 100644
index 0000000..04acc20
--- /dev/null
+++ b/src/wallet/connector.js
@@ -0,0 +1,210 @@
+import WalletConnect from '@walletconnect/client';
+
+const GET_ACCOUNTS = {
+ jsonrpc: '2.0',
+ method: 'get_accounts'
+};
+
+const GET_SIGN = {
+ jsonrpc: '2.0',
+ method: 'okt_signTransaction'
+};
+
+const OKEXCHAIN = 'okexchain';
+
+// const DURING = 5000;
+
+class Connector {
+
+ constructor() {
+ this.resetConnector();
+ }
+
+ resetConnector() {
+ if(this.interval) clearInterval(this.interval);
+ this.walletConnector = null;
+ this.account = null;
+ this.address = '';
+ this.interval = null;
+ this.callback = {};
+ }
+
+ handleConnect(accounts) {
+ this.account = accounts[0];
+ }
+
+ async onConnect(payload) {
+ try {
+ await this.getAccounts();
+ const { accounts } = payload.params[0];
+ this.handleConnect(accounts);
+ if(!this.address) throw new Error;
+ this.doCallback('success',{address: this.address});
+ } catch {
+ this.doCallback('error');
+ }
+ }
+
+ onDisconnect() {
+ this.killSession();
+ }
+
+ async getAccounts() {
+ const walletConnector = this.walletConnector;
+ if(!walletConnector) return '';
+ // this.startTimer();
+ return new Promise((resolve,reject) => {
+ let address = '';
+ // let timer = setTimeout(() => {
+ // if(!address) {
+ // console.log('获取address超时,将断开链接');
+ // this.killSession();
+ // }
+ // }, DURING);
+ const params = {...GET_ACCOUNTS, id: Date.now()};
+ console.log('get address params: ' + JSON.stringify(params));
+ walletConnector.sendCustomRequest(params).then((res) => {
+ const okexchainAccount = res.find((account) => {
+ return account.address.startsWith(OKEXCHAIN);
+ });
+ if (okexchainAccount) {
+ address = okexchainAccount.address;
+ this.address = address;
+ }
+ if(!address) throw new Error('get address failed');
+ resolve(this.address);
+ }).catch(err => {
+ // console.log('获取address失败,将断开链接');
+ // this.killSession();
+ reject(err);
+ }).finally(() => {
+ // clearTimeout(timer);
+ });
+ });
+ }
+
+ async startTimer() {
+ if(this.startTimer.interval) return;
+ this.startTimer.interval = setInterval(() => {
+ console.log('get address');
+ this.getAccounts();
+ }, DURING);
+ }
+
+ async subscribeToEvents() {
+ const walletConnector = this.walletConnector;
+ if (!walletConnector) {
+ return;
+ }
+ walletConnector.on('call_request', (error, payload) => {
+ console.log('call_request', payload, error);
+ if (error) {
+ throw error;
+ }
+ });
+
+ walletConnector.on('connect', (error, payload) => {
+ console.log('connect', payload);
+ if (error) {
+ throw error;
+ }
+ this.onConnect(payload);
+ });
+
+ walletConnector.on('disconnect', (error, payload) => {
+ console.log('disconnect', payload);
+ this.onDisconnect();
+ if (error) {
+ throw error;
+ }
+ });
+
+ walletConnector.on('session_request',(error, payload) => {
+ console.log('session_request', payload);
+ if (error) {
+ throw error;
+ }
+ });
+
+ if (walletConnector.connected) {
+ const { accounts } = walletConnector;
+ this.handleConnect(accounts);
+ }
+ }
+
+ async createSession() {
+ const walletConnector = this.walletConnector;
+ if(!walletConnector) return;
+ await walletConnector.createSession();
+ }
+
+ async walletConnectInit() {
+ const bridge = 'wss://bridge.walletconnect.org';
+ const walletConnector = new WalletConnect({ bridge });
+ walletConnector._clientMeta.name = 'ΟKEx DEX';
+ walletConnector._clientMeta.url = walletConnector._clientMeta.url.replace(/okex/i,'οkex');
+ this.walletConnector = walletConnector;
+
+ this.subscribeToEvents();
+
+ if (!walletConnector.connected || !walletConnector.uri) {
+ console.log('create session');
+ await this.createSession();
+ } else {
+ await this.getAccounts();
+ }
+ }
+
+ killSession(callback) {
+ const walletConnector = this.walletConnector;
+ if (walletConnector && walletConnector.connected) {
+ walletConnector.killSession();
+ }
+ if(callback) callback();
+ else this.doCallback('sessionCancel');
+ this.resetConnector();
+ }
+
+ setCallback(callback={}) {
+ this.callback = callback;
+ }
+
+ doCallback(type,params) {
+ if(typeof this.callback[type] === 'function' )this.callback[type](params);
+ }
+
+ async getSession(callback) {
+ this.setCallback(callback);
+ let session = '';
+ try {
+ if(!this.walletConnector || !this.walletConnector.uri) {
+ await this.walletConnectInit();
+ }
+ session = this.walletConnector.uri;
+ } finally {
+ if(!session) {
+ console.log('初始链接失败')
+ this.killSession();
+ }
+ else this.doCallback('sessionSuccess');
+ }
+ return session;
+ }
+
+ async sign(signMsg) {
+ return new Promise((resolve,reject) => {
+ const params = {...GET_SIGN,params:[signMsg],id:Date.now()};
+ console.log('发送签名数据',JSON.stringify(params));
+ this.walletConnector.sendCustomRequest(params).then((res) => {
+ res = JSON.parse(res);
+ console.log(res);
+ resolve(res.tx.signatures);
+ }).catch(err => {
+ console.log('签名失败')
+ reject(err);
+ });
+ });
+ }
+}
+
+export default new Connector();
diff --git a/src/wallet/index.js b/src/wallet/index.js
new file mode 100644
index 0000000..22390f4
--- /dev/null
+++ b/src/wallet/index.js
@@ -0,0 +1,29 @@
+import connector from './connector';
+
+/**
+ * {sessionSuccess,sessionFail,sessionCancel,success,error}
+ * @param {*} callbacks
+ */
+export function getSession(callback={}) {
+ return connector.getSession(callback);
+}
+
+export function killSession() {
+ return connector.killSession();
+}
+
+export async function getAddress() {
+ let address = connector.address;
+ try {
+ if(!address) address = await connector.getAccounts();
+ } catch {
+ console.log('get address fail');
+ }
+ return address;
+}
+
+export function sign(signMsg) {
+ return connector.sign(signMsg);
+}
+
+