Merge branch 'development' into feature/instant/stable-css-classes
This commit is contained in:
19
.github/stale.yml
vendored
Normal file
19
.github/stale.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 30
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- pinned
|
||||
- security
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
This issue has been automatically closed because no activity occured in 7 days after being marked as stale. If it's still relevant - feel free to reopen. Thank you
|
||||
for your contributions.
|
||||
@@ -1,4 +1,14 @@
|
||||
[
|
||||
{
|
||||
"name": "OrderValidator",
|
||||
"version": "1.0.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "remove `getApproved` check from ERC721 approval query",
|
||||
"pr": 1149
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Forwarder",
|
||||
"version": "1.1.0",
|
||||
|
||||
@@ -148,7 +148,7 @@ contract OrderValidator {
|
||||
balance = target == owner ? 1 : 0;
|
||||
|
||||
// Check if ERC721Proxy is approved to spend tokenId
|
||||
bool isApproved = IERC721Token(token).isApprovedForAll(target, assetProxy) || IERC721Token(token).getApproved(tokenId) == assetProxy;
|
||||
bool isApproved = IERC721Token(token).isApprovedForAll(target, assetProxy);
|
||||
|
||||
// Set alowance to 1 if ERC721Proxy is approved to spend tokenId
|
||||
allowance = isApproved ? 1 : 0;
|
||||
|
||||
@@ -198,7 +198,7 @@ describe('OrderValidator', () => {
|
||||
);
|
||||
expect(newAllowance).to.be.bignumber.equal(ERC721_ALLOWANCE);
|
||||
});
|
||||
it('should return an allowance of 1 when ERC721Proxy is approved for specific tokenId', async () => {
|
||||
it('should return an allowance of 0 when ERC721Proxy is approved for specific tokenId', async () => {
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc721Token.mint.sendTransactionAsync(makerAddress, tokenId),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
@@ -213,7 +213,7 @@ describe('OrderValidator', () => {
|
||||
makerAddress,
|
||||
erc721AssetData,
|
||||
);
|
||||
expect(newAllowance).to.be.bignumber.equal(ERC721_ALLOWANCE);
|
||||
expect(newAllowance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -248,8 +248,9 @@ describe('OrderValidator', () => {
|
||||
await erc721Token.mint.sendTransactionAsync(makerAddress, tokenId),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const isApproved = true;
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc721Token.approve.sendTransactionAsync(erc721Proxy.address, tokenId, {
|
||||
await erc721Token.setApprovalForAll.sendTransactionAsync(erc721Proxy.address, isApproved, {
|
||||
from: makerAddress,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
@@ -311,8 +312,9 @@ describe('OrderValidator', () => {
|
||||
await erc721Token.mint.sendTransactionAsync(takerAddress, tokenId),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const isApproved = true;
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc721Token.approve.sendTransactionAsync(erc721Proxy.address, tokenId, {
|
||||
await erc721Token.setApprovalForAll.sendTransactionAsync(erc721Proxy.address, isApproved, {
|
||||
from: takerAddress,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
@@ -465,8 +467,9 @@ describe('OrderValidator', () => {
|
||||
await erc721Token.mint.sendTransactionAsync(takerAddress, tokenId),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
const isApproved = true;
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await erc721Token.approve.sendTransactionAsync(erc721Proxy.address, tokenId, {
|
||||
await erc721Token.setApprovalForAll.sendTransactionAsync(erc721Proxy.address, isApproved, {
|
||||
from: takerAddress,
|
||||
}),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
"private": true,
|
||||
"description": "0x Instant React Component",
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
|
||||
@@ -3,6 +3,7 @@ import * as React from 'react';
|
||||
|
||||
import { ColorOption } from '../style/theme';
|
||||
import { ERC20Asset } from '../types';
|
||||
import { analytics } from '../util/analytics';
|
||||
import { assetUtils } from '../util/asset';
|
||||
|
||||
import { SearchInput } from './search_input';
|
||||
@@ -57,6 +58,7 @@ export class ERC20TokenSelector extends React.Component<ERC20TokenSelectorProps>
|
||||
this.setState({
|
||||
searchQuery,
|
||||
});
|
||||
analytics.trackTokenSelectorSearched(searchQuery);
|
||||
};
|
||||
private readonly _isTokenQueryMatch = (token: ERC20Asset): boolean => {
|
||||
const { searchQuery } = this.state;
|
||||
|
||||
@@ -11,21 +11,20 @@ import { SelectedAssetBuyOrderStateButtons } from '../containers/selected_asset_
|
||||
import { SelectedAssetInstantHeading } from '../containers/selected_asset_instant_heading';
|
||||
import { ColorOption } from '../style/theme';
|
||||
import { zIndex } from '../style/z_index';
|
||||
import { OrderProcessState, SlideAnimationState } from '../types';
|
||||
import { SlideAnimationState } from '../types';
|
||||
import { analytics, TokenSelectorClosedVia } from '../util/analytics';
|
||||
|
||||
import { CSSReset } from './css_reset';
|
||||
import { SlidingPanel } from './sliding_panel';
|
||||
import { Container } from './ui/container';
|
||||
import { Flex } from './ui/flex';
|
||||
|
||||
export interface ZeroExInstantContainerProps {
|
||||
orderProcessState: OrderProcessState;
|
||||
}
|
||||
export interface ZeroExInstantContainerProps {}
|
||||
export interface ZeroExInstantContainerState {
|
||||
tokenSelectionPanelAnimationState: SlideAnimationState;
|
||||
}
|
||||
|
||||
export class ZeroExInstantContainer extends React.Component<{}, ZeroExInstantContainerState> {
|
||||
export class ZeroExInstantContainer extends React.Component<ZeroExInstantContainerProps, ZeroExInstantContainerState> {
|
||||
public state = {
|
||||
tokenSelectionPanelAnimationState: 'none' as SlideAnimationState,
|
||||
};
|
||||
@@ -60,9 +59,9 @@ export class ZeroExInstantContainer extends React.Component<{}, ZeroExInstantCon
|
||||
</Flex>
|
||||
<SlidingPanel
|
||||
animationState={this.state.tokenSelectionPanelAnimationState}
|
||||
onClose={this._handlePanelClose}
|
||||
onClose={this._handlePanelCloseClickedX}
|
||||
>
|
||||
<AvailableERC20TokenSelector onTokenSelect={this._handlePanelClose} />
|
||||
<AvailableERC20TokenSelector onTokenSelect={this._handlePanelCloseAfterChose} />
|
||||
</SlidingPanel>
|
||||
<CurrentStandardSlidingPanel />
|
||||
</Container>
|
||||
@@ -82,11 +81,19 @@ export class ZeroExInstantContainer extends React.Component<{}, ZeroExInstantCon
|
||||
);
|
||||
}
|
||||
private readonly _handleSymbolClick = (): void => {
|
||||
analytics.trackTokenSelectorOpened();
|
||||
this.setState({
|
||||
tokenSelectionPanelAnimationState: 'slidIn',
|
||||
});
|
||||
};
|
||||
private readonly _handlePanelClose = (): void => {
|
||||
private readonly _handlePanelCloseClickedX = (): void => {
|
||||
this._handlePanelClose(TokenSelectorClosedVia.ClickedX);
|
||||
};
|
||||
private readonly _handlePanelCloseAfterChose = (): void => {
|
||||
this._handlePanelClose(TokenSelectorClosedVia.TokenChose);
|
||||
};
|
||||
private readonly _handlePanelClose = (closedVia: TokenSelectorClosedVia): void => {
|
||||
analytics.trackTokenSelectorClosed(closedVia);
|
||||
this.setState({
|
||||
tokenSelectionPanelAnimationState: 'slidOut',
|
||||
});
|
||||
|
||||
@@ -131,6 +131,7 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider
|
||||
this.props.orderSource,
|
||||
state.providerState,
|
||||
window,
|
||||
state.selectedAsset,
|
||||
this.props.affiliateInfo,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -53,6 +53,30 @@ export const analyticsMiddleware: Middleware = store => next => middlewareAction
|
||||
).toString();
|
||||
analytics.addUserProperties({ ethBalanceInUnitAmount });
|
||||
}
|
||||
break;
|
||||
case ActionTypes.UPDATE_SELECTED_ASSET:
|
||||
const selectedAsset = curState.selectedAsset;
|
||||
if (selectedAsset) {
|
||||
const assetName = selectedAsset.metaData.name;
|
||||
const assetData = selectedAsset.assetData;
|
||||
analytics.trackTokenSelectorChose({
|
||||
assetName,
|
||||
assetData,
|
||||
});
|
||||
analytics.addEventProperties({
|
||||
selectedAssetName: assetName,
|
||||
selectedAssetData: assetData,
|
||||
});
|
||||
}
|
||||
break;
|
||||
case ActionTypes.SET_AVAILABLE_ASSETS:
|
||||
const availableAssets = curState.availableAssets;
|
||||
if (availableAssets) {
|
||||
analytics.addEventProperties({
|
||||
numberAvailableAssets: availableAssets.length,
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return nextAction;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AffiliateInfo, Network, OrderSource, ProviderState } from '../types';
|
||||
import { AffiliateInfo, Asset, Network, OrderSource, ProviderState } from '../types';
|
||||
|
||||
import { EventProperties, heapUtil } from './heap';
|
||||
|
||||
@@ -20,7 +20,12 @@ enum EventNames {
|
||||
ACCOUNT_UNLOCK_REQUESTED = 'Account - Unlock Requested',
|
||||
ACCOUNT_UNLOCK_DENIED = 'Account - Unlock Denied',
|
||||
ACCOUNT_ADDRESS_CHANGED = 'Account - Address Changed',
|
||||
TOKEN_SELECTOR_OPENED = 'Token Selector - Opened',
|
||||
TOKEN_SELECTOR_CLOSED = 'Token Selector - Closed',
|
||||
TOKEN_SELECTOR_CHOSE = 'Token Selector - Chose',
|
||||
TOKEN_SELECTOR_SEARCHED = 'Token Selector - Searched',
|
||||
}
|
||||
|
||||
const track = (eventName: EventNames, eventProperties: EventProperties = {}): void => {
|
||||
evaluateIfEnabled(() => {
|
||||
heapUtil.evaluateHeapCall(heap => heap.track(eventName, eventProperties));
|
||||
@@ -52,8 +57,14 @@ export interface AnalyticsEventOptions {
|
||||
orderSource?: string;
|
||||
affiliateAddress?: string;
|
||||
affiliateFeePercent?: number;
|
||||
numberAvailableAssets?: number;
|
||||
selectedAssetName?: string;
|
||||
selectedAssetData?: string;
|
||||
}
|
||||
export enum TokenSelectorClosedVia {
|
||||
ClickedX = 'Clicked X',
|
||||
TokenChose = 'Token Chose',
|
||||
}
|
||||
|
||||
export const analytics = {
|
||||
addUserProperties: (properties: AnalyticsUserOptions): void => {
|
||||
evaluateIfEnabled(() => {
|
||||
@@ -70,12 +81,13 @@ export const analytics = {
|
||||
orderSource: OrderSource,
|
||||
providerState: ProviderState,
|
||||
window: Window,
|
||||
selectedAsset?: Asset,
|
||||
affiliateInfo?: AffiliateInfo,
|
||||
): AnalyticsEventOptions => {
|
||||
const affiliateAddress = affiliateInfo ? affiliateInfo.feeRecipient : 'none';
|
||||
const affiliateFeePercent = affiliateInfo ? parseFloat(affiliateInfo.feePercentage.toFixed(4)) : 0;
|
||||
const orderSourceName = typeof orderSource === 'string' ? orderSource : 'provided';
|
||||
return {
|
||||
const eventOptions: AnalyticsEventOptions = {
|
||||
embeddedHost: window.location.host,
|
||||
embeddedUrl: window.location.href,
|
||||
networkId: network,
|
||||
@@ -85,7 +97,10 @@ export const analytics = {
|
||||
orderSource: orderSourceName,
|
||||
affiliateAddress,
|
||||
affiliateFeePercent,
|
||||
selectedAssetName: selectedAsset ? selectedAsset.metaData.name : 'none',
|
||||
selectedAssetData: selectedAsset ? selectedAsset.assetData : 'none',
|
||||
};
|
||||
return eventOptions;
|
||||
},
|
||||
trackInstantOpened: trackingEventFnWithoutPayload(EventNames.INSTANT_OPENED),
|
||||
trackAccountLocked: trackingEventFnWithoutPayload(EventNames.ACCOUNT_LOCKED),
|
||||
@@ -94,4 +109,11 @@ export const analytics = {
|
||||
trackAccountUnlockDenied: trackingEventFnWithoutPayload(EventNames.ACCOUNT_UNLOCK_DENIED),
|
||||
trackAccountAddressChanged: (address: string) =>
|
||||
trackingEventFnWithPayload(EventNames.ACCOUNT_ADDRESS_CHANGED)({ address }),
|
||||
trackTokenSelectorOpened: trackingEventFnWithoutPayload(EventNames.TOKEN_SELECTOR_OPENED),
|
||||
trackTokenSelectorClosed: (closedVia: TokenSelectorClosedVia) =>
|
||||
trackingEventFnWithPayload(EventNames.TOKEN_SELECTOR_CLOSED)({ closedVia }),
|
||||
trackTokenSelectorChose: (payload: { assetName: string; assetData: string }) =>
|
||||
trackingEventFnWithPayload(EventNames.TOKEN_SELECTOR_CHOSE)(payload),
|
||||
trackTokenSelectorSearched: (searchText: string) =>
|
||||
trackingEventFnWithPayload(EventNames.TOKEN_SELECTOR_SEARCHED)({ searchText }),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user