@btc-vision/transaction 1.5.4 → 1.6.0

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.
Files changed (95) hide show
  1. package/browser/_version.d.ts +1 -1
  2. package/browser/epoch/ChallengeSolution.d.ts +45 -0
  3. package/browser/epoch/interfaces/IChallengeSolution.d.ts +50 -0
  4. package/browser/epoch/validator/EpochValidator.d.ts +19 -0
  5. package/browser/generators/Features.d.ts +6 -1
  6. package/browser/generators/Generator.d.ts +1 -0
  7. package/browser/generators/builders/CalldataGenerator.d.ts +2 -1
  8. package/browser/generators/builders/DeploymentGenerator.d.ts +3 -1
  9. package/browser/index.js +1 -1
  10. package/browser/keypair/Address.d.ts +2 -0
  11. package/browser/opnet.d.ts +4 -3
  12. package/browser/transaction/TransactionFactory.d.ts +4 -15
  13. package/browser/transaction/browser/Web3Provider.d.ts +3 -3
  14. package/browser/transaction/builders/ChallengeSolutionTransaction.d.ts +1 -18
  15. package/browser/transaction/builders/CustomScriptTransaction.d.ts +1 -1
  16. package/browser/transaction/builders/DeploymentTransaction.d.ts +6 -4
  17. package/browser/transaction/builders/SharedInteractionTransaction.d.ts +5 -4
  18. package/browser/transaction/builders/TransactionBuilder.d.ts +2 -0
  19. package/browser/transaction/interfaces/ITransactionParameters.d.ts +4 -6
  20. package/browser/transaction/mineable/TimelockGenerator.d.ts +9 -0
  21. package/browser/utils/StringToBuffer.d.ts +1 -0
  22. package/browser/verification/TapscriptVerificator.d.ts +4 -1
  23. package/build/_version.d.ts +1 -1
  24. package/build/_version.js +1 -1
  25. package/build/epoch/ChallengeSolution.d.ts +45 -0
  26. package/build/epoch/ChallengeSolution.js +105 -0
  27. package/build/epoch/interfaces/IChallengeSolution.d.ts +50 -0
  28. package/build/epoch/interfaces/IChallengeSolution.js +1 -0
  29. package/build/epoch/validator/EpochValidator.d.ts +19 -0
  30. package/build/epoch/validator/EpochValidator.js +99 -0
  31. package/build/generators/Features.d.ts +6 -1
  32. package/build/generators/Features.js +1 -0
  33. package/build/generators/Generator.d.ts +1 -0
  34. package/build/generators/Generator.js +17 -1
  35. package/build/generators/builders/CalldataGenerator.d.ts +2 -1
  36. package/build/generators/builders/CalldataGenerator.js +4 -2
  37. package/build/generators/builders/DeploymentGenerator.d.ts +3 -1
  38. package/build/generators/builders/DeploymentGenerator.js +5 -3
  39. package/build/keypair/Address.d.ts +2 -0
  40. package/build/keypair/Address.js +12 -0
  41. package/build/keypair/EcKeyPair.js +6 -3
  42. package/build/opnet.d.ts +4 -3
  43. package/build/opnet.js +4 -3
  44. package/build/transaction/TransactionFactory.d.ts +4 -15
  45. package/build/transaction/TransactionFactory.js +4 -32
  46. package/build/transaction/browser/Web3Provider.d.ts +3 -3
  47. package/build/transaction/builders/ChallengeSolutionTransaction.d.ts +0 -18
  48. package/build/transaction/builders/ChallengeSolutionTransaction.js +1 -51
  49. package/build/transaction/builders/CustomScriptTransaction.d.ts +1 -1
  50. package/build/transaction/builders/DeploymentTransaction.d.ts +6 -4
  51. package/build/transaction/builders/DeploymentTransaction.js +19 -7
  52. package/build/transaction/builders/InteractionTransaction.js +8 -1
  53. package/build/transaction/builders/SharedInteractionTransaction.d.ts +5 -4
  54. package/build/transaction/builders/SharedInteractionTransaction.js +7 -7
  55. package/build/transaction/builders/TransactionBuilder.d.ts +2 -0
  56. package/build/transaction/builders/TransactionBuilder.js +31 -3
  57. package/build/transaction/interfaces/ITransactionParameters.d.ts +4 -6
  58. package/build/transaction/mineable/TimelockGenerator.d.ts +9 -0
  59. package/build/transaction/mineable/TimelockGenerator.js +24 -0
  60. package/build/utils/StringToBuffer.d.ts +1 -0
  61. package/build/utils/StringToBuffer.js +3 -0
  62. package/build/verification/TapscriptVerificator.d.ts +4 -1
  63. package/build/verification/TapscriptVerificator.js +2 -2
  64. package/package.json +15 -15
  65. package/src/_version.ts +1 -1
  66. package/src/epoch/ChallengeSolution.ts +196 -0
  67. package/src/epoch/interfaces/IChallengeSolution.ts +56 -0
  68. package/src/epoch/validator/EpochValidator.ts +180 -0
  69. package/src/generators/Features.ts +6 -0
  70. package/src/generators/Generator.ts +24 -2
  71. package/src/generators/builders/CalldataGenerator.ts +7 -3
  72. package/src/generators/builders/DeploymentGenerator.ts +18 -6
  73. package/src/keypair/Address.ts +34 -0
  74. package/src/keypair/EcKeyPair.ts +9 -4
  75. package/src/opnet.ts +6 -3
  76. package/src/transaction/TransactionFactory.ts +7 -62
  77. package/src/transaction/browser/Web3Provider.ts +3 -3
  78. package/src/transaction/builders/ChallengeSolutionTransaction.ts +3 -4
  79. package/src/transaction/builders/CustomScriptTransaction.ts +2 -1
  80. package/src/transaction/builders/DeploymentTransaction.ts +27 -9
  81. package/src/transaction/builders/InteractionTransaction.ts +10 -2
  82. package/src/transaction/builders/SharedInteractionTransaction.ts +12 -28
  83. package/src/transaction/builders/TransactionBuilder.ts +40 -2
  84. package/src/transaction/interfaces/ITransactionParameters.ts +5 -8
  85. package/src/transaction/mineable/TimelockGenerator.ts +42 -0
  86. package/src/utils/StringToBuffer.ts +3 -0
  87. package/src/verification/TapscriptVerificator.ts +8 -4
  88. package/browser/generators/builders/MineableReward.d.ts +0 -7
  89. package/browser/transaction/mineable/ChallengeGenerator.d.ts +0 -9
  90. package/build/generators/builders/MineableReward.d.ts +0 -7
  91. package/build/generators/builders/MineableReward.js +0 -48
  92. package/build/transaction/mineable/ChallengeGenerator.d.ts +0 -9
  93. package/build/transaction/mineable/ChallengeGenerator.js +0 -28
  94. package/src/generators/builders/MineableReward.ts +0 -66
  95. package/src/transaction/mineable/ChallengeGenerator.ts +0 -39
