mirror of
https://github.com/orionprotocol/sdk.git
synced 2026-04-01 02:27:56 +03:00
massive refactor
This commit is contained in:
@@ -9,10 +9,10 @@ import {
|
||||
INTERNAL_PROTOCOL_PRECISION,
|
||||
NATIVE_CURRENCY_PRECISION,
|
||||
SWAP_THROUGH_ORION_POOL_GAS_LIMIT
|
||||
} from '../../constants/index.js';
|
||||
} from '../../constants';
|
||||
import getNativeCryptocurrencyName from '../../utils/getNativeCryptocurrencyName.js';
|
||||
import { calculateFeeInFeeAsset, denormalizeNumber, normalizeNumber } from '../../utils/index.js';
|
||||
import { signOrder } from '../../crypt/index.js';
|
||||
import { signOrder } from '../../crypt';
|
||||
import type orderSchema from '../../services/Aggregator/schemas/orderSchema.js';
|
||||
import type { z } from 'zod';
|
||||
import { simpleFetch } from 'simple-typed-fetch';
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from '../../constants';
|
||||
import getNativeCryptocurrencyName from '../../utils/getNativeCryptocurrencyName.js';
|
||||
import { calculateFeeInFeeAsset, denormalizeNumber, normalizeNumber } from '../../utils/index.js';
|
||||
import { signOrder } from '../../crypt/index.js';
|
||||
import { signOrder } from '../../crypt';
|
||||
import type orderSchema from '../../services/Aggregator/schemas/orderSchema.js';
|
||||
import type { z } from 'zod';
|
||||
import type { SwapLimitParams } from './swapLimit.js';
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
export { default as cancelOrderTypes } from './cancelOrderTypes.js';
|
||||
export { default as orderStatuses } from './orderStatuses.js';
|
||||
export { default as orderTypes } from './orderTypes.js';
|
||||
export { default as subOrderStatuses } from './subOrderStatuses.js';
|
||||
export { default as networkCodes } from './networkCodes.js';
|
||||
export { default as exchanges } from './exchanges.js';
|
||||
export { default as exchangesMap } from './exchangesMap.js';
|
||||
|
||||
export * from './orderTypes';
|
||||
export * from './chains.js';
|
||||
export * from './precisions.js';
|
||||
export * from './gasLimits.js';
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
export const ORDER_TYPES = {
|
||||
Order: [
|
||||
{ name: 'senderAddress', type: 'address' },
|
||||
{ name: 'matcherAddress', type: 'address' },
|
||||
{ name: 'baseAsset', type: 'address' },
|
||||
{ name: 'quoteAsset', type: 'address' },
|
||||
{ name: 'matcherFeeAsset', type: 'address' },
|
||||
{ name: 'amount', type: 'uint64' },
|
||||
{ name: 'price', type: 'uint64' },
|
||||
{ name: 'matcherFee', type: 'uint64' },
|
||||
{ name: 'nonce', type: 'uint64' },
|
||||
{ name: 'expiration', type: 'uint64' },
|
||||
{ name: 'buySide', type: 'uint8' },
|
||||
],
|
||||
CrossChainOrder: [
|
||||
{ name: 'limitOrder', type: 'Order' },
|
||||
{ name: 'chainId', type: 'uint24' },
|
||||
{ name: 'secretHash', type: 'bytes32' },
|
||||
{ name: 'lockOrderExpiration', type: 'uint64' },
|
||||
]
|
||||
}
|
||||
|
||||
export default ORDER_TYPES;
|
||||
11
src/constants/orderTypes/crossChainOrderTypes.ts
Normal file
11
src/constants/orderTypes/crossChainOrderTypes.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import {ORDER_TYPE} from './orderTypes';
|
||||
|
||||
export const CROSS_CHAIN_ORDER_TYPES = {
|
||||
Order: ORDER_TYPE,
|
||||
CrossChainOrder: [
|
||||
{name: 'limitOrder', type: 'Order'},
|
||||
{name: 'chainId', type: 'uint24'},
|
||||
{name: 'secretHash', type: 'bytes32'},
|
||||
{name: 'lockOrderExpiration', type: 'uint64'},
|
||||
]
|
||||
}
|
||||
3
src/constants/orderTypes/index.ts
Normal file
3
src/constants/orderTypes/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './crossChainOrderTypes';
|
||||
export * from './lockOrderTypes';
|
||||
export { ORDER_TYPES } from './orderTypes';
|
||||
27
src/constants/orderTypes/orderTypes.ts
Normal file
27
src/constants/orderTypes/orderTypes.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
export const ORDER_TYPE = [
|
||||
{ name: 'senderAddress', type: 'address' },
|
||||
{ name: 'matcherAddress', type: 'address' },
|
||||
{ name: 'baseAsset', type: 'address' },
|
||||
{ name: 'quoteAsset', type: 'address' },
|
||||
{ name: 'matcherFeeAsset', type: 'address' },
|
||||
{ name: 'amount', type: 'uint64' },
|
||||
{ name: 'price', type: 'uint64' },
|
||||
{ name: 'matcherFee', type: 'uint64' },
|
||||
{ name: 'nonce', type: 'uint64' },
|
||||
{ name: 'expiration', type: 'uint64' },
|
||||
{ name: 'buySide', type: 'uint8' },
|
||||
];
|
||||
|
||||
export const ORDER_TYPES = {
|
||||
Order: ORDER_TYPE
|
||||
}
|
||||
|
||||
export const CROSS_CHAIN_ORDER_TYPES = {
|
||||
Order: ORDER_TYPE,
|
||||
CrossChainOrder: [
|
||||
{ name: 'limitOrder', type: 'Order' },
|
||||
{ name: 'chainId', type: 'uint24' },
|
||||
{ name: 'secretHash', type: 'bytes32' },
|
||||
{ name: 'lockOrderExpiration', type: 'uint64' },
|
||||
]
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { SupportedChainId } from '../types.js';
|
||||
import eip712DomainData from '../config/eip712DomainData.json' assert { type: 'json' };
|
||||
import eip712DomainData from '../config/eip712DomainData.json' assert {type: 'json'};
|
||||
import eip712DomainSchema from '../config/schemas/eip712DomainSchema.js';
|
||||
|
||||
const EIP712Domain = eip712DomainSchema.parse(eip712DomainData);
|
||||
@@ -19,7 +19,7 @@ function removeUndefined<T>(obj: Record<string, T | undefined>) {
|
||||
*/
|
||||
const getDomainData = (chainId: SupportedChainId) => ({
|
||||
...removeUndefined(EIP712Domain),
|
||||
chainId: Number(chainId), // check if it broke
|
||||
chainId: Number(chainId),
|
||||
});
|
||||
|
||||
export default getDomainData;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { ethers, keccak256 } from 'ethers';
|
||||
import type { SupportedChainId, SignedOrder } from '../types.js';
|
||||
import type { SupportedChainId, CrossChainOrder } from '../../types';
|
||||
|
||||
const ORDER_TYPEHASH =
|
||||
'0xb5132db62dfceb466f2f8aee7a039db36a99772e5a9771d28388a5f9baad7c54';
|
||||
const CROSS_CHAIN_ORDER_TYPEHASH =
|
||||
'0xc4666edeecc42a94cf6b87f39e1ca967792e6d738224365e54d7d06ec632b05c';
|
||||
|
||||
export function getOrderHash(order: Omit<SignedOrder, 'id'>, chainId: SupportedChainId) {
|
||||
export function getOrderHash(order: CrossChainOrder, chainId: SupportedChainId) {
|
||||
const abiCoder = ethers.AbiCoder.defaultAbiCoder();
|
||||
|
||||
// Generate the orderParamsHash
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ethers } from 'ethers';
|
||||
import type { LockOrder } from '../types.js';
|
||||
import type { LockOrder } from '../../types';
|
||||
|
||||
export const hashLockOrder = (order: LockOrder) => ethers.solidityPackedKeccak256(
|
||||
[
|
||||
@@ -10,11 +10,9 @@ export const hashLockOrder = (order: LockOrder) => ethers.solidityPackedKeccak25
|
||||
'uint64',
|
||||
'uint64',
|
||||
'uint64',
|
||||
'string'
|
||||
],
|
||||
[
|
||||
'0x03',
|
||||
order.user,
|
||||
order.sender,
|
||||
order.expiration,
|
||||
order.asset,
|
||||
54
src/crypt/hashOrders/hashOrder.ts
Normal file
54
src/crypt/hashOrders/hashOrder.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { ethers, keccak256 } from 'ethers';
|
||||
import type { Order } from '../../types';
|
||||
|
||||
const ORDER_TYPEHASH = '0xb5132db62dfceb466f2f8aee7a039db36a99772e5a9771d28388a5f9baad7c54'
|
||||
|
||||
export default function getOrderHash(order: Order) {
|
||||
const abiCoder = ethers.AbiCoder.defaultAbiCoder()
|
||||
|
||||
const {
|
||||
senderAddress,
|
||||
matcherAddress,
|
||||
baseAsset,
|
||||
quoteAsset,
|
||||
matcherFeeAsset,
|
||||
amount,
|
||||
price,
|
||||
matcherFee,
|
||||
nonce,
|
||||
expiration,
|
||||
buySide
|
||||
} = order
|
||||
const orderBytes = abiCoder.encode(
|
||||
[
|
||||
'bytes32',
|
||||
'address',
|
||||
'address',
|
||||
'address',
|
||||
'address',
|
||||
'address',
|
||||
'uint64',
|
||||
'uint64',
|
||||
'uint64',
|
||||
'uint64',
|
||||
'uint64',
|
||||
'uint8'
|
||||
],
|
||||
[
|
||||
ORDER_TYPEHASH,
|
||||
senderAddress,
|
||||
matcherAddress,
|
||||
baseAsset,
|
||||
quoteAsset,
|
||||
matcherFeeAsset,
|
||||
amount,
|
||||
price,
|
||||
matcherFee,
|
||||
nonce,
|
||||
expiration,
|
||||
buySide
|
||||
]
|
||||
)
|
||||
|
||||
return keccak256(orderBytes)
|
||||
}
|
||||
3
src/crypt/hashOrders/index.ts
Normal file
3
src/crypt/hashOrders/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './hashCrossChainOrder';
|
||||
export * from './hashOrder';
|
||||
export * from './hashLockOrder';
|
||||
@@ -1,3 +1,4 @@
|
||||
export { default as signCancelOrder } from './signCancelOrder.js';
|
||||
export { signOrder, type SignOrderProps } from './signOrder.js';
|
||||
export { signCrossChainOrder, type SignCrossChainOrderProps } from './signCrossChainOrder.js';
|
||||
export { signLockOrder, type SignLockOrderProps } from './signLockOrder.js';
|
||||
|
||||
111
src/crypt/signCrossChainOrder.ts
Normal file
111
src/crypt/signCrossChainOrder.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import { ethers, keccak256 } from 'ethers';
|
||||
import { INTERNAL_PROTOCOL_PRECISION } from '../constants';
|
||||
import { CROSS_CHAIN_ORDER_TYPES } from '../constants/orderTypes/orderTypes';
|
||||
import type { Order, SignedCrossChainOrder, SupportedChainId } from '../types.js';
|
||||
import normalizeNumber from '../utils/normalizeNumber.js';
|
||||
import getDomainData from './getDomainData.js';
|
||||
import generateSecret from '../utils/generateSecret';
|
||||
import { getOrderHash } from './hashOrders';
|
||||
|
||||
const DAY = 24 * 60 * 60 * 1000;
|
||||
const LOCK_ORDER_EXPIRATION = 4 * DAY;
|
||||
const DEFAULT_EXPIRATION = 29 * DAY;
|
||||
|
||||
export type SignCrossChainOrderProps = {
|
||||
baseAssetAddress: string
|
||||
quoteAssetAddress: string
|
||||
side: 'BUY' | 'SELL'
|
||||
price: BigNumber.Value
|
||||
amount: BigNumber.Value
|
||||
matcherFee: BigNumber.Value
|
||||
senderAddress: string
|
||||
matcherAddress: string
|
||||
serviceFeeAssetAddress: string
|
||||
signer: ethers.Signer
|
||||
chainId: SupportedChainId
|
||||
targetChainId?: SupportedChainId
|
||||
}
|
||||
|
||||
export const signCrossChainOrder = async ({
|
||||
amount,
|
||||
signer,
|
||||
side,
|
||||
baseAssetAddress,
|
||||
quoteAssetAddress,
|
||||
serviceFeeAssetAddress,
|
||||
matcherFee,
|
||||
matcherAddress,
|
||||
senderAddress,
|
||||
targetChainId,
|
||||
chainId,
|
||||
price
|
||||
}: SignCrossChainOrderProps): Promise<SignedCrossChainOrder> => {
|
||||
const nonce = Date.now();
|
||||
const expiration = nonce + DEFAULT_EXPIRATION;
|
||||
const lockOrderExpiration = nonce + LOCK_ORDER_EXPIRATION;
|
||||
|
||||
const order: Order = {
|
||||
senderAddress,
|
||||
matcherAddress,
|
||||
baseAsset: baseAssetAddress,
|
||||
quoteAsset: quoteAssetAddress,
|
||||
matcherFeeAsset: serviceFeeAssetAddress,
|
||||
amount: Number(normalizeNumber(
|
||||
amount,
|
||||
INTERNAL_PROTOCOL_PRECISION,
|
||||
BigNumber.ROUND_FLOOR,
|
||||
)),
|
||||
price: Number(normalizeNumber(
|
||||
price,
|
||||
INTERNAL_PROTOCOL_PRECISION,
|
||||
BigNumber.ROUND_FLOOR,
|
||||
)),
|
||||
matcherFee: Number(normalizeNumber(
|
||||
matcherFee,
|
||||
INTERNAL_PROTOCOL_PRECISION,
|
||||
BigNumber.ROUND_CEIL, // ROUND_CEIL because we don't want get "not enough fee" error
|
||||
)),
|
||||
nonce,
|
||||
expiration,
|
||||
buySide: side === 'BUY' ? 1 : 0
|
||||
};
|
||||
|
||||
const secret = generateSecret();
|
||||
const secretHash = keccak256(secret);
|
||||
|
||||
const crossChainOrder = {
|
||||
limitOrder: order,
|
||||
chainId: Number(chainId),
|
||||
secretHash,
|
||||
lockOrderExpiration
|
||||
}
|
||||
|
||||
const signature = await signer.signTypedData(
|
||||
getDomainData(chainId),
|
||||
CROSS_CHAIN_ORDER_TYPES,
|
||||
crossChainOrder
|
||||
);
|
||||
|
||||
// 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 = ethers.Signature.from(signature).serialized;
|
||||
|
||||
// if (!fixedSignature) throw new Error("Can't sign order");
|
||||
const signedOrderWithoutId: Omit<SignedCrossChainOrder, 'id'> = {
|
||||
...order,
|
||||
signature: fixedSignature,
|
||||
secret,
|
||||
secretHash,
|
||||
targetChainId: Number(targetChainId),
|
||||
lockOrderExpiration
|
||||
}
|
||||
const orderHash = getOrderHash(signedOrderWithoutId, chainId);
|
||||
|
||||
const signedCrossChainOrder: SignedCrossChainOrder = {
|
||||
...signedOrderWithoutId,
|
||||
id: orderHash
|
||||
};
|
||||
|
||||
return signedCrossChainOrder;
|
||||
};
|
||||
@@ -4,8 +4,7 @@ import getDomainData from './getDomainData.js';
|
||||
import generateSecret from '../utils/generateSecret';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import normalizeNumber from '../utils/normalizeNumber';
|
||||
import { INTERNAL_PROTOCOL_PRECISION } from '../constants';
|
||||
import { LOCK_ORDER_TYPES } from '../constants/lockOrderTypes';
|
||||
import { INTERNAL_PROTOCOL_PRECISION, LOCK_ORDER_TYPES } from '../constants';
|
||||
|
||||
const DEFAULT_EXPIRATION = 29 * 24 * 60 * 60 * 1000; // 29 days
|
||||
|
||||
@@ -41,6 +40,7 @@ export const signLockOrder = async ({
|
||||
BigNumber.ROUND_FLOOR,
|
||||
)),
|
||||
targetChainId: Number(targetChainId),
|
||||
secret,
|
||||
secretHash
|
||||
};
|
||||
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import { ethers, keccak256 } from 'ethers';
|
||||
import { INTERNAL_PROTOCOL_PRECISION } from '../constants';
|
||||
import ORDER_TYPES from '../constants/orderTypes.js';
|
||||
import { ethers } from 'ethers';
|
||||
import { INTERNAL_PROTOCOL_PRECISION, ORDER_TYPES } from '../constants';
|
||||
import type { Order, SignedOrder, SupportedChainId } from '../types.js';
|
||||
import normalizeNumber from '../utils/normalizeNumber.js';
|
||||
import getDomainData from './getDomainData.js';
|
||||
import generateSecret from '../utils/generateSecret';
|
||||
import { getOrderHash } from './hashOrder';
|
||||
import hashOrder from './hashOrders/hashOrder';
|
||||
|
||||
const DAY = 24 * 60 * 60 * 1000;
|
||||
const LOCK_ORDER_EXPIRATION = 4 * DAY;
|
||||
const DEFAULT_EXPIRATION = 29 * DAY;
|
||||
const DEFAULT_EXPIRATION = 29 * 24 * 60 * 60 * 1000; // 29 days
|
||||
|
||||
export type SignOrderProps = {
|
||||
baseAssetAddress: string
|
||||
@@ -24,28 +20,23 @@ export type SignOrderProps = {
|
||||
serviceFeeAssetAddress: string
|
||||
signer: ethers.Signer
|
||||
chainId: SupportedChainId
|
||||
targetChainId?: SupportedChainId
|
||||
}
|
||||
|
||||
export const signOrder = async ({
|
||||
amount,
|
||||
signer,
|
||||
side,
|
||||
senderAddress,
|
||||
serviceFeeAssetAddress,
|
||||
baseAssetAddress,
|
||||
quoteAssetAddress,
|
||||
serviceFeeAssetAddress,
|
||||
matcherFee,
|
||||
matcherAddress,
|
||||
senderAddress,
|
||||
targetChainId,
|
||||
chainId,
|
||||
signer,
|
||||
side,
|
||||
amount,
|
||||
price
|
||||
}: SignOrderProps): Promise<SignedOrder> => {
|
||||
}: SignOrderProps) => {
|
||||
const nonce = Date.now();
|
||||
const expiration = nonce + DEFAULT_EXPIRATION;
|
||||
const lockOrderExpiration = nonce + LOCK_ORDER_EXPIRATION;
|
||||
|
||||
const isCrossChain = targetChainId === undefined || targetChainId !== chainId;
|
||||
|
||||
const order: Order = {
|
||||
senderAddress,
|
||||
@@ -70,29 +61,13 @@ export const signOrder = async ({
|
||||
)),
|
||||
nonce,
|
||||
expiration,
|
||||
...(isCrossChain
|
||||
? {
|
||||
targetChainId: Number(targetChainId)
|
||||
}
|
||||
: {}),
|
||||
buySide: side === 'BUY' ? 1 : 0
|
||||
buySide: side === 'BUY' ? 1 : 0,
|
||||
};
|
||||
|
||||
const secret = generateSecret();
|
||||
const secretHash = keccak256(secret);
|
||||
|
||||
const crossChainOrder = {
|
||||
limitOrder: order,
|
||||
chainId: Number(chainId),
|
||||
secretHash,
|
||||
lockOrderExpiration
|
||||
}
|
||||
|
||||
// TODO: change what to show
|
||||
const signature = await signer.signTypedData(
|
||||
getDomainData(chainId),
|
||||
ORDER_TYPES,
|
||||
crossChainOrder
|
||||
order,
|
||||
);
|
||||
|
||||
// https://github.com/poap-xyz/poap-fun/pull/62#issue-928290265
|
||||
@@ -100,25 +75,11 @@ export const signOrder = async ({
|
||||
const fixedSignature = ethers.Signature.from(signature).serialized;
|
||||
|
||||
// if (!fixedSignature) throw new Error("Can't sign order");
|
||||
const signedOrderWithoutId: Omit<SignedOrder, 'id'> = {
|
||||
...order,
|
||||
signature: fixedSignature,
|
||||
secret,
|
||||
secretHash,
|
||||
...(isCrossChain
|
||||
? {
|
||||
targetChainId: Number(targetChainId)
|
||||
}
|
||||
: {}),
|
||||
lockOrderExpiration
|
||||
}
|
||||
const orderHash = getOrderHash(signedOrderWithoutId, chainId);
|
||||
|
||||
const signedOrder: SignedOrder = {
|
||||
...signedOrderWithoutId,
|
||||
id: orderHash
|
||||
...order,
|
||||
id: hashOrder(order),
|
||||
signature: fixedSignature,
|
||||
};
|
||||
return signedOrder;
|
||||
};
|
||||
|
||||
export default signOrder;
|
||||
|
||||
@@ -14,7 +14,8 @@ import type {
|
||||
NetworkShortName,
|
||||
SignedLockOrder,
|
||||
SignedCancelOrderRequest,
|
||||
SignedOrder
|
||||
SignedOrder,
|
||||
SignedCrossChainOrder
|
||||
} from '../../types.js';
|
||||
import {
|
||||
pairConfigSchema, aggregatedOrderbookSchema,
|
||||
@@ -211,7 +212,7 @@ class Aggregator {
|
||||
);
|
||||
|
||||
placeOrder = (
|
||||
signedOrder: SignedOrder,
|
||||
signedOrder: SignedOrder | SignedCrossChainOrder,
|
||||
isCreateInternalOrder: boolean,
|
||||
isReversedOrder?: boolean,
|
||||
partnerId?: string,
|
||||
|
||||
14
src/types.ts
14
src/types.ts
@@ -50,7 +50,9 @@ export type Order = {
|
||||
expiration: number // uint64
|
||||
buySide: 0 | 1 // uint8, 1=buy, 0=sell
|
||||
}
|
||||
export type CrossOrder = Order & {
|
||||
|
||||
export type CrossChainOrder = Order & {
|
||||
secret: string
|
||||
secretHash: string // bytes32
|
||||
targetChainId: number // uint24
|
||||
lockOrderExpiration: number // uint64
|
||||
@@ -62,18 +64,20 @@ export type LockOrder = {
|
||||
asset: string // address(?)
|
||||
amount: number // uint64
|
||||
targetChainId: number // uint64
|
||||
secret: string // bytes32
|
||||
secretHash: string // bytes32
|
||||
}
|
||||
|
||||
type SignedOrderAdditionalProps = {
|
||||
signature: string // bytes
|
||||
secret?: string
|
||||
secretHash?: string // bytes32
|
||||
needWithdraw?: boolean // bool (not supported yet by smart-contract)
|
||||
lockOrderExpiration?: number
|
||||
}
|
||||
|
||||
export type SignedOrder = SignedOrderAdditionalProps & (Order | CrossOrder) & {
|
||||
export type SignedOrder = SignedOrderAdditionalProps & Order & {
|
||||
id: string // hash of Order (it's not part of order structure in smart-contract)
|
||||
}
|
||||
|
||||
export type SignedCrossChainOrder = SignedOrderAdditionalProps & CrossChainOrder & {
|
||||
id: string // hash of Order (it's not part of order structure in smart-contract)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user