Merge development
This commit is contained in:
commit
e6fe728bcb
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "1.0.6",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547561734,
|
||||
"version": "1.0.5",
|
||||
|
@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.6 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.5 - _January 15, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-examples",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.6",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@ -34,7 +34,7 @@
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/examples/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^1.0.22",
|
||||
"@0x/contracts-test-utils": "^2.0.0",
|
||||
"@0x/contracts-test-utils": "^2.0.1",
|
||||
"@0x/dev-utils": "^1.0.24",
|
||||
"@0x/sol-compiler": "^2.0.2",
|
||||
"@0x/subproviders": "^2.1.11",
|
||||
@ -59,11 +59,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^3.0.13",
|
||||
"@0x/contracts-interfaces": "^1.0.5",
|
||||
"@0x/contracts-libs": "^1.0.5",
|
||||
"@0x/contracts-multisig": "^1.0.5",
|
||||
"@0x/contracts-tokens": "^1.0.5",
|
||||
"@0x/contracts-utils": "^1.0.5",
|
||||
"@0x/contracts-interfaces": "^1.0.6",
|
||||
"@0x/contracts-libs": "^1.0.6",
|
||||
"@0x/contracts-multisig": "^1.0.6",
|
||||
"@0x/contracts-tokens": "^1.0.6",
|
||||
"@0x/contracts-utils": "^1.0.6",
|
||||
"@0x/order-utils": "^3.1.2",
|
||||
"@0x/types": "^1.5.2",
|
||||
"@0x/typescript-typings": "^3.0.8",
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "1.2.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547561734,
|
||||
"version": "1.2.2",
|
||||
|
@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.2.3 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.2.2 - _January 15, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-extensions",
|
||||
"version": "1.2.2",
|
||||
"version": "1.2.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@ -45,8 +45,8 @@
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^1.0.22",
|
||||
"@0x/contract-wrappers": "^5.0.0",
|
||||
"@0x/contracts-test-utils": "^2.0.0",
|
||||
"@0x/contract-wrappers": "^5.0.1",
|
||||
"@0x/contracts-test-utils": "^2.0.1",
|
||||
"@0x/dev-utils": "^1.0.24",
|
||||
"@0x/sol-compiler": "^2.0.2",
|
||||
"@0x/subproviders": "^2.1.11",
|
||||
@ -71,11 +71,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^3.0.13",
|
||||
"@0x/contracts-interfaces": "^1.0.5",
|
||||
"@0x/contracts-libs": "^1.0.5",
|
||||
"@0x/contracts-protocol": "^2.2.2",
|
||||
"@0x/contracts-tokens": "^1.0.5",
|
||||
"@0x/contracts-utils": "^1.0.5",
|
||||
"@0x/contracts-interfaces": "^1.0.6",
|
||||
"@0x/contracts-libs": "^1.0.6",
|
||||
"@0x/contracts-protocol": "^2.2.3",
|
||||
"@0x/contracts-tokens": "^1.0.6",
|
||||
"@0x/contracts-utils": "^1.0.6",
|
||||
"@0x/order-utils": "^3.1.2",
|
||||
"@0x/types": "^1.5.2",
|
||||
"@0x/typescript-typings": "^3.0.8",
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "1.0.6",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547561734,
|
||||
"version": "1.0.5",
|
||||
|
@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.6 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.5 - _January 15, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-interfaces",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.6",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@ -42,8 +42,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^3.0.13",
|
||||
"@0x/contracts-libs": "^1.0.5",
|
||||
"@0x/contracts-utils": "^1.0.5",
|
||||
"@0x/contracts-libs": "^1.0.6",
|
||||
"@0x/contracts-utils": "^1.0.6",
|
||||
"@0x/types": "^1.5.2",
|
||||
"@0x/typescript-typings": "^3.0.8",
|
||||
"@0x/utils": "^3.0.1",
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "1.0.6",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547561734,
|
||||
"version": "1.0.5",
|
||||
|
@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.6 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.5 - _January 15, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-libs",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.6",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@ -45,7 +45,7 @@
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/libs/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^1.0.22",
|
||||
"@0x/contracts-test-utils": "^2.0.0",
|
||||
"@0x/contracts-test-utils": "^2.0.1",
|
||||
"@0x/dev-utils": "^1.0.24",
|
||||
"@0x/sol-compiler": "^2.0.2",
|
||||
"@0x/subproviders": "^2.1.11",
|
||||
@ -70,8 +70,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^3.0.13",
|
||||
"@0x/contracts-multisig": "^1.0.5",
|
||||
"@0x/contracts-utils": "^1.0.5",
|
||||
"@0x/contracts-multisig": "^1.0.6",
|
||||
"@0x/contracts-utils": "^1.0.6",
|
||||
"@0x/order-utils": "^3.1.2",
|
||||
"@0x/types": "^1.5.2",
|
||||
"@0x/typescript-typings": "^3.0.8",
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "1.0.6",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547561734,
|
||||
"version": "1.0.5",
|
||||
|
@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.6 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.5 - _January 15, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-multisig",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.6",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@ -45,7 +45,7 @@
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/multisig/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^1.0.22",
|
||||
"@0x/contracts-test-utils": "^2.0.0",
|
||||
"@0x/contracts-test-utils": "^2.0.1",
|
||||
"@0x/dev-utils": "^1.0.24",
|
||||
"@0x/sol-compiler": "^2.0.2",
|
||||
"@0x/subproviders": "^2.1.11",
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "2.2.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547561734,
|
||||
"version": "2.2.2",
|
||||
|
@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.2.3 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.2.2 - _January 15, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-protocol",
|
||||
"version": "2.2.2",
|
||||
"version": "2.2.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@ -69,13 +69,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^3.0.13",
|
||||
"@0x/contracts-examples": "^1.0.5",
|
||||
"@0x/contracts-interfaces": "^1.0.5",
|
||||
"@0x/contracts-libs": "^1.0.5",
|
||||
"@0x/contracts-multisig": "^1.0.5",
|
||||
"@0x/contracts-test-utils": "^2.0.0",
|
||||
"@0x/contracts-tokens": "^1.0.5",
|
||||
"@0x/contracts-utils": "^1.0.5",
|
||||
"@0x/contracts-examples": "^1.0.6",
|
||||
"@0x/contracts-interfaces": "^1.0.6",
|
||||
"@0x/contracts-libs": "^1.0.6",
|
||||
"@0x/contracts-multisig": "^1.0.6",
|
||||
"@0x/contracts-test-utils": "^2.0.1",
|
||||
"@0x/contracts-tokens": "^1.0.6",
|
||||
"@0x/contracts-utils": "^1.0.6",
|
||||
"@0x/order-utils": "^3.1.2",
|
||||
"@0x/types": "^1.5.2",
|
||||
"@0x/typescript-typings": "^3.0.8",
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "2.0.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
|
@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.0.1 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.0.0 - _January 15, 2019_
|
||||
|
||||
* Renamed OrderStatus enum members to PascalCase to conform with tslint enum-naming rule (#1474)
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-test-utils",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.1",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@ -44,9 +44,9 @@
|
||||
"@0x/dev-utils": "^1.0.24",
|
||||
"@0x/order-utils": "^3.1.2",
|
||||
"@0x/sol-compiler": "^2.0.2",
|
||||
"@0x/sol-coverage": "^1.0.2",
|
||||
"@0x/sol-profiler": "^1.0.2",
|
||||
"@0x/sol-trace": "^1.0.2",
|
||||
"@0x/sol-coverage": "^1.0.3",
|
||||
"@0x/sol-profiler": "^1.0.3",
|
||||
"@0x/sol-trace": "^1.0.3",
|
||||
"@0x/subproviders": "^2.1.11",
|
||||
"@0x/tslint-config": "^2.0.2",
|
||||
"@0x/types": "^1.5.2",
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "1.0.6",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547561734,
|
||||
"version": "1.0.5",
|
||||
|
@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.6 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.5 - _January 15, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-tokens",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.6",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@ -45,7 +45,7 @@
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^1.0.22",
|
||||
"@0x/contracts-test-utils": "^2.0.0",
|
||||
"@0x/contracts-test-utils": "^2.0.1",
|
||||
"@0x/dev-utils": "^1.0.24",
|
||||
"@0x/sol-compiler": "^2.0.2",
|
||||
"@0x/subproviders": "^2.1.11",
|
||||
@ -70,10 +70,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^3.0.13",
|
||||
"@0x/contracts-interfaces": "^1.0.5",
|
||||
"@0x/contracts-libs": "^1.0.5",
|
||||
"@0x/contracts-multisig": "^1.0.5",
|
||||
"@0x/contracts-utils": "^1.0.5",
|
||||
"@0x/contracts-interfaces": "^1.0.6",
|
||||
"@0x/contracts-libs": "^1.0.6",
|
||||
"@0x/contracts-multisig": "^1.0.6",
|
||||
"@0x/contracts-utils": "^1.0.6",
|
||||
"@0x/order-utils": "^3.1.2",
|
||||
"@0x/types": "^1.5.2",
|
||||
"@0x/typescript-typings": "^3.0.8",
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "1.0.6",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547561734,
|
||||
"version": "1.0.5",
|
||||
|
@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.6 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.5 - _January 15, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contracts-utils",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.6",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@ -45,7 +45,7 @@
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/contracts/utils/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^1.0.22",
|
||||
"@0x/contracts-test-utils": "^2.0.0",
|
||||
"@0x/contracts-test-utils": "^2.0.1",
|
||||
"@0x/dev-utils": "^1.0.24",
|
||||
"@0x/sol-compiler": "^2.0.2",
|
||||
"@0x/subproviders": "^2.1.11",
|
||||
@ -71,7 +71,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^3.0.13",
|
||||
"@0x/contracts-multisig": "^1.0.5",
|
||||
"@0x/contracts-multisig": "^1.0.6",
|
||||
"@0x/order-utils": "^3.1.2",
|
||||
"@0x/types": "^1.5.2",
|
||||
"@0x/typescript-typings": "^3.0.8",
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "3.0.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547561734,
|
||||
"version": "3.0.2",
|
||||
|
@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.0.3 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.0.2 - _January 15, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "0x.js",
|
||||
"version": "3.0.2",
|
||||
"version": "3.0.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@ -74,9 +74,9 @@
|
||||
"dependencies": {
|
||||
"@0x/assert": "^1.0.23",
|
||||
"@0x/base-contract": "^3.0.13",
|
||||
"@0x/contract-wrappers": "^5.0.0",
|
||||
"@0x/contract-wrappers": "^5.0.1",
|
||||
"@0x/order-utils": "^3.1.2",
|
||||
"@0x/order-watcher": "^2.4.2",
|
||||
"@0x/order-watcher": "^2.4.3",
|
||||
"@0x/subproviders": "^2.1.11",
|
||||
"@0x/types": "^1.5.2",
|
||||
"@0x/typescript-typings": "^3.0.8",
|
||||
|
@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"version": "4.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Adds new public method getLiquidityForAssetDataAsync, and exposes getOrdersAndFillableAmountsAsync as public method",
|
||||
"pr": 1512
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "4.0.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547561734,
|
||||
"version": "4.0.1",
|
||||
|
@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.0.2 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.0.1 - _January 15, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/asset-buyer",
|
||||
"version": "4.0.1",
|
||||
"version": "4.0.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@ -38,7 +38,7 @@
|
||||
"dependencies": {
|
||||
"@0x/assert": "^1.0.23",
|
||||
"@0x/connect": "^3.0.13",
|
||||
"@0x/contract-wrappers": "^5.0.0",
|
||||
"@0x/contract-wrappers": "^5.0.1",
|
||||
"@0x/json-schemas": "^2.1.7",
|
||||
"@0x/order-utils": "^3.1.2",
|
||||
"@0x/subproviders": "^2.1.11",
|
||||
@ -65,6 +65,7 @@
|
||||
"shx": "^0.2.2",
|
||||
"tslint": "5.11.0",
|
||||
"typedoc": "0.13.0",
|
||||
"typemoq": "^2.1.0",
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@ -16,14 +16,16 @@ import {
|
||||
BuyQuote,
|
||||
BuyQuoteExecutionOpts,
|
||||
BuyQuoteRequestOpts,
|
||||
LiquidityForAssetData,
|
||||
LiquidityRequestOpts,
|
||||
OrderProvider,
|
||||
OrderProviderResponse,
|
||||
OrdersAndFillableAmounts,
|
||||
} from './types';
|
||||
|
||||
import { assert } from './utils/assert';
|
||||
import { assetDataUtils } from './utils/asset_data_utils';
|
||||
import { buyQuoteCalculator } from './utils/buy_quote_calculator';
|
||||
import { calculateLiquidity } from './utils/calculate_liquidity';
|
||||
import { orderProviderResponseProcessor } from './utils/order_provider_response_processor';
|
||||
|
||||
interface OrdersEntry {
|
||||
@ -138,10 +140,10 @@ export class AssetBuyer {
|
||||
// get the relevant orders for the makerAsset and fees
|
||||
// if the requested assetData is ZRX, don't get the fee info
|
||||
const [ordersAndFillableAmounts, feeOrdersAndFillableAmounts] = await Promise.all([
|
||||
this._getOrdersAndFillableAmountsAsync(assetData, shouldForceOrderRefresh),
|
||||
this.getOrdersAndFillableAmountsAsync(assetData, shouldForceOrderRefresh),
|
||||
isMakerAssetZrxToken
|
||||
? Promise.resolve(constants.EMPTY_ORDERS_AND_FILLABLE_AMOUNTS)
|
||||
: this._getOrdersAndFillableAmountsAsync(zrxTokenAssetData, shouldForceOrderRefresh),
|
||||
: this.getOrdersAndFillableAmountsAsync(zrxTokenAssetData, shouldForceOrderRefresh),
|
||||
shouldForceOrderRefresh,
|
||||
]);
|
||||
if (ordersAndFillableAmounts.orders.length === 0) {
|
||||
@ -177,6 +179,40 @@ export class AssetBuyer {
|
||||
const buyQuote = this.getBuyQuoteAsync(assetData, assetBuyAmount, options);
|
||||
return buyQuote;
|
||||
}
|
||||
/**
|
||||
* Returns information about available liquidity for an asset
|
||||
* Does not factor in slippage or fees
|
||||
* @param assetData The assetData of the desired asset to buy (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md).
|
||||
* @param options Options for the request. See type definition for more information.
|
||||
*
|
||||
* @return An object that conforms to LiquidityForAssetData that satisfies the request. See type definition for more information.
|
||||
*/
|
||||
public async getLiquidityForAssetDataAsync(
|
||||
assetData: string,
|
||||
options: Partial<LiquidityRequestOpts> = {},
|
||||
): Promise<LiquidityForAssetData> {
|
||||
const shouldForceOrderRefresh =
|
||||
options.shouldForceOrderRefresh !== undefined ? options.shouldForceOrderRefresh : false;
|
||||
assetDataUtils.decodeAssetDataOrThrow(assetData);
|
||||
assert.isBoolean('options.shouldForceOrderRefresh', shouldForceOrderRefresh);
|
||||
|
||||
const assetPairs = await this.orderProvider.getAvailableMakerAssetDatasAsync(assetData);
|
||||
const etherTokenAssetData = this._getEtherTokenAssetDataOrThrow();
|
||||
if (!assetPairs.includes(etherTokenAssetData)) {
|
||||
return {
|
||||
tokensAvailableInBaseUnits: new BigNumber(0),
|
||||
ethValueAvailableInWei: new BigNumber(0),
|
||||
};
|
||||
}
|
||||
|
||||
const ordersAndFillableAmounts = await this.getOrdersAndFillableAmountsAsync(
|
||||
assetData,
|
||||
shouldForceOrderRefresh,
|
||||
);
|
||||
|
||||
return calculateLiquidity(ordersAndFillableAmounts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a BuyQuote and desired rate, attempt to execute the buy.
|
||||
* @param buyQuote An object that conforms to BuyQuote. See type definition for more information.
|
||||
@ -260,8 +296,10 @@ export class AssetBuyer {
|
||||
}
|
||||
/**
|
||||
* Grab orders from the map, if there is a miss or it is time to refresh, fetch and process the orders
|
||||
* @param assetData The assetData of the desired asset to buy (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md).
|
||||
* @param shouldForceOrderRefresh If set to true, new orders and state will be fetched instead of waiting for the next orderRefreshIntervalMs.
|
||||
*/
|
||||
private async _getOrdersAndFillableAmountsAsync(
|
||||
public async getOrdersAndFillableAmountsAsync(
|
||||
assetData: string,
|
||||
shouldForceOrderRefresh: boolean,
|
||||
): Promise<OrdersAndFillableAmounts> {
|
||||
|
@ -19,6 +19,9 @@ export {
|
||||
BuyQuoteExecutionOpts,
|
||||
BuyQuoteInfo,
|
||||
BuyQuoteRequestOpts,
|
||||
LiquidityForAssetData,
|
||||
LiquidityRequestOpts,
|
||||
OrdersAndFillableAmounts,
|
||||
OrderProvider,
|
||||
OrderProviderRequest,
|
||||
OrderProviderResponse,
|
||||
|
@ -75,6 +75,13 @@ export interface BuyQuoteRequestOpts {
|
||||
slippagePercentage: number;
|
||||
}
|
||||
|
||||
/*
|
||||
* Options for checking liquidity
|
||||
*
|
||||
* shouldForceOrderRefresh: If set to true, new orders and state will be fetched instead of waiting for the next orderRefreshIntervalMs. Defaults to false.
|
||||
*/
|
||||
export type LiquidityRequestOpts = Pick<BuyQuoteRequestOpts, 'shouldForceOrderRefresh'>;
|
||||
|
||||
/**
|
||||
* ethAmount: The desired amount of eth to spend. Defaults to buyQuote.worstCaseQuoteInfo.totalEthAmount.
|
||||
* takerAddress: The address to perform the buy. Defaults to the first available address from the provider.
|
||||
@ -117,7 +124,19 @@ export enum AssetBuyerError {
|
||||
TransactionValueTooLow = 'TRANSACTION_VALUE_TOO_LOW',
|
||||
}
|
||||
|
||||
/**
|
||||
* orders: An array of signed orders
|
||||
* remainingFillableMakerAssetAmounts: A list of fillable amounts for the signed orders. The index of an item in the array associates the amount with the corresponding order.
|
||||
*/
|
||||
export interface OrdersAndFillableAmounts {
|
||||
orders: SignedOrder[];
|
||||
remainingFillableMakerAssetAmounts: BigNumber[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents available liquidity for a given assetData
|
||||
*/
|
||||
export interface LiquidityForAssetData {
|
||||
tokensAvailableInBaseUnits: BigNumber;
|
||||
ethValueAvailableInWei: BigNumber;
|
||||
}
|
||||
|
34
packages/asset-buyer/src/utils/calculate_liquidity.ts
Normal file
34
packages/asset-buyer/src/utils/calculate_liquidity.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
import { LiquidityForAssetData, OrdersAndFillableAmounts } from '../types';
|
||||
|
||||
import { orderUtils } from './order_utils';
|
||||
|
||||
export const calculateLiquidity = (ordersAndFillableAmounts: OrdersAndFillableAmounts): LiquidityForAssetData => {
|
||||
const { orders, remainingFillableMakerAssetAmounts } = ordersAndFillableAmounts;
|
||||
const liquidityInBigNumbers = orders.reduce(
|
||||
(acc, order, curIndex) => {
|
||||
const availableMakerAssetAmount = remainingFillableMakerAssetAmounts[curIndex];
|
||||
if (availableMakerAssetAmount === undefined) {
|
||||
throw new Error(`No corresponding fillableMakerAssetAmounts at index ${curIndex}`);
|
||||
}
|
||||
|
||||
const tokensAvailableForCurrentOrder = availableMakerAssetAmount;
|
||||
const ethValueAvailableForCurrentOrder = orderUtils.getTakerFillAmount(order, availableMakerAssetAmount);
|
||||
return {
|
||||
tokensAvailableInBaseUnits: acc.tokensAvailableInBaseUnits.plus(tokensAvailableForCurrentOrder),
|
||||
ethValueAvailableInWei: acc.ethValueAvailableInWei.plus(ethValueAvailableForCurrentOrder),
|
||||
};
|
||||
},
|
||||
{
|
||||
tokensAvailableInBaseUnits: new BigNumber(0),
|
||||
ethValueAvailableInWei: new BigNumber(0),
|
||||
},
|
||||
);
|
||||
|
||||
// Turn into regular numbers
|
||||
return {
|
||||
tokensAvailableInBaseUnits: liquidityInBigNumbers.tokensAvailableInBaseUnits,
|
||||
ethValueAvailableInWei: liquidityInBigNumbers.ethValueAvailableInWei,
|
||||
};
|
||||
};
|
212
packages/asset-buyer/test/asset_buyer_test.ts
Normal file
212
packages/asset-buyer/test/asset_buyer_test.ts
Normal file
@ -0,0 +1,212 @@
|
||||
import { orderFactory } from '@0x/order-utils/lib/src/order_factory';
|
||||
import { Web3ProviderEngine } from '@0x/subproviders';
|
||||
import { SignedOrder } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import * as chai from 'chai';
|
||||
import 'mocha';
|
||||
import * as TypeMoq from 'typemoq';
|
||||
|
||||
import { AssetBuyer } from '../src';
|
||||
import { constants } from '../src/constants';
|
||||
import { LiquidityForAssetData, OrderProvider, OrdersAndFillableAmounts } from '../src/types';
|
||||
|
||||
import { chaiSetup } from './utils/chai_setup';
|
||||
import {
|
||||
mockAvailableAssetDatas,
|
||||
mockedAssetBuyerWithOrdersAndFillableAmounts,
|
||||
orderProviderMock,
|
||||
} from './utils/mocks';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
|
||||
const FAKE_SRA_URL = 'https://fakeurl.com';
|
||||
const FAKE_ASSET_DATA = '0xf47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48';
|
||||
const TOKEN_DECIMALS = 18;
|
||||
const DAI_ASSET_DATA = '0xf47261b000000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359"';
|
||||
const WETH_ASSET_DATA = '0xf47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2';
|
||||
const WETH_DECIMALS = constants.ETHER_TOKEN_DECIMALS;
|
||||
|
||||
const baseUnitAmount = (unitAmount: number, decimals = TOKEN_DECIMALS): BigNumber => {
|
||||
return Web3Wrapper.toBaseUnitAmount(new BigNumber(unitAmount), decimals);
|
||||
};
|
||||
|
||||
const expectLiquidityResult = async (
|
||||
web3Provider: Web3ProviderEngine,
|
||||
orderProvider: OrderProvider,
|
||||
ordersAndFillableAmounts: OrdersAndFillableAmounts,
|
||||
expectedLiquidityResult: LiquidityForAssetData,
|
||||
) => {
|
||||
const mockedAssetBuyer = mockedAssetBuyerWithOrdersAndFillableAmounts(
|
||||
web3Provider,
|
||||
orderProvider,
|
||||
FAKE_ASSET_DATA,
|
||||
ordersAndFillableAmounts,
|
||||
);
|
||||
const liquidityResult = await mockedAssetBuyer.object.getLiquidityForAssetDataAsync(FAKE_ASSET_DATA);
|
||||
expect(liquidityResult).to.deep.equal(expectedLiquidityResult);
|
||||
};
|
||||
|
||||
// tslint:disable:custom-no-magic-numbers
|
||||
describe('AssetBuyer', () => {
|
||||
describe('getLiquidityForAssetDataAsync', () => {
|
||||
const mockWeb3Provider = TypeMoq.Mock.ofType(Web3ProviderEngine);
|
||||
const mockOrderProvider = orderProviderMock();
|
||||
|
||||
beforeEach(() => {
|
||||
mockWeb3Provider.reset();
|
||||
mockOrderProvider.reset();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockWeb3Provider.verifyAll();
|
||||
mockOrderProvider.verifyAll();
|
||||
});
|
||||
|
||||
describe('validation', () => {
|
||||
it('should ensure assetData is a string', async () => {
|
||||
const assetBuyer = AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl(
|
||||
mockWeb3Provider.object,
|
||||
FAKE_SRA_URL,
|
||||
);
|
||||
|
||||
expect(assetBuyer.getLiquidityForAssetDataAsync(false as any)).to.be.rejectedWith(
|
||||
'Expected assetData to be of type string, encountered: false',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('asset pair not supported', () => {
|
||||
it('should return 0s when no asset pair not supported', async () => {
|
||||
mockAvailableAssetDatas(mockOrderProvider, FAKE_ASSET_DATA, []);
|
||||
|
||||
const assetBuyer = new AssetBuyer(mockWeb3Provider.object, mockOrderProvider.object);
|
||||
const liquidityResult = await assetBuyer.getLiquidityForAssetDataAsync(FAKE_ASSET_DATA);
|
||||
expect(liquidityResult).to.deep.equal({
|
||||
tokensAvailableInBaseUnits: new BigNumber(0),
|
||||
ethValueAvailableInWei: new BigNumber(0),
|
||||
});
|
||||
});
|
||||
it('should return 0s when only other asset pair supported', async () => {
|
||||
mockAvailableAssetDatas(mockOrderProvider, FAKE_ASSET_DATA, [DAI_ASSET_DATA]);
|
||||
|
||||
const assetBuyer = new AssetBuyer(mockWeb3Provider.object, mockOrderProvider.object);
|
||||
const liquidityResult = await assetBuyer.getLiquidityForAssetDataAsync(FAKE_ASSET_DATA);
|
||||
expect(liquidityResult).to.deep.equal({
|
||||
tokensAvailableInBaseUnits: new BigNumber(0),
|
||||
ethValueAvailableInWei: new BigNumber(0),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('assetData is supported', () => {
|
||||
// orders
|
||||
const sellTwoTokensFor1Weth: SignedOrder = orderFactory.createSignedOrderFromPartial({
|
||||
makerAssetAmount: baseUnitAmount(2),
|
||||
takerAssetAmount: baseUnitAmount(1, WETH_DECIMALS),
|
||||
});
|
||||
const sellTenTokensFor10Weth: SignedOrder = orderFactory.createSignedOrderFromPartial({
|
||||
makerAssetAmount: baseUnitAmount(10),
|
||||
takerAssetAmount: baseUnitAmount(10, WETH_DECIMALS),
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
mockAvailableAssetDatas(mockOrderProvider, FAKE_ASSET_DATA, [WETH_ASSET_DATA]);
|
||||
});
|
||||
|
||||
it('should return 0s when no orders available', async () => {
|
||||
const ordersAndFillableAmounts: OrdersAndFillableAmounts = {
|
||||
orders: [],
|
||||
remainingFillableMakerAssetAmounts: [],
|
||||
};
|
||||
const expectedResult = {
|
||||
tokensAvailableInBaseUnits: new BigNumber(0),
|
||||
ethValueAvailableInWei: new BigNumber(0),
|
||||
};
|
||||
await expectLiquidityResult(
|
||||
mockWeb3Provider.object,
|
||||
mockOrderProvider.object,
|
||||
ordersAndFillableAmounts,
|
||||
expectedResult,
|
||||
);
|
||||
});
|
||||
|
||||
it('should return correct computed value when orders provided with full fillableAmounts', async () => {
|
||||
const orders: SignedOrder[] = [sellTwoTokensFor1Weth, sellTenTokensFor10Weth];
|
||||
const ordersAndFillableAmounts = {
|
||||
orders: [sellTwoTokensFor1Weth, sellTenTokensFor10Weth],
|
||||
remainingFillableMakerAssetAmounts: orders.map(o => o.makerAssetAmount),
|
||||
};
|
||||
|
||||
const expectedTokensAvailable = orders[0].makerAssetAmount.plus(orders[1].makerAssetAmount);
|
||||
const expectedEthValueAvailable = orders[0].takerAssetAmount.plus(orders[1].takerAssetAmount);
|
||||
const expectedResult = {
|
||||
tokensAvailableInBaseUnits: expectedTokensAvailable,
|
||||
ethValueAvailableInWei: expectedEthValueAvailable,
|
||||
};
|
||||
|
||||
await expectLiquidityResult(
|
||||
mockWeb3Provider.object,
|
||||
mockOrderProvider.object,
|
||||
ordersAndFillableAmounts,
|
||||
expectedResult,
|
||||
);
|
||||
});
|
||||
|
||||
it('should return correct computed value with one partial fillableAmounts', async () => {
|
||||
const ordersAndFillableAmounts = {
|
||||
orders: [sellTwoTokensFor1Weth],
|
||||
remainingFillableMakerAssetAmounts: [baseUnitAmount(1)],
|
||||
};
|
||||
const expectedResult = {
|
||||
tokensAvailableInBaseUnits: baseUnitAmount(1),
|
||||
ethValueAvailableInWei: baseUnitAmount(0.5, WETH_DECIMALS),
|
||||
};
|
||||
|
||||
await expectLiquidityResult(
|
||||
mockWeb3Provider.object,
|
||||
mockOrderProvider.object,
|
||||
ordersAndFillableAmounts,
|
||||
expectedResult,
|
||||
);
|
||||
});
|
||||
|
||||
it('should return correct computed value with multiple orders and fillable amounts', async () => {
|
||||
const ordersAndFillableAmounts = {
|
||||
orders: [sellTwoTokensFor1Weth, sellTenTokensFor10Weth],
|
||||
remainingFillableMakerAssetAmounts: [baseUnitAmount(1), baseUnitAmount(3)],
|
||||
};
|
||||
const expectedResult = {
|
||||
tokensAvailableInBaseUnits: baseUnitAmount(4),
|
||||
ethValueAvailableInWei: baseUnitAmount(3.5, WETH_DECIMALS),
|
||||
};
|
||||
|
||||
await expectLiquidityResult(
|
||||
mockWeb3Provider.object,
|
||||
mockOrderProvider.object,
|
||||
ordersAndFillableAmounts,
|
||||
expectedResult,
|
||||
);
|
||||
});
|
||||
|
||||
it('should return 0s when no amounts fillable', async () => {
|
||||
const ordersAndFillableAmounts = {
|
||||
orders: [sellTwoTokensFor1Weth, sellTenTokensFor10Weth],
|
||||
remainingFillableMakerAssetAmounts: [baseUnitAmount(0), baseUnitAmount(0)],
|
||||
};
|
||||
const expectedResult = {
|
||||
tokensAvailableInBaseUnits: baseUnitAmount(0),
|
||||
ethValueAvailableInWei: baseUnitAmount(0, WETH_DECIMALS),
|
||||
};
|
||||
|
||||
await expectLiquidityResult(
|
||||
mockWeb3Provider.object,
|
||||
mockOrderProvider.object,
|
||||
ordersAndFillableAmounts,
|
||||
expectedResult,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -168,7 +168,7 @@ describe('buyQuoteCalculator', () => {
|
||||
};
|
||||
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(1));
|
||||
});
|
||||
it('should throw without amount available to fill if amount rounds to 0', () => {
|
||||
it('should throw with 0 available to fill if amount rounds to 0', () => {
|
||||
const smallOrder = orderFactory.createSignedOrderFromPartial({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
takerAssetAmount: new BigNumber(1),
|
||||
|
68
packages/asset-buyer/test/utils/mocks.ts
Normal file
68
packages/asset-buyer/test/utils/mocks.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import { Web3ProviderEngine } from '@0x/subproviders';
|
||||
import * as TypeMoq from 'typemoq';
|
||||
|
||||
import { AssetBuyer } from '../../src/asset_buyer';
|
||||
import { OrderProvider, OrderProviderResponse, OrdersAndFillableAmounts } from '../../src/types';
|
||||
|
||||
// tslint:disable:promise-function-async
|
||||
|
||||
// Implementing dummy class for using in mocks, see https://github.com/florinn/typemoq/issues/3
|
||||
class OrderProviderClass implements OrderProvider {
|
||||
// tslint:disable-next-line:prefer-function-over-method
|
||||
public async getOrdersAsync(): Promise<OrderProviderResponse> {
|
||||
return Promise.resolve({ orders: [] });
|
||||
}
|
||||
// tslint:disable-next-line:prefer-function-over-method
|
||||
public async getAvailableMakerAssetDatasAsync(takerAssetData: string): Promise<string[]> {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
}
|
||||
|
||||
export const orderProviderMock = () => {
|
||||
return TypeMoq.Mock.ofType(OrderProviderClass, TypeMoq.MockBehavior.Strict);
|
||||
};
|
||||
|
||||
export const mockAvailableAssetDatas = (
|
||||
mockOrderProvider: TypeMoq.IMock<OrderProviderClass>,
|
||||
assetData: string,
|
||||
availableAssetDatas: string[],
|
||||
) => {
|
||||
mockOrderProvider
|
||||
.setup(op => op.getAvailableMakerAssetDatasAsync(TypeMoq.It.isValue(assetData)))
|
||||
.returns(() => {
|
||||
return Promise.resolve(availableAssetDatas);
|
||||
})
|
||||
.verifiable(TypeMoq.Times.once());
|
||||
};
|
||||
|
||||
const partiallyMockedAssetBuyer = (
|
||||
provider: Web3ProviderEngine,
|
||||
orderProvider: OrderProvider,
|
||||
): TypeMoq.IMock<AssetBuyer> => {
|
||||
const rawAssetBuyer = new AssetBuyer(provider, orderProvider);
|
||||
const mockedAssetBuyer = TypeMoq.Mock.ofInstance(rawAssetBuyer, TypeMoq.MockBehavior.Loose, false);
|
||||
mockedAssetBuyer.callBase = true;
|
||||
return mockedAssetBuyer;
|
||||
};
|
||||
|
||||
const mockGetOrdersAndAvailableAmounts = (
|
||||
mockedAssetBuyer: TypeMoq.IMock<AssetBuyer>,
|
||||
assetData: string,
|
||||
ordersAndFillableAmounts: OrdersAndFillableAmounts,
|
||||
): void => {
|
||||
mockedAssetBuyer
|
||||
.setup(a => a.getOrdersAndFillableAmountsAsync(assetData, false))
|
||||
.returns(() => Promise.resolve(ordersAndFillableAmounts))
|
||||
.verifiable(TypeMoq.Times.once());
|
||||
};
|
||||
|
||||
export const mockedAssetBuyerWithOrdersAndFillableAmounts = (
|
||||
provider: Web3ProviderEngine,
|
||||
orderProvider: OrderProvider,
|
||||
assetData: string,
|
||||
ordersAndFillableAmounts: OrdersAndFillableAmounts,
|
||||
): TypeMoq.IMock<AssetBuyer> => {
|
||||
const mockedAssetBuyer = partiallyMockedAssetBuyer(provider, orderProvider);
|
||||
mockGetOrdersAndAvailableAmounts(mockedAssetBuyer, assetData, ordersAndFillableAmounts);
|
||||
return mockedAssetBuyer;
|
||||
};
|
@ -6,7 +6,7 @@ export const testHelpers = {
|
||||
expectInsufficientLiquidityError: (
|
||||
expect: Chai.ExpectStatic,
|
||||
functionWhichTriggersError: () => void,
|
||||
expectedAmountAvailableToFill?: BigNumber,
|
||||
expectedAmountAvailableToFill: BigNumber,
|
||||
): void => {
|
||||
let wasErrorThrown = false;
|
||||
try {
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "5.0.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "5.0.0",
|
||||
"changes": [
|
||||
|
@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v5.0.1 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v5.0.0 - _January 15, 2019_
|
||||
|
||||
* Renamed OrderStatus enum members to PascalCase to conform with tslint enum-naming rule (#1474)
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contract-wrappers",
|
||||
"version": "5.0.0",
|
||||
"version": "5.0.1",
|
||||
"description": "Smart TS wrappers for 0x smart contracts",
|
||||
"keywords": [
|
||||
"0xproject",
|
||||
@ -69,7 +69,7 @@
|
||||
"@0x/assert": "^1.0.23",
|
||||
"@0x/contract-addresses": "^2.2.0",
|
||||
"@0x/contract-artifacts": "^1.3.0",
|
||||
"@0x/contracts-test-utils": "^2.0.0",
|
||||
"@0x/contracts-test-utils": "^2.0.1",
|
||||
"@0x/fill-scenarios": "^1.1.2",
|
||||
"@0x/json-schemas": "^2.1.7",
|
||||
"@0x/order-utils": "^3.1.2",
|
||||
|
2
packages/dev-tools-pages/.gitignore
vendored
2
packages/dev-tools-pages/.gitignore
vendored
@ -1,3 +1 @@
|
||||
public
|
||||
assets/fonts/*.woff
|
||||
assets/fonts/*.woff2
|
@ -1,20 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<ul>
|
||||
<li><a href="/compiler">Compiler</a></li>
|
||||
<li><a href="/cov">Cov</a></li>
|
||||
<li><a href="/profiler">Profiler</a></li>
|
||||
<li><a href="/trace">Trace</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>Test</title>
|
||||
</head>
|
||||
<body>
|
||||
<ul>
|
||||
<li><a href="/compiler">Compiler</a></li>
|
||||
<li><a href="/coverage">Coverage</a></li>
|
||||
<li><a href="/profiler">Profiler</a></li>
|
||||
<li><a href="/trace">Trace</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
Binary file not shown.
@ -1,18 +1,28 @@
|
||||
{
|
||||
"name": "@0x/dev-tools-pages",
|
||||
"version": "0.0.13",
|
||||
"version": "0.0.14",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
"private": true,
|
||||
"description": "0x Dev tools pages",
|
||||
"scripts": {
|
||||
"build": "node --max_old_space_size=8192 ../../node_modules/.bin/webpack --mode production && react-snap",
|
||||
"build": "node --max_old_space_size=8192 ../../node_modules/.bin/webpack --mode production",
|
||||
"build:ci": "yarn build",
|
||||
"build:dev": "../../node_modules/.bin/webpack --mode development",
|
||||
"clean": "shx rm -f public/bundle*",
|
||||
"lint": "tslint --format stylish --project . 'ts/**/*.ts' 'ts/**/*.tsx'",
|
||||
"dev": "webpack-dev-server --mode development --content-base public"
|
||||
"dev": "webpack-dev-server --mode development --content-base public",
|
||||
"deploy:all": "npm run build; npm run deploy:compiler; npm run deploy:compiler:index; npm run deploy:coverage; npm run deploy:coverage:index; npm run deploy:profiler; npm run deploy:profiler:index; npm run deploy:trace; npm run deploy:trace:index;",
|
||||
"deploy:compiler": "DIR_NAME=./public/. BUCKET=s3://sol-compiler.com yarn s3:sync --exclude 'bundle-cov*' --exclude 'bundle-trace*' --exclude 'bundle-profiler*'",
|
||||
"deploy:coverage": "DIR_NAME=./public/. BUCKET=s3://sol-coverage.com yarn s3:sync --exclude 'bundle-compiler*' --exclude 'bundle-trace*' --exclude 'bundle-profiler*'",
|
||||
"deploy:profiler": "DIR_NAME=./public/. BUCKET=s3://sol-profiler.com yarn s3:sync --exclude 'bundle-cov*' --exclude 'bundle-trace*' --exclude 'bundle-compiler*'",
|
||||
"deploy:trace": "DIR_NAME=./public/. BUCKET=s3://sol-trace.com yarn s3:sync --exclude 'bundle-cov*' --exclude 'bundle-compiler*' --exclude 'bundle-profiler*'",
|
||||
"deploy:compiler:index": "DIR_NAME=./public/compiler/. BUCKET=s3://sol-compiler.com yarn s3:sync",
|
||||
"deploy:coverage:index": "DIR_NAME=./public/coverage/. BUCKET=s3://sol-coverage.com yarn s3:sync",
|
||||
"deploy:profiler:index": "DIR_NAME=./public/profiler/. BUCKET=s3://sol-profiler.com yarn s3:sync",
|
||||
"deploy:trace:index": "DIR_NAME=./public/trace/. BUCKET=s3://sol-trace.com yarn s3:sync",
|
||||
"s3:sync": "aws s3 sync $DIR_NAME $BUCKET --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --exclude *.map.js --exclude 'profiler/*' --exclude 'trace/*' --exclude 'coverage/*' --exclude 'compiler/*'"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
@ -51,7 +61,6 @@
|
||||
"less-loader": "^4.1.0",
|
||||
"make-promises-safe": "^1.1.0",
|
||||
"raw-loader": "^0.5.1",
|
||||
"react-snap": "^1.19.0",
|
||||
"react-svg-loader": "^2.1.0",
|
||||
"shx": "^0.2.2",
|
||||
"source-map-loader": "^0.2.4",
|
||||
@ -65,12 +74,5 @@
|
||||
"webpack-bundle-analyzer": "^3.0.3",
|
||||
"webpack-cli": "3.1.2",
|
||||
"webpack-dev-server": "^3.1.9"
|
||||
},
|
||||
"reactSnap": {
|
||||
"source": "public",
|
||||
"puppeteerArgs": [
|
||||
"--no-sandbox",
|
||||
"--disable-setuid-sandbox"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -11,26 +11,26 @@ const pages = [
|
||||
'og-title': { property: 'og:title', content: 'sol-compiler' },
|
||||
'og-description': { property: 'og:description', content: 'Solidity compilation that just works' },
|
||||
'og-type': { property: 'og:type', content: 'website' },
|
||||
'og-image': { property: 'og:image', content: '/images/og-compiler' },
|
||||
'og-image': { property: 'og:image', content: '/images/og-compiler.png' },
|
||||
'twitter:site': '@0xproject',
|
||||
'twitter:image': '/images/og-compiler',
|
||||
'twitter:image': '/images/og-compiler.png',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'sol-cov',
|
||||
filename: 'cov/index.html',
|
||||
title: 'sol-coverage',
|
||||
filename: 'coverage/index.html',
|
||||
template: 'assets/index.html',
|
||||
chunks: ['cov'],
|
||||
chunks: ['coverage'],
|
||||
favicon: 'assets/favicons/cov.ico',
|
||||
minify: true,
|
||||
meta: {
|
||||
description: 'Solidity code coverage',
|
||||
'og-title': { property: 'og:title', content: 'sol-cov' },
|
||||
'og-title': { property: 'og:title', content: 'sol-coverage' },
|
||||
'og-description': { property: 'og:description', content: 'Solidity code coverage' },
|
||||
'og-type': { property: 'og:type', content: 'website' },
|
||||
'og-image': { property: 'og:image', content: '/images/og-cov' },
|
||||
'og-image': { property: 'og:image', content: '/images/og-cov.png' },
|
||||
'twitter:site': '@0xproject',
|
||||
'twitter:image': '/images/og-cov',
|
||||
'twitter:image': '/images/og-cov.png',
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -45,9 +45,9 @@ const pages = [
|
||||
'og-title': { property: 'og:title', content: 'sol-profiler' },
|
||||
'og-description': { property: 'og:description', content: 'Gas profiling for Solidity' },
|
||||
'og-type': { property: 'og:type', content: 'website' },
|
||||
'og-image': { property: 'og:image', content: '/images/og-profiler' },
|
||||
'og-image': { property: 'og:image', content: '/images/og-profiler.png' },
|
||||
'twitter:site': '@0xproject',
|
||||
'twitter:image': '/images/og-profiler',
|
||||
'twitter:image': '/images/og-profiler.png',
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -62,9 +62,9 @@ const pages = [
|
||||
'og-title': { property: 'og:title', content: 'sol-trace' },
|
||||
'og-description': { property: 'og:description', content: 'Human-readable stack traces' },
|
||||
'og-type': { property: 'og:type', content: 'website' },
|
||||
'og-image': { property: 'og:image', content: '/images/og-trace' },
|
||||
'og-image': { property: 'og:image', content: '/images/og-trace.png' },
|
||||
'twitter:site': '@0xproject',
|
||||
'twitter:image': '/images/og-trace',
|
||||
'twitter:image': '/images/og-trace.png',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
40
packages/dev-tools-pages/ts/components/call_to_action.tsx
Normal file
40
packages/dev-tools-pages/ts/components/call_to_action.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
import * as React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { ContextInterface, ThemeContext } from 'ts/context';
|
||||
|
||||
import { Button } from './button';
|
||||
|
||||
const CallToAction: React.StatelessComponent<ContextInterface> = ({ children }) => (
|
||||
<ThemeContext.Consumer>
|
||||
{({ docLink }: ContextInterface) => (
|
||||
<StyledCallToAction>
|
||||
<CallToActionContainer>
|
||||
<Button as="a" href={docLink} target="_blank" large={true}>
|
||||
Read the Docs
|
||||
</Button>
|
||||
</CallToActionContainer>
|
||||
{children}
|
||||
</StyledCallToAction>
|
||||
)}
|
||||
</ThemeContext.Consumer>
|
||||
);
|
||||
|
||||
const StyledCallToAction = styled.section`
|
||||
text-align: center;
|
||||
padding-top: 0;
|
||||
padding-bottom: 1rem;
|
||||
padding-left: 2.5rem;
|
||||
padding-right: 2.5rem;
|
||||
min-height: min-content;
|
||||
max-height: 37.5rem;
|
||||
height: 20vh;
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
const CallToActionContainer = styled.div`
|
||||
margin: 0 auto;
|
||||
max-width: 590px;
|
||||
`;
|
||||
|
||||
export { CallToAction };
|
@ -139,7 +139,6 @@ class Code extends React.Component<CodeProps, CodeState> {
|
||||
public render(): React.ReactNode {
|
||||
const { language, isLight, isDiff, children, gutterLength, canCopy } = this.props;
|
||||
const { hlCode } = this.state;
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Base language={language} isDiff={isDiff} isLight={isLight}>
|
||||
@ -157,7 +156,7 @@ class Code extends React.Component<CodeProps, CodeState> {
|
||||
<StyledCopyInput readOnly={true} aria-hidden="true" ref={this._code} value={children} />
|
||||
) : null}
|
||||
</Base>
|
||||
{navigator.userAgent !== 'ReactSnap' && canCopy ? (
|
||||
{canCopy ? (
|
||||
<Button onClick={this._handleCopyAsync.bind(this)}>{this.state.didCopy ? 'Copied' : 'Copy'}</Button>
|
||||
) : null}
|
||||
</Container>
|
||||
|
@ -45,7 +45,7 @@ const Dd = styled.dd`
|
||||
|
||||
const cards = [
|
||||
{
|
||||
title: 'A Project-centric',
|
||||
title: 'Project-centric',
|
||||
body: (
|
||||
<React.Fragment>
|
||||
Compiles an entire project instead of only individual <InlineCode isAlt={true}>.sol</InlineCode> files.
|
||||
@ -54,7 +54,7 @@ const cards = [
|
||||
},
|
||||
{
|
||||
title: 'Incremental builds',
|
||||
body: 'Recompiles your smart contracts after they have changed',
|
||||
body: 'Only recompiles smart contracts that have been modified.',
|
||||
},
|
||||
{
|
||||
title: 'Customizable artifacts',
|
||||
@ -63,12 +63,16 @@ const cards = [
|
||||
},
|
||||
{
|
||||
title: 'Seamless',
|
||||
body: 'Fetches and caches the required compiler binaries.',
|
||||
body: 'Fetches and caches the required compiler binaries for the Solidity versions you use.',
|
||||
},
|
||||
{
|
||||
title: 'Versioning',
|
||||
body:
|
||||
'Compiles each contract with the version specified at the top of its file (sol-compiler even supports version ranges!).',
|
||||
'Compiles each contract with the Solidity version specified at the top of its file (it even supports version ranges!).',
|
||||
},
|
||||
{
|
||||
title: 'Watch mode',
|
||||
body: 'Have your contracts instantly recompile on file save.',
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -3,7 +3,7 @@ import * as React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { context as compiler } from 'ts/context/compiler';
|
||||
import { context as cov } from 'ts/context/cov';
|
||||
import { context as coverage } from 'ts/context/coverage';
|
||||
import { context as profiler } from 'ts/context/profiler';
|
||||
import { context as trace } from 'ts/context/trace';
|
||||
import MainIcon from 'ts/icons/logos/0x.svg';
|
||||
@ -12,7 +12,7 @@ import { media } from 'ts/variables';
|
||||
import { Container } from './container';
|
||||
import { Alpha, Beta } from './typography';
|
||||
|
||||
const tools = [trace, cov, compiler, profiler];
|
||||
const tools = [trace, coverage, compiler, profiler];
|
||||
|
||||
const Footer: React.StatelessComponent<{}> = () => (
|
||||
<StyledFooter>
|
||||
@ -20,9 +20,9 @@ const Footer: React.StatelessComponent<{}> = () => (
|
||||
<Top>
|
||||
<Alpha>Other tools by 0x</Alpha>
|
||||
<List>
|
||||
{_.map(tools, ({ title, subtitle, icon }) => (
|
||||
{_.map(tools, ({ title, subtitle, icon, name }) => (
|
||||
<ListItem key={title}>
|
||||
<ListLink href="#">
|
||||
<ListLink href={`https://sol-${name}.com`}>
|
||||
<Icon as={icon as 'svg'} />
|
||||
<div>
|
||||
<Beta>{title}</Beta>
|
||||
@ -37,6 +37,10 @@ const Footer: React.StatelessComponent<{}> = () => (
|
||||
<Icon as={MainIcon} />
|
||||
<Small>
|
||||
0x is an open, permissionless protocol allowing for tokens to be traded on the Ethereum blockchain.
|
||||
Interested in joining our team?{' '}
|
||||
<a href="https://0x.org/careers" target="_blank">
|
||||
We're hiring
|
||||
</a>
|
||||
</Small>
|
||||
</Media>
|
||||
</Container>
|
||||
|
@ -17,7 +17,7 @@ const Header: React.StatelessComponent<{}> = () => (
|
||||
<Title>{title}</Title>
|
||||
</LogoMark>
|
||||
|
||||
<Link as="a" href="https://0xproject.com/">
|
||||
<Link as="a" href="https://0x.org/" target="_blank">
|
||||
Built by 0x
|
||||
</Link>
|
||||
</Container>
|
||||
|
@ -9,16 +9,16 @@ import { Beta } from './typography';
|
||||
|
||||
const Hero: React.StatelessComponent<ContextInterface> = ({ children }) => (
|
||||
<ThemeContext.Consumer>
|
||||
{({ subtitle, tagline }: ContextInterface) => (
|
||||
{({ subtitle, tagline, docLink }: ContextInterface) => (
|
||||
<StyledHero>
|
||||
<HeroContainer>
|
||||
<Subtitle>{subtitle}</Subtitle>
|
||||
<Tagline as="p">{tagline}</Tagline>
|
||||
<Button as="a" href="#" large={true}>
|
||||
<Button as="a" href={docLink} target="_blank" large={true}>
|
||||
Read the Docs
|
||||
</Button>
|
||||
</HeroContainer>
|
||||
{navigator.userAgent !== 'ReactSnap' ? children : null}
|
||||
{children}
|
||||
</StyledHero>
|
||||
)}
|
||||
</ThemeContext.Consumer>
|
||||
|
@ -25,7 +25,7 @@ const Trace: React.StatelessComponent<{}> = () => (
|
||||
troublemaking line of code. The only hint you'll get is a generic error.
|
||||
</MainCopy>
|
||||
<Breakout>
|
||||
<Code isLight={true}>Error: VM Exception while processing transaction: rever</Code>
|
||||
<Code isLight={true}>Error: VM Exception while processing transaction: revert</Code>
|
||||
</Breakout>
|
||||
|
||||
<List>
|
||||
@ -44,8 +44,8 @@ const Trace: React.StatelessComponent<{}> = () => (
|
||||
<Copy dark={true}>
|
||||
<Gamma as="h3">Time-consuming</Gamma>
|
||||
<p>
|
||||
Working with a large code-base that contains hundreds of smart contracts,
|
||||
finding the failing line of code quickly becomes a daunting task.
|
||||
Working within a large code-base that contains many smart contracts, finding the
|
||||
failing line of code quickly becomes a daunting task.
|
||||
</p>
|
||||
</Copy>
|
||||
<Icon as={TimeConsuming} />
|
||||
@ -78,8 +78,8 @@ const Trace: React.StatelessComponent<{}> = () => (
|
||||
<Copy>
|
||||
<Gamma as="h3">Exact location</Gamma>
|
||||
<p>
|
||||
It shows you the exact location of the specific code linen and where it was
|
||||
called from.
|
||||
It shows you the exact location of the offending line and where it was called
|
||||
from.
|
||||
</p>
|
||||
</Copy>
|
||||
<Icon as={ExactLocation} />
|
||||
@ -90,8 +90,7 @@ const Trace: React.StatelessComponent<{}> = () => (
|
||||
<Gamma as="h3">Time-saving</Gamma>
|
||||
<p>
|
||||
Turning "Your code failed somewhere, good luck debugging it" into "Your code
|
||||
failed on line X of contract Y", it drastically improves the developer
|
||||
experience.
|
||||
failed on line X of contract Y", drastically improves the developer experience.
|
||||
</p>
|
||||
</Copy>
|
||||
<Icon as={TimeSaving} />
|
||||
|
@ -5,6 +5,7 @@ import { ContextInterface } from './index';
|
||||
export const context: ContextInterface = {
|
||||
title: 'sol-compiler',
|
||||
name: 'compiler',
|
||||
docLink: 'https://0x.org/docs/sol-compiler',
|
||||
subtitle: 'Solidity compilation that just works',
|
||||
tagline: 'Seamlessly compile an entire solidity project and generate customisable artifacts',
|
||||
icon: Icon,
|
||||
|
@ -3,9 +3,10 @@ import Icon from 'ts/icons/logos/cov.svg';
|
||||
import { ContextInterface } from './index';
|
||||
|
||||
export const context: ContextInterface = {
|
||||
title: 'sol-cov',
|
||||
name: 'cov',
|
||||
title: 'sol-coverage',
|
||||
name: 'coverage',
|
||||
subtitle: 'Solidity code coverage',
|
||||
docLink: 'https://0x.org/docs/sol-coverage',
|
||||
tagline: 'Measure Solidity code coverage',
|
||||
icon: Icon,
|
||||
colors: {
|
@ -3,6 +3,7 @@ import { createContext } from 'react';
|
||||
interface ContextInterface {
|
||||
title?: string;
|
||||
name?: string;
|
||||
docLink?: string;
|
||||
subtitle?: string;
|
||||
tagline?: string;
|
||||
icon?: React.ReactNode;
|
||||
|
@ -5,6 +5,7 @@ import { ContextInterface } from './index';
|
||||
export const context: ContextInterface = {
|
||||
title: 'sol-profiler',
|
||||
name: 'profiler',
|
||||
docLink: 'https://0x.org/docs/sol-profiler',
|
||||
subtitle: 'Gas profiling for Solidity',
|
||||
tagline: "Implement data-guided optimizations by profiling your contract's gas usage",
|
||||
icon: Icon,
|
||||
|
@ -6,6 +6,7 @@ export const context: ContextInterface = {
|
||||
title: 'sol-trace',
|
||||
name: 'trace',
|
||||
subtitle: 'Human-readable stack traces',
|
||||
docLink: 'https://0x.org/docs/sol-trace',
|
||||
tagline: 'Immediately locate Solidity errors and rapidly debug failed transactions',
|
||||
icon: Icon,
|
||||
colors: {
|
||||
|
@ -6,6 +6,7 @@ import { context } from 'ts/context/compiler';
|
||||
|
||||
import { Base } from 'ts/components/base';
|
||||
import { Breakout } from 'ts/components/breakout';
|
||||
import { CallToAction } from 'ts/components/call_to_action';
|
||||
import { Code } from 'ts/components/code';
|
||||
import { Compiler as CompilerComponent } from 'ts/components/compiler';
|
||||
import { Content } from 'ts/components/content';
|
||||
@ -24,6 +25,9 @@ const Animation = Loadable({
|
||||
},
|
||||
});
|
||||
|
||||
const SOLIDITY_INPUT_FORMAT_DOCS =
|
||||
'https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#compiler-input-and-output-json-description';
|
||||
|
||||
const Compiler: React.StatelessComponent<{}> = () => (
|
||||
<Base context={context}>
|
||||
<Hero>
|
||||
@ -40,7 +44,7 @@ const Compiler: React.StatelessComponent<{}> = () => (
|
||||
|
||||
<ContentBlock title="Run">
|
||||
<Breakout>
|
||||
<Code>cd /your_project_dir && sol-compiler</Code>
|
||||
<Code canCopy={true}>cd /your_project_dir && sol-compiler</Code>
|
||||
</Breakout>
|
||||
</ContentBlock>
|
||||
|
||||
@ -49,11 +53,11 @@ const Compiler: React.StatelessComponent<{}> = () => (
|
||||
Configure via a <InlineCode>compiler.json</InlineCode> file.
|
||||
</p>
|
||||
<Breakout>
|
||||
<Code>mkdir compiler.json</Code>
|
||||
<Code canCopy={true}>mkdir compiler.json</Code>
|
||||
</Breakout>
|
||||
<p>Example of settings:</p>
|
||||
<Breakout>
|
||||
<Code language="json">
|
||||
<Code language="json" canCopy={true}>
|
||||
{`{
|
||||
"contractsDir": "contracts",
|
||||
"artifactsDir": "artifacts",
|
||||
@ -74,15 +78,19 @@ const Compiler: React.StatelessComponent<{}> = () => (
|
||||
<Content dark={true}>
|
||||
<ContentBlock main={true} title="Artifacts">
|
||||
<Lead>
|
||||
Sol compiler uses solidity standard JSON output format for the artifacts. This way, you can define
|
||||
which parts of the artifact you need.
|
||||
Sol compiler uses{' '}
|
||||
<a href={SOLIDITY_INPUT_FORMAT_DOCS} target="_blank">
|
||||
Solidity standard JSON input format
|
||||
</a>{' '}
|
||||
to specify what to include in the generated artifacts. This way, you have complete flexibility on
|
||||
what is included.
|
||||
</Lead>
|
||||
</ContentBlock>
|
||||
|
||||
<ContentBlock title="Production">
|
||||
<p>
|
||||
Sol compiler uses solidity standard JSON output format for the artifacts. This way, you can define
|
||||
which parts of the artifact you need.
|
||||
In production, you want to optimize for a small bundle size, so your compiler.json config would
|
||||
instruct sol-compiler to only output the contract ABI.
|
||||
</p>
|
||||
<Breakout>
|
||||
<Code isLight={true} language="json" isEtc={true}>
|
||||
@ -109,8 +117,9 @@ const Compiler: React.StatelessComponent<{}> = () => (
|
||||
</ContentBlock>
|
||||
<ContentBlock title="Development">
|
||||
<p>
|
||||
Sometimes you need to use some debuggers or other dev tools and you’ll need more info in the
|
||||
artifact.
|
||||
In development, you need to use profiler and other dev tools that require more information from the
|
||||
artifact. To do this, you can specify that the artifact also contain the bytecode, deployed bytecode
|
||||
and source maps.
|
||||
</p>
|
||||
<Breakout>
|
||||
<Code isLight={true} language="json" isEtc={true}>
|
||||
@ -158,6 +167,9 @@ const Compiler: React.StatelessComponent<{}> = () => (
|
||||
</Breakout>
|
||||
</ContentBlock>
|
||||
</Content>
|
||||
<div style={{ paddingTop: '5rem' }}>
|
||||
<CallToAction />
|
||||
</div>
|
||||
</Base>
|
||||
);
|
||||
|
||||
|
@ -2,10 +2,11 @@ import * as React from 'react';
|
||||
import { hydrate, render } from 'react-dom';
|
||||
import * as Loadable from 'react-loadable';
|
||||
|
||||
import { context } from 'ts/context/cov';
|
||||
import { context } from 'ts/context/coverage';
|
||||
|
||||
import { Base } from 'ts/components/base';
|
||||
import { Breakout } from 'ts/components/breakout';
|
||||
import { CallToAction } from 'ts/components/call_to_action';
|
||||
import { Code } from 'ts/components/code';
|
||||
import { Content } from 'ts/components/content';
|
||||
import { ContentBlock } from 'ts/components/content-block';
|
||||
@ -25,7 +26,7 @@ const Animation = Loadable({
|
||||
},
|
||||
});
|
||||
|
||||
const Cov: React.StatelessComponent<{}> = () => (
|
||||
const Coverage: React.StatelessComponent<{}> = () => (
|
||||
<Base context={context}>
|
||||
<Hero>
|
||||
<Animation />
|
||||
@ -33,9 +34,9 @@ const Cov: React.StatelessComponent<{}> = () => (
|
||||
<Intro>
|
||||
<IntroLead title="Measure your tests">
|
||||
<p>
|
||||
When it comes to writing smart contracts, testing is one of the most important steps of the process.
|
||||
In order to quantify the robustness of your Solidity testing suite, you need to measure its code
|
||||
coverage.
|
||||
When it comes to writing secure smart contracts, testing is one of the most important steps in the
|
||||
process. In order to quantify the robustness of your Solidity testing suite, you need to measure its
|
||||
code coverage.
|
||||
</p>
|
||||
</IntroLead>
|
||||
<IntroAside>
|
||||
@ -69,29 +70,57 @@ const Cov: React.StatelessComponent<{}> = () => (
|
||||
<ContentBlock title="Prerequisites">
|
||||
<List>
|
||||
<ListItem>
|
||||
Use <a href="#">ganache-cli</a> as a backing node.
|
||||
Use{' '}
|
||||
<a href="https://github.com/ethereum/go-ethereum" target="_blank">
|
||||
Geth
|
||||
</a>{' '}
|
||||
as a backing node. We recommend using our{' '}
|
||||
<a href="https://hub.docker.com/r/0xorg/devnet" target="_blank">
|
||||
Devnet Docker container
|
||||
</a>{' '}
|
||||
which sets up a Geth node for testing purposes.{' '}
|
||||
<a href="https://github.com/0xProject/0x-monorepo/issues/1520" target="_blank">
|
||||
Ganache support is a work in progress.
|
||||
</a>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
Understand and use <a href="#">web3-provider-engine</a>.
|
||||
Understand and use{' '}
|
||||
<a href="https://github.com/MetaMask/provider-engine" target="_blank">
|
||||
web3-provider-engine
|
||||
</a>
|
||||
.
|
||||
</ListItem>
|
||||
</List>
|
||||
</ContentBlock>
|
||||
<ContentBlock title="Installation">
|
||||
<Breakout>
|
||||
<Code>npm install @0x/sol-coverage --save</Code>
|
||||
<Code canCopy={true}>npm install @0x/sol-coverage --save</Code>
|
||||
</Breakout>
|
||||
|
||||
<p>
|
||||
Sol-cov is a subprovider that needs to be prepended to your <a href="#">provider engine</a>.
|
||||
Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-cov ships with
|
||||
the <InlineCode>SolCompilerArtifactAdapter</InlineCode> for use with <a href="#">Sol-compiler</a>{' '}
|
||||
Sol-coverage is a subprovider that needs to be prepended to your{' '}
|
||||
<a href="https://github.com/MetaMask/provider-engine" target="_blank">
|
||||
provider engine
|
||||
</a>
|
||||
. Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-coverage
|
||||
ships with the <InlineCode>SolCompilerArtifactAdapter</InlineCode> for use with{' '}
|
||||
<a href="https://sol-compiler.com" target="_blank">
|
||||
Sol-compiler
|
||||
</a>{' '}
|
||||
and <InlineCode>TruffleArtifactAdapter</InlineCode> for use with the{' '}
|
||||
<a href="#">Truffle framework</a>. You can also write your own and support any artifact format.
|
||||
<a href="https://truffleframework.com/truffle" target="_blank">
|
||||
Truffle framework
|
||||
</a>{' '}
|
||||
(Also see our{' '}
|
||||
<a href="https://github.com/0xProject/dev-tools-truffle-example" target="_blank">
|
||||
Truffle example project
|
||||
</a>{' '}
|
||||
for a complete walk-through). You can also write your own and support any artifact format.
|
||||
</p>
|
||||
|
||||
<Tabs>
|
||||
<TabBlock title="Sol-compiler">
|
||||
<Code language="javascript">
|
||||
<Code language="javascript" canCopy={true}>
|
||||
{`import { SolCompilerArtifactAdapter } from '@0x/sol-trace';
|
||||
|
||||
// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
|
||||
@ -99,16 +128,16 @@ const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDi
|
||||
</Code>
|
||||
</TabBlock>
|
||||
<TabBlock title="Truffle">
|
||||
<Code language="javascript">
|
||||
<Code language="javascript" canCopy={true}>
|
||||
{`import { TruffleArtifactAdapter } from '@0x/sol-trace';
|
||||
|
||||
const projectRoot = '.';
|
||||
const solcVersion = '0.4.24';
|
||||
const solcVersion = '0.5.0';
|
||||
const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);`}
|
||||
</Code>
|
||||
</TabBlock>
|
||||
<TabBlock title="Custom">
|
||||
<Code language="javascript">
|
||||
<Code language="javascript" canCopy={true}>
|
||||
{`import { AbstractArtifactAdapter } from '@0x/sol-trace';
|
||||
|
||||
class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...};
|
||||
@ -118,32 +147,33 @@ const artifactAdapter = new YourCustomArtifactsAdapter(...);`}
|
||||
</Tabs>
|
||||
<p>
|
||||
Now that we have an <InlineCode>artifactAdapter</InlineCode>, we can create a{' '}
|
||||
<InlineCode>RevertTraceSubprovider</InlineCode> and append it to our provider engine.
|
||||
<InlineCode>CoverageSubprovider</InlineCode> and append it to our provider engine.
|
||||
</p>
|
||||
|
||||
<Breakout>
|
||||
<Code language="javascript">
|
||||
<Code language="javascript" canCopy={true}>
|
||||
{`import { ProviderEngine, RpcSubprovider } from 'web3-provider-engine';
|
||||
import { RevertTraceSubprovider } from '@0x/sol-coverage';
|
||||
import { CoverageSubprovider } from '@0x/sol-coverage';
|
||||
|
||||
const defaultFromAddress = "..."; // Some ethereum address with test funds
|
||||
const revertTraceSubprovider = new RevertTraceSubprovider(artifactAdapter, defaultFromAddress);
|
||||
const coverageSubprovider = new CoverageSubprovider(artifactAdapter, defaultFromAddress);
|
||||
|
||||
const providerEngine = new ProviderEngine();
|
||||
providerEngine.addProvider(revertTraceSubprovider);
|
||||
providerEngine.addProvider(coverageSubprovider);
|
||||
providerEngine.addProvider(new RpcSubprovider({rpcUrl: 'http://localhost:8545'}));
|
||||
providerEngine.start();`}
|
||||
</Code>
|
||||
</Breakout>
|
||||
</ContentBlock>
|
||||
</Content>
|
||||
<CallToAction />
|
||||
</Base>
|
||||
);
|
||||
|
||||
const root = document.getElementById('app');
|
||||
|
||||
if (root.hasChildNodes()) {
|
||||
hydrate(<Cov />, root);
|
||||
hydrate(<Coverage />, root);
|
||||
} else {
|
||||
render(<Cov />, root);
|
||||
render(<Coverage />, root);
|
||||
}
|
@ -6,6 +6,7 @@ import { context } from 'ts/context/profiler';
|
||||
|
||||
import { Base } from 'ts/components/base';
|
||||
import { Breakout } from 'ts/components/breakout';
|
||||
import { CallToAction } from 'ts/components/call_to_action';
|
||||
import { Code } from 'ts/components/code';
|
||||
import { Content } from 'ts/components/content';
|
||||
import { ContentBlock } from 'ts/components/content-block';
|
||||
@ -66,29 +67,57 @@ const Profiler: React.StatelessComponent<{}> = () => (
|
||||
<ContentBlock title="Prerequisites">
|
||||
<List>
|
||||
<ListItem>
|
||||
Use <a href="#">ganache-cli</a> as a backing node.
|
||||
Use{' '}
|
||||
<a href="https://github.com/ethereum/go-ethereum" target="_blank">
|
||||
Geth
|
||||
</a>{' '}
|
||||
as a backing node. We recommend using our{' '}
|
||||
<a href="https://hub.docker.com/r/0xorg/devnet" target="_blank">
|
||||
Devnet Docker container
|
||||
</a>{' '}
|
||||
which sets up a Geth node for testing purposes.{' '}
|
||||
<a href="https://github.com/0xProject/0x-monorepo/issues/1520" target="_blank">
|
||||
Ganache support is a work in progress.
|
||||
</a>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
Understand and use <a href="#">web3-provider-engine</a>.
|
||||
Understand and use{' '}
|
||||
<a href="https://github.com/MetaMask/provider-engine" target="_blank">
|
||||
web3-provider-engine
|
||||
</a>
|
||||
.
|
||||
</ListItem>
|
||||
</List>
|
||||
</ContentBlock>
|
||||
<ContentBlock title="Installation">
|
||||
<Breakout>
|
||||
<Code>npm install @0x/sol-trace --save</Code>
|
||||
<Code canCopy={true}>npm install @0x/sol-trace --save</Code>
|
||||
</Breakout>
|
||||
|
||||
<p>
|
||||
Sol-trace is a subprovider that needs to be prepended to your <a href="#">provider engine</a>.
|
||||
Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-trace ships
|
||||
Sol-trace is a subprovider that needs to be prepended to your{' '}
|
||||
<a href="https://github.com/MetaMask/provider-engine" target="_blank">
|
||||
provider engine
|
||||
</a>
|
||||
. Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-trace ships
|
||||
with the <InlineCode>SolCompilerArtifactAdapter</InlineCode> for use with{' '}
|
||||
<a href="#">Sol-compiler</a> and <InlineCode>TruffleArtifactAdapter</InlineCode> for use with the{' '}
|
||||
<a href="#">Truffle framework</a>. You can also write your own and support any artifact format.
|
||||
<a href="https://sol-compiler.com" target="_blank">
|
||||
Sol-compiler
|
||||
</a>{' '}
|
||||
and <InlineCode>TruffleArtifactAdapter</InlineCode> for use with the{' '}
|
||||
<a href="https://truffleframework.com/truffle" target="_blank">
|
||||
Truffle framework
|
||||
</a>{' '}
|
||||
(Also see our{' '}
|
||||
<a href="https://github.com/0xProject/dev-tools-truffle-example" target="_blank">
|
||||
Truffle example project
|
||||
</a>{' '}
|
||||
for a complete walk-through). You can also write your own and support any artifact format.
|
||||
</p>
|
||||
|
||||
<Tabs>
|
||||
<TabBlock title="Sol-compiler">
|
||||
<Code language="javascript">
|
||||
<Code language="javascript" canCopy={true}>
|
||||
{`import { SolCompilerArtifactAdapter } from '@0x/sol-trace';
|
||||
|
||||
// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
|
||||
@ -96,16 +125,16 @@ const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDi
|
||||
</Code>
|
||||
</TabBlock>
|
||||
<TabBlock title="Truffle">
|
||||
<Code language="javascript">
|
||||
<Code language="javascript" canCopy={true}>
|
||||
{`import { TruffleArtifactAdapter } from '@0x/sol-trace';
|
||||
|
||||
const projectRoot = '.';
|
||||
const solcVersion = '0.4.24';
|
||||
const solcVersion = '0.5.0';
|
||||
const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);`}
|
||||
</Code>
|
||||
</TabBlock>
|
||||
<TabBlock title="Custom">
|
||||
<Code language="javascript">
|
||||
<Code language="javascript" canCopy={true}>
|
||||
{`import { AbstractArtifactAdapter } from '@0x/sol-trace';
|
||||
|
||||
class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...};
|
||||
@ -115,25 +144,26 @@ const artifactAdapter = new YourCustomArtifactsAdapter(...);`}
|
||||
</Tabs>
|
||||
<p>
|
||||
Now that we have an <InlineCode>artifactAdapter</InlineCode>, we can create a{' '}
|
||||
<InlineCode>RevertTraceSubprovider</InlineCode> and append it to our provider engine.
|
||||
<InlineCode>ProfilerSubprovider</InlineCode> and append it to our provider engine.
|
||||
</p>
|
||||
|
||||
<Breakout>
|
||||
<Code language="javascript">
|
||||
<Code language="javascript" canCopy={true}>
|
||||
{`import { ProviderEngine, RpcSubprovider } from 'web3-provider-engine';
|
||||
import { RevertTraceSubprovider } from '@0x/sol-coverage';
|
||||
import { ProfilerSubprovider } from '@0x/sol-profiler';
|
||||
|
||||
const defaultFromAddress = "..."; // Some ethereum address with test funds
|
||||
const revertTraceSubprovider = new RevertTraceSubprovider(artifactAdapter, defaultFromAddress);
|
||||
const profilerSubprovider = new ProfilerSubprovider(artifactAdapter, defaultFromAddress);
|
||||
|
||||
const providerEngine = new ProviderEngine();
|
||||
providerEngine.addProvider(revertTraceSubprovider);
|
||||
providerEngine.addProvider(profilerSubprovider);
|
||||
providerEngine.addProvider(new RpcSubprovider({rpcUrl: 'http://localhost:8545'}));
|
||||
providerEngine.start();`}
|
||||
</Code>
|
||||
</Breakout>
|
||||
</ContentBlock>
|
||||
</Content>
|
||||
<CallToAction />
|
||||
</Base>
|
||||
);
|
||||
|
||||
|
@ -6,6 +6,7 @@ import { context } from 'ts/context/trace';
|
||||
|
||||
import { Base } from 'ts/components/base';
|
||||
import { Breakout } from 'ts/components/breakout';
|
||||
import { CallToAction } from 'ts/components/call_to_action';
|
||||
import { Code } from 'ts/components/code';
|
||||
import { Content } from 'ts/components/content';
|
||||
import { ContentBlock } from 'ts/components/content-block';
|
||||
@ -36,29 +37,57 @@ const Trace: React.StatelessComponent<{}> = () => (
|
||||
<ContentBlock title="Prerequisites">
|
||||
<List>
|
||||
<ListItem>
|
||||
Use <a href="#">ganache-cli</a> as a backing node.
|
||||
Use{' '}
|
||||
<a href="https://github.com/ethereum/go-ethereum" target="_blank">
|
||||
Geth
|
||||
</a>{' '}
|
||||
as a backing node. We recommend using our{' '}
|
||||
<a href="https://hub.docker.com/r/0xorg/devnet" target="_blank">
|
||||
Devnet Docker container
|
||||
</a>{' '}
|
||||
which sets up a Geth node for testing purposes.{' '}
|
||||
<a href="https://github.com/0xProject/0x-monorepo/issues/1520" target="_blank">
|
||||
Ganache support is a work in progress.
|
||||
</a>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
Understand and use <a href="#">web3-provider-engine</a>.
|
||||
Understand and use{' '}
|
||||
<a href="https://github.com/MetaMask/provider-engine" target="_blank">
|
||||
web3-provider-engine
|
||||
</a>
|
||||
.
|
||||
</ListItem>
|
||||
</List>
|
||||
</ContentBlock>
|
||||
<ContentBlock title="Installation">
|
||||
<Breakout>
|
||||
<Code>npm install @0x/sol-trace --save</Code>
|
||||
<Code canCopy={true}>npm install @0x/sol-trace --save</Code>
|
||||
</Breakout>
|
||||
|
||||
<p>
|
||||
Sol-trace is a subprovider that needs to be prepended to your <a href="#">provider engine</a>.
|
||||
Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-trace ships
|
||||
Sol-trace is a subprovider that needs to be prepended to your{' '}
|
||||
<a href="https://github.com/MetaMask/provider-engine" target="_blank">
|
||||
provider engine
|
||||
</a>
|
||||
. Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-trace ships
|
||||
with the <InlineCode>SolCompilerArtifactAdapter</InlineCode> for use with{' '}
|
||||
<a href="#">Sol-compiler</a> and <InlineCode>TruffleArtifactAdapter</InlineCode> for use with the{' '}
|
||||
<a href="#">Truffle framework</a>. You can also write your own and support any artifact format.
|
||||
<a href="https://sol-compiler.com" target="_blank">
|
||||
Sol-compiler
|
||||
</a>{' '}
|
||||
and <InlineCode>TruffleArtifactAdapter</InlineCode> for use with the{' '}
|
||||
<a href="https://truffleframework.com/truffle" target="_blank">
|
||||
Truffle framework
|
||||
</a>{' '}
|
||||
(Also see our{' '}
|
||||
<a href="https://github.com/0xProject/dev-tools-truffle-example" target="_blank">
|
||||
Truffle example project
|
||||
</a>{' '}
|
||||
for a complete walk-through). You can also write your own and support any artifact format.
|
||||
</p>
|
||||
|
||||
<Tabs>
|
||||
<TabBlock title="Sol-compiler">
|
||||
<Code language="javascript">
|
||||
<Code language="javascript" canCopy={true}>
|
||||
{`import { SolCompilerArtifactAdapter } from '@0x/sol-trace';
|
||||
|
||||
// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
|
||||
@ -66,16 +95,16 @@ const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDi
|
||||
</Code>
|
||||
</TabBlock>
|
||||
<TabBlock title="Truffle">
|
||||
<Code language="javascript">
|
||||
<Code language="javascript" canCopy={true}>
|
||||
{`import { TruffleArtifactAdapter } from '@0x/sol-trace';
|
||||
|
||||
const projectRoot = '.';
|
||||
const solcVersion = '0.4.24';
|
||||
const solcVersion = '0.5.0';
|
||||
const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);`}
|
||||
</Code>
|
||||
</TabBlock>
|
||||
<TabBlock title="Custom">
|
||||
<Code language="javascript">
|
||||
<Code language="javascript" canCopy={true}>
|
||||
{`import { AbstractArtifactAdapter } from '@0x/sol-trace';
|
||||
|
||||
class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...};
|
||||
@ -85,13 +114,13 @@ const artifactAdapter = new YourCustomArtifactsAdapter(...);`}
|
||||
</Tabs>
|
||||
<p>
|
||||
Now that we have an <InlineCode>artifactAdapter</InlineCode>, we can create a{' '}
|
||||
<InlineCode>RevertTraceSubprovider</InlineCode> and append it to our provider engine.
|
||||
<InlineCode>revertTraceSubprovider</InlineCode> and append it to our provider engine.
|
||||
</p>
|
||||
|
||||
<Breakout>
|
||||
<Code language="javascript">
|
||||
<Code language="javascript" canCopy={true}>
|
||||
{`import { ProviderEngine, RpcSubprovider } from 'web3-provider-engine';
|
||||
import { RevertTraceSubprovider } from '@0x/sol-coverage';
|
||||
import { RevertTraceSubprovider } from '@0x/sol-trace';
|
||||
|
||||
const defaultFromAddress = "..."; // Some ethereum address with test funds
|
||||
const revertTraceSubprovider = new RevertTraceSubprovider(artifactAdapter, defaultFromAddress);
|
||||
@ -102,8 +131,10 @@ providerEngine.addProvider(new RpcSubprovider({rpcUrl: 'http://localhost:8545'})
|
||||
providerEngine.start();`}
|
||||
</Code>
|
||||
</Breakout>
|
||||
<p>Stack traces will now be printed whenever your contracts revert!</p>
|
||||
</ContentBlock>
|
||||
</Content>
|
||||
<CallToAction />
|
||||
</Base>
|
||||
);
|
||||
|
||||
|
@ -3,7 +3,6 @@ const webpack = require('webpack');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const childProcess = require('child_process');
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const CleanWebpackPlugin = require('clean-webpack-plugin');
|
||||
|
||||
@ -12,7 +11,7 @@ const pages = require('./pages');
|
||||
const config = {
|
||||
entry: {
|
||||
compiler: './ts/pages/compiler.tsx',
|
||||
cov: './ts/pages/cov.tsx',
|
||||
coverage: './ts/pages/coverage.tsx',
|
||||
profiler: './ts/pages/profiler.tsx',
|
||||
trace: './ts/pages/trace.tsx',
|
||||
},
|
||||
|
@ -8,7 +8,7 @@
|
||||
"eip158Block": 3,
|
||||
"byzantiumBlock": 4,
|
||||
"clique": {
|
||||
"period": 1,
|
||||
"period": 0,
|
||||
"epoch": 30000
|
||||
}
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/instant",
|
||||
"version": "1.0.7",
|
||||
"version": "1.0.8",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@ -42,7 +42,7 @@
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/instant/README.md",
|
||||
"dependencies": {
|
||||
"@0x/assert": "^1.0.23",
|
||||
"@0x/asset-buyer": "^4.0.1",
|
||||
"@0x/asset-buyer": "^4.0.2",
|
||||
"@0x/json-schemas": "^2.1.7",
|
||||
"@0x/order-utils": "^3.1.2",
|
||||
"@0x/subproviders": "^2.1.11",
|
||||
|
@ -1,3 +1,6 @@
|
||||
import { AssetBuyer, BigNumber } from '@0x/asset-buyer';
|
||||
import { assetDataUtils } from '@0x/order-utils';
|
||||
import { Provider } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
@ -9,9 +12,12 @@ import {
|
||||
INJECTED_DIV_ID,
|
||||
NPM_PACKAGE_VERSION,
|
||||
} from './constants';
|
||||
import { assetMetaDataMap } from './data/asset_meta_data_map';
|
||||
import { ZeroExInstantOverlay, ZeroExInstantOverlayProps } from './index';
|
||||
import { Network, OrderSource } from './types';
|
||||
import { analytics } from './util/analytics';
|
||||
import { assert } from './util/assert';
|
||||
import { providerFactory } from './util/provider_factory';
|
||||
import { util } from './util/util';
|
||||
|
||||
const isInstantRendered = (): boolean => !!document.getElementById(INJECTED_DIV_ID);
|
||||
@ -122,6 +128,42 @@ export const render = (config: ZeroExInstantConfig, selector: string = DEFAULT_Z
|
||||
window.onpopstate = onPopStateHandler;
|
||||
};
|
||||
|
||||
export const assetDataForERC20TokenAddress = (tokenAddress: string): string => {
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
return assetDataUtils.encodeERC20AssetData(tokenAddress);
|
||||
};
|
||||
|
||||
export const hasMetaDataForAssetData = (assetData: string): boolean => {
|
||||
assert.isHexString('assetData', assetData);
|
||||
return assetMetaDataMap[assetData] !== undefined;
|
||||
};
|
||||
|
||||
export const hasLiquidityForAssetDataAsync = async (
|
||||
assetData: string,
|
||||
orderSource: OrderSource,
|
||||
networkId: Network = Network.Mainnet,
|
||||
provider?: Provider,
|
||||
): Promise<boolean> => {
|
||||
assert.isHexString('assetData', assetData);
|
||||
assert.isValidOrderSource('orderSource', orderSource);
|
||||
assert.isNumber('networkId', networkId);
|
||||
|
||||
if (provider !== undefined) {
|
||||
assert.isWeb3Provider('provider', provider);
|
||||
}
|
||||
|
||||
const bestProvider: Provider = provider || providerFactory.getFallbackNoSigningProvider(networkId);
|
||||
|
||||
const assetBuyerOptions = { networkId };
|
||||
|
||||
const assetBuyer = _.isString(orderSource)
|
||||
? AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl(bestProvider, orderSource, assetBuyerOptions)
|
||||
: AssetBuyer.getAssetBuyerForProvidedOrders(bestProvider, orderSource, assetBuyerOptions);
|
||||
|
||||
const liquidity = await assetBuyer.getLiquidityForAssetDataAsync(assetData);
|
||||
return liquidity.ethValueAvailableInWei.gt(new BigNumber(0));
|
||||
};
|
||||
|
||||
// Write version info to the exported object for debugging
|
||||
export const GIT_SHA = GIT_SHA_FROM_CONSTANT;
|
||||
export const NPM_VERSION = NPM_PACKAGE_VERSION;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/metacoin",
|
||||
"version": "0.0.35",
|
||||
"version": "0.0.36",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@ -32,9 +32,9 @@
|
||||
"@0x/abi-gen": "^1.0.22",
|
||||
"@0x/abi-gen-templates": "^1.0.2",
|
||||
"@0x/base-contract": "^3.0.13",
|
||||
"@0x/sol-coverage": "^1.0.2",
|
||||
"@0x/sol-profiler": "^1.0.2",
|
||||
"@0x/sol-trace": "^1.0.2",
|
||||
"@0x/sol-coverage": "^1.0.3",
|
||||
"@0x/sol-profiler": "^1.0.3",
|
||||
"@0x/sol-trace": "^1.0.3",
|
||||
"@0x/subproviders": "^2.1.11",
|
||||
"@0x/tslint-config": "^2.0.2",
|
||||
"@0x/types": "^1.5.2",
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@0x/monorepo-scripts",
|
||||
"version": "1.0.18",
|
||||
"version": "1.0.19",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
|
@ -6,6 +6,8 @@ import semverSort = require('semver-sort');
|
||||
import { constants } from './constants';
|
||||
import { Package } from './types';
|
||||
import { changelogUtils } from './utils/changelog_utils';
|
||||
import { configs } from './utils/configs';
|
||||
import { dockerHubUtils } from './utils/docker_hub_utils';
|
||||
import { npmUtils } from './utils/npm_utils';
|
||||
import { utils } from './utils/utils';
|
||||
|
||||
@ -17,6 +19,12 @@ async function prepublishChecksAsync(): Promise<void> {
|
||||
await checkChangelogFormatAsync(updatedPublicPackages);
|
||||
await checkGitTagsForNextVersionAndDeleteIfExistAsync(updatedPublicPackages);
|
||||
await checkPublishRequiredSetupAsync();
|
||||
await checkDockerHubSetupAsync();
|
||||
}
|
||||
|
||||
async function checkDockerHubSetupAsync(): Promise<void> {
|
||||
await dockerHubUtils.checkUserAddedToOrganizationOrThrowAsync(configs.DOCKER_HUB_ORG);
|
||||
await dockerHubUtils.loginUserToDockerCommandlineOrThrowAsync();
|
||||
}
|
||||
|
||||
async function checkGitTagsForNextVersionAndDeleteIfExistAsync(updatedPublicPackages: Package[]): Promise<void> {
|
||||
|
@ -1,11 +1,12 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { logUtils } from '@0x/utils';
|
||||
import * as promisify from 'es6-promisify';
|
||||
import * as fs from 'fs';
|
||||
import * as _ from 'lodash';
|
||||
import * as moment from 'moment';
|
||||
import opn = require('opn');
|
||||
import { exec as execAsync } from 'promisify-child-process';
|
||||
import { exec as execAsync, spawn as spawnAsync } from 'promisify-child-process';
|
||||
import * as prompt from 'prompt';
|
||||
import semver = require('semver');
|
||||
import semverSort = require('semver-sort');
|
||||
@ -79,12 +80,16 @@ async function confirmAsync(message: string): Promise<void> {
|
||||
});
|
||||
utils.log(`Calling 'lerna publish'...`);
|
||||
await lernaPublishAsync(packageToNextVersion);
|
||||
if (!configs.IS_LOCAL_PUBLISH) {
|
||||
|
||||
const isDryRun = configs.IS_LOCAL_PUBLISH;
|
||||
if (!isDryRun) {
|
||||
// Publish docker images to DockerHub
|
||||
await publishImagesToDockerHubAsync(allPackagesToPublish);
|
||||
|
||||
const isStaging = false;
|
||||
const shouldUploadDocs = true;
|
||||
await generateAndUploadDocJsonsAsync(packagesWithDocs, isStaging, shouldUploadDocs);
|
||||
}
|
||||
const isDryRun = configs.IS_LOCAL_PUBLISH;
|
||||
const releaseNotes = await publishReleaseNotesAsync(updatedPublicPackages, isDryRun);
|
||||
utils.log('Published release notes');
|
||||
|
||||
@ -95,11 +100,45 @@ async function confirmAsync(message: string): Promise<void> {
|
||||
utils.log("Publish successful, but couldn't auto-alert discord (", e.message, '), Please alert manually.');
|
||||
}
|
||||
}
|
||||
process.exit(0);
|
||||
})().catch(err => {
|
||||
utils.log(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
async function publishImagesToDockerHubAsync(allUpdatedPackages: Package[]): Promise<void> {
|
||||
for (const pkg of allUpdatedPackages) {
|
||||
const packageJSON = pkg.packageJson;
|
||||
const shouldPublishDockerImage =
|
||||
!_.isUndefined(packageJSON.config) &&
|
||||
!_.isUndefined(packageJSON.config.postpublish) &&
|
||||
!_.isUndefined(packageJSON.config.postpublish.dockerHubRepo);
|
||||
if (!shouldPublishDockerImage) {
|
||||
continue;
|
||||
}
|
||||
const dockerHubRepo = _.get(packageJSON, 'config.postpublish.dockerHubRepo');
|
||||
const pkgName = pkg.packageJson.name;
|
||||
const packageDirName = _.startsWith(pkgName, '@0x/') ? pkgName.split('/')[1] : pkgName;
|
||||
|
||||
// Build the Docker image
|
||||
logUtils.log(`Building '${dockerHubRepo}' docker image...`);
|
||||
await spawnAsync('docker', ['build', '-t', dockerHubRepo, '.'], {
|
||||
cwd: `${constants.monorepoRootPath}/packages/${packageDirName}`,
|
||||
});
|
||||
|
||||
// Tag the docker image with the latest version
|
||||
const version = pkg.packageJson.version;
|
||||
logUtils.log(`Tagging '${dockerHubRepo}' docker image with version ${version}...`);
|
||||
await execAsync(`docker tag ${dockerHubRepo} ${configs.DOCKER_HUB_ORG}/${dockerHubRepo}:${version}`);
|
||||
await execAsync(`docker tag ${dockerHubRepo} ${configs.DOCKER_HUB_ORG}/${dockerHubRepo}:latest`);
|
||||
|
||||
// Publish to DockerHub
|
||||
logUtils.log(`Pushing '${dockerHubRepo}' docker image to DockerHub...`);
|
||||
await execAsync(`docker push ${configs.DOCKER_HUB_ORG}/${dockerHubRepo}:${version}`);
|
||||
await execAsync(`docker push ${configs.DOCKER_HUB_ORG}/${dockerHubRepo}:latest`);
|
||||
}
|
||||
}
|
||||
|
||||
function getPackagesWithDocs(allUpdatedPackages: Package[]): Package[] {
|
||||
const rootPackageJsonPath = `${constants.monorepoRootPath}/package.json`;
|
||||
const rootPackageJson = JSON.parse(fs.readFileSync(rootPackageJsonPath).toString());
|
||||
|
@ -41,7 +41,11 @@ export interface PackageJSON {
|
||||
main?: string;
|
||||
scripts?: { [command: string]: string };
|
||||
config?: {
|
||||
additionalTsTypings?: string[];
|
||||
postpublish?: {
|
||||
assets?: string[];
|
||||
docOmitExports?: string[];
|
||||
dockerHubRepo?: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -5,4 +5,5 @@ const REMOTE_NPM_REGISTRY_URL = 'https://registry.npmjs.org';
|
||||
export const configs = {
|
||||
IS_LOCAL_PUBLISH,
|
||||
NPM_REGISTRY_URL: IS_LOCAL_PUBLISH ? LOCAL_NPM_REGISTRY_URL : REMOTE_NPM_REGISTRY_URL,
|
||||
DOCKER_HUB_ORG: '0xorg',
|
||||
};
|
||||
|
65
packages/monorepo-scripts/src/utils/docker_hub_utils.ts
Normal file
65
packages/monorepo-scripts/src/utils/docker_hub_utils.ts
Normal file
@ -0,0 +1,65 @@
|
||||
import { fetchAsync } from '@0x/utils';
|
||||
import { exec as execAsync } from 'promisify-child-process';
|
||||
|
||||
import { utils } from './utils';
|
||||
|
||||
const API_ENDPOINT = 'https://hub.docker.com/v2';
|
||||
const HTTP_OK_STATUS = 200;
|
||||
|
||||
export const dockerHubUtils = {
|
||||
async getTokenAsync(): Promise<string> {
|
||||
const payload = {
|
||||
username: process.env.DOCKER_USERNAME,
|
||||
password: process.env.DOCKER_PASS,
|
||||
};
|
||||
const response = await fetchAsync(`${API_ENDPOINT}/users/login`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
if (response.status !== HTTP_OK_STATUS) {
|
||||
throw new Error(
|
||||
`DockerHub user login failed (status code: ${
|
||||
response.status
|
||||
}). Make sure you have environment variables 'DOCKER_USERNAME; and 'DOCKER_PASS' set`,
|
||||
);
|
||||
}
|
||||
const respPayload = await response.json();
|
||||
const token = respPayload.token;
|
||||
return token;
|
||||
},
|
||||
async checkUserAddedToOrganizationOrThrowAsync(organization: string): Promise<void> {
|
||||
utils.log('Checking that the user was added to the 0xorg DockerHub organization...');
|
||||
const token = await dockerHubUtils.getTokenAsync();
|
||||
const response = await fetchAsync(`${API_ENDPOINT}/repositories/${organization}/?page_size=10`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
Authorization: `JWT ${token}`,
|
||||
},
|
||||
});
|
||||
const respPayload = await response.json();
|
||||
if (response.status !== HTTP_OK_STATUS || respPayload.count === 0) {
|
||||
throw new Error(
|
||||
`Failed to fetch org: ${organization}'s list of repos (status code: ${
|
||||
response.status
|
||||
}). Make sure your account has been added to the '${organization}' org on DockerHub`,
|
||||
);
|
||||
}
|
||||
},
|
||||
async loginUserToDockerCommandlineOrThrowAsync(): Promise<void> {
|
||||
try {
|
||||
utils.log('Checking that the user is logged in to docker command...');
|
||||
await execAsync(`echo "$DOCKER_PASS" | docker login -u $DOCKER_USERNAME --password-stdin`);
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`Failed to log you into the 'docker' commandline tool. Make sure you have the 'docker' commandline tool installed. Full error: ${
|
||||
err.message
|
||||
}`,
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
@ -106,8 +106,10 @@ export const utils = {
|
||||
return nextVersionIfValid;
|
||||
},
|
||||
async getRemoteGitTagsAsync(): Promise<string[]> {
|
||||
const TEN_MEGA_BYTES = 1024 * 1024 * 10; // tslint:disable-line custom-no-magic-numbers
|
||||
const result = await execAsync(`git ls-remote --tags`, {
|
||||
cwd: constants.monorepoRootPath,
|
||||
maxBuffer: TEN_MEGA_BYTES,
|
||||
});
|
||||
const tagsString = result.stdout;
|
||||
const tagOutputs: string[] = tagsString.split('\n');
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "2.4.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547561734,
|
||||
"version": "2.4.2",
|
||||
|
@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.4.3 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.4.2 - _January 15, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/order-watcher",
|
||||
"version": "2.4.2",
|
||||
"version": "2.4.3",
|
||||
"description": "An order watcher daemon that watches for order validity",
|
||||
"keywords": [
|
||||
"0x",
|
||||
@ -24,6 +24,11 @@
|
||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js lib/test/global_hooks.js --timeout 10000 --bail --exit",
|
||||
"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
|
||||
},
|
||||
"config": {
|
||||
"postpublish": {
|
||||
"dockerHubRepo": "order-watcher"
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/0xProject/0x-monorepo"
|
||||
@ -63,7 +68,7 @@
|
||||
"@0x/base-contract": "^3.0.13",
|
||||
"@0x/contract-addresses": "^2.2.0",
|
||||
"@0x/contract-artifacts": "^1.3.0",
|
||||
"@0x/contract-wrappers": "^5.0.0",
|
||||
"@0x/contract-wrappers": "^5.0.1",
|
||||
"@0x/fill-scenarios": "^1.1.2",
|
||||
"@0x/json-schemas": "^2.1.7",
|
||||
"@0x/order-utils": "^3.1.2",
|
||||
|
@ -52,7 +52,7 @@
|
||||
"material-ui": "^0.20.0",
|
||||
"react": "^16.5.2",
|
||||
"react-dom": "^16.5.2",
|
||||
"react-highlight": "0xproject/react-highlight#699ac4d9529e33520bff4b9bd9c624d21efbba75",
|
||||
"react-highlight": "0xproject/react-highlight#fix/react-version",
|
||||
"react-markdown": "^3.2.2",
|
||||
"react-router-dom": "^4.1.1",
|
||||
"react-scroll": "0xproject/react-scroll#pr-330-and-replace-state",
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "1.0.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547561734,
|
||||
"version": "1.0.2",
|
||||
|
@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.3 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.2 - _January 15, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/sol-coverage",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@ -29,7 +29,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/sol-coverage/README.md",
|
||||
"dependencies": {
|
||||
"@0x/sol-tracing-utils": "^4.0.0",
|
||||
"@0x/sol-tracing-utils": "^4.0.1",
|
||||
"@0x/subproviders": "^2.1.11",
|
||||
"@0x/typescript-typings": "^3.0.8",
|
||||
"ethereum-types": "^1.1.6",
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "1.0.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547561734,
|
||||
"version": "1.0.2",
|
||||
|
@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.3 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.2 - _January 15, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/sol-profiler",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@ -29,7 +29,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/sol-profiler/README.md",
|
||||
"dependencies": {
|
||||
"@0x/sol-tracing-utils": "^4.0.0",
|
||||
"@0x/sol-tracing-utils": "^4.0.1",
|
||||
"@0x/subproviders": "^2.1.11",
|
||||
"@0x/typescript-typings": "^3.0.8",
|
||||
"ethereum-types": "^1.1.6",
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "1.0.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547561734,
|
||||
"version": "1.0.2",
|
||||
|
@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.3 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.2 - _January 15, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/sol-trace",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@ -29,7 +29,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/sol-trace/README.md",
|
||||
"dependencies": {
|
||||
"@0x/sol-tracing-utils": "^4.0.0",
|
||||
"@0x/sol-tracing-utils": "^4.0.1",
|
||||
"@0x/subproviders": "^2.1.11",
|
||||
"@0x/typescript-typings": "^3.0.8",
|
||||
"ethereum-types": "^1.1.6",
|
||||
|
@ -109,10 +109,8 @@ export class RevertTraceSubprovider extends TraceCollectionSubprovider {
|
||||
const fileNameToFileIndex = _.invert(contractData.sources);
|
||||
const fileIndex = _.parseInt(fileNameToFileIndex[sourceRange.fileName]);
|
||||
const sourceSnippet = getSourceRangeSnippet(sourceRange, contractData.sourceCodes[fileIndex]);
|
||||
if (sourceSnippet !== null) {
|
||||
sourceSnippets.push(sourceSnippet);
|
||||
}
|
||||
}
|
||||
const filteredSnippets = filterSnippets(sourceSnippets);
|
||||
if (filteredSnippets.length > 0) {
|
||||
this._logger.error('\n\nStack trace for REVERT:\n');
|
||||
@ -135,9 +133,7 @@ function filterSnippets(sourceSnippets: SourceSnippet[]): SourceSnippet[] {
|
||||
const results: SourceSnippet[] = [sourceSnippets[0]];
|
||||
let prev = sourceSnippets[0];
|
||||
for (const sourceSnippet of sourceSnippets) {
|
||||
if (sourceSnippet.type === 'IfStatement') {
|
||||
continue;
|
||||
} else if (sourceSnippet.source === prev.source) {
|
||||
if (sourceSnippet.source === prev.source) {
|
||||
prev = sourceSnippet;
|
||||
continue;
|
||||
}
|
||||
@ -157,12 +153,5 @@ function getStackTraceString(sourceSnippet: SourceSnippet): string {
|
||||
}
|
||||
|
||||
function getSourceSnippetString(sourceSnippet: SourceSnippet): string {
|
||||
switch (sourceSnippet.type) {
|
||||
case 'ContractDefinition':
|
||||
return `contract ${sourceSnippet.name}`;
|
||||
case 'FunctionDefinition':
|
||||
return `function ${sourceSnippet.name}`;
|
||||
default:
|
||||
return `${sourceSnippet.source}`;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"version": "4.0.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Fix a bug where a custom `Geth` tracer didn't return stack entries for `DELEGATECALL`",
|
||||
"pr": 1521
|
||||
},
|
||||
{
|
||||
"note": "Fix a bug where `TraceCollectionSubprovider` was hanging on the fake `Geth` snapshot transaction",
|
||||
"pr": 1521
|
||||
},
|
||||
{
|
||||
"note": "Fix/simplify handling of revert trace snippets",
|
||||
"pr": 1521
|
||||
}
|
||||
],
|
||||
"timestamp": 1547747677
|
||||
},
|
||||
{
|
||||
"version": "4.0.0",
|
||||
"changes": [
|
||||
|
@ -5,6 +5,12 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.0.1 - _January 17, 2019_
|
||||
|
||||
* Fix a bug where a custom `Geth` tracer didn't return stack entries for `DELEGATECALL` (#1521)
|
||||
* Fix a bug where `TraceCollectionSubprovider` was hanging on the fake `Geth` snapshot transaction (#1521)
|
||||
* Fix/simplify handling of revert trace snippets (#1521)
|
||||
|
||||
## v4.0.0 - _January 15, 2019_
|
||||
|
||||
* Fix a bug with incorrect parsing of `sourceMaps` due to sources being in an array instead of a map (#1498)
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/sol-tracing-utils",
|
||||
"version": "4.0.0",
|
||||
"version": "4.0.1",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
|
@ -1,185 +1,16 @@
|
||||
import * as ethUtil from 'ethereumjs-util';
|
||||
import * as _ from 'lodash';
|
||||
import * as Parser from 'solidity-parser-antlr';
|
||||
|
||||
import { SingleFileSourceRange, SourceRange, SourceSnippet } from './types';
|
||||
import { SourceRange, SourceSnippet } from './types';
|
||||
import { utils } from './utils';
|
||||
|
||||
interface ASTInfo {
|
||||
type: string;
|
||||
node: Parser.ASTNode;
|
||||
name: string | null;
|
||||
range?: SingleFileSourceRange;
|
||||
}
|
||||
|
||||
// Parsing source code for each transaction/code is slow and therefore we cache it
|
||||
const hashToParsedSource: { [sourceHash: string]: Parser.ASTNode } = {};
|
||||
|
||||
/**
|
||||
* Gets the source range snippet by source range to be used by revert trace.
|
||||
* @param sourceRange source range
|
||||
* @param sourceCode source code
|
||||
*/
|
||||
export function getSourceRangeSnippet(sourceRange: SourceRange, sourceCode: string): SourceSnippet | null {
|
||||
const sourceHash = ethUtil.sha3(sourceCode).toString('hex');
|
||||
if (_.isUndefined(hashToParsedSource[sourceHash])) {
|
||||
hashToParsedSource[sourceHash] = Parser.parse(sourceCode, { loc: true });
|
||||
}
|
||||
const astNode = hashToParsedSource[sourceHash];
|
||||
const visitor = new ASTInfoVisitor();
|
||||
Parser.visit(astNode, visitor);
|
||||
const astInfo = visitor.getASTInfoForRange(sourceRange);
|
||||
if (astInfo === null) {
|
||||
return null;
|
||||
}
|
||||
export function getSourceRangeSnippet(sourceRange: SourceRange, sourceCode: string): SourceSnippet {
|
||||
const sourceCodeInRange = utils.getRange(sourceCode, sourceRange.location);
|
||||
return {
|
||||
...astInfo,
|
||||
range: astInfo.range as SingleFileSourceRange,
|
||||
range: sourceRange.location,
|
||||
source: sourceCodeInRange,
|
||||
fileName: sourceRange.fileName,
|
||||
};
|
||||
}
|
||||
|
||||
// A visitor which collects ASTInfo for most nodes in the AST.
|
||||
class ASTInfoVisitor {
|
||||
private readonly _astInfos: ASTInfo[] = [];
|
||||
public getASTInfoForRange(sourceRange: SourceRange): ASTInfo | null {
|
||||
// HACK(albrow): Sometimes the source range doesn't exactly match that
|
||||
// of astInfo. To work around that we try with a +/-1 offset on
|
||||
// end.column. If nothing matches even with the offset, we return null.
|
||||
const offset = {
|
||||
start: {
|
||||
line: 0,
|
||||
column: 0,
|
||||
},
|
||||
end: {
|
||||
line: 0,
|
||||
column: 0,
|
||||
},
|
||||
};
|
||||
let astInfo = this._getASTInfoForRange(sourceRange, offset);
|
||||
if (astInfo !== null) {
|
||||
return astInfo;
|
||||
}
|
||||
offset.end.column += 1;
|
||||
astInfo = this._getASTInfoForRange(sourceRange, offset);
|
||||
if (astInfo !== null) {
|
||||
return astInfo;
|
||||
}
|
||||
offset.end.column -= 2;
|
||||
astInfo = this._getASTInfoForRange(sourceRange, offset);
|
||||
if (astInfo !== null) {
|
||||
return astInfo;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public ContractDefinition(ast: Parser.ContractDefinition): void {
|
||||
this._visitContractDefinition(ast);
|
||||
}
|
||||
public IfStatement(ast: Parser.IfStatement): void {
|
||||
this._visitStatement(ast);
|
||||
}
|
||||
public FunctionDefinition(ast: Parser.FunctionDefinition): void {
|
||||
this._visitFunctionLikeDefinition(ast);
|
||||
}
|
||||
public ModifierDefinition(ast: Parser.ModifierDefinition): void {
|
||||
this._visitFunctionLikeDefinition(ast);
|
||||
}
|
||||
public ForStatement(ast: Parser.ForStatement): void {
|
||||
this._visitStatement(ast);
|
||||
}
|
||||
public ReturnStatement(ast: Parser.ReturnStatement): void {
|
||||
this._visitStatement(ast);
|
||||
}
|
||||
public BreakStatement(ast: Parser.BreakStatement): void {
|
||||
this._visitStatement(ast);
|
||||
}
|
||||
public ContinueStatement(ast: Parser.ContinueStatement): void {
|
||||
this._visitStatement(ast);
|
||||
}
|
||||
public EmitStatement(ast: any /* TODO: Parser.EmitStatement */): void {
|
||||
this._visitStatement(ast);
|
||||
}
|
||||
public VariableDeclarationStatement(ast: Parser.VariableDeclarationStatement): void {
|
||||
this._visitStatement(ast);
|
||||
}
|
||||
public Statement(ast: Parser.Statement): void {
|
||||
this._visitStatement(ast);
|
||||
}
|
||||
public WhileStatement(ast: Parser.WhileStatement): void {
|
||||
this._visitStatement(ast);
|
||||
}
|
||||
public SimpleStatement(ast: Parser.SimpleStatement): void {
|
||||
this._visitStatement(ast);
|
||||
}
|
||||
public ThrowStatement(ast: Parser.ThrowStatement): void {
|
||||
this._visitStatement(ast);
|
||||
}
|
||||
public DoWhileStatement(ast: Parser.DoWhileStatement): void {
|
||||
this._visitStatement(ast);
|
||||
}
|
||||
public ExpressionStatement(ast: Parser.ExpressionStatement): void {
|
||||
this._visitStatement(ast.expression);
|
||||
}
|
||||
public InlineAssemblyStatement(ast: Parser.InlineAssemblyStatement): void {
|
||||
this._visitStatement(ast);
|
||||
}
|
||||
public ModifierInvocation(ast: Parser.ModifierInvocation): void {
|
||||
const BUILTIN_MODIFIERS = ['public', 'view', 'payable', 'external', 'internal', 'pure', 'constant'];
|
||||
if (!_.includes(BUILTIN_MODIFIERS, ast.name)) {
|
||||
this._visitStatement(ast);
|
||||
}
|
||||
}
|
||||
private _visitStatement(ast: Parser.ASTNode): void {
|
||||
this._astInfos.push({
|
||||
type: ast.type,
|
||||
node: ast,
|
||||
name: null,
|
||||
range: ast.loc,
|
||||
});
|
||||
}
|
||||
private _visitFunctionLikeDefinition(ast: Parser.ModifierDefinition | Parser.FunctionDefinition): void {
|
||||
this._astInfos.push({
|
||||
type: ast.type,
|
||||
node: ast,
|
||||
name: ast.name,
|
||||
range: ast.loc,
|
||||
});
|
||||
}
|
||||
private _visitContractDefinition(ast: Parser.ContractDefinition): void {
|
||||
this._astInfos.push({
|
||||
type: ast.type,
|
||||
node: ast,
|
||||
name: ast.name,
|
||||
range: ast.loc,
|
||||
});
|
||||
}
|
||||
private _getASTInfoForRange(sourceRange: SourceRange, offset: SingleFileSourceRange): ASTInfo | null {
|
||||
const offsetSourceRange = {
|
||||
...sourceRange,
|
||||
location: {
|
||||
start: {
|
||||
line: sourceRange.location.start.line + offset.start.line,
|
||||
column: sourceRange.location.start.column + offset.start.column,
|
||||
},
|
||||
end: {
|
||||
line: sourceRange.location.end.line + offset.end.line,
|
||||
column: sourceRange.location.end.column + offset.end.column,
|
||||
},
|
||||
},
|
||||
};
|
||||
for (const astInfo of this._astInfos) {
|
||||
const astInfoRange = astInfo.range as SingleFileSourceRange;
|
||||
if (
|
||||
astInfoRange.start.column === offsetSourceRange.location.start.column &&
|
||||
astInfoRange.start.line === offsetSourceRange.location.start.line &&
|
||||
astInfoRange.end.column === offsetSourceRange.location.end.column &&
|
||||
astInfoRange.end.line === offsetSourceRange.location.end.line
|
||||
) {
|
||||
return astInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ export abstract class TraceCollectionSubprovider extends Subprovider {
|
||||
txHash: string | undefined,
|
||||
cb: Callback,
|
||||
): Promise<void> {
|
||||
if (!txData.isFakeTransaction) {
|
||||
if (!(txData.isFakeTransaction || txData.from === txData.to)) {
|
||||
// This transaction is a usual transaction. Not a call executed as one.
|
||||
// And we don't want it to be executed within a snapshotting period
|
||||
await this._lock.acquire();
|
||||
|
@ -31,7 +31,7 @@ export abstract class TraceInfoSubprovider extends TraceCollectionSubprovider {
|
||||
const depth = 0 | log.getDepth();
|
||||
const gasCost = 0 | log.getCost();
|
||||
const gas = 0 | log.getGas();
|
||||
const isCall = opn == 0xf1 || opn == 0xf2 || opn == 0xf4 || opn == 0xf5;
|
||||
const isCall = opn == 0xf1 || opn == 0xf2 || opn == 0xf4 || opn == 0xf5 || opn == 0xfa;
|
||||
const stack = isCall ? ['0x'+log.stack.peek(1).toString(16), null] : null;
|
||||
this.data.push({ pc, gasCost, depth, op, stack, gas });
|
||||
},
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { StructLog } from 'ethereum-types';
|
||||
import * as Parser from 'solidity-parser-antlr';
|
||||
|
||||
export interface LineColumn {
|
||||
line: number;
|
||||
@ -126,8 +125,5 @@ export type EvmCallStack = EvmCallStackEntry[];
|
||||
export interface SourceSnippet {
|
||||
source: string;
|
||||
fileName: string;
|
||||
type: string;
|
||||
node: Parser.ASTNode;
|
||||
name: string | null;
|
||||
range: SingleFileSourceRange;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user