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