Skip to content

Commit

Permalink
Merge pull request #33 from Once-Upon/feat/extractNetAssetTransfers
Browse files Browse the repository at this point in the history
feat:  add extractNetAssetTransfers
  • Loading branch information
pcowgill authored Mar 5, 2024
2 parents 71d11cd + 4f6b99c commit 5bd9a23
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 126 deletions.
259 changes: 134 additions & 125 deletions src/transformers/_common/netAssetTransfers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,152 +6,161 @@ import {
ERC1155Asset,
ERC20Asset,
ETHAsset,
AssetTransfer,
} from '../../types';

export function transform(block: RawBlock): RawBlock {
block.transactions = block.transactions.map((tx) => {
const assetTransfers = tx.assetTransfers;
if (!assetTransfers?.length) {
return tx;
export function extractNetAssetTransfers(
assetTransfers: AssetTransfer[],
): NetAssetTransfers {
const assetsById: Record<string, Asset> = {};
const netAssetsByAddress: Record<string, Record<string, bigint>> = {};

for (const assetTransfer of assetTransfers) {
if (
assetTransfer.from === assetTransfer.to ||
!assetTransfer.from ||
!assetTransfer.to
) {
continue;
}

let asset: Asset | undefined = undefined;
let assetValue = BigInt(0);
let assetId = '';
switch (assetTransfer.type) {
case 'erc721':
asset = {
contract: assetTransfer.contract,
tokenId: assetTransfer.tokenId,
type: assetTransfer.type,
};
assetValue = BigInt(1);
assetId = `${assetTransfer.contract}-${assetTransfer.tokenId}`;
break;
case 'erc1155':
asset = {
contract: assetTransfer.contract,
tokenId: assetTransfer.tokenId,
type: assetTransfer.type,
value: assetTransfer.value,
};
assetValue = BigInt(assetTransfer.value);
assetId = `${assetTransfer.contract}-${assetTransfer.tokenId}`;
break;
case 'erc20':
asset = {
contract: assetTransfer.contract,
type: assetTransfer.type,
value: assetTransfer.value,
};
assetValue = BigInt(assetTransfer.value);
assetId = `${assetTransfer.contract}`;
break;
case 'eth':
asset = {
type: assetTransfer.type,
value: assetTransfer.value,
};
assetValue = BigInt(assetTransfer.value);
assetId = 'eth';
break;
}

const assetsById: Record<string, Asset> = {};
const netAssetsByAddress: Record<string, Record<string, bigint>> = {};
if (!asset || !assetId) {
continue;
}

for (const assetTransfer of assetTransfers) {
if (
assetTransfer.from === assetTransfer.to ||
!assetTransfer.from ||
!assetTransfer.to
) {
continue;
}
if (!netAssetsByAddress[assetTransfer.from]) {
netAssetsByAddress[assetTransfer.from] = {};
}
if (!netAssetsByAddress[assetTransfer.to]) {
netAssetsByAddress[assetTransfer.to] = {};
}
if (!netAssetsByAddress[assetTransfer.from][assetId]) {
netAssetsByAddress[assetTransfer.from][assetId] = BigInt(0);
}
if (!netAssetsByAddress[assetTransfer.to][assetId]) {
netAssetsByAddress[assetTransfer.to][assetId] = BigInt(0);
}

let asset: Asset | undefined = undefined;
let assetValue = BigInt(0);
let assetId = '';
switch (assetTransfer.type) {
case 'erc721':
asset = {
contract: assetTransfer.contract,
tokenId: assetTransfer.tokenId,
type: assetTransfer.type,
};
assetValue = BigInt(1);
assetId = `${assetTransfer.contract}-${assetTransfer.tokenId}`;
break;
case 'erc1155':
asset = {
contract: assetTransfer.contract,
tokenId: assetTransfer.tokenId,
type: assetTransfer.type,
value: assetTransfer.value,
};
assetValue = BigInt(assetTransfer.value);
assetId = `${assetTransfer.contract}-${assetTransfer.tokenId}`;
break;
case 'erc20':
asset = {
contract: assetTransfer.contract,
type: assetTransfer.type,
value: assetTransfer.value,
};
assetValue = BigInt(assetTransfer.value);
assetId = `${assetTransfer.contract}`;
break;
case 'eth':
asset = {
type: assetTransfer.type,
value: assetTransfer.value,
};
assetValue = BigInt(assetTransfer.value);
assetId = 'eth';
break;
}
assetsById[assetId] = asset;
netAssetsByAddress[assetTransfer.from][assetId] =
netAssetsByAddress[assetTransfer.from][assetId] - BigInt(assetValue);
netAssetsByAddress[assetTransfer.to][assetId] =
netAssetsByAddress[assetTransfer.to][assetId] + BigInt(assetValue);
}

if (!asset || !assetId) {
const netAssetTransfers: NetAssetTransfers = {};
for (const [address, assets] of Object.entries(netAssetsByAddress)) {
for (const [id, value] of Object.entries(assets)) {
if (value === BigInt(0)) {
continue;
}

if (!netAssetsByAddress[assetTransfer.from]) {
netAssetsByAddress[assetTransfer.from] = {};
if (!netAssetTransfers[address]) {
netAssetTransfers[address] = { received: [], sent: [] };
}
if (!netAssetsByAddress[assetTransfer.to]) {
netAssetsByAddress[assetTransfer.to] = {};
}
if (!netAssetsByAddress[assetTransfer.from][assetId]) {
netAssetsByAddress[assetTransfer.from][assetId] = BigInt(0);
}
if (!netAssetsByAddress[assetTransfer.to][assetId]) {
netAssetsByAddress[assetTransfer.to][assetId] = BigInt(0);
}

assetsById[assetId] = asset;
netAssetsByAddress[assetTransfer.from][assetId] =
netAssetsByAddress[assetTransfer.from][assetId] - BigInt(assetValue);
netAssetsByAddress[assetTransfer.to][assetId] =
netAssetsByAddress[assetTransfer.to][assetId] + BigInt(assetValue);
}

const netAssetTransfers: NetAssetTransfers = {};
for (const [address, assets] of Object.entries(netAssetsByAddress)) {
for (const [id, value] of Object.entries(assets)) {
if (value === BigInt(0)) {
continue;
}

if (!netAssetTransfers[address]) {
netAssetTransfers[address] = { received: [], sent: [] };
}
const type = assetsById[id].type;
let assetTransferred: Asset = {
type: AssetType.ETH,
value: '',
};

const type = assetsById[id].type;
let assetTransferred: Asset = {
type: AssetType.ETH,
value: '',
if (type === AssetType.ERC721) {
assetTransferred = {
...assetsById[id],
};

if (type === AssetType.ERC721) {
assetTransferred = {
...assetsById[id],
};
} else {
switch (assetsById[id].type) {
case AssetType.ERC1155:
assetTransferred = assetsById[id] as ERC1155Asset;
assetTransferred.value =
value > BigInt(0)
? value.toString()
: (value * BigInt(-1)).toString();
break;
case AssetType.ERC20:
assetTransferred = assetsById[id] as ERC20Asset;
assetTransferred.value =
value > BigInt(0)
? value.toString()
: (value * BigInt(-1)).toString();
break;
case AssetType.ETH:
assetTransferred = assetsById[id] as ETHAsset;
assetTransferred.value =
value > BigInt(0)
? value.toString()
: (value * BigInt(-1)).toString();
break;
}
} else {
switch (assetsById[id].type) {
case AssetType.ERC1155:
assetTransferred = assetsById[id] as ERC1155Asset;
assetTransferred.value =
value > BigInt(0)
? value.toString()
: (value * BigInt(-1)).toString();
break;
case AssetType.ERC20:
assetTransferred = assetsById[id] as ERC20Asset;
assetTransferred.value =
value > BigInt(0)
? value.toString()
: (value * BigInt(-1)).toString();
break;
case AssetType.ETH:
assetTransferred = assetsById[id] as ETHAsset;
assetTransferred.value =
value > BigInt(0)
? value.toString()
: (value * BigInt(-1)).toString();
break;
}
}

if (value < BigInt(0)) {
netAssetTransfers[address].sent.push(assetTransferred);
} else {
netAssetTransfers[address].received.push(assetTransferred);
}
if (value < BigInt(0)) {
netAssetTransfers[address].sent.push(assetTransferred);
} else {
netAssetTransfers[address].received.push(assetTransferred);
}
}
}

if (Object.keys(netAssetTransfers).length > 0) {
return netAssetTransfers;
}

if (Object.keys(netAssetTransfers).length > 0) {
tx.netAssetTransfers = netAssetTransfers;
return {};
}

export function transform(block: RawBlock): RawBlock {
block.transactions = block.transactions.map((tx) => {
const assetTransfers = tx.assetTransfers;
if (!assetTransfers?.length) {
return tx;
}

tx.netAssetTransfers = extractNetAssetTransfers(assetTransfers);

return tx;
});

Expand Down
13 changes: 12 additions & 1 deletion src/transformers/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RawBlock } from 'src/types';
import { AssetTransfer, NetAssetTransfers, RawBlock } from 'src/types';
import { makeTransform } from '../helpers/utils';
import * as transactionAssetTransfers from './_common/assetTransfers';
import * as transactionDelegateCalls from './_common/delegateCalls';
Expand Down Expand Up @@ -28,6 +28,11 @@ const children = {
transactionForks,
};

const utils = {
extractNetAssetTransfers:
transactionNetAssetTransfers.extractNetAssetTransfers,
};

const transformers = Object.fromEntries(
Object.keys(children).map((key) => [key, children[key].transform]),
);
Expand All @@ -37,9 +42,15 @@ const transform = makeTransform(transformers);
type UsabilityTransformer = {
transform: (block: RawBlock) => RawBlock;
children: Record<string, unknown>;
utils: {
extractNetAssetTransfers: (
assetTransfers: AssetTransfer[],
) => NetAssetTransfers;
};
};

export const transformer: UsabilityTransformer = {
transform,
children,
utils,
};

0 comments on commit 5bd9a23

Please sign in to comment.