mirror of
https://github.com/orionprotocol/sdk.git
synced 2026-04-06 04:57:53 +03:00
CFD (#28)
* Added new pairs type: futures * Added new pairs type: futures * added market param to pairsConfig request * OP-3268 [CFD] Deposit amount Added CFDContracts endpoint package.json version update * OP-3268 [CFD] Deposit amount CFDContractsSchema export * OP-3268 [CFD] Deposit amount CFDContractsSchema export package.json update * cfdContractsSchema rename Add getCFDHistory method package.json update * Parameter of getCFDHistory method was updated * cfdHistorySchema was updated * WS subscribtion for CFD balances, CFD Order signing functionality * cfdHistorySchema was updated package.json version 0.16.0-rc.6 was updated * package.json version 0.16.0-rc.7 was updated * Exchange and CFD history schemas was transformed package.json version 0.16.0-rc.8 was updated * Added HistoryTransactionStatus package.json version 0.16.0-rc.8 was updated * cfdContractsSchema was updated package.json version 0.16.0-rc.10 was updated * Merge conflicts fix package.json version was updated to 0.16.0-rc.12 * updated schemas, updated version * Updated CFD balance schema, updated unsubscribe with passing extra details * CFD balances schema update * Added CFD prices request * typing small fix * fixed transformation of CFD init / update responses * temporary added debug * temporary added debug. changed ver * debug, ver up * Add currentPrice to cfdBalanceSchema * Added maxAvailableLong maxAvailableShort to balances * added leverage and position status * Update isWithCode - allow string code * version up Co-authored-by: Mikhail Gladchenko <m@gladchenko.pw> Co-authored-by: Demid <demidn@gmail.com> Co-authored-by: Dmitry Leleko <lelekodmitry@gmail.com>
This commit is contained in:
31
src/crypt/hashCFDOrder.ts
Normal file
31
src/crypt/hashCFDOrder.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { ethers } from 'ethers';
|
||||
import { CFDOrder } from '../types';
|
||||
|
||||
const hashCFDOrder = (order: CFDOrder) => ethers.utils.solidityKeccak256(
|
||||
[
|
||||
'uint8',
|
||||
'address',
|
||||
'address',
|
||||
'address',
|
||||
'uint64',
|
||||
'uint64',
|
||||
'uint64',
|
||||
'uint64',
|
||||
'uint64',
|
||||
'uint8',
|
||||
],
|
||||
[
|
||||
'0x03',
|
||||
order.senderAddress,
|
||||
order.matcherAddress,
|
||||
order.instrumentAddress,
|
||||
order.amount,
|
||||
order.price,
|
||||
order.matcherFee,
|
||||
order.nonce,
|
||||
order.expiration,
|
||||
order.buySide ? '0x01' : '0x00',
|
||||
],
|
||||
);
|
||||
|
||||
export default hashCFDOrder;
|
||||
@@ -1,4 +1,5 @@
|
||||
export { default as signCancelOrder } from './signCancelOrder';
|
||||
export { default as signCancelOrderPersonal } from './signCancelOrderPersonal';
|
||||
export { default as signOrder } from './signOrder';
|
||||
export { default as signCFDOrder } from './signCFDOrder';
|
||||
export { default as signOrderPersonal } from './signOrderPersonal';
|
||||
|
||||
83
src/crypt/signCFDOrder.ts
Normal file
83
src/crypt/signCFDOrder.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
/* 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 { CFDOrder, SignedCFDOrder, SupportedChainId } from '../types';
|
||||
import normalizeNumber from '../utils/normalizeNumber';
|
||||
import getDomainData from './getDomainData';
|
||||
import signCFDOrderPersonal from "./signCFDOrderPersonal";
|
||||
import hashCFDOrder from "./hashCFDOrder";
|
||||
import CFD_ORDER_TYPES from "../constants/cfdOrderTypes";
|
||||
|
||||
const DEFAULT_EXPIRATION = 29 * 24 * 60 * 60 * 1000; // 29 days
|
||||
|
||||
type SignerWithTypedDataSign = ethers.Signer & TypedDataSigner;
|
||||
|
||||
export const signCFDOrder = async (
|
||||
instrumentAddress: string,
|
||||
side: 'BUY' | 'SELL',
|
||||
price: BigNumber.Value,
|
||||
amount: BigNumber.Value,
|
||||
matcherFee: BigNumber.Value,
|
||||
senderAddress: string,
|
||||
matcherAddress: string,
|
||||
usePersonalSign: boolean,
|
||||
signer: ethers.Signer,
|
||||
chainId: SupportedChainId,
|
||||
) => {
|
||||
const nonce = Date.now();
|
||||
const expiration = nonce + DEFAULT_EXPIRATION;
|
||||
|
||||
const order: CFDOrder = {
|
||||
senderAddress,
|
||||
matcherAddress,
|
||||
instrumentAddress,
|
||||
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 signCFDOrderPersonal(order, signer)
|
||||
: await typedDataSigner._signTypedData(
|
||||
getDomainData(chainId),
|
||||
CFD_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: SignedCFDOrder = {
|
||||
...order,
|
||||
id: hashCFDOrder(order),
|
||||
signature: fixedSignature,
|
||||
};
|
||||
|
||||
return signedOrder;
|
||||
};
|
||||
|
||||
export default signCFDOrder;
|
||||
30
src/crypt/signCFDOrderPersonal.ts
Normal file
30
src/crypt/signCFDOrderPersonal.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { ethers } from 'ethers';
|
||||
import { CFDOrder } from '../types';
|
||||
|
||||
const { arrayify, joinSignature, splitSignature } = ethers.utils;
|
||||
|
||||
const signCFDOrderPersonal = async (order: CFDOrder, signer: ethers.Signer) => {
|
||||
const message = ethers.utils.solidityKeccak256(
|
||||
[
|
||||
'string', 'address', 'address', 'address', 'uint64', 'uint64', 'uint64', 'uint64', 'uint64', 'uint8',
|
||||
],
|
||||
[
|
||||
'order',
|
||||
order.senderAddress,
|
||||
order.matcherAddress,
|
||||
order.instrumentAddress,
|
||||
order.amount,
|
||||
order.price,
|
||||
order.matcherFee,
|
||||
order.nonce,
|
||||
order.expiration,
|
||||
order.buySide,
|
||||
],
|
||||
);
|
||||
const signature = await signer.signMessage(arrayify(message));
|
||||
|
||||
// NOTE: metamask broke sig.v value and we fix it in next line
|
||||
return joinSignature(splitSignature(signature));
|
||||
};
|
||||
|
||||
export default signCFDOrderPersonal;
|
||||
Reference in New Issue
Block a user