Skip to content

Commit

Permalink
Update analytics for Send and Swap form txs (#377)
Browse files Browse the repository at this point in the history
* Update analytics for Send and Swap form txs
  • Loading branch information
everdimension authored Dec 7, 2023
1 parent 160227c commit 14342ed
Show file tree
Hide file tree
Showing 14 changed files with 310 additions and 11 deletions.
28 changes: 26 additions & 2 deletions src/background/Wallet/Wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { UnsignedTransaction } from 'ethers';
import { ethers } from 'ethers';
import type { Emitter } from 'nanoevents';
import { createNanoEvents } from 'nanoevents';
import type { AddressAction } from 'defi-sdk';
import { Store } from 'store-unit';
import { isTruthy } from 'is-truthy-ts';
import { encrypt, decrypt } from 'src/modules/crypto';
Expand Down Expand Up @@ -61,6 +62,7 @@ import {
isMnemonicContainer,
} from 'src/shared/types/validators';
import { ERC20_ALLOWANCE_ABI } from 'src/modules/ethereum/abi/allowance-abi';
import type { Quote } from 'src/shared/types/Quote';
import type { DaylightEventParams, ScreenViewParams } from '../events';
import { emitter } from '../events';
import type { Credentials, SessionCredentials } from '../account/Credentials';
Expand Down Expand Up @@ -881,10 +883,14 @@ export class Wallet {
context,
initiator,
feeValueCommon,
addressAction,
quote,
}: {
context: Partial<ChannelContext> | undefined;
initiator: string;
feeValueCommon: string | null;
addressAction: AddressAction | null;
quote?: Quote;
}
): Promise<ethers.providers.TransactionResponse> {
this.verifyInternalOrigin(context);
Expand Down Expand Up @@ -937,6 +943,8 @@ export class Wallet {
transaction: safeTx,
initiator,
feeValueCommon,
addressAction,
quote,
});
return safeTx;
} catch (error) {
Expand All @@ -953,19 +961,24 @@ export class Wallet {
{
initiator: string;
feeValueCommon: string | null;
addressAction: AddressAction | null;
quote?: Quote;
}
]
>) {
this.verifyInternalOrigin(context);
this.ensureStringOrigin(context);
const [transaction, { initiator, feeValueCommon }] = params;
const [transaction, { initiator, feeValueCommon, addressAction, quote }] =
params;
if (!transaction) {
throw new InvalidParams();
}
return this.sendTransaction(transaction, {
context,
initiator,
feeValueCommon,
addressAction,
quote,
});
}

Expand All @@ -977,10 +990,19 @@ export class Wallet {
chain: string;
initiator: string;
feeValueCommon: string | null;
addressAction: AddressAction | null;
quote?: Quote;
}>): Promise<ethers.providers.TransactionResponse> {
this.verifyInternalOrigin(context);
this.ensureStringOrigin(context);
const { chain, serialized, initiator, feeValueCommon } = params;
const {
chain,
serialized,
initiator,
feeValueCommon,
addressAction,
quote,
} = params;
const networks = await networksStore.load();
const chainId = networks.getChainId(createChain(chain));
const provider = await this.getProvider(chainId);
Expand All @@ -991,6 +1013,8 @@ export class Wallet {
transaction: safeTx,
initiator,
feeValueCommon,
addressAction,
quote,
});
return safeTx;
} catch (error) {
Expand Down
4 changes: 4 additions & 0 deletions src/background/events.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import type { ethers } from 'ethers';
import type { AddressAction } from 'defi-sdk';
import { createNanoEvents } from 'nanoevents';
import type { TypedData } from 'src/modules/ethereum/message-signing/TypedData';
import type { NetworkConfig } from 'src/modules/networks/NetworkConfig';
import type { Quote } from 'src/shared/types/Quote';
import type { State as GlobalPreferencesState } from './Wallet/GlobalPreferences';
import type { WalletOrigin } from './Wallet/model/WalletOrigin';
import type { WalletContainer } from './Wallet/model/types';
Expand All @@ -28,6 +30,8 @@ export const emitter = createNanoEvents<{
transaction: TransactionResponse;
initiator: string;
feeValueCommon: string | null;
addressAction: AddressAction | null;
quote?: Quote;
}) => void;
typedDataSigned: (data: {
typedData: TypedData;
Expand Down
1 change: 1 addition & 0 deletions src/background/transactions/TransactionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ function testAddTransaction() {
transaction: createMockTxResponse(),
initiator: 'https://app.zerion.io',
feeValueCommon: '0.123',
addressAction: null,
});
}

