diff --git a/package-lock.json b/package-lock.json index d8b46ea..16a9075 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@orionprotocol/sdk", - "version": "0.22.0-rc0", + "version": "0.22.0-rc1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@orionprotocol/sdk", - "version": "0.22.0-rc0", + "version": "0.22.0-rc1", "hasInstallScript": true, "license": "ISC", "dependencies": { diff --git a/package.json b/package.json index 0ef962f..0947637 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@orionprotocol/sdk", - "version": "0.22.0-rc0", + "version": "0.22.0-rc1", "description": "Orion Protocol SDK", "main": "./lib/index.cjs", "module": "./lib/index.js", diff --git a/src/constants/orderTypes.ts b/src/constants/orderTypes.ts index cf80f60..b14ecd7 100644 --- a/src/constants/orderTypes.ts +++ b/src/constants/orderTypes.ts @@ -1,16 +1,9 @@ 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' }, + { name: 'limitOrder', type: 'bytes32' }, + { name: 'chainId', type: 'uint24' }, + { name: 'secretHash', type: 'bytes32' }, + { name: 'lockOrderExpiration', type: 'uint64' }, ], }; diff --git a/src/crypt/signOrder.ts b/src/crypt/signOrder.ts index 7ab50c9..f7b2134 100644 --- a/src/crypt/signOrder.ts +++ b/src/crypt/signOrder.ts @@ -1,11 +1,11 @@ import { BigNumber } from 'bignumber.js'; -import { ethers } from 'ethers'; +import { ethers, keccak256 } from 'ethers'; import { INTERNAL_PROTOCOL_PRECISION } from '../constants'; import ORDER_TYPES from '../constants/orderTypes.js'; -import type { CrossOrder, Order, SignedOrder, SupportedChainId } from '../types.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 generateSecret from '../utils/generateSecret'; const DEFAULT_EXPIRATION = 29 * 24 * 60 * 60 * 1000; // 29 days @@ -40,11 +40,10 @@ export const signOrder = async ({ }: SignOrderProps) => { const nonce = Date.now(); const expiration = nonce + DEFAULT_EXPIRATION; - // const secretHash = ethers.keccak256(secret); const isCrossChain = targetChainId === undefined || targetChainId !== chainId; - const order: Order | CrossOrder = { + const order: Order = { senderAddress, matcherAddress, baseAsset: baseAssetAddress, @@ -72,42 +71,50 @@ export const signOrder = async ({ targetChainId } : {}), - buySide: side === 'BUY' ? 1 : 0, - // chainId, - // secretHash, - // lockOrderExpiration: expiration + buySide: side === 'BUY' ? 1 : 0 }; - const limitOrder: 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 abiCoder = ethers.AbiCoder.defaultAbiCoder(); + + // Generate the orderParamsHash + const limitOrderHash = keccak256((abiCoder.encode( + ['address', 'address', 'address', 'address', 'address', 'uint64', 'uint64', 'uint64', 'uint64', 'uint64', 'uint8'], + [ + order.senderAddress, + order.matcherAddress, + order.baseAsset, + order.quoteAsset, + order.matcherFeeAsset, + order.amount, + order.price, + order.matcherFee, + order.nonce, + order.expiration, + order.buySide + ] + ))); + + const crossChainOrder = { + limitOrder: limitOrderHash, + chainId, + secretHash, + lockOrderExpiration: expiration + } + + // Generate the full crossChainOrder hash + // const orderHash = ethers.keccak256(ethers.AbiCoder.defaultAbiCoder().encode( + // ['bytes32', 'bytes32', 'uint24', 'bytes32', 'uint64'], + // [CROSS_CHAIN_ORDER_TYPEHASH, orderParamsHash, 97, '0x74a00e5cceb68d791486ddb9ea83bb8245eca22f67cb0ea81342f6eff8bf6e51', 1718955340461] + // )); + + // TODO: change what to show const signature = await signer.signTypedData( getDomainData(chainId), ORDER_TYPES, - order, + crossChainOrder, ); // https://github.com/poap-xyz/poap-fun/pull/62#issue-928290265 @@ -115,11 +122,11 @@ export const signOrder = async ({ const fixedSignature = ethers.Signature.from(signature).serialized; // if (!fixedSignature) throw new Error("Can't sign order"); - const { orderHash, secret, secretHash } = hashOrder(limitOrder, chainId); + // const { orderHash, secret, secretHash } = hashOrder(limitOrder, chainId); const signedOrder: SignedOrder = { ...order, - id: orderHash, + id: limitOrderHash, // TODO: change to orderHash signature: fixedSignature, ...(isCrossChain ? { secret, secretHash, targetChainId } : {}) }; diff --git a/src/utils/generateSecret.ts b/src/utils/generateSecret.ts index 513e42e..68dc7dc 100644 --- a/src/utils/generateSecret.ts +++ b/src/utils/generateSecret.ts @@ -1,3 +1,5 @@ +import { ethers } from 'ethers'; + class XorShift128Plus { private x: number; private y: number; @@ -41,13 +43,11 @@ function isomorphicCryptoRandomBytes(size: number): Uint8Array { return generateRandomBytes(size, rng); } -function decodeToString(uint8Array: Uint8Array): string { - return new TextDecoder('utf-8').decode(uint8Array); -} - -const generateSecret = (): string => { +const generateSecret = () => { const RANDOM_BITS = 256; - return decodeToString(isomorphicCryptoRandomBytes(RANDOM_BITS)); + const rand = isomorphicCryptoRandomBytes(RANDOM_BITS); + const secret = ethers.keccak256(rand); + return secret; }; export default generateSecret;