import { Wallet , utils } from 'ethers' ; import { orderBNToString , BigNumber } from '../utils' ; import { generateSaltWithFeeFactor , signWithUserAndFee } from './pmmv5' ; import { getOrderSignDigest } from './orderHash' ; import { RFQOrder } from './types' ; import * as ethUtils from 'ethereumjs-util' ; export enum SignatureType { Illegal = 0 , Invalid = 1 , EIP712 = 2 , EthSign = 3 , WalletBytes = 4 , WalletBytes32 = 5 , Wallet = 6 , NSignatureTypes = 7 } export async function signByEOA ( orderHash , wallet ) { const hashArray = utils . arrayify ( orderHash ) ; let signature = await wallet . signMessage ( hashArray ) ; var signatureBuffer = Buffer . concat ( [ ethUtils . toBuffer ( signature ) , ethUtils . toBuffer ( '0x' + '00' . repeat ( 32 ) ) , ethUtils . toBuffer ( SignatureType . EthSign ) , ] ) ; signature = '0x' + signatureBuffer . toString ( 'hex' ) ; return signature ; } export function signByMMPSigner ( orderHash , userAddr , feeFactor , wallet ) { let signature = signWithUserAndFee ( wallet , orderHash , userAddr , feeFactor ) ; const signatureBuffer = Buffer . concat ( [ ethUtils . toBuffer ( signature ) , ethUtils . toBuffer ( SignatureType . Wallet ) , ] ) ; signature = '0x' + signatureBuffer . toString ( 'hex' ) ; return signature ; } export const buildSignedOrder = async ( signer , order , userAddr , chainId , rfqAddr ) : Promise < any > => { const feeFactor = order . feeFactor ; order . takerAddress = userAddr . toLowerCase ( ) ; order . salt = generateSaltWithFeeFactor ( feeFactor ) ; const rfqOrer = toRFQOrder ( order ) ; const orderHash = getOrderSignDigest ( rfqOrer , chainId , rfqAddr ) ; const makerWalletSignature = signer . address . toLowerCase ( ) == order . makerAddress . toLowerCase ( ) ? await signByEOA ( orderHash , signer ) : signByMMPSigner ( orderHash , userAddr , feeFactor , signer ) ; const signedOrder = { ... order , makerWalletSignature , } ; return orderBNToString ( signedOrder ) ; } ; const toNumber = ( obj ) : number => new BigNumber ( obj ) . toNumber ( ) ; export function toRFQOrder ( order ) { return { takerAddr : order . takerAddress , makerAddr : order . makerAddress , takerAssetAddr : order . takerAssetAddress , makerAssetAddr : order . makerAssetAddress , takerAssetAmount : order . takerAssetAmount , makerAssetAmount : order . makerAssetAmount , deadline : toNumber ( order . expirationTimeSeconds ) , feeFactor : order . feeFactor , salt : order . salt , } ; }