diff --git a/packages/order-utils/CHANGELOG.json b/packages/order-utils/CHANGELOG.json index 290563e85a..340541034b 100644 --- a/packages/order-utils/CHANGELOG.json +++ b/packages/order-utils/CHANGELOG.json @@ -13,6 +13,10 @@ { "note": "Add `refundReceiver` field to `FillQuoteTransformer.TransformData`.", "pr": 2657 + }, + { + "note": "Add `findTransformerNonce()` and `getTransformerAddress()` functions.", + "pr": 2657 } ] }, diff --git a/packages/order-utils/src/index.ts b/packages/order-utils/src/index.ts index bfc0d9506a..6a54e31604 100644 --- a/packages/order-utils/src/index.ts +++ b/packages/order-utils/src/index.ts @@ -77,7 +77,9 @@ export { AffiliateFeeTransformerData, encodeAffiliateFeeTransformerData, decodeAffiliateFeeTransformerData, -} from './transformer_data_encoders'; + findTransformerNonce, + getTransformerAddress, +} from './transformer_utils'; export { getOrderHash, getExchangeMetaTransactionHash, getExchangeProxyMetaTransactionHash } from './hash_utils'; diff --git a/packages/order-utils/src/transformer_data_encoders.ts b/packages/order-utils/src/transformer_utils.ts similarity index 81% rename from packages/order-utils/src/transformer_data_encoders.ts rename to packages/order-utils/src/transformer_utils.ts index 8f747bdbe7..1383558cb5 100644 --- a/packages/order-utils/src/transformer_data_encoders.ts +++ b/packages/order-utils/src/transformer_utils.ts @@ -1,5 +1,10 @@ import { Order } from '@0x/types'; import { AbiEncoder, BigNumber } from '@0x/utils'; +import * as ethjs from 'ethereumjs-util'; + +import { constants } from './constants'; + +const { NULL_ADDRESS } = constants; const ORDER_ABI_COMPONENTS = [ { name: 'makerAddress', type: 'address' }, @@ -187,3 +192,36 @@ export function encodeAffiliateFeeTransformerData(data: AffiliateFeeTransformerD export function decodeAffiliateFeeTransformerData(encoded: string): AffiliateFeeTransformerData { return affiliateFeeTransformerDataEncoder.decode(encoded); } + +/** + * Find the nonce for a transformer given its deployer. + * If `deployer` is the null address, zero will always be returned. + */ +export function findTransformerNonce( + transformer: string, + deployer: string = NULL_ADDRESS, + maxGuesses: number = 1024, +): number { + if (deployer === NULL_ADDRESS) { + return 0; + } + const lowercaseTransformer = transformer.toLowerCase(); + // Try to guess the nonce. + for (let nonce = 0; nonce < maxGuesses; ++nonce) { + const deployedAddress = getTransformerAddress(deployer, nonce); + if (deployedAddress === lowercaseTransformer) { + return nonce; + } + } + throw new Error(`${deployer} did not deploy ${transformer}!`); +} + +/** + * Compute the deployed address for a transformer given a deployer and nonce. + */ +export function getTransformerAddress(deployer: string, nonce: number): string { + return ethjs.bufferToHex( + // tslint:disable-next-line: custom-no-magic-numbers + ethjs.rlphash([deployer, nonce] as any).slice(12), + ); +}