diff --git a/package.json b/package.json index f11622e..d9fa949 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "Crypto used in the Sorare stack", "author": "Sorare", "license": "MIT", - "version": "2.0.0", + "version": "2.0.1", "main": "lib.js", "dependencies": { "@noble/curves": "^1.0.0", diff --git a/src/index.ts b/src/index.ts index 32ce007..4dbdf90 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,7 +7,14 @@ import { keccak_256 as keccak } from '@noble/hashes/sha3'; import { bytesToHex } from '@noble/hashes/utils'; import * as starknet from 'micro-starknet'; -import { LimitOrder, Transfer, Signature } from './types'; +import { + LimitOrder, + Transfer, + FiatTransfer, + AuthorizationRequest, + Signature, +} from './types'; + import { getTransferMsgHash, getTransferMsgHashWithFee, @@ -141,6 +148,20 @@ const hashMessage = (message: string) => { return starknet.pedersen(h.substring(0, 32), h.substring(32)); }; +const hashFiatTransfer = (fiatTransfer: FiatTransfer) => { + const { mangopayWalletId, operationHash, amount, currency, nonce } = + fiatTransfer; + const message = [ + mangopayWalletId, + operationHash, + currency, + amount, + nonce, + ].join(':'); + + return hashMessage(message); +}; + export const signMessage = (privateKey: string, message: string): Signature => sign(privateKey, hashMessage(message)); @@ -186,3 +207,51 @@ export const verifyLimitOrder = ( const message = hashLimitOrder(limitOrder); return verify(signature, message, publicKey); }; + +export const signFiatTransfer = ( + privateKey: string, + fiatTransfer: FiatTransfer +): Signature => { + const message = hashFiatTransfer(fiatTransfer); + + return sign(privateKey, message); +}; + +export const verifyFiatTransfer = ( + publicKey: string, + fiatTransfer: FiatTransfer, + signature: Signature +): boolean => { + const message = hashFiatTransfer(fiatTransfer); + + return verify(signature, message, publicKey); +}; + +export const isATransferAuthorizationRequest = ( + request: AuthorizationRequest +): request is Transfer => 'receiverVaultId' in request; + +export const isALimitOrderAuthorizationRequest = ( + request: AuthorizationRequest +): request is LimitOrder => 'vaultIdSell' in request; + +export const isAFiatTransferAuthorizationRequest = ( + request: AuthorizationRequest +): request is FiatTransfer => 'mangopayWalletId' in request; + +export const signAuthorizationRequest = ( + privateKey: string, + authorizationRequest: AuthorizationRequest +) => { + if (isATransferAuthorizationRequest(authorizationRequest)) { + return signTransfer(privateKey, authorizationRequest); + } + if (isALimitOrderAuthorizationRequest(authorizationRequest)) { + return signLimitOrder(privateKey, authorizationRequest); + } + if (isAFiatTransferAuthorizationRequest(authorizationRequest)) { + return signFiatTransfer(privateKey, authorizationRequest); + } + + throw new Error('Invalid authorization request'); +}; diff --git a/src/types.ts b/src/types.ts index c7d4257..57fb10e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -28,6 +28,16 @@ export interface LimitOrder { feeInfo?: Fee | null; } +export interface FiatTransfer { + mangopayWalletId: string; + operationHash: string; + currency: string; + amount: number; + nonce: number; +} + +export type AuthorizationRequest = LimitOrder | Transfer | FiatTransfer; + export interface Signature { r: string; s: string;