Rename ISigner to IWallet and implement SignatureType.Validator

This commit is contained in:
Fabio Berger
2018-05-31 21:23:08 -07:00
parent e654616b6d
commit 719c432ca8
7 changed files with 196 additions and 9 deletions

View File

@@ -11,7 +11,7 @@
"watch": "tsc -w",
"prebuild": "run-s clean update_artifacts generate_contract_wrappers",
"build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
"generate_contract_wrappers": "abi-gen --abis 'lib/src/artifacts/@(Exchange|ISigner).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated_contract_wrappers --backend ethers && prettier --write 'src/generated_contract_wrappers/**.ts'",
"generate_contract_wrappers": "abi-gen --abis 'lib/src/artifacts/@(Exchange|IWallet|IValidator).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated_contract_wrappers --backend ethers && prettier --write 'src/generated_contract_wrappers/**.ts'",
"update_artifacts": "for i in ${npm_package_config_contracts}; do copyfiles -u 4 ../migrations/artifacts/2.0.0/$i.json lib/src/artifacts; done;",
"test": "run-s build run_mocha",
"test:circleci": "yarn test:coverage",
@@ -26,7 +26,7 @@
"upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json"
},
"config": {
"contracts": "ISigner Exchange",
"contracts": "IWallet IValidator Exchange",
"postpublish": {
"docPublishConfigs": {
"extraFileIncludes": [

View File

@@ -1,8 +1,10 @@
import { Artifact } from '@0xproject/types';
import * as Exchange from './artifacts/Exchange.json';
import * as ISigner from './artifacts/ISigner.json';
import * as IValidator from './artifacts/IValidator.json';
import * as IWallet from './artifacts/IWallet.json';
export const artifacts = {
Exchange: (Exchange as any) as Artifact,
ISigner: (ISigner as any) as Artifact,
IWallet: (IWallet as any) as Artifact,
IValidator: (IValidator as any) as Artifact,
};

View File

@@ -7,7 +7,8 @@ import * as _ from 'lodash';
import { artifacts } from './artifacts';
import { assert } from './assert';
import { ExchangeContract } from './generated_contract_wrappers/exchange';
import { ISignerContract } from './generated_contract_wrappers/i_signer';
import { IWalletContract } from './generated_contract_wrappers/i_signer';
import { IValidatorContract } from './generated_contract_wrappers/i_validator';
import { MessagePrefixOpts, MessagePrefixType, OrderError } from './types';
/**
@@ -51,12 +52,27 @@ export async function isValidSignatureAsync(
throw new Error('Caller signature type cannot be validated off-chain');
case SignatureType.Wallet: {
const signerContract = new ISignerContract(artifacts.ISigner.abi, signerAddress, provider);
const signerContract = new IWalletContract(artifacts.IWallet.abi, signerAddress, provider);
const isValid = await signerContract.isValidSignature.callAsync(data, signature);
return isValid;
}
// TODO: Add SignatureType.Validator
case SignatureType.Validator: {
const validatorAddress = getValidatorAddressFromSignature(signature);
const exchangeContract = new ExchangeContract(artifacts.Exchange.abi, signerAddress, provider);
const isValidatorApproved = await exchangeContract.allowedValidators.callAsync(
signerAddress,
validatorAddress,
);
if (!isValidatorApproved) {
throw new Error(`Validator ${validatorAddress} was not pre-approved by ${signerAddress}.`);
}
const validatorSignature = getValidatorSignatureFromSignature(signature);
const validatorContract = new IValidatorContract(artifacts.IValidator.abi, signerAddress, provider);
const isValid = await validatorContract.isValidSignature.callAsync(data, signerAddress, validatorSignature);
return isValid;
}
case SignatureType.PreSigned: {
return isValidPresignedSignatureAsync(provider, data, signature, signerAddress);
@@ -219,6 +235,26 @@ function parseECSignature(signature: string): ECSignature {
return ecSignature;
}
function getValidatorSignatureFromSignature(signature: string): string {
const signatureTypeIndex = getSignatureTypeIndexIfExists(signature);
if (signatureTypeIndex !== SignatureType.Validator) {
throw new Error('Cannot get validator address from non-validator signature');
}
// tslint:disable-next-line:custom-no-magic-numbers
const validatorSignature = signature.slice(0, -22);
return validatorSignature;
}
function getValidatorAddressFromSignature(signature: string): string {
const signatureTypeIndex = getSignatureTypeIndexIfExists(signature);
if (signatureTypeIndex !== SignatureType.Validator) {
throw new Error('Cannot get validator address from non-validator signature');
}
// tslint:disable-next-line:custom-no-magic-numbers
const validatorAddress = signature.slice(-22, -2);
return `0x${validatorAddress}`;
}
function getSignatureTypeIndexIfExists(signature: string): number {
const unprefixedSignature = ethUtil.stripHexPrefix(signature);
// tslint:disable-next-line:custom-no-magic-numbers