@leofcoin/chain 1.9.25 → 1.10.1
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/exports/browser/{browser-tK3uOLQV-CtcRBohi.js → browser-BKlRwB0A-CKYDFr2l.js} +2 -2
- package/exports/browser/{browser-DEjI2nFg-CL-zDjzl.js → browser-Dx3X9MHO-DjR7iqyW.js} +2 -2
- package/exports/browser/chain.js +5130 -934
- package/exports/browser/{client-Ba1cHcxF-B4lH2-fQ.js → client-eYBPUrVq-CukSyZyC.js} +4 -4
- package/exports/browser/{constants-COpvMqFX.js → constants-CUoFxEp2.js} +195 -88
- package/exports/browser/{index-DIhxISkU-Bdapw5qM.js → index-B91mcwxm-D4wHXLVh.js} +2 -2
- package/exports/browser/{messages-BX59GgBQ-DVjVrJBf.js → messages-D0Goitr6-BWN8uKkb.js} +2 -2
- package/exports/browser/{node-browser-Cdgaf6tz.js → node-browser-JBfPNMJs.js} +46 -8
- package/exports/browser/node-browser.js +2 -2
- package/exports/browser/workers/block-worker.js +46 -1
- package/exports/browser/workers/machine-worker.js +32 -61
- package/exports/browser/workers/{worker-Bsi6vKgF-Bsi6vKgF.js → worker-jeGMMCte-BwFbyiks.js} +17 -92
- package/exports/chain.d.ts +10 -0
- package/exports/chain.js +291 -194
- package/exports/{constants-C83ZCYKa.js → constants-D6gWzJZg.js} +2 -1
- package/exports/node.d.ts +15 -0
- package/exports/node.js +7 -5
- package/exports/workers/block-worker.js +46 -1
- package/exports/workers/machine-worker.js +32 -61
- package/exports/workers/{worker-Bsi6vKgF-Bsi6vKgF.js → worker-jeGMMCte-BwFbyiks.js} +17 -92
- package/package.json +10 -5
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import networks from '@leofcoin/networks';
|
|
2
2
|
|
|
3
|
-
const PROTOCOL_VERSION = "0.
|
|
3
|
+
const PROTOCOL_VERSION = "0.2.0";
|
|
4
4
|
const REACHED_ONE_ZERO_ZERO = false;
|
|
5
5
|
const DEFAULT_NODE_OPTIONS = {
|
|
6
|
+
autoStart: false,
|
|
6
7
|
network: "leofcoin:peach",
|
|
7
8
|
networkVersion: "peach",
|
|
8
9
|
version: PROTOCOL_VERSION,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type NodeOptions = {
|
|
2
|
+
network?: string
|
|
3
|
+
networkVersion?: string
|
|
4
|
+
version?: string
|
|
5
|
+
stars?: string[]
|
|
6
|
+
autoStart?: boolean
|
|
7
|
+
root?: string
|
|
8
|
+
storePrefix?: string
|
|
9
|
+
storeNamespace?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default class Node {
|
|
13
|
+
constructor(config?: NodeOptions, password?: string)
|
|
14
|
+
ready: Promise<this>
|
|
15
|
+
}
|
package/exports/node.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import Peernet from '@leofcoin/peernet';
|
|
2
2
|
import nodeConfig from '@leofcoin/lib/node-config';
|
|
3
|
-
import { D as DEFAULT_NODE_OPTIONS } from './constants-
|
|
3
|
+
import { D as DEFAULT_NODE_OPTIONS } from './constants-D6gWzJZg.js';
|
|
4
4
|
import '@leofcoin/networks';
|
|
5
5
|
|
|
6
6
|
class Node {
|
|
7
7
|
#node;
|
|
8
|
-
constructor(config, password) {
|
|
8
|
+
constructor(config = {}, password) {
|
|
9
9
|
this.ready = this._init(config, password);
|
|
10
10
|
}
|
|
11
|
-
async _init(config = {
|
|
12
|
-
autoStart: false
|
|
13
|
-
}, password) {
|
|
11
|
+
async _init(config = { autoStart: false }, password) {
|
|
14
12
|
config = { ...DEFAULT_NODE_OPTIONS, ...config };
|
|
13
|
+
if (config.storeNamespace && !config.root) {
|
|
14
|
+
const [network, networkVersion] = config.network.split(":");
|
|
15
|
+
config.root = `.${network}/${networkVersion || config.networkVersion}/${config.storeNamespace}`;
|
|
16
|
+
}
|
|
15
17
|
this.#node = globalThis.Peernet ? await new globalThis.Peernet(config, password) : await new Peernet(config, password);
|
|
16
18
|
await nodeConfig(config);
|
|
17
19
|
globalThis.pubsub.subscribe("chain:ready", async () => {
|
|
@@ -1,4 +1,49 @@
|
|
|
1
|
-
import { E as EasyWorker,
|
|
1
|
+
import { E as EasyWorker, F as FormatInterface, p as proto$3, i as index$3, a as index$2, b as proto$2 } from './worker-jeGMMCte-BwFbyiks.js';
|
|
2
|
+
|
|
3
|
+
class ValidatorMessage extends FormatInterface {
|
|
4
|
+
get messageName() {
|
|
5
|
+
return 'ValidatorMessage';
|
|
6
|
+
}
|
|
7
|
+
constructor(buffer) {
|
|
8
|
+
if (buffer instanceof ValidatorMessage)
|
|
9
|
+
return buffer;
|
|
10
|
+
const name = 'validator-message';
|
|
11
|
+
super(buffer, proto$2, { name });
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
class BlockMessage extends FormatInterface {
|
|
16
|
+
get messageName() {
|
|
17
|
+
return 'BlockMessage';
|
|
18
|
+
}
|
|
19
|
+
constructor(buffer) {
|
|
20
|
+
if (buffer instanceof BlockMessage)
|
|
21
|
+
return buffer;
|
|
22
|
+
const name = 'block-message';
|
|
23
|
+
super(buffer, proto$3, { name });
|
|
24
|
+
}
|
|
25
|
+
encode(decoded) {
|
|
26
|
+
decoded = decoded || this.decoded;
|
|
27
|
+
const validators = [];
|
|
28
|
+
for (const validator of decoded.validators) {
|
|
29
|
+
if (validator instanceof ValidatorMessage)
|
|
30
|
+
validators.push(validator.encode());
|
|
31
|
+
else
|
|
32
|
+
validators.push(new ValidatorMessage(validator).encode());
|
|
33
|
+
}
|
|
34
|
+
return super.encode({
|
|
35
|
+
...decoded,
|
|
36
|
+
validators: index$3(validators)
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
decode(encoded) {
|
|
40
|
+
encoded = encoded || this.encoded;
|
|
41
|
+
super.decode(encoded);
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
this.decoded.validators = index$2(this.decoded.validators).map((validator) => new ValidatorMessage(validator).decoded);
|
|
44
|
+
return this.decoded;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
2
47
|
|
|
3
48
|
const worker = new EasyWorker();
|
|
4
49
|
globalThis.BigNumber = BigNumber;
|
|
@@ -1,63 +1,34 @@
|
|
|
1
|
-
import { E as EasyWorker,
|
|
1
|
+
import { E as EasyWorker, j as jsonParseBigInt$1, c as jsonStringifyBigInt$1, F as FormatInterface, d as proto$1, e as proto } from './worker-jeGMMCte-BwFbyiks.js';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if ("test".normalize(form) !== "test") {
|
|
12
|
-
throw new Error("bad");
|
|
13
|
-
}
|
|
14
|
-
;
|
|
15
|
-
/* c8 ignore stop */
|
|
16
|
-
if (form === "NFD") {
|
|
17
|
-
const check = String.fromCharCode(0xe9).normalize("NFD");
|
|
18
|
-
const expected = String.fromCharCode(0x65, 0x0301);
|
|
19
|
-
/* c8 ignore start */
|
|
20
|
-
if (check !== expected) {
|
|
21
|
-
throw new Error("broken");
|
|
22
|
-
}
|
|
23
|
-
/* c8 ignore stop */
|
|
24
|
-
}
|
|
25
|
-
accum.push(form);
|
|
3
|
+
class ContractMessage extends FormatInterface {
|
|
4
|
+
get messageName() {
|
|
5
|
+
return 'ContractMessage';
|
|
6
|
+
}
|
|
7
|
+
constructor(buffer) {
|
|
8
|
+
if (buffer instanceof ContractMessage)
|
|
9
|
+
return buffer;
|
|
10
|
+
super(buffer, proto$1, { name: 'contract-message' });
|
|
26
11
|
}
|
|
27
|
-
catch (error) { }
|
|
28
|
-
return accum;
|
|
29
|
-
}, []);
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Some mathematic operations.
|
|
33
|
-
*
|
|
34
|
-
* @_subsection: api/utils:Math Helpers [about-maths]
|
|
35
|
-
*/
|
|
36
|
-
BigInt(0);
|
|
37
|
-
BigInt(1);
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* The **FixedNumber** class permits using values with decimal places,
|
|
41
|
-
* using fixed-pont math.
|
|
42
|
-
*
|
|
43
|
-
* Fixed-point math is still based on integers under-the-hood, but uses an
|
|
44
|
-
* internal offset to store fractional components below, and each operation
|
|
45
|
-
* corrects for this after each operation.
|
|
46
|
-
*
|
|
47
|
-
* @_section: api/utils/fixed-point-math:Fixed-Point Maths [about-fixed-point-math]
|
|
48
|
-
*/
|
|
49
|
-
BigInt(-1);
|
|
50
|
-
BigInt(0);
|
|
51
|
-
BigInt(1);
|
|
52
|
-
BigInt(5);
|
|
53
|
-
// Constant to pull zeros from for multipliers
|
|
54
|
-
let Zeros = "0000";
|
|
55
|
-
while (Zeros.length < 80) {
|
|
56
|
-
Zeros += Zeros;
|
|
57
12
|
}
|
|
58
13
|
|
|
59
|
-
|
|
60
|
-
|
|
14
|
+
class TransactionMessage extends FormatInterface {
|
|
15
|
+
get messageName() {
|
|
16
|
+
return 'TransactionMessage';
|
|
17
|
+
}
|
|
18
|
+
constructor(buffer) {
|
|
19
|
+
if (buffer instanceof TransactionMessage)
|
|
20
|
+
return buffer;
|
|
21
|
+
const name = 'transaction-message';
|
|
22
|
+
super(buffer, proto, { name });
|
|
23
|
+
}
|
|
24
|
+
beforeHashing(decoded) {
|
|
25
|
+
decoded = super.beforeHashing(decoded);
|
|
26
|
+
delete decoded.signature;
|
|
27
|
+
delete decoded.priority;
|
|
28
|
+
delete decoded.dependsOn;
|
|
29
|
+
return decoded;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
61
32
|
|
|
62
33
|
const byteFormats = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
63
34
|
const formatBytes = (bytes, decimals = 2) => {
|
|
@@ -370,16 +341,16 @@ const _ = {
|
|
|
370
341
|
throw new Error(`error: ${e.message}
|
|
371
342
|
contract: ${contract}
|
|
372
343
|
method: ${method}
|
|
373
|
-
params: ${JSON.stringify(params, jsonStringifyBigInt, '\t')}
|
|
344
|
+
params: ${JSON.stringify(params, jsonStringifyBigInt$1, '\t')}
|
|
374
345
|
`);
|
|
375
346
|
}
|
|
376
347
|
},
|
|
377
348
|
init: async (message) => {
|
|
378
349
|
let { peerid, fromState, state, info } = message;
|
|
379
350
|
if (info)
|
|
380
|
-
info = JSON.parse(info, jsonParseBigInt);
|
|
351
|
+
info = JSON.parse(info, jsonParseBigInt$1);
|
|
381
352
|
if (state)
|
|
382
|
-
state = JSON.parse(state, jsonParseBigInt);
|
|
353
|
+
state = JSON.parse(state, jsonParseBigInt$1);
|
|
383
354
|
globalThis.peerid = peerid;
|
|
384
355
|
console.log({ fromState, info });
|
|
385
356
|
nativeCalls = BigInt(info?.nativeCalls ?? 0);
|
|
@@ -393,7 +364,7 @@ const _ = {
|
|
|
393
364
|
totalBlocks = BigInt(info?.totalBlocks ?? 0);
|
|
394
365
|
if (fromState) {
|
|
395
366
|
if (message.lastBlock) {
|
|
396
|
-
lastBlock = JSON.parse(message.lastBlock, jsonParseBigInt);
|
|
367
|
+
lastBlock = JSON.parse(message.lastBlock, jsonParseBigInt$1);
|
|
397
368
|
}
|
|
398
369
|
const setState = async (address, state) => {
|
|
399
370
|
const contractBytes = await resolveContract(address);
|
|
@@ -513,7 +484,7 @@ const _ = {
|
|
|
513
484
|
},
|
|
514
485
|
addLoadedBlock: (block) => {
|
|
515
486
|
const size = formatBytes(block.length);
|
|
516
|
-
block = JSON.parse(block, jsonParseBigInt);
|
|
487
|
+
block = JSON.parse(block, jsonParseBigInt$1);
|
|
517
488
|
// if (block.decoded) block = { ...block.decoded, hash: await new BlockMessage(block).hash() }
|
|
518
489
|
// if (blocks[block.index - 1]) {
|
|
519
490
|
// console.warn(`block ${block.index} already loaded, skipping`)
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
var proto$3 = {
|
|
2
|
+
index: BigInt(0),
|
|
3
|
+
previousHash: String(),
|
|
4
|
+
timestamp: Number(),
|
|
5
|
+
reward: BigInt(0),
|
|
6
|
+
fees: BigInt(0),
|
|
7
|
+
transactions: Array(),
|
|
8
|
+
validators: new Uint8Array(),
|
|
9
|
+
producer: String(),
|
|
10
|
+
producerProof: String(),
|
|
11
|
+
protocolVersion: String()
|
|
12
|
+
};
|
|
13
|
+
|
|
1
14
|
// base-x encoding / decoding
|
|
2
15
|
// Copyright (c) 2018 base-x contributors
|
|
3
16
|
// Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)
|
|
@@ -7602,7 +7615,7 @@ const blockchainCodecs = [
|
|
|
7602
7615
|
},
|
|
7603
7616
|
{
|
|
7604
7617
|
name: 'raw-transaction-message',
|
|
7605
|
-
codec: '
|
|
7618
|
+
codec: '0x72746d',
|
|
7606
7619
|
hashAlg: 'keccak-256'
|
|
7607
7620
|
},
|
|
7608
7621
|
{
|
|
@@ -7725,7 +7738,7 @@ const peernetCodecs = [
|
|
|
7725
7738
|
},
|
|
7726
7739
|
{
|
|
7727
7740
|
name: 'peernet-ps',
|
|
7728
|
-
codec: '
|
|
7741
|
+
codec: '0x707073',
|
|
7729
7742
|
hashAlg: 'keccak-256'
|
|
7730
7743
|
},
|
|
7731
7744
|
{
|
|
@@ -8766,86 +8779,17 @@ let FormatInterface$1 = class FormatInterface extends BasicInterface {
|
|
|
8766
8779
|
*/
|
|
8767
8780
|
const FormatInterface = FormatInterface$1;
|
|
8768
8781
|
|
|
8769
|
-
var proto$
|
|
8782
|
+
var proto$2 = {
|
|
8770
8783
|
address: String(),
|
|
8771
8784
|
reward: BigInt(0)
|
|
8772
8785
|
};
|
|
8773
8786
|
|
|
8774
|
-
class ValidatorMessage extends FormatInterface {
|
|
8775
|
-
get messageName() {
|
|
8776
|
-
return 'ValidatorMessage';
|
|
8777
|
-
}
|
|
8778
|
-
constructor(buffer) {
|
|
8779
|
-
if (buffer instanceof ValidatorMessage)
|
|
8780
|
-
return buffer;
|
|
8781
|
-
const name = 'validator-message';
|
|
8782
|
-
super(buffer, proto$3, { name });
|
|
8783
|
-
}
|
|
8784
|
-
}
|
|
8785
|
-
|
|
8786
|
-
var proto$2 = {
|
|
8787
|
-
index: BigInt(0),
|
|
8788
|
-
previousHash: String(),
|
|
8789
|
-
timestamp: Number(),
|
|
8790
|
-
reward: BigInt(0),
|
|
8791
|
-
fees: BigInt(0),
|
|
8792
|
-
transactions: Array(),
|
|
8793
|
-
validators: new Uint8Array(),
|
|
8794
|
-
producer: String(),
|
|
8795
|
-
producerProof: String(),
|
|
8796
|
-
protocolVersion: String()
|
|
8797
|
-
};
|
|
8798
|
-
|
|
8799
|
-
class BlockMessage extends FormatInterface {
|
|
8800
|
-
get messageName() {
|
|
8801
|
-
return 'BlockMessage';
|
|
8802
|
-
}
|
|
8803
|
-
constructor(buffer) {
|
|
8804
|
-
if (buffer instanceof BlockMessage)
|
|
8805
|
-
return buffer;
|
|
8806
|
-
const name = 'block-message';
|
|
8807
|
-
super(buffer, proto$2, { name });
|
|
8808
|
-
}
|
|
8809
|
-
encode(decoded) {
|
|
8810
|
-
decoded = decoded || this.decoded;
|
|
8811
|
-
const validators = [];
|
|
8812
|
-
for (const validator of decoded.validators) {
|
|
8813
|
-
if (validator instanceof ValidatorMessage)
|
|
8814
|
-
validators.push(validator.encode());
|
|
8815
|
-
else
|
|
8816
|
-
validators.push(new ValidatorMessage(validator).encode());
|
|
8817
|
-
}
|
|
8818
|
-
return super.encode({
|
|
8819
|
-
...decoded,
|
|
8820
|
-
validators: index$3(validators)
|
|
8821
|
-
});
|
|
8822
|
-
}
|
|
8823
|
-
decode(encoded) {
|
|
8824
|
-
encoded = encoded || this.encoded;
|
|
8825
|
-
super.decode(encoded);
|
|
8826
|
-
// @ts-ignore
|
|
8827
|
-
this.decoded.validators = index$2(this.decoded.validators).map((validator) => new ValidatorMessage(validator).decoded);
|
|
8828
|
-
return this.decoded;
|
|
8829
|
-
}
|
|
8830
|
-
}
|
|
8831
|
-
|
|
8832
8787
|
var proto$1 = {
|
|
8833
8788
|
creator: String(),
|
|
8834
8789
|
contract: new Uint8Array(),
|
|
8835
8790
|
constructorParameters: Array()
|
|
8836
8791
|
};
|
|
8837
8792
|
|
|
8838
|
-
class ContractMessage extends FormatInterface {
|
|
8839
|
-
get messageName() {
|
|
8840
|
-
return 'ContractMessage';
|
|
8841
|
-
}
|
|
8842
|
-
constructor(buffer) {
|
|
8843
|
-
if (buffer instanceof ContractMessage)
|
|
8844
|
-
return buffer;
|
|
8845
|
-
super(buffer, proto$1, { name: 'contract-message' });
|
|
8846
|
-
}
|
|
8847
|
-
}
|
|
8848
|
-
|
|
8849
8793
|
({
|
|
8850
8794
|
index: BigInt(0)
|
|
8851
8795
|
});
|
|
@@ -8862,25 +8806,6 @@ var proto = {
|
|
|
8862
8806
|
'priority?': Boolean()
|
|
8863
8807
|
};
|
|
8864
8808
|
|
|
8865
|
-
class TransactionMessage extends FormatInterface {
|
|
8866
|
-
get messageName() {
|
|
8867
|
-
return 'TransactionMessage';
|
|
8868
|
-
}
|
|
8869
|
-
constructor(buffer) {
|
|
8870
|
-
if (buffer instanceof TransactionMessage)
|
|
8871
|
-
return buffer;
|
|
8872
|
-
const name = 'transaction-message';
|
|
8873
|
-
super(buffer, proto, { name });
|
|
8874
|
-
}
|
|
8875
|
-
beforeHashing(decoded) {
|
|
8876
|
-
decoded = super.beforeHashing(decoded);
|
|
8877
|
-
delete decoded.signature;
|
|
8878
|
-
delete decoded.priority;
|
|
8879
|
-
delete decoded.dependsOn;
|
|
8880
|
-
return decoded;
|
|
8881
|
-
}
|
|
8882
|
-
}
|
|
8883
|
-
|
|
8884
8809
|
({
|
|
8885
8810
|
params: Array()});
|
|
8886
8811
|
|
|
@@ -9013,4 +8938,4 @@ class EasyWorker {
|
|
|
9013
8938
|
}
|
|
9014
8939
|
}
|
|
9015
8940
|
|
|
9016
|
-
export {
|
|
8941
|
+
export { EasyWorker as E, FormatInterface as F, index$2 as a, proto$2 as b, jsonStringifyBigInt$1 as c, proto$1 as d, proto as e, index$3 as i, jsonParseBigInt$1 as j, proto$3 as p };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leofcoin/chain",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.1",
|
|
4
4
|
"description": "Official javascript implementation",
|
|
5
5
|
"private": false,
|
|
6
6
|
"exports": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"docs": "sh ./node_modules/.bin/esdoc src/chain.js",
|
|
36
36
|
"workers": "cp ./../workers/src/** ./workers",
|
|
37
37
|
"demo": "jsproject --serve ./ --port 5478 --open demo",
|
|
38
|
-
"test": "node --
|
|
38
|
+
"test": "node --test test/operational.test.js test/unit/*.test.js",
|
|
39
39
|
"pack": "webpack",
|
|
40
40
|
"build": "rollup -c --silent error",
|
|
41
41
|
"npm-check-updates": "npx npm-check-updates -u --install always"
|
|
@@ -67,16 +67,21 @@
|
|
|
67
67
|
"@leofcoin/contracts": "^0.1.20",
|
|
68
68
|
"@leofcoin/crypto": "^0.2.40",
|
|
69
69
|
"@leofcoin/errors": "^1.0.29",
|
|
70
|
-
"@leofcoin/lib": "^1.
|
|
71
|
-
"@leofcoin/messages": "^1.
|
|
70
|
+
"@leofcoin/lib": "^1.3.1",
|
|
71
|
+
"@leofcoin/messages": "^1.6.0",
|
|
72
72
|
"@leofcoin/multi-wallet": "^3.1.9",
|
|
73
73
|
"@leofcoin/networks": "^1.1.29",
|
|
74
|
-
"@leofcoin/peernet": "^1.2.
|
|
74
|
+
"@leofcoin/peernet": "^1.2.23",
|
|
75
75
|
"@leofcoin/storage": "^3.5.38",
|
|
76
76
|
"@leofcoin/utils": "^1.1.43",
|
|
77
77
|
"@leofcoin/workers": "^1.5.31",
|
|
78
78
|
"@vandeurenglenn/base58": "^1.1.9",
|
|
79
79
|
"@vandeurenglenn/easy-worker": "^1.0.3",
|
|
80
|
+
"@vandeurenglenn/typed-array-utils": "^1.2.0",
|
|
80
81
|
"semver": "^7.8.5"
|
|
82
|
+
},
|
|
83
|
+
"repository": {
|
|
84
|
+
"type": "git",
|
|
85
|
+
"url": "https://github.com/leofcoin/monorepo"
|
|
81
86
|
}
|
|
82
87
|
}
|