Add StaticCallAssetData encoding and decoding
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
import {
|
||||
AssetProxyId,
|
||||
ERC1155AssetData,
|
||||
ERC1155AssetDataAbi,
|
||||
ERC1155AssetDataNoProxyId,
|
||||
ERC20AssetData,
|
||||
ERC721AssetData,
|
||||
MultiAssetData,
|
||||
MultiAssetDataWithRecursiveDecoding,
|
||||
SingleAssetData,
|
||||
StaticCallAssetData,
|
||||
} from '@0x/types';
|
||||
import { AbiEncoder, BigNumber } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
@@ -31,7 +31,7 @@ export const assetDataUtils = {
|
||||
return assetData;
|
||||
},
|
||||
/**
|
||||
* Decodes an ERC20 assetData hex string into it's corresponding ERC20 tokenAddress & assetProxyId
|
||||
* Decodes an ERC20 assetData hex string into its corresponding ERC20 tokenAddress & assetProxyId
|
||||
* @param assetData Hex encoded assetData string to decode
|
||||
* @return An object containing the decoded tokenAddress & assetProxyId
|
||||
*/
|
||||
@@ -60,7 +60,7 @@ export const assetDataUtils = {
|
||||
return assetData;
|
||||
},
|
||||
/**
|
||||
* Decodes an ERC721 assetData hex string into it's corresponding ERC721 tokenAddress, tokenId & assetProxyId
|
||||
* Decodes an ERC721 assetData hex string into its corresponding ERC721 tokenAddress, tokenId & assetProxyId
|
||||
* @param assetData Hex encoded assetData string to decode
|
||||
* @return An object containing the decoded tokenAddress, tokenId & assetProxyId
|
||||
*/
|
||||
@@ -91,13 +91,13 @@ export const assetDataUtils = {
|
||||
tokenValues: BigNumber[],
|
||||
callbackData: string,
|
||||
): string {
|
||||
const abiEncoder = AbiEncoder.createMethod('ERC1155Assets', ERC1155AssetDataAbi);
|
||||
const abiEncoder = AbiEncoder.createMethod('ERC1155Assets', constants.ERC1155_METHOD_ABI.inputs);
|
||||
const args = [tokenAddress, tokenIds, tokenValues, callbackData];
|
||||
const assetData = abiEncoder.encode(args, encodingRules);
|
||||
return assetData;
|
||||
},
|
||||
/**
|
||||
* Decodes an ERC1155 assetData hex string into it's corresponding ERC1155 components.
|
||||
* Decodes an ERC1155 assetData hex string into its corresponding ERC1155 components.
|
||||
* @param assetData Hex encoded assetData string to decode
|
||||
* @return An object containing the decoded tokenAddress, tokenIds, tokenValues, callbackData & assetProxyId
|
||||
*/
|
||||
@@ -106,7 +106,7 @@ export const assetDataUtils = {
|
||||
if (assetProxyId !== AssetProxyId.ERC1155) {
|
||||
throw new Error(`Invalid assetProxyId. Expected '${AssetProxyId.ERC1155}', got '${assetProxyId}'`);
|
||||
}
|
||||
const abiEncoder = AbiEncoder.createMethod('ERC1155Assets', ERC1155AssetDataAbi);
|
||||
const abiEncoder = AbiEncoder.createMethod('ERC1155Assets', constants.ERC1155_METHOD_ABI.inputs);
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const decodedAssetData = abiEncoder.decode(assetData, decodingRules) as ERC1155AssetDataNoProxyId;
|
||||
return {
|
||||
@@ -139,7 +139,7 @@ export const assetDataUtils = {
|
||||
return assetData;
|
||||
},
|
||||
/**
|
||||
* Decodes a MultiAsset assetData hex string into it's corresponding amounts and nestedAssetData
|
||||
* Decodes a MultiAsset assetData hex string into its corresponding amounts and nestedAssetData
|
||||
* @param assetData Hex encoded assetData string to decode
|
||||
* @return An object containing the decoded amounts and nestedAssetData
|
||||
*/
|
||||
@@ -165,7 +165,7 @@ export const assetDataUtils = {
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Decodes a MultiAsset assetData hex string into it's corresponding amounts and decoded nestedAssetData elements (all nested elements are flattened)
|
||||
* Decodes a MultiAsset assetData hex string into its corresponding amounts and decoded nestedAssetData elements (all nested elements are flattened)
|
||||
* @param assetData Hex encoded assetData string to decode
|
||||
* @return An object containing the decoded amounts and nestedAssetData
|
||||
*/
|
||||
@@ -201,6 +201,35 @@ export const assetDataUtils = {
|
||||
nestedAssetData: flattenedDecodedNestedAssetData as SingleAssetData[],
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Encodes StaticCallProxy data into an assetData hex string
|
||||
* @param callTarget Address of contract to call from StaticCallProxy
|
||||
* @param staticCallData The function data that will be called on the callTarget contract
|
||||
* @param callResultHash The keccak256 hash of the ABI encoded expected output of the static call
|
||||
* @return The hex encoded assetData string
|
||||
*/
|
||||
encodeStaticCallAssetData(callTarget: string, staticCallData: string, callResultHash: string): string {
|
||||
const abiEncoder = AbiEncoder.createMethod('StaticCall', constants.STATIC_CALL_METHOD_ABI.inputs);
|
||||
const args = [callTarget, staticCallData, callResultHash];
|
||||
const assetData = abiEncoder.encode(args, encodingRules);
|
||||
return assetData;
|
||||
},
|
||||
/**
|
||||
* Decoded StaticCall assetData into its corresponding callTarget, staticCallData, and expected callResultHash
|
||||
* @param assetData Hex encoded assetData string to decode
|
||||
* @return An object containing the decoded callTarget, staticCallData, and expected callResultHash
|
||||
*/
|
||||
decodeStaticCallAssetData(assetData: string): StaticCallAssetData {
|
||||
const abiEncoder = AbiEncoder.createMethod('StaticCall', constants.STATIC_CALL_METHOD_ABI.inputs);
|
||||
const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData);
|
||||
const decodedAssetData = abiEncoder.decode(assetData, decodingRules) as any;
|
||||
return {
|
||||
assetProxyId,
|
||||
callTarget: decodedAssetData.callTarget,
|
||||
callResultHash: decodedAssetData.callResultHash,
|
||||
staticCallData: decodedAssetData.staticCallData,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Decode and return the assetProxyId from the assetData
|
||||
* @param assetData Hex encoded assetData string to decode
|
||||
@@ -219,6 +248,7 @@ export const assetDataUtils = {
|
||||
assetProxyId !== AssetProxyId.ERC20 &&
|
||||
assetProxyId !== AssetProxyId.ERC721 &&
|
||||
assetProxyId !== AssetProxyId.ERC1155 &&
|
||||
assetProxyId !== AssetProxyId.StaticCall &&
|
||||
assetProxyId !== AssetProxyId.MultiAsset
|
||||
) {
|
||||
throw new Error(`Invalid assetProxyId: ${assetProxyId}`);
|
||||
@@ -253,6 +283,13 @@ export const assetDataUtils = {
|
||||
isMultiAssetData(decodedAssetData: SingleAssetData | MultiAssetData): decodedAssetData is MultiAssetData {
|
||||
return decodedAssetData.assetProxyId === AssetProxyId.MultiAsset;
|
||||
},
|
||||
/**
|
||||
* Checks if the decoded asset data is valid StaticCall data
|
||||
* @param decodedAssetData The decoded asset data to check
|
||||
*/
|
||||
isStaticCallAssetData(decodedAssetData: SingleAssetData | MultiAssetData): decodedAssetData is StaticCallAssetData {
|
||||
return decodedAssetData.assetProxyId === AssetProxyId.StaticCall;
|
||||
},
|
||||
/**
|
||||
* Throws if the length or assetProxyId are invalid for the ERC20Proxy.
|
||||
* @param assetData Hex encoded assetData string
|
||||
@@ -324,6 +361,13 @@ export const assetDataUtils = {
|
||||
);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Throws if the assetData is not StaticCallData.
|
||||
* @param assetData Hex encoded assetData string
|
||||
*/
|
||||
assertIsStaticCallAssetData(assetData: string): void {
|
||||
assetDataUtils.decodeStaticCallAssetData(assetData);
|
||||
},
|
||||
/**
|
||||
* Throws if the length or assetProxyId are invalid for the corresponding AssetProxy.
|
||||
* @param assetData Hex encoded assetData string
|
||||
@@ -348,7 +392,7 @@ export const assetDataUtils = {
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Decode any assetData into it's corresponding assetData object
|
||||
* Decode any assetData into its corresponding assetData object
|
||||
* @param assetData Hex encoded assetData string to decode
|
||||
* @return Either a ERC20, ERC721, ERC1155, or MultiAsset assetData object
|
||||
*/
|
||||
|
||||
@@ -48,7 +48,6 @@ export {
|
||||
ERC20AssetData,
|
||||
ERC721AssetData,
|
||||
ERC1155AssetData,
|
||||
ERC1155AssetDataAbi,
|
||||
MultiAssetData,
|
||||
MultiAssetDataWithRecursiveDecoding,
|
||||
AssetProxyId,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as chai from 'chai';
|
||||
|
||||
import { AssetProxyId, ERC1155AssetData, ERC721AssetData } from '@0x/types';
|
||||
import { AssetProxyId, ERC1155AssetData, ERC20AssetData, ERC721AssetData } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
import { assetDataUtils } from '../src/asset_data_utils';
|
||||
@@ -98,7 +98,8 @@ describe('assetDataUtils', () => {
|
||||
expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.MultiAsset);
|
||||
expect(decodedAssetData.amounts).to.deep.equal(KNOWN_MULTI_ASSET_ENCODING.amounts);
|
||||
expect(decodedAssetData.nestedAssetData.length).to.equal(3);
|
||||
const decodedErc20AssetData = decodedAssetData.nestedAssetData[0];
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const decodedErc20AssetData = decodedAssetData.nestedAssetData[0] as ERC20AssetData;
|
||||
expect(decodedErc20AssetData.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address);
|
||||
expect(decodedErc20AssetData.assetProxyId).to.equal(AssetProxyId.ERC20);
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
@@ -144,7 +145,8 @@ describe('assetDataUtils', () => {
|
||||
expect(decodedAssetData.nestedAssetData.length).to.be.equal(expectedNestedAssetDataLength);
|
||||
// validate nested asset data (outer)
|
||||
let nestedAssetDataIndex = 0;
|
||||
const decodedErc20AssetData1 = decodedAssetData.nestedAssetData[nestedAssetDataIndex++];
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const decodedErc20AssetData1 = decodedAssetData.nestedAssetData[nestedAssetDataIndex++] as ERC20AssetData;
|
||||
expect(decodedErc20AssetData1.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address);
|
||||
expect(decodedErc20AssetData1.assetProxyId).to.equal(AssetProxyId.ERC20);
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
@@ -158,7 +160,8 @@ describe('assetDataUtils', () => {
|
||||
expect(decodedErc1155AssetData1.tokenIds).to.be.deep.equal(KNOWN_ERC1155_ENCODING.tokenIds);
|
||||
expect(decodedErc1155AssetData1.callbackData).to.be.equal(KNOWN_ERC1155_ENCODING.callbackData);
|
||||
// validate nested asset data (inner)
|
||||
const decodedErc20AssetData2 = decodedAssetData.nestedAssetData[nestedAssetDataIndex++];
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const decodedErc20AssetData2 = decodedAssetData.nestedAssetData[nestedAssetDataIndex++] as ERC20AssetData;
|
||||
expect(decodedErc20AssetData2.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address);
|
||||
expect(decodedErc20AssetData2.assetProxyId).to.equal(AssetProxyId.ERC20);
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
|
||||
Reference in New Issue
Block a user