Expand Down
106 changes: 104 additions & 2 deletions src/modules/ethereum/transactions/addressAction.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { capitalize } from 'capitalize-ts';
import type { AddressAction } from 'defi-sdk';
import type { AddressAction, Asset } from 'defi-sdk';
import { ethers } from 'ethers';
import type { Networks } from 'src/modules/networks/Networks';
import type { CachedAssetQuery } from 'src/modules/defi-sdk/queries';
import { fetchAssetFromCacheOrAPI } from 'src/modules/defi-sdk/queries';
import type { Chain } from 'src/modules/networks/Chain';
import { UnsupportedNetwork } from 'src/modules/networks/errors';
import { nanoid } from 'nanoid';
import type {
IncomingTransaction,
IncomingTransactionWithChainId,
Expand All @@ -24,7 +25,6 @@ export type ClientTransactionStatus =

export type LocalAddressAction = Omit<AddressAction, 'transaction'> & {
transaction: Omit<AddressAction['transaction'], 'status'> & {
hash: string;
status: ClientTransactionStatus;
};
local: true;
Expand All @@ -41,6 +41,108 @@ export type IncomingAddressAction = Omit<
};
};

const ZERO_HASH =
'0x0000000000000000000000000000000000000000000000000000000000000000';

const toActionTx = (tx: IncomingTransaction, chain: Chain) =>
({
...tx,
chain: chain.toString(),
hash: (tx as { hash?: string }).hash || ZERO_HASH,
fee: null,
status: 'pending',
nonce: -1,
} as const);

export function createSendAddressAction({
transaction,
asset,
quantity,
chain,
}: {
transaction: IncomingTransaction;
asset: Asset;
quantity: string;
chain: Chain;
}): AddressAction {
return {
id: nanoid(),
datetime: new Date().toISOString(),
type: { display_value: 'Send', value: 'send' },
label: null,
transaction: toActionTx(transaction, chain),
content: {
transfers: {
outgoing: [
{
asset: { fungible: asset },
quantity,
price: asset.price?.value ?? null,
},
],
incoming: [],
},
},
};
}

type AssetQuantity = { asset: Asset; quantity: string };

export function createTradeAddressAction({
transaction,
outgoing,
incoming,
chain,
}: {
transaction: IncomingTransaction;
outgoing: AssetQuantity[];
incoming: AssetQuantity[];
chain: Chain;
}): AddressAction {
return {
id: nanoid(),
datetime: new Date().toISOString(),
type: { value: 'trade', display_value: 'Trade' },
transaction: toActionTx(transaction, chain),
label: null,
content: {
transfers: {
outgoing: outgoing.map(({ asset, quantity }) => ({
asset: { fungible: asset },
quantity,
price: asset.price?.value ?? null,
})),
incoming: incoming.map(({ asset, quantity }) => ({
asset: { fungible: asset },
quantity,
price: asset.price?.value ?? null,
})),
},
},
};
}

export function createApproveAddressAction({
transaction,
asset,
quantity,
chain,
}: {
transaction: IncomingTransaction;
asset: Asset;
quantity: string;
chain: Chain;
}): AddressAction {
return {
id: nanoid(),
datetime: new Date().toISOString(),
type: { value: 'approve', display_value: 'Approve' },
transaction: toActionTx(transaction, chain),
label: null,
content: { single_asset: { asset: { fungible: asset }, quantity } },
};
}

export type AnyAddressAction = AddressAction | LocalAddressAction;

type AddressActionLabelType = 'to' | 'from' | 'application' | 'contract';
Expand Down
10 changes: 9 additions & 1 deletion src/shared/analytics/analytics.background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
getProviderForMetabase,
getProviderNameFromGroup,
} from './getProviderNameFromGroup';
import { addressActionToAnalytics } from './shared/addressActionToAnalytics';

function queryWalletProvider(account: Account, address: string) {
const apiLayer = account.getCurrentWallet();
Expand Down Expand Up @@ -73,7 +74,13 @@ function trackAppEvents({ account }: { account: Account }) {

emitter.on(
'transactionSent',
async ({ transaction, initiator, feeValueCommon }) => {
async ({
transaction,
initiator,
feeValueCommon,
addressAction,
quote,
}) => {
const initiatorURL = new URL(initiator);
const { origin, pathname } = initiatorURL;
const networks = await networksStore.load();
Expand All @@ -95,6 +102,7 @@ function trackAppEvents({ account }: { account: Account }) {
gas_price: null, // TODO
network_fee: null, // TODO
network_fee_value: feeValueCommon,
...addressActionToAnalytics({ addressAction, quote }),
});
sendToMetabase('signed_transaction', params);
}
Expand Down
Loading

0 comments on commit 14342ed

Please sign in to comment.