mirror of
https://github.com/orionprotocol/sdk.git
synced 2026-03-15 22:52:36 +03:00
88 lines
2.6 KiB
TypeScript
88 lines
2.6 KiB
TypeScript
/* eslint-disable no-underscore-dangle */
|
|
import { TypedDataSigner } from '@ethersproject/abstract-signer';
|
|
import BigNumber from 'bignumber.js';
|
|
import { ethers } from 'ethers';
|
|
import { joinSignature, splitSignature } from 'ethers/lib/utils';
|
|
import { INTERNAL_ORION_PRECISION } from '../constants';
|
|
import ORDER_TYPES from '../constants/orderTypes';
|
|
import { Order, SignedOrder, SupportedChainId } from '../types';
|
|
import normalizeNumber from '../utils/normalizeNumber';
|
|
import getDomainData from './getDomainData';
|
|
import hashOrder from './hashOrder';
|
|
import signOrderPersonal from './signOrderPersonal';
|
|
|
|
const DEFAULT_EXPIRATION = 29 * 24 * 60 * 60 * 1000; // 29 days
|
|
|
|
type SignerWithTypedDataSign = ethers.Signer & TypedDataSigner;
|
|
|
|
export const signOrder = async (
|
|
baseAssetAddr: string,
|
|
quoteAssetAddr: string,
|
|
side: 'BUY' | 'SELL',
|
|
price: BigNumber.Value,
|
|
amount: BigNumber.Value,
|
|
matcherFee: BigNumber.Value,
|
|
senderAddress: string,
|
|
matcherAddress: string,
|
|
orionFeeAssetAddr: string,
|
|
usePersonalSign: boolean,
|
|
signer: ethers.Signer,
|
|
chainId: SupportedChainId,
|
|
) => {
|
|
const nonce = Date.now();
|
|
const expiration = nonce + DEFAULT_EXPIRATION;
|
|
|
|
const order: Order = {
|
|
senderAddress,
|
|
matcherAddress,
|
|
baseAsset: baseAssetAddr,
|
|
quoteAsset: quoteAssetAddr,
|
|
matcherFeeAsset: orionFeeAssetAddr,
|
|
amount: normalizeNumber(
|
|
amount,
|
|
INTERNAL_ORION_PRECISION,
|
|
BigNumber.ROUND_FLOOR,
|
|
).toNumber(),
|
|
price: normalizeNumber(
|
|
price,
|
|
INTERNAL_ORION_PRECISION,
|
|
BigNumber.ROUND_FLOOR,
|
|
).toNumber(),
|
|
matcherFee: normalizeNumber(
|
|
matcherFee,
|
|
INTERNAL_ORION_PRECISION,
|
|
BigNumber.ROUND_CEIL, // ROUND_CEIL because we don't want get "not enough fee" error
|
|
).toNumber(),
|
|
nonce,
|
|
expiration,
|
|
buySide: side === 'BUY' ? 1 : 0,
|
|
isPersonalSign: usePersonalSign,
|
|
};
|
|
|
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
const typedDataSigner = signer as SignerWithTypedDataSign;
|
|
|
|
const signature = usePersonalSign
|
|
? await signOrderPersonal(order, signer)
|
|
: await typedDataSigner._signTypedData(
|
|
getDomainData(chainId),
|
|
ORDER_TYPES,
|
|
order,
|
|
);
|
|
|
|
// https://github.com/poap-xyz/poap-fun/pull/62#issue-928290265
|
|
// "Signature's v was always send as 27 or 28, but from Ledger was 0 or 1"
|
|
const fixedSignature = joinSignature(splitSignature(signature));
|
|
|
|
if (!fixedSignature) throw new Error("Can't sign order");
|
|
|
|
const signedOrder: SignedOrder = {
|
|
...order,
|
|
id: hashOrder(order),
|
|
signature: fixedSignature,
|
|
};
|
|
return signedOrder;
|
|
};
|
|
|
|
export default signOrder;
|