@@ -1,4 +1,5 @@
1
1
  import { Network } from '@btc-vision/bitcoin';
2
+ import { ITimeLockOutput } from '../transaction/mineable/TimelockGenerator.js';
2
3
  export declare class Address extends Uint8Array {
3
4
  #private;
4
5
  constructor(bytes?: ArrayLike<number>);
@@ -28,6 +29,7 @@ export declare class Address extends Uint8Array {
28
29
  toString(): string;
29
30
  toJSON(): string;
30
31
  p2tr(network: Network): string;
32
+ toCSV(duration: bigint | number | string, network: Network): ITimeLockOutput;
31
33
  p2op(network: Network): string;
32
34
  toTweakedHybridPublicKeyHex(): string;
33
35
  toTweakedHybridPublicKeyBuffer(): Buffer;
@@ -5,11 +5,10 @@ export * from './generators/builders/CalldataGenerator.js';
5
5
  export * from './generators/builders/CustomGenerator.js';
6
6
  export * from './generators/builders/DeploymentGenerator.js';
7
7
  export * from './generators/builders/LegacyCalldataGenerator.js';
8
- export * from './generators/builders/MineableReward.js';
9
8
  export * from './generators/builders/MultiSignGenerator.js';
10
9
  export * from './generators/Features.js';
11
10
  export * from './generators/Generator.js';
12
- export * from './transaction/mineable/ChallengeGenerator.js';
11
+ export * from './transaction/mineable/TimelockGenerator.js';
13
12
  export * from './generators/AddressGenerator.js';
14
13
  export * from './verification/TapscriptVerificator.js';
15
14
  export * from './keypair/AddressVerificator.js';
@@ -24,7 +23,6 @@ export * from './transaction/enums/TransactionType.js';
24
23
  export * from './transaction/interfaces/ITransactionParameters.js';
25
24
  export * from './transaction/interfaces/Tap.js';
26
25
  export * from './transaction/TransactionFactory.js';
27
- export * from './transaction/builders/ChallengeSolutionTransaction.js';
28
26
  export * from './transaction/builders/CustomScriptTransaction.js';
29
27
  export * from './transaction/builders/DeploymentTransaction.js';
30
28
  export * from './transaction/builders/FundingTransaction.js';
@@ -32,6 +30,9 @@ export * from './transaction/builders/InteractionTransaction.js';
32
30
  export * from './transaction/builders/MultiSignTransaction.js';
33
31
  export * from './transaction/builders/SharedInteractionTransaction.js';
34
32
  export * from './transaction/builders/TransactionBuilder.js';
33
+ export * from './epoch/interfaces/IChallengeSolution.js';
34
+ export * from './epoch/validator/EpochValidator.js';
35
+ export * from './epoch/ChallengeSolution.js';
35
36
  export * from './utils/BitcoinUtils.js';
36
37
  export * from './utils/lengths.js';
37
38
  export * from './utxo/interfaces/IUTXO.js';
@@ -4,14 +4,14 @@ import { ICustomTransactionParameters } from './builders/CustomScriptTransaction
4
4
  import { FundingTransaction } from './builders/FundingTransaction.js';
5
5
  import { TransactionBuilder } from './builders/TransactionBuilder.js';
6
6
  import { TransactionType } from './enums/TransactionType.js';
7
- import { IChallengeSolutionTransactionParameters, IDeploymentParameters, IFundingTransactionParameters, IInteractionParameters } from './interfaces/ITransactionParameters.js';
8
- import { ChallengeSolutionTransaction } from './builders/ChallengeSolutionTransaction.js';
7
+ import { IDeploymentParameters, IFundingTransactionParameters, IInteractionParameters } from './interfaces/ITransactionParameters.js';
9
8
  import { InteractionParametersWithoutSigner } from './browser/Web3Provider.js';
9
+ import { RawChallenge } from '../epoch/interfaces/IChallengeSolution.js';
10
10
  export interface DeploymentResult {
11
11
  readonly transaction: [string, string];
12
12
  readonly contractAddress: string;
13
13
  readonly contractPubKey: string;
14
- readonly preimage: string;
14
+ readonly preimage: RawChallenge;
15
15
  readonly utxos: UTXO[];
16
16
  }
17
17
  export interface FundingTransactionResponse {
@@ -20,12 +20,6 @@ export interface FundingTransactionResponse {
20
20
  readonly estimatedFees: bigint;
21
21
  readonly nextUTXOs: UTXO[];
22
22
  }
23
- export interface ChallengeSolutionResponse {
24
- readonly tx: Transaction;
25
- readonly original: ChallengeSolutionTransaction;
26
- readonly estimatedFees: bigint;
27
- readonly nextUTXOs: UTXO[];
28
- }
29
23
  export interface BitcoinTransferBase {
30
24
  readonly tx: string;
31
25
  readonly estimatedFees: bigint;
@@ -36,10 +30,7 @@ export interface InteractionResponse {
36
30
  readonly interactionTransaction: string;
37
31
  readonly estimatedFees: bigint;
38
32
  readonly nextUTXOs: UTXO[];
39
- readonly preimage: string;
40
- }
41
- export interface ChallengeSolution extends BitcoinTransferBase {
42
- readonly original: ChallengeSolutionTransaction;
33
+ readonly preimage: RawChallenge;
43
34
  }
44
35
  export interface BitcoinTransferResponse extends BitcoinTransferBase {
45
36
  readonly original: FundingTransaction;
@@ -49,12 +40,10 @@ export declare class TransactionFactory {
49
40
  signInteraction(interactionParameters: IInteractionParameters | InteractionParametersWithoutSigner): Promise<InteractionResponse>;
50
41
  signDeployment(deploymentParameters: IDeploymentParameters): Promise<DeploymentResult>;
51
42
  createBTCTransfer(parameters: IFundingTransactionParameters): Promise<BitcoinTransferResponse>;
52
- createChallengeSolution(parameters: IChallengeSolutionTransactionParameters): Promise<ChallengeSolution>;
53
43
  getAllNewUTXOs(original: TransactionBuilder<TransactionType>, tx: Transaction, to: string): UTXO[];
54
44
  private parseOptionalInputs;
55
45
  private detectInteractionOPWallet;
56
46
  private detectDeploymentOPWallet;
57
- private _createChallengeSolution;
58
47
  private createFundTransaction;
59
48
  private writePSBTHeader;
60
49
  private getPriorityFee;
@@ -2,9 +2,9 @@ import { IDeploymentParameters, IInteractionParameters } from '../interfaces/ITr
2
2
  import { UTXO } from '../../utxo/interfaces/IUTXO.js';
3
3
  import { DeploymentResult, InteractionResponse } from '../TransactionFactory';
4
4
  import { ICustomTransactionParameters } from '../builders/CustomScriptTransaction.js';
5
- export type InteractionParametersWithoutSigner = Omit<IInteractionParameters, 'signer' | 'preimage'>;
6
- export type IDeploymentParametersWithoutSigner = Omit<IDeploymentParameters, 'signer' | 'network' | 'preimage'>;
7
- export type CustomTransactionWithoutSigner = Omit<ICustomTransactionParameters, 'signer' | 'preimage'>;
5
+ export type InteractionParametersWithoutSigner = Omit<IInteractionParameters, 'signer' | 'challenge'>;
6
+ export type IDeploymentParametersWithoutSigner = Omit<IDeploymentParameters, 'signer' | 'network' | 'challenge'>;
7
+ export type CustomTransactionWithoutSigner = Omit<ICustomTransactionParameters, 'signer' | 'challenge'>;
8
8
  export interface BroadcastTransactionOptions {
9
9
  raw: string;
10
10
  psbt: boolean;
@@ -1,18 +1 @@
1
- import { TransactionType } from '../enums/TransactionType.js';
2
- import { IChallengeSolutionTransactionParameters } from '../interfaces/ITransactionParameters.js';
3
- import { Psbt, PsbtInput, Signer } from '@btc-vision/bitcoin';
4
- import { TransactionBuilder } from './TransactionBuilder.js';
5
- import { ECPairInterface } from 'ecpair';
6
- export declare class ChallengeSolutionTransaction extends TransactionBuilder<TransactionType.CHALLENGE_SOLUTION> {
7
- readonly type: TransactionType.CHALLENGE_SOLUTION;
8
- protected amount: bigint;
9
- protected readonly challengeSolution: Buffer;
10
- constructor(parameters: IChallengeSolutionTransactionParameters);
11
- protected buildTransaction(): Promise<void>;
12
- protected signInput(transaction: Psbt, input: PsbtInput, i: number, signer: Signer | ECPairInterface, reverse?: boolean, errored?: boolean): Promise<void>;
13
- protected customFinalizerP2SH: (inputIndex: number, input: PsbtInput, scriptA: Buffer, isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean) => {
14
- finalScriptSig: Buffer | undefined;
15
- finalScriptWitness: Buffer | undefined;
16
- };
17
- protected getSignerKey(): Signer | ECPairInterface;
18
- }
1
+ export {};
@@ -3,7 +3,7 @@ import { TransactionType } from '../enums/TransactionType.js';
3
3
  import { TapLeafScript } from '../interfaces/Tap.js';
4
4
  import { SharedInteractionParameters } from '../interfaces/ITransactionParameters.js';
5
5
  import { TransactionBuilder } from './TransactionBuilder.js';
6
- export interface ICustomTransactionParameters extends SharedInteractionParameters {
6
+ export interface ICustomTransactionParameters extends Omit<SharedInteractionParameters, 'challenge'> {
7
7
  script: (Buffer | Stack)[];
8
8
  witnesses: Buffer[];
9
9
  annex?: Buffer;
@@ -4,12 +4,13 @@ import { P2TRPayment, Psbt } from '@btc-vision/bitcoin';
4
4
  import { TransactionBuilder } from './TransactionBuilder.js';
5
5
  import { TapLeafScript } from '../interfaces/Tap.js';
6
6
  import { Address } from '../../keypair/Address.js';
7
- import { IMineableReward } from '../mineable/ChallengeGenerator.js';
7
+ import { ITimeLockOutput } from '../mineable/TimelockGenerator.js';
8
+ import { ChallengeSolution } from '../../epoch/ChallengeSolution.js';
8
9
  export declare class DeploymentTransaction extends TransactionBuilder<TransactionType.DEPLOYMENT> {
9
10
  static readonly MAXIMUM_CONTRACT_SIZE: number;
10
11
  type: TransactionType.DEPLOYMENT;
11
- protected readonly preimage: Buffer;
12
- protected readonly rewardChallenge: IMineableReward;
12
+ protected readonly preimage: ChallengeSolution;
13
+ protected readonly epochChallenge: ITimeLockOutput;
13
14
  protected readonly _contractAddress: Address;
14
15
  protected tapLeafScript: TapLeafScript | null;
15
16
  private readonly deploymentVersion;
@@ -30,7 +31,7 @@ export declare class DeploymentTransaction extends TransactionBuilder<Transactio
30
31
  get contractAddress(): Address;
31
32
  get p2trAddress(): string;
32
33
  getRndBytes(): Buffer;
33
- getPreimage(): Buffer;
34
+ getPreimage(): ChallengeSolution;
34
35
  getContractAddress(): string;
35
36
  protected contractSignerXOnlyPubKey(): Buffer;
36
37
  protected buildTransaction(): Promise<void>;
@@ -38,6 +39,7 @@ export declare class DeploymentTransaction extends TransactionBuilder<Transactio
38
39
  protected signInputs(transaction: Psbt): Promise<void>;
39
40
  protected generateScriptAddress(): P2TRPayment;
40
41
  protected generateTapData(): P2TRPayment;
42
+ private generateFeatures;
41
43
  private verifyCalldata;
42
44
  private verifyBytecode;
43
45
  private getContractSeed;
@@ -4,7 +4,8 @@ import { TransactionBuilder } from './TransactionBuilder.js';
4
4
  import { TransactionType } from '../enums/TransactionType.js';
5
5
  import { CalldataGenerator } from '../../generators/builders/CalldataGenerator.js';
6
6
  import { SharedInteractionParameters } from '../interfaces/ITransactionParameters.js';
7
- import { IMineableReward } from '../mineable/ChallengeGenerator.js';
7
+ import { ITimeLockOutput } from '../mineable/TimelockGenerator.js';
8
+ import { ChallengeSolution } from '../../epoch/ChallengeSolution.js';
8
9
  export declare abstract class SharedInteractionTransaction<T extends TransactionType> extends TransactionBuilder<T> {
9
10
  static readonly MAXIMUM_CALLDATA_SIZE: number;
10
11
  readonly randomBytes: Buffer;
@@ -12,8 +13,8 @@ export declare abstract class SharedInteractionTransaction<T extends Transaction
12
13
  protected leftOverFundsScriptRedeem: P2TRPayment | null;
13
14
  protected abstract readonly compiledTargetScript: Buffer;
14
15
  protected abstract readonly scriptTree: Taptree;
15
- protected readonly preimage: Buffer;
16
- protected readonly rewardChallenge: IMineableReward;
16
+ protected readonly challenge: ChallengeSolution;
17
+ protected readonly epochChallenge: ITimeLockOutput;
17
18
  protected calldataGenerator: CalldataGenerator;
18
19
  protected readonly calldata: Buffer;
19
20
  protected abstract readonly contractSecret: Buffer;
@@ -22,7 +23,7 @@ export declare abstract class SharedInteractionTransaction<T extends Transaction
22
23
  protected constructor(parameters: SharedInteractionParameters);
23
24
  getContractSecret(): Buffer;
24
25
  getRndBytes(): Buffer;
25
- getPreimage(): Buffer;
26
+ getPreimage(): ChallengeSolution;
26
27
  protected scriptSignerXOnlyPubKey(): Buffer;
27
28
  protected generateKeyPairFromSeed(): ECPairInterface;
28
29
  protected buildTransaction(): Promise<void>;
@@ -33,9 +33,11 @@ export declare abstract class TransactionBuilder<T extends TransactionType> exte
33
33
  protected from: string;
34
34
  protected _maximumFeeRate: number;
35
35
  protected isPubKeyDestination: boolean;
36
+ protected note?: Buffer;
36
37
  protected constructor(parameters: ITransactionParameters);
37
38
  static getFrom(from: string | undefined, keypair: ECPairInterface | Signer, network: Network): string;
38
39
  static witnessStackToScriptWitness(witness: Buffer[]): Buffer;
40
+ addOPReturn(buffer: Buffer): void;
39
41
  getFundingTransactionParameters(): Promise<IFundingTransactionParameters>;
40
42
  setDestinationAddress(address: string): void;
41
43
  setMaximumFeeRate(feeRate: number): void;
@@ -2,6 +2,7 @@ import { UTXO } from '../../utxo/interfaces/IUTXO.js';
2
2
  import { ITweakedTransactionData } from '../shared/TweakedTransaction.js';
3
3
  import { ChainId } from '../../network/ChainId.js';
4
4
  import { PsbtOutputExtended } from '@btc-vision/bitcoin';
5
+ import { ChallengeSolution } from '../../epoch/ChallengeSolution.js';
5
6
  export interface LoadedStorage {
6
7
  [key: string]: string[];
7
8
  }
@@ -15,6 +16,7 @@ export interface ITransactionParameters extends ITweakedTransactionData {
15
16
  optionalOutputs?: PsbtOutputExtended[];
16
17
  chainId?: ChainId;
17
18
  noSignatures?: boolean;
19
+ readonly note?: string | Buffer;
18
20
  readonly feeRate: number;
19
21
  readonly priorityFee: bigint;
20
22
  readonly gasSatFee: bigint;
@@ -23,14 +25,10 @@ export interface IFundingTransactionParameters extends ITransactionParameters {
23
25
  amount: bigint;
24
26
  splitInputsInto?: number;
25
27
  }
26
- export interface IChallengeSolutionTransactionParameters extends ITransactionParameters {
27
- amount: bigint;
28
- readonly challengeSolution: Buffer;
29
- }
30
28
  export interface SharedInteractionParameters extends ITransactionParameters {
31
29
  calldata?: Buffer;
32
30
  disableAutoRefund?: boolean;
33
- readonly preimage: Buffer;
31
+ readonly challenge: ChallengeSolution;
34
32
  readonly randomBytes?: Buffer;
35
33
  readonly loadedStorage?: LoadedStorage;
36
34
  }
@@ -43,5 +41,5 @@ export interface IDeploymentParameters extends Omit<ITransactionParameters, 'to'
43
41
  readonly bytecode: Buffer;
44
42
  readonly calldata?: Buffer;
45
43
  readonly randomBytes?: Buffer;
46
- readonly preimage: Buffer;
44
+ readonly challenge: ChallengeSolution;
47
45
  }
@@ -0,0 +1,9 @@
1
+ import { Network } from '@btc-vision/bitcoin';
2
+ export interface ITimeLockOutput {
3
+ address: string;
4
+ witnessScript: Buffer;
5
+ }
6
+ export declare class TimeLockGenerator {
7
+ private static readonly CSV_BLOCKS;
8
+ static generateTimeLockAddress(publicKey: Buffer, network?: Network, csvBlocks?: number): ITimeLockOutput;
9
+ }
@@ -0,0 +1 @@
1
+ export declare function stringToBuffer(str: string): Buffer;
@@ -1,11 +1,14 @@
1
1
  import { Network, Taptree } from '@btc-vision/bitcoin';
2
+ import { ChallengeSolution } from '../epoch/ChallengeSolution.js';
3
+ import { Feature, Features } from '../generators/Features.js';
2
4
  export interface ContractAddressVerificationParams {
3
5
  readonly deployerPubKey: Buffer;
4
6
  readonly contractSaltPubKey: Buffer;
5
7
  readonly originalSalt: Buffer;
6
8
  readonly bytecode: Buffer;
7
- readonly preimage: Buffer;
9
+ readonly challenge: ChallengeSolution;
8
10
  readonly priorityFee: bigint;
11
+ readonly features: Feature<Features>[];
9
12
  readonly calldata?: Buffer;
10
13
  readonly network?: Network;
11
14
  }
@@ -1 +1 @@
1
- export declare const version = "1.5.3";
1
+ export declare const version = "1.6.0";
package/build/_version.js CHANGED
@@ -1 +1 @@
1
- export const version = '1.5.3';
1
+ export const version = '1.6.0';
@@ -0,0 +1,45 @@
1
+ import { IChallengeSolution, IChallengeSubmission, IChallengeVerification, RawChallenge, RawChallengeSubmission, RawChallengeVerification } from './interfaces/IChallengeSolution.js';
2
+ import { Address } from '../keypair/Address.js';
3
+ export declare class ChallengeVerification implements IChallengeVerification {
4
+ readonly epochHash: Buffer;
5
+ readonly epochRoot: Buffer;
6
+ readonly targetHash: Buffer;
7
+ readonly targetChecksum: Buffer;
8
+ readonly startBlock: bigint;
9
+ readonly endBlock: bigint;
10
+ readonly proofs: readonly Buffer[];
11
+ constructor(data: RawChallengeVerification);
12
+ }
13
+ export declare class ChallengeSubmission implements IChallengeSubmission {
14
+ readonly epochNumber: bigint;
15
+ readonly publicKey: Address;
16
+ readonly solution: Buffer;
17
+ readonly graffiti: Buffer | undefined;
18
+ readonly signature: Buffer;
19
+ constructor(data: RawChallengeSubmission, epochNumber: bigint);
20
+ verifySignature(): boolean;
21
+ }
22
+ export declare class ChallengeSolution implements IChallengeSolution {
23
+ readonly epochNumber: bigint;
24
+ readonly publicKey: Address;
25
+ readonly solution: Buffer;
26
+ readonly salt: Buffer;
27
+ readonly graffiti: Buffer;
28
+ readonly difficulty: number;
29
+ readonly verification: ChallengeVerification;
30
+ private readonly submission?;
31
+ constructor(data: RawChallenge);
32
+ static validateRaw(data: RawChallenge): Promise<boolean>;
33
+ verifySubmissionSignature(): boolean;
34
+ getSubmission(): ChallengeSubmission | undefined;
35
+ verify(): Promise<boolean>;
36
+ toBuffer(): Buffer;
37
+ toHex(): string;
38
+ toRaw(): RawChallenge;
39
+ calculateSolution(): Promise<Buffer>;
40
+ checkDifficulty(minDifficulty: number): {
41
+ valid: boolean;
42
+ difficulty: number;
43
+ };
44
+ getMiningTargetBlock(): bigint | null;
45
+ }
@@ -0,0 +1,105 @@
1
+ import { stringToBuffer } from '../utils/StringToBuffer.js';
2
+ import { Address } from '../keypair/Address.js';
3
+ import { EpochValidator } from './validator/EpochValidator.js';
4
+ import { BinaryWriter } from '../buffer/BinaryWriter.js';
5
+ import { MessageSigner } from '../keypair/MessageSigner.js';
6
+ export class ChallengeVerification {
7
+ constructor(data) {
8
+ this.epochHash = stringToBuffer(data.epochHash);
9
+ this.epochRoot = stringToBuffer(data.epochRoot);
10
+ this.targetHash = stringToBuffer(data.targetHash);
11
+ this.targetChecksum = stringToBuffer(data.targetChecksum);
12
+ this.startBlock = BigInt(data.startBlock);
13
+ this.endBlock = BigInt(data.endBlock);
14
+ this.proofs = Object.freeze(data.proofs.map((proof) => stringToBuffer(proof)));
15
+ }
16
+ }
17
+ export class ChallengeSubmission {
18
+ constructor(data, epochNumber) {
19
+ this.epochNumber = epochNumber;
20
+ this.publicKey = Address.fromString(data.publicKey);
21
+ this.solution = stringToBuffer(data.solution);
22
+ this.graffiti = data.graffiti ? stringToBuffer(data.graffiti) : undefined;
23
+ this.signature = stringToBuffer(data.signature);
24
+ }
25
+ verifySignature() {
26
+ const signatureDataWriter = new BinaryWriter();
27
+ signatureDataWriter.writeAddress(this.publicKey);
28
+ signatureDataWriter.writeU64(this.epochNumber);
29
+ signatureDataWriter.writeBytes(this.solution);
30
+ if (this.graffiti) {
31
+ signatureDataWriter.writeBytes(this.graffiti);
32
+ }
33
+ const buffer = signatureDataWriter.getBuffer();
34
+ return MessageSigner.verifySignature(this.publicKey, buffer, this.signature);
35
+ }
36
+ }
37
+ export class ChallengeSolution {
38
+ constructor(data) {
39
+ this.epochNumber = BigInt(data.epochNumber);
40
+ this.publicKey = Address.fromString(data.publicKey);
41
+ this.solution = stringToBuffer(data.solution);
42
+ this.salt = stringToBuffer(data.salt);
43
+ this.graffiti = stringToBuffer(data.graffiti);
44
+ this.difficulty = data.difficulty;
45
+ this.verification = new ChallengeVerification(data.verification);
46
+ this.submission = data.submission
47
+ ? new ChallengeSubmission(data.submission, this.epochNumber + 2n)
48
+ : data.submission;
49
+ }
50
+ static async validateRaw(data) {
51
+ return EpochValidator.validateEpochWinner(data);
52
+ }
53
+ verifySubmissionSignature() {
54
+ if (!this.submission) {
55
+ throw new Error('No submission provided in request.');
56
+ }
57
+ return this.submission.verifySignature();
58
+ }
59
+ getSubmission() {
60
+ if (!this.submission) {
61
+ return;
62
+ }
63
+ if (!this.verifySubmissionSignature()) {
64
+ throw new Error('Invalid submission signature.');
65
+ }
66
+ return this.submission;
67
+ }
68
+ async verify() {
69
+ return EpochValidator.validatePreimage(this);
70
+ }
71
+ toBuffer() {
72
+ return this.solution;
73
+ }
74
+ toHex() {
75
+ return '0x' + this.solution.toString('hex');
76
+ }
77
+ toRaw() {
78
+ return {
79
+ epochNumber: this.epochNumber.toString(),
80
+ publicKey: this.publicKey.toHex(),
81
+ solution: this.toHex(),
82
+ salt: '0x' + this.salt.toString('hex'),
83
+ graffiti: '0x' + this.graffiti.toString('hex'),
84
+ difficulty: this.difficulty,
85
+ verification: {
86
+ epochHash: '0x' + this.verification.epochHash.toString('hex'),
87
+ epochRoot: '0x' + this.verification.epochRoot.toString('hex'),
88
+ targetHash: '0x' + this.verification.targetHash.toString('hex'),
89
+ targetChecksum: '0x' + this.verification.targetChecksum.toString('hex'),
90
+ startBlock: this.verification.startBlock.toString(),
91
+ endBlock: this.verification.endBlock.toString(),
92
+ proofs: this.verification.proofs.map((p) => '0x' + p.toString('hex')),
93
+ },
94
+ };
95
+ }
96
+ async calculateSolution() {
97
+ return EpochValidator.calculateSolution(this.verification.targetChecksum, this.publicKey.toBuffer(), this.salt);
98
+ }
99
+ checkDifficulty(minDifficulty) {
100
+ return EpochValidator.checkDifficulty(this.solution, this.verification.targetHash, minDifficulty);
101
+ }
102
+ getMiningTargetBlock() {
103
+ return EpochValidator.getMiningTargetBlock(this.epochNumber);
104
+ }
105
+ }
@@ -0,0 +1,50 @@
1
+ import { Address } from '../../keypair/Address.js';
2
+ export interface IChallengeVerification {
3
+ readonly epochHash: Buffer;
4
+ readonly epochRoot: Buffer;
5
+ readonly targetHash: Buffer;
6
+ readonly targetChecksum: Buffer;
7
+ readonly startBlock: bigint;
8
+ readonly endBlock: bigint;
9
+ readonly proofs: readonly Buffer[];
10
+ }
11
+ export interface IChallengeSolution {
12
+ readonly epochNumber: bigint;
13
+ readonly publicKey: Address;
14
+ readonly solution: Buffer;
15
+ readonly salt: Buffer;
16
+ readonly graffiti: Buffer;
17
+ readonly difficulty: number;
18
+ readonly verification: IChallengeVerification;
19
+ }
20
+ export interface RawChallengeVerification {
21
+ readonly epochHash: string;
22
+ readonly epochRoot: string;
23
+ readonly targetHash: string;
24
+ readonly targetChecksum: string;
25
+ readonly startBlock: string;
26
+ readonly endBlock: string;
27
+ readonly proofs: readonly string[];
28
+ }
29
+ export interface RawChallengeSubmission {
30
+ readonly publicKey: string;
31
+ readonly solution: string;
32
+ readonly graffiti?: string;
33
+ readonly signature: string;
34
+ }
35
+ export interface IChallengeSubmission {
36
+ readonly publicKey: Address;
37
+ readonly solution: Buffer;
38
+ readonly graffiti?: Buffer;
39
+ readonly signature: Buffer;
40
+ }
41
+ export interface RawChallenge {
42
+ readonly epochNumber: string;
43
+ readonly publicKey: string;
44
+ readonly solution: string;
45
+ readonly salt: string;
46
+ readonly graffiti: string;
47
+ readonly difficulty: number;
48
+ readonly verification: RawChallengeVerification;
49
+ readonly submission?: RawChallengeSubmission;
50
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,19 @@
1
+ import { IChallengeSolution, RawChallenge } from '../interfaces/IChallengeSolution.js';
2
+ export declare class EpochValidator {
3
+ private static readonly BLOCKS_PER_EPOCH;
4
+ private static readonly GRAFFITI_LENGTH;
5
+ static bufferToUint8Array(buffer: Buffer): Uint8Array;
6
+ static uint8ArrayToBuffer(array: Uint8Array): Buffer;
7
+ static sha1(data: Uint8Array): Promise<Uint8Array>;
8
+ static calculatePreimage(checksumRoot: Buffer, publicKey: Buffer, salt: Buffer): Buffer;
9
+ static countMatchingBits(hash1: Buffer, hash2: Buffer): number;
10
+ static verifySolution(preimage: IChallengeSolution, log?: boolean): Promise<boolean>;
11
+ static getMiningTargetBlock(epochNumber: bigint): bigint | null;
12
+ static validateEpochWinner(epochData: RawChallenge): Promise<boolean>;
13
+ static validatePreimage(preimage: IChallengeSolution): Promise<boolean>;
14
+ static calculateSolution(targetChecksum: Buffer, publicKey: Buffer, salt: Buffer): Promise<Buffer>;
15
+ static checkDifficulty(solution: Buffer, targetHash: Buffer, minDifficulty: number): {
16
+ valid: boolean;
17
+ difficulty: number;
18
+ };
19
+ }
@@ -0,0 +1,99 @@
1
+ import { ChallengeSolution } from '../ChallengeSolution.js';
2
+ export class EpochValidator {
3
+ static bufferToUint8Array(buffer) {
4
+ return new Uint8Array(buffer);
5
+ }
6
+ static uint8ArrayToBuffer(array) {
7
+ return Buffer.from(array);
8
+ }
9
+ static async sha1(data) {
10
+ const hashBuffer = await crypto.subtle.digest('SHA-1', data);
11
+ return new Uint8Array(hashBuffer);
12
+ }
13
+ static calculatePreimage(checksumRoot, publicKey, salt) {
14
+ if (checksumRoot.length !== 32 || publicKey.length !== 32 || salt.length !== 32) {
15
+ throw new Error('All inputs must be 32 bytes');
16
+ }
17
+ const preimage = Buffer.alloc(32);
18
+ for (let i = 0; i < 32; i++) {
19
+ preimage[i] = checksumRoot[i] ^ publicKey[i] ^ salt[i];
20
+ }
21
+ return preimage;
22
+ }
23
+ static countMatchingBits(hash1, hash2) {
24
+ let matchingBits = 0;
25
+ if (hash1.length !== hash2.length) {
26
+ throw new Error('Hashes must be of the same length');
27
+ }
28
+ const minLength = Math.min(hash1.length, hash2.length);
29
+ for (let i = 0; i < minLength; i++) {
30
+ const byte1 = hash1[i];
31
+ const byte2 = hash2[i];
32
+ if (byte1 === byte2) {
33
+ matchingBits += 8;
34
+ }
35
+ else {
36
+ for (let bit = 7; bit >= 0; bit--) {
37
+ if (((byte1 >> bit) & 1) === ((byte2 >> bit) & 1)) {
38
+ matchingBits++;
39
+ }
40
+ else {
41
+ return matchingBits;
42
+ }
43
+ }
44
+ }
45
+ }
46
+ return matchingBits;
47
+ }
48
+ static async verifySolution(preimage, log = false) {
49
+ try {
50
+ const verification = preimage.verification;
51
+ const calculatedPreimage = this.calculatePreimage(verification.targetChecksum, preimage.publicKey.toBuffer(), preimage.salt);
52
+ const computedSolution = await this.sha1(this.bufferToUint8Array(calculatedPreimage));
53
+ const computedSolutionBuffer = this.uint8ArrayToBuffer(computedSolution);
54
+ if (!computedSolutionBuffer.equals(preimage.solution)) {
55
+ return false;
56
+ }
57
+ const matchingBits = this.countMatchingBits(computedSolutionBuffer, verification.targetHash);
58
+ if (matchingBits !== preimage.difficulty) {
59
+ return false;
60
+ }
61
+ const expectedStartBlock = preimage.epochNumber * this.BLOCKS_PER_EPOCH;
62
+ const expectedEndBlock = expectedStartBlock + this.BLOCKS_PER_EPOCH - 1n;
63
+ return !(verification.startBlock !== expectedStartBlock ||
64
+ verification.endBlock !== expectedEndBlock);
65
+ }
66
+ catch (error) {
67
+ if (log)
68
+ console.error('Verification error:', error);
69
+ return false;
70
+ }
71
+ }
72
+ static getMiningTargetBlock(epochNumber) {
73
+ if (epochNumber === 0n) {
74
+ return null;
75
+ }
76
+ return epochNumber * this.BLOCKS_PER_EPOCH - 1n;
77
+ }
78
+ static async validateEpochWinner(epochData) {
79
+ const preimage = new ChallengeSolution(epochData);
80
+ return await this.verifySolution(preimage);
81
+ }
82
+ static async validatePreimage(preimage) {
83
+ return await this.verifySolution(preimage);
84
+ }
85
+ static async calculateSolution(targetChecksum, publicKey, salt) {
86
+ const preimage = this.calculatePreimage(targetChecksum, publicKey, salt);
87
+ const hash = await this.sha1(this.bufferToUint8Array(preimage));
88
+ return this.uint8ArrayToBuffer(hash);
89
+ }
90
+ static checkDifficulty(solution, targetHash, minDifficulty) {
91
+ const difficulty = this.countMatchingBits(solution, targetHash);
92
+ return {
93
+ valid: difficulty >= minDifficulty,
94
+ difficulty,
95
+ };
96
+ }
97
+ }
98
+ EpochValidator.BLOCKS_PER_EPOCH = 5n;
99
+ EpochValidator.GRAFFITI_LENGTH = 16;
@@ -1,6 +1,8 @@
1
1
  import { LoadedStorage } from '../transaction/interfaces/ITransactionParameters.js';
2
+ import { ChallengeSubmission } from '../epoch/ChallengeSolution.js';
2
3
  export declare enum Features {
3
- ACCESS_LIST = 1
4
+ ACCESS_LIST = 1,
5
+ EPOCH_SUBMISSION = 2
4
6
  }
5
7
  export interface Feature<T extends Features> {
6
8
  opcode: T;
@@ -9,3 +11,6 @@ export interface Feature<T extends Features> {
9
11
  export interface AccessListFeature extends Feature<Features.ACCESS_LIST> {
10
12
  data: LoadedStorage;
11
13
  }
14
+ export interface EpochSubmissionFeature extends Feature<Features.EPOCH_SUBMISSION> {
15
+ data: ChallengeSubmission;
16
+ }
@@ -1,4 +1,5 @@
1
1
  export var Features;
2
2
  (function (Features) {
3
3
  Features[Features["ACCESS_LIST"] = 1] = "ACCESS_LIST";
4
+ Features[Features["EPOCH_SUBMISSION"] = 2] = "EPOCH_SUBMISSION";
4
5
  })(Features || (Features = {}));