MetaTransaction V2 Utility Packages (#714)
* add utility class for MetaTransactionsV2, update artifacts, update wrappers * fix exports * update artifacts, update wrappers * update changelogs
This commit is contained in:
parent
e57fc60a76
commit
a7acf2951d
@ -1,4 +1,12 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "3.19.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Regenerate IZeroEx artifact"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1674517560,
|
"timestamp": 1674517560,
|
||||||
"version": "3.18.3",
|
"version": "3.18.3",
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,12 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "13.23.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Regenerate IZeroEx wrapper"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1681969282,
|
"timestamp": 1681969282,
|
||||||
"version": "13.22.21",
|
"version": "13.22.21",
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,12 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "11.22.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add MetaTransactionV2 utilities"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "11.21.0",
|
"version": "11.21.0",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
@ -12,6 +12,7 @@ export const NFTOrder = {
|
|||||||
export * from './eip712_utils';
|
export * from './eip712_utils';
|
||||||
export * from './orders';
|
export * from './orders';
|
||||||
export * from './meta_transactions';
|
export * from './meta_transactions';
|
||||||
|
export * from './meta_transactions_v2';
|
||||||
export * from './signature_utils';
|
export * from './signature_utils';
|
||||||
export * from './transformer_utils';
|
export * from './transformer_utils';
|
||||||
export * from './constants';
|
export * from './constants';
|
||||||
|
143
packages/protocol-utils/src/meta_transactions_v2.ts
Normal file
143
packages/protocol-utils/src/meta_transactions_v2.ts
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
import { getContractAddressesForChainOrThrow } from '@0x/contract-addresses';
|
||||||
|
import { EIP712TypedData } from '@0x/types';
|
||||||
|
import { BigNumber, hexUtils, NULL_ADDRESS } from '@0x/utils';
|
||||||
|
import { ZERO } from './constants';
|
||||||
|
import {
|
||||||
|
createExchangeProxyEIP712Domain,
|
||||||
|
EIP712_DOMAIN_PARAMETERS,
|
||||||
|
getExchangeProxyEIP712Hash,
|
||||||
|
getTypeHash,
|
||||||
|
} from './eip712_utils';
|
||||||
|
|
||||||
|
export interface MetaTransactionV2Fee {
|
||||||
|
recipient: string,
|
||||||
|
amount: BigNumber,
|
||||||
|
}
|
||||||
|
|
||||||
|
const MTX_DEFAULT_VALUES = {
|
||||||
|
signer: NULL_ADDRESS,
|
||||||
|
sender: NULL_ADDRESS,
|
||||||
|
expirationTimeSeconds: ZERO,
|
||||||
|
salt: ZERO,
|
||||||
|
callData: hexUtils.leftPad(0),
|
||||||
|
feeToken: NULL_ADDRESS,
|
||||||
|
fees: [] as MetaTransactionV2Fee[],
|
||||||
|
chainId: 1,
|
||||||
|
verifyingContract: getContractAddressesForChainOrThrow(1).exchangeProxy,
|
||||||
|
};
|
||||||
|
|
||||||
|
export type MetaTransactionV2Fields = typeof MTX_DEFAULT_VALUES;
|
||||||
|
|
||||||
|
export class MetaTransactionV2 {
|
||||||
|
public static readonly FEE_STRUCT_NAME = 'MetaTransactionFeeData';
|
||||||
|
public static readonly FEE_STRUCT_ABI = [
|
||||||
|
{ type: 'address', name: 'recipient' },
|
||||||
|
{ type: 'uint256', name: 'amount' },
|
||||||
|
];
|
||||||
|
public static readonly FEE_TYPE_HASH = getTypeHash(MetaTransactionV2.FEE_STRUCT_NAME, MetaTransactionV2.FEE_STRUCT_ABI);
|
||||||
|
|
||||||
|
public static readonly MTX_STRUCT_NAME = 'MetaTransactionDataV2';
|
||||||
|
public static readonly MTX_STRUCT_ABI = [
|
||||||
|
{ type: 'address', name: 'signer' },
|
||||||
|
{ type: 'address', name: 'sender' },
|
||||||
|
{ type: 'uint256', name: 'expirationTimeSeconds' },
|
||||||
|
{ type: 'uint256', name: 'salt' },
|
||||||
|
{ type: 'bytes', name: 'callData' },
|
||||||
|
{ type: 'address', name: 'feeToken' },
|
||||||
|
{ type: `${MetaTransactionV2.FEE_STRUCT_NAME}[]`, name: 'fees' },
|
||||||
|
];
|
||||||
|
public static readonly MTX_TYPE_HASH = getTypeHash(
|
||||||
|
MetaTransactionV2.MTX_STRUCT_NAME,
|
||||||
|
MetaTransactionV2.MTX_STRUCT_ABI,
|
||||||
|
{ [MetaTransactionV2.FEE_STRUCT_NAME]: MetaTransactionV2.FEE_STRUCT_ABI }
|
||||||
|
);
|
||||||
|
|
||||||
|
public signer: string;
|
||||||
|
public sender: string;
|
||||||
|
public expirationTimeSeconds: BigNumber;
|
||||||
|
public salt: BigNumber;
|
||||||
|
public callData: string;
|
||||||
|
public feeToken: string;
|
||||||
|
public fees: MetaTransactionV2Fee[];
|
||||||
|
public chainId: number;
|
||||||
|
public verifyingContract: string;
|
||||||
|
|
||||||
|
public constructor(fields: Partial<MetaTransactionV2Fields> = {}) {
|
||||||
|
const _fields = { ...MTX_DEFAULT_VALUES, ...fields };
|
||||||
|
this.signer = _fields.signer;
|
||||||
|
this.sender = _fields.sender;
|
||||||
|
this.expirationTimeSeconds = _fields.expirationTimeSeconds;
|
||||||
|
this.salt = _fields.salt;
|
||||||
|
this.callData = _fields.callData;
|
||||||
|
this.feeToken = _fields.feeToken;
|
||||||
|
this.fees = _fields.fees;
|
||||||
|
this.chainId = _fields.chainId;
|
||||||
|
this.verifyingContract = _fields.verifyingContract;
|
||||||
|
}
|
||||||
|
|
||||||
|
public clone(fields: Partial<MetaTransactionV2Fields> = {}): MetaTransactionV2 {
|
||||||
|
return new MetaTransactionV2({
|
||||||
|
signer: this.signer,
|
||||||
|
sender: this.sender,
|
||||||
|
expirationTimeSeconds: this.expirationTimeSeconds,
|
||||||
|
salt: this.salt,
|
||||||
|
callData: this.callData,
|
||||||
|
feeToken: this.feeToken,
|
||||||
|
fees: this.fees,
|
||||||
|
chainId: this.chainId,
|
||||||
|
verifyingContract: this.verifyingContract,
|
||||||
|
...fields,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getStructHash(): string {
|
||||||
|
const feesHash = hexUtils.hash(hexUtils.concat(
|
||||||
|
...this.fees.map((fee) => hexUtils.hash(hexUtils.concat(
|
||||||
|
hexUtils.leftPad(MetaTransactionV2.FEE_TYPE_HASH),
|
||||||
|
hexUtils.leftPad(fee.recipient),
|
||||||
|
hexUtils.leftPad(fee.amount),
|
||||||
|
)))
|
||||||
|
));
|
||||||
|
|
||||||
|
return hexUtils.hash(
|
||||||
|
hexUtils.concat(
|
||||||
|
hexUtils.leftPad(MetaTransactionV2.MTX_TYPE_HASH),
|
||||||
|
hexUtils.leftPad(this.signer),
|
||||||
|
hexUtils.leftPad(this.sender),
|
||||||
|
hexUtils.leftPad(this.expirationTimeSeconds),
|
||||||
|
hexUtils.leftPad(this.salt),
|
||||||
|
hexUtils.hash(this.callData),
|
||||||
|
hexUtils.leftPad(this.feeToken),
|
||||||
|
hexUtils.leftPad(feesHash),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getEIP712TypedData(): EIP712TypedData {
|
||||||
|
return {
|
||||||
|
types: {
|
||||||
|
EIP712Domain: EIP712_DOMAIN_PARAMETERS,
|
||||||
|
[MetaTransactionV2.MTX_STRUCT_NAME]: MetaTransactionV2.MTX_STRUCT_ABI,
|
||||||
|
[MetaTransactionV2.FEE_STRUCT_NAME]: MetaTransactionV2.FEE_STRUCT_ABI,
|
||||||
|
},
|
||||||
|
domain: createExchangeProxyEIP712Domain(this.chainId, this.verifyingContract) as any,
|
||||||
|
primaryType: MetaTransactionV2.MTX_STRUCT_NAME,
|
||||||
|
message: {
|
||||||
|
signer: this.signer,
|
||||||
|
sender: this.sender,
|
||||||
|
expirationTimeSeconds: this.expirationTimeSeconds.toString(10),
|
||||||
|
salt: this.salt.toString(10),
|
||||||
|
callData: this.callData,
|
||||||
|
feeToken: this.feeToken,
|
||||||
|
fees: this.fees.map(({recipient, amount}) => ({
|
||||||
|
recipient,
|
||||||
|
amount: amount.toString(10),
|
||||||
|
})) as any,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public getHash(): string {
|
||||||
|
return getExchangeProxyEIP712Hash(this.getStructHash(), this.chainId, this.verifyingContract);
|
||||||
|
}
|
||||||
|
}
|
66
packages/protocol-utils/test/meta_transactions_v2_test.ts
Normal file
66
packages/protocol-utils/test/meta_transactions_v2_test.ts
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import { chaiSetup, } from '@0x/dev-utils';
|
||||||
|
import { BigNumber } from '@0x/utils';
|
||||||
|
import { expect } from 'chai';
|
||||||
|
import { MetaTransactionV2 } from '../src/meta_transactions_v2';
|
||||||
|
|
||||||
|
chaiSetup.configure();
|
||||||
|
|
||||||
|
describe('mtxs v2', () => {
|
||||||
|
describe('MetaTransactionV2 (no fees)', () => {
|
||||||
|
const mtx = new MetaTransactionV2({
|
||||||
|
signer: '0x349e8d89e8b37214d9ce3949fc5754152c525bc3',
|
||||||
|
sender: '0x83c62b2e67dea0df2a27be0def7a22bd7102642c',
|
||||||
|
expirationTimeSeconds: new BigNumber(9101112),
|
||||||
|
salt: new BigNumber(2001),
|
||||||
|
callData: '0x12345678',
|
||||||
|
feeToken: '0xcc3c7ea403427154ec908203ba6c418bd699f7ce',
|
||||||
|
fees: [] as any,
|
||||||
|
chainId: 8008,
|
||||||
|
verifyingContract: '0x6701704d2421c64ee9aa93ec7f96ede81c4be77d',
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can get the struct hash', () => {
|
||||||
|
const actual = mtx.getStructHash();
|
||||||
|
const expected = '0x57db4055edfed82a6d86103197c21390bf29412fb4585e08c708454e03d92516';
|
||||||
|
expect(actual).to.eq(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can get the EIP712 hash', () => {
|
||||||
|
const actual = mtx.getHash();
|
||||||
|
const expected = '0x05fc975cb9f37cc442a2975bc479502ce33d2d068fe8a1d6f50dbb11c1499137';
|
||||||
|
expect(actual).to.eq(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('MetaTransactionV2 (two fees)', () => {
|
||||||
|
const mtx = new MetaTransactionV2({
|
||||||
|
signer: '0x349e8d89e8b37214d9ce3949fc5754152c525bc3',
|
||||||
|
sender: '0x83c62b2e67dea0df2a27be0def7a22bd7102642c',
|
||||||
|
expirationTimeSeconds: new BigNumber(9101112),
|
||||||
|
salt: new BigNumber(2001),
|
||||||
|
callData: '0x12345678',
|
||||||
|
feeToken: '0xcc3c7ea403427154ec908203ba6c418bd699f7ce',
|
||||||
|
fees: [{
|
||||||
|
recipient: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
|
||||||
|
amount: new BigNumber(1000000),
|
||||||
|
}, {
|
||||||
|
recipient: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
|
||||||
|
amount: new BigNumber(1000),
|
||||||
|
}] as any,
|
||||||
|
chainId: 8008,
|
||||||
|
verifyingContract: '0x6701704d2421c64ee9aa93ec7f96ede81c4be77d',
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can get the struct hash', () => {
|
||||||
|
const actual = mtx.getStructHash();
|
||||||
|
const expected = '0x441c8b8a8f25c1716f2880326d008d07d0b8eb9606623c0a81dd5d9fa14dd12e';
|
||||||
|
expect(actual).to.eq(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can get the EIP712 hash', () => {
|
||||||
|
const actual = mtx.getHash();
|
||||||
|
const expected = '0xfc85ef2149bd49fcc8fee2571ed8f0ecd671dec03845637ab1ded3d891ac3386';
|
||||||
|
expect(actual).to.eq(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user