diff --git a/package.json b/package.json index d26cc23c..bebb16cd 100644 --- a/package.json +++ b/package.json @@ -3,12 +3,12 @@ "private": true, "packageManager": "pnpm@10.6.2", "scripts": { - "build": "turbo run build --filter=gridplus-sdk --filter=@gridplus/btc", + "build": "turbo run build --filter=gridplus-sdk --filter=@gridplus/btc --filter=@gridplus/types", "test": "turbo run test --filter=gridplus-sdk --filter=@gridplus/btc", "test-unit": "turbo run test-unit --filter=gridplus-sdk --filter=@gridplus/btc", - "lint": "turbo run lint --filter=gridplus-sdk --filter=@gridplus/btc", - "lint:fix": "turbo run lint:fix --filter=gridplus-sdk --filter=@gridplus/btc", - "typecheck": "turbo run typecheck --filter=gridplus-sdk --filter=@gridplus/btc", + "lint": "turbo run lint --filter=gridplus-sdk --filter=@gridplus/btc --filter=@gridplus/types", + "lint:fix": "turbo run lint:fix --filter=gridplus-sdk --filter=@gridplus/btc --filter=@gridplus/types", + "typecheck": "turbo run typecheck --filter=gridplus-sdk --filter=@gridplus/btc --filter=@gridplus/types", "e2e": "turbo run e2e --filter=gridplus-sdk", "docs:build": "pnpm --filter gridplus-sdk-docs run build", "docs:start": "pnpm --filter gridplus-sdk-docs run start" diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 5f007ee6..2dd57d45 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -55,6 +55,7 @@ }, "dependencies": { "@gridplus/btc": "workspace:*", + "@gridplus/types": "workspace:*", "@ethereumjs/common": "^10.0.0", "@ethereumjs/rlp": "^10.0.0", "@ethereumjs/tx": "^10.0.0", diff --git a/packages/sdk/src/constants.ts b/packages/sdk/src/constants.ts index d29182d9..8de74ee2 100644 --- a/packages/sdk/src/constants.ts +++ b/packages/sdk/src/constants.ts @@ -81,12 +81,8 @@ const addressSizes = { ETH: 20, // 20 byte address not including 0x prefix } as const; -/** @internal */ -const CURRENCIES = { - ETH: 'ETH', - BTC: 'BTC', - ETH_MSG: 'ETH_MSG', -} as const; +/** @internal - Re-export from @gridplus/types */ +export { CURRENCIES } from '@gridplus/types'; /** @internal */ // THIS NEEDS TO BE A PROTOCOL CONSTANT TOO @@ -646,7 +642,6 @@ export { getFwVersionConst, BIP_CONSTANTS, BASE_URL, - CURRENCIES, MAX_ADDR, NETWORKS_BY_CHAIN_ID, EXTERNAL_NETWORKS_BY_CHAIN_ID_URL, diff --git a/packages/sdk/src/protocol/latticeConstants.ts b/packages/sdk/src/protocol/latticeConstants.ts index 041564aa..06d40cf9 100644 --- a/packages/sdk/src/protocol/latticeConstants.ts +++ b/packages/sdk/src/protocol/latticeConstants.ts @@ -1,204 +1,18 @@ -export enum LatticeResponseCode { - success = 0x00, - invalidMsg = 0x80, - unsupportedVersion = 0x81, - deviceBusy = 0x82, - userTimeout = 0x83, - userDeclined = 0x84, - pairFailed = 0x85, - pairDisabled = 0x86, - permissionDisabled = 0x87, - internalError = 0x88, - gceTimeout = 0x89, - wrongWallet = 0x8a, - deviceLocked = 0x8b, - disabled = 0x8c, - already = 0x8d, - invalidEphemId = 0x8e, -} - -export enum LatticeSecureMsgType { - connect = 0x01, - encrypted = 0x02, -} - -export enum LatticeProtocolVersion { - v1 = 0x01, -} - -export enum LatticeMsgType { - response = 0x00, - secure = 0x02, -} - -export enum LatticeSecureEncryptedRequestType { - finalizePairing = 0, - getAddresses = 1, - sign = 3, - getWallets = 4, - getKvRecords = 7, - addKvRecords = 8, - removeKvRecords = 9, - fetchEncryptedData = 12, - test = 13, -} - -export enum LatticeGetAddressesFlag { - none = 0, // For formatted addresses - secp256k1Pubkey = 3, - ed25519Pubkey = 4, - bls12_381Pubkey = 5, - secp256k1Xpub = 6, // For Bitcoin XPUB -} - -export enum LatticeSignSchema { - bitcoin = 0, - ethereum = 1, // Deprecated - ethereumMsg = 3, - extraData = 4, - generic = 5, -} - -export enum LatticeSignHash { - none = 0, - keccak256 = 1, - sha256 = 2, -} - -export enum LatticeSignCurve { - secp256k1 = 0, - ed25519 = 1, - bls12_381 = 2, -} - -export enum LatticeSignEncoding { - none = 1, - solana = 2, - evm = 4, - eth_deposit = 5, - eip7702_auth = 6, - eip7702_auth_list = 7, -} - -export enum LatticeSignBlsDst { - NUL = 1, - POP = 2, -} - -export enum LatticeEncDataSchema { - eip2335 = 0, -} - -export const ProtocolConstants = { - // Lattice firmware uses a static initialization vector for - // message encryption/decryption. This is generally considered - // fine because each encryption/decryption uses a unique encryption - // secret (derived from the per-message ephemeral key pair). - aesIv: [ - 0x6d, 0x79, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x70, 0x61, 0x73, 0x73, - 0x77, 0x6f, 0x72, 0x64, - ], - // Constant size of address buffers from the Lattice. - // Note that this size also captures public keys returned - // by the Lattice (addresses = strings, pubkeys = buffers) - addrStrLen: 129, - // Status of the client's pairing with the target Lattice - pairingStatus: { - notPaired: 0x00, - paired: 0x01, - }, - // Response types, codes, and error messages - responseMsg: { - [LatticeResponseCode.success]: '', - [LatticeResponseCode.invalidMsg]: 'Invalid Request', - [LatticeResponseCode.unsupportedVersion]: 'Unsupported Version', - [LatticeResponseCode.deviceBusy]: 'Device Busy', - [LatticeResponseCode.userTimeout]: 'Timeout waiting for user', - [LatticeResponseCode.userDeclined]: 'Request declined by user', - [LatticeResponseCode.pairFailed]: 'Pairing failed', - [LatticeResponseCode.pairDisabled]: 'Pairing is currently disabled', - [LatticeResponseCode.permissionDisabled]: - 'Automated signing is currently disabled', - [LatticeResponseCode.internalError]: 'Device Error', - [LatticeResponseCode.gceTimeout]: 'Device Timeout', - [LatticeResponseCode.wrongWallet]: 'Active wallet does not match request', - [LatticeResponseCode.deviceLocked]: 'Device Locked', - [LatticeResponseCode.disabled]: 'Feature Disabled', - [LatticeResponseCode.already]: 'Record already exists on device', - [LatticeResponseCode.invalidEphemId]: 'Request failed - needs resync', - }, - msgSizes: { - // General message header size. Valid for all Lattice messages - header: 8, - // Checksum must be appended to each message - checksum: 4, - // Lattice secure message constants. All requests from this SDK - // are secure messages. - secure: { - // Sizes of full payloads for secure messages - payload: { - request: { - // [ requestType (1 byte) | pubkey (65 bytes) ] - connect: 66, - // [ requestType (1 byte) | ephemeralId (4 bytes) | encryptedData (1728 bytes) ] - encrypted: 1733, - }, - // Note that the response payload always has status code as the - // first byte. This byte is removed as part of `request`, inside - // `parseLattice1Response`. These constants include the status - // code byte. - response: { - connect: 215, - // Encrypted responses are as follows: - // encryptedData (1728) | empty (1728) - // The latter half is empty due to an invalid type definition - // in Lattice firmware. (Someone made a C `struct` instead of - // a `union`, oops). - encrypted: 3457, - }, - }, - // Sizes for data inside secure message payloads - data: { - // All requests also have a `requestCode`, which is omitted - // from these constants. - request: { - connect: 65, - encrypted: { - // All encrypted requests are encrypted into a 1728 byte buffer - encryptedData: 1728, - // Individual request types have different data sizes. - [LatticeSecureEncryptedRequestType.finalizePairing]: 99, - [LatticeSecureEncryptedRequestType.getAddresses]: 54, - [LatticeSecureEncryptedRequestType.sign]: 1680, - [LatticeSecureEncryptedRequestType.getWallets]: 0, - [LatticeSecureEncryptedRequestType.getKvRecords]: 9, - [LatticeSecureEncryptedRequestType.addKvRecords]: 1391, - [LatticeSecureEncryptedRequestType.removeKvRecords]: 405, - [LatticeSecureEncryptedRequestType.fetchEncryptedData]: 1025, - [LatticeSecureEncryptedRequestType.test]: 506, - }, - }, - // All responses also have a `responseCode`, which is omitted - // from these constants. - response: { - encrypted: { - encryptedData: 1728, - // Once decrypted, the data size of the response - // payload will be determined by the request type. - // NOTE: All requests also have ephemeralPublicKey (65 bytes) and - // checksum (4 bytes), which are excluded from these sizes. - [LatticeSecureEncryptedRequestType.finalizePairing]: 0, - [LatticeSecureEncryptedRequestType.getAddresses]: 1290, - [LatticeSecureEncryptedRequestType.sign]: 1090, - [LatticeSecureEncryptedRequestType.getWallets]: 142, - [LatticeSecureEncryptedRequestType.getKvRecords]: 1395, - [LatticeSecureEncryptedRequestType.addKvRecords]: 0, - [LatticeSecureEncryptedRequestType.removeKvRecords]: 0, - [LatticeSecureEncryptedRequestType.fetchEncryptedData]: 1608, - [LatticeSecureEncryptedRequestType.test]: 1646, - }, - }, - }, - }, - }, -} as const; +/** + * Re-export protocol enums and constants from @gridplus/types + */ +export { + LatticeResponseCode, + LatticeSecureMsgType, + LatticeProtocolVersion, + LatticeMsgType, + LatticeSecureEncryptedRequestType, + LatticeGetAddressesFlag, + LatticeSignSchema, + LatticeSignHash, + LatticeSignCurve, + LatticeSignEncoding, + LatticeSignBlsDst, + LatticeEncDataSchema, + ProtocolConstants, +} from '@gridplus/types'; diff --git a/packages/sdk/src/types/client.ts b/packages/sdk/src/types/client.ts index 61554783..e47424df 100644 --- a/packages/sdk/src/types/client.ts +++ b/packages/sdk/src/types/client.ts @@ -1,83 +1,15 @@ -import type { Address, Hash } from 'viem'; -import type { CURRENCIES } from '../constants'; -import type { KeyPair } from './shared'; - -export type Currency = keyof typeof CURRENCIES; - -export type SigningPath = number[]; - /** - * Signature components as returned by the Lattice device. - * Values can be Buffer (raw) or string (hex) depending on context. + * Re-export client types from @gridplus/types */ -export interface LatticeSignature { - r: Buffer | string; - s: Buffer | string; - v?: Buffer | string | number | bigint; -} - -export interface SignData { - tx?: string; - txHash?: Hash; - changeRecipient?: string; - sig?: LatticeSignature; - sigs?: Buffer[]; - signer?: Address; - pubkey?: Buffer; - err?: string; -} - -export type SigningRequestResponse = SignData | { pubkey: null; sig: null }; - -/** - * @deprecated This type uses legacy field names and number types instead of viem-compatible bigint. - * Use viem's TransactionSerializable types directly, or create viem-aligned request types. - * This will be removed in a future version. - */ -export interface TransactionPayload { - type: number; - gasPrice: number; - nonce: number; - gasLimit: number; - to: string; - value: number; - data: string; - maxFeePerGas: number; - maxPriorityFeePerGas: number; -} - -export interface Wallet { - /** 32 byte id */ - uid: Buffer; - /** 20 char (max) string */ - name: Buffer | null; - /** 4 byte flag */ - capabilities: number; - /** External or internal wallet */ - external: boolean; -} - -export interface ActiveWallets { - internal: Wallet; - external: Wallet; -} - -export interface RequestParams { - url: string; - payload: any; //TODO Fix this any - timeout?: number; - retries?: number; -} - -export interface ClientStateData { - activeWallets: ActiveWallets; - ephemeralPub: KeyPair; - fwVersion: Buffer; - deviceId: string; - name: string; - baseUrl: string; - privKey: Buffer; - key: Buffer; - retryCount: number; - timeout: number; -} +export { + type Currency, + type SigningPath, + type LatticeSignature, + type SignData, + type SigningRequestResponse, + type TransactionPayload, + type Wallet, + type ActiveWallets, + type RequestParams, + type ClientStateData, +} from '@gridplus/types'; diff --git a/packages/sdk/src/types/firmware.ts b/packages/sdk/src/types/firmware.ts index d3b6bab3..a5d23353 100644 --- a/packages/sdk/src/types/firmware.ts +++ b/packages/sdk/src/types/firmware.ts @@ -1,65 +1,10 @@ -import type { EXTERNAL } from '../constants'; - -export type FirmwareArr = [number, number, number]; - -export interface FirmwareVersion { - major: number; - minor: number; - fix: number; -} - -export interface GenericSigningData { - calldataDecoding: { - reserved: number; - maxSz: number; - }; - baseReqSz: number; - // See `GENERIC_SIGNING_BASE_MSG_SZ` in firmware - baseDataSz: number; - hashTypes: typeof EXTERNAL.SIGNING.HASHES; - curveTypes: typeof EXTERNAL.SIGNING.CURVES; - encodingTypes: { - NONE: typeof EXTERNAL.SIGNING.ENCODINGS.NONE; - SOLANA: typeof EXTERNAL.SIGNING.ENCODINGS.SOLANA; - EVM?: typeof EXTERNAL.SIGNING.ENCODINGS.EVM; - }; -} - -export interface FirmwareConstants { - abiCategorySz: number; - abiMaxRmv: number; - addrFlagsAllowed: boolean; - allowBtcLegacyAndSegwitAddrs: boolean; - allowedEthTxTypes: number[]; - contractDeployKey: string; - eip712MaxTypeParams: number; - eip712Supported: boolean; - ethMaxDataSz: number; - ethMaxGasPrice: number; - ethMaxMsgSz: number; - ethMsgPreHashAllowed: boolean; - extraDataFrameSz: number; - extraDataMaxFrames: number; - genericSigning: GenericSigningData; - getAddressFlags: [ - typeof EXTERNAL.GET_ADDR_FLAGS.ED25519_PUB, - typeof EXTERNAL.GET_ADDR_FLAGS.SECP256K1_PUB, - ]; - kvActionMaxNum: number; - kvActionsAllowed: boolean; - kvKeyMaxStrSz: number; - kvRemoveMaxNum: number; - kvValMaxStrSz: number; - maxDecoderBufSz: number; - personalSignHeaderSz: number; - prehashAllowed: boolean; - reqMaxDataSz: number; - varAddrPathSzAllowed: boolean; - flexibleAddrPaths?: boolean; -} - -export interface LatticeError { - code: string; - errno: string; - message: string; -} +/** + * Re-export firmware types from @gridplus/types + */ +export type { + FirmwareArr, + FirmwareVersion, + GenericSigningData, + FirmwareConstants, + LatticeError, +} from '@gridplus/types'; diff --git a/packages/sdk/src/types/messages.ts b/packages/sdk/src/types/messages.ts index 78a77821..5ec03cc1 100644 --- a/packages/sdk/src/types/messages.ts +++ b/packages/sdk/src/types/messages.ts @@ -1,19 +1,4 @@ -import type { LatticeMsgType } from '../protocol'; - -export interface LatticeMessageHeader { - // Protocol version. Should always be 0x01 - // [uint8] - version: number; - // Protocol request type. Should always be 0x02 - // for "secure" message type. - // [uint8] - type: LatticeMsgType; - // Random message ID for internal tracking in firmware - // [4 bytes] - id: Buffer; - // Length of payload data being used - // For an encrypted request, this indicates the - // size of the non-zero decrypted data. - // [uint16] - len: number; -} +/** + * Re-export message types from @gridplus/types + */ +export type { LatticeMessageHeader } from '@gridplus/types'; diff --git a/packages/sdk/src/types/secureMessages.ts b/packages/sdk/src/types/secureMessages.ts index ebbb9127..8f1156c9 100644 --- a/packages/sdk/src/types/secureMessages.ts +++ b/packages/sdk/src/types/secureMessages.ts @@ -1,59 +1,12 @@ -import type { LatticeResponseCode, LatticeSecureMsgType } from '../protocol'; -import type { LatticeMessageHeader } from './messages'; - -export interface LatticeSecureRequest { - // Message header - header: LatticeMessageHeader; - // Request data - payload: LatticeSecureRequestPayload; -} - -export interface LatticeSecureRequestPayload { - // Indicates whether this is a connect (0x01) or - // encrypted (0x02) secure request - // [uint8] - requestType: LatticeSecureMsgType; - // Request data - // [connect = 65 bytes, encrypted = 1732] - data: Buffer; -} - -export interface LatticeSecureConnectResponsePayload { - // [214 bytes] - data: Buffer; -} - -export interface LatticeSecureEncryptedResponsePayload { - // Error code - responseCode: LatticeResponseCode; - // Response data - // [3392 bytes] - data: Buffer; -} - -export interface LatticeSecureConnectRequestPayloadData { - // Public key corresponding to the static Client keypair - // [65 bytes] - pubkey: Buffer; -} - -export interface LatticeSecureEncryptedRequestPayloadData { - // SHA256(sharedSecret).slice(0, 4) - // [uint32] - ephemeralId: number; - // Encrypted data envelope - // [1728 bytes] - encryptedData: Buffer; -} - -export interface LatticeSecureDecryptedResponse { - // ECDSA public key that should replace the client's ephemeral key - // [65 bytes] - ephemeralPub: Buffer; - // Decrypted response data - // [Variable size] - data: Buffer; - // Checksum on response data (ephemeralKey | data) - // [uint32] - checksum: number; -} +/** + * Re-export secure message types from @gridplus/types + */ +export type { + LatticeSecureRequest, + LatticeSecureRequestPayload, + LatticeSecureConnectResponsePayload, + LatticeSecureEncryptedResponsePayload, + LatticeSecureConnectRequestPayloadData, + LatticeSecureEncryptedRequestPayloadData, + LatticeSecureDecryptedResponse, +} from '@gridplus/types'; diff --git a/packages/sdk/src/types/shared.ts b/packages/sdk/src/types/shared.ts index 9592cb4c..64c96c85 100644 --- a/packages/sdk/src/types/shared.ts +++ b/packages/sdk/src/types/shared.ts @@ -1,19 +1,10 @@ -import type { ec } from 'elliptic'; - -export interface KVRecords { - [key: string]: string; -} - -export interface EncrypterParams { - payload: Buffer; - sharedSecret: Buffer; -} - -export type KeyPair = ec.KeyPair; - -export type WalletPath = [number, number, number, number, number]; - -export interface DecryptedResponse { - decryptedData: Buffer; - newEphemeralPub: KeyPair; -} +/** + * Re-export shared types from @gridplus/types + */ +export type { + KVRecords, + EncrypterParams, + KeyPair, + WalletPath, + DecryptedResponse, +} from '@gridplus/types'; diff --git a/packages/sdk/src/types/sign.ts b/packages/sdk/src/types/sign.ts index f9ed2121..ce5f13ee 100644 --- a/packages/sdk/src/types/sign.ts +++ b/packages/sdk/src/types/sign.ts @@ -1,193 +1,34 @@ -import type { - AccessList, - Address, - Hex, - SignedAuthorization, - SignedAuthorizationList, - TypedData, - TypedDataDefinition, -} from 'viem'; +import type { TypedData } from 'viem'; import type { Client } from '../client'; -import type { Currency, SigningPath, Wallet } from './client'; -import type { FirmwareConstants } from './firmware'; - -export type ETH_MESSAGE_PROTOCOLS = 'eip712' | 'signPersonal'; - -export const TRANSACTION_TYPE = { - LEGACY: 0, - EIP2930: 1, - EIP1559: 2, - EIP7702_AUTH: 4, - EIP7702_AUTH_LIST: 5, -} as const; - -// Base transaction request with common fields -type BaseTransactionRequest = { - from?: Address; - to: Address; - value?: Hex | bigint; - data?: Hex; - chainId: number; - nonce: number; - gasLimit?: Hex | bigint; -}; - -// Legacy transaction request -type LegacyTransactionRequest = BaseTransactionRequest & { - type: typeof TRANSACTION_TYPE.LEGACY; - gasPrice: Hex | bigint; -}; - -// EIP-2930 transaction request -type EIP2930TransactionRequest = BaseTransactionRequest & { - type: typeof TRANSACTION_TYPE.EIP2930; - gasPrice: Hex | bigint; - accessList?: AccessList; -}; - -// EIP-1559 transaction request -type EIP1559TransactionRequest = BaseTransactionRequest & { - type: typeof TRANSACTION_TYPE.EIP1559; - maxFeePerGas: Hex | bigint; - maxPriorityFeePerGas: Hex | bigint; - accessList?: AccessList; -}; - -// EIP-7702 single authorization transaction request (type 4) -export type EIP7702AuthTransactionRequest = BaseTransactionRequest & { - type: typeof TRANSACTION_TYPE.EIP7702_AUTH; - maxFeePerGas: Hex | bigint; - maxPriorityFeePerGas: Hex | bigint; - accessList?: AccessList; - authorization: SignedAuthorization; -}; - -// EIP-7702 authorization list transaction request (type 5) -export type EIP7702AuthListTransactionRequest = BaseTransactionRequest & { - type: typeof TRANSACTION_TYPE.EIP7702_AUTH_LIST; - maxFeePerGas: Hex | bigint; - maxPriorityFeePerGas: Hex | bigint; - accessList?: AccessList; - authorizationList: SignedAuthorizationList; -}; - -// Main discriminated union for transaction requests -export type TransactionRequest = - | LegacyTransactionRequest - | EIP2930TransactionRequest - | EIP1559TransactionRequest - | EIP7702AuthTransactionRequest - | EIP7702AuthListTransactionRequest; - -export interface SigningPayload< - TTypedData extends TypedData | Record = TypedData, -> { - signerPath: SigningPath; - payload: - | Uint8Array - | Uint8Array[] - | Buffer - | Buffer[] - | Hex - | EIP712MessagePayload; - curveType: number; - hashType: number; - encodingType?: number; - protocol?: ETH_MESSAGE_PROTOCOLS; - decoder?: Buffer; -} - -export interface SignRequestParams< - TTypedData extends TypedData | Record = TypedData, -> { - data: SigningPayload | BitcoinSignPayload; - currency?: Currency; - cachedData?: unknown; - nextCode?: Buffer; -} - +import type { SigningPayload, BitcoinSignPayload, SignRequestParams } from '@gridplus/types'; + +/** + * Re-export sign types from @gridplus/types + */ +export { + TRANSACTION_TYPE, + type ETH_MESSAGE_PROTOCOLS, + type EIP7702AuthTransactionRequest, + type EIP7702AuthListTransactionRequest, + type TransactionRequest, + type SigningPayload, + type SignRequestParams, + type EncodeSignRequestParams, + type SignRequest, + type EthSignRequest, + type EthMsgSignRequest, + type BitcoinSignRequest, + type PreviousOutput, + type BitcoinSignPayload, + type DecodeSignResponseParams, + type EIP712MessagePayload, +} from '@gridplus/types'; + +/** + * SDK-specific types that reference the Client class + */ export interface SignRequestFunctionParams< TTypedData extends TypedData | Record = TypedData, > extends SignRequestParams { client: Client; } - -export interface EncodeSignRequestParams { - fwConstants: FirmwareConstants; - wallet: Wallet; - requestData: unknown; - cachedData?: unknown; - nextCode?: Buffer; -} - -export interface SignRequest { - payload: Buffer; - schema: number; -} - -export interface EthSignRequest extends SignRequest { - curveType: number; - encodingType: number; - hashType: number; - omitPubkey: boolean; - origPayloadBuf: Buffer; - extraDataPayloads: Buffer[]; -} - -export interface EthMsgSignRequest extends SignRequest { - input: { - signerPath: SigningPath; - payload: Buffer; - protocol: string; - fwConstants: FirmwareConstants; - }; -} - -export interface BitcoinSignRequest extends SignRequest { - origData: { - prevOuts: PreviousOutput[]; - recipient: string; - value: number; - fee: number; - changePath: number[]; - fwConstants: FirmwareConstants; - }; - changeData?: { value: number }; -} - -export type PreviousOutput = { - txHash: string; - value: number; - index: number; - signerPath: number[]; -}; - -export type BitcoinSignPayload = { - prevOuts: PreviousOutput[]; - recipient: string; - value: number; - fee: number; - changePath: number[]; -}; - -export interface DecodeSignResponseParams { - data: Buffer; - request: SignRequest; - isGeneric: boolean; - currency?: Currency; -} - -// Align EIP712MessagePayload with Viem's TypedDataDefinition -export interface EIP712MessagePayload< - TTypedData extends TypedData | Record = TypedData, - TPrimaryType extends keyof TTypedData | 'EIP712Domain' = keyof TTypedData, -> { - types: TTypedData; - domain: TTypedData extends TypedData - ? TypedDataDefinition['domain'] - : Record; - primaryType: TPrimaryType; - message: TTypedData extends TypedData - ? TypedDataDefinition['message'] - : Record; -} diff --git a/packages/types/biome.json b/packages/types/biome.json new file mode 100644 index 00000000..c365284a --- /dev/null +++ b/packages/types/biome.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "extends": ["../../biome.json"], + "files": { + "include": ["src/**/*.ts"], + "ignore": ["**/dist/**", "**/node_modules/**"] + } +} diff --git a/packages/types/package.json b/packages/types/package.json new file mode 100644 index 00000000..87769ec8 --- /dev/null +++ b/packages/types/package.json @@ -0,0 +1,46 @@ +{ + "name": "@gridplus/types", + "version": "0.1.0", + "type": "module", + "description": "Shared types for GridPlus SDK", + "scripts": { + "build": "tsup", + "lint": "biome check src", + "lint:fix": "biome check --write src", + "typecheck": "tsc --noEmit" + }, + "files": [ + "dist" + ], + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.cjs" + }, + "./package.json": "./package.json" + }, + "types": "./dist/index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/GridPlus/gridplus-sdk.git", + "directory": "packages/types" + }, + "dependencies": { + "elliptic": "6.6.1", + "viem": "^2.37.8" + }, + "devDependencies": { + "@biomejs/biome": "^1.9.0", + "@types/elliptic": "^6.4.18", + "@types/node": "^24.10.4", + "tsup": "^8.5.0", + "typescript": "^5.9.2" + }, + "license": "MIT", + "engines": { + "node": ">=20" + } +} diff --git a/packages/types/src/client.ts b/packages/types/src/client.ts new file mode 100644 index 00000000..6a8d4897 --- /dev/null +++ b/packages/types/src/client.ts @@ -0,0 +1,80 @@ +import type { Address, Hash } from 'viem'; +import type { KeyPair } from './shared'; + +export type SigningPath = number[]; + +/** + * Signature components as returned by the Lattice device. + * Values can be Buffer (raw) or string (hex) depending on context. + */ +export interface LatticeSignature { + r: Buffer | string; + s: Buffer | string; + v?: Buffer | string | number | bigint; +} + +export interface SignData { + tx?: string; + txHash?: Hash; + changeRecipient?: string; + sig?: LatticeSignature; + sigs?: Buffer[]; + signer?: Address; + pubkey?: Buffer; + err?: string; +} + +export type SigningRequestResponse = SignData | { pubkey: null; sig: null }; + +/** + * @deprecated This type uses legacy field names and number types instead of viem-compatible bigint. + * Use viem's TransactionSerializable types directly, or create viem-aligned request types. + * This will be removed in a future version. + */ +export interface TransactionPayload { + type: number; + gasPrice: number; + nonce: number; + gasLimit: number; + to: string; + value: number; + data: string; + maxFeePerGas: number; + maxPriorityFeePerGas: number; +} + +export interface Wallet { + /** 32 byte id */ + uid: Buffer; + /** 20 char (max) string */ + name: Buffer | null; + /** 4 byte flag */ + capabilities: number; + /** External or internal wallet */ + external: boolean; +} + +export interface ActiveWallets { + internal: Wallet; + external: Wallet; +} + +export interface RequestParams { + url: string; + payload: unknown; + timeout?: number; + retries?: number; +} + +export interface ClientStateData { + activeWallets: ActiveWallets; + ephemeralPub: KeyPair; + fwVersion: Buffer; + deviceId: string; + name: string; + baseUrl: string; + privKey: Buffer; + key: Buffer; + retryCount: number; + timeout: number; +} diff --git a/packages/types/src/constants.ts b/packages/types/src/constants.ts new file mode 100644 index 00000000..b91e1ac1 --- /dev/null +++ b/packages/types/src/constants.ts @@ -0,0 +1,11 @@ +/** + * SDK Constants that are needed for type definitions + */ + +export const CURRENCIES = { + ETH: 'ETH', + BTC: 'BTC', + ETH_MSG: 'ETH_MSG', +} as const; + +export type Currency = keyof typeof CURRENCIES; diff --git a/packages/types/src/firmware.ts b/packages/types/src/firmware.ts new file mode 100644 index 00000000..49c44230 --- /dev/null +++ b/packages/types/src/firmware.ts @@ -0,0 +1,78 @@ +import type { + LatticeGetAddressesFlag, + LatticeSignCurve, + LatticeSignEncoding, + LatticeSignHash, +} from './protocol'; + +export type FirmwareArr = [number, number, number]; + +export interface FirmwareVersion { + major: number; + minor: number; + fix: number; +} + +export interface GenericSigningData { + calldataDecoding: { + reserved: number; + maxSz: number; + }; + baseReqSz: number; + // See `GENERIC_SIGNING_BASE_MSG_SZ` in firmware + baseDataSz: number; + hashTypes: { + NONE: typeof LatticeSignHash.none; + KECCAK256: typeof LatticeSignHash.keccak256; + SHA256: typeof LatticeSignHash.sha256; + }; + curveTypes: { + SECP256K1: typeof LatticeSignCurve.secp256k1; + ED25519: typeof LatticeSignCurve.ed25519; + BLS12_381_G2: typeof LatticeSignCurve.bls12_381; + }; + encodingTypes: { + NONE: typeof LatticeSignEncoding.none; + SOLANA: typeof LatticeSignEncoding.solana; + EVM?: typeof LatticeSignEncoding.evm; + }; +} + +export interface FirmwareConstants { + abiCategorySz: number; + abiMaxRmv: number; + addrFlagsAllowed: boolean; + allowBtcLegacyAndSegwitAddrs: boolean; + allowedEthTxTypes: number[]; + contractDeployKey: string; + eip712MaxTypeParams: number; + eip712Supported: boolean; + ethMaxDataSz: number; + ethMaxGasPrice: number; + ethMaxMsgSz: number; + ethMsgPreHashAllowed: boolean; + extraDataFrameSz: number; + extraDataMaxFrames: number; + genericSigning: GenericSigningData; + getAddressFlags: [ + typeof LatticeGetAddressesFlag.ed25519Pubkey, + typeof LatticeGetAddressesFlag.secp256k1Pubkey, + ]; + kvActionMaxNum: number; + kvActionsAllowed: boolean; + kvKeyMaxStrSz: number; + kvRemoveMaxNum: number; + kvValMaxStrSz: number; + maxDecoderBufSz: number; + personalSignHeaderSz: number; + prehashAllowed: boolean; + reqMaxDataSz: number; + varAddrPathSzAllowed: boolean; + flexibleAddrPaths?: boolean; +} + +export interface LatticeError { + code: string; + errno: string; + message: string; +} diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts new file mode 100644 index 00000000..36d39f6a --- /dev/null +++ b/packages/types/src/index.ts @@ -0,0 +1,23 @@ +// Protocol enums and constants +export * from './protocol'; + +// SDK constants +export * from './constants'; + +// Shared types +export * from './shared'; + +// Message types +export * from './messages'; + +// Secure message types +export * from './secureMessages'; + +// Client-related types +export * from './client'; + +// Firmware types +export * from './firmware'; + +// Signing types +export * from './sign'; diff --git a/packages/types/src/messages.ts b/packages/types/src/messages.ts new file mode 100644 index 00000000..4b210efa --- /dev/null +++ b/packages/types/src/messages.ts @@ -0,0 +1,19 @@ +import type { LatticeMsgType } from './protocol'; + +export interface LatticeMessageHeader { + // Protocol version. Should always be 0x01 + // [uint8] + version: number; + // Protocol request type. Should always be 0x02 + // for "secure" message type. + // [uint8] + type: LatticeMsgType; + // Random message ID for internal tracking in firmware + // [4 bytes] + id: Buffer; + // Length of payload data being used + // For an encrypted request, this indicates the + // size of the non-zero decrypted data. + // [uint16] + len: number; +} diff --git a/packages/types/src/protocol.ts b/packages/types/src/protocol.ts new file mode 100644 index 00000000..9c444b93 --- /dev/null +++ b/packages/types/src/protocol.ts @@ -0,0 +1,208 @@ +/** + * Lattice protocol enums and constants + */ + +export enum LatticeResponseCode { + success = 0x00, + invalidMsg = 0x80, + unsupportedVersion = 0x81, + deviceBusy = 0x82, + userTimeout = 0x83, + userDeclined = 0x84, + pairFailed = 0x85, + pairDisabled = 0x86, + permissionDisabled = 0x87, + internalError = 0x88, + gceTimeout = 0x89, + wrongWallet = 0x8a, + deviceLocked = 0x8b, + disabled = 0x8c, + already = 0x8d, + invalidEphemId = 0x8e, +} + +export enum LatticeSecureMsgType { + connect = 0x01, + encrypted = 0x02, +} + +export enum LatticeProtocolVersion { + v1 = 0x01, +} + +export enum LatticeMsgType { + response = 0x00, + secure = 0x02, +} + +export enum LatticeSecureEncryptedRequestType { + finalizePairing = 0, + getAddresses = 1, + sign = 3, + getWallets = 4, + getKvRecords = 7, + addKvRecords = 8, + removeKvRecords = 9, + fetchEncryptedData = 12, + test = 13, +} + +export enum LatticeGetAddressesFlag { + none = 0, // For formatted addresses + secp256k1Pubkey = 3, + ed25519Pubkey = 4, + bls12_381Pubkey = 5, + secp256k1Xpub = 6, // For Bitcoin XPUB +} + +export enum LatticeSignSchema { + bitcoin = 0, + ethereum = 1, // Deprecated + ethereumMsg = 3, + extraData = 4, + generic = 5, +} + +export enum LatticeSignHash { + none = 0, + keccak256 = 1, + sha256 = 2, +} + +export enum LatticeSignCurve { + secp256k1 = 0, + ed25519 = 1, + bls12_381 = 2, +} + +export enum LatticeSignEncoding { + none = 1, + solana = 2, + evm = 4, + eth_deposit = 5, + eip7702_auth = 6, + eip7702_auth_list = 7, +} + +export enum LatticeSignBlsDst { + NUL = 1, + POP = 2, +} + +export enum LatticeEncDataSchema { + eip2335 = 0, +} + +export const ProtocolConstants = { + // Lattice firmware uses a static initialization vector for + // message encryption/decryption. This is generally considered + // fine because each encryption/decryption uses a unique encryption + // secret (derived from the per-message ephemeral key pair). + aesIv: [ + 0x6d, 0x79, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x70, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, + ], + // Constant size of address buffers from the Lattice. + // Note that this size also captures public keys returned + // by the Lattice (addresses = strings, pubkeys = buffers) + addrStrLen: 129, + // Status of the client's pairing with the target Lattice + pairingStatus: { + notPaired: 0x00, + paired: 0x01, + }, + // Response types, codes, and error messages + responseMsg: { + [LatticeResponseCode.success]: '', + [LatticeResponseCode.invalidMsg]: 'Invalid Request', + [LatticeResponseCode.unsupportedVersion]: 'Unsupported Version', + [LatticeResponseCode.deviceBusy]: 'Device Busy', + [LatticeResponseCode.userTimeout]: 'Timeout waiting for user', + [LatticeResponseCode.userDeclined]: 'Request declined by user', + [LatticeResponseCode.pairFailed]: 'Pairing failed', + [LatticeResponseCode.pairDisabled]: 'Pairing is currently disabled', + [LatticeResponseCode.permissionDisabled]: + 'Automated signing is currently disabled', + [LatticeResponseCode.internalError]: 'Device Error', + [LatticeResponseCode.gceTimeout]: 'Device Timeout', + [LatticeResponseCode.wrongWallet]: 'Active wallet does not match request', + [LatticeResponseCode.deviceLocked]: 'Device Locked', + [LatticeResponseCode.disabled]: 'Feature Disabled', + [LatticeResponseCode.already]: 'Record already exists on device', + [LatticeResponseCode.invalidEphemId]: 'Request failed - needs resync', + }, + msgSizes: { + // General message header size. Valid for all Lattice messages + header: 8, + // Checksum must be appended to each message + checksum: 4, + // Lattice secure message constants. All requests from this SDK + // are secure messages. + secure: { + // Sizes of full payloads for secure messages + payload: { + request: { + // [ requestType (1 byte) | pubkey (65 bytes) ] + connect: 66, + // [ requestType (1 byte) | ephemeralId (4 bytes) | encryptedData (1728 bytes) ] + encrypted: 1733, + }, + // Note that the response payload always has status code as the + // first byte. This byte is removed as part of `request`, inside + // `parseLattice1Response`. These constants include the status + // code byte. + response: { + connect: 215, + // Encrypted responses are as follows: + // encryptedData (1728) | empty (1728) + // The latter half is empty due to an invalid type definition + // in Lattice firmware. (Someone made a C `struct` instead of + // a `union`, oops). + encrypted: 3457, + }, + }, + // Sizes for data inside secure message payloads + data: { + // All requests also have a `requestCode`, which is omitted + // from these constants. + request: { + connect: 65, + encrypted: { + // All encrypted requests are encrypted into a 1728 byte buffer + encryptedData: 1728, + // Individual request types have different data sizes. + [LatticeSecureEncryptedRequestType.finalizePairing]: 99, + [LatticeSecureEncryptedRequestType.getAddresses]: 54, + [LatticeSecureEncryptedRequestType.sign]: 1680, + [LatticeSecureEncryptedRequestType.getWallets]: 0, + [LatticeSecureEncryptedRequestType.getKvRecords]: 9, + [LatticeSecureEncryptedRequestType.addKvRecords]: 1391, + [LatticeSecureEncryptedRequestType.removeKvRecords]: 405, + [LatticeSecureEncryptedRequestType.fetchEncryptedData]: 1025, + [LatticeSecureEncryptedRequestType.test]: 506, + }, + }, + // All responses also have a `responseCode`, which is omitted + // from these constants. + response: { + encrypted: { + encryptedData: 1728, + // Once decrypted, the data size of the response + // payload will be determined by the request type. + // NOTE: All requests also have ephemeralPublicKey (65 bytes) and + // checksum (4 bytes), which are excluded from these sizes. + [LatticeSecureEncryptedRequestType.finalizePairing]: 0, + [LatticeSecureEncryptedRequestType.getAddresses]: 1290, + [LatticeSecureEncryptedRequestType.sign]: 1090, + [LatticeSecureEncryptedRequestType.getWallets]: 142, + [LatticeSecureEncryptedRequestType.getKvRecords]: 1395, + [LatticeSecureEncryptedRequestType.addKvRecords]: 0, + [LatticeSecureEncryptedRequestType.removeKvRecords]: 0, + [LatticeSecureEncryptedRequestType.fetchEncryptedData]: 1608, + [LatticeSecureEncryptedRequestType.test]: 1646, + }, + }, + }, + }, + }, +} as const; diff --git a/packages/types/src/secureMessages.ts b/packages/types/src/secureMessages.ts new file mode 100644 index 00000000..083285f9 --- /dev/null +++ b/packages/types/src/secureMessages.ts @@ -0,0 +1,59 @@ +import type { LatticeResponseCode, LatticeSecureMsgType } from './protocol'; +import type { LatticeMessageHeader } from './messages'; + +export interface LatticeSecureRequest { + // Message header + header: LatticeMessageHeader; + // Request data + payload: LatticeSecureRequestPayload; +} + +export interface LatticeSecureRequestPayload { + // Indicates whether this is a connect (0x01) or + // encrypted (0x02) secure request + // [uint8] + requestType: LatticeSecureMsgType; + // Request data + // [connect = 65 bytes, encrypted = 1732] + data: Buffer; +} + +export interface LatticeSecureConnectResponsePayload { + // [214 bytes] + data: Buffer; +} + +export interface LatticeSecureEncryptedResponsePayload { + // Error code + responseCode: LatticeResponseCode; + // Response data + // [3392 bytes] + data: Buffer; +} + +export interface LatticeSecureConnectRequestPayloadData { + // Public key corresponding to the static Client keypair + // [65 bytes] + pubkey: Buffer; +} + +export interface LatticeSecureEncryptedRequestPayloadData { + // SHA256(sharedSecret).slice(0, 4) + // [uint32] + ephemeralId: number; + // Encrypted data envelope + // [1728 bytes] + encryptedData: Buffer; +} + +export interface LatticeSecureDecryptedResponse { + // ECDSA public key that should replace the client's ephemeral key + // [65 bytes] + ephemeralPub: Buffer; + // Decrypted response data + // [Variable size] + data: Buffer; + // Checksum on response data (ephemeralKey | data) + // [uint32] + checksum: number; +} diff --git a/packages/types/src/shared.ts b/packages/types/src/shared.ts new file mode 100644 index 00000000..9592cb4c --- /dev/null +++ b/packages/types/src/shared.ts @@ -0,0 +1,19 @@ +import type { ec } from 'elliptic'; + +export interface KVRecords { + [key: string]: string; +} + +export interface EncrypterParams { + payload: Buffer; + sharedSecret: Buffer; +} + +export type KeyPair = ec.KeyPair; + +export type WalletPath = [number, number, number, number, number]; + +export interface DecryptedResponse { + decryptedData: Buffer; + newEphemeralPub: KeyPair; +} diff --git a/packages/types/src/sign.ts b/packages/types/src/sign.ts new file mode 100644 index 00000000..565bca1e --- /dev/null +++ b/packages/types/src/sign.ts @@ -0,0 +1,187 @@ +import type { + AccessList, + Address, + Hex, + SignedAuthorization, + SignedAuthorizationList, + TypedData, + TypedDataDefinition, +} from 'viem'; +import type { Currency, SigningPath } from './index'; +import type { FirmwareConstants } from './firmware'; +import type { Wallet } from './client'; + +export type ETH_MESSAGE_PROTOCOLS = 'eip712' | 'signPersonal'; + +export const TRANSACTION_TYPE = { + LEGACY: 0, + EIP2930: 1, + EIP1559: 2, + EIP7702_AUTH: 4, + EIP7702_AUTH_LIST: 5, +} as const; + +// Base transaction request with common fields +type BaseTransactionRequest = { + from?: Address; + to: Address; + value?: Hex | bigint; + data?: Hex; + chainId: number; + nonce: number; + gasLimit?: Hex | bigint; +}; + +// Legacy transaction request +type LegacyTransactionRequest = BaseTransactionRequest & { + type: typeof TRANSACTION_TYPE.LEGACY; + gasPrice: Hex | bigint; +}; + +// EIP-2930 transaction request +type EIP2930TransactionRequest = BaseTransactionRequest & { + type: typeof TRANSACTION_TYPE.EIP2930; + gasPrice: Hex | bigint; + accessList?: AccessList; +}; + +// EIP-1559 transaction request +type EIP1559TransactionRequest = BaseTransactionRequest & { + type: typeof TRANSACTION_TYPE.EIP1559; + maxFeePerGas: Hex | bigint; + maxPriorityFeePerGas: Hex | bigint; + accessList?: AccessList; +}; + +// EIP-7702 single authorization transaction request (type 4) +export type EIP7702AuthTransactionRequest = BaseTransactionRequest & { + type: typeof TRANSACTION_TYPE.EIP7702_AUTH; + maxFeePerGas: Hex | bigint; + maxPriorityFeePerGas: Hex | bigint; + accessList?: AccessList; + authorization: SignedAuthorization; +}; + +// EIP-7702 authorization list transaction request (type 5) +export type EIP7702AuthListTransactionRequest = BaseTransactionRequest & { + type: typeof TRANSACTION_TYPE.EIP7702_AUTH_LIST; + maxFeePerGas: Hex | bigint; + maxPriorityFeePerGas: Hex | bigint; + accessList?: AccessList; + authorizationList: SignedAuthorizationList; +}; + +// Main discriminated union for transaction requests +export type TransactionRequest = + | LegacyTransactionRequest + | EIP2930TransactionRequest + | EIP1559TransactionRequest + | EIP7702AuthTransactionRequest + | EIP7702AuthListTransactionRequest; + +export interface SigningPayload< + TTypedData extends TypedData | Record = TypedData, +> { + signerPath: SigningPath; + payload: + | Uint8Array + | Uint8Array[] + | Buffer + | Buffer[] + | Hex + | EIP712MessagePayload; + curveType: number; + hashType: number; + encodingType?: number; + protocol?: ETH_MESSAGE_PROTOCOLS; + decoder?: Buffer; +} + +export interface SignRequestParams< + TTypedData extends TypedData | Record = TypedData, +> { + data: SigningPayload | BitcoinSignPayload; + currency?: Currency; + cachedData?: unknown; + nextCode?: Buffer; +} + +export interface EncodeSignRequestParams { + fwConstants: FirmwareConstants; + wallet: Wallet; + requestData: unknown; + cachedData?: unknown; + nextCode?: Buffer; +} + +export interface SignRequest { + payload: Buffer; + schema: number; +} + +export interface EthSignRequest extends SignRequest { + curveType: number; + encodingType: number; + hashType: number; + omitPubkey: boolean; + origPayloadBuf: Buffer; + extraDataPayloads: Buffer[]; +} + +export interface EthMsgSignRequest extends SignRequest { + input: { + signerPath: SigningPath; + payload: Buffer; + protocol: string; + fwConstants: FirmwareConstants; + }; +} + +export interface BitcoinSignRequest extends SignRequest { + origData: { + prevOuts: PreviousOutput[]; + recipient: string; + value: number; + fee: number; + changePath: number[]; + fwConstants: FirmwareConstants; + }; + changeData?: { value: number }; +} + +export type PreviousOutput = { + txHash: string; + value: number; + index: number; + signerPath: number[]; +}; + +export type BitcoinSignPayload = { + prevOuts: PreviousOutput[]; + recipient: string; + value: number; + fee: number; + changePath: number[]; +}; + +export interface DecodeSignResponseParams { + data: Buffer; + request: SignRequest; + isGeneric: boolean; + currency?: Currency; +} + +// Align EIP712MessagePayload with Viem's TypedDataDefinition +export interface EIP712MessagePayload< + TTypedData extends TypedData | Record = TypedData, + TPrimaryType extends keyof TTypedData | 'EIP712Domain' = keyof TTypedData, +> { + types: TTypedData; + domain: TTypedData extends TypedData + ? TypedDataDefinition['domain'] + : Record; + primaryType: TPrimaryType; + message: TTypedData extends TypedData + ? TypedDataDefinition['message'] + : Record; +} diff --git a/packages/types/tsconfig.json b/packages/types/tsconfig.json new file mode 100644 index 00000000..d8636539 --- /dev/null +++ b/packages/types/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "declaration": true, + "declarationMap": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "lib": ["ES2022", "DOM"], + "module": "ES2022", + "moduleResolution": "Bundler", + "outDir": "./dist", + "resolveJsonModule": true, + "rootDir": "./src", + "skipDefaultLibCheck": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "target": "ES2022", + "types": ["node"] + }, + "exclude": ["node_modules"], + "include": ["src"] +} diff --git a/packages/types/tsup.config.ts b/packages/types/tsup.config.ts new file mode 100644 index 00000000..12a41f8d --- /dev/null +++ b/packages/types/tsup.config.ts @@ -0,0 +1,31 @@ +import { readFileSync } from 'node:fs'; +import { dirname, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { defineConfig } from 'tsup'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const pkg = JSON.parse( + readFileSync(resolve(__dirname, 'package.json'), 'utf-8'), +); + +const external = Object.keys({ + ...(pkg.dependencies ?? {}), + ...(pkg.peerDependencies ?? {}), +}); + +export default defineConfig({ + entry: ['src/index.ts'], + outDir: './dist', + format: ['esm', 'cjs'], + target: 'node20', + sourcemap: true, + clean: true, + bundle: true, + dts: true, + silent: true, + outExtension: ({ format }) => ({ + js: format === 'esm' ? '.mjs' : '.cjs', + }), + external, + tsconfig: './tsconfig.json', +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3442ba99..c63b2149 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -143,6 +143,9 @@ importers: '@gridplus/btc': specifier: workspace:* version: link:../btc + '@gridplus/types': + specifier: workspace:* + version: link:../types '@metamask/eth-sig-util': specifier: ^8.2.0 version: 8.2.0 @@ -304,6 +307,31 @@ importers: specifier: 3.2.4 version: 3.2.4(@types/debug@4.1.12)(@types/node@24.10.4)(jiti@1.21.7)(msw@2.12.7(@types/node@24.10.4)(typescript@5.9.3))(terser@5.44.1)(tsx@4.21.0) + packages/types: + dependencies: + elliptic: + specifier: 6.6.1 + version: 6.6.1 + viem: + specifier: ^2.37.8 + version: 2.43.5(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.5) + devDependencies: + '@biomejs/biome': + specifier: ^1.9.0 + version: 1.9.4 + '@types/elliptic': + specifier: ^6.4.18 + version: 6.4.18 + '@types/node': + specifier: ^24.10.4 + version: 24.10.4 + tsup: + specifier: ^8.5.0 + version: 8.5.1(@microsoft/api-extractor@7.55.2(@types/node@24.10.4))(jiti@1.21.7)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3) + typescript: + specifier: ^5.9.2 + version: 5.9.3 + packages: '@adraffy/ens-normalize@1.11.1': @@ -10720,7 +10748,7 @@ snapshots: '@scure/bip32@1.7.0': dependencies: - '@noble/curves': 1.9.1 + '@noble/curves': 1.9.7 '@noble/hashes': 1.8.0 '@scure/base': 1.2.6