From fa0674c3396ed7f1acba049bad1aaec70c20859a Mon Sep 17 00:00:00 2001 From: janniks Date: Thu, 25 Apr 2024 20:25:35 +0700 Subject: [PATCH] refactor: decrease circular deps in tx package --- packages/common/src/keys.ts | 5 +- packages/encryption/src/keys.ts | 2 +- packages/stacking/src/index.ts | 10 ++- packages/stacking/src/utils.ts | 3 +- packages/transactions/src/authorization.ts | 2 +- packages/transactions/src/cl.ts | 1 - .../transactions/src/clarity/clarityValue.ts | 3 +- .../transactions/src/clarity/deserialize.ts | 5 +- packages/transactions/src/clarity/index.ts | 49 +++-------- .../transactions/src/clarity/serialize.ts | 5 +- packages/transactions/src/clarity/types.ts | 87 +++++++++++++++++++ .../clarity/{types => values}/booleanCV.ts | 19 +--- .../src/clarity/{types => values}/bufferCV.ts | 12 +-- .../src/clarity/{types => values}/intCV.ts | 17 +--- .../src/clarity/{types => values}/listCV.ts | 10 +-- .../clarity/{types => values}/optionalCV.ts | 25 ++---- .../clarity/{types => values}/principalCV.ts | 43 +++------ .../clarity/{types => values}/responseCV.ts | 21 ++--- .../src/clarity/{types => values}/stringCV.ts | 22 ++--- .../src/clarity/{types => values}/tupleCV.ts | 14 +-- packages/transactions/src/contract-abi.ts | 3 +- packages/transactions/src/keys.ts | 6 +- packages/transactions/src/payload.ts | 3 +- .../transactions/src/postcondition-types.ts | 8 +- packages/transactions/src/signer.ts | 3 +- .../src/structuredDataSignature.ts | 4 +- packages/transactions/src/transaction.ts | 11 ++- packages/transactions/tests/abi.test.ts | 9 +- packages/transactions/tests/builder.test.ts | 2 +- packages/transactions/tests/clarity.test.ts | 5 +- packages/transactions/tests/keys.test.ts | 4 +- 31 files changed, 194 insertions(+), 219 deletions(-) create mode 100644 packages/transactions/src/clarity/types.ts rename packages/transactions/src/clarity/{types => values}/booleanCV.ts (75%) rename packages/transactions/src/clarity/{types => values}/bufferCV.ts (86%) rename packages/transactions/src/clarity/{types => values}/intCV.ts (88%) rename packages/transactions/src/clarity/{types => values}/listCV.ts (79%) rename packages/transactions/src/clarity/{types => values}/optionalCV.ts (64%) rename packages/transactions/src/clarity/{types => values}/principalCV.ts (83%) rename packages/transactions/src/clarity/{types => values}/responseCV.ts (69%) rename packages/transactions/src/clarity/{types => values}/stringCV.ts (74%) rename packages/transactions/src/clarity/{types => values}/tupleCV.ts (75%) diff --git a/packages/common/src/keys.ts b/packages/common/src/keys.ts index 78618fecd..ffa1ec5d0 100644 --- a/packages/common/src/keys.ts +++ b/packages/common/src/keys.ts @@ -1,10 +1,13 @@ import { hexToBytes } from './utils'; +export type PrivateKey = string | Uint8Array; +export type PublicKey = string | Uint8Array; + /** * @private * @ignore */ -export function privateKeyToBytes(privateKey: string | Uint8Array): Uint8Array { +export function privateKeyToBytes(privateKey: PrivateKey): Uint8Array { const privateKeyBuffer = typeof privateKey === 'string' ? hexToBytes(privateKey) : privateKey; if (privateKeyBuffer.length != 32 && privateKeyBuffer.length != 33) { diff --git a/packages/encryption/src/keys.ts b/packages/encryption/src/keys.ts index 2f0a1e28a..1b59c7805 100644 --- a/packages/encryption/src/keys.ts +++ b/packages/encryption/src/keys.ts @@ -3,6 +3,7 @@ import { sha256 } from '@noble/hashes/sha256'; import { getPublicKey as nobleGetPublicKey, signSync, utils } from '@noble/secp256k1'; import { PRIVATE_KEY_COMPRESSED_LENGTH, + PrivateKey, bytesToHex, concatBytes, hexToBytes, @@ -10,7 +11,6 @@ import { readUInt8, } from '@stacks/common'; import base58 from 'bs58'; -import { PrivateKey } from '../../transactions/src'; import { hashRipemd160 } from './hashRipemd160'; import { hashSha256Sync } from './sha2Hash'; diff --git a/packages/stacking/src/index.ts b/packages/stacking/src/index.ts index 43225b899..202ae7425 100644 --- a/packages/stacking/src/index.ts +++ b/packages/stacking/src/index.ts @@ -5,7 +5,14 @@ import { StacksNodeApi, V2PoxInfoResponse, } from '@stacks/api'; -import { ApiOpts, IntegerType, hexToBytes, intToBigInt, isInstance } from '@stacks/common'; +import { + ApiOpts, + IntegerType, + PrivateKey, + hexToBytes, + intToBigInt, + isInstance, +} from '@stacks/common'; import { StacksNetwork } from '@stacks/network'; import { BurnchainRewardListResponse, @@ -21,7 +28,6 @@ import { ContractCallPayload, OptionalCV, PrincipalCV, - PrivateKey, ResponseErrorCV, StacksTransaction, TupleCV, diff --git a/packages/stacking/src/utils.ts b/packages/stacking/src/utils.ts index 0bf8f0667..3a643f810 100644 --- a/packages/stacking/src/utils.ts +++ b/packages/stacking/src/utils.ts @@ -1,6 +1,6 @@ import { sha256 } from '@noble/hashes/sha256'; import { bech32, bech32m } from '@scure/base'; -import { IntegerType, bigIntToBytes } from '@stacks/common'; +import { IntegerType, PrivateKey, bigIntToBytes } from '@stacks/common'; import { base58CheckDecode, base58CheckEncode, @@ -12,7 +12,6 @@ import { ClarityType, ClarityValue, OptionalCV, - PrivateKey, TupleCV, bufferCV, encodeStructuredData, diff --git a/packages/transactions/src/authorization.ts b/packages/transactions/src/authorization.ts index 77f13054c..b4413e370 100644 --- a/packages/transactions/src/authorization.ts +++ b/packages/transactions/src/authorization.ts @@ -5,6 +5,7 @@ import { IntegerType, intToBigInt, intToBytes, + PrivateKey, writeUInt16BE, } from '@stacks/common'; import { @@ -22,7 +23,6 @@ import { MessageSignature } from './common'; import { DeserializationError, SigningError, VerificationError } from './errors'; import { createStacksPublicKey, - PrivateKey, privateKeyToPublic, publicKeyFromSignatureVrs, publicKeyIsCompressed, diff --git a/packages/transactions/src/cl.ts b/packages/transactions/src/cl.ts index c326f9cee..1e320f566 100644 --- a/packages/transactions/src/cl.ts +++ b/packages/transactions/src/cl.ts @@ -17,7 +17,6 @@ import { tupleCV, uintCV, } from './clarity'; - export { prettyPrint } from './clarity/prettyPrint'; // todo: https://github.com/hirosystems/clarinet/issues/786 diff --git a/packages/transactions/src/clarity/clarityValue.ts b/packages/transactions/src/clarity/clarityValue.ts index 1731de610..f025c1828 100644 --- a/packages/transactions/src/clarity/clarityValue.ts +++ b/packages/transactions/src/clarity/clarityValue.ts @@ -15,9 +15,8 @@ import { SomeCV, TrueCV, FalseCV, + principalToString, } from '.'; - -import { principalToString } from './types/principalCV'; import { ClarityType } from './constants'; import { asciiToBytes, bytesToAscii, bytesToHex, utf8ToBytes } from '@stacks/common'; diff --git a/packages/transactions/src/clarity/deserialize.ts b/packages/transactions/src/clarity/deserialize.ts index 4d3720380..4700483e2 100644 --- a/packages/transactions/src/clarity/deserialize.ts +++ b/packages/transactions/src/clarity/deserialize.ts @@ -12,13 +12,14 @@ import { responseErrorCV, noneCV, someCV, - listCV, + stringAsciiCV, + stringUtf8CV, tupleCV, + listCV, } from '.'; import { BytesReader as BytesReader } from '../bytesReader'; import { deserializeAddressBytes, deserializeLPStringBytes } from '../types'; import { DeserializationError } from '../errors'; -import { stringAsciiCV, stringUtf8CV } from './types/stringCV'; import { bytesToAscii, bytesToUtf8, hexToBytes } from '@stacks/common'; /** diff --git a/packages/transactions/src/clarity/index.ts b/packages/transactions/src/clarity/index.ts index 48c7eb9a0..4471957fa 100644 --- a/packages/transactions/src/clarity/index.ts +++ b/packages/transactions/src/clarity/index.ts @@ -2,48 +2,25 @@ export { ClarityValue, - getCVTypeString, - cvToString, cvToJSON, + cvToString, cvToValue, + getCVTypeString, isClarityType, } from './clarityValue'; export * from './constants'; -export { BooleanCV, TrueCV, FalseCV, trueCV, falseCV, boolCV } from './types/booleanCV'; -export { IntCV, UIntCV, intCV, uintCV } from './types/intCV'; -export { BufferCV, bufferCV, bufferCVFromString } from './types/bufferCV'; -export { OptionalCV, NoneCV, SomeCV, noneCV, someCV, optionalCVOf } from './types/optionalCV'; - -export { - ResponseCV, - ResponseOkCV, - ResponseErrorCV, - responseOkCV, - responseErrorCV, -} from './types/responseCV'; -export { - StandardPrincipalCV, - ContractPrincipalCV, - standardPrincipalCV, - contractPrincipalCV, - standardPrincipalCVFromAddress, - contractPrincipalCVFromAddress, - PrincipalCV, - contractPrincipalCVFromStandard, - principalCV, - principalToString, -} from './types/principalCV'; +export * from './values/booleanCV'; +export * from './values/bufferCV'; +export * from './values/intCV'; +export * from './values/listCV'; +export * from './values/optionalCV'; +export * from './values/principalCV'; +export * from './values/responseCV'; +export * from './values/stringCV'; +export * from './values/tupleCV'; -export { ListCV, listCV } from './types/listCV'; -export { TupleCV, tupleCV } from './types/tupleCV'; -export { - StringAsciiCV, - StringUtf8CV, - stringUtf8CV, - stringAsciiCV, - stringCV, -} from './types/stringCV'; +export * from './types'; -export * from './serialize'; export * from './deserialize'; +export * from './serialize'; diff --git a/packages/transactions/src/clarity/serialize.ts b/packages/transactions/src/clarity/serialize.ts index 26759a59e..ac9019dc9 100644 --- a/packages/transactions/src/clarity/serialize.ts +++ b/packages/transactions/src/clarity/serialize.ts @@ -19,15 +19,12 @@ import { StandardPrincipalCV, ContractPrincipalCV, ResponseCV, - ListCV, - TupleCV, ClarityValue, } from '.'; import { ClarityType, clarityTypeToByte } from './constants'; - import { SerializationError } from '../errors'; -import { StringAsciiCV, StringUtf8CV } from './types/stringCV'; import { CLARITY_INT_BYTE_SIZE, CLARITY_INT_SIZE } from '../constants'; +import { ListCV, StringAsciiCV, StringUtf8CV, TupleCV } from './types'; function bytesWithTypeID(typeId: ClarityType, bytes: Uint8Array): Uint8Array { return concatArray([clarityTypeToByte(typeId), bytes]); diff --git a/packages/transactions/src/clarity/types.ts b/packages/transactions/src/clarity/types.ts new file mode 100644 index 000000000..8696e186a --- /dev/null +++ b/packages/transactions/src/clarity/types.ts @@ -0,0 +1,87 @@ +import { Address } from '../common'; +import { LengthPrefixedString } from '../postcondition-types'; +import { ClarityValue } from './clarityValue'; +import { ClarityType } from './constants'; + +export type BooleanCV = TrueCV | FalseCV; + +export interface TrueCV { + type: ClarityType.BoolTrue; +} + +export interface FalseCV { + type: ClarityType.BoolFalse; +} + +export interface BufferCV { + readonly type: ClarityType.Buffer; + readonly buffer: Uint8Array; +} + +export interface IntCV { + readonly type: ClarityType.Int; + readonly value: bigint; +} + +export interface UIntCV { + readonly type: ClarityType.UInt; + readonly value: bigint; +} + +export interface ListCV { + type: ClarityType.List; + list: T[]; +} + +export type OptionalCV = NoneCV | SomeCV; + +export interface NoneCV { + readonly type: ClarityType.OptionalNone; +} + +export interface SomeCV { + readonly type: ClarityType.OptionalSome; + readonly value: T; +} + +export type PrincipalCV = StandardPrincipalCV | ContractPrincipalCV; + +export interface StandardPrincipalCV { + readonly type: ClarityType.PrincipalStandard; + readonly address: Address; +} + +export interface ContractPrincipalCV { + readonly type: ClarityType.PrincipalContract; + readonly address: Address; + readonly contractName: LengthPrefixedString; +} + +export type ResponseCV = ResponseErrorCV | ResponseOkCV; + +export interface ResponseErrorCV { + readonly type: ClarityType.ResponseErr; + readonly value: T; +} + +export interface ResponseOkCV { + readonly type: ClarityType.ResponseOk; + readonly value: T; +} + +export interface StringAsciiCV { + readonly type: ClarityType.StringASCII; + readonly data: string; +} + +export interface StringUtf8CV { + readonly type: ClarityType.StringUTF8; + readonly data: string; +} + +export type TupleData = { [key: string]: T }; + +export interface TupleCV { + type: ClarityType.Tuple; + data: T; +} diff --git a/packages/transactions/src/clarity/types/booleanCV.ts b/packages/transactions/src/clarity/values/booleanCV.ts similarity index 75% rename from packages/transactions/src/clarity/types/booleanCV.ts rename to packages/transactions/src/clarity/values/booleanCV.ts index 1e535022e..71ea8b8d7 100644 --- a/packages/transactions/src/clarity/types/booleanCV.ts +++ b/packages/transactions/src/clarity/values/booleanCV.ts @@ -1,14 +1,5 @@ import { ClarityType } from '../constants'; - -type BooleanCV = TrueCV | FalseCV; - -interface TrueCV { - type: ClarityType.BoolTrue; -} - -interface FalseCV { - type: ClarityType.BoolFalse; -} +import { BooleanCV } from '../types'; /** * Converts true to BooleanCV clarity type @@ -26,7 +17,7 @@ interface FalseCV { * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -const trueCV = (): BooleanCV => ({ type: ClarityType.BoolTrue }); +export const trueCV = (): BooleanCV => ({ type: ClarityType.BoolTrue }); /** * Converts false to BooleanCV clarity type @@ -44,7 +35,7 @@ const trueCV = (): BooleanCV => ({ type: ClarityType.BoolTrue }); * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -const falseCV = (): BooleanCV => ({ type: ClarityType.BoolFalse }); +export const falseCV = (): BooleanCV => ({ type: ClarityType.BoolFalse }); /** * Converts a boolean to BooleanCV clarity type @@ -62,6 +53,4 @@ const falseCV = (): BooleanCV => ({ type: ClarityType.BoolFalse }); * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -const boolCV = (bool: boolean) => (bool ? trueCV() : falseCV()); - -export { BooleanCV, TrueCV, FalseCV, boolCV, trueCV, falseCV }; +export const boolCV = (bool: boolean) => (bool ? trueCV() : falseCV()); diff --git a/packages/transactions/src/clarity/types/bufferCV.ts b/packages/transactions/src/clarity/values/bufferCV.ts similarity index 86% rename from packages/transactions/src/clarity/types/bufferCV.ts rename to packages/transactions/src/clarity/values/bufferCV.ts index 79d3ed5e7..baa73e681 100644 --- a/packages/transactions/src/clarity/types/bufferCV.ts +++ b/packages/transactions/src/clarity/values/bufferCV.ts @@ -1,10 +1,6 @@ import { utf8ToBytes } from '@stacks/common'; import { ClarityType } from '../constants'; - -interface BufferCV { - readonly type: ClarityType.Buffer; - readonly buffer: Uint8Array; -} +import { BufferCV } from '../types'; /** * Converts a Uint8Array to a BufferCV clarity type @@ -27,7 +23,7 @@ interface BufferCV { * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -const bufferCV = (buffer: Uint8Array): BufferCV => { +export const bufferCV = (buffer: Uint8Array): BufferCV => { // max size 1024 * 1024 = 1MB; https://github.com/stacks-network/stacks-core/blob/c50a93088d7c0261f1dbe31ab24b95028a038447/clarity/src/vm/types/mod.rs#L47 if (buffer.byteLength > 1_048_576) { throw new Error('Cannot construct clarity buffer that is greater than 1MB'); @@ -57,6 +53,4 @@ const bufferCV = (buffer: Uint8Array): BufferCV => { * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -const bufferCVFromString = (str: string): BufferCV => bufferCV(utf8ToBytes(str)); - -export { BufferCV, bufferCV, bufferCVFromString }; +export const bufferCVFromString = (str: string): BufferCV => bufferCV(utf8ToBytes(str)); diff --git a/packages/transactions/src/clarity/types/intCV.ts b/packages/transactions/src/clarity/values/intCV.ts similarity index 88% rename from packages/transactions/src/clarity/types/intCV.ts rename to packages/transactions/src/clarity/values/intCV.ts index 77e6bd362..13a4752df 100644 --- a/packages/transactions/src/clarity/types/intCV.ts +++ b/packages/transactions/src/clarity/values/intCV.ts @@ -1,5 +1,6 @@ import { IntegerType, intToBigInt } from '@stacks/common'; import { ClarityType } from '../constants'; +import { IntCV, UIntCV } from '../types'; const MAX_U128 = BigInt('0xffffffffffffffffffffffffffffffff'); // (2 ** 128 - 1) const MIN_U128 = BigInt(0); @@ -7,11 +8,6 @@ const MAX_I128 = BigInt('0x7fffffffffffffffffffffffffffffff'); // (2 ** 127 - 1) // no signed (negative) hex support in bigint constructor const MIN_I128 = BigInt('-170141183460469231731687303715884105728'); // (-2 ** 127) -interface IntCV { - readonly type: ClarityType.Int; - readonly value: bigint; -} - /** * Converts IntegerType in to IntCV clarity type * @@ -30,7 +26,7 @@ interface IntCV { * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -const intCV = (value: IntegerType): IntCV => { +export const intCV = (value: IntegerType): IntCV => { const bigInt = intToBigInt(value, true); if (bigInt > MAX_I128) { throw new RangeError(`Cannot construct clarity integer from value greater than ${MAX_I128}`); @@ -40,11 +36,6 @@ const intCV = (value: IntegerType): IntCV => { return { type: ClarityType.Int, value: bigInt }; }; -interface UIntCV { - readonly type: ClarityType.UInt; - readonly value: bigint; -} - /** * Converts IntegerType in to IntCV clarity type * @@ -63,7 +54,7 @@ interface UIntCV { * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -const uintCV = (value: IntegerType): UIntCV => { +export const uintCV = (value: IntegerType): UIntCV => { const bigInt = intToBigInt(value, false); if (bigInt < MIN_U128) { throw new RangeError('Cannot construct unsigned clarity integer from negative value'); @@ -72,5 +63,3 @@ const uintCV = (value: IntegerType): UIntCV => { } return { type: ClarityType.UInt, value: bigInt }; }; - -export { IntCV, UIntCV, intCV, uintCV }; diff --git a/packages/transactions/src/clarity/types/listCV.ts b/packages/transactions/src/clarity/values/listCV.ts similarity index 79% rename from packages/transactions/src/clarity/types/listCV.ts rename to packages/transactions/src/clarity/values/listCV.ts index 8e7995086..8002aba69 100644 --- a/packages/transactions/src/clarity/types/listCV.ts +++ b/packages/transactions/src/clarity/values/listCV.ts @@ -1,10 +1,6 @@ import { ClarityValue } from '../clarityValue'; import { ClarityType } from '../constants'; - -interface ListCV { - type: ClarityType.List; - list: T[]; -} +import { ListCV } from '../types'; /** * Create list of clarity types @@ -24,8 +20,6 @@ interface ListCV { * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -function listCV(values: T[]): ListCV { +export function listCV(values: T[]): ListCV { return { type: ClarityType.List, list: values }; } - -export { ListCV, listCV }; diff --git a/packages/transactions/src/clarity/types/optionalCV.ts b/packages/transactions/src/clarity/values/optionalCV.ts similarity index 64% rename from packages/transactions/src/clarity/types/optionalCV.ts rename to packages/transactions/src/clarity/values/optionalCV.ts index d7a6ba539..1e9c59a73 100644 --- a/packages/transactions/src/clarity/types/optionalCV.ts +++ b/packages/transactions/src/clarity/values/optionalCV.ts @@ -1,15 +1,6 @@ import { ClarityValue } from '../clarityValue'; import { ClarityType } from '../constants'; -type OptionalCV = NoneCV | SomeCV; - -interface NoneCV { - readonly type: ClarityType.OptionalNone; -} - -interface SomeCV { - readonly type: ClarityType.OptionalSome; - readonly value: T; -} +import { NoneCV, OptionalCV } from '../types'; /** * Create a null clarity type @@ -27,7 +18,7 @@ interface SomeCV { * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -function noneCV(): NoneCV { +export function noneCV(): NoneCV { return { type: ClarityType.OptionalNone }; } @@ -49,16 +40,10 @@ function noneCV(): NoneCV { * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -function someCV(value: T): OptionalCV { +export function someCV(value: T): OptionalCV { return { type: ClarityType.OptionalSome, value }; } -function optionalCVOf(value?: T): OptionalCV { - if (value) { - return someCV(value); - } else { - return noneCV(); - } +export function optionalCVOf(value?: T): OptionalCV { + return value ? someCV(value) : noneCV(); } - -export { OptionalCV, NoneCV, SomeCV, noneCV, someCV, optionalCVOf }; diff --git a/packages/transactions/src/clarity/types/principalCV.ts b/packages/transactions/src/clarity/values/principalCV.ts similarity index 83% rename from packages/transactions/src/clarity/types/principalCV.ts rename to packages/transactions/src/clarity/values/principalCV.ts index b0c8233e6..cb9728ee7 100644 --- a/packages/transactions/src/clarity/types/principalCV.ts +++ b/packages/transactions/src/clarity/values/principalCV.ts @@ -2,21 +2,10 @@ import { utf8ToBytes } from '@stacks/common'; import { Address, addressToString } from '../../common'; import { LengthPrefixedString, createAddress, createLPString } from '../../postcondition-types'; import { ClarityType } from '../constants'; +import { ContractPrincipalCV, PrincipalCV, StandardPrincipalCV } from '../types'; -type PrincipalCV = StandardPrincipalCV | ContractPrincipalCV; - -interface StandardPrincipalCV { - readonly type: ClarityType.PrincipalStandard; - readonly address: Address; -} - -interface ContractPrincipalCV { - readonly type: ClarityType.PrincipalContract; - readonly address: Address; - readonly contractName: LengthPrefixedString; -} /** Returns a string in the format `address` or `address.contract-name` from a principal (standard or contract) */ -function principalToString(principal: PrincipalCV): string { +export function principalToString(principal: PrincipalCV): string { if (principal.type === ClarityType.PrincipalStandard) { return addressToString(principal.address); } else if (principal.type === ClarityType.PrincipalContract) { @@ -27,7 +16,7 @@ function principalToString(principal: PrincipalCV): string { } } -function principalCV(principal: string): PrincipalCV { +export function principalCV(principal: string): PrincipalCV { if (principal.includes('.')) { const [address, contractName] = principal.split('.'); return contractPrincipalCV(address, contractName); @@ -52,7 +41,7 @@ function principalCV(principal: string): PrincipalCV { * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -function standardPrincipalCV(addressString: string): StandardPrincipalCV { +export function standardPrincipalCV(addressString: string): StandardPrincipalCV { const addr = createAddress(addressString); return { type: ClarityType.PrincipalStandard, address: addr }; } @@ -79,7 +68,7 @@ function standardPrincipalCV(addressString: string): StandardPrincipalCV { * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -function standardPrincipalCVFromAddress(address: Address): StandardPrincipalCV { +export function standardPrincipalCVFromAddress(address: Address): StandardPrincipalCV { return { type: ClarityType.PrincipalStandard, address }; } @@ -100,7 +89,10 @@ function standardPrincipalCVFromAddress(address: Address): StandardPrincipalCV { * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -function contractPrincipalCV(addressString: string, contractName: string): ContractPrincipalCV { +export function contractPrincipalCV( + addressString: string, + contractName: string +): ContractPrincipalCV { const addr = createAddress(addressString); const lengthPrefixedContractName = createLPString(contractName); return contractPrincipalCVFromAddress(addr, lengthPrefixedContractName); @@ -124,7 +116,7 @@ function contractPrincipalCV(addressString: string, contractName: string): Contr * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -function contractPrincipalCVFromAddress( +export function contractPrincipalCVFromAddress( address: Address, contractName: LengthPrefixedString ): ContractPrincipalCV { @@ -134,7 +126,7 @@ function contractPrincipalCVFromAddress( return { type: ClarityType.PrincipalContract, address, contractName }; } -function contractPrincipalCVFromStandard( +export function contractPrincipalCVFromStandard( sp: StandardPrincipalCV, contractName: string ): ContractPrincipalCV { @@ -145,16 +137,3 @@ function contractPrincipalCVFromStandard( contractName: lengthPrefixedContractName, }; } - -export { - PrincipalCV, - StandardPrincipalCV, - ContractPrincipalCV, - principalCV, - principalToString, - standardPrincipalCV, - standardPrincipalCVFromAddress, - contractPrincipalCV, - contractPrincipalCVFromAddress, - contractPrincipalCVFromStandard, -}; diff --git a/packages/transactions/src/clarity/types/responseCV.ts b/packages/transactions/src/clarity/values/responseCV.ts similarity index 69% rename from packages/transactions/src/clarity/types/responseCV.ts rename to packages/transactions/src/clarity/values/responseCV.ts index 3340e120b..e99ab3ea7 100644 --- a/packages/transactions/src/clarity/types/responseCV.ts +++ b/packages/transactions/src/clarity/values/responseCV.ts @@ -1,17 +1,6 @@ import { ClarityValue } from '../clarityValue'; import { ClarityType } from '../constants'; - -type ResponseCV = ResponseErrorCV | ResponseOkCV; - -interface ResponseErrorCV { - readonly type: ClarityType.ResponseErr; - readonly value: T; -} - -interface ResponseOkCV { - readonly type: ClarityType.ResponseOk; - readonly value: T; -} +import { ResponseErrorCV, ResponseOkCV } from '../types'; /** * Converts ClarityValue to responseErrorCV @@ -32,7 +21,9 @@ interface ResponseOkCV { * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -function responseErrorCV(value: T): ResponseErrorCV { +export function responseErrorCV( + value: T +): ResponseErrorCV { return { type: ClarityType.ResponseErr, value }; } @@ -55,8 +46,6 @@ function responseErrorCV(value: T): Respo * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -function responseOkCV(value: T): ResponseOkCV { +export function responseOkCV(value: T): ResponseOkCV { return { type: ClarityType.ResponseOk, value }; } - -export { ResponseCV, ResponseErrorCV, ResponseOkCV, responseErrorCV, responseOkCV }; diff --git a/packages/transactions/src/clarity/types/stringCV.ts b/packages/transactions/src/clarity/values/stringCV.ts similarity index 74% rename from packages/transactions/src/clarity/types/stringCV.ts rename to packages/transactions/src/clarity/values/stringCV.ts index c098c6f61..60c38b2aa 100644 --- a/packages/transactions/src/clarity/types/stringCV.ts +++ b/packages/transactions/src/clarity/values/stringCV.ts @@ -1,14 +1,5 @@ import { ClarityType } from '../constants'; - -interface StringAsciiCV { - readonly type: ClarityType.StringASCII; - readonly data: string; -} - -interface StringUtf8CV { - readonly type: ClarityType.StringUTF8; - readonly data: string; -} +import { StringAsciiCV, StringUtf8CV } from '../types'; /** * Converts ClarityValue to stringAsciiCV @@ -29,7 +20,7 @@ interface StringUtf8CV { * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -const stringAsciiCV = (data: string): StringAsciiCV => { +export const stringAsciiCV = (data: string): StringAsciiCV => { return { type: ClarityType.StringASCII, data }; }; @@ -52,14 +43,17 @@ const stringAsciiCV = (data: string): StringAsciiCV => { * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -const stringUtf8CV = (data: string): StringUtf8CV => { +export const stringUtf8CV = (data: string): StringUtf8CV => { return { type: ClarityType.StringUTF8, data }; }; /** * @ignore */ -const stringCV = (data: string, encoding: 'ascii' | 'utf8'): StringAsciiCV | StringUtf8CV => { +export const stringCV = ( + data: string, + encoding: 'ascii' | 'utf8' +): StringAsciiCV | StringUtf8CV => { switch (encoding) { case 'ascii': return stringAsciiCV(data); @@ -67,5 +61,3 @@ const stringCV = (data: string, encoding: 'ascii' | 'utf8'): StringAsciiCV | Str return stringUtf8CV(data); } }; - -export { StringAsciiCV, StringUtf8CV, stringAsciiCV, stringUtf8CV, stringCV }; diff --git a/packages/transactions/src/clarity/types/tupleCV.ts b/packages/transactions/src/clarity/values/tupleCV.ts similarity index 75% rename from packages/transactions/src/clarity/types/tupleCV.ts rename to packages/transactions/src/clarity/values/tupleCV.ts index 9dd55a9f1..1e393966e 100644 --- a/packages/transactions/src/clarity/types/tupleCV.ts +++ b/packages/transactions/src/clarity/values/tupleCV.ts @@ -1,13 +1,7 @@ import { ClarityValue } from '../clarityValue'; import { ClarityType } from '../constants'; import { isClarityName } from '../../utils'; - -type TupleData = { [key: string]: T }; - -interface TupleCV { - type: ClarityType.Tuple; - data: T; -} +import { TupleCV, TupleData } from '../types'; /** * Create tuple of clarity values @@ -31,7 +25,9 @@ interface TupleCV { * @see * {@link https://github.com/hirosystems/stacks.js/blob/main/packages/transactions/tests/clarity.test.ts | clarity test cases for more examples} */ -function tupleCV(data: TupleData): TupleCV> { +export function tupleCV( + data: TupleData +): TupleCV> { for (const key in data) { if (!isClarityName(key)) { throw new Error(`"${key}" is not a valid Clarity name`); @@ -40,5 +36,3 @@ function tupleCV(data: TupleData): Tup return { type: ClarityType.Tuple, data }; } - -export { TupleCV, tupleCV }; diff --git a/packages/transactions/src/contract-abi.ts b/packages/transactions/src/contract-abi.ts index 3bc014277..ff1b3b8ee 100644 --- a/packages/transactions/src/contract-abi.ts +++ b/packages/transactions/src/contract-abi.ts @@ -12,10 +12,11 @@ import { ClarityType, getCVTypeString, bufferCVFromString, + stringAsciiCV, + stringUtf8CV, } from './clarity'; import { ContractCallPayload } from './payload'; import { NotImplementedError } from './errors'; -import { stringAsciiCV, stringUtf8CV } from './clarity/types/stringCV'; import { utf8ToBytes } from '@stacks/common'; // From https://github.com/blockstack/stacks-blockchain-sidecar/blob/master/src/event-stream/contract-abi.ts diff --git a/packages/transactions/src/keys.ts b/packages/transactions/src/keys.ts index d29a52268..48b4d38a0 100644 --- a/packages/transactions/src/keys.ts +++ b/packages/transactions/src/keys.ts @@ -16,7 +16,9 @@ import { isInstance, parseRecoverableSignatureVrs, PRIVATE_KEY_COMPRESSED_LENGTH, + PrivateKey, privateKeyToBytes, + PublicKey, signatureRsvToVrs, signatureVrsToRsv, } from '@stacks/common'; @@ -171,10 +173,6 @@ export function makeRandomPrivKey(): string { return bytesToHex(utils.randomPrivateKey()); } -// todo: complete refactor -export type PrivateKey = string | Uint8Array; -export type PublicKey = string | Uint8Array; - /** * @deprecated The Clarity compatible {@link signMessageHashRsv} is preferred, but differs in signature format * @returns A recoverable signature (in VRS order) diff --git a/packages/transactions/src/payload.ts b/packages/transactions/src/payload.ts index 2bed34f36..5a2a6f6fb 100644 --- a/packages/transactions/src/payload.ts +++ b/packages/transactions/src/payload.ts @@ -16,10 +16,10 @@ import { deserializeCV, noneCV, OptionalCV, + principalCV, serializeCVBytes, someCV, } from './clarity/'; -import { PrincipalCV, principalCV } from './clarity/types/principalCV'; import { Address } from './common'; import { ClarityVersion, @@ -38,6 +38,7 @@ import { MemoString, serializeStacksMessageBytes, } from './types'; +import { PrincipalCV } from './clarity/types'; export type Payload = | TokenTransferPayload diff --git a/packages/transactions/src/postcondition-types.ts b/packages/transactions/src/postcondition-types.ts index 9421d7323..bc994df5e 100644 --- a/packages/transactions/src/postcondition-types.ts +++ b/packages/transactions/src/postcondition-types.ts @@ -81,6 +81,10 @@ export interface NonFungiblePostCondition { readonly assetName: ClarityValue; } +export type PostCondition = STXPostCondition | FungiblePostCondition | NonFungiblePostCondition; + +export type PostConditionPrincipal = StandardPrincipal | ContractPrincipal; + export function parseAssetString(id: AssetString): Asset { const [assetAddress, assetContractName, assetTokenName] = id.split(/\.|::/); const asset = createAsset(assetAddress, assetContractName, assetTokenName); @@ -169,7 +173,3 @@ export function createStandardPrincipal(addressString: string): StandardPrincipa address: addr, }; } - -export type PostCondition = STXPostCondition | FungiblePostCondition | NonFungiblePostCondition; - -export type PostConditionPrincipal = StandardPrincipal | ContractPrincipal; diff --git a/packages/transactions/src/signer.ts b/packages/transactions/src/signer.ts index ea5f960a0..a5cee7f13 100644 --- a/packages/transactions/src/signer.ts +++ b/packages/transactions/src/signer.ts @@ -3,8 +3,9 @@ import { StacksTransaction } from './transaction'; import { SpendingConditionOpts, isSingleSig, nextVerification } from './authorization'; import { AuthType, PubKeyEncoding, StacksMessageType } from './constants'; import { SigningError } from './errors'; -import { PrivateKey, StacksPublicKey } from './keys'; +import { StacksPublicKey } from './keys'; import { cloneDeep } from './utils'; +import { PrivateKey } from '@stacks/common'; export class TransactionSigner { transaction: StacksTransaction; diff --git a/packages/transactions/src/structuredDataSignature.ts b/packages/transactions/src/structuredDataSignature.ts index 998b3b54a..9d36d4ac8 100644 --- a/packages/transactions/src/structuredDataSignature.ts +++ b/packages/transactions/src/structuredDataSignature.ts @@ -1,9 +1,9 @@ import { sha256 } from '@noble/hashes/sha256'; -import { bytesToHex, concatBytes, utf8ToBytes } from '@stacks/common'; +import { PrivateKey, bytesToHex, concatBytes, utf8ToBytes } from '@stacks/common'; import { ClarityType, ClarityValue, serializeCVBytes } from './clarity'; import { StacksMessageType } from './constants'; import { StructuredDataSignature } from './message-types'; -import { PrivateKey, signMessageHashRsv } from './keys'; +import { signMessageHashRsv } from './keys'; // Refer to SIP018 https://github.com/stacksgov/sips/ // > asciiToBytes('SIP018') diff --git a/packages/transactions/src/transaction.ts b/packages/transactions/src/transaction.ts index 62ea6ec0b..ccca1e438 100644 --- a/packages/transactions/src/transaction.ts +++ b/packages/transactions/src/transaction.ts @@ -1,4 +1,11 @@ -import { concatArray, hexToBytes, IntegerType, intToBigInt, writeUInt32BE } from '@stacks/common'; +import { + concatArray, + hexToBytes, + IntegerType, + intToBigInt, + PrivateKey, + writeUInt32BE, +} from '@stacks/common'; import { ChainId, DEFAULT_CHAIN_ID, @@ -36,7 +43,7 @@ import { StacksMessageType, } from './constants'; import { SerializationError, SigningError } from './errors'; -import { PrivateKey, privateKeyIsCompressed, publicKeyIsCompressed, StacksPublicKey } from './keys'; +import { privateKeyIsCompressed, publicKeyIsCompressed, StacksPublicKey } from './keys'; import { deserializePayloadBytes, Payload, PayloadInput, serializePayloadBytes } from './payload'; import { createTransactionAuthField } from './signature'; import { diff --git a/packages/transactions/tests/abi.test.ts b/packages/transactions/tests/abi.test.ts index ff0ca3a64..8c2940328 100644 --- a/packages/transactions/tests/abi.test.ts +++ b/packages/transactions/tests/abi.test.ts @@ -1,7 +1,6 @@ +import { utf8ToBytes } from '@stacks/common'; import { readFileSync } from 'fs'; import path from 'path'; -import { createContractCallPayload } from '../src/payload'; - import { bufferCVFromString, contractPrincipalCV, @@ -19,16 +18,14 @@ import { tupleCV, uintCV, } from '../src/clarity'; - import { - abiFunctionToString, ClarityAbi, ClarityAbiType, + abiFunctionToString, parseToCV, validateContractCall, } from '../src/contract-abi'; - -import { utf8ToBytes } from '@stacks/common'; +import { createContractCallPayload } from '../src/payload'; const TEST_ABI: ClarityAbi = JSON.parse( readFileSync(path.join(__dirname, './abi/test-abi.json')).toString() diff --git a/packages/transactions/tests/builder.test.ts b/packages/transactions/tests/builder.test.ts index 9363c2dd9..c5d36a175 100644 --- a/packages/transactions/tests/builder.test.ts +++ b/packages/transactions/tests/builder.test.ts @@ -71,12 +71,12 @@ import { bufferCV, bufferCVFromString, noneCV, + principalCV, serializeCV, serializeCVBytes, standardPrincipalCV, uintCV, } from '../src/clarity'; -import { principalCV } from '../src/clarity/types/principalCV'; import { createMessageSignature } from '../src/common'; import { AddressHashMode, diff --git a/packages/transactions/tests/clarity.test.ts b/packages/transactions/tests/clarity.test.ts index d4a89b3f2..96410d145 100644 --- a/packages/transactions/tests/clarity.test.ts +++ b/packages/transactions/tests/clarity.test.ts @@ -8,12 +8,8 @@ import { ClarityValue, ClarityWireType, IntCV, - ListCV, SomeCV, StandardPrincipalCV, - StringAsciiCV, - StringUtf8CV, - TupleCV, UIntCV, bufferCV, clarityByteToType, @@ -47,6 +43,7 @@ import { } from '../src/clarity/clarityValue'; import { addressToString } from '../src/common'; import { deserializeAddressBytes } from '../src/types'; +import { ListCV, StringAsciiCV, StringUtf8CV, TupleCV } from '../src/clarity/types'; const ADDRESS = 'SP2JXKMSH007NPYAQHKJPQMAQYAD90NQGTVJVQ02B'; diff --git a/packages/transactions/tests/keys.test.ts b/packages/transactions/tests/keys.test.ts index d47d222d8..478e43848 100644 --- a/packages/transactions/tests/keys.test.ts +++ b/packages/transactions/tests/keys.test.ts @@ -13,13 +13,14 @@ import { signatureRsvToVrs, utf8ToBytes, } from '@stacks/common'; +import { TransactionVersion } from '@stacks/network'; import { ec as EC } from 'elliptic'; import { PubKeyEncoding, StacksMessageType, compressPublicKey, - encodeStructuredData, createStacksPublicKey, + encodeStructuredData, getAddressFromPrivateKey, getAddressFromPublicKey, makeRandomPrivKey, @@ -37,7 +38,6 @@ import { } from '../src'; import { randomBytes } from '../src/utils'; import { serializeDeserialize } from './macros'; -import { TransactionVersion } from '@stacks/network'; // Create and initialize EC context // Better do it once and reuse it