This commit is contained in:
Alex Kraiz
2023-10-11 17:06:46 +04:00
parent ec81a62d65
commit ea794d9ce3
10 changed files with 303 additions and 9726 deletions

View File

@@ -1,140 +1,113 @@
{
"ignorePatterns": [
".eslintrc.js"
"ignorePatterns": [".eslintrc.js"],
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"standard-with-typescript",
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"plugin:@typescript-eslint/strict",
// "plugin:import/recommended",
// "plugin:import/typescript"
"prettier"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"tsconfigRootDir": ".",
"project": ["./tsconfig.json"],
"ecmaVersion": 2020,
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"rules": {
"@typescript-eslint/consistent-type-imports": [
"error",
{
"fixStyle": "separate-type-imports",
"disallowTypeAnnotations": true
}
],
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"standard-with-typescript",
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"plugin:@typescript-eslint/strict"
// "plugin:import/recommended",
// "plugin:import/typescript"
"@typescript-eslint/strict-boolean-expressions": [
"error",
{
"allowNullableObject": true,
"allowString": false,
"allowNumber": false,
"allowNullableBoolean": false,
"allowNullableString": false,
"allowNullableNumber": false,
"allowAny": false,
"allowNullableEnum": false
}
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"tsconfigRootDir": ".",
"project": [
"./tsconfig.json"
],
"ecmaVersion": 2020,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
"eqeqeq": "error",
"@typescript-eslint/consistent-type-definitions": ["warn", "type"],
"@typescript-eslint/promise-function-async": 0,
// "import/no-cycle": "error",
"@typescript-eslint/space-before-function-paren": 0,
"@typescript-eslint/comma-dangle": 0,
"@typescript-eslint/semi": 0,
"comma-dangle": 0,
"semi": 0,
"space-before-function-paren": 0,
"@typescript-eslint/explicit-function-return-type": 0,
"no-param-reassign": [
"error",
{
"props": true,
"ignorePropertyModificationsFor": ["acc", "prev"]
}
],
"rules": {
"@typescript-eslint/consistent-type-imports": [
"error",
{
"fixStyle": "separate-type-imports",
"disallowTypeAnnotations": true
}
],
"@typescript-eslint/strict-boolean-expressions": [
"error",
{
"allowNullableObject": true,
"allowString": false,
"allowNumber": false,
"allowNullableBoolean": false,
"allowNullableString": false,
"allowNullableNumber": false,
"allowAny": false,
"allowNullableEnum": false
}
],
"eqeqeq": "error",
"@typescript-eslint/consistent-type-definitions": [
"warn",
"type"
],
"@typescript-eslint/indent": [
"error",
2,
{
"SwitchCase": 1,
"ignoredNodes": [
"TSTypeParameterInstantiation"
]
}
],
"@typescript-eslint/promise-function-async": 0,
// "import/no-cycle": "error",
"@typescript-eslint/space-before-function-paren": 0,
"@typescript-eslint/comma-dangle": 0,
"@typescript-eslint/semi": 0,
"comma-dangle": 0,
"semi": 0,
"space-before-function-paren": 0,
"@typescript-eslint/explicit-function-return-type": 0,
"no-param-reassign": [
"error",
{
"props": true,
"ignorePropertyModificationsFor": [
"acc",
"prev"
]
}
],
"camelcase": "off",
"@typescript-eslint/consistent-type-assertions": [
"error",
{
"assertionStyle": "never"
}
],
// "import/max-dependencies": [
// "error",
// {
// "max": 20,
// "ignoreTypeImports": false
// }
// ],
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "error",
"no-shadow": "off",
"@typescript-eslint/no-shadow": [
"error"
],
"max-len": [
1,
140,
2,
{
"ignoreComments": true,
"ignoreUrls": true,
"ignoreTemplateLiterals": true
}
]
// "import/extensions": [
// "error",
// "ignorePackages",
// {
// "js": "never",
// "jsx": "never",
// "ts": "never",
// "tsx": "never"
// }
// ]
},
"settings": {
"import/resolver": {
"node": {
"extensions": [
".js",
".jsx",
".ts",
".tsx"
]
}
}
"camelcase": "off",
"@typescript-eslint/consistent-type-assertions": [
"error",
{
"assertionStyle": "never"
}
],
// "import/max-dependencies": [
// "error",
// {
// "max": 20,
// "ignoreTypeImports": false
// }
// ],
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "error",
"no-shadow": "off",
"@typescript-eslint/no-shadow": ["error"],
"max-len": [
1,
140,
2,
{
"ignoreComments": true,
"ignoreUrls": true,
"ignoreTemplateLiterals": true
}
]
// "import/extensions": [
// "error",
// "ignorePackages",
// {
// "js": "never",
// "jsx": "never",
// "ts": "never",
// "tsx": "never"
// }
// ]
},
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".jsx", ".ts", ".tsx"]
}
}
}
}
}

9536
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "@orionprotocol/sdk",
"version": "0.20.8",
"version": "0.20.9-dev.0",
"description": "Orion Protocol SDK",
"main": "./lib/index.cjs",
"module": "./lib/index.js",
@@ -69,6 +69,7 @@
"esbuild": "^0.13.4",
"eslint": "^8.47.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-standard": "^17.1.0",
"eslint-config-standard-with-typescript": "^38.0.0",
"eslint-plugin-import": "^2.28.1",
@@ -86,8 +87,6 @@
},
"dependencies": {
"@babel/runtime": "^7.21.0",
"@ethersproject/abstract-signer": "^5.7.0",
"@ethersproject/providers": "^5.7.2",
"@orionprotocol/contracts": "1.19.5",
"bignumber.js": "^9.1.1",
"bson-objectid": "^2.0.4",

View File

@@ -1,6 +1,7 @@
import { SwapExecutor__factory, UniswapV3Pool__factory } from "@orionprotocol/contracts/lib/ethers-v6/index.js"
import { type BigNumberish , type BytesLike, ethers, JsonRpcProvider } from "ethers"
import { SafeArray } from "../../../utils/safeGetters.js"
import { ethers } from "ethers";
import type { JsonRpcProvider , BigNumberish } from "ethers";
import type { SafeArray } from "../../../utils/safeGetters.js"
import { addCallParams, generateCalls } from "./utils.js"
import type { SingleSwap } from "../../../types.js"
@@ -10,11 +11,13 @@ export async function generateUni3Call(
recipient: string,
provider: JsonRpcProvider
) {
if (typeof amount === 'undefined') amount = 0
if (typeof amount === 'undefined') {
amount = 0
}
const encodedPool = await encodePoolV3(swap.pool, swap.assetIn, swap.assetOut, provider)
const executorInterface = SwapExecutor__factory.createInterface()
let calldata = executorInterface.encodeFunctionData('uniswapV3SingleSwapTo', [encodedPool, recipient, amount])
const calldata = executorInterface.encodeFunctionData('uniswapV3SingleSwapTo', [encodedPool, recipient, amount])
return addCallParams(calldata)
}
@@ -25,7 +28,9 @@ export async function generateOrion3Call(
recipient: string,
provider: JsonRpcProvider
) {
if (amount === undefined) amount = 0
if (amount === undefined) {
amount = 0
}
const encodedPool = await encodePoolV3(swap.pool, swap.assetIn, swap.assetOut, provider)
const executorInterface = SwapExecutor__factory.createInterface()

View File

@@ -0,0 +1,19 @@
const CROSS_CHAIN_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" },
{ name: "secretHash", type: "bytes32" },
{ name: "targetChainId", type: "uint24" },
],
};
export default CROSS_CHAIN_ORDER_TYPES;

View File

@@ -1,4 +1,5 @@
export { default as signCancelOrder } from './signCancelOrder.js';
export { default as signCancelOrderPersonal } from './signCancelOrderPersonal.js';
export { default as signOrder } from './signOrder.js';
export { default as signOrderPersonal } from './signOrderPersonal.js';
export { default as signCancelOrder } from "./signCancelOrder.js";
export { default as signCancelOrderPersonal } from "./signCancelOrderPersonal.js";
export { default as signOrder } from "./signOrder.js";
export { default as signOrderPersonal } from "./signOrderPersonal.js";
export { default as signCrossChainOrder } from "./sign-cross-chain-order.js";

View File

@@ -0,0 +1,89 @@
import { BigNumber } from "bignumber.js";
import { ethers } from "ethers";
import { INTERNAL_PROTOCOL_PRECISION } from "../constants/index.js";
import CROSS_CHAIN_ORDER_TYPES from "../constants/cross-chain-order-types.js";
import type {
CrossChainOrder,
SignedOrder,
SupportedChainId,
} from "../types.js";
import normalizeNumber from "../utils/normalizeNumber.js";
import getDomainData from "./getDomainData.js";
import hashOrder from "./hashOrder.js";
import signOrderPersonal from "./signOrderPersonal.js";
const DEFAULT_EXPIRATION = 29 * 24 * 60 * 60 * 1000; // 29 days
export const signCrossChainOrder = async (
baseAssetAddr: string,
quoteAssetAddr: string,
side: "BUY" | "SELL",
price: BigNumber.Value,
amount: BigNumber.Value,
matcherFee: BigNumber.Value,
senderAddress: string,
matcherAddress: string,
serviceFeeAssetAddr: string,
usePersonalSign: boolean,
secretHash: string,
targetChainId: number,
signer: ethers.Signer,
chainId: SupportedChainId
) => {
const nonce = Date.now();
const expiration = nonce + DEFAULT_EXPIRATION;
const order: CrossChainOrder = {
senderAddress,
matcherAddress,
baseAsset: baseAssetAddr,
quoteAsset: quoteAssetAddr,
matcherFeeAsset: serviceFeeAssetAddr,
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,
isPersonalSign: usePersonalSign,
secretHash,
targetChainId,
};
const signature = usePersonalSign
? await signOrderPersonal(order, signer)
: await signer.signTypedData(
getDomainData(chainId),
CROSS_CHAIN_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 = ethers.Signature.from(signature).serialized;
// if (!fixedSignature) throw new Error("Can't sign order");
const signedOrder: SignedOrder = {
...order,
id: hashOrder(order),
signature: fixedSignature,
};
return signedOrder;
};
export default signCrossChainOrder;

View File

@@ -1,42 +1,38 @@
import type { TypedDataSigner } from '@ethersproject/abstract-signer';
import { ethers } from 'ethers';
import CANCEL_ORDER_TYPES from '../constants/cancelOrderTypes.js';
import type { CancelOrderRequest, SignedCancelOrderRequest, SupportedChainId } from '../types.js';
import getDomainData from './getDomainData.js';
import signCancelOrderPersonal from './signCancelOrderPersonal.js';
type SignerWithTypedDataSign = ethers.Signer & TypedDataSigner;
import { ethers } from "ethers";
import CANCEL_ORDER_TYPES from "../constants/cancelOrderTypes.js";
import type {
CancelOrderRequest,
SignedCancelOrderRequest,
SupportedChainId,
} from "../types.js";
import getDomainData from "./getDomainData.js";
import signCancelOrderPersonal from "./signCancelOrderPersonal.js";
const signCancelOrder = async (
senderAddress: string,
id: string,
usePersonalSign: boolean,
signer: ethers.Signer,
chainId: SupportedChainId,
chainId: SupportedChainId
) => {
const cancelOrderRequest: CancelOrderRequest = {
id,
senderAddress,
isPersonalSign: usePersonalSign,
};
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const typedDataSigner = signer as SignerWithTypedDataSign;
const signature = usePersonalSign
? await signCancelOrderPersonal(cancelOrderRequest, signer)
// https://docs.ethers.io/v5/api/signer/#Signer-signTypedData
: await typedDataSigner.signTypedData(
getDomainData(chainId),
CANCEL_ORDER_TYPES,
cancelOrderRequest,
);
: await signer.signTypedData(
getDomainData(chainId),
CANCEL_ORDER_TYPES,
cancelOrderRequest
);
// 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 cancel");
const signedCancelOrderReqeust: SignedCancelOrderRequest = {
...cancelOrderRequest,
signature: fixedSignature,

View File

@@ -1,22 +1,19 @@
import type { TypedDataSigner } from '@ethersproject/abstract-signer';
import { BigNumber } from 'bignumber.js';
import { ethers } from 'ethers';
import { INTERNAL_PROTOCOL_PRECISION } from '../constants/index.js';
import ORDER_TYPES from '../constants/orderTypes.js';
import type { Order, SignedOrder, SupportedChainId } from '../types.js';
import normalizeNumber from '../utils/normalizeNumber.js';
import getDomainData from './getDomainData.js';
import hashOrder from './hashOrder.js';
import signOrderPersonal from './signOrderPersonal.js';
import { BigNumber } from "bignumber.js";
import { ethers } from "ethers";
import { INTERNAL_PROTOCOL_PRECISION } from "../constants/index.js";
import ORDER_TYPES from "../constants/orderTypes.js";
import type { Order, SignedOrder, SupportedChainId } from "../types.js";
import normalizeNumber from "../utils/normalizeNumber.js";
import getDomainData from "./getDomainData.js";
import hashOrder from "./hashOrder.js";
import signOrderPersonal from "./signOrderPersonal.js";
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',
side: "BUY" | "SELL",
price: BigNumber.Value,
amount: BigNumber.Value,
matcherFee: BigNumber.Value,
@@ -25,7 +22,7 @@ export const signOrder = async (
serviceFeeAssetAddr: string,
usePersonalSign: boolean,
signer: ethers.Signer,
chainId: SupportedChainId,
chainId: SupportedChainId
) => {
const nonce = Date.now();
const expiration = nonce + DEFAULT_EXPIRATION;
@@ -36,37 +33,32 @@ export const signOrder = async (
baseAsset: baseAssetAddr,
quoteAsset: quoteAssetAddr,
matcherFeeAsset: serviceFeeAssetAddr,
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
)),
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,
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,
);
: await signer.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"

View File

@@ -51,12 +51,23 @@ export type Order = {
isPersonalSign: boolean // bool
}
export type CrossChainOrder = Order & {
secretHash: string // bytes32
targetChainId: number // uint24
}
export type SignedOrder = {
id: string // hash of Order (it's not part of order structure in smart-contract)
signature: string // bytes
needWithdraw?: boolean // bool (not supported yet by smart-contract)
} & Order
export type SignedCrossChainOrder = {
id: string
signature: string // bytes
needWithdraw?: boolean // bool
} & CrossChainOrder
export type CancelOrderRequest = {
id: number | string
senderAddress: string