@leather.io/stacks 1.6.2 → 1.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # @leather.io/stacks
2
+
3
+ `@leather.io/stacks` is intended to be the home of domain logic relating to the Stacks blockchain operations, such as address generation, and transaction signing.
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import { PrivateKey } from '@stacks/common';
2
2
  import * as _stacks_transactions from '@stacks/transactions';
3
3
  import { ClarityValue, StacksTransactionWire, AssetString, UnsignedContractCallOptions, UnsignedContractDeployOptions, UnsignedTokenTransferOptions, PostConditionWire, PostCondition } from '@stacks/transactions';
4
4
  import { Signer } from '@leather.io/crypto';
5
- import { NetworkModes, ReplaceTypes, Money, ChainId as ChainId$1 } from '@leather.io/models';
5
+ import { NetworkModes, ReplaceTypes, Money, TransactionErrorKey, ChainId as ChainId$1 } from '@leather.io/models';
6
6
  import { HDKey } from '@scure/bip32';
7
7
  import { ChainId } from '@stacks/network';
8
8
  import BigNumber from 'bignumber.js';
@@ -135,7 +135,6 @@ declare function ensurePostConditionWireFormat(postCondition: string | PostCondi
135
135
  declare function getPostCondition(postCondition: string | PostCondition | PostConditionWire): PostConditionWire;
136
136
  declare function getPostConditions(postConditions?: (string | PostCondition | PostConditionWire)[]): PostConditionWire[] | undefined;
137
137
 
138
- type TransactionErrorKey = 'InvalidAddress' | 'InsufficientFunds' | 'InvalidNetworkAddress';
139
138
  type StacksErrorKey = TransactionErrorKey | 'InvalidSameAddress';
140
139
  declare class StacksError extends Error {
141
140
  message: StacksErrorKey;
@@ -146,6 +145,12 @@ declare function isValidStacksAddress(address: string): boolean;
146
145
  declare function isValidAddressChain(address: string, chainId: ChainId$1): boolean;
147
146
  declare function validatePayerNotRecipient(senderAddress: string, recipientAddress: string): boolean;
148
147
 
149
- declare function isValidStacksTransaction(senderAddress: string, recipientAddress: string, chainId: ChainId$1): void;
148
+ interface StacksTransaction {
149
+ amount: Money;
150
+ payer: string;
151
+ recipient: string;
152
+ chainId: ChainId$1;
153
+ }
154
+ declare function isValidStacksTransaction({ payer, recipient, chainId }: StacksTransaction): void;
150
155
 
151
156
  export { StacksError, type StacksErrorKey, type StacksSigner, type StacksSignerFn, type StacksUnsignedContractCallOptions, type StacksUnsignedContractDeployOptions, type StacksUnsignedTokenTransferOptions, type StacksUnsignedTransactionOptions, TEST_ACCOUNT_1_STX_ADDRESS, TEST_ACCOUNT_1_STX_ADDRESS_SM, TEST_ACCOUNT_2_STX_ADDRESS, TEST_TESTNET_ACCOUNT_2_STX_ADDRESS, TEST_TESTNET_ACCOUNT_2_STX_ADDRESS_SN, TransactionTypes, cleanHex, createSignFnFromMnemonic, deriveStxPrivateKey, deriveStxPublicKey, ensurePostConditionWireFormat, extractStacksDerivationPathAccountIndex, formatAssetString, formatContractId, generateStacksUnsignedTransaction, generateUnsignedContractCall, generateUnsignedContractDeploy, generateUnsignedStxTokenTransfer, getPostCondition, getPostConditionFromString, getPostConditions, getPrincipalFromAssetString, getStacksAssetStringParts, getStacksBurnAddress, getStacksContractAssetName, getStacksContractName, initNonce, initalizeStacksSigner, isTransactionTypeSupported, isValidAddressChain, isValidStacksAddress, isValidStacksTransaction, makeAccountIndexDerivationPathFactory, makeStxDerivationPath, signMessage, signStacksTransaction, signStructuredDataMessage, stacksChainIdToCoreNetworkMode, stacksRootKeychainToAccountDescriptor, stxDerivationWithAccount, validatePayerNotRecipient, whenStacksChainId };
package/dist/index.js CHANGED
@@ -331,14 +331,14 @@ function validatePayerNotRecipient(senderAddress, recipientAddress) {
331
331
  }
332
332
 
333
333
  // src/validation/transaction-validation.ts
334
- function isValidStacksTransaction(senderAddress, recipientAddress, chainId) {
335
- if (!isValidStacksAddress(senderAddress) || !isValidStacksAddress(recipientAddress)) {
334
+ function isValidStacksTransaction({ payer, recipient, chainId }) {
335
+ if (!isValidStacksAddress(payer) || !isValidStacksAddress(recipient)) {
336
336
  throw new StacksError("InvalidAddress");
337
337
  }
338
- if (!isValidAddressChain(senderAddress, chainId) || !isValidAddressChain(recipientAddress, chainId)) {
338
+ if (!isValidAddressChain(payer, chainId) || !isValidAddressChain(recipient, chainId)) {
339
339
  throw new StacksError("InvalidNetworkAddress");
340
340
  }
341
- if (!validatePayerNotRecipient(senderAddress, recipientAddress)) {
341
+ if (!validatePayerNotRecipient(payer, recipient)) {
342
342
  throw new StacksError("InvalidSameAddress");
343
343
  }
344
344
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/message-signing.ts","../src/mocks/mocks.ts","../src/signer/signer.ts","../src/stacks.utils.ts","../src/transactions/generate-unsigned-transaction.ts","../src/transactions/post-condition.utils.ts","../src/transactions/transaction.types.ts","../src/validation/stacks-error.ts","../src/validation/address-validation.ts","../src/validation/transaction-validation.ts"],"sourcesContent":["import { bytesToHex } from '@noble/hashes/utils';\nimport { PrivateKey } from '@stacks/common';\nimport { hashMessage } from '@stacks/encryption';\nimport {\n ClarityValue,\n privateKeyToPublic,\n signMessageHashRsv,\n signStructuredData,\n} from '@stacks/transactions';\n\ninterface SignatureData {\n signature: string;\n publicKey: string;\n}\nexport function signMessage(message: string, privateKey: PrivateKey): SignatureData {\n const hash = hashMessage(message);\n return {\n signature: signMessageHashRsv({ privateKey, messageHash: bytesToHex(hash) }),\n publicKey: privateKeyToPublic(privateKey) as string,\n };\n}\n\nexport function signStructuredDataMessage(\n message: ClarityValue,\n domain: ClarityValue,\n privateKey: PrivateKey\n): SignatureData {\n const signature = signStructuredData({\n message,\n domain,\n privateKey,\n });\n\n return {\n signature,\n publicKey: privateKeyToPublic(privateKey) as string,\n };\n}\n","// Stacks test addresses\nexport const TEST_ACCOUNT_1_STX_ADDRESS = 'SPS8CKF63P16J28AYF7PXW9E5AACH0NZNTEFWSFE';\nexport const TEST_ACCOUNT_2_STX_ADDRESS = 'SPXH3HNBPM5YP15VH16ZXZ9AX6CK289K3MCXRKCB';\nexport const TEST_TESTNET_ACCOUNT_2_STX_ADDRESS = 'STXH3HNBPM5YP15VH16ZXZ9AX6CK289K3NVR9T1P';\n// TODO ask about these prefixs\n// TEST_ACCOUNT_.. from extension mocks with prefix changed to SM / SN\nexport const TEST_ACCOUNT_1_STX_ADDRESS_SM = 'SM3FBR6RDNZYC5K4TZWV9VZJ6NGA4VX3YBQ8X2PQ';\nexport const TEST_TESTNET_ACCOUNT_2_STX_ADDRESS_SN = 'SNXH3HNBPM5YP15VH16ZXZ9AX6CK289K3NVR9T1P';\n","import {\n StacksTransactionWire,\n TransactionSigner,\n createStacksPublicKey,\n publicKeyToAddressSingleSig,\n} from '@stacks/transactions';\n\nimport {\n Signer,\n decomposeDescriptor,\n deriveRootKeychainFromMnemonic,\n extractKeyFromDescriptor,\n} from '@leather.io/crypto';\nimport { NetworkModes } from '@leather.io/models';\n\nimport { deriveStxPrivateKey, extractStacksDerivationPathAccountIndex } from '../stacks.utils';\n\n// Warning: mutatitive. Ideally there would be a tx.clone() method\nexport function signStacksTransaction(tx: StacksTransactionWire, privateKey: string) {\n const signer = new TransactionSigner(tx);\n signer.signOrigin(privateKey);\n return tx;\n}\n\nexport type StacksSignerFn = (tx: StacksTransactionWire) => Promise<StacksTransactionWire>;\n\nexport interface StacksSigner extends Signer {\n descriptor: string;\n keyOrigin: string;\n address: string;\n accountIndex: number;\n network: NetworkModes;\n sign: StacksSignerFn;\n}\n\nexport function createSignFnFromMnemonic(\n keyOrigin: string,\n getMnemonicFn: () => Promise<{ mnemonic: string; passphrase?: string }>\n) {\n return async (tx: StacksTransactionWire) => {\n const { mnemonic, passphrase } = await getMnemonicFn();\n const keychain = await deriveRootKeychainFromMnemonic(mnemonic, passphrase);\n const privateKey = deriveStxPrivateKey({\n keychain,\n index: extractStacksDerivationPathAccountIndex(keyOrigin),\n });\n return signStacksTransaction(tx, privateKey);\n };\n}\n\ninterface InitalizeStacksSignerArgs {\n descriptor: string;\n network: NetworkModes;\n signFn: StacksSignerFn;\n}\nexport function initalizeStacksSigner(args: InitalizeStacksSignerArgs): StacksSigner {\n const { descriptor, network, signFn } = args;\n\n const publicKey = createStacksPublicKey(extractKeyFromDescriptor(descriptor)).data;\n\n return {\n ...decomposeDescriptor(descriptor),\n // here we overwrite the accountIndex with the derivation path account index for stx\n accountIndex: extractStacksDerivationPathAccountIndex(descriptor),\n publicKey: publicKey,\n network,\n address: publicKeyToAddressSingleSig(publicKey, network),\n sign: signFn,\n };\n}\n","import { HDKey } from '@scure/bip32';\nimport { ChainId } from '@stacks/network';\nimport { AssetString, compressPrivateKey, privateKeyToPublic } from '@stacks/transactions';\n\nimport {\n DerivationPathDepth,\n createDescriptor,\n createKeyOriginPath,\n extractAddressIndexFromPath,\n} from '@leather.io/crypto';\nimport type { NetworkModes } from '@leather.io/models';\nimport { assertIsTruthy, isString, toHexString } from '@leather.io/utils';\n\nexport const stxDerivationWithAccount = `m/44'/5757'/0'/0/{account}`;\n\nexport function makeAccountIndexDerivationPathFactory(derivationPath: string) {\n return (account: number) => derivationPath.replace('{account}', account.toString());\n}\n\nexport function extractStacksDerivationPathAccountIndex(path: string) {\n if (!path.includes('5757')) throw new Error('Not a valid Stacks derivation path: ' + path);\n return extractAddressIndexFromPath(path);\n}\n\n/**\n * Stacks accounts always use the same derivation path, regardless of network\n */\nexport const makeStxDerivationPath =\n makeAccountIndexDerivationPathFactory(stxDerivationWithAccount);\n\nexport function stacksChainIdToCoreNetworkMode(chainId: ChainId): NetworkModes {\n return whenStacksChainId(chainId)({\n [ChainId.Mainnet]: 'mainnet',\n [ChainId.Testnet]: 'testnet',\n });\n}\n\ninterface WhenStacksChainIdMap<T> {\n [ChainId.Mainnet]: T;\n [ChainId.Testnet]: T;\n}\nexport function whenStacksChainId(chainId: ChainId) {\n return <T>(chainIdMap: WhenStacksChainIdMap<T>): T => chainIdMap[chainId];\n}\n\n// From `@stacks/wallet-sdk` package we are trying not to use\nexport function deriveStxPrivateKey({ keychain, index }: { keychain: HDKey; index: number }) {\n if (keychain.depth !== DerivationPathDepth.Root) throw new Error('Root keychain must be depth 0');\n const accountKeychain = keychain.derive(makeStxDerivationPath(index));\n assertIsTruthy(accountKeychain.privateKey);\n return compressPrivateKey(accountKeychain.privateKey);\n}\n\nexport function deriveStxPublicKey({\n keychain,\n index,\n}: {\n keychain: HDKey;\n index: number;\n}): string {\n return privateKeyToPublic(deriveStxPrivateKey({ keychain, index })) as string;\n}\n\nexport function stacksRootKeychainToAccountDescriptor(keychain: HDKey, accountIndex: number) {\n const fingerprint = toHexString(keychain.fingerprint);\n const publicKey = deriveStxPublicKey({ keychain, index: accountIndex });\n return createDescriptor(\n createKeyOriginPath(fingerprint, makeStxDerivationPath(accountIndex)),\n publicKey\n );\n}\n\nexport function getStacksBurnAddress(chainIdChainId: ChainId): string {\n switch (chainIdChainId) {\n case ChainId.Mainnet:\n return 'SP00000000000003SCNSJTCSE62ZF4MSE';\n case ChainId.Testnet:\n default:\n return 'ST000000000000000000002AMW42H';\n }\n}\n\nexport function cleanHex(hexWithMaybePrefix: string): string {\n if (!isString(hexWithMaybePrefix)) return hexWithMaybePrefix;\n return hexWithMaybePrefix.startsWith('0x')\n ? hexWithMaybePrefix.replace('0x', '')\n : hexWithMaybePrefix;\n}\n\nexport function getPrincipalFromAssetString(assetString: string) {\n return assetString.split('::')[0];\n}\n\nexport function formatContractId(address: string, name: string) {\n return `${address}.${name}`;\n}\n\ninterface FormatAssetStringArgs {\n contractAddress: string;\n contractName: string;\n assetName: string;\n}\nexport function formatAssetString({\n contractAddress,\n contractName,\n assetName,\n}: FormatAssetStringArgs): AssetString {\n return `${contractAddress}.${contractName}::${assetName}`;\n}\n\n/**\n * Gets the contract name.\n *\n * @param identifier - [principal].[contract-name] or [principal].[contract-name]::[asset-name]\n */\nexport function getStacksContractName(identifier: string): string {\n if (identifier.includes('.')) {\n const parts = identifier?.split('.');\n if (identifier.includes('::')) {\n return parts[1].split('::')[0];\n }\n return parts[1];\n }\n return identifier;\n}\n\n/**\n * Gets the asset name.\n *\n * @param identifier - [principal].[contract-name]::[asset-name]\n */\nexport function getStacksContractAssetName(identifier: string): string {\n if (!identifier.includes('::')) return identifier;\n return identifier.split('::')[1];\n}\n\n/**\n * Gets the parts that make up a fully qualified name of an asset.\n *\n * @param identifier - [principal].[contract-name]::[asset-name]\n */\nexport function getStacksAssetStringParts(identifier: string): {\n contractAddress: string;\n contractAssetName: string;\n contractName: string;\n} {\n if (!identifier.includes('.') || !identifier.includes('::')) {\n return {\n contractAddress: identifier,\n contractAssetName: identifier,\n contractName: identifier,\n };\n }\n\n const contractAddress = identifier.split('.')[0];\n const contractAssetName = getStacksContractAssetName(identifier);\n const contractName = getStacksContractName(identifier);\n\n return {\n contractAddress,\n contractAssetName,\n contractName,\n };\n}\n","import { hexToBytes } from '@noble/hashes/utils';\nimport {\n deserializeCV,\n makeUnsignedContractCall,\n makeUnsignedContractDeploy,\n makeUnsignedSTXTokenTransfer,\n} from '@stacks/transactions';\nimport BigNumber from 'bignumber.js';\n\nimport { assertUnreachable } from '@leather.io/utils';\n\nimport { cleanHex } from '../stacks.utils';\nimport { ensurePostConditionWireFormat, getPostConditions } from './post-condition.utils';\nimport {\n StacksUnsignedContractCallOptions,\n StacksUnsignedContractDeployOptions,\n StacksUnsignedTokenTransferOptions,\n StacksUnsignedTransactionOptions,\n TransactionTypes,\n isTransactionTypeSupported,\n} from './transaction.types';\n\nexport function initNonce(nonce: number | string) {\n return new BigNumber(nonce, 10);\n}\n\nexport function generateUnsignedContractCall(options: StacksUnsignedContractCallOptions) {\n const { fee, functionArgs, nonce, postConditions } = options;\n\n const fnArgs = functionArgs.map(arg => deserializeCV(hexToBytes(cleanHex(arg))));\n\n const parsedOptions = {\n fee: fee.amount.toString(),\n functionArgs: fnArgs,\n nonce: initNonce(nonce).toString(),\n postConditions,\n };\n\n return makeUnsignedContractCall({ ...options, ...parsedOptions });\n}\n\nexport function generateUnsignedContractDeploy(options: StacksUnsignedContractDeployOptions) {\n const { fee, nonce, postConditions } = options;\n\n const parsedOptions = {\n fee: fee.amount.toString(),\n nonce: initNonce(nonce).toString(),\n postConditions: getPostConditions(postConditions?.map(pc => ensurePostConditionWireFormat(pc))),\n };\n\n return makeUnsignedContractDeploy({ ...options, ...parsedOptions });\n}\n\nexport function generateUnsignedStxTokenTransfer(options: StacksUnsignedTokenTransferOptions) {\n const { amount, fee, nonce } = options;\n\n const parsedOptions = {\n amount: amount.amount.toString(),\n fee: fee.amount.toString(),\n nonce: initNonce(nonce).toString(),\n };\n\n return makeUnsignedSTXTokenTransfer({ ...options, ...parsedOptions });\n}\n\nexport async function generateStacksUnsignedTransaction(options: StacksUnsignedTransactionOptions) {\n const { txType } = options;\n\n const isValid = isTransactionTypeSupported(txType);\n\n if (!isValid) throw new Error(`Invalid Transaction Type: ${txType}`);\n\n switch (txType) {\n case TransactionTypes.StxTokenTransfer:\n return generateUnsignedStxTokenTransfer(options);\n case TransactionTypes.ContractCall:\n return generateUnsignedContractCall(options);\n case TransactionTypes.ContractDeploy:\n return generateUnsignedContractDeploy(options);\n default:\n assertUnreachable(txType);\n }\n}\n","import { hexToBytes } from '@noble/hashes/utils';\nimport {\n BytesReader,\n PostCondition,\n PostConditionWire,\n deserializePostConditionWire,\n postConditionToWire,\n} from '@stacks/transactions';\n\nimport { isString } from '@leather.io/utils';\n\nexport function getPostConditionFromString(postCondition: string): PostConditionWire {\n try {\n const reader = new BytesReader(hexToBytes(postCondition));\n return deserializePostConditionWire(reader);\n } catch {\n throw new Error('Not a serialized post condition');\n }\n}\n\nexport function ensurePostConditionWireFormat(\n postCondition: string | PostCondition | PostConditionWire\n) {\n if (isString(postCondition)) return getPostConditionFromString(postCondition);\n if ('conditionType' in postCondition) return postCondition;\n return postConditionToWire(postCondition);\n}\n\nexport function getPostCondition(\n postCondition: string | PostCondition | PostConditionWire\n): PostConditionWire {\n return isString(postCondition)\n ? getPostConditionFromString(postCondition)\n : ensurePostConditionWireFormat(postCondition);\n}\n\nexport function getPostConditions(\n postConditions?: (string | PostCondition | PostConditionWire)[]\n): PostConditionWire[] | undefined {\n return postConditions?.map(getPostCondition);\n}\n","import {\n UnsignedContractCallOptions,\n UnsignedContractDeployOptions,\n UnsignedTokenTransferOptions,\n} from '@stacks/transactions';\n\nimport { Money, ReplaceTypes } from '@leather.io/models';\n\nexport enum TransactionTypes {\n ContractCall = 'contract_call',\n ContractDeploy = 'smart_contract',\n StxTokenTransfer = 'token_transfer',\n}\n\nexport function isTransactionTypeSupported(txType: TransactionTypes) {\n return (\n txType === TransactionTypes.ContractCall ||\n txType === TransactionTypes.ContractDeploy ||\n txType === TransactionTypes.StxTokenTransfer\n );\n}\n\nexport type StacksUnsignedContractCallOptions = ReplaceTypes<\n UnsignedContractCallOptions,\n {\n fee: Money;\n functionArgs: string[];\n nonce: number | string;\n }\n> & { txType: TransactionTypes.ContractCall };\n\nexport type StacksUnsignedContractDeployOptions = ReplaceTypes<\n UnsignedContractDeployOptions,\n {\n fee: Money;\n nonce: number | string;\n }\n> & { txType: TransactionTypes.ContractDeploy };\n\nexport type StacksUnsignedTokenTransferOptions = ReplaceTypes<\n UnsignedTokenTransferOptions,\n {\n amount: Money;\n fee: Money;\n nonce: number | string;\n }\n> & { txType: TransactionTypes.StxTokenTransfer };\n\nexport type StacksUnsignedTransactionOptions =\n | StacksUnsignedContractCallOptions\n | StacksUnsignedContractDeployOptions\n | StacksUnsignedTokenTransferOptions;\n","type TransactionErrorKey = 'InvalidAddress' | 'InsufficientFunds' | 'InvalidNetworkAddress';\n\nexport type StacksErrorKey = TransactionErrorKey | 'InvalidSameAddress';\n\nexport class StacksError extends Error {\n public message: StacksErrorKey;\n constructor(message: StacksErrorKey) {\n super(message);\n this.name = 'BitcoinError';\n this.message = message;\n\n // Fix the prototype chain\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import { c32addressDecode } from 'c32check';\n\nimport { ChainId } from '@leather.io/models';\nimport { isEmptyString, isUndefined } from '@leather.io/utils';\n\n// taken from stacks-utils.ts\nexport function isValidStacksAddress(address: string) {\n if (isUndefined(address) || isEmptyString(address)) {\n return false;\n }\n try {\n c32addressDecode(address);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function isValidAddressChain(address: string, chainId: ChainId) {\n if (!isValidStacksAddress(address)) {\n return false;\n }\n\n const prefix = address.slice(0, 2);\n switch (chainId) {\n case ChainId.Mainnet:\n return prefix === 'SM' || prefix === 'SP';\n case ChainId.Testnet:\n return prefix === 'SN' || prefix === 'ST';\n default:\n return false;\n }\n}\n\nexport function validatePayerNotRecipient(senderAddress: string, recipientAddress: string) {\n if (!isValidStacksAddress(senderAddress) || !isValidStacksAddress(recipientAddress)) {\n return false;\n }\n if (senderAddress === recipientAddress) {\n return false;\n }\n return true;\n}\n","import { ChainId } from '@leather.io/models';\n\nimport {\n isValidAddressChain,\n isValidStacksAddress,\n validatePayerNotRecipient,\n} from './address-validation';\nimport { StacksError } from './stacks-error';\n\nexport function isValidStacksTransaction(\n senderAddress: string,\n recipientAddress: string,\n chainId: ChainId\n) {\n if (!isValidStacksAddress(senderAddress) || !isValidStacksAddress(recipientAddress)) {\n throw new StacksError('InvalidAddress');\n }\n if (\n !isValidAddressChain(senderAddress, chainId) ||\n !isValidAddressChain(recipientAddress, chainId)\n ) {\n throw new StacksError('InvalidNetworkAddress');\n }\n if (!validatePayerNotRecipient(senderAddress, recipientAddress)) {\n throw new StacksError('InvalidSameAddress');\n }\n}"],"mappings":"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","names":["privateKeyToPublic","hexToBytes","isString","TransactionTypes","hexToBytes","ChainId"]}
1
+ {"version":3,"sources":["../src/message-signing.ts","../src/mocks/mocks.ts","../src/signer/signer.ts","../src/stacks.utils.ts","../src/transactions/generate-unsigned-transaction.ts","../src/transactions/post-condition.utils.ts","../src/transactions/transaction.types.ts","../src/validation/stacks-error.ts","../src/validation/address-validation.ts","../src/validation/transaction-validation.ts"],"sourcesContent":["import { bytesToHex } from '@noble/hashes/utils';\nimport { PrivateKey } from '@stacks/common';\nimport { hashMessage } from '@stacks/encryption';\nimport {\n ClarityValue,\n privateKeyToPublic,\n signMessageHashRsv,\n signStructuredData,\n} from '@stacks/transactions';\n\ninterface SignatureData {\n signature: string;\n publicKey: string;\n}\nexport function signMessage(message: string, privateKey: PrivateKey): SignatureData {\n const hash = hashMessage(message);\n return {\n signature: signMessageHashRsv({ privateKey, messageHash: bytesToHex(hash) }),\n publicKey: privateKeyToPublic(privateKey) as string,\n };\n}\n\nexport function signStructuredDataMessage(\n message: ClarityValue,\n domain: ClarityValue,\n privateKey: PrivateKey\n): SignatureData {\n const signature = signStructuredData({\n message,\n domain,\n privateKey,\n });\n\n return {\n signature,\n publicKey: privateKeyToPublic(privateKey) as string,\n };\n}\n","// Stacks test addresses\nexport const TEST_ACCOUNT_1_STX_ADDRESS = 'SPS8CKF63P16J28AYF7PXW9E5AACH0NZNTEFWSFE';\nexport const TEST_ACCOUNT_2_STX_ADDRESS = 'SPXH3HNBPM5YP15VH16ZXZ9AX6CK289K3MCXRKCB';\nexport const TEST_TESTNET_ACCOUNT_2_STX_ADDRESS = 'STXH3HNBPM5YP15VH16ZXZ9AX6CK289K3NVR9T1P';\n// TODO ask about these prefixs\n// TEST_ACCOUNT_.. from extension mocks with prefix changed to SM / SN\nexport const TEST_ACCOUNT_1_STX_ADDRESS_SM = 'SM3FBR6RDNZYC5K4TZWV9VZJ6NGA4VX3YBQ8X2PQ';\nexport const TEST_TESTNET_ACCOUNT_2_STX_ADDRESS_SN = 'SNXH3HNBPM5YP15VH16ZXZ9AX6CK289K3NVR9T1P';\n","import {\n StacksTransactionWire,\n TransactionSigner,\n createStacksPublicKey,\n publicKeyToAddressSingleSig,\n} from '@stacks/transactions';\n\nimport {\n Signer,\n decomposeDescriptor,\n deriveRootKeychainFromMnemonic,\n extractKeyFromDescriptor,\n} from '@leather.io/crypto';\nimport { NetworkModes } from '@leather.io/models';\n\nimport { deriveStxPrivateKey, extractStacksDerivationPathAccountIndex } from '../stacks.utils';\n\n// Warning: mutatitive. Ideally there would be a tx.clone() method\nexport function signStacksTransaction(tx: StacksTransactionWire, privateKey: string) {\n const signer = new TransactionSigner(tx);\n signer.signOrigin(privateKey);\n return tx;\n}\n\nexport type StacksSignerFn = (tx: StacksTransactionWire) => Promise<StacksTransactionWire>;\n\nexport interface StacksSigner extends Signer {\n descriptor: string;\n keyOrigin: string;\n address: string;\n accountIndex: number;\n network: NetworkModes;\n sign: StacksSignerFn;\n}\n\nexport function createSignFnFromMnemonic(\n keyOrigin: string,\n getMnemonicFn: () => Promise<{ mnemonic: string; passphrase?: string }>\n) {\n return async (tx: StacksTransactionWire) => {\n const { mnemonic, passphrase } = await getMnemonicFn();\n const keychain = await deriveRootKeychainFromMnemonic(mnemonic, passphrase);\n const privateKey = deriveStxPrivateKey({\n keychain,\n index: extractStacksDerivationPathAccountIndex(keyOrigin),\n });\n return signStacksTransaction(tx, privateKey);\n };\n}\n\ninterface InitalizeStacksSignerArgs {\n descriptor: string;\n network: NetworkModes;\n signFn: StacksSignerFn;\n}\nexport function initalizeStacksSigner(args: InitalizeStacksSignerArgs): StacksSigner {\n const { descriptor, network, signFn } = args;\n\n const publicKey = createStacksPublicKey(extractKeyFromDescriptor(descriptor)).data;\n\n return {\n ...decomposeDescriptor(descriptor),\n // here we overwrite the accountIndex with the derivation path account index for stx\n accountIndex: extractStacksDerivationPathAccountIndex(descriptor),\n publicKey: publicKey,\n network,\n address: publicKeyToAddressSingleSig(publicKey, network),\n sign: signFn,\n };\n}\n","import { HDKey } from '@scure/bip32';\nimport { ChainId } from '@stacks/network';\nimport { AssetString, compressPrivateKey, privateKeyToPublic } from '@stacks/transactions';\n\nimport {\n DerivationPathDepth,\n createDescriptor,\n createKeyOriginPath,\n extractAddressIndexFromPath,\n} from '@leather.io/crypto';\nimport type { NetworkModes } from '@leather.io/models';\nimport { assertIsTruthy, isString, toHexString } from '@leather.io/utils';\n\nexport const stxDerivationWithAccount = `m/44'/5757'/0'/0/{account}`;\n\nexport function makeAccountIndexDerivationPathFactory(derivationPath: string) {\n return (account: number) => derivationPath.replace('{account}', account.toString());\n}\n\nexport function extractStacksDerivationPathAccountIndex(path: string) {\n if (!path.includes('5757')) throw new Error('Not a valid Stacks derivation path: ' + path);\n return extractAddressIndexFromPath(path);\n}\n\n/**\n * Stacks accounts always use the same derivation path, regardless of network\n */\nexport const makeStxDerivationPath =\n makeAccountIndexDerivationPathFactory(stxDerivationWithAccount);\n\nexport function stacksChainIdToCoreNetworkMode(chainId: ChainId): NetworkModes {\n return whenStacksChainId(chainId)({\n [ChainId.Mainnet]: 'mainnet',\n [ChainId.Testnet]: 'testnet',\n });\n}\n\ninterface WhenStacksChainIdMap<T> {\n [ChainId.Mainnet]: T;\n [ChainId.Testnet]: T;\n}\nexport function whenStacksChainId(chainId: ChainId) {\n return <T>(chainIdMap: WhenStacksChainIdMap<T>): T => chainIdMap[chainId];\n}\n\n// From `@stacks/wallet-sdk` package we are trying not to use\nexport function deriveStxPrivateKey({ keychain, index }: { keychain: HDKey; index: number }) {\n if (keychain.depth !== DerivationPathDepth.Root) throw new Error('Root keychain must be depth 0');\n const accountKeychain = keychain.derive(makeStxDerivationPath(index));\n assertIsTruthy(accountKeychain.privateKey);\n return compressPrivateKey(accountKeychain.privateKey);\n}\n\nexport function deriveStxPublicKey({\n keychain,\n index,\n}: {\n keychain: HDKey;\n index: number;\n}): string {\n return privateKeyToPublic(deriveStxPrivateKey({ keychain, index })) as string;\n}\n\nexport function stacksRootKeychainToAccountDescriptor(keychain: HDKey, accountIndex: number) {\n const fingerprint = toHexString(keychain.fingerprint);\n const publicKey = deriveStxPublicKey({ keychain, index: accountIndex });\n return createDescriptor(\n createKeyOriginPath(fingerprint, makeStxDerivationPath(accountIndex)),\n publicKey\n );\n}\n\nexport function getStacksBurnAddress(chainIdChainId: ChainId): string {\n switch (chainIdChainId) {\n case ChainId.Mainnet:\n return 'SP00000000000003SCNSJTCSE62ZF4MSE';\n case ChainId.Testnet:\n default:\n return 'ST000000000000000000002AMW42H';\n }\n}\n\nexport function cleanHex(hexWithMaybePrefix: string): string {\n if (!isString(hexWithMaybePrefix)) return hexWithMaybePrefix;\n return hexWithMaybePrefix.startsWith('0x')\n ? hexWithMaybePrefix.replace('0x', '')\n : hexWithMaybePrefix;\n}\n\nexport function getPrincipalFromAssetString(assetString: string) {\n return assetString.split('::')[0];\n}\n\nexport function formatContractId(address: string, name: string) {\n return `${address}.${name}`;\n}\n\ninterface FormatAssetStringArgs {\n contractAddress: string;\n contractName: string;\n assetName: string;\n}\nexport function formatAssetString({\n contractAddress,\n contractName,\n assetName,\n}: FormatAssetStringArgs): AssetString {\n return `${contractAddress}.${contractName}::${assetName}`;\n}\n\n/**\n * Gets the contract name.\n *\n * @param identifier - [principal].[contract-name] or [principal].[contract-name]::[asset-name]\n */\nexport function getStacksContractName(identifier: string): string {\n if (identifier.includes('.')) {\n const parts = identifier?.split('.');\n if (identifier.includes('::')) {\n return parts[1].split('::')[0];\n }\n return parts[1];\n }\n return identifier;\n}\n\n/**\n * Gets the asset name.\n *\n * @param identifier - [principal].[contract-name]::[asset-name]\n */\nexport function getStacksContractAssetName(identifier: string): string {\n if (!identifier.includes('::')) return identifier;\n return identifier.split('::')[1];\n}\n\n/**\n * Gets the parts that make up a fully qualified name of an asset.\n *\n * @param identifier - [principal].[contract-name]::[asset-name]\n */\nexport function getStacksAssetStringParts(identifier: string): {\n contractAddress: string;\n contractAssetName: string;\n contractName: string;\n} {\n if (!identifier.includes('.') || !identifier.includes('::')) {\n return {\n contractAddress: identifier,\n contractAssetName: identifier,\n contractName: identifier,\n };\n }\n\n const contractAddress = identifier.split('.')[0];\n const contractAssetName = getStacksContractAssetName(identifier);\n const contractName = getStacksContractName(identifier);\n\n return {\n contractAddress,\n contractAssetName,\n contractName,\n };\n}\n","import { hexToBytes } from '@noble/hashes/utils';\nimport {\n deserializeCV,\n makeUnsignedContractCall,\n makeUnsignedContractDeploy,\n makeUnsignedSTXTokenTransfer,\n} from '@stacks/transactions';\nimport BigNumber from 'bignumber.js';\n\nimport { assertUnreachable } from '@leather.io/utils';\n\nimport { cleanHex } from '../stacks.utils';\nimport { ensurePostConditionWireFormat, getPostConditions } from './post-condition.utils';\nimport {\n StacksUnsignedContractCallOptions,\n StacksUnsignedContractDeployOptions,\n StacksUnsignedTokenTransferOptions,\n StacksUnsignedTransactionOptions,\n TransactionTypes,\n isTransactionTypeSupported,\n} from './transaction.types';\n\nexport function initNonce(nonce: number | string) {\n return new BigNumber(nonce, 10);\n}\n\nexport function generateUnsignedContractCall(options: StacksUnsignedContractCallOptions) {\n const { fee, functionArgs, nonce, postConditions } = options;\n\n const fnArgs = functionArgs.map(arg => deserializeCV(hexToBytes(cleanHex(arg))));\n\n const parsedOptions = {\n fee: fee.amount.toString(),\n functionArgs: fnArgs,\n nonce: initNonce(nonce).toString(),\n postConditions,\n };\n\n return makeUnsignedContractCall({ ...options, ...parsedOptions });\n}\n\nexport function generateUnsignedContractDeploy(options: StacksUnsignedContractDeployOptions) {\n const { fee, nonce, postConditions } = options;\n\n const parsedOptions = {\n fee: fee.amount.toString(),\n nonce: initNonce(nonce).toString(),\n postConditions: getPostConditions(postConditions?.map(pc => ensurePostConditionWireFormat(pc))),\n };\n\n return makeUnsignedContractDeploy({ ...options, ...parsedOptions });\n}\n\nexport function generateUnsignedStxTokenTransfer(options: StacksUnsignedTokenTransferOptions) {\n const { amount, fee, nonce } = options;\n\n const parsedOptions = {\n amount: amount.amount.toString(),\n fee: fee.amount.toString(),\n nonce: initNonce(nonce).toString(),\n };\n\n return makeUnsignedSTXTokenTransfer({ ...options, ...parsedOptions });\n}\n\nexport async function generateStacksUnsignedTransaction(options: StacksUnsignedTransactionOptions) {\n const { txType } = options;\n\n const isValid = isTransactionTypeSupported(txType);\n\n if (!isValid) throw new Error(`Invalid Transaction Type: ${txType}`);\n\n switch (txType) {\n case TransactionTypes.StxTokenTransfer:\n return generateUnsignedStxTokenTransfer(options);\n case TransactionTypes.ContractCall:\n return generateUnsignedContractCall(options);\n case TransactionTypes.ContractDeploy:\n return generateUnsignedContractDeploy(options);\n default:\n assertUnreachable(txType);\n }\n}\n","import { hexToBytes } from '@noble/hashes/utils';\nimport {\n BytesReader,\n PostCondition,\n PostConditionWire,\n deserializePostConditionWire,\n postConditionToWire,\n} from '@stacks/transactions';\n\nimport { isString } from '@leather.io/utils';\n\nexport function getPostConditionFromString(postCondition: string): PostConditionWire {\n try {\n const reader = new BytesReader(hexToBytes(postCondition));\n return deserializePostConditionWire(reader);\n } catch {\n throw new Error('Not a serialized post condition');\n }\n}\n\nexport function ensurePostConditionWireFormat(\n postCondition: string | PostCondition | PostConditionWire\n) {\n if (isString(postCondition)) return getPostConditionFromString(postCondition);\n if ('conditionType' in postCondition) return postCondition;\n return postConditionToWire(postCondition);\n}\n\nexport function getPostCondition(\n postCondition: string | PostCondition | PostConditionWire\n): PostConditionWire {\n return isString(postCondition)\n ? getPostConditionFromString(postCondition)\n : ensurePostConditionWireFormat(postCondition);\n}\n\nexport function getPostConditions(\n postConditions?: (string | PostCondition | PostConditionWire)[]\n): PostConditionWire[] | undefined {\n return postConditions?.map(getPostCondition);\n}\n","import {\n UnsignedContractCallOptions,\n UnsignedContractDeployOptions,\n UnsignedTokenTransferOptions,\n} from '@stacks/transactions';\n\nimport { Money, ReplaceTypes } from '@leather.io/models';\n\nexport enum TransactionTypes {\n ContractCall = 'contract_call',\n ContractDeploy = 'smart_contract',\n StxTokenTransfer = 'token_transfer',\n}\n\nexport function isTransactionTypeSupported(txType: TransactionTypes) {\n return (\n txType === TransactionTypes.ContractCall ||\n txType === TransactionTypes.ContractDeploy ||\n txType === TransactionTypes.StxTokenTransfer\n );\n}\n\nexport type StacksUnsignedContractCallOptions = ReplaceTypes<\n UnsignedContractCallOptions,\n {\n fee: Money;\n functionArgs: string[];\n nonce: number | string;\n }\n> & { txType: TransactionTypes.ContractCall };\n\nexport type StacksUnsignedContractDeployOptions = ReplaceTypes<\n UnsignedContractDeployOptions,\n {\n fee: Money;\n nonce: number | string;\n }\n> & { txType: TransactionTypes.ContractDeploy };\n\nexport type StacksUnsignedTokenTransferOptions = ReplaceTypes<\n UnsignedTokenTransferOptions,\n {\n amount: Money;\n fee: Money;\n nonce: number | string;\n }\n> & { txType: TransactionTypes.StxTokenTransfer };\n\nexport type StacksUnsignedTransactionOptions =\n | StacksUnsignedContractCallOptions\n | StacksUnsignedContractDeployOptions\n | StacksUnsignedTokenTransferOptions;\n","import { TransactionErrorKey } from '@leather.io/models';\n\nexport type StacksErrorKey = TransactionErrorKey | 'InvalidSameAddress';\n\nexport class StacksError extends Error {\n public message: StacksErrorKey;\n constructor(message: StacksErrorKey) {\n super(message);\n this.name = 'BitcoinError';\n this.message = message;\n\n // Fix the prototype chain\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import { c32addressDecode } from 'c32check';\n\nimport { ChainId } from '@leather.io/models';\nimport { isEmptyString, isUndefined } from '@leather.io/utils';\n\n// taken from stacks-utils.ts\nexport function isValidStacksAddress(address: string) {\n if (isUndefined(address) || isEmptyString(address)) {\n return false;\n }\n try {\n c32addressDecode(address);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function isValidAddressChain(address: string, chainId: ChainId) {\n if (!isValidStacksAddress(address)) {\n return false;\n }\n\n const prefix = address.slice(0, 2);\n switch (chainId) {\n case ChainId.Mainnet:\n return prefix === 'SM' || prefix === 'SP';\n case ChainId.Testnet:\n return prefix === 'SN' || prefix === 'ST';\n default:\n return false;\n }\n}\n\nexport function validatePayerNotRecipient(senderAddress: string, recipientAddress: string) {\n if (!isValidStacksAddress(senderAddress) || !isValidStacksAddress(recipientAddress)) {\n return false;\n }\n if (senderAddress === recipientAddress) {\n return false;\n }\n return true;\n}\n","import { ChainId, Money } from '@leather.io/models';\n\nimport {\n isValidAddressChain,\n isValidStacksAddress,\n validatePayerNotRecipient,\n} from './address-validation';\nimport { StacksError } from './stacks-error';\n\ninterface StacksTransaction {\n amount: Money;\n payer: string;\n recipient: string;\n chainId: ChainId;\n}\n\nexport function isValidStacksTransaction({ payer, recipient, chainId }: StacksTransaction) {\n if (!isValidStacksAddress(payer) || !isValidStacksAddress(recipient)) {\n throw new StacksError('InvalidAddress');\n }\n if (!isValidAddressChain(payer, chainId) || !isValidAddressChain(recipient, chainId)) {\n throw new StacksError('InvalidNetworkAddress');\n }\n if (!validatePayerNotRecipient(payer, recipient)) {\n throw new StacksError('InvalidSameAddress');\n }\n}\n"],"mappings":"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","names":["privateKeyToPublic","hexToBytes","isString","TransactionTypes","hexToBytes","ChainId"]}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@leather.io/stacks",
3
3
  "author": "leather.io",
4
4
  "description": "Stacks package for Leather",
5
- "version": "1.6.2",
5
+ "version": "1.6.3",
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "exports": {
@@ -18,10 +18,10 @@
18
18
  "@stacks/transactions": "7.0.2",
19
19
  "bignumber.js": "9.1.2",
20
20
  "c32check": "2.0.0",
21
- "@leather.io/constants": "0.17.2",
22
- "@leather.io/crypto": "1.6.45",
23
- "@leather.io/models": "0.26.2",
24
- "@leather.io/utils": "0.27.4"
21
+ "@leather.io/constants": "0.17.3",
22
+ "@leather.io/crypto": "1.6.46",
23
+ "@leather.io/models": "0.26.3",
24
+ "@leather.io/utils": "0.27.5"
25
25
  },
26
26
  "devDependencies": {
27
27
  "tsup": "8.1.0",