@leofcoin/peernet 0.11.24 → 0.11.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/peernet.js +1861 -1847
- package/dist/commonjs/dht-response.js +2 -9
- package/dist/commonjs/dht.js +2 -9
- package/dist/commonjs/{http-b45d1330.js → http-78686629.js} +1 -1
- package/dist/commonjs/peernet-message.js +2 -9
- package/dist/commonjs/peernet.js +15 -20
- package/dist/commonjs/request.js +2 -9
- package/dist/commonjs/response.js +2 -9
- package/dist/module/peernet.js +6 -542
- package/package.json +2 -1
- package/rollup.config.js +2 -2
- package/src/handlers/message.js +1 -1
- package/src/messages/chat-message.js +2 -2
- package/src/messages/data-response.js +2 -2
- package/src/messages/data.js +2 -2
- package/src/messages/dht-response.js +2 -2
- package/src/messages/dht.js +2 -2
- package/src/messages/peer-response.js +2 -2
- package/src/messages/peer.js +2 -2
- package/src/messages/peernet-message.js +2 -2
- package/src/messages/ps.js +2 -2
- package/src/messages/request.js +2 -2
- package/src/messages/response.js +2 -2
- package/src/peernet.js +1 -2
- package/src/utils/utils.js +2 -1
- package/dist/commonjs/codec-45796010.js +0 -215
- package/dist/commonjs/codec-format-interface.js +0 -206
- package/dist/commonjs/codec.js +0 -11
- package/dist/commonjs/hash.js +0 -164
- package/src/codec/codec-format-interface.js +0 -194
- package/src/codec/codec.js +0 -124
- package/src/codec/codecs.js +0 -79
- package/src/hash/hash.js +0 -152
package/dist/browser/peernet.js
CHANGED
|
@@ -13,17 +13,15 @@ __webpack_require__(307);
|
|
|
13
13
|
var pako = __webpack_require__(9591);
|
|
14
14
|
var LeofcoinStorage = __webpack_require__(1116);
|
|
15
15
|
var protons = __webpack_require__(7160);
|
|
16
|
-
var
|
|
17
|
-
var bs58 = __webpack_require__(158);
|
|
18
|
-
var isHex = __webpack_require__(6187);
|
|
19
|
-
var varint = __webpack_require__(4676);
|
|
20
|
-
var createKeccakHash = __webpack_require__(5811);
|
|
16
|
+
var codecFormatInterface = __webpack_require__(5698);
|
|
21
17
|
var MultiWallet$1 = __webpack_require__(9755);
|
|
22
18
|
var bs58check = __webpack_require__(8334);
|
|
23
19
|
var bip32 = __webpack_require__(7786);
|
|
20
|
+
var createKeccakHash = __webpack_require__(5811);
|
|
24
21
|
var ecc = __webpack_require__(5892);
|
|
25
22
|
var Mnemonic = __webpack_require__(4911);
|
|
26
23
|
var MultiSignature = __webpack_require__(6697);
|
|
24
|
+
var varint = __webpack_require__(4676);
|
|
27
25
|
var randombytes = __webpack_require__(1798);
|
|
28
26
|
|
|
29
27
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
@@ -49,18 +47,15 @@ function _interopNamespace(e) {
|
|
|
49
47
|
var pako__default = /*#__PURE__*/_interopDefaultLegacy(pako);
|
|
50
48
|
var LeofcoinStorage__default = /*#__PURE__*/_interopDefaultLegacy(LeofcoinStorage);
|
|
51
49
|
var protons__default = /*#__PURE__*/_interopDefaultLegacy(protons);
|
|
52
|
-
var bs32__default = /*#__PURE__*/_interopDefaultLegacy(bs32);
|
|
53
|
-
var bs58__default = /*#__PURE__*/_interopDefaultLegacy(bs58);
|
|
54
|
-
var isHex__default = /*#__PURE__*/_interopDefaultLegacy(isHex);
|
|
55
|
-
var varint__default = /*#__PURE__*/_interopDefaultLegacy(varint);
|
|
56
|
-
var createKeccakHash__default = /*#__PURE__*/_interopDefaultLegacy(createKeccakHash);
|
|
57
50
|
var MultiWallet__default = /*#__PURE__*/_interopDefaultLegacy(MultiWallet$1);
|
|
58
51
|
var bs58check__default = /*#__PURE__*/_interopDefaultLegacy(bs58check);
|
|
59
52
|
var bs58check__namespace = /*#__PURE__*/_interopNamespace(bs58check);
|
|
60
53
|
var bip32__namespace = /*#__PURE__*/_interopNamespace(bip32);
|
|
54
|
+
var createKeccakHash__default = /*#__PURE__*/_interopDefaultLegacy(createKeccakHash);
|
|
61
55
|
var ecc__default = /*#__PURE__*/_interopDefaultLegacy(ecc);
|
|
62
56
|
var Mnemonic__default = /*#__PURE__*/_interopDefaultLegacy(Mnemonic);
|
|
63
57
|
var MultiSignature__default = /*#__PURE__*/_interopDefaultLegacy(MultiSignature);
|
|
58
|
+
var varint__default = /*#__PURE__*/_interopDefaultLegacy(varint);
|
|
64
59
|
var randombytes__default = /*#__PURE__*/_interopDefaultLegacy(randombytes);
|
|
65
60
|
|
|
66
61
|
/* socket-request-client version 1.6.3 */
|
|
@@ -771,1425 +766,891 @@ message PeernetMessage {
|
|
|
771
766
|
optional string id = 5;
|
|
772
767
|
}`;
|
|
773
768
|
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
codec: parseInt('30', 16),
|
|
778
|
-
hashAlg: 'dbl-keccak-256', // ,
|
|
779
|
-
// testnet: 'olivia'
|
|
780
|
-
},
|
|
781
|
-
'peernet-peer-response': {
|
|
782
|
-
codec: parseInt('707072', 16),
|
|
783
|
-
hashAlg: 'keccak-256',
|
|
784
|
-
},
|
|
785
|
-
'peernet-peer': {
|
|
786
|
-
codec: parseInt('7070', 16),
|
|
787
|
-
hashAlg: 'keccak-256',
|
|
788
|
-
},
|
|
789
|
-
'peernet-dht': {
|
|
790
|
-
codec: parseInt('706468', 16),
|
|
791
|
-
hashAlg: 'keccak-256',
|
|
792
|
-
},
|
|
793
|
-
'peernet-dht-response': {
|
|
794
|
-
codec: parseInt('706472', 16),
|
|
795
|
-
hashAlg: 'keccak-256',
|
|
796
|
-
},
|
|
797
|
-
// data
|
|
798
|
-
'peernet-data': {
|
|
799
|
-
codec: parseInt('706461', 16),
|
|
800
|
-
hashAlg: 'keccak-256',
|
|
801
|
-
},
|
|
802
|
-
'peernet-data-response': {
|
|
803
|
-
codec: parseInt('70646172', 16),
|
|
804
|
-
hashAlg: 'keccak-256',
|
|
805
|
-
},
|
|
806
|
-
// message
|
|
807
|
-
'peernet-message': {
|
|
808
|
-
codec: parseInt('706d65', 16),
|
|
809
|
-
hashAlg: 'keccak-256',
|
|
810
|
-
},
|
|
811
|
-
// pubsub
|
|
812
|
-
'peernet-ps': {
|
|
813
|
-
codec: parseInt('707073', 16),
|
|
814
|
-
hashAlg: 'keccak-256',
|
|
815
|
-
},
|
|
816
|
-
'peernet-response': {
|
|
817
|
-
codec: parseInt('7072', 16),
|
|
818
|
-
hashAlg: 'keccak-256',
|
|
819
|
-
},
|
|
820
|
-
'peernet-request': {
|
|
821
|
-
codec: parseInt('707271', 16),
|
|
822
|
-
hashAlg: 'keccak-256',
|
|
823
|
-
},
|
|
824
|
-
// normal block
|
|
825
|
-
'leofcoin-block': {
|
|
826
|
-
codec: parseInt('6c62', 16),
|
|
827
|
-
hashAlg: 'dbl-keccak-512', // ,
|
|
828
|
-
// testnet: 'olivia'
|
|
829
|
-
},
|
|
830
|
-
'leofcoin-tx': {
|
|
831
|
-
codec: parseInt('6c74', 16),
|
|
832
|
-
hashAlg: 'dbl-keccak-512', // ,
|
|
833
|
-
// testnet: 'olivia'
|
|
834
|
-
},
|
|
835
|
-
// itx
|
|
836
|
-
'leofcoin-itx': {
|
|
837
|
-
codec: parseInt('6c69', 16),
|
|
838
|
-
hashAlg: 'keccak-512', // ,
|
|
839
|
-
// testnet: 'olivia'
|
|
840
|
-
},
|
|
841
|
-
// peer reputation
|
|
842
|
-
'leofcoin-pr': {
|
|
843
|
-
codec: parseInt('6c70', 16),
|
|
844
|
-
hashAlg: 'keccak-256', // ,
|
|
845
|
-
// testnet: 'olivia'
|
|
846
|
-
},
|
|
847
|
-
// chat message
|
|
848
|
-
'chat-message': {
|
|
849
|
-
codec: parseInt('636d', 16),
|
|
850
|
-
hashAlg: 'dbl-keccak-256',
|
|
851
|
-
},
|
|
852
|
-
};
|
|
853
|
-
|
|
854
|
-
class PeernetCodec {
|
|
855
|
-
get codecs() {
|
|
856
|
-
return {...globalThis.peernet.codecs, ...codecs}
|
|
769
|
+
class PeernetMessage extends codecFormatInterface.FormatInterface {
|
|
770
|
+
get keys() {
|
|
771
|
+
return ['data', 'signature', 'from', 'to', 'id']
|
|
857
772
|
}
|
|
858
|
-
constructor(buffer) {
|
|
859
|
-
if (buffer) {
|
|
860
|
-
if (buffer instanceof Uint8Array) {
|
|
861
|
-
const codec = varint__default["default"].decode(buffer);
|
|
862
|
-
const name = this.getCodecName(codec);
|
|
863
|
-
if (name) {
|
|
864
|
-
this.name = name;
|
|
865
|
-
this.encoded = buffer;
|
|
866
|
-
this.decode(buffer);
|
|
867
|
-
} else {
|
|
868
|
-
this.encode(buffer);
|
|
869
|
-
}
|
|
870
|
-
} else if (buffer instanceof ArrayBuffer) {
|
|
871
|
-
const encoded = new Uint8Array(buffer.byteLength);
|
|
872
773
|
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
this.encoded = encoded;
|
|
877
|
-
// this.encoded = new Uint8Array(buffer, buffer.byteOffset, buffer.byteLength)
|
|
878
|
-
this.decode(buffer);
|
|
879
|
-
return
|
|
880
|
-
}
|
|
881
|
-
if (typeof buffer === 'string') {
|
|
882
|
-
if (this.codecs[buffer]) this.fromName(buffer);
|
|
883
|
-
else if (isHex__default["default"](buffer)) this.fromHex(buffer);
|
|
884
|
-
else if (bs32__default["default"].isBase32(buffer)) this.fromBs32(buffer);
|
|
885
|
-
else if (bs58__default["default"].isBase58(buffer)) this.fromBs58(buffer);
|
|
886
|
-
else throw new Error(`unsupported string ${buffer}`)
|
|
887
|
-
}
|
|
888
|
-
if (!isNaN(buffer)) if (this.codecs[this.getCodecName(buffer)]) this.fromCodec(buffer);
|
|
889
|
-
}
|
|
774
|
+
constructor(buffer) {
|
|
775
|
+
const name = 'peernet-message';
|
|
776
|
+
super(buffer, protons__default["default"](proto$a).PeernetMessage, {name});
|
|
890
777
|
}
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
var proto$9 = `
|
|
781
|
+
// PeernetDHTMessage
|
|
782
|
+
message PeernetDHTMessage {
|
|
783
|
+
required string hash = 1;
|
|
784
|
+
optional string store = 2;
|
|
785
|
+
}
|
|
786
|
+
`;
|
|
787
|
+
|
|
788
|
+
/**
|
|
789
|
+
* @example `
|
|
790
|
+
new DHTMessage(hash, store)
|
|
791
|
+
// store = optional if not set, peernet checks every store
|
|
792
|
+
let message = new DHTMessage('hashmvbs124xcfd...', 'transaction')
|
|
793
|
+
message = new DHTMessage('hashmvbs124xcfd...', 'block')
|
|
794
|
+
`
|
|
795
|
+
*/
|
|
796
|
+
class DHTMessage extends codecFormatInterface.FormatInterface {
|
|
797
|
+
/**
|
|
798
|
+
*
|
|
799
|
+
*/
|
|
800
|
+
get keys() {
|
|
801
|
+
return ['hash', 'store']
|
|
898
802
|
}
|
|
899
803
|
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
804
|
+
constructor(data) {
|
|
805
|
+
const name = 'peernet-dht';
|
|
806
|
+
super(data, protons__default["default"](proto$9).PeernetDHTMessage, {name});
|
|
903
807
|
}
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
var proto$8 = `
|
|
811
|
+
// PeernetDHTMessageResponse
|
|
812
|
+
message PeernetDHTMessageResponse {
|
|
813
|
+
required string hash = 1;
|
|
814
|
+
required bool has = 2;
|
|
815
|
+
}
|
|
816
|
+
`;
|
|
817
|
+
|
|
818
|
+
class DHTMessageResponse extends codecFormatInterface.FormatInterface {
|
|
819
|
+
get keys() {
|
|
820
|
+
return ['hash', 'has']
|
|
908
821
|
}
|
|
909
822
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
823
|
+
constructor(data) {
|
|
824
|
+
const name = 'peernet-dht-response';
|
|
825
|
+
super(data, protons__default["default"](proto$8).PeernetDHTMessageResponse, {name});
|
|
913
826
|
}
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
var proto$7 = `
|
|
830
|
+
// PeernetDataMessage
|
|
831
|
+
message PeernetDataMessage {
|
|
832
|
+
required string hash = 1;
|
|
833
|
+
optional string store = 2;
|
|
834
|
+
}
|
|
835
|
+
`;
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* @extends {CodecFormat}
|
|
839
|
+
*/
|
|
840
|
+
class DataMessage extends codecFormatInterface.FormatInterface {
|
|
841
|
+
get keys() {
|
|
842
|
+
return ['hash', 'store']
|
|
917
843
|
}
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
else return p;
|
|
924
|
-
}, undefined)
|
|
844
|
+
/**
|
|
845
|
+
* @param {Buffer|String|Object|DataMessage} data - The data needed to create the DataMessage
|
|
846
|
+
*/
|
|
847
|
+
constructor(data) {
|
|
848
|
+
super(data, protons__default["default"](proto$7).PeernetDataMessage, {name: 'peernet-data'});
|
|
925
849
|
}
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
var proto$6 = `
|
|
853
|
+
// PsMessage
|
|
854
|
+
message PsMessage {
|
|
855
|
+
required bytes data = 1;
|
|
856
|
+
required bytes topic = 2;
|
|
857
|
+
}`;
|
|
858
|
+
|
|
859
|
+
class PsMessage extends codecFormatInterface.FormatInterface {
|
|
860
|
+
get keys() {
|
|
861
|
+
return ['data', 'topic']
|
|
929
862
|
}
|
|
930
863
|
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
this.codec = this.getCodec(this.name);
|
|
936
|
-
this.codecBuffer = varint__default["default"].encode(codec);
|
|
864
|
+
constructor(buffer) {
|
|
865
|
+
const name = 'peernet-ps';
|
|
866
|
+
super(buffer, protons__default["default"](proto$6).PsMessage, {name});
|
|
937
867
|
}
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
var proto$5 = `
|
|
871
|
+
// PeernetPeerMessage
|
|
872
|
+
message PeernetPeerMessage {
|
|
873
|
+
required string id = 1;
|
|
874
|
+
}
|
|
875
|
+
`;
|
|
876
|
+
|
|
877
|
+
class PeerMessage extends codecFormatInterface.FormatInterface {
|
|
878
|
+
get keys() {
|
|
879
|
+
return ['id']
|
|
945
880
|
}
|
|
946
881
|
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
882
|
+
constructor(data) {
|
|
883
|
+
const name = 'peernet-peer';
|
|
884
|
+
super(data, protons__default["default"](proto$5).PeernetPeerMessage, {name});
|
|
950
885
|
}
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
var proto$4 = `
|
|
889
|
+
// PeernetRequestMessage
|
|
890
|
+
message PeernetRequestMessage {
|
|
891
|
+
required string request = 1;
|
|
892
|
+
}
|
|
893
|
+
`;
|
|
894
|
+
|
|
895
|
+
class RequestMessage extends codecFormatInterface.FormatInterface {
|
|
896
|
+
get keys() {
|
|
897
|
+
return ['request']
|
|
955
898
|
}
|
|
956
899
|
|
|
957
|
-
|
|
958
|
-
|
|
900
|
+
constructor(data) {
|
|
901
|
+
const name = 'peernet-request';
|
|
902
|
+
super(data, protons__default["default"](proto$4).PeernetRequestMessage, {name});
|
|
959
903
|
}
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
var proto$3 = `
|
|
907
|
+
// PeernetResponseMessage
|
|
908
|
+
message PeernetResponseMessage {
|
|
909
|
+
required bytes response = 1;
|
|
910
|
+
}
|
|
911
|
+
`;
|
|
912
|
+
|
|
913
|
+
class ResponseMessage extends codecFormatInterface.FormatInterface {
|
|
914
|
+
get keys() {
|
|
915
|
+
return ['response']
|
|
964
916
|
}
|
|
965
917
|
|
|
966
|
-
|
|
967
|
-
const
|
|
968
|
-
|
|
969
|
-
return this.encoded
|
|
918
|
+
constructor(data) {
|
|
919
|
+
const name = 'peernet-response';
|
|
920
|
+
super(data, protons__default["default"](proto$3).PeernetResponseMessage, {name});
|
|
970
921
|
}
|
|
971
922
|
}
|
|
972
923
|
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
if (name) {
|
|
984
|
-
this.name = name;
|
|
985
|
-
this.decode(buffer);
|
|
986
|
-
} else {
|
|
987
|
-
this.encode(buffer);
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
if (typeof buffer === 'string') {
|
|
992
|
-
if (isHex__default["default"](buffer)) this.fromHex(buffer);
|
|
993
|
-
if (bs32__default["default"].isBase32(buffer)) this.fromBs32(buffer);
|
|
994
|
-
else if (bs58__default["default"].isBase58(buffer)) this.fromBs58(buffer);
|
|
995
|
-
else throw new Error(`unsupported string ${buffer}`)
|
|
996
|
-
} else if (typeof buffer === 'object') this.fromJSON(buffer);
|
|
997
|
-
}
|
|
924
|
+
var proto$2 = `
|
|
925
|
+
// PeernetPeerMessageResponse
|
|
926
|
+
message PeernetPeerMessageResponse {
|
|
927
|
+
required string id = 1;
|
|
928
|
+
}
|
|
929
|
+
`;
|
|
930
|
+
|
|
931
|
+
class PeerMessageResponse extends codecFormatInterface.FormatInterface {
|
|
932
|
+
get keys() {
|
|
933
|
+
return ['id']
|
|
998
934
|
}
|
|
999
935
|
|
|
1000
|
-
|
|
1001
|
-
const
|
|
1002
|
-
|
|
1003
|
-
uint8Array.set(length);
|
|
1004
|
-
uint8Array.set(this.discoCodec.codecBuffer, length.length);
|
|
1005
|
-
|
|
1006
|
-
return uint8Array
|
|
936
|
+
constructor(data) {
|
|
937
|
+
const name = 'peernet-peer-response';
|
|
938
|
+
super(data, protons__default["default"](proto$2).PeernetPeerMessageResponse, {name});
|
|
1007
939
|
}
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
var proto$1 = `
|
|
943
|
+
// PeernetDataMessageResponse
|
|
944
|
+
message PeernetDataMessageResponse {
|
|
945
|
+
required string hash = 1;
|
|
946
|
+
required bytes data = 2;
|
|
947
|
+
}
|
|
948
|
+
`;
|
|
949
|
+
|
|
950
|
+
class DataMessageResponse extends codecFormatInterface.FormatInterface {
|
|
951
|
+
get keys() {
|
|
952
|
+
return ['hash', 'data']
|
|
1011
953
|
}
|
|
1012
954
|
|
|
1013
|
-
|
|
1014
|
-
|
|
955
|
+
constructor(data) {
|
|
956
|
+
const name = 'peernet-data-response';
|
|
957
|
+
super(data, protons__default["default"](proto$1).PeernetDataMessageResponse, {name});
|
|
1015
958
|
}
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
var proto = `
|
|
962
|
+
message ChatMessage {
|
|
963
|
+
required string value = 1;
|
|
964
|
+
required string author = 2;
|
|
965
|
+
required uint64 timestamp = 3;
|
|
966
|
+
repeated string files = 4;
|
|
967
|
+
}`;
|
|
968
|
+
|
|
969
|
+
class ChatMessage extends codecFormatInterface.FormatInterface {
|
|
970
|
+
get keys() {
|
|
971
|
+
return ['author', 'value', 'timestamp', 'files']
|
|
1019
972
|
}
|
|
1020
973
|
|
|
1021
|
-
|
|
1022
|
-
|
|
974
|
+
constructor(buffer) {
|
|
975
|
+
const name = 'chat-message';
|
|
976
|
+
super(buffer, protons__default["default"](proto).ChatMessage, {name});
|
|
1023
977
|
}
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
const protoFor = (data) => {
|
|
981
|
+
if (!Buffer.isBuffer(data)) data = Buffer.from(data);
|
|
982
|
+
const codec = new codecFormatInterface.Codec(data);
|
|
983
|
+
if (!codec.name) throw new Error('proto not found')
|
|
984
|
+
const Proto = globalThis.peernet.protos[codec.name];
|
|
985
|
+
if (!Proto) throw (new Error(`No proto defined for ${codec.name}`))
|
|
986
|
+
return new Proto(data)
|
|
987
|
+
};
|
|
1024
988
|
|
|
1025
|
-
|
|
1026
|
-
|
|
989
|
+
/**
|
|
990
|
+
* wether or not a peernet daemon is active
|
|
991
|
+
* @return {Boolean}
|
|
992
|
+
*/
|
|
993
|
+
const hasDaemon = async () => {
|
|
994
|
+
try {
|
|
995
|
+
let response = await fetch('http://127.0.0.1:1000/api/version');
|
|
996
|
+
response = await response.json();
|
|
997
|
+
return Boolean(response.client === '@peernet/api/http')
|
|
998
|
+
} catch (e) {
|
|
999
|
+
return false
|
|
1027
1000
|
}
|
|
1001
|
+
};
|
|
1028
1002
|
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1003
|
+
const https = () => {
|
|
1004
|
+
if (!globalThis.location) return false;
|
|
1005
|
+
return Boolean(globalThis.location.protocol === 'https:')
|
|
1006
|
+
};
|
|
1032
1007
|
|
|
1033
|
-
|
|
1034
|
-
|
|
1008
|
+
/**
|
|
1009
|
+
* Get current environment
|
|
1010
|
+
* @return {String} current environment [node, electron, browser]
|
|
1011
|
+
*/
|
|
1012
|
+
const environment = () => {
|
|
1013
|
+
const _navigator = globalThis.navigator;
|
|
1014
|
+
if (!_navigator) {
|
|
1015
|
+
return 'node'
|
|
1016
|
+
} else if (_navigator && /electron/i.test(_navigator.userAgent)) {
|
|
1017
|
+
return 'electron'
|
|
1018
|
+
} else {
|
|
1019
|
+
return 'browser'
|
|
1035
1020
|
}
|
|
1021
|
+
};
|
|
1036
1022
|
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1023
|
+
/**
|
|
1024
|
+
* * Get current environment
|
|
1025
|
+
* @return {Object} result
|
|
1026
|
+
* @property {Boolean} reult.daemon whether or not daemon is running
|
|
1027
|
+
* @property {Boolean} reult.environment Current environment
|
|
1028
|
+
*/
|
|
1029
|
+
const target = async () => {
|
|
1030
|
+
let daemon = false;
|
|
1031
|
+
const env = await environment();
|
|
1032
|
+
if (!https()) daemon = await hasDaemon();
|
|
1040
1033
|
|
|
1041
|
-
|
|
1042
|
-
|
|
1034
|
+
return {daemon, environment: env}
|
|
1035
|
+
};
|
|
1036
|
+
|
|
1037
|
+
class PeerDiscovery {
|
|
1038
|
+
constructor(id) {
|
|
1039
|
+
this.id = id;
|
|
1043
1040
|
}
|
|
1044
1041
|
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
}
|
|
1042
|
+
_getPeerId(id) {
|
|
1043
|
+
if (!peernet.peerMap || peernet.peerMap && peernet.peerMap.size === 0) return false
|
|
1048
1044
|
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
this.discoCodec.fromName(this.name);
|
|
1054
|
-
let hashAlg = this.discoCodec.hashAlg;
|
|
1055
|
-
if (hashAlg.includes('dbl')) {
|
|
1056
|
-
hashAlg = hashAlg.replace('dbl-', '');
|
|
1057
|
-
buffer = createKeccakHash__default["default"](hashAlg.replace('-', '')).update(buffer).digest();
|
|
1045
|
+
for (const entry of [...peernet.peerMap.entries()]) {
|
|
1046
|
+
for (const _id of entry[1]) {
|
|
1047
|
+
if (_id === id) return entry[0]
|
|
1048
|
+
}
|
|
1058
1049
|
}
|
|
1059
|
-
|
|
1060
|
-
this.size = this.digest.length;
|
|
1050
|
+
}
|
|
1061
1051
|
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1052
|
+
async discover(peer) {
|
|
1053
|
+
let id = this._getPeerId(peer.id);
|
|
1054
|
+
if (id) return id
|
|
1055
|
+
const data = new peernet.protos['peernet-peer']({id: this.id});
|
|
1056
|
+
const node = await peernet.prepareMessage(peer.id, data.encoded);
|
|
1067
1057
|
|
|
1068
|
-
|
|
1058
|
+
let response = await peer.request(node.encoded);
|
|
1059
|
+
response = protoFor(response);
|
|
1060
|
+
response = new peernet.protos['peernet-peer-response'](response.decoded.data);
|
|
1069
1061
|
|
|
1070
|
-
|
|
1071
|
-
|
|
1062
|
+
id = response.decoded.id;
|
|
1063
|
+
if (id === this.id) return;
|
|
1072
1064
|
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
const
|
|
1076
|
-
if (
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
this.encode(buffer);
|
|
1065
|
+
if (!peernet.peerMap.has(id)) peernet.peerMap.set(id, [peer.id]);
|
|
1066
|
+
else {
|
|
1067
|
+
const connections = peernet.peerMap.get(id);
|
|
1068
|
+
if (connections.indexOf(peer.id) === -1) {
|
|
1069
|
+
connections.push(peer.id);
|
|
1070
|
+
peernet.peerMap.set(peer.id, connections);
|
|
1080
1071
|
}
|
|
1081
1072
|
}
|
|
1082
|
-
|
|
1083
|
-
if (isHex__default["default"](buffer)) this.fromHex(buffer);
|
|
1084
|
-
if (bs32__default["default"].test(buffer)) this.fromBs32(buffer);
|
|
1085
|
-
}
|
|
1086
|
-
if (typeof buffer === 'object') this.fromJSON(buffer);
|
|
1073
|
+
return id
|
|
1087
1074
|
}
|
|
1088
1075
|
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
buffer = buffer.slice(varint__default["default"].decode.bytes);
|
|
1096
|
-
this.size = varint__default["default"].decode(buffer);
|
|
1097
|
-
this.digest = buffer.slice(varint__default["default"].decode.bytes);
|
|
1098
|
-
if (this.digest.length !== this.size) {
|
|
1099
|
-
throw new Error(`hash length inconsistent: 0x${this.hash.toString('hex')}`)
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
// const discoCodec = new Codec(codec, this.codecs)
|
|
1103
|
-
|
|
1104
|
-
this.name = this.discoCodec.name;
|
|
1076
|
+
async discoverHandler(message, peer) {
|
|
1077
|
+
const {id, proto} = message;
|
|
1078
|
+
// if (typeof message.data === 'string') message.data = Buffer.from(message.data)
|
|
1079
|
+
if (proto.name === 'peernet-peer') {
|
|
1080
|
+
const from = proto.decoded.id;
|
|
1081
|
+
if (from === this.id) return;
|
|
1105
1082
|
|
|
1083
|
+
if (!peernet.peerMap.has(from)) peernet.peerMap.set(from, [peer.id]);
|
|
1084
|
+
else {
|
|
1085
|
+
const connections = peernet.peerMap.get(from);
|
|
1086
|
+
if (connections.indexOf(peer.id) === -1) {
|
|
1087
|
+
connections.push(peer.id);
|
|
1088
|
+
peernet.peerMap.set(from, connections);
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
const data = new peernet.protos['peernet-peer-response']({id: this.id});
|
|
1092
|
+
const node = await peernet.prepareMessage(from, data.encoded);
|
|
1106
1093
|
|
|
1107
|
-
|
|
1094
|
+
peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})));
|
|
1095
|
+
} else if (proto.name === 'peernet-peer-response') {
|
|
1096
|
+
const from = proto.decoded.id;
|
|
1097
|
+
if (from === this.id) return;
|
|
1108
1098
|
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1099
|
+
if (!peernet.peerMap.has(from)) peernet.peerMap.set(from, [peer.id]);
|
|
1100
|
+
else {
|
|
1101
|
+
const connections = peernet.peerMap.get(from);
|
|
1102
|
+
if (connections.indexOf(peer.id) === -1) {
|
|
1103
|
+
connections.push(peer.id);
|
|
1104
|
+
peernet.peerMap.set(from, connections);
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1115
1107
|
}
|
|
1116
1108
|
}
|
|
1117
1109
|
}
|
|
1118
1110
|
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
if (isHex__default["default"](buffer)) this.fromHex(buffer);
|
|
1135
|
-
else if (bs32__default["default"].isBase32(buffer)) this.fromBs32(buffer);
|
|
1136
|
-
else if (bs58__default["default"].isBase58(buffer)) this.fromBs58(buffer);
|
|
1137
|
-
else throw new Error(`unsupported string ${buffer}`)
|
|
1138
|
-
} else {
|
|
1139
|
-
this.create(buffer);
|
|
1140
|
-
}
|
|
1141
|
-
}
|
|
1111
|
+
/**
|
|
1112
|
+
* Keep history of fetched address and ptr
|
|
1113
|
+
* @property {Object} address
|
|
1114
|
+
* @property {Object} ptr
|
|
1115
|
+
*/
|
|
1116
|
+
const lastFetched = {
|
|
1117
|
+
address: {
|
|
1118
|
+
value: undefined,
|
|
1119
|
+
timestamp: 0,
|
|
1120
|
+
},
|
|
1121
|
+
ptr: {
|
|
1122
|
+
value: undefined,
|
|
1123
|
+
timestamp: 0,
|
|
1124
|
+
},
|
|
1125
|
+
};
|
|
1142
1126
|
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1127
|
+
const getAddress = async () => {
|
|
1128
|
+
const {address} = lastFetched;
|
|
1129
|
+
const now = Math.round(new Date().getTime() / 1000);
|
|
1130
|
+
if (now - address.timestamp > 1200000) {
|
|
1131
|
+
address.value = await fetch('https://icanhazip.com/');
|
|
1132
|
+
address.value = await address.value.text();
|
|
1133
|
+
address.timestamp = Math.round(new Date().getTime() / 1000);
|
|
1134
|
+
lastFetched.address = address;
|
|
1148
1135
|
}
|
|
1149
1136
|
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
*/
|
|
1153
|
-
get hash() {
|
|
1154
|
-
const upper = this.hashFormat.charAt(0).toUpperCase();
|
|
1155
|
-
const format = `${upper}${this.hashFormat.substring(1, this.hashFormat.length)}`;
|
|
1156
|
-
return this.peernetHash[`to${format}`]()
|
|
1157
|
-
}
|
|
1137
|
+
return address.value
|
|
1138
|
+
};
|
|
1158
1139
|
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
decode() {
|
|
1163
|
-
let encoded = this.encoded;
|
|
1164
|
-
const discoCodec = new PeernetCodec(this.encoded);
|
|
1165
|
-
encoded = encoded.slice(discoCodec.codecBuffer.length);
|
|
1166
|
-
this.name = discoCodec.name;
|
|
1167
|
-
this.decoded = this.protoDecode(encoded);
|
|
1168
|
-
return this.decoded
|
|
1169
|
-
}
|
|
1140
|
+
const degreesToRadians = (degrees) => {
|
|
1141
|
+
return degrees * Math.PI / 180;
|
|
1142
|
+
};
|
|
1170
1143
|
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
*/
|
|
1174
|
-
encode(decoded) {
|
|
1175
|
-
if (!decoded) decoded = this.decoded;
|
|
1176
|
-
const codec = new PeernetCodec(this.name);
|
|
1177
|
-
const encoded = this.protoEncode(decoded);
|
|
1178
|
-
const uint8Array = new Uint8Array(encoded.length + codec.codecBuffer.length);
|
|
1179
|
-
uint8Array.set(codec.codecBuffer);
|
|
1180
|
-
uint8Array.set(encoded, codec.codecBuffer.length);
|
|
1181
|
-
this.encoded = uint8Array;
|
|
1182
|
-
return this.encoded
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
|
-
hasCodec() {
|
|
1186
|
-
if (!this.encoded) return false
|
|
1187
|
-
const codec = new PeernetCodec(this.encoded);
|
|
1188
|
-
if (codec.name) return true
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
fromUint8Array(buffer) {
|
|
1192
|
-
this.encoded = buffer;
|
|
1193
|
-
if (!this.hasCodec()) this.create(
|
|
1194
|
-
JSON.parse(new TextDecoder().decode(this.encoded))
|
|
1195
|
-
);
|
|
1196
|
-
else this.decode();
|
|
1197
|
-
}
|
|
1198
|
-
|
|
1199
|
-
fromArrayBuffer(buffer) {
|
|
1200
|
-
this.encoded = new Uint8Array(buffer, buffer.byteOffset, buffer.byteLength);
|
|
1201
|
-
if (!this.hasCodec()) this.create(
|
|
1202
|
-
JSON.parse(new TextDecoder().decode(this.encoded))
|
|
1203
|
-
);
|
|
1204
|
-
else this.decode();
|
|
1205
|
-
}
|
|
1206
|
-
|
|
1207
|
-
toString() {
|
|
1208
|
-
return this.encoded.toString()
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
async toArray() {
|
|
1212
|
-
const array = [];
|
|
1213
|
-
for await (const value of this.encoded.values()) {
|
|
1214
|
-
array.push(value);
|
|
1215
|
-
}
|
|
1216
|
-
return array
|
|
1217
|
-
}
|
|
1144
|
+
const distanceInKmBetweenEarthCoordinates = (lat1, lon1, lat2, lon2) => {
|
|
1145
|
+
const earthRadiusKm = 6371;
|
|
1218
1146
|
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
this.decode();
|
|
1222
|
-
}
|
|
1147
|
+
const dLat = degreesToRadians(lat2-lat1);
|
|
1148
|
+
const dLon = degreesToRadians(lon2-lon1);
|
|
1223
1149
|
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1150
|
+
lat1 = degreesToRadians(lat1);
|
|
1151
|
+
lat2 = degreesToRadians(lat2);
|
|
1152
|
+
const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
|
|
1153
|
+
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
|
|
1154
|
+
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
|
|
1155
|
+
return earthRadiusKm * c;
|
|
1156
|
+
};
|
|
1228
1157
|
|
|
1158
|
+
class DhtEarth {
|
|
1229
1159
|
/**
|
|
1230
|
-
*
|
|
1160
|
+
*
|
|
1231
1161
|
*/
|
|
1232
|
-
|
|
1233
|
-
this.
|
|
1234
|
-
this.decode();
|
|
1162
|
+
constructor() {
|
|
1163
|
+
this.providerMap = new Map();
|
|
1235
1164
|
}
|
|
1236
1165
|
|
|
1237
1166
|
/**
|
|
1238
|
-
* @param {
|
|
1167
|
+
* @param {Object} address
|
|
1168
|
+
* @return {Object} {latitude: lat, longitude: lon}
|
|
1239
1169
|
*/
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1170
|
+
async getCoordinates(address) {
|
|
1171
|
+
// const {address} = parseAddress(provider)
|
|
1172
|
+
const request = `https://whereis.leofcoin.org/?ip=${address}`;
|
|
1173
|
+
let response = await fetch(request);
|
|
1174
|
+
response = await response.json();
|
|
1175
|
+
const {lat, lon} = response;
|
|
1176
|
+
return {latitude: lat, longitude: lon}
|
|
1243
1177
|
}
|
|
1244
1178
|
|
|
1245
1179
|
/**
|
|
1246
|
-
* @param {
|
|
1180
|
+
* @param {Object} peer
|
|
1181
|
+
* @param {Object} provider
|
|
1182
|
+
* @return {Object} {provider, distance}
|
|
1247
1183
|
*/
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1184
|
+
async getDistance(peer, provider) {
|
|
1185
|
+
const {latitude, longitude} = await this.getCoordinates(provider.address);
|
|
1186
|
+
return {provider, distance: distanceInKmBetweenEarthCoordinates(peer.latitude, peer.longitude, latitude, longitude)}
|
|
1251
1187
|
}
|
|
1252
1188
|
|
|
1253
1189
|
/**
|
|
1254
|
-
* @param {
|
|
1190
|
+
* @param {Array} providers
|
|
1191
|
+
* @return {Object} closestPeer
|
|
1255
1192
|
*/
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1193
|
+
async closestPeer(providers) {
|
|
1194
|
+
let all = [];
|
|
1195
|
+
const address = await getAddress();
|
|
1196
|
+
const peerLoc = await this.getCoordinates(address);
|
|
1260
1197
|
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
if (!this.encoded) this.encode();
|
|
1266
|
-
return this.encoded.toString('hex')
|
|
1267
|
-
}
|
|
1198
|
+
for (const provider of providers) {
|
|
1199
|
+
if (provider.address === '127.0.0.1') all.push({provider, distance: 0});
|
|
1200
|
+
else all.push(this.getDistance(peerLoc, provider));
|
|
1201
|
+
}
|
|
1268
1202
|
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
toBs32() {
|
|
1273
|
-
if (!this.encoded) this.encode();
|
|
1274
|
-
return bs32__default["default"].encode(this.encoded)
|
|
1203
|
+
all = await Promise.all(all);
|
|
1204
|
+
all = all.sort((previous, current) => previous.distance - current.distance);
|
|
1205
|
+
return all[0].provider;
|
|
1275
1206
|
}
|
|
1276
1207
|
|
|
1277
1208
|
/**
|
|
1278
|
-
* @
|
|
1209
|
+
* @param {String} hash
|
|
1210
|
+
* @return {Array} providers
|
|
1279
1211
|
*/
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
return bs58__default["default"].encode(this.encoded)
|
|
1212
|
+
providersFor(hash) {
|
|
1213
|
+
return this.providerMap.get(hash);
|
|
1283
1214
|
}
|
|
1284
1215
|
|
|
1285
1216
|
/**
|
|
1286
|
-
* @param {
|
|
1217
|
+
* @param {String} address
|
|
1218
|
+
* @param {String} hash
|
|
1219
|
+
* @return {Array} providers
|
|
1287
1220
|
*/
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
if (this.
|
|
1291
|
-
for (const key of this.keys) {
|
|
1292
|
-
Object.defineProperties(decoded, {
|
|
1293
|
-
[key]: {
|
|
1294
|
-
enumerable: true,
|
|
1295
|
-
configurable: true,
|
|
1296
|
-
set: (val) => value = data[key],
|
|
1297
|
-
get: () => data[key]
|
|
1298
|
-
}
|
|
1299
|
-
});
|
|
1300
|
-
}
|
|
1301
|
-
|
|
1302
|
-
this.decoded = decoded;
|
|
1303
|
-
this.encode();
|
|
1304
|
-
}
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
|
|
1308
|
-
class PeernetMessage extends FormatInterface {
|
|
1309
|
-
get keys() {
|
|
1310
|
-
return ['data', 'signature', 'from', 'to', 'id']
|
|
1311
|
-
}
|
|
1221
|
+
async addProvider(address, hash) {
|
|
1222
|
+
let providers = [];
|
|
1223
|
+
if (this.providerMap.has(hash)) providers = this.providerMap.get(hash);
|
|
1312
1224
|
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1225
|
+
providers = new Set([...providers, address]);
|
|
1226
|
+
this.providerMap.set(hash, providers);
|
|
1227
|
+
return providers;
|
|
1316
1228
|
}
|
|
1317
1229
|
}
|
|
1318
1230
|
|
|
1319
|
-
var proto$9 = `
|
|
1320
|
-
// PeernetDHTMessage
|
|
1321
|
-
message PeernetDHTMessage {
|
|
1322
|
-
required string hash = 1;
|
|
1323
|
-
optional string store = 2;
|
|
1324
|
-
}
|
|
1325
|
-
`;
|
|
1326
|
-
|
|
1327
1231
|
/**
|
|
1328
|
-
* @
|
|
1329
|
-
|
|
1330
|
-
// store = optional if not set, peernet checks every store
|
|
1331
|
-
let message = new DHTMessage('hashmvbs124xcfd...', 'transaction')
|
|
1332
|
-
message = new DHTMessage('hashmvbs124xcfd...', 'block')
|
|
1333
|
-
`
|
|
1232
|
+
* @params {String} network
|
|
1233
|
+
* @return {object} { identity, accounts, config }
|
|
1334
1234
|
*/
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
}
|
|
1235
|
+
var generateAccount = async network => {
|
|
1236
|
+
let wallet = new MultiWallet__default["default"](network);
|
|
1237
|
+
/**
|
|
1238
|
+
* @type {string}
|
|
1239
|
+
*/
|
|
1240
|
+
const mnemonic = await wallet.generate();
|
|
1342
1241
|
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1242
|
+
wallet = new MultiWallet__default["default"](network);
|
|
1243
|
+
await wallet.recover(mnemonic, network);
|
|
1244
|
+
/**
|
|
1245
|
+
* @type {object}
|
|
1246
|
+
*/
|
|
1247
|
+
const account = wallet.account(0);
|
|
1248
|
+
/**
|
|
1249
|
+
* @type {object}
|
|
1250
|
+
*/
|
|
1251
|
+
const external = account.external(0);
|
|
1252
|
+
const internal = account.internal(0);
|
|
1253
|
+
|
|
1254
|
+
return {
|
|
1255
|
+
identity: {
|
|
1256
|
+
mnemonic,
|
|
1257
|
+
// multiWIF: wallet.export(),
|
|
1258
|
+
publicKey: external.publicKey,
|
|
1259
|
+
privateKey: external.privateKey,
|
|
1260
|
+
walletId: external.id
|
|
1261
|
+
},
|
|
1262
|
+
accounts: [['main account', external.address, internal.address]]
|
|
1263
|
+
// config: {
|
|
1264
|
+
// }
|
|
1265
|
+
}
|
|
1266
|
+
};
|
|
1356
1267
|
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1268
|
+
var testnets = {
|
|
1269
|
+
'leofcoin:olivia': {
|
|
1270
|
+
messagePrefix: '\u0019Leofcoin Signed Message:',
|
|
1271
|
+
pubKeyHash: 0x73, // o
|
|
1272
|
+
scriptHash: 0x76, // p
|
|
1273
|
+
multiTxHash: 0x8b4125, // omtx
|
|
1274
|
+
payments: {
|
|
1275
|
+
version: 0,
|
|
1276
|
+
unspent: 0x1fa443d7 // ounsp
|
|
1277
|
+
},
|
|
1278
|
+
wif: 0x7D, // s
|
|
1279
|
+
multiCodec: 0x7c4,
|
|
1280
|
+
bip32: { public: 0x13BBF2D5, private: 0x13BBCBC5 }
|
|
1281
|
+
},
|
|
1282
|
+
'bitcoin:testnet': {
|
|
1283
|
+
messagePrefix: '\x18Bitcoin Signed Message:\n',
|
|
1284
|
+
bech32: 'tb',
|
|
1285
|
+
pubKeyHash: 0x6f,
|
|
1286
|
+
scriptHash: 0xc4,
|
|
1287
|
+
wif: 0xef,
|
|
1288
|
+
bip32: {
|
|
1289
|
+
public: 0x043587cf,
|
|
1290
|
+
private: 0x04358394
|
|
1291
|
+
}
|
|
1360
1292
|
}
|
|
1361
1293
|
|
|
1362
|
-
|
|
1363
|
-
const name = 'peernet-dht-response';
|
|
1364
|
-
super(data, protons__default["default"](proto$8).PeernetDHTMessageResponse, {name});
|
|
1365
|
-
}
|
|
1366
|
-
}
|
|
1367
|
-
|
|
1368
|
-
var proto$7 = `
|
|
1369
|
-
// PeernetDataMessage
|
|
1370
|
-
message PeernetDataMessage {
|
|
1371
|
-
required string hash = 1;
|
|
1372
|
-
optional string store = 2;
|
|
1373
|
-
}
|
|
1374
|
-
`;
|
|
1294
|
+
};
|
|
1375
1295
|
|
|
1296
|
+
// https://en.bitcoin.it/wiki/List_of_address_prefixes
|
|
1376
1297
|
/**
|
|
1377
|
-
*
|
|
1298
|
+
* Main network
|
|
1299
|
+
* @return {messagePrefix, pubKeyHash, scriptHash, wif, bip32}
|
|
1378
1300
|
*/
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
message PsMessage {
|
|
1394
|
-
required bytes data = 1;
|
|
1395
|
-
required bytes topic = 2;
|
|
1396
|
-
}`;
|
|
1397
|
-
|
|
1398
|
-
class PsMessage extends FormatInterface {
|
|
1399
|
-
get keys() {
|
|
1400
|
-
return ['data', 'topic']
|
|
1401
|
-
}
|
|
1402
|
-
|
|
1403
|
-
constructor(buffer) {
|
|
1404
|
-
const name = 'peernet-ps';
|
|
1405
|
-
super(buffer, protons__default["default"](proto$6).PsMessage, {name});
|
|
1406
|
-
}
|
|
1407
|
-
}
|
|
1408
|
-
|
|
1409
|
-
var proto$5 = `
|
|
1410
|
-
// PeernetPeerMessage
|
|
1411
|
-
message PeernetPeerMessage {
|
|
1412
|
-
required string id = 1;
|
|
1413
|
-
}
|
|
1414
|
-
`;
|
|
1415
|
-
|
|
1416
|
-
class PeerMessage extends FormatInterface {
|
|
1417
|
-
get keys() {
|
|
1418
|
-
return ['id']
|
|
1419
|
-
}
|
|
1420
|
-
|
|
1421
|
-
constructor(data) {
|
|
1422
|
-
const name = 'peernet-peer';
|
|
1423
|
-
super(data, protons__default["default"](proto$5).PeernetPeerMessage, {name});
|
|
1424
|
-
}
|
|
1425
|
-
}
|
|
1426
|
-
|
|
1427
|
-
var proto$4 = `
|
|
1428
|
-
// PeernetRequestMessage
|
|
1429
|
-
message PeernetRequestMessage {
|
|
1430
|
-
required string request = 1;
|
|
1431
|
-
}
|
|
1432
|
-
`;
|
|
1433
|
-
|
|
1434
|
-
class RequestMessage extends FormatInterface {
|
|
1435
|
-
get keys() {
|
|
1436
|
-
return ['request']
|
|
1437
|
-
}
|
|
1438
|
-
|
|
1439
|
-
constructor(data) {
|
|
1440
|
-
const name = 'peernet-request';
|
|
1441
|
-
super(data, protons__default["default"](proto$4).PeernetRequestMessage, {name});
|
|
1442
|
-
}
|
|
1443
|
-
}
|
|
1444
|
-
|
|
1445
|
-
var proto$3 = `
|
|
1446
|
-
// PeernetResponseMessage
|
|
1447
|
-
message PeernetResponseMessage {
|
|
1448
|
-
required bytes response = 1;
|
|
1449
|
-
}
|
|
1450
|
-
`;
|
|
1451
|
-
|
|
1452
|
-
class ResponseMessage extends FormatInterface {
|
|
1453
|
-
get keys() {
|
|
1454
|
-
return ['response']
|
|
1455
|
-
}
|
|
1456
|
-
|
|
1457
|
-
constructor(data) {
|
|
1458
|
-
const name = 'peernet-response';
|
|
1459
|
-
super(data, protons__default["default"](proto$3).PeernetResponseMessage, {name});
|
|
1460
|
-
}
|
|
1461
|
-
}
|
|
1462
|
-
|
|
1463
|
-
var proto$2 = `
|
|
1464
|
-
// PeernetPeerMessageResponse
|
|
1465
|
-
message PeernetPeerMessageResponse {
|
|
1466
|
-
required string id = 1;
|
|
1467
|
-
}
|
|
1468
|
-
`;
|
|
1469
|
-
|
|
1470
|
-
class PeerMessageResponse extends FormatInterface {
|
|
1471
|
-
get keys() {
|
|
1472
|
-
return ['id']
|
|
1473
|
-
}
|
|
1474
|
-
|
|
1475
|
-
constructor(data) {
|
|
1476
|
-
const name = 'peernet-peer-response';
|
|
1477
|
-
super(data, protons__default["default"](proto$2).PeernetPeerMessageResponse, {name});
|
|
1478
|
-
}
|
|
1479
|
-
}
|
|
1480
|
-
|
|
1481
|
-
var proto$1 = `
|
|
1482
|
-
// PeernetDataMessageResponse
|
|
1483
|
-
message PeernetDataMessageResponse {
|
|
1484
|
-
required string hash = 1;
|
|
1485
|
-
required bytes data = 2;
|
|
1486
|
-
}
|
|
1487
|
-
`;
|
|
1488
|
-
|
|
1489
|
-
class DataMessageResponse extends FormatInterface {
|
|
1490
|
-
get keys() {
|
|
1491
|
-
return ['hash', 'data']
|
|
1492
|
-
}
|
|
1493
|
-
|
|
1494
|
-
constructor(data) {
|
|
1495
|
-
const name = 'peernet-data-response';
|
|
1496
|
-
super(data, protons__default["default"](proto$1).PeernetDataMessageResponse, {name});
|
|
1497
|
-
}
|
|
1498
|
-
}
|
|
1499
|
-
|
|
1500
|
-
var proto = `
|
|
1501
|
-
message ChatMessage {
|
|
1502
|
-
required string value = 1;
|
|
1503
|
-
required string author = 2;
|
|
1504
|
-
required uint64 timestamp = 3;
|
|
1505
|
-
repeated string files = 4;
|
|
1506
|
-
}`;
|
|
1507
|
-
|
|
1508
|
-
class ChatMessage extends FormatInterface {
|
|
1509
|
-
get keys() {
|
|
1510
|
-
return ['author', 'value', 'timestamp', 'files']
|
|
1511
|
-
}
|
|
1512
|
-
|
|
1513
|
-
constructor(buffer) {
|
|
1514
|
-
const name = 'chat-message';
|
|
1515
|
-
super(buffer, protons__default["default"](proto).ChatMessage, {name});
|
|
1516
|
-
}
|
|
1517
|
-
}
|
|
1518
|
-
|
|
1519
|
-
const protoFor = (data) => {
|
|
1520
|
-
if (!Buffer.isBuffer(data)) data = Buffer.from(data);
|
|
1521
|
-
const codec = new PeernetCodec(data);
|
|
1522
|
-
if (!codec.name) throw new Error('proto not found')
|
|
1523
|
-
const Proto = globalThis.peernet.protos[codec.name];
|
|
1524
|
-
if (!Proto) throw (new Error(`No proto defined for ${codec.name}`))
|
|
1525
|
-
return new Proto(data)
|
|
1301
|
+
const leofcoin = {
|
|
1302
|
+
messagePrefix: '\u0019Leofcoin Signed Message:',
|
|
1303
|
+
pubKeyHash: 0x30, // L
|
|
1304
|
+
scriptHash: 0x37, // P
|
|
1305
|
+
multiTxHash: 0x3adeed, // Lmtx
|
|
1306
|
+
payments: {
|
|
1307
|
+
version: 0,
|
|
1308
|
+
unspent: 0x0d6e0327 // Lunsp
|
|
1309
|
+
},
|
|
1310
|
+
coin_type: 640,
|
|
1311
|
+
wif: 0x3F, // S
|
|
1312
|
+
multiCodec: 0x3c4,
|
|
1313
|
+
bip32: { public: 0x13BBF2D4, private: 0x13BBCBC4 },
|
|
1314
|
+
testnet: testnets['leofcoin:olivia']
|
|
1526
1315
|
};
|
|
1527
1316
|
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1317
|
+
const bitcoin = {
|
|
1318
|
+
messagePrefix: '\x18Bitcoin Signed Message:\n',
|
|
1319
|
+
bech32: 'bc',
|
|
1320
|
+
pubKeyHash: 0x00,
|
|
1321
|
+
multiCodec: 0x00,
|
|
1322
|
+
scriptHash: 0x05,
|
|
1323
|
+
wif: 0x80,
|
|
1324
|
+
coin_type: 0,
|
|
1325
|
+
bip32: {
|
|
1326
|
+
public: 0x0488b21e, private: 0x0488ade4
|
|
1327
|
+
},
|
|
1328
|
+
testnet: testnets['bitcoin:testnet']
|
|
1540
1329
|
};
|
|
1541
1330
|
|
|
1542
|
-
const
|
|
1543
|
-
|
|
1544
|
-
|
|
1331
|
+
const litecoin = {
|
|
1332
|
+
messagePrefix: '\x19Litecoin Signed Message:\n',
|
|
1333
|
+
pubKeyHash: 0x30,
|
|
1334
|
+
scriptHash: 0x32,
|
|
1335
|
+
wif: 0xb0,
|
|
1336
|
+
bip32: {
|
|
1337
|
+
public: 0x019da462,
|
|
1338
|
+
private: 0x019d9cfe
|
|
1339
|
+
}
|
|
1545
1340
|
};
|
|
1546
1341
|
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
} else {
|
|
1558
|
-
return 'browser'
|
|
1559
|
-
}
|
|
1342
|
+
const ethereum = {
|
|
1343
|
+
messagePrefix: '\x19Ethereum Signed Message:\n',
|
|
1344
|
+
pubKeyHash: 0x30,
|
|
1345
|
+
scriptHash: 0x32,
|
|
1346
|
+
bip32: {
|
|
1347
|
+
private: 0x0488ADE4, public: 0x0488B21E
|
|
1348
|
+
},
|
|
1349
|
+
coin_type: 60,
|
|
1350
|
+
wif: 0x45,//E
|
|
1351
|
+
multiCodec: 0x3c5
|
|
1560
1352
|
};
|
|
1561
1353
|
|
|
1562
1354
|
/**
|
|
1563
|
-
*
|
|
1564
|
-
* @return {
|
|
1565
|
-
* @property {Boolean} reult.daemon whether or not daemon is running
|
|
1566
|
-
* @property {Boolean} reult.environment Current environment
|
|
1355
|
+
* Our & supported networks
|
|
1356
|
+
* @return {leofcoin, olivia}
|
|
1567
1357
|
*/
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
return {daemon, environment: env}
|
|
1358
|
+
var networks = {
|
|
1359
|
+
leofcoin,
|
|
1360
|
+
bitcoin,
|
|
1361
|
+
litecoin,
|
|
1362
|
+
ethereum
|
|
1574
1363
|
};
|
|
1575
1364
|
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
_getPeerId(id) {
|
|
1582
|
-
if (!peernet.peerMap || peernet.peerMap && peernet.peerMap.size === 0) return false
|
|
1365
|
+
const fromNetworkString = network => {
|
|
1366
|
+
const parts = network.split(':');
|
|
1367
|
+
network = networks[parts[0]];
|
|
1368
|
+
if (parts[1]) {
|
|
1369
|
+
if (network[parts[1]]) network = network[parts[1]];
|
|
1583
1370
|
|
|
1584
|
-
|
|
1585
|
-
for (const _id of entry[1]) {
|
|
1586
|
-
if (_id === id) return entry[0]
|
|
1587
|
-
}
|
|
1588
|
-
}
|
|
1371
|
+
network.coin_type = 1;
|
|
1589
1372
|
}
|
|
1373
|
+
return network;
|
|
1374
|
+
};
|
|
1375
|
+
|
|
1376
|
+
// import { createHash } from 'crypto'
|
|
1377
|
+
// import { createHash as _createHash } from './hash'
|
|
1590
1378
|
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
if (id) return id
|
|
1594
|
-
const data = new peernet.protos['peernet-peer']({id: this.id});
|
|
1595
|
-
const node = await peernet.prepareMessage(peer.id, data.encoded);
|
|
1379
|
+
const { encode: encode$1, decode: decode$1 } = bs58check__default["default"];
|
|
1380
|
+
class HDWallet {
|
|
1596
1381
|
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1382
|
+
get chainCodeBuffer() {
|
|
1383
|
+
return this.ifNotLocked(() => this.hdnode.chainCode)
|
|
1384
|
+
}
|
|
1600
1385
|
|
|
1601
|
-
|
|
1602
|
-
|
|
1386
|
+
get chainCode() {
|
|
1387
|
+
return this.ifNotLocked(() => this.chainCodeBuffer.toString('hex'))
|
|
1388
|
+
}
|
|
1603
1389
|
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
if (connections.indexOf(peer.id) === -1) {
|
|
1608
|
-
connections.push(peer.id);
|
|
1609
|
-
peernet.peerMap.set(peer.id, connections);
|
|
1610
|
-
}
|
|
1611
|
-
}
|
|
1612
|
-
return id
|
|
1613
|
-
}
|
|
1390
|
+
get privateKeyBuffer() {
|
|
1391
|
+
return this.ifNotLocked(() => this.hdnode.privateKey)
|
|
1392
|
+
}
|
|
1614
1393
|
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
if (proto.name === 'peernet-peer') {
|
|
1619
|
-
const from = proto.decoded.id;
|
|
1620
|
-
if (from === this.id) return;
|
|
1394
|
+
get privateKey() {
|
|
1395
|
+
return this.ifNotLocked(() => this.privateKeyBuffer.toString('hex'))
|
|
1396
|
+
}
|
|
1621
1397
|
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
if (connections.indexOf(peer.id) === -1) {
|
|
1626
|
-
connections.push(peer.id);
|
|
1627
|
-
peernet.peerMap.set(from, connections);
|
|
1628
|
-
}
|
|
1629
|
-
}
|
|
1630
|
-
const data = new peernet.protos['peernet-peer-response']({id: this.id});
|
|
1631
|
-
const node = await peernet.prepareMessage(from, data.encoded);
|
|
1398
|
+
get publicKeyBuffer() {
|
|
1399
|
+
return this.ifNotLocked(() => this.hdnode.publicKey)
|
|
1400
|
+
}
|
|
1632
1401
|
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
if (from === this.id) return;
|
|
1402
|
+
get publicKey() {
|
|
1403
|
+
return this.ifNotLocked(() => this.publicKeyBuffer.toString('hex'))
|
|
1404
|
+
}
|
|
1637
1405
|
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
peernet.peerMap.set(from, connections);
|
|
1644
|
-
}
|
|
1645
|
-
}
|
|
1646
|
-
}
|
|
1647
|
-
}
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
|
-
/**
|
|
1651
|
-
* Keep history of fetched address and ptr
|
|
1652
|
-
* @property {Object} address
|
|
1653
|
-
* @property {Object} ptr
|
|
1654
|
-
*/
|
|
1655
|
-
const lastFetched = {
|
|
1656
|
-
address: {
|
|
1657
|
-
value: undefined,
|
|
1658
|
-
timestamp: 0,
|
|
1659
|
-
},
|
|
1660
|
-
ptr: {
|
|
1661
|
-
value: undefined,
|
|
1662
|
-
timestamp: 0,
|
|
1663
|
-
},
|
|
1664
|
-
};
|
|
1406
|
+
get ethereumAddress() {
|
|
1407
|
+
const buffer = ecc__default["default"].pointFromScalar(this.hdnode.__D, false);
|
|
1408
|
+
let hash = createKeccakHash__default["default"]('keccak256').update(buffer.slice(1)).digest();
|
|
1409
|
+
return `0x${hash.slice(-20).toString('hex')}`
|
|
1410
|
+
}
|
|
1665
1411
|
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1412
|
+
// async bitcoinAddress() {
|
|
1413
|
+
// const chainCode = this.privateKeyBuffer
|
|
1414
|
+
//
|
|
1415
|
+
// const node = bip32.fromPrivateKey(this.privateKeyBuffer, chainCode, networks['bitcoin'])
|
|
1416
|
+
// let buffer = await _createHash(node.publicKey, 'SHA-256')
|
|
1417
|
+
// buffer = createHash('ripemd160').update(buffer).digest()
|
|
1418
|
+
// // buffer = Buffer.from(`0x00${buffer.toString('hex')}`, 'hex')
|
|
1419
|
+
// // buffer = createHash('sha256').update(buffer).digest()
|
|
1420
|
+
// // const mainHash = buffer
|
|
1421
|
+
// // buffer = createHash('sha256').update(buffer).digest()
|
|
1422
|
+
// // const checksum = buffer.toString('hex').substring(0, 8)
|
|
1423
|
+
// // return base58.encode(Buffer.concat([mainHash, Buffer.from(checksum, 'hex')]))
|
|
1424
|
+
// const payload = Buffer.allocUnsafe(21)
|
|
1425
|
+
// payload.writeUInt8(networks['bitcoin'].pubKeyHash, 0)
|
|
1426
|
+
// buffer.copy(payload, 1)
|
|
1427
|
+
//
|
|
1428
|
+
// return encode(payload)
|
|
1429
|
+
// }
|
|
1675
1430
|
|
|
1676
|
-
|
|
1677
|
-
|
|
1431
|
+
get leofcoinAddress() {
|
|
1432
|
+
return encode$1(this.neutered.publicKeyBuffer)
|
|
1433
|
+
}
|
|
1678
1434
|
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
}
|
|
1435
|
+
get address() {
|
|
1436
|
+
return this.getAddressForCoin()
|
|
1437
|
+
}
|
|
1682
1438
|
|
|
1683
|
-
|
|
1684
|
-
|
|
1439
|
+
getAddressForCoin(coin_type) {
|
|
1440
|
+
if (!coin_type) coin_type = this.hdnode.network.coin_type;
|
|
1441
|
+
if (coin_type === 1) {
|
|
1442
|
+
if (this.networkName?.split(':')[0] === 'ethereum') coin_type = 60;
|
|
1443
|
+
if (this.networkName?.split(':')[0] === 'leofcoin') coin_type = 640;
|
|
1444
|
+
}
|
|
1445
|
+
// if (coin_type === 0) return this.bitcoinAddress
|
|
1446
|
+
if (coin_type === 60) return this.ethereumAddress
|
|
1447
|
+
if (coin_type === 640) return this.leofcoinAddress
|
|
1448
|
+
}
|
|
1685
1449
|
|
|
1686
|
-
|
|
1687
|
-
|
|
1450
|
+
get accountAddress() {
|
|
1451
|
+
return this.ifNotLocked(() => encode$1(this.hdnode.publicKeyBuffer))
|
|
1452
|
+
}
|
|
1688
1453
|
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
|
|
1693
|
-
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
|
|
1694
|
-
return earthRadiusKm * c;
|
|
1695
|
-
};
|
|
1454
|
+
get isTestnet() {
|
|
1455
|
+
if (typeof network === 'string')
|
|
1456
|
+
this.hdnode.network = fromNetworkString(network);
|
|
1696
1457
|
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
*
|
|
1700
|
-
*/
|
|
1701
|
-
constructor() {
|
|
1702
|
-
this.providerMap = new Map();
|
|
1703
|
-
}
|
|
1458
|
+
return Boolean(this.hdnode.network.coin_type === 1)
|
|
1459
|
+
}
|
|
1704
1460
|
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
const request = `https://whereis.leofcoin.org/?ip=${address}`;
|
|
1712
|
-
let response = await fetch(request);
|
|
1713
|
-
response = await response.json();
|
|
1714
|
-
const {lat, lon} = response;
|
|
1715
|
-
return {latitude: lat, longitude: lon}
|
|
1716
|
-
}
|
|
1461
|
+
constructor(network, hdnode) {
|
|
1462
|
+
if (typeof network === 'string') {
|
|
1463
|
+
this.networkName = network;
|
|
1464
|
+
this.network = fromNetworkString(network);
|
|
1465
|
+
} else if (typeof network === 'object')
|
|
1466
|
+
this.network = network;
|
|
1717
1467
|
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
* @param {Object} provider
|
|
1721
|
-
* @return {Object} {provider, distance}
|
|
1722
|
-
*/
|
|
1723
|
-
async getDistance(peer, provider) {
|
|
1724
|
-
const {latitude, longitude} = await this.getCoordinates(provider.address);
|
|
1725
|
-
return {provider, distance: distanceInKmBetweenEarthCoordinates(peer.latitude, peer.longitude, latitude, longitude)}
|
|
1726
|
-
}
|
|
1468
|
+
if (hdnode) this.defineHDNode(hdnode);
|
|
1469
|
+
}
|
|
1727
1470
|
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
async closestPeer(providers) {
|
|
1733
|
-
let all = [];
|
|
1734
|
-
const address = await getAddress();
|
|
1735
|
-
const peerLoc = await this.getCoordinates(address);
|
|
1471
|
+
ifNotLocked(fn, params) {
|
|
1472
|
+
if (!this.locked) return fn(params);
|
|
1473
|
+
return null
|
|
1474
|
+
}
|
|
1736
1475
|
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1476
|
+
defineHDNode(value) {
|
|
1477
|
+
Object.defineProperty(this, 'hdnode', {
|
|
1478
|
+
configurable: false,
|
|
1479
|
+
writable: false,
|
|
1480
|
+
value: value
|
|
1481
|
+
});
|
|
1482
|
+
}
|
|
1741
1483
|
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1484
|
+
validateNetwork(network) {
|
|
1485
|
+
if (!network && !this.network) return console.error(`expected network to be defined`);
|
|
1486
|
+
if (!network && this.network) network = this.network;
|
|
1487
|
+
if (typeof network === 'string') network = fromNetworkString(network);
|
|
1488
|
+
if (typeof network !== 'object') return console.error('network not found');
|
|
1489
|
+
return network;
|
|
1490
|
+
}
|
|
1746
1491
|
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1492
|
+
async generate(password, network) {
|
|
1493
|
+
network = this.validateNetwork(network);
|
|
1494
|
+
const mnemonic = new Mnemonic__default["default"]().generate();
|
|
1495
|
+
const seed = new Mnemonic__default["default"]().seedFromMnemonic(mnemonic, password);
|
|
1496
|
+
this.defineHDNode(bip32__namespace.fromSeed(seed, network));
|
|
1497
|
+
return mnemonic;
|
|
1498
|
+
}
|
|
1754
1499
|
|
|
1755
|
-
|
|
1756
|
-
*
|
|
1757
|
-
* @param {String} hash
|
|
1758
|
-
* @return {Array} providers
|
|
1500
|
+
/**
|
|
1501
|
+
* recover using mnemonic (recovery word list)
|
|
1759
1502
|
*/
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
this.providerMap.set(hash, providers);
|
|
1766
|
-
return providers;
|
|
1767
|
-
}
|
|
1768
|
-
}
|
|
1769
|
-
|
|
1770
|
-
/**
|
|
1771
|
-
* @params {String} network
|
|
1772
|
-
* @return {object} { identity, accounts, config }
|
|
1773
|
-
*/
|
|
1774
|
-
var generateAccount = async network => {
|
|
1775
|
-
let wallet = new MultiWallet__default["default"](network);
|
|
1776
|
-
/**
|
|
1777
|
-
* @type {string}
|
|
1778
|
-
*/
|
|
1779
|
-
const mnemonic = await wallet.generate();
|
|
1503
|
+
async recover(mnemonic, password, network) {
|
|
1504
|
+
network = this.validateNetwork(network, password);
|
|
1505
|
+
const seed = new Mnemonic__default["default"]().seedFromMnemonic(mnemonic, password);
|
|
1506
|
+
this.defineHDNode(bip32__namespace.fromSeed(seed, network));
|
|
1507
|
+
}
|
|
1780
1508
|
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
*/
|
|
1786
|
-
const account = wallet.account(0);
|
|
1787
|
-
/**
|
|
1788
|
-
* @type {object}
|
|
1789
|
-
*/
|
|
1790
|
-
const external = account.external(0);
|
|
1791
|
-
const internal = account.internal(0);
|
|
1509
|
+
load(base58, network) {
|
|
1510
|
+
network = this.validateNetwork(network);
|
|
1511
|
+
this.defineHDNode(bip32__namespace.fromBase58(base58, network));
|
|
1512
|
+
}
|
|
1792
1513
|
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
// multiWIF: wallet.export(),
|
|
1797
|
-
publicKey: external.publicKey,
|
|
1798
|
-
privateKey: external.privateKey,
|
|
1799
|
-
walletId: external.id
|
|
1800
|
-
},
|
|
1801
|
-
accounts: [['main account', external.address, internal.address]]
|
|
1802
|
-
// config: {
|
|
1803
|
-
// }
|
|
1804
|
-
}
|
|
1805
|
-
};
|
|
1806
|
-
|
|
1807
|
-
var testnets = {
|
|
1808
|
-
'leofcoin:olivia': {
|
|
1809
|
-
messagePrefix: '\u0019Leofcoin Signed Message:',
|
|
1810
|
-
pubKeyHash: 0x73, // o
|
|
1811
|
-
scriptHash: 0x76, // p
|
|
1812
|
-
multiTxHash: 0x8b4125, // omtx
|
|
1813
|
-
payments: {
|
|
1814
|
-
version: 0,
|
|
1815
|
-
unspent: 0x1fa443d7 // ounsp
|
|
1816
|
-
},
|
|
1817
|
-
wif: 0x7D, // s
|
|
1818
|
-
multiCodec: 0x7c4,
|
|
1819
|
-
bip32: { public: 0x13BBF2D5, private: 0x13BBCBC5 }
|
|
1820
|
-
},
|
|
1821
|
-
'bitcoin:testnet': {
|
|
1822
|
-
messagePrefix: '\x18Bitcoin Signed Message:\n',
|
|
1823
|
-
bech32: 'tb',
|
|
1824
|
-
pubKeyHash: 0x6f,
|
|
1825
|
-
scriptHash: 0xc4,
|
|
1826
|
-
wif: 0xef,
|
|
1827
|
-
bip32: {
|
|
1828
|
-
public: 0x043587cf,
|
|
1829
|
-
private: 0x04358394
|
|
1830
|
-
}
|
|
1831
|
-
}
|
|
1514
|
+
save() {
|
|
1515
|
+
return this.hdnode.toBase58();
|
|
1516
|
+
}
|
|
1832
1517
|
|
|
1833
|
-
|
|
1518
|
+
fromAddress(address, chainCode, network) {
|
|
1519
|
+
network = this.validateNetwork(network);
|
|
1520
|
+
// if (network.coin_type === 60) {
|
|
1521
|
+
// address = Buffer.from(address, 'hex')
|
|
1522
|
+
// } else {
|
|
1523
|
+
address = decode$1(address);
|
|
1524
|
+
// }
|
|
1525
|
+
|
|
1526
|
+
if (!chainCode || chainCode && !Buffer.isBuffer(chainCode)) chainCode = address.slice(1);
|
|
1527
|
+
this.defineHDNode(bip32__namespace.fromPublicKey(address, chainCode, network));
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
fromPublicKey(hex, chainCode, network) {
|
|
1531
|
+
network = this.validateNetwork(network);
|
|
1532
|
+
if (!Buffer.isBuffer(hex)) hex = Buffer.from(hex, 'hex');
|
|
1533
|
+
if (!chainCode || chainCode && !Buffer.isBuffer(chainCode)) chainCode = hex.slice(1);
|
|
1534
|
+
this.defineHDNode(bip32__namespace.fromPublicKey(hex, chainCode, network));
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1834
1537
|
|
|
1835
|
-
|
|
1836
|
-
/**
|
|
1837
|
-
* Main network
|
|
1838
|
-
* @return {messagePrefix, pubKeyHash, scriptHash, wif, bip32}
|
|
1839
|
-
*/
|
|
1840
|
-
const leofcoin = {
|
|
1841
|
-
messagePrefix: '\u0019Leofcoin Signed Message:',
|
|
1842
|
-
pubKeyHash: 0x30, // L
|
|
1843
|
-
scriptHash: 0x37, // P
|
|
1844
|
-
multiTxHash: 0x3adeed, // Lmtx
|
|
1845
|
-
payments: {
|
|
1846
|
-
version: 0,
|
|
1847
|
-
unspent: 0x0d6e0327 // Lunsp
|
|
1848
|
-
},
|
|
1849
|
-
coin_type: 640,
|
|
1850
|
-
wif: 0x3F, // S
|
|
1851
|
-
multiCodec: 0x3c4,
|
|
1852
|
-
bip32: { public: 0x13BBF2D4, private: 0x13BBCBC4 },
|
|
1853
|
-
testnet: testnets['leofcoin:olivia']
|
|
1854
|
-
};
|
|
1538
|
+
const { subtle } = crypto;
|
|
1855
1539
|
|
|
1856
|
-
const
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
coin_type: 0,
|
|
1864
|
-
bip32: {
|
|
1865
|
-
public: 0x0488b21e, private: 0x0488ade4
|
|
1866
|
-
},
|
|
1867
|
-
testnet: testnets['bitcoin:testnet']
|
|
1540
|
+
const generateAesKey = async (length = 256) => {
|
|
1541
|
+
const key = await subtle.generateKey({
|
|
1542
|
+
name: 'AES-CBC',
|
|
1543
|
+
length
|
|
1544
|
+
}, true, ['encrypt', 'decrypt']);
|
|
1545
|
+
|
|
1546
|
+
return key;
|
|
1868
1547
|
};
|
|
1869
1548
|
|
|
1870
|
-
const
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
bip32: {
|
|
1876
|
-
public: 0x019da462,
|
|
1877
|
-
private: 0x019d9cfe
|
|
1878
|
-
}
|
|
1549
|
+
const importAesKey = async (exported, format = 'raw', length = 256) => {
|
|
1550
|
+
return await subtle.importKey(format, exported, {
|
|
1551
|
+
name: 'AES-CBC',
|
|
1552
|
+
length
|
|
1553
|
+
}, true, ['encrypt', 'decrypt'])
|
|
1879
1554
|
};
|
|
1880
1555
|
|
|
1881
|
-
const
|
|
1882
|
-
|
|
1883
|
-
pubKeyHash: 0x30,
|
|
1884
|
-
scriptHash: 0x32,
|
|
1885
|
-
bip32: {
|
|
1886
|
-
private: 0x0488ADE4, public: 0x0488B21E
|
|
1887
|
-
},
|
|
1888
|
-
coin_type: 60,
|
|
1889
|
-
wif: 0x45,//E
|
|
1890
|
-
multiCodec: 0x3c5
|
|
1556
|
+
const exportAesKey = async (key, format = 'raw') => {
|
|
1557
|
+
return await subtle.exportKey(format, key)
|
|
1891
1558
|
};
|
|
1892
1559
|
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
var networks = {
|
|
1898
|
-
leofcoin,
|
|
1899
|
-
bitcoin,
|
|
1900
|
-
litecoin,
|
|
1901
|
-
ethereum
|
|
1902
|
-
};
|
|
1903
|
-
|
|
1904
|
-
const fromNetworkString = network => {
|
|
1905
|
-
const parts = network.split(':');
|
|
1906
|
-
network = networks[parts[0]];
|
|
1907
|
-
if (parts[1]) {
|
|
1908
|
-
if (network[parts[1]]) network = network[parts[1]];
|
|
1560
|
+
const encryptAes = async (uint8Array, key, iv) => subtle.encrypt({
|
|
1561
|
+
name: 'AES-CBC',
|
|
1562
|
+
iv,
|
|
1563
|
+
}, key, uint8Array);
|
|
1909
1564
|
|
|
1910
|
-
|
|
1565
|
+
const uint8ArrayToHex = uint8Array =>
|
|
1566
|
+
[...uint8Array].map(x => x.toString(16).padStart(2, '0')).join('');
|
|
1567
|
+
|
|
1568
|
+
const arrayBufferToHex = arrayBuffer =>
|
|
1569
|
+
uint8ArrayToHex(new Uint8Array(arrayBuffer));
|
|
1570
|
+
|
|
1571
|
+
const hexToUint8Array = hex =>
|
|
1572
|
+
new Uint8Array(hex.match(/[\da-f]{2}/gi).map(x => parseInt(x, 16)));
|
|
1573
|
+
|
|
1574
|
+
const encrypt = async string => {
|
|
1575
|
+
const ec = new TextEncoder();
|
|
1576
|
+
const key = await generateAesKey();
|
|
1577
|
+
const iv = await randombytes__default["default"](16);
|
|
1578
|
+
|
|
1579
|
+
const ciphertext = await encryptAes(ec.encode(string), key, iv);
|
|
1580
|
+
const exported = await exportAesKey(key);
|
|
1581
|
+
|
|
1582
|
+
return {
|
|
1583
|
+
key: arrayBufferToHex(exported),
|
|
1584
|
+
iv: iv.toString('hex'),
|
|
1585
|
+
cipher: arrayBufferToHex(ciphertext)
|
|
1911
1586
|
}
|
|
1912
|
-
|
|
1587
|
+
};
|
|
1588
|
+
|
|
1589
|
+
const decrypt = async (cipher, key, iv) => {
|
|
1590
|
+
if (!key.type) key = await importAesKey(hexToUint8Array(key));
|
|
1591
|
+
cipher = new Uint8Array(hexToUint8Array(cipher));
|
|
1592
|
+
iv = new Uint8Array(hexToUint8Array(iv));
|
|
1593
|
+
|
|
1594
|
+
const dec = new TextDecoder();
|
|
1595
|
+
const plaintext = await subtle.decrypt({
|
|
1596
|
+
name: 'AES-CBC',
|
|
1597
|
+
iv,
|
|
1598
|
+
}, key, cipher);
|
|
1599
|
+
|
|
1600
|
+
return dec.decode(plaintext);
|
|
1913
1601
|
};
|
|
1914
1602
|
|
|
1915
|
-
|
|
1916
|
-
// import { createHash as _createHash } from './hash'
|
|
1603
|
+
const { encode, decode } = bs58check__namespace;
|
|
1917
1604
|
|
|
1918
|
-
|
|
1919
|
-
class
|
|
1605
|
+
// TODO: multihash addresses
|
|
1606
|
+
class HDAccount {
|
|
1607
|
+
/**
|
|
1608
|
+
* @param {number} depth - acount depth
|
|
1609
|
+
*/
|
|
1610
|
+
constructor(node, depth = 0) {
|
|
1611
|
+
this.node = node;
|
|
1612
|
+
this.depth = depth;
|
|
1613
|
+
this._prefix = `m/44'/${node.network.coin_type}'/${depth}'/`;
|
|
1614
|
+
}
|
|
1920
1615
|
|
|
1921
|
-
|
|
1922
|
-
|
|
1616
|
+
/**
|
|
1617
|
+
* @param {number} index - address index
|
|
1618
|
+
*/
|
|
1619
|
+
internal(index = 0) {
|
|
1620
|
+
return this.node.derivePath(`${this._prefix}1/${index}`)
|
|
1923
1621
|
}
|
|
1924
1622
|
|
|
1925
|
-
|
|
1926
|
-
|
|
1623
|
+
/**
|
|
1624
|
+
* @param {number} index - address index
|
|
1625
|
+
*/
|
|
1626
|
+
external(index = 0) {
|
|
1627
|
+
return this.node.derivePath(`${this._prefix}0/${index}`)
|
|
1927
1628
|
}
|
|
1629
|
+
}
|
|
1928
1630
|
|
|
1929
|
-
|
|
1930
|
-
|
|
1631
|
+
class MultiWallet extends HDWallet {
|
|
1632
|
+
constructor(network, hdnode) {
|
|
1633
|
+
super(network, hdnode);
|
|
1634
|
+
this.multiCodec = this.network.multiCodec;
|
|
1635
|
+
this.version = 0x00;
|
|
1931
1636
|
}
|
|
1932
1637
|
|
|
1933
|
-
get
|
|
1934
|
-
|
|
1638
|
+
get id() {
|
|
1639
|
+
const buffer = Buffer.concat([
|
|
1640
|
+
Buffer.from(varint__default["default"].encode(this.multiCodec)),
|
|
1641
|
+
Buffer.from(this.account(0).node.neutered.publicKey, 'hex')
|
|
1642
|
+
]);
|
|
1643
|
+
return encode(buffer)
|
|
1935
1644
|
}
|
|
1936
1645
|
|
|
1937
|
-
get
|
|
1938
|
-
return this.ifNotLocked(() => this.
|
|
1646
|
+
get multiWIF() {
|
|
1647
|
+
return this.ifNotLocked(() => this.encode())
|
|
1939
1648
|
}
|
|
1940
1649
|
|
|
1941
|
-
get
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
get ethereumAddress() {
|
|
1946
|
-
const buffer = ecc__default["default"].pointFromScalar(this.hdnode.__D, false);
|
|
1947
|
-
let hash = createKeccakHash__default["default"]('keccak256').update(buffer.slice(1)).digest();
|
|
1948
|
-
return `0x${hash.slice(-20).toString('hex')}`
|
|
1949
|
-
}
|
|
1950
|
-
|
|
1951
|
-
// async bitcoinAddress() {
|
|
1952
|
-
// const chainCode = this.privateKeyBuffer
|
|
1953
|
-
//
|
|
1954
|
-
// const node = bip32.fromPrivateKey(this.privateKeyBuffer, chainCode, networks['bitcoin'])
|
|
1955
|
-
// let buffer = await _createHash(node.publicKey, 'SHA-256')
|
|
1956
|
-
// buffer = createHash('ripemd160').update(buffer).digest()
|
|
1957
|
-
// // buffer = Buffer.from(`0x00${buffer.toString('hex')}`, 'hex')
|
|
1958
|
-
// // buffer = createHash('sha256').update(buffer).digest()
|
|
1959
|
-
// // const mainHash = buffer
|
|
1960
|
-
// // buffer = createHash('sha256').update(buffer).digest()
|
|
1961
|
-
// // const checksum = buffer.toString('hex').substring(0, 8)
|
|
1962
|
-
// // return base58.encode(Buffer.concat([mainHash, Buffer.from(checksum, 'hex')]))
|
|
1963
|
-
// const payload = Buffer.allocUnsafe(21)
|
|
1964
|
-
// payload.writeUInt8(networks['bitcoin'].pubKeyHash, 0)
|
|
1965
|
-
// buffer.copy(payload, 1)
|
|
1966
|
-
//
|
|
1967
|
-
// return encode(payload)
|
|
1968
|
-
// }
|
|
1969
|
-
|
|
1970
|
-
get leofcoinAddress() {
|
|
1971
|
-
return encode$1(this.neutered.publicKeyBuffer)
|
|
1972
|
-
}
|
|
1973
|
-
|
|
1974
|
-
get address() {
|
|
1975
|
-
return this.getAddressForCoin()
|
|
1976
|
-
}
|
|
1977
|
-
|
|
1978
|
-
getAddressForCoin(coin_type) {
|
|
1979
|
-
if (!coin_type) coin_type = this.hdnode.network.coin_type;
|
|
1980
|
-
if (coin_type === 1) {
|
|
1981
|
-
if (this.networkName?.split(':')[0] === 'ethereum') coin_type = 60;
|
|
1982
|
-
if (this.networkName?.split(':')[0] === 'leofcoin') coin_type = 640;
|
|
1983
|
-
}
|
|
1984
|
-
// if (coin_type === 0) return this.bitcoinAddress
|
|
1985
|
-
if (coin_type === 60) return this.ethereumAddress
|
|
1986
|
-
if (coin_type === 640) return this.leofcoinAddress
|
|
1987
|
-
}
|
|
1988
|
-
|
|
1989
|
-
get accountAddress() {
|
|
1990
|
-
return this.ifNotLocked(() => encode$1(this.hdnode.publicKeyBuffer))
|
|
1991
|
-
}
|
|
1992
|
-
|
|
1993
|
-
get isTestnet() {
|
|
1994
|
-
if (typeof network === 'string')
|
|
1995
|
-
this.hdnode.network = fromNetworkString(network);
|
|
1996
|
-
|
|
1997
|
-
return Boolean(this.hdnode.network.coin_type === 1)
|
|
1998
|
-
}
|
|
1999
|
-
|
|
2000
|
-
constructor(network, hdnode) {
|
|
2001
|
-
if (typeof network === 'string') {
|
|
2002
|
-
this.networkName = network;
|
|
2003
|
-
this.network = fromNetworkString(network);
|
|
2004
|
-
} else if (typeof network === 'object')
|
|
2005
|
-
this.network = network;
|
|
2006
|
-
|
|
2007
|
-
if (hdnode) this.defineHDNode(hdnode);
|
|
2008
|
-
}
|
|
2009
|
-
|
|
2010
|
-
ifNotLocked(fn, params) {
|
|
2011
|
-
if (!this.locked) return fn(params);
|
|
2012
|
-
return null
|
|
2013
|
-
}
|
|
2014
|
-
|
|
2015
|
-
defineHDNode(value) {
|
|
2016
|
-
Object.defineProperty(this, 'hdnode', {
|
|
2017
|
-
configurable: false,
|
|
2018
|
-
writable: false,
|
|
2019
|
-
value: value
|
|
2020
|
-
});
|
|
2021
|
-
}
|
|
2022
|
-
|
|
2023
|
-
validateNetwork(network) {
|
|
2024
|
-
if (!network && !this.network) return console.error(`expected network to be defined`);
|
|
2025
|
-
if (!network && this.network) network = this.network;
|
|
2026
|
-
if (typeof network === 'string') network = fromNetworkString(network);
|
|
2027
|
-
if (typeof network !== 'object') return console.error('network not found');
|
|
2028
|
-
return network;
|
|
2029
|
-
}
|
|
2030
|
-
|
|
2031
|
-
async generate(password, network) {
|
|
2032
|
-
network = this.validateNetwork(network);
|
|
2033
|
-
const mnemonic = new Mnemonic__default["default"]().generate();
|
|
2034
|
-
const seed = new Mnemonic__default["default"]().seedFromMnemonic(mnemonic, password);
|
|
2035
|
-
this.defineHDNode(bip32__namespace.fromSeed(seed, network));
|
|
2036
|
-
return mnemonic;
|
|
2037
|
-
}
|
|
2038
|
-
|
|
2039
|
-
/**
|
|
2040
|
-
* recover using mnemonic (recovery word list)
|
|
2041
|
-
*/
|
|
2042
|
-
async recover(mnemonic, password, network) {
|
|
2043
|
-
network = this.validateNetwork(network, password);
|
|
2044
|
-
const seed = new Mnemonic__default["default"]().seedFromMnemonic(mnemonic, password);
|
|
2045
|
-
this.defineHDNode(bip32__namespace.fromSeed(seed, network));
|
|
2046
|
-
}
|
|
2047
|
-
|
|
2048
|
-
load(base58, network) {
|
|
2049
|
-
network = this.validateNetwork(network);
|
|
2050
|
-
this.defineHDNode(bip32__namespace.fromBase58(base58, network));
|
|
2051
|
-
}
|
|
2052
|
-
|
|
2053
|
-
save() {
|
|
2054
|
-
return this.hdnode.toBase58();
|
|
2055
|
-
}
|
|
2056
|
-
|
|
2057
|
-
fromAddress(address, chainCode, network) {
|
|
2058
|
-
network = this.validateNetwork(network);
|
|
2059
|
-
// if (network.coin_type === 60) {
|
|
2060
|
-
// address = Buffer.from(address, 'hex')
|
|
2061
|
-
// } else {
|
|
2062
|
-
address = decode$1(address);
|
|
2063
|
-
// }
|
|
2064
|
-
|
|
2065
|
-
if (!chainCode || chainCode && !Buffer.isBuffer(chainCode)) chainCode = address.slice(1);
|
|
2066
|
-
this.defineHDNode(bip32__namespace.fromPublicKey(address, chainCode, network));
|
|
2067
|
-
}
|
|
2068
|
-
|
|
2069
|
-
fromPublicKey(hex, chainCode, network) {
|
|
2070
|
-
network = this.validateNetwork(network);
|
|
2071
|
-
if (!Buffer.isBuffer(hex)) hex = Buffer.from(hex, 'hex');
|
|
2072
|
-
if (!chainCode || chainCode && !Buffer.isBuffer(chainCode)) chainCode = hex.slice(1);
|
|
2073
|
-
this.defineHDNode(bip32__namespace.fromPublicKey(hex, chainCode, network));
|
|
2074
|
-
}
|
|
2075
|
-
}
|
|
2076
|
-
|
|
2077
|
-
const { subtle } = crypto;
|
|
2078
|
-
|
|
2079
|
-
const generateAesKey = async (length = 256) => {
|
|
2080
|
-
const key = await subtle.generateKey({
|
|
2081
|
-
name: 'AES-CBC',
|
|
2082
|
-
length
|
|
2083
|
-
}, true, ['encrypt', 'decrypt']);
|
|
2084
|
-
|
|
2085
|
-
return key;
|
|
2086
|
-
};
|
|
2087
|
-
|
|
2088
|
-
const importAesKey = async (exported, format = 'raw', length = 256) => {
|
|
2089
|
-
return await subtle.importKey(format, exported, {
|
|
2090
|
-
name: 'AES-CBC',
|
|
2091
|
-
length
|
|
2092
|
-
}, true, ['encrypt', 'decrypt'])
|
|
2093
|
-
};
|
|
2094
|
-
|
|
2095
|
-
const exportAesKey = async (key, format = 'raw') => {
|
|
2096
|
-
return await subtle.exportKey(format, key)
|
|
2097
|
-
};
|
|
2098
|
-
|
|
2099
|
-
const encryptAes = async (uint8Array, key, iv) => subtle.encrypt({
|
|
2100
|
-
name: 'AES-CBC',
|
|
2101
|
-
iv,
|
|
2102
|
-
}, key, uint8Array);
|
|
2103
|
-
|
|
2104
|
-
const uint8ArrayToHex = uint8Array =>
|
|
2105
|
-
[...uint8Array].map(x => x.toString(16).padStart(2, '0')).join('');
|
|
2106
|
-
|
|
2107
|
-
const arrayBufferToHex = arrayBuffer =>
|
|
2108
|
-
uint8ArrayToHex(new Uint8Array(arrayBuffer));
|
|
2109
|
-
|
|
2110
|
-
const hexToUint8Array = hex =>
|
|
2111
|
-
new Uint8Array(hex.match(/[\da-f]{2}/gi).map(x => parseInt(x, 16)));
|
|
2112
|
-
|
|
2113
|
-
const encrypt = async string => {
|
|
2114
|
-
const ec = new TextEncoder();
|
|
2115
|
-
const key = await generateAesKey();
|
|
2116
|
-
const iv = await randombytes__default["default"](16);
|
|
2117
|
-
|
|
2118
|
-
const ciphertext = await encryptAes(ec.encode(string), key, iv);
|
|
2119
|
-
const exported = await exportAesKey(key);
|
|
2120
|
-
|
|
2121
|
-
return {
|
|
2122
|
-
key: arrayBufferToHex(exported),
|
|
2123
|
-
iv: iv.toString('hex'),
|
|
2124
|
-
cipher: arrayBufferToHex(ciphertext)
|
|
2125
|
-
}
|
|
2126
|
-
};
|
|
2127
|
-
|
|
2128
|
-
const decrypt = async (cipher, key, iv) => {
|
|
2129
|
-
if (!key.type) key = await importAesKey(hexToUint8Array(key));
|
|
2130
|
-
cipher = new Uint8Array(hexToUint8Array(cipher));
|
|
2131
|
-
iv = new Uint8Array(hexToUint8Array(iv));
|
|
2132
|
-
|
|
2133
|
-
const dec = new TextDecoder();
|
|
2134
|
-
const plaintext = await subtle.decrypt({
|
|
2135
|
-
name: 'AES-CBC',
|
|
2136
|
-
iv,
|
|
2137
|
-
}, key, cipher);
|
|
2138
|
-
|
|
2139
|
-
return dec.decode(plaintext);
|
|
2140
|
-
};
|
|
2141
|
-
|
|
2142
|
-
const { encode, decode } = bs58check__namespace;
|
|
2143
|
-
|
|
2144
|
-
// TODO: multihash addresses
|
|
2145
|
-
class HDAccount {
|
|
2146
|
-
/**
|
|
2147
|
-
* @param {number} depth - acount depth
|
|
2148
|
-
*/
|
|
2149
|
-
constructor(node, depth = 0) {
|
|
2150
|
-
this.node = node;
|
|
2151
|
-
this.depth = depth;
|
|
2152
|
-
this._prefix = `m/44'/${node.network.coin_type}'/${depth}'/`;
|
|
2153
|
-
}
|
|
2154
|
-
|
|
2155
|
-
/**
|
|
2156
|
-
* @param {number} index - address index
|
|
2157
|
-
*/
|
|
2158
|
-
internal(index = 0) {
|
|
2159
|
-
return this.node.derivePath(`${this._prefix}1/${index}`)
|
|
2160
|
-
}
|
|
2161
|
-
|
|
2162
|
-
/**
|
|
2163
|
-
* @param {number} index - address index
|
|
2164
|
-
*/
|
|
2165
|
-
external(index = 0) {
|
|
2166
|
-
return this.node.derivePath(`${this._prefix}0/${index}`)
|
|
2167
|
-
}
|
|
2168
|
-
}
|
|
2169
|
-
|
|
2170
|
-
class MultiWallet extends HDWallet {
|
|
2171
|
-
constructor(network, hdnode) {
|
|
2172
|
-
super(network, hdnode);
|
|
2173
|
-
this.multiCodec = this.network.multiCodec;
|
|
2174
|
-
this.version = 0x00;
|
|
2175
|
-
}
|
|
2176
|
-
|
|
2177
|
-
get id() {
|
|
2178
|
-
const buffer = Buffer.concat([
|
|
2179
|
-
Buffer.from(varint__default["default"].encode(this.multiCodec)),
|
|
2180
|
-
Buffer.from(this.account(0).node.neutered.publicKey, 'hex')
|
|
2181
|
-
]);
|
|
2182
|
-
return encode(buffer)
|
|
2183
|
-
}
|
|
2184
|
-
|
|
2185
|
-
get multiWIF() {
|
|
2186
|
-
return this.ifNotLocked(() => this.encode())
|
|
2187
|
-
}
|
|
2188
|
-
|
|
2189
|
-
get neutered() {
|
|
2190
|
-
const neutered = this.ifNotLocked(() => new MultiWallet(this.networkName, this.hdnode.neutered()));
|
|
2191
|
-
if (neutered) this._neutered = neutered;
|
|
2192
|
-
return this._neutered
|
|
1650
|
+
get neutered() {
|
|
1651
|
+
const neutered = this.ifNotLocked(() => new MultiWallet(this.networkName, this.hdnode.neutered()));
|
|
1652
|
+
if (neutered) this._neutered = neutered;
|
|
1653
|
+
return this._neutered
|
|
2193
1654
|
}
|
|
2194
1655
|
|
|
2195
1656
|
fromId(id) {
|
|
@@ -2243,707 +1704,1272 @@ class MultiWallet extends HDWallet {
|
|
|
2243
1704
|
return encode(buffer);
|
|
2244
1705
|
}
|
|
2245
1706
|
|
|
2246
|
-
decode(bs58) {
|
|
2247
|
-
let buffer = decode(bs58);
|
|
2248
|
-
const version = varint__default["default"].decode(buffer);
|
|
2249
|
-
buffer = buffer.slice(varint__default["default"].decode.bytes);
|
|
2250
|
-
const multiCodec = varint__default["default"].decode(buffer);
|
|
2251
|
-
buffer = buffer.slice(varint__default["default"].decode.bytes);
|
|
2252
|
-
bs58 = encode(buffer);
|
|
2253
|
-
if (version !== this.version) throw TypeError('Invalid version');
|
|
2254
|
-
if (this.multiCodec !== multiCodec) throw TypeError('Invalid multiCodec');
|
|
2255
|
-
return { version, multiCodec, bs58 };
|
|
2256
|
-
}
|
|
1707
|
+
decode(bs58) {
|
|
1708
|
+
let buffer = decode(bs58);
|
|
1709
|
+
const version = varint__default["default"].decode(buffer);
|
|
1710
|
+
buffer = buffer.slice(varint__default["default"].decode.bytes);
|
|
1711
|
+
const multiCodec = varint__default["default"].decode(buffer);
|
|
1712
|
+
buffer = buffer.slice(varint__default["default"].decode.bytes);
|
|
1713
|
+
bs58 = encode(buffer);
|
|
1714
|
+
if (version !== this.version) throw TypeError('Invalid version');
|
|
1715
|
+
if (this.multiCodec !== multiCodec) throw TypeError('Invalid multiCodec');
|
|
1716
|
+
return { version, multiCodec, bs58 };
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
sign(hash) {
|
|
1720
|
+
return new MultiSignature__default["default"](this.version, this.network.multiCodec)
|
|
1721
|
+
.sign(hash, this.privateKeyBuffer);
|
|
1722
|
+
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
verify(multiSignature, hash) {
|
|
1726
|
+
return new MultiSignature__default["default"](this.version, this.network.multiCodec)
|
|
1727
|
+
.verify(multiSignature, hash, this.publicKeyBuffer)
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
/**
|
|
1731
|
+
* @param {number} account - account to return chain for
|
|
1732
|
+
* @return { internal(addressIndex), external(addressIndex) }
|
|
1733
|
+
*/
|
|
1734
|
+
account(index) {
|
|
1735
|
+
return new HDAccount(new MultiWallet(this.networkName, this.hdnode), index);
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
/**
|
|
1739
|
+
* m / purpose' / coin_type' / account' / change / aadress_index
|
|
1740
|
+
*
|
|
1741
|
+
* see https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
|
|
1742
|
+
*/
|
|
1743
|
+
derivePath(path) {
|
|
1744
|
+
return new MultiWallet(this.networkName, this.hdnode.derivePath(path))
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
derive(index) {
|
|
1748
|
+
return new MultiWallet(this.networkName, this.hdnode.derive(index));
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
class MessageHandler {
|
|
1753
|
+
constructor(network) {
|
|
1754
|
+
this.network = network;
|
|
1755
|
+
}
|
|
1756
|
+
/**
|
|
1757
|
+
* hash and sign message
|
|
1758
|
+
*
|
|
1759
|
+
* @param {object} message
|
|
1760
|
+
* @param {Buffer} message.from peer id
|
|
1761
|
+
* @param {Buffer} message.to peer id
|
|
1762
|
+
* @param {string} message.data Peernet message
|
|
1763
|
+
* (PeernetMessage excluded) encoded as a string
|
|
1764
|
+
* @return signature
|
|
1765
|
+
*/
|
|
1766
|
+
async hashAndSignMessage(message) {
|
|
1767
|
+
const hasher = new codecFormatInterface.CodecHash(message, {name: 'peernet-message'});
|
|
1768
|
+
let identity = await walletStore.get('identity');
|
|
1769
|
+
identity = JSON.parse(new TextDecoder().decode(identity));
|
|
1770
|
+
const wallet = new MultiWallet(this.network);
|
|
1771
|
+
wallet.recover(identity.mnemonic);
|
|
1772
|
+
return wallet.sign(Buffer.from(hasher.hash).slice(0, 32))
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
/**
|
|
1776
|
+
* @param {String} from - peer id
|
|
1777
|
+
* @param {String} to - peer id
|
|
1778
|
+
* @param {String|PeernetMessage} data - data encoded message string
|
|
1779
|
+
* or the messageNode itself
|
|
1780
|
+
*/
|
|
1781
|
+
async prepareMessage(from, to, data, id) {
|
|
1782
|
+
if (data.encoded) data = data.encoded;
|
|
1783
|
+
|
|
1784
|
+
const message = {
|
|
1785
|
+
from,
|
|
1786
|
+
to,
|
|
1787
|
+
data,
|
|
1788
|
+
};
|
|
1789
|
+
const signature = await this.hashAndSignMessage(message);
|
|
1790
|
+
const node = new PeernetMessage({
|
|
1791
|
+
...message,
|
|
1792
|
+
signature,
|
|
1793
|
+
});
|
|
1794
|
+
|
|
1795
|
+
return node
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
const dataHandler = async message => {
|
|
1800
|
+
if (!message) return
|
|
1801
|
+
|
|
1802
|
+
const {data, id} = message;
|
|
1803
|
+
|
|
1804
|
+
message = protoFor(data);
|
|
1805
|
+
const proto = protoFor(message.decoded.data);
|
|
1806
|
+
const from = message.decoded.from;
|
|
1807
|
+
|
|
1808
|
+
peernet._protoHandler({id, proto}, peernet.client.connections[from], from);
|
|
1809
|
+
};
|
|
1810
|
+
|
|
1811
|
+
const encapsulatedError = () => {
|
|
1812
|
+
return new Error('Nodes/Data should be send encapsulated by peernet-message')
|
|
1813
|
+
};
|
|
1814
|
+
|
|
1815
|
+
const dhtError = (proto) => {
|
|
1816
|
+
const text = `Received proto ${proto.name} expected peernet-dht-response`;
|
|
1817
|
+
return new Error(`Routing error: ${text}`)
|
|
1818
|
+
};
|
|
1819
|
+
|
|
1820
|
+
const nothingFoundError = (hash) => {
|
|
1821
|
+
return new Error(`nothing found for ${hash}`)
|
|
1822
|
+
};
|
|
1823
|
+
|
|
1824
|
+
globalThis.leofcoin = globalThis.leofcoin || {};
|
|
1825
|
+
globalThis.globalSub = globalThis.globalSub || new PubSub({verbose: true});
|
|
1826
|
+
|
|
1827
|
+
/**
|
|
1828
|
+
* @access public
|
|
1829
|
+
* @example
|
|
1830
|
+
* const peernet = new Peernet();
|
|
1831
|
+
*/
|
|
1832
|
+
class Peernet {
|
|
1833
|
+
/**
|
|
1834
|
+
* @access public
|
|
1835
|
+
* @param {Object} options
|
|
1836
|
+
* @param {String} options.network - desired network
|
|
1837
|
+
* @param {String} options.root - path to root directory
|
|
1838
|
+
* @param {String} options.storePrefix - prefix for datatores (lfc)
|
|
1839
|
+
*
|
|
1840
|
+
* @return {Promise} instance of Peernet
|
|
1841
|
+
*
|
|
1842
|
+
* @example
|
|
1843
|
+
* const peernet = new Peernet({network: 'leofcoin', root: '.leofcoin'});
|
|
1844
|
+
*/
|
|
1845
|
+
constructor(options = {}) {
|
|
1846
|
+
this._discovered = [];
|
|
1847
|
+
/**
|
|
1848
|
+
* @property {String} network - current network
|
|
1849
|
+
*/
|
|
1850
|
+
this.network = options.network || 'leofcoin';
|
|
1851
|
+
const parts = this.network.split(':');
|
|
1852
|
+
|
|
1853
|
+
if (!options.storePrefix) options.storePrefix = 'lfc';
|
|
1854
|
+
if (!options.port) options.port = 2000;
|
|
1855
|
+
if (!options.root) {
|
|
1856
|
+
if (parts[1]) options.root = `.${parts[0]}/peernet/${parts[1]}`;
|
|
1857
|
+
else options.root = `.${this.network}/peernet`;
|
|
1858
|
+
}
|
|
1859
|
+
globalThis.peernet = this;
|
|
1860
|
+
this.bw = {
|
|
1861
|
+
up: 0,
|
|
1862
|
+
down: 0,
|
|
1863
|
+
};
|
|
1864
|
+
return this._init(options)
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
get defaultStores() {
|
|
1868
|
+
return ['account', 'wallet', 'block', 'transaction', 'chain', 'data', 'message']
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
addProto(name, proto) {
|
|
1872
|
+
if (!this.protos[name]) this.protos[name] = proto;
|
|
1873
|
+
}
|
|
1874
|
+
|
|
1875
|
+
addCodec(name, codec) {
|
|
1876
|
+
if (!this.codecs[name]) this.codecs[name] = codec;
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
async addStore(name, prefix, root, isPrivate = true) {
|
|
1880
|
+
if (name === 'block' || name === 'transaction' || name === 'chain' ||
|
|
1881
|
+
name === 'data' || name === 'message') isPrivate = false;
|
|
1882
|
+
|
|
1883
|
+
let Storage;
|
|
1884
|
+
if (this.hasDaemon) {
|
|
1885
|
+
Storage = LeofcoinStorageClient;
|
|
1886
|
+
} else {
|
|
1887
|
+
Storage = globalThis.LeofcoinStorage?.default ? globalThis.LeofcoinStorage.default : LeofcoinStorage__default["default"];
|
|
1888
|
+
}
|
|
1889
|
+
globalThis[`${name}Store`] = globalThis[`${name}Store`] ||
|
|
1890
|
+
await new Storage(name, root);
|
|
1891
|
+
|
|
1892
|
+
globalThis[`${name}Store`].private = isPrivate;
|
|
1893
|
+
if (!isPrivate) this.stores.push(name);
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
|
|
1897
|
+
/**
|
|
1898
|
+
* @see MessageHandler
|
|
1899
|
+
*/
|
|
1900
|
+
prepareMessage(to, data) {
|
|
1901
|
+
return this._messageHandler.prepareMessage(this.id, to, data)
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
/**
|
|
1905
|
+
* @access public
|
|
1906
|
+
*
|
|
1907
|
+
* @return {Array} peerId
|
|
1908
|
+
*/
|
|
1909
|
+
get peers() {
|
|
1910
|
+
return Object.keys(this.client.connections)
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
get connections() {
|
|
1914
|
+
return Object.values(this.client.connections)
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1917
|
+
get peerEntries() {
|
|
1918
|
+
return Object.entries(this.client.connections)
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
/**
|
|
1922
|
+
* @return {String} id - peerId
|
|
1923
|
+
*/
|
|
1924
|
+
getConnection(id) {
|
|
1925
|
+
return this.client.connections[id]
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1928
|
+
/**
|
|
1929
|
+
* @private
|
|
1930
|
+
*
|
|
1931
|
+
* @param {Object} options
|
|
1932
|
+
* @param {String} options.root - path to root directory
|
|
1933
|
+
*
|
|
1934
|
+
* @return {Promise} instance of Peernet
|
|
1935
|
+
*/
|
|
1936
|
+
async _init(options) {
|
|
1937
|
+
// peernetDHT aka closesPeer by coordinates
|
|
1938
|
+
/**
|
|
1939
|
+
* @type {Object}
|
|
1940
|
+
* @property {Object} peer Instance of Peer
|
|
1941
|
+
*/
|
|
1942
|
+
this.dht = new DhtEarth();
|
|
1943
|
+
/**
|
|
1944
|
+
* @type {Map}
|
|
1945
|
+
* @property {Object} peer Instance of Peer
|
|
1946
|
+
*/
|
|
1947
|
+
this.stores = [];
|
|
1948
|
+
this.requestProtos = {};
|
|
1949
|
+
this.storePrefix = options.storePrefix;
|
|
1950
|
+
this.root = options.root;
|
|
1951
|
+
|
|
1952
|
+
/**
|
|
1953
|
+
* proto Object containing protos
|
|
1954
|
+
* @type {Object}
|
|
1955
|
+
* @property {PeernetMessage} protos[peernet-message] messageNode
|
|
1956
|
+
* @property {DHTMessage} protos[peernet-dht] messageNode
|
|
1957
|
+
* @property {DHTMessageResponse} protos[peernet-dht-response] messageNode
|
|
1958
|
+
* @property {DataMessage} protos[peernet-data] messageNode
|
|
1959
|
+
* @property {DataMessageResponse} protos[peernet-data-response] messageNode
|
|
1960
|
+
*/
|
|
1961
|
+
globalThis.peernet.protos = {
|
|
1962
|
+
'peernet-request': RequestMessage,
|
|
1963
|
+
'peernet-response': ResponseMessage,
|
|
1964
|
+
'peernet-peer': PeerMessage,
|
|
1965
|
+
'peernet-peer-response': PeerMessageResponse,
|
|
1966
|
+
'peernet-message': PeernetMessage,
|
|
1967
|
+
'peernet-dht': DHTMessage,
|
|
1968
|
+
'peernet-dht-response': DHTMessageResponse,
|
|
1969
|
+
'peernet-data': DataMessage,
|
|
1970
|
+
'peernet-data-response': DataMessageResponse,
|
|
1971
|
+
'peernet-ps': PsMessage,
|
|
1972
|
+
'chat-message': ChatMessage,
|
|
1973
|
+
};
|
|
1974
|
+
|
|
1975
|
+
this.protos = globalThis.peernet.protos;
|
|
1976
|
+
this.codecs = codecFormatInterface.codecs;
|
|
1977
|
+
|
|
1978
|
+
this._messageHandler = new MessageHandler(this.network);
|
|
1979
|
+
|
|
1980
|
+
const {daemon, environment} = await target();
|
|
1981
|
+
this.hasDaemon = daemon;
|
|
1982
|
+
|
|
1983
|
+
|
|
1984
|
+
|
|
1985
|
+
for (const store of this.defaultStores) {
|
|
1986
|
+
await this.addStore(store, options.storePrefix, options.root);
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
try {
|
|
1990
|
+
const pub = await accountStore.get('public');
|
|
1991
|
+
this.id = JSON.parse(new TextDecoder().decode(pub)).walletId;
|
|
1992
|
+
} catch (e) {
|
|
1993
|
+
if (e.code === 'ERR_NOT_FOUND') {
|
|
1994
|
+
const {identity, accounts, config} = await generateAccount(this.network);
|
|
1995
|
+
walletStore.put('version', new TextEncoder().encode(1));
|
|
1996
|
+
walletStore.put('accounts', new TextEncoder().encode(accounts));
|
|
1997
|
+
walletStore.put('identity', new TextEncoder().encode(JSON.stringify(identity)));
|
|
1998
|
+
await accountStore.put('config', new TextEncoder().encode(JSON.stringify(config)));
|
|
1999
|
+
await accountStore.put('public', new TextEncoder().encode(JSON.stringify({walletId: identity.walletId})));
|
|
2000
|
+
|
|
2001
|
+
this.id = identity.walletId;
|
|
2002
|
+
} else {
|
|
2003
|
+
throw e
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
this._peerHandler = new PeerDiscovery(this.id);
|
|
2007
|
+
this.peerId = this.id;
|
|
2008
|
+
|
|
2009
|
+
pubsub.subscribe('peer:connected', async (peer) => {
|
|
2010
|
+
console.log(peer);
|
|
2011
|
+
// console.log({connected: peer.id, as: this._getPeerId(peer.id) });
|
|
2012
|
+
// peer.on('peernet.data', async (message) => {
|
|
2013
|
+
// const id = message.id
|
|
2014
|
+
// message = new PeernetMessage(Buffer.from(message.data.data))
|
|
2015
|
+
// const proto = protoFor(message.decoded.data)
|
|
2016
|
+
// this._protoHandler({id, proto}, peer)
|
|
2017
|
+
// })
|
|
2018
|
+
});
|
|
2019
|
+
|
|
2020
|
+
/**
|
|
2021
|
+
* converts data -> message -> proto
|
|
2022
|
+
* @see DataHandler
|
|
2023
|
+
*/
|
|
2024
|
+
pubsub.subscribe('peer:data', dataHandler);
|
|
2025
|
+
|
|
2026
|
+
/**
|
|
2027
|
+
* @access public
|
|
2028
|
+
* @type {PeernetClient}
|
|
2029
|
+
*/
|
|
2030
|
+
this.client = new Client(this.id);
|
|
2031
|
+
if (globalThis.onbeforeunload) {
|
|
2032
|
+
globalThis.addEventListener('beforeunload', async () => this.client.close());
|
|
2033
|
+
}
|
|
2034
|
+
return this
|
|
2035
|
+
}
|
|
2036
|
+
|
|
2037
|
+
addRequestHandler(name, method) {
|
|
2038
|
+
this.requestProtos[name] = method;
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
sendMessage(peer, id, data) {
|
|
2042
|
+
if (peer.readyState === 'open') {
|
|
2043
|
+
peer.send(data, id);
|
|
2044
|
+
this.bw.up += data.length;
|
|
2045
|
+
} else if (peer.readyState === 'closed') ;
|
|
2046
|
+
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
/**
|
|
2050
|
+
* @private
|
|
2051
|
+
*
|
|
2052
|
+
* @param {Buffer} message - peernet message
|
|
2053
|
+
* @param {PeernetPeer} peer - peernet peer
|
|
2054
|
+
*/
|
|
2055
|
+
async _protoHandler(message, peer, from) {
|
|
2056
|
+
|
|
2057
|
+
const {id, proto} = message;
|
|
2058
|
+
this.bw.down += proto.encoded.length;
|
|
2059
|
+
if (proto.name === 'peernet-dht') {
|
|
2060
|
+
let { hash, store } = proto.decoded;
|
|
2061
|
+
let has;
|
|
2062
|
+
|
|
2063
|
+
if (!store) {
|
|
2064
|
+
has = await this.has(hash);
|
|
2065
|
+
} else {
|
|
2066
|
+
store = globalThis[`${store}Store`];
|
|
2067
|
+
if (store.private) has = false;
|
|
2068
|
+
else has = await store.has(hash);
|
|
2069
|
+
}
|
|
2070
|
+
const data = new DHTMessageResponse({hash, has});
|
|
2071
|
+
const node = await this.prepareMessage(from, data.encoded);
|
|
2072
|
+
|
|
2073
|
+
this.sendMessage(peer, id, node.encoded);
|
|
2074
|
+
} else if (proto.name === 'peernet-data') {
|
|
2075
|
+
let { hash, store } = proto.decoded;
|
|
2076
|
+
let data;
|
|
2077
|
+
if (!store) {
|
|
2078
|
+
store = await this.whichStore([...this.stores], hash);
|
|
2079
|
+
} else {
|
|
2080
|
+
store = globalThis[`${store}Store`];
|
|
2081
|
+
}
|
|
2082
|
+
if (store && !store.private) {
|
|
2083
|
+
data = await store.get(hash);
|
|
2084
|
+
|
|
2085
|
+
if (data) {
|
|
2086
|
+
data = new DataMessageResponse({hash, data});
|
|
2087
|
+
|
|
2088
|
+
const node = await this.prepareMessage(from, data.encoded);
|
|
2089
|
+
this.sendMessage(peer, id, node.encoded);
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2093
|
+
} else if (proto.name === 'peernet-request') {
|
|
2094
|
+
const method = this.requestProtos[proto.decoded.request];
|
|
2095
|
+
if (method) {
|
|
2096
|
+
const data = await method();
|
|
2097
|
+
const node = await this.prepareMessage(from, data.encoded);
|
|
2098
|
+
this.sendMessage(peer, id, node.encoded);
|
|
2099
|
+
}
|
|
2100
|
+
} else if (proto.name === 'peernet-ps' && peer.peerId !== this.id) {
|
|
2101
|
+
globalSub.publish(new TextDecoder().decode(proto.decoded.topic), proto.decoded.data);
|
|
2102
|
+
}
|
|
2103
|
+
// }
|
|
2104
|
+
}
|
|
2105
|
+
|
|
2106
|
+
/**
|
|
2107
|
+
* performs a walk and resolves first encounter
|
|
2108
|
+
*
|
|
2109
|
+
* @param {String} hash
|
|
2110
|
+
*/
|
|
2111
|
+
async walk(hash) {
|
|
2112
|
+
if (!hash) throw new Error('hash expected, received undefined')
|
|
2113
|
+
const data = new DHTMessage({hash});
|
|
2114
|
+
this.client.id;
|
|
2115
|
+
const walk = async peer => {
|
|
2116
|
+
const node = await this.prepareMessage(peer.peerId, data.encoded);
|
|
2117
|
+
let result = await peer.request(node.encoded);
|
|
2118
|
+
result = new Uint8Array(Object.values(result));
|
|
2119
|
+
let proto = protoFor(result);
|
|
2120
|
+
if (proto.name !== 'peernet-message') throw encapsulatedError()
|
|
2121
|
+
const from = proto.decoded.from;
|
|
2122
|
+
proto = protoFor(proto.decoded.data);
|
|
2123
|
+
if (proto.name !== 'peernet-dht-response') throw dhtError(proto.name)
|
|
2124
|
+
|
|
2125
|
+
// TODO: give ip and port (just used for location)
|
|
2126
|
+
if (!peer.connection.remoteAddress || !peer.connection.localAddress) {
|
|
2127
|
+
peer.connection.remoteFamily = 'ipv4';
|
|
2128
|
+
peer.connection.remoteAddress = '127.0.0.1';
|
|
2129
|
+
peer.connection.remotePort = '0000';
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2132
|
+
const peerInfo = {
|
|
2133
|
+
family: peer.connection.remoteFamily || peer.connection.localFamily,
|
|
2134
|
+
address: peer.connection.remoteAddress || peer.connection.localAddress,
|
|
2135
|
+
port: peer.connection.remotePort || peer.connection.localPort,
|
|
2136
|
+
id: from,
|
|
2137
|
+
};
|
|
2138
|
+
|
|
2139
|
+
if (proto.decoded.has) this.dht.addProvider(peerInfo, proto.decoded.hash);
|
|
2140
|
+
};
|
|
2141
|
+
let walks = [];
|
|
2142
|
+
for (const peer of this.connections) {
|
|
2143
|
+
if (peer.peerId !== this.id) {
|
|
2144
|
+
walks.push(walk(peer));
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
return Promise.all(walks)
|
|
2148
|
+
}
|
|
2149
|
+
|
|
2150
|
+
/**
|
|
2151
|
+
* Override DHT behavior, try's finding the content three times
|
|
2152
|
+
*
|
|
2153
|
+
* @param {String} hash
|
|
2154
|
+
*/
|
|
2155
|
+
async providersFor(hash) {
|
|
2156
|
+
let providers = await this.dht.providersFor(hash);
|
|
2157
|
+
// walk the network to find a provider
|
|
2158
|
+
if (!providers || providers.length === 0) {
|
|
2159
|
+
await this.walk(hash);
|
|
2160
|
+
providers = await this.dht.providersFor(hash);
|
|
2161
|
+
// second walk the network to find a provider
|
|
2162
|
+
if (!providers || providers.length === 0) {
|
|
2163
|
+
await this.walk(hash);
|
|
2164
|
+
providers = await this.dht.providersFor(hash);
|
|
2165
|
+
}
|
|
2166
|
+
// last walk
|
|
2167
|
+
if (!providers || providers.length === 0) {
|
|
2168
|
+
await this.walk(hash);
|
|
2169
|
+
providers = await this.dht.providersFor(hash);
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
// undefined if no providers given
|
|
2173
|
+
return providers
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
get block() {
|
|
2177
|
+
return {
|
|
2178
|
+
get: async (hash) => {
|
|
2179
|
+
const data = await blockStore.has(hash);
|
|
2180
|
+
if (data) return await blockStore.get(hash)
|
|
2181
|
+
return this.requestData(hash, 'block')
|
|
2182
|
+
},
|
|
2183
|
+
put: async (hash, data) => {
|
|
2184
|
+
if (await blockStore.has(hash)) return
|
|
2185
|
+
return await blockStore.put(hash, data)
|
|
2186
|
+
},
|
|
2187
|
+
has: async (hash) => await blockStore.has(hash, 'block'),
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
|
|
2191
|
+
get transaction() {
|
|
2192
|
+
return {
|
|
2193
|
+
get: async (hash) => {
|
|
2194
|
+
const data = await transactionStore.has(hash);
|
|
2195
|
+
if (data) return await transactionStore.get(hash)
|
|
2196
|
+
return this.requestData(hash, 'transaction')
|
|
2197
|
+
},
|
|
2198
|
+
put: async (hash, data) => {
|
|
2199
|
+
if (await transactionStore.has(hash)) return
|
|
2200
|
+
return await transactionStore.put(hash, data)
|
|
2201
|
+
},
|
|
2202
|
+
has: async (hash) => await transactionStore.has(hash),
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
|
|
2206
|
+
async requestData(hash, store) {
|
|
2207
|
+
const providers = await this.providersFor(hash);
|
|
2208
|
+
if (!providers || providers.size === 0) throw nothingFoundError(hash)
|
|
2209
|
+
debug(`found ${providers.size} provider(s) for ${hash}`);
|
|
2210
|
+
// get closest peer on earth
|
|
2211
|
+
const closestPeer = await this.dht.closestPeer(providers);
|
|
2212
|
+
// get peer instance by id
|
|
2213
|
+
if (!closestPeer || !closestPeer.id) return this.requestData(hash, store?.name ? store?.name : store)
|
|
2214
|
+
|
|
2215
|
+
const id = closestPeer.id;
|
|
2216
|
+
if (this.connections) {
|
|
2217
|
+
let closest = this.connections.filter((peer) => {
|
|
2218
|
+
if (peer.peerId === id) return peer
|
|
2219
|
+
});
|
|
2257
2220
|
|
|
2258
|
-
|
|
2259
|
-
return new MultiSignature__default["default"](this.version, this.network.multiCodec)
|
|
2260
|
-
.sign(hash, this.privateKeyBuffer);
|
|
2221
|
+
let data = new DataMessage({hash, store: store?.name ? store?.name : store});
|
|
2261
2222
|
|
|
2262
|
-
|
|
2223
|
+
const node = await this.prepareMessage(id, data.encoded);
|
|
2224
|
+
if (closest[0]) data = await closest[0].request(node.encoded);
|
|
2225
|
+
else {
|
|
2226
|
+
closest = this.connections.filter((peer) => {
|
|
2227
|
+
if (peer.peerId === id) return peer
|
|
2228
|
+
});
|
|
2229
|
+
if (closest[0]) data = await closest[0].request(node.encoded);
|
|
2230
|
+
}
|
|
2231
|
+
data = new Uint8Array(Object.values(data));
|
|
2232
|
+
let proto = protoFor(data);
|
|
2233
|
+
proto = protoFor(proto.decoded.data);
|
|
2234
|
+
// TODO: store data automaticly or not
|
|
2235
|
+
return proto.decoded.data
|
|
2263
2236
|
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2237
|
+
// this.put(hash, proto.decoded.data)
|
|
2238
|
+
}
|
|
2239
|
+
return null
|
|
2240
|
+
}
|
|
2268
2241
|
|
|
2269
|
-
/**
|
|
2270
|
-
* @param {number} account - account to return chain for
|
|
2271
|
-
* @return { internal(addressIndex), external(addressIndex) }
|
|
2272
|
-
*/
|
|
2273
|
-
account(index) {
|
|
2274
|
-
return new HDAccount(new MultiWallet(this.networkName, this.hdnode), index);
|
|
2275
|
-
}
|
|
2276
2242
|
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2243
|
+
get message() {
|
|
2244
|
+
return {
|
|
2245
|
+
/**
|
|
2246
|
+
* Get content for given message hash
|
|
2247
|
+
*
|
|
2248
|
+
* @param {String} hash
|
|
2249
|
+
*/
|
|
2250
|
+
get: async (hash) => {
|
|
2251
|
+
debug(`get message ${hash}`);
|
|
2252
|
+
const message = await messageStore.has(hash);
|
|
2253
|
+
if (message) return await messageStore.get(hash)
|
|
2254
|
+
return this.requestData(hash, 'message')
|
|
2255
|
+
},
|
|
2256
|
+
/**
|
|
2257
|
+
* put message content
|
|
2258
|
+
*
|
|
2259
|
+
* @param {String} hash
|
|
2260
|
+
* @param {Buffer} message
|
|
2261
|
+
*/
|
|
2262
|
+
put: async (hash, message) => await messageStore.put(hash, message),
|
|
2263
|
+
/**
|
|
2264
|
+
* @param {String} hash
|
|
2265
|
+
* @return {Boolean}
|
|
2266
|
+
*/
|
|
2267
|
+
has: async (hash) => await messageStore.has(hash),
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2285
2270
|
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2271
|
+
get data() {
|
|
2272
|
+
return {
|
|
2273
|
+
/**
|
|
2274
|
+
* Get content for given data hash
|
|
2275
|
+
*
|
|
2276
|
+
* @param {String} hash
|
|
2277
|
+
*/
|
|
2278
|
+
get: async (hash) => {
|
|
2279
|
+
debug(`get data ${hash}`);
|
|
2280
|
+
const data = await dataStore.has(hash);
|
|
2281
|
+
if (data) return await dataStore.get(hash)
|
|
2282
|
+
return this.requestData(hash, 'data')
|
|
2283
|
+
},
|
|
2284
|
+
/**
|
|
2285
|
+
* put data content
|
|
2286
|
+
*
|
|
2287
|
+
* @param {String} hash
|
|
2288
|
+
* @param {Buffer} data
|
|
2289
|
+
*/
|
|
2290
|
+
put: async (hash, data) => await dataStore.put(hash, data),
|
|
2291
|
+
/**
|
|
2292
|
+
* @param {String} hash
|
|
2293
|
+
* @return {Boolean}
|
|
2294
|
+
*/
|
|
2295
|
+
has: async (hash) => await dataStore.has(hash),
|
|
2296
|
+
}
|
|
2294
2297
|
}
|
|
2298
|
+
|
|
2295
2299
|
/**
|
|
2296
|
-
*
|
|
2297
|
-
*
|
|
2298
|
-
* @param {
|
|
2299
|
-
* @param {Buffer} message.from peer id
|
|
2300
|
-
* @param {Buffer} message.to peer id
|
|
2301
|
-
* @param {string} message.data Peernet message
|
|
2302
|
-
* (PeernetMessage excluded) encoded as a string
|
|
2303
|
-
* @return signature
|
|
2300
|
+
* goes trough given stores and tries to find data for given hash
|
|
2301
|
+
* @param {Array} stores
|
|
2302
|
+
* @param {string} hash
|
|
2304
2303
|
*/
|
|
2305
|
-
async
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2304
|
+
async whichStore(stores, hash) {
|
|
2305
|
+
let store = stores.pop();
|
|
2306
|
+
store = globalThis[`${store}Store`];
|
|
2307
|
+
if (store) {
|
|
2308
|
+
const has = await store.has(hash);
|
|
2309
|
+
if (has) return store
|
|
2310
|
+
if (stores.length > 0) return this.whichStore(stores, hash)
|
|
2311
|
+
} else return null
|
|
2312
2312
|
}
|
|
2313
2313
|
|
|
2314
2314
|
/**
|
|
2315
|
-
*
|
|
2316
|
-
*
|
|
2317
|
-
* @param {String
|
|
2318
|
-
*
|
|
2315
|
+
* Get content for given hash
|
|
2316
|
+
*
|
|
2317
|
+
* @param {String} hash - the hash of the wanted data
|
|
2318
|
+
* @param {String} store - storeName to access
|
|
2319
2319
|
*/
|
|
2320
|
-
async
|
|
2321
|
-
|
|
2320
|
+
async get(hash, store) {
|
|
2321
|
+
debug(`get ${hash}`);
|
|
2322
|
+
let data;
|
|
2323
|
+
if (store) store = globalThis[`${store}Store`];
|
|
2324
|
+
if (!store) store = await this.whichStore([...this.stores], hash);
|
|
2325
|
+
if (store && await store.has(hash)) data = await store.get(hash);
|
|
2326
|
+
if (data) return data
|
|
2322
2327
|
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
to,
|
|
2326
|
-
data,
|
|
2327
|
-
};
|
|
2328
|
-
const signature = await this.hashAndSignMessage(message);
|
|
2329
|
-
const node = new PeernetMessage({
|
|
2330
|
-
...message,
|
|
2331
|
-
signature,
|
|
2332
|
-
});
|
|
2328
|
+
return this.requestData(hash, store?.name ? store.name : store)
|
|
2329
|
+
}
|
|
2333
2330
|
|
|
2334
|
-
|
|
2331
|
+
/**
|
|
2332
|
+
* put content
|
|
2333
|
+
*
|
|
2334
|
+
* @param {String} hash
|
|
2335
|
+
* @param {Buffer} data
|
|
2336
|
+
* @param {String} store - storeName to access
|
|
2337
|
+
*/
|
|
2338
|
+
async put(hash, data, store = 'data') {
|
|
2339
|
+
store = globalThis[`${store}Store`];
|
|
2340
|
+
return store.put(hash, data)
|
|
2335
2341
|
}
|
|
2336
|
-
}
|
|
2337
|
-
|
|
2338
|
-
const dataHandler = async message => {
|
|
2339
|
-
if (!message) return
|
|
2340
2342
|
|
|
2341
|
-
|
|
2343
|
+
/**
|
|
2344
|
+
* @param {String} hash
|
|
2345
|
+
* @return {Boolean}
|
|
2346
|
+
*/
|
|
2347
|
+
async has(hash) {
|
|
2348
|
+
const store = await this.whichStore([...this.stores], hash);
|
|
2349
|
+
if (store) {
|
|
2350
|
+
if (store.private) return false
|
|
2351
|
+
else return true
|
|
2352
|
+
}
|
|
2353
|
+
return false
|
|
2354
|
+
}
|
|
2342
2355
|
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2356
|
+
/**
|
|
2357
|
+
*
|
|
2358
|
+
* @param {String} topic
|
|
2359
|
+
* @param {String|Object|Array|Boolean|Buffer} data
|
|
2360
|
+
*/
|
|
2361
|
+
async publish(topic, data) {
|
|
2362
|
+
// globalSub.publish(topic, data)
|
|
2363
|
+
if (topic instanceof Uint8Array === false) topic = new TextEncoder().encode(topic);
|
|
2364
|
+
if (data instanceof Uint8Array === false) data = new TextEncoder().encode(JSON.stringify(data));
|
|
2365
|
+
const id = Math.random().toString(36).slice(-12);
|
|
2366
|
+
data = new PsMessage({data, topic});
|
|
2367
|
+
for (const peer of this.connections) {
|
|
2368
|
+
if (peer.peerId !== this.peerId) {
|
|
2369
|
+
const node = await this.prepareMessage(peer.peerId, data.encoded);
|
|
2370
|
+
this.sendMessage(peer, id, node.encoded);
|
|
2371
|
+
}
|
|
2372
|
+
// TODO: if peer subscribed
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2346
2375
|
|
|
2347
|
-
|
|
2348
|
-
}
|
|
2349
|
-
|
|
2350
|
-
const encapsulatedError = () => {
|
|
2351
|
-
return new Error('Nodes/Data should be send encapsulated by peernet-message')
|
|
2352
|
-
};
|
|
2353
|
-
|
|
2354
|
-
const dhtError = (proto) => {
|
|
2355
|
-
const text = `Received proto ${proto.name} expected peernet-dht-response`;
|
|
2356
|
-
return new Error(`Routing error: ${text}`)
|
|
2357
|
-
};
|
|
2358
|
-
|
|
2359
|
-
const nothingFoundError = (hash) => {
|
|
2360
|
-
return new Error(`nothing found for ${hash}`)
|
|
2361
|
-
};
|
|
2362
|
-
|
|
2363
|
-
globalThis.leofcoin = globalThis.leofcoin || {};
|
|
2364
|
-
globalThis.globalSub = globalThis.globalSub || new PubSub({verbose: true});
|
|
2376
|
+
createHash(data, name) {
|
|
2377
|
+
return new codecFormatInterface.CodecHash(data, {name})
|
|
2378
|
+
}
|
|
2365
2379
|
|
|
2366
|
-
/**
|
|
2367
|
-
* @access public
|
|
2368
|
-
* @example
|
|
2369
|
-
* const peernet = new Peernet();
|
|
2370
|
-
*/
|
|
2371
|
-
class Peernet {
|
|
2372
2380
|
/**
|
|
2373
|
-
* @access public
|
|
2374
|
-
* @param {Object} options
|
|
2375
|
-
* @param {String} options.network - desired network
|
|
2376
|
-
* @param {String} options.root - path to root directory
|
|
2377
|
-
* @param {String} options.storePrefix - prefix for datatores (lfc)
|
|
2378
|
-
*
|
|
2379
|
-
* @return {Promise} instance of Peernet
|
|
2380
2381
|
*
|
|
2381
|
-
* @
|
|
2382
|
-
*
|
|
2382
|
+
* @param {String} topic
|
|
2383
|
+
* @param {Method} cb
|
|
2383
2384
|
*/
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
*/
|
|
2389
|
-
this.network = options.network || 'leofcoin';
|
|
2390
|
-
const parts = this.network.split(':');
|
|
2385
|
+
async subscribe(topic, cb) {
|
|
2386
|
+
// TODO: if peer subscribed
|
|
2387
|
+
globalSub.subscribe(topic, cb);
|
|
2388
|
+
}
|
|
2391
2389
|
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
if (!options.root) {
|
|
2395
|
-
if (parts[1]) options.root = `.${parts[0]}/peernet/${parts[1]}`;
|
|
2396
|
-
else options.root = `.${this.network}/peernet`;
|
|
2397
|
-
}
|
|
2398
|
-
globalThis.peernet = this;
|
|
2399
|
-
this.bw = {
|
|
2400
|
-
up: 0,
|
|
2401
|
-
down: 0,
|
|
2402
|
-
};
|
|
2403
|
-
return this._init(options)
|
|
2390
|
+
async removePeer(peer) {
|
|
2391
|
+
return this.client.removePeer(peer)
|
|
2404
2392
|
}
|
|
2405
2393
|
|
|
2406
|
-
get
|
|
2407
|
-
return
|
|
2394
|
+
get Buffer() {
|
|
2395
|
+
return Buffer
|
|
2408
2396
|
}
|
|
2397
|
+
// async block(index) {
|
|
2398
|
+
// const _values = []
|
|
2399
|
+
// for (const peer of this.peers) {
|
|
2400
|
+
// const value = await peer.request({type: 'block', index})
|
|
2401
|
+
// console.log(value);
|
|
2402
|
+
// }
|
|
2403
|
+
//
|
|
2404
|
+
// }
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
module.exports = Peernet;
|
|
2408
|
+
|
|
2409
|
+
|
|
2410
|
+
/***/ }),
|
|
2411
|
+
|
|
2412
|
+
/***/ 5698:
|
|
2413
|
+
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
2414
|
+
|
|
2415
|
+
"use strict";
|
|
2416
|
+
// ESM COMPAT FLAG
|
|
2417
|
+
__webpack_require__.r(__webpack_exports__);
|
|
2418
|
+
|
|
2419
|
+
// EXPORTS
|
|
2420
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
2421
|
+
"default": function() { return /* binding */ src; }
|
|
2422
|
+
});
|
|
2423
|
+
|
|
2424
|
+
// EXTERNAL MODULE: ./node_modules/@vandeurenglenn/base32/src/base32.js
|
|
2425
|
+
var src_base32 = __webpack_require__(103);
|
|
2426
|
+
// EXTERNAL MODULE: ./node_modules/@vandeurenglenn/base58/src/base58.js
|
|
2427
|
+
var src_base58 = __webpack_require__(158);
|
|
2428
|
+
;// CONCATENATED MODULE: ./node_modules/@vandeurenglenn/is-hex/is-hex.js
|
|
2429
|
+
/* harmony default export */ var is_hex = (string => /^[A-F0-9]+$/i.test(string));
|
|
2430
|
+
|
|
2431
|
+
;// CONCATENATED MODULE: ./node_modules/@leofcoin/codec-format-interface/src/basic-interface.js
|
|
2432
|
+
/* provided dependency */ var Buffer = __webpack_require__(8764)["Buffer"];
|
|
2409
2433
|
|
|
2410
|
-
|
|
2411
|
-
|
|
2434
|
+
|
|
2435
|
+
|
|
2436
|
+
|
|
2437
|
+
class BasicInterface {
|
|
2438
|
+
#handleDecode() {
|
|
2439
|
+
if (!this.decode) throw new Error('bad implementation: needs decode func')
|
|
2440
|
+
this.decode()
|
|
2412
2441
|
}
|
|
2413
2442
|
|
|
2414
|
-
|
|
2415
|
-
if (!this.
|
|
2443
|
+
#handleEncode() {
|
|
2444
|
+
if (!this.encode) throw new Error('bad implementation: needs encode func')
|
|
2445
|
+
this.encode()
|
|
2446
|
+
}
|
|
2447
|
+
isHex(string) {
|
|
2448
|
+
return is_hex(string)
|
|
2449
|
+
}
|
|
2450
|
+
isBase32(string) {
|
|
2451
|
+
return base32.isBase32(string)
|
|
2452
|
+
}
|
|
2453
|
+
isBase58(string) {
|
|
2454
|
+
return base58.isBase32(string)
|
|
2455
|
+
}
|
|
2456
|
+
/**
|
|
2457
|
+
* @param {String} encoded
|
|
2458
|
+
*/
|
|
2459
|
+
fromBs32(encoded) {
|
|
2460
|
+
this.encoded = src_base32/* default.decode */.Z.decode(encoded)
|
|
2461
|
+
return this.#handleDecode()
|
|
2416
2462
|
}
|
|
2417
2463
|
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2464
|
+
/**
|
|
2465
|
+
* @param {String} encoded
|
|
2466
|
+
*/
|
|
2467
|
+
fromBs58(encoded) {
|
|
2468
|
+
this.encoded = src_base58/* default.decode */.Z.decode(encoded)
|
|
2469
|
+
return this.#handleDecode()
|
|
2470
|
+
}
|
|
2421
2471
|
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
Storage = globalThis.LeofcoinStorage?.default ? globalThis.LeofcoinStorage.default : LeofcoinStorage__default["default"];
|
|
2472
|
+
async toArray() {
|
|
2473
|
+
const array = []
|
|
2474
|
+
for await (const value of this.encoded.values()) {
|
|
2475
|
+
array.push(value)
|
|
2427
2476
|
}
|
|
2428
|
-
|
|
2429
|
-
|
|
2477
|
+
return array
|
|
2478
|
+
}
|
|
2430
2479
|
|
|
2431
|
-
|
|
2432
|
-
|
|
2480
|
+
fromString(string) {
|
|
2481
|
+
this.encoded = new Uint8Array(string.split(','))
|
|
2482
|
+
return this.#handleDecode()
|
|
2433
2483
|
}
|
|
2434
2484
|
|
|
2485
|
+
fromArray(array) {
|
|
2486
|
+
this.encoded = new Uint8Array([...array])
|
|
2487
|
+
return this.#handleDecode()
|
|
2488
|
+
}
|
|
2435
2489
|
|
|
2436
2490
|
/**
|
|
2437
|
-
* @
|
|
2491
|
+
* @param {Buffer} encoded
|
|
2438
2492
|
*/
|
|
2439
|
-
|
|
2440
|
-
|
|
2493
|
+
fromEncoded(encoded) {
|
|
2494
|
+
this.encoded = encoded
|
|
2495
|
+
return this.#handleDecode()
|
|
2441
2496
|
}
|
|
2442
2497
|
|
|
2443
2498
|
/**
|
|
2444
|
-
* @
|
|
2445
|
-
*
|
|
2446
|
-
* @return {Array} peerId
|
|
2499
|
+
* @param {String} encoded
|
|
2447
2500
|
*/
|
|
2448
|
-
|
|
2449
|
-
|
|
2501
|
+
fromHex(encoded) {
|
|
2502
|
+
this.encoded = Buffer.from(encoded, 'hex')
|
|
2503
|
+
return this.#handleDecode()
|
|
2450
2504
|
}
|
|
2451
2505
|
|
|
2452
|
-
|
|
2453
|
-
|
|
2506
|
+
toString(encoding = 'utf8') {
|
|
2507
|
+
if (!this.encoded) this.#handleEncode()
|
|
2508
|
+
return this.encoded.toString(encoding)
|
|
2454
2509
|
}
|
|
2455
2510
|
|
|
2456
|
-
|
|
2457
|
-
|
|
2511
|
+
/**
|
|
2512
|
+
* @return {String} encoded
|
|
2513
|
+
*/
|
|
2514
|
+
toHex() {
|
|
2515
|
+
return this.toString('hex')
|
|
2458
2516
|
}
|
|
2459
2517
|
|
|
2460
2518
|
/**
|
|
2461
|
-
* @return {String}
|
|
2519
|
+
* @return {String} encoded
|
|
2462
2520
|
*/
|
|
2463
|
-
|
|
2464
|
-
|
|
2521
|
+
toBs32() {
|
|
2522
|
+
if (!this.encoded) this.#handleEncode()
|
|
2523
|
+
return src_base32/* default.encode */.Z.encode(this.encoded)
|
|
2465
2524
|
}
|
|
2466
2525
|
|
|
2467
2526
|
/**
|
|
2468
|
-
* @
|
|
2469
|
-
*
|
|
2470
|
-
* @param {Object} options
|
|
2471
|
-
* @param {String} options.root - path to root directory
|
|
2472
|
-
*
|
|
2473
|
-
* @return {Promise} instance of Peernet
|
|
2527
|
+
* @return {String} encoded
|
|
2474
2528
|
*/
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
* @property {Object} peer Instance of Peer
|
|
2480
|
-
*/
|
|
2481
|
-
this.dht = new DhtEarth();
|
|
2482
|
-
/**
|
|
2483
|
-
* @type {Map}
|
|
2484
|
-
* @property {Object} peer Instance of Peer
|
|
2485
|
-
*/
|
|
2486
|
-
this.stores = [];
|
|
2487
|
-
this.requestProtos = {};
|
|
2488
|
-
this.storePrefix = options.storePrefix;
|
|
2489
|
-
this.root = options.root;
|
|
2490
|
-
|
|
2491
|
-
/**
|
|
2492
|
-
* proto Object containing protos
|
|
2493
|
-
* @type {Object}
|
|
2494
|
-
* @property {PeernetMessage} protos[peernet-message] messageNode
|
|
2495
|
-
* @property {DHTMessage} protos[peernet-dht] messageNode
|
|
2496
|
-
* @property {DHTMessageResponse} protos[peernet-dht-response] messageNode
|
|
2497
|
-
* @property {DataMessage} protos[peernet-data] messageNode
|
|
2498
|
-
* @property {DataMessageResponse} protos[peernet-data-response] messageNode
|
|
2499
|
-
*/
|
|
2500
|
-
globalThis.peernet.protos = {
|
|
2501
|
-
'peernet-request': RequestMessage,
|
|
2502
|
-
'peernet-response': ResponseMessage,
|
|
2503
|
-
'peernet-peer': PeerMessage,
|
|
2504
|
-
'peernet-peer-response': PeerMessageResponse,
|
|
2505
|
-
'peernet-message': PeernetMessage,
|
|
2506
|
-
'peernet-dht': DHTMessage,
|
|
2507
|
-
'peernet-dht-response': DHTMessageResponse,
|
|
2508
|
-
'peernet-data': DataMessage,
|
|
2509
|
-
'peernet-data-response': DataMessageResponse,
|
|
2510
|
-
'peernet-ps': PsMessage,
|
|
2511
|
-
'chat-message': ChatMessage,
|
|
2512
|
-
};
|
|
2529
|
+
toBs58() {
|
|
2530
|
+
if (!this.encoded) this.#handleEncode()
|
|
2531
|
+
return src_base58/* default.encode */.Z.encode(this.encoded)
|
|
2532
|
+
}
|
|
2513
2533
|
|
|
2514
|
-
|
|
2515
|
-
|
|
2534
|
+
/**
|
|
2535
|
+
* @param {Object} data
|
|
2536
|
+
*/
|
|
2537
|
+
create(data) {
|
|
2538
|
+
const decoded = {}
|
|
2539
|
+
if (this.keys?.length > 0) {
|
|
2540
|
+
for (const key of this.keys) {
|
|
2541
|
+
Object.defineProperties(decoded, {
|
|
2542
|
+
[key]: {
|
|
2543
|
+
enumerable: true,
|
|
2544
|
+
configurable: true,
|
|
2545
|
+
set: (val) => value = data[key],
|
|
2546
|
+
get: () => data[key]
|
|
2547
|
+
}
|
|
2548
|
+
})
|
|
2549
|
+
}
|
|
2516
2550
|
|
|
2517
|
-
|
|
2551
|
+
this.decoded = decoded
|
|
2552
|
+
this.encode()
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2557
|
+
// EXTERNAL MODULE: ./node_modules/varint/index.js
|
|
2558
|
+
var varint = __webpack_require__(4676);
|
|
2559
|
+
var varint_default = /*#__PURE__*/__webpack_require__.n(varint);
|
|
2560
|
+
;// CONCATENATED MODULE: ./node_modules/@leofcoin/codec-format-interface/src/codecs.js
|
|
2561
|
+
/* harmony default export */ var codecs = ({
|
|
2562
|
+
// just a hash
|
|
2563
|
+
'disco-hash': {
|
|
2564
|
+
codec: parseInt('30', 16),
|
|
2565
|
+
hashAlg: 'dbl-keccak-256', // ,
|
|
2566
|
+
// testnet: 'olivia'
|
|
2567
|
+
},
|
|
2568
|
+
'peernet-peer-response': {
|
|
2569
|
+
codec: parseInt('707072', 16),
|
|
2570
|
+
hashAlg: 'keccak-256',
|
|
2571
|
+
},
|
|
2572
|
+
'peernet-peer': {
|
|
2573
|
+
codec: parseInt('7070', 16),
|
|
2574
|
+
hashAlg: 'keccak-256',
|
|
2575
|
+
},
|
|
2576
|
+
'peernet-dht': {
|
|
2577
|
+
codec: parseInt('706468', 16),
|
|
2578
|
+
hashAlg: 'keccak-256',
|
|
2579
|
+
},
|
|
2580
|
+
'peernet-dht-response': {
|
|
2581
|
+
codec: parseInt('706472', 16),
|
|
2582
|
+
hashAlg: 'keccak-256',
|
|
2583
|
+
},
|
|
2584
|
+
// data
|
|
2585
|
+
'peernet-data': {
|
|
2586
|
+
codec: parseInt('706461', 16),
|
|
2587
|
+
hashAlg: 'keccak-256',
|
|
2588
|
+
},
|
|
2589
|
+
'peernet-data-response': {
|
|
2590
|
+
codec: parseInt('70646172', 16),
|
|
2591
|
+
hashAlg: 'keccak-256',
|
|
2592
|
+
},
|
|
2593
|
+
// message
|
|
2594
|
+
'peernet-message': {
|
|
2595
|
+
codec: parseInt('706d65', 16),
|
|
2596
|
+
hashAlg: 'keccak-256',
|
|
2597
|
+
},
|
|
2598
|
+
// pubsub
|
|
2599
|
+
'peernet-ps': {
|
|
2600
|
+
codec: parseInt('707073', 16),
|
|
2601
|
+
hashAlg: 'keccak-256',
|
|
2602
|
+
},
|
|
2603
|
+
'peernet-response': {
|
|
2604
|
+
codec: parseInt('7072', 16),
|
|
2605
|
+
hashAlg: 'keccak-256',
|
|
2606
|
+
},
|
|
2607
|
+
'peernet-request': {
|
|
2608
|
+
codec: parseInt('707271', 16),
|
|
2609
|
+
hashAlg: 'keccak-256',
|
|
2610
|
+
},
|
|
2611
|
+
// normal block
|
|
2612
|
+
'leofcoin-block': {
|
|
2613
|
+
codec: parseInt('6c62', 16),
|
|
2614
|
+
hashAlg: 'dbl-keccak-512', // ,
|
|
2615
|
+
// testnet: 'olivia'
|
|
2616
|
+
},
|
|
2617
|
+
'leofcoin-tx': {
|
|
2618
|
+
codec: parseInt('6c74', 16),
|
|
2619
|
+
hashAlg: 'dbl-keccak-512', // ,
|
|
2620
|
+
// testnet: 'olivia'
|
|
2621
|
+
},
|
|
2622
|
+
// itx
|
|
2623
|
+
'leofcoin-itx': {
|
|
2624
|
+
codec: parseInt('6c69', 16),
|
|
2625
|
+
hashAlg: 'keccak-512', // ,
|
|
2626
|
+
// testnet: 'olivia'
|
|
2627
|
+
},
|
|
2628
|
+
// peer reputation
|
|
2629
|
+
'leofcoin-pr': {
|
|
2630
|
+
codec: parseInt('6c70', 16),
|
|
2631
|
+
hashAlg: 'keccak-256', // ,
|
|
2632
|
+
// testnet: 'olivia'
|
|
2633
|
+
},
|
|
2634
|
+
// chat message
|
|
2635
|
+
'chat-message': {
|
|
2636
|
+
codec: parseInt('636d', 16),
|
|
2637
|
+
hashAlg: 'dbl-keccak-256',
|
|
2638
|
+
},
|
|
2639
|
+
});
|
|
2640
|
+
|
|
2641
|
+
;// CONCATENATED MODULE: ./node_modules/@leofcoin/codec-format-interface/src/codec.js
|
|
2518
2642
|
|
|
2519
|
-
const {daemon, environment} = await target();
|
|
2520
|
-
this.hasDaemon = daemon;
|
|
2521
2643
|
|
|
2522
|
-
|
|
2523
2644
|
|
|
2524
|
-
for (const store of this.defaultStores) {
|
|
2525
|
-
await this.addStore(store, options.storePrefix, options.root);
|
|
2526
|
-
}
|
|
2527
2645
|
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2646
|
+
class PeernetCodec extends BasicInterface {
|
|
2647
|
+
get codecs() {
|
|
2648
|
+
return {...globalThis.peernet.codecs, ...codecs}
|
|
2649
|
+
}
|
|
2650
|
+
constructor(buffer) {
|
|
2651
|
+
super()
|
|
2652
|
+
if (buffer) {
|
|
2653
|
+
if (buffer instanceof Uint8Array) {
|
|
2654
|
+
const codec = varint_default().decode(buffer);
|
|
2655
|
+
const name = this.getCodecName(codec)
|
|
2656
|
+
if (name) {
|
|
2657
|
+
this.name = name
|
|
2658
|
+
this.encoded = buffer
|
|
2659
|
+
this.decode(buffer)
|
|
2660
|
+
} else {
|
|
2661
|
+
this.encode(buffer)
|
|
2662
|
+
}
|
|
2663
|
+
} else if (buffer instanceof ArrayBuffer) {
|
|
2664
|
+
const encoded = new Uint8Array(buffer.byteLength)
|
|
2539
2665
|
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2666
|
+
for (let i = 0; i < buffer.byteLength; i++) {
|
|
2667
|
+
encoded[i] = buffer[i]
|
|
2668
|
+
}
|
|
2669
|
+
this.encoded = encoded
|
|
2670
|
+
// this.encoded = new Uint8Array(buffer, buffer.byteOffset, buffer.byteLength)
|
|
2671
|
+
this.decode(buffer)
|
|
2672
|
+
return
|
|
2673
|
+
}
|
|
2674
|
+
if (typeof buffer === 'string') {
|
|
2675
|
+
if (this.codecs[buffer]) this.fromName(buffer)
|
|
2676
|
+
else if (this.isHex(buffer)) this.fromHex(buffer)
|
|
2677
|
+
else if (this.isBase32(buffer)) this.fromBs32(buffer)
|
|
2678
|
+
else if (this.isBase58(buffer)) this.fromBs58(buffer)
|
|
2679
|
+
else throw new Error(`unsupported string ${buffer}`)
|
|
2543
2680
|
}
|
|
2681
|
+
if (!isNaN(buffer)) if (this.codecs[this.getCodecName(buffer)]) this.fromCodec(buffer)
|
|
2544
2682
|
}
|
|
2545
|
-
|
|
2546
|
-
this.peerId = this.id;
|
|
2683
|
+
}
|
|
2547
2684
|
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
// this._protoHandler({id, proto}, peer)
|
|
2556
|
-
// })
|
|
2557
|
-
});
|
|
2685
|
+
fromEncoded(encoded) {
|
|
2686
|
+
const codec = varint_default().decode(encoded);
|
|
2687
|
+
const name = this.getCodecName(codec)
|
|
2688
|
+
this.name = name
|
|
2689
|
+
this.encoded = encoded
|
|
2690
|
+
this.decode(encoded)
|
|
2691
|
+
}
|
|
2558
2692
|
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
*/
|
|
2563
|
-
pubsub.subscribe('peer:data', dataHandler);
|
|
2693
|
+
getCodec(name) {
|
|
2694
|
+
return this.codecs[name].codec
|
|
2695
|
+
}
|
|
2564
2696
|
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
globalThis.addEventListener('beforeunload', async () => this.client.close());
|
|
2572
|
-
}
|
|
2573
|
-
return this
|
|
2697
|
+
getCodecName(codec) {
|
|
2698
|
+
return Object.keys(this.codecs).reduce((p, c) => {
|
|
2699
|
+
const item = this.codecs[c]
|
|
2700
|
+
if (item.codec === codec) return c;
|
|
2701
|
+
else return p;
|
|
2702
|
+
}, undefined)
|
|
2574
2703
|
}
|
|
2575
2704
|
|
|
2576
|
-
|
|
2577
|
-
this.
|
|
2705
|
+
getHashAlg(name) {
|
|
2706
|
+
return this.codecs[name].hashAlg
|
|
2578
2707
|
}
|
|
2579
2708
|
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
this.bw.up += data.length;
|
|
2584
|
-
} else if (peer.readyState === 'closed') ;
|
|
2709
|
+
fromCodec(codec) {
|
|
2710
|
+
this.name = this.getCodecName(codec)
|
|
2711
|
+
this.hashAlg = this.getHashAlg(this.name)
|
|
2585
2712
|
|
|
2713
|
+
this.codec = this.getCodec(this.name)
|
|
2714
|
+
this.codecBuffer = varint_default().encode(codec)
|
|
2586
2715
|
}
|
|
2587
2716
|
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2717
|
+
fromName(name) {
|
|
2718
|
+
const codec = this.getCodec(name)
|
|
2719
|
+
this.name = name
|
|
2720
|
+
this.codec = codec
|
|
2721
|
+
this.hashAlg = this.getHashAlg(name)
|
|
2722
|
+
this.codecBuffer = varint_default().encode(codec)
|
|
2723
|
+
}
|
|
2595
2724
|
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
let has;
|
|
2725
|
+
decode() {
|
|
2726
|
+
const codec = varint_default().decode(this.encoded);
|
|
2727
|
+
this.fromCodec(codec)
|
|
2728
|
+
}
|
|
2601
2729
|
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2730
|
+
encode() {
|
|
2731
|
+
const codec = varint_default().encode(this.decoded)
|
|
2732
|
+
this.encoded = codec
|
|
2733
|
+
return this.encoded
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
|
|
2737
|
+
// EXTERNAL MODULE: ./node_modules/keccak/js.js
|
|
2738
|
+
var js = __webpack_require__(5811);
|
|
2739
|
+
var js_default = /*#__PURE__*/__webpack_require__.n(js);
|
|
2740
|
+
;// CONCATENATED MODULE: ./node_modules/@leofcoin/codec-format-interface/src/codec-hash.js
|
|
2741
|
+
/* provided dependency */ var codec_hash_Buffer = __webpack_require__(8764)["Buffer"];
|
|
2611
2742
|
|
|
2612
|
-
this.sendMessage(peer, id, node.encoded);
|
|
2613
|
-
} else if (proto.name === 'peernet-data') {
|
|
2614
|
-
let { hash, store } = proto.decoded;
|
|
2615
|
-
let data;
|
|
2616
|
-
if (!store) {
|
|
2617
|
-
store = await this.whichStore([...this.stores], hash);
|
|
2618
|
-
} else {
|
|
2619
|
-
store = globalThis[`${store}Store`];
|
|
2620
|
-
}
|
|
2621
|
-
if (store && !store.private) {
|
|
2622
|
-
data = await store.get(hash);
|
|
2623
2743
|
|
|
2624
|
-
if (data) {
|
|
2625
|
-
data = new DataMessageResponse({hash, data});
|
|
2626
2744
|
|
|
2627
|
-
const node = await this.prepareMessage(from, data.encoded);
|
|
2628
|
-
this.sendMessage(peer, id, node.encoded);
|
|
2629
|
-
}
|
|
2630
|
-
}
|
|
2631
2745
|
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2746
|
+
|
|
2747
|
+
class CodecHash extends BasicInterface {
|
|
2748
|
+
constructor(buffer, options = {}) {
|
|
2749
|
+
super()
|
|
2750
|
+
if (options.name) this.name = options.name
|
|
2751
|
+
else this.name = 'disco-hash'
|
|
2752
|
+
if (options.codecs) this.codecs = options.codecs
|
|
2753
|
+
if (buffer) {
|
|
2754
|
+
if (buffer instanceof Uint8Array) {
|
|
2755
|
+
this.discoCodec = new PeernetCodec(buffer, this.codecs)
|
|
2756
|
+
const name = this.discoCodec.name
|
|
2757
|
+
|
|
2758
|
+
if (name) {
|
|
2759
|
+
this.name = name
|
|
2760
|
+
this.decode(buffer)
|
|
2761
|
+
} else {
|
|
2762
|
+
this.encode(buffer)
|
|
2638
2763
|
}
|
|
2639
|
-
} else if (proto.name === 'peernet-ps' && peer.peerId !== this.id) {
|
|
2640
|
-
globalSub.publish(new TextDecoder().decode(proto.decoded.topic), proto.decoded.data);
|
|
2641
2764
|
}
|
|
2642
|
-
// }
|
|
2643
|
-
}
|
|
2644
2765
|
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
this.client.id;
|
|
2654
|
-
const walk = async peer => {
|
|
2655
|
-
const node = await this.prepareMessage(peer.peerId, data.encoded);
|
|
2656
|
-
let result = await peer.request(node.encoded);
|
|
2657
|
-
result = new Uint8Array(Object.values(result));
|
|
2658
|
-
let proto = protoFor(result);
|
|
2659
|
-
if (proto.name !== 'peernet-message') throw encapsulatedError()
|
|
2660
|
-
const from = proto.decoded.from;
|
|
2661
|
-
proto = protoFor(proto.decoded.data);
|
|
2662
|
-
if (proto.name !== 'peernet-dht-response') throw dhtError(proto.name)
|
|
2766
|
+
if (typeof buffer === 'string') {
|
|
2767
|
+
if (this.isHex(buffer)) this.fromHex(buffer)
|
|
2768
|
+
if (this.isBase32(buffer)) this.fromBs32(buffer)
|
|
2769
|
+
else if (this.isBase58(buffer)) this.fromBs58(buffer)
|
|
2770
|
+
else throw new Error(`unsupported string ${buffer}`)
|
|
2771
|
+
} else if (typeof buffer === 'object') this.fromJSON(buffer)
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2663
2774
|
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
}
|
|
2775
|
+
get prefix() {
|
|
2776
|
+
const length = this.length
|
|
2777
|
+
const uint8Array = new Uint8Array(length.length + this.discoCodec.codecBuffer.length)
|
|
2778
|
+
uint8Array.set(length)
|
|
2779
|
+
uint8Array.set(this.discoCodec.codecBuffer, length.length)
|
|
2670
2780
|
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
address: peer.connection.remoteAddress || peer.connection.localAddress,
|
|
2674
|
-
port: peer.connection.remotePort || peer.connection.localPort,
|
|
2675
|
-
id: from,
|
|
2676
|
-
};
|
|
2781
|
+
return uint8Array
|
|
2782
|
+
}
|
|
2677
2783
|
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
let walks = [];
|
|
2681
|
-
for (const peer of this.connections) {
|
|
2682
|
-
if (peer.peerId !== this.id) {
|
|
2683
|
-
walks.push(walk(peer));
|
|
2684
|
-
}
|
|
2685
|
-
}
|
|
2686
|
-
return Promise.all(walks)
|
|
2784
|
+
get length() {
|
|
2785
|
+
return varint_default().encode(this.size)
|
|
2687
2786
|
}
|
|
2688
2787
|
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
*
|
|
2692
|
-
* @param {String} hash
|
|
2693
|
-
*/
|
|
2694
|
-
async providersFor(hash) {
|
|
2695
|
-
let providers = await this.dht.providersFor(hash);
|
|
2696
|
-
// walk the network to find a provider
|
|
2697
|
-
if (!providers || providers.length === 0) {
|
|
2698
|
-
await this.walk(hash);
|
|
2699
|
-
providers = await this.dht.providersFor(hash);
|
|
2700
|
-
// second walk the network to find a provider
|
|
2701
|
-
if (!providers || providers.length === 0) {
|
|
2702
|
-
await this.walk(hash);
|
|
2703
|
-
providers = await this.dht.providersFor(hash);
|
|
2704
|
-
}
|
|
2705
|
-
// last walk
|
|
2706
|
-
if (!providers || providers.length === 0) {
|
|
2707
|
-
await this.walk(hash);
|
|
2708
|
-
providers = await this.dht.providersFor(hash);
|
|
2709
|
-
}
|
|
2710
|
-
}
|
|
2711
|
-
// undefined if no providers given
|
|
2712
|
-
return providers
|
|
2788
|
+
get buffer() {
|
|
2789
|
+
return this.encoded
|
|
2713
2790
|
}
|
|
2714
2791
|
|
|
2715
|
-
get
|
|
2716
|
-
return
|
|
2717
|
-
get: async (hash) => {
|
|
2718
|
-
const data = await blockStore.has(hash);
|
|
2719
|
-
if (data) return await blockStore.get(hash)
|
|
2720
|
-
return this.requestData(hash, 'block')
|
|
2721
|
-
},
|
|
2722
|
-
put: async (hash, data) => {
|
|
2723
|
-
if (await blockStore.has(hash)) return
|
|
2724
|
-
return await blockStore.put(hash, data)
|
|
2725
|
-
},
|
|
2726
|
-
has: async (hash) => await blockStore.has(hash, 'block'),
|
|
2727
|
-
}
|
|
2792
|
+
get hash() {
|
|
2793
|
+
return this.encoded
|
|
2728
2794
|
}
|
|
2729
2795
|
|
|
2730
|
-
|
|
2731
|
-
return
|
|
2732
|
-
get: async (hash) => {
|
|
2733
|
-
const data = await transactionStore.has(hash);
|
|
2734
|
-
if (data) return await transactionStore.get(hash)
|
|
2735
|
-
return this.requestData(hash, 'transaction')
|
|
2736
|
-
},
|
|
2737
|
-
put: async (hash, data) => {
|
|
2738
|
-
if (await transactionStore.has(hash)) return
|
|
2739
|
-
return await transactionStore.put(hash, data)
|
|
2740
|
-
},
|
|
2741
|
-
has: async (hash) => await transactionStore.has(hash),
|
|
2742
|
-
}
|
|
2796
|
+
fromJSON(json) {
|
|
2797
|
+
return this.encode(codec_hash_Buffer.from(JSON.stringify(json)))
|
|
2743
2798
|
}
|
|
2744
2799
|
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
if (!
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2800
|
+
encode(buffer, name) {
|
|
2801
|
+
if (!this.name && name) this.name = name;
|
|
2802
|
+
if (!buffer) buffer = this.buffer;
|
|
2803
|
+
this.discoCodec = new PeernetCodec(this.name, this.codecs)
|
|
2804
|
+
this.discoCodec.fromName(this.name)
|
|
2805
|
+
let hashAlg = this.discoCodec.hashAlg
|
|
2806
|
+
if (hashAlg.includes('dbl')) {
|
|
2807
|
+
hashAlg = hashAlg.replace('dbl-', '')
|
|
2808
|
+
buffer = js_default()(hashAlg.replace('-', '')).update(buffer).digest()
|
|
2809
|
+
}
|
|
2810
|
+
this.digest = js_default()(hashAlg.replace('-', '')).update(buffer).digest()
|
|
2811
|
+
this.size = this.digest.length
|
|
2753
2812
|
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2813
|
+
this.codec = this.discoCodec.encode();
|
|
2814
|
+
this.codec = this.discoCodec.codecBuffer
|
|
2815
|
+
const uint8Array = new Uint8Array(this.digest.length + this.prefix.length)
|
|
2816
|
+
uint8Array.set(this.prefix)
|
|
2817
|
+
uint8Array.set(this.digest, this.prefix.length)
|
|
2759
2818
|
|
|
2760
|
-
|
|
2819
|
+
this.encoded = uint8Array
|
|
2761
2820
|
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
else {
|
|
2765
|
-
closest = this.connections.filter((peer) => {
|
|
2766
|
-
if (peer.peerId === id) return peer
|
|
2767
|
-
});
|
|
2768
|
-
if (closest[0]) data = await closest[0].request(node.encoded);
|
|
2769
|
-
}
|
|
2770
|
-
data = new Uint8Array(Object.values(data));
|
|
2771
|
-
let proto = protoFor(data);
|
|
2772
|
-
proto = protoFor(proto.decoded.data);
|
|
2773
|
-
// TODO: store data automaticly or not
|
|
2774
|
-
return proto.decoded.data
|
|
2821
|
+
return this.encoded
|
|
2822
|
+
}
|
|
2775
2823
|
|
|
2776
|
-
|
|
2824
|
+
validate(buffer) {
|
|
2825
|
+
if (codec_hash_Buffer.isBuffer(buffer)) {
|
|
2826
|
+
const codec = varint_default().decode(buffer);
|
|
2827
|
+
if (this.codecs[codec]) {
|
|
2828
|
+
this.decode(buffer)
|
|
2829
|
+
} else {
|
|
2830
|
+
this.encode(buffer)
|
|
2831
|
+
}
|
|
2777
2832
|
}
|
|
2778
|
-
|
|
2833
|
+
if (typeof buffer === 'string') {
|
|
2834
|
+
if (this.isHex(buffer)) this.fromHex(buffer)
|
|
2835
|
+
if (this.isBase32(buffer)) this.fromBs32(buffer)
|
|
2836
|
+
}
|
|
2837
|
+
if (typeof buffer === 'object') this.fromJSON(buffer)
|
|
2779
2838
|
}
|
|
2780
2839
|
|
|
2840
|
+
decode(buffer) {
|
|
2841
|
+
this.encoded = buffer
|
|
2842
|
+
const codec = varint_default().decode(buffer);
|
|
2781
2843
|
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
get: async (hash) => {
|
|
2790
|
-
debug(`get message ${hash}`);
|
|
2791
|
-
const message = await messageStore.has(hash);
|
|
2792
|
-
if (message) return await messageStore.get(hash)
|
|
2793
|
-
return this.requestData(hash, 'message')
|
|
2794
|
-
},
|
|
2795
|
-
/**
|
|
2796
|
-
* put message content
|
|
2797
|
-
*
|
|
2798
|
-
* @param {String} hash
|
|
2799
|
-
* @param {Buffer} message
|
|
2800
|
-
*/
|
|
2801
|
-
put: async (hash, message) => await messageStore.put(hash, message),
|
|
2802
|
-
/**
|
|
2803
|
-
* @param {String} hash
|
|
2804
|
-
* @return {Boolean}
|
|
2805
|
-
*/
|
|
2806
|
-
has: async (hash) => await messageStore.has(hash),
|
|
2844
|
+
this.discoCodec = new PeernetCodec(codec, this.codecs)
|
|
2845
|
+
// TODO: validate codec
|
|
2846
|
+
buffer = buffer.slice((varint_default()).decode.bytes);
|
|
2847
|
+
this.size = varint_default().decode(buffer);
|
|
2848
|
+
this.digest = buffer.slice((varint_default()).decode.bytes);
|
|
2849
|
+
if (this.digest.length !== this.size) {
|
|
2850
|
+
throw new Error(`hash length inconsistent: 0x${this.encoded.toString('hex')}`)
|
|
2807
2851
|
}
|
|
2808
|
-
}
|
|
2809
2852
|
|
|
2810
|
-
|
|
2853
|
+
// const discoCodec = new Codec(codec, this.codecs)
|
|
2854
|
+
|
|
2855
|
+
this.name = this.discoCodec.name
|
|
2856
|
+
|
|
2857
|
+
|
|
2858
|
+
this.size = this.digest.length
|
|
2859
|
+
|
|
2811
2860
|
return {
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
get: async (hash) => {
|
|
2818
|
-
debug(`get data ${hash}`);
|
|
2819
|
-
const data = await dataStore.has(hash);
|
|
2820
|
-
if (data) return await dataStore.get(hash)
|
|
2821
|
-
return this.requestData(hash, 'data')
|
|
2822
|
-
},
|
|
2823
|
-
/**
|
|
2824
|
-
* put data content
|
|
2825
|
-
*
|
|
2826
|
-
* @param {String} hash
|
|
2827
|
-
* @param {Buffer} data
|
|
2828
|
-
*/
|
|
2829
|
-
put: async (hash, data) => await dataStore.put(hash, data),
|
|
2830
|
-
/**
|
|
2831
|
-
* @param {String} hash
|
|
2832
|
-
* @return {Boolean}
|
|
2833
|
-
*/
|
|
2834
|
-
has: async (hash) => await dataStore.has(hash),
|
|
2861
|
+
codec: this.codec,
|
|
2862
|
+
name: this.name,
|
|
2863
|
+
size: this.size,
|
|
2864
|
+
length: this.length,
|
|
2865
|
+
digest: this.digest,
|
|
2835
2866
|
}
|
|
2836
2867
|
}
|
|
2868
|
+
}
|
|
2869
|
+
|
|
2870
|
+
;// CONCATENATED MODULE: ./node_modules/@leofcoin/codec-format-interface/src/codec-format-interface.js
|
|
2871
|
+
|
|
2837
2872
|
|
|
2873
|
+
|
|
2874
|
+
|
|
2875
|
+
class FormatInterface extends BasicInterface {
|
|
2838
2876
|
/**
|
|
2839
|
-
*
|
|
2840
|
-
* @param {
|
|
2841
|
-
* @param {
|
|
2877
|
+
* @param {Buffer|String|Object} buffer - data - The data needed to create the desired message
|
|
2878
|
+
* @param {Object} proto - {encode, decode}
|
|
2879
|
+
* @param {Object} options - {hashFormat, name}
|
|
2842
2880
|
*/
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2881
|
+
constructor(buffer, proto, options = {}) {
|
|
2882
|
+
super()
|
|
2883
|
+
this.protoEncode = proto.encode
|
|
2884
|
+
this.protoDecode = proto.decode
|
|
2885
|
+
this.hashFormat = options.hashFormat || 'bs32'
|
|
2886
|
+
if (options.name) this.name = options.name
|
|
2887
|
+
if (buffer instanceof Uint8Array) this.fromUint8Array(buffer)
|
|
2888
|
+
else if (buffer instanceof ArrayBuffer) this.fromArrayBuffer(buffer)
|
|
2889
|
+
else if (buffer.name === options.name) return buffer
|
|
2890
|
+
else if (buffer instanceof String) {
|
|
2891
|
+
if (this.isHex(buffer)) this.fromHex(buffer)
|
|
2892
|
+
else if (this.isBase32(buffer)) this.fromBs32(buffer)
|
|
2893
|
+
else if (this.isBase58(buffer)) this.fromBs58(buffer)
|
|
2894
|
+
else throw new Error(`unsupported string ${buffer}`)
|
|
2895
|
+
} else {
|
|
2896
|
+
this.create(buffer)
|
|
2897
|
+
}
|
|
2851
2898
|
}
|
|
2852
2899
|
|
|
2853
2900
|
/**
|
|
2854
|
-
*
|
|
2855
|
-
*
|
|
2856
|
-
* @param {String} hash - the hash of the wanted data
|
|
2857
|
-
* @param {String} store - storeName to access
|
|
2901
|
+
* @return {PeernetHash}
|
|
2858
2902
|
*/
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
let data;
|
|
2862
|
-
if (store) store = globalThis[`${store}Store`];
|
|
2863
|
-
if (!store) store = await this.whichStore([...this.stores], hash);
|
|
2864
|
-
if (store && await store.has(hash)) data = await store.get(hash);
|
|
2865
|
-
if (data) return data
|
|
2866
|
-
|
|
2867
|
-
return this.requestData(hash, store?.name ? store.name : store)
|
|
2903
|
+
get peernetHash() {
|
|
2904
|
+
return new CodecHash(this.decoded, {name: this.name})
|
|
2868
2905
|
}
|
|
2869
2906
|
|
|
2870
2907
|
/**
|
|
2871
|
-
*
|
|
2872
|
-
*
|
|
2873
|
-
* @param {String} hash
|
|
2874
|
-
* @param {Buffer} data
|
|
2875
|
-
* @param {String} store - storeName to access
|
|
2908
|
+
* @return {peernetHash}
|
|
2876
2909
|
*/
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2910
|
+
get hash() {
|
|
2911
|
+
const upper = this.hashFormat.charAt(0).toUpperCase()
|
|
2912
|
+
const format = `${upper}${this.hashFormat.substring(1, this.hashFormat.length)}`
|
|
2913
|
+
return this.peernetHash[`to${format}`]()
|
|
2880
2914
|
}
|
|
2881
2915
|
|
|
2882
2916
|
/**
|
|
2883
|
-
* @
|
|
2884
|
-
* @return {Boolean}
|
|
2917
|
+
* @return {Object}
|
|
2885
2918
|
*/
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
return
|
|
2919
|
+
decode() {
|
|
2920
|
+
let encoded = this.encoded;
|
|
2921
|
+
const discoCodec = new PeernetCodec(this.encoded)
|
|
2922
|
+
encoded = encoded.slice(discoCodec.codecBuffer.length)
|
|
2923
|
+
this.name = discoCodec.name
|
|
2924
|
+
this.decoded = this.protoDecode(encoded)
|
|
2925
|
+
return this.decoded
|
|
2893
2926
|
}
|
|
2894
2927
|
|
|
2895
2928
|
/**
|
|
2896
|
-
*
|
|
2897
|
-
* @param {String} topic
|
|
2898
|
-
* @param {String|Object|Array|Boolean|Buffer} data
|
|
2929
|
+
* @return {Buffer}
|
|
2899
2930
|
*/
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
const
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
this.sendMessage(peer, id, node.encoded);
|
|
2910
|
-
}
|
|
2911
|
-
// TODO: if peer subscribed
|
|
2912
|
-
}
|
|
2913
|
-
}
|
|
2914
|
-
|
|
2915
|
-
createHash(data, name) {
|
|
2916
|
-
return new PeernetHash(data, {name})
|
|
2931
|
+
encode(decoded) {
|
|
2932
|
+
if (!decoded) decoded = this.decoded;
|
|
2933
|
+
const codec = new PeernetCodec(this.name)
|
|
2934
|
+
const encoded = this.protoEncode(decoded)
|
|
2935
|
+
const uint8Array = new Uint8Array(encoded.length + codec.codecBuffer.length)
|
|
2936
|
+
uint8Array.set(codec.codecBuffer)
|
|
2937
|
+
uint8Array.set(encoded, codec.codecBuffer.length)
|
|
2938
|
+
this.encoded = uint8Array
|
|
2939
|
+
return this.encoded
|
|
2917
2940
|
}
|
|
2918
2941
|
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
*/
|
|
2924
|
-
async subscribe(topic, cb) {
|
|
2925
|
-
// TODO: if peer subscribed
|
|
2926
|
-
globalSub.subscribe(topic, cb);
|
|
2942
|
+
hasCodec() {
|
|
2943
|
+
if (!this.encoded) return false
|
|
2944
|
+
const codec = new PeernetCodec(this.encoded)
|
|
2945
|
+
if (codec.name) return true
|
|
2927
2946
|
}
|
|
2928
2947
|
|
|
2929
|
-
|
|
2930
|
-
|
|
2948
|
+
fromUint8Array(buffer) {
|
|
2949
|
+
this.encoded = buffer
|
|
2950
|
+
if (!this.hasCodec()) this.create(
|
|
2951
|
+
JSON.parse(new TextDecoder().decode(this.encoded))
|
|
2952
|
+
)
|
|
2953
|
+
else this.decode()
|
|
2931
2954
|
}
|
|
2932
2955
|
|
|
2933
|
-
|
|
2934
|
-
|
|
2956
|
+
fromArrayBuffer(buffer) {
|
|
2957
|
+
this.encoded = new Uint8Array(buffer, buffer.byteOffset, buffer.byteLength)
|
|
2958
|
+
if (!this.hasCodec()) this.create(
|
|
2959
|
+
JSON.parse(new TextDecoder().decode(this.encoded))
|
|
2960
|
+
)
|
|
2961
|
+
else this.decode()
|
|
2935
2962
|
}
|
|
2936
|
-
|
|
2937
|
-
// const _values = []
|
|
2938
|
-
// for (const peer of this.peers) {
|
|
2939
|
-
// const value = await peer.request({type: 'block', index})
|
|
2940
|
-
// console.log(value);
|
|
2941
|
-
// }
|
|
2942
|
-
//
|
|
2943
|
-
// }
|
|
2944
|
-
}
|
|
2963
|
+
}
|
|
2945
2964
|
|
|
2946
|
-
|
|
2965
|
+
;// CONCATENATED MODULE: ./node_modules/@leofcoin/codec-format-interface/src/index.js
|
|
2966
|
+
|
|
2967
|
+
|
|
2968
|
+
|
|
2969
|
+
|
|
2970
|
+
|
|
2971
|
+
|
|
2972
|
+
/* harmony default export */ var src = ({ codecs: codecs, Codec: PeernetCodec, CodecHash: CodecHash, FormatInterface: FormatInterface, BasicInterface: BasicInterface });
|
|
2947
2973
|
|
|
2948
2974
|
|
|
2949
2975
|
/***/ }),
|
|
@@ -3185,7 +3211,6 @@ const base = ALPHABET => {
|
|
|
3185
3211
|
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
3186
3212
|
|
|
3187
3213
|
"use strict";
|
|
3188
|
-
__webpack_require__.r(__webpack_exports__);
|
|
3189
3214
|
/* harmony import */ var _vandeurenglenn_base_x__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2353);
|
|
3190
3215
|
|
|
3191
3216
|
|
|
@@ -3197,7 +3222,7 @@ const decode = (uint8Array, hex = false) => {
|
|
|
3197
3222
|
return decoder.decode(uint8Array)
|
|
3198
3223
|
}
|
|
3199
3224
|
|
|
3200
|
-
/* harmony default export */ __webpack_exports__["
|
|
3225
|
+
/* harmony default export */ __webpack_exports__["Z"] = ({
|
|
3201
3226
|
encode: (uint8Array, hex = false) => {
|
|
3202
3227
|
const encoder = hex ? (0,_vandeurenglenn_base_x__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(base32Hex) : (0,_vandeurenglenn_base_x__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(base32)
|
|
3203
3228
|
return encoder.encode(uint8Array)
|
|
@@ -3220,7 +3245,6 @@ const decode = (uint8Array, hex = false) => {
|
|
|
3220
3245
|
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
3221
3246
|
|
|
3222
3247
|
"use strict";
|
|
3223
|
-
__webpack_require__.r(__webpack_exports__);
|
|
3224
3248
|
/* harmony import */ var _vandeurenglenn_base_x__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2353);
|
|
3225
3249
|
|
|
3226
3250
|
|
|
@@ -3228,7 +3252,7 @@ const base58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
|
|
3228
3252
|
|
|
3229
3253
|
const decode = uint8Array => (0,_vandeurenglenn_base_x__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(base58).decode(uint8Array)
|
|
3230
3254
|
|
|
3231
|
-
/* harmony default export */ __webpack_exports__["
|
|
3255
|
+
/* harmony default export */ __webpack_exports__["Z"] = ({
|
|
3232
3256
|
encode: uint8Array => (0,_vandeurenglenn_base_x__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(base58).encode(uint8Array),
|
|
3233
3257
|
decode,
|
|
3234
3258
|
isBase58: uint8Array => {
|
|
@@ -3256,16 +3280,6 @@ globalThis.debug = text => {
|
|
|
3256
3280
|
}
|
|
3257
3281
|
|
|
3258
3282
|
|
|
3259
|
-
/***/ }),
|
|
3260
|
-
|
|
3261
|
-
/***/ 6187:
|
|
3262
|
-
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
3263
|
-
|
|
3264
|
-
"use strict";
|
|
3265
|
-
__webpack_require__.r(__webpack_exports__);
|
|
3266
|
-
/* harmony default export */ __webpack_exports__["default"] = (string => /^[A-F0-9]+$/i.test(string));
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
3283
|
/***/ }),
|
|
3270
3284
|
|
|
3271
3285
|
/***/ 8162:
|
|
@@ -16966,11 +16980,11 @@ class MultiSignature {
|
|
|
16966
16980
|
}
|
|
16967
16981
|
|
|
16968
16982
|
export() {
|
|
16969
|
-
return _vandeurenglenn_base58__WEBPACK_IMPORTED_MODULE_0__["default"].encode(this.multiSignature);
|
|
16983
|
+
return _vandeurenglenn_base58__WEBPACK_IMPORTED_MODULE_0__/* ["default"].encode */ .Z.encode(this.multiSignature);
|
|
16970
16984
|
}
|
|
16971
16985
|
|
|
16972
16986
|
import(encoded) {
|
|
16973
|
-
return _vandeurenglenn_base58__WEBPACK_IMPORTED_MODULE_0__["default"].decode(this.decode(encoded));
|
|
16987
|
+
return _vandeurenglenn_base58__WEBPACK_IMPORTED_MODULE_0__/* ["default"].decode */ .Z.decode(this.decode(encoded));
|
|
16974
16988
|
}
|
|
16975
16989
|
|
|
16976
16990
|
sign(hash, privateKey) {
|
|
@@ -17047,23 +17061,23 @@ class MultiSignature {
|
|
|
17047
17061
|
}
|
|
17048
17062
|
|
|
17049
17063
|
fromHex(hex) {
|
|
17050
|
-
return _vandeurenglenn_base58__WEBPACK_IMPORTED_MODULE_0__["default"].decode(Buffer.from(hex, 'hex'))
|
|
17064
|
+
return _vandeurenglenn_base58__WEBPACK_IMPORTED_MODULE_0__/* ["default"].decode */ .Z.decode(Buffer.from(hex, 'hex'))
|
|
17051
17065
|
}
|
|
17052
17066
|
|
|
17053
17067
|
toBs58() {
|
|
17054
|
-
return _vandeurenglenn_base58__WEBPACK_IMPORTED_MODULE_0__["default"].encode(this.multiSignature)
|
|
17068
|
+
return _vandeurenglenn_base58__WEBPACK_IMPORTED_MODULE_0__/* ["default"].encode */ .Z.encode(this.multiSignature)
|
|
17055
17069
|
}
|
|
17056
17070
|
|
|
17057
17071
|
fromBs58(multiSignature) {
|
|
17058
|
-
return _vandeurenglenn_base58__WEBPACK_IMPORTED_MODULE_0__["default"].decode(multiSignature)
|
|
17072
|
+
return _vandeurenglenn_base58__WEBPACK_IMPORTED_MODULE_0__/* ["default"].decode */ .Z.decode(multiSignature)
|
|
17059
17073
|
}
|
|
17060
17074
|
|
|
17061
17075
|
toBs32() {
|
|
17062
|
-
return _vandeurenglenn_base32__WEBPACK_IMPORTED_MODULE_1__["default"].encode(this.multiSignature)
|
|
17076
|
+
return _vandeurenglenn_base32__WEBPACK_IMPORTED_MODULE_1__/* ["default"].encode */ .Z.encode(this.multiSignature)
|
|
17063
17077
|
}
|
|
17064
17078
|
|
|
17065
17079
|
fromBs32(multiSignature) {
|
|
17066
|
-
return _vandeurenglenn_base32__WEBPACK_IMPORTED_MODULE_1__["default"].decode(multiSignature)
|
|
17080
|
+
return _vandeurenglenn_base32__WEBPACK_IMPORTED_MODULE_1__/* ["default"].decode */ .Z.decode(multiSignature)
|
|
17067
17081
|
}
|
|
17068
17082
|
}
|
|
17069
17083
|
|