Skip to content

Commit

Permalink
chore: txEnvelope tsdocs
Browse files Browse the repository at this point in the history
  • Loading branch information
jxom committed Aug 28, 2024
1 parent b462e30 commit 5797217
Show file tree
Hide file tree
Showing 42 changed files with 1,091 additions and 176 deletions.
12 changes: 9 additions & 3 deletions src/internal/signature/extract.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { GlobalErrorType } from '../errors/error.js'
import type { Compute, ExactPartial, OneOf } from '../types.js'
import type { Compute } from '../types.js'
import { Signature_from } from './from.js'
import type { Signature, Signature_Legacy } from './types.js'
import type { Signature } from './types.js'

/**
* Extracts a {@link Signature#Signature} from an arbitrary object that may include signature properties.
Expand Down Expand Up @@ -30,14 +30,20 @@ import type { Signature, Signature_Legacy } from './types.js'
* @returns The extracted {@link Signature#Signature}.
*/
export function Signature_extract(
value: OneOf<ExactPartial<Signature> | ExactPartial<Signature_Legacy>>,
value: Signature_extract.Value,
): Signature_extract.ReturnType {
if (typeof value.r === 'undefined') return undefined
if (typeof value.s === 'undefined') return undefined
return Signature_from(value as any)
}

export declare namespace Signature_extract {
type Value = {
r?: bigint | undefined
s?: bigint | undefined
yParity?: 0 | 1 | undefined
v?: number | undefined
}
type ReturnType = Compute<Signature> | undefined
type ErrorType = GlobalErrorType
}
Expand Down
16 changes: 15 additions & 1 deletion src/internal/transactionEnvelope/eip1559/assert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,21 @@ import type { TransactionEnvelopeEip1559 } from './types.js'
* Asserts a {@link TransactionEnvelope#Eip1559} is valid.
*
* @example
* // TODO
* ```ts twoslash
* import { TransactionEnvelopeEip1559, Value } from 'ox'
*
* TransactionEnvelopeEip1559.assert({
* maxFeePerGas: 2n ** 256n - 1n + 1n,
* chainId: 1,
* to: '0x0000000000000000000000000000000000000000',
* value: Value.fromEther('1'),
* })
* // @error: FeeCapTooHighError:
* // @error: The fee cap (`masFeePerGas` = 115792089237316195423570985008687907853269984665640564039457584007913 gwei) cannot be
* // @error: higher than the maximum allowed value (2^256-1).
* ```
*
* @param envelope - The transaction envelope to assert.
*/
export function TransactionEnvelopeEip1559_assert(
envelope: PartialBy<TransactionEnvelopeEip1559, 'type'>,
Expand Down
23 changes: 12 additions & 11 deletions src/internal/transactionEnvelope/eip1559/deserialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,22 @@ import type {
* Deserializes a {@link TransactionEnvelope#Eip1559} from its serialized form.
*
* @example
* ```ts
* ```ts twoslash
* import { TransactionEnvelopeEip1559 } from 'ox'
*
* const envelope = TransactionEnvelopeEip1559.deserialize('0x02ef0182031184773594008477359400809470997970c51812dc3a010c7d01b50e0d17dc79c8880de0b6b3a764000080c0')
* // {
* // type: 'eip1559',
* // chainId: 1,
* // nonce: 785n,
* // maxFeePerGas: 2000000000n,
* // maxPriorityFeePerGas: 2000000000n,
* // gas: 1000000n,
* // to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* // value: 1000000000000000000n,
* // }
* // @log: {
* // @log: type: 'eip1559',
* // @log: nonce: 785n,
* // @log: maxFeePerGas: 2000000000n,
* // @log: gas: 1000000n,
* // @log: to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* // @log: value: 1000000000000000000n,
* // @log: }
* ```
*
* @param serializedTransaction - The serialized transaction.
* @returns Deserialized Transaction Envelope.
*/
export function TransactionEnvelopeEip1559_deserialize(
serializedTransaction: TransactionEnvelopeEip1559_Serialized,
Expand Down
76 changes: 68 additions & 8 deletions src/internal/transactionEnvelope/eip1559/from.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import type {
* Converts an arbitrary transaction object into an EIP-1559 Transaction Envelope.
*
* @example
* ```ts
* ```ts twoslash
* import { TransactionEnvelopeEip1559, Value } from 'ox'
*
* const envelope = TransactionEnvelopeEip1559.from({
Expand All @@ -26,31 +26,91 @@ import type {
* value: Value.fromEther('1'),
* })
* ```
*
* @example
* ### Attaching Signatures
*
* It is possible to attach a `signature` to the transaction envelope.
*
* ```ts twoslash
* import { Secp256k1, TransactionEnvelopeEip1559, Value } from 'ox'
*
* const envelope = TransactionEnvelopeEip1559.from({
* chainId: 1,
* maxFeePerGas: Value.fromGwei('10'),
* maxPriorityFeePerGas: Value.fromGwei('1'),
* to: '0x0000000000000000000000000000000000000000',
* value: Value.fromEther('1'),
* })
*
* const signature = Secp256k1.sign({
* payload: TransactionEnvelopeEip1559.getSignPayload(envelope),
* privateKey: '0x...',
* })
*
* const envelope_signed = TransactionEnvelopeEip1559.from(envelope, { // [!code focus]
* signature, // [!code focus]
* }) // [!code focus]
* // @log: {
* // @log: chainId: 1,
* // @log: maxFeePerGas: 10000000000n,
* // @log: maxPriorityFeePerGas: 1000000000n,
* // @log: to: '0x0000000000000000000000000000000000000000',
* // @log: type: 'eip1559',
* // @log: value: 1000000000000000000n,
* // @log: r: 125...n,
* // @log: s: 642...n,
* // @log: yParity: 0,
* // @log: }
* ```
*
* @example
* ### From Serialized
*
* It is possible to instantiate an EIP-1559 Transaction Envelope from a {@link TransactionEnvelope#Serialized} value.
*
* ```ts twoslash
* import { TransactionEnvelopeEip1559 } from 'ox'
*
* const envelope = TransactionEnvelopeEip1559.from('0x02f858018203118502540be4008504a817c800809470997970c51812dc3a010c7d01b50e0d17dc79c8880de0b6b3a764000080c08477359400e1a001627c687261b0e7f8638af1112efa8a77e23656f6e7945275b19e9deed80261')
* // @log: {
* // @log: chainId: 1,
* // @log: maxFeePerGas: 10000000000n,
* // @log: maxPriorityFeePerGas: 1000000000n,
* // @log: to: '0x0000000000000000000000000000000000000000',
* // @log: type: 'eip1559',
* // @log: value: 1000000000000000000n,
* // @log: }
* ```
*
* @param envelope - The transaction object to convert.
* @param options -
* @returns An EIP-1559 Transaction Envelope.
*/
export function TransactionEnvelopeEip1559_from<
const envelope extends
| UnionPartialBy<TransactionEnvelopeEip1559, 'type'>
| TransactionEnvelopeEip1559_Serialized,
const signature extends Signature | undefined = undefined,
>(
envelope_:
envelope:
| envelope
| UnionPartialBy<TransactionEnvelopeEip1559, 'type'>
| TransactionEnvelopeEip1559_Serialized,
options: TransactionEnvelopeEip1559_from.Options<signature> = {},
): TransactionEnvelopeEip1559_from.ReturnType<envelope, signature> {
const { signature } = options

const envelope = (
typeof envelope_ === 'string'
? TransactionEnvelopeEip1559_deserialize(envelope_)
: envelope_
const envelope_ = (
typeof envelope === 'string'
? TransactionEnvelopeEip1559_deserialize(envelope)
: envelope
) as TransactionEnvelopeEip1559

TransactionEnvelopeEip1559_assert(envelope)
TransactionEnvelopeEip1559_assert(envelope_)

return {
...envelope,
...envelope_,
...(signature ? Signature_from(signature) : {}),
type: 'eip1559',
} as never
Expand Down
24 changes: 23 additions & 1 deletion src/internal/transactionEnvelope/eip1559/getSignPayload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,29 @@ import type { TransactionEnvelopeEip1559 } from './types.js'
* Returns the payload to sign for a {@link TransactionEnvelope#Eip1559}.
*
* @example
* // TODO
* The example below demonstrates how to compute the sign payload which can be used
* with ECDSA signing utilities like {@link Secp256k1#sign}.
*
* ```ts twoslash
* import { Secp256k1, TransactionEnvelopeEip1559 } from 'ox'
*
* const envelope = TransactionEnvelopeEip1559.from({
* chainId: 1,
* nonce: 0n,
* maxFeePerGas: 1000000000n,
* gas: 21000n,
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* value: 1000000000000000000n,
* })
*
* const payload = TransactionEnvelopeEip1559.getSignPayload(envelope) // [!code focus]
* // @log: '0x...'
*
* const signature = Secp256k1.sign({ payload, privateKey: '0x...' })
* ```
*
* @param envelope - The transaction envelope to get the sign payload for.
* @returns The sign payload.
*/
export function TransactionEnvelopeEip1559_getSignPayload(
envelope: TransactionEnvelopeEip1559,
Expand Down
21 changes: 19 additions & 2 deletions src/internal/transactionEnvelope/eip1559/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,27 @@ import { TransactionEnvelopeEip1559_serialize } from './serialize.js'
import type { TransactionEnvelopeEip1559 } from './types.js'

/**
* Hashes a {@link TransactionEnvelope#Eip1559} for signing.
* Hashes a {@link TransactionEnvelope#Eip1559}. This is the "transaction hash".
*
* @example
* // TODO
* ```ts twoslash
* import { TransactionEnvelopeEip1559 } from 'ox'
*
* const envelope = TransactionEnvelopeEip1559.from({
* chainId: 1,
* nonce: 0n,
* maxFeePerGas: 1000000000n,
* gas: 21000n,
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8',
* value: 1000000000000000000n,
* })
*
* const hash = TransactionEnvelopeEip1559.hash(envelope) // [!code focus]
* ```
*
* @param envelope - The EIP-1559 Transaction Envelope to hash.
* @param options -
* @returns The hash of the transaction envelope.
*/
export function TransactionEnvelopeEip1559_hash(
envelope: TransactionEnvelopeEip1559,
Expand Down
48 changes: 40 additions & 8 deletions src/internal/transactionEnvelope/eip1559/serialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,56 @@ import type {
* Serializes a {@link TransactionEnvelope#Eip1559}.
*
* @example
* ```ts
* import { TransactionEnvelopeEip1559 } from 'ox'
* ```ts twoslash
* import { TransactionEnvelopeEip1559, Value } from 'ox'
*
* const envelope = TransactionEnvelopeEip1559.from({
* maxFeePerGas: 1000000n,
* chainId: 1,
* maxFeePerGas: Value.fromGwei('10'),
* maxPriorityFeePerGas: Value.fromGwei('1'),
* to: '0x0000000000000000000000000000000000000000',
* value: Value.fromEther('1'),
* })
*
* const serialized = TransactionEnvelopeEip1559.serialize(envelope)
* // '0x02...'
* const serialized = TransactionEnvelopeEip1559.serialize(envelope) // [!code focus]
* ```
*
* @example
* ### Attaching Signatures
*
* It is possible to attach a `signature` to the serialized Transaction Envelope.
*
* ```ts twoslash
* import { Secp256k1, TransactionEnvelopeEip1559, Value } from 'ox'
*
* const envelope = TransactionEnvelopeEip1559.from({
* chainId: 1,
* maxFeePerGas: Value.fromGwei('10'),
* maxPriorityFeePerGas: Value.fromGwei('1'),
* to: '0x0000000000000000000000000000000000000000',
* value: Value.fromEther('1'),
* })
*
* const signature = Secp256k1.sign({
* payload: TransactionEnvelopeEip1559.getSignPayload(envelope),
* privateKey: '0x...',
* })
*
* const serialized = TransactionEnvelopeEip1559.serialize(envelope, { // [!code focus]
* signature, // [!code focus]
* }) // [!code focus]
*
* // ... send `serialized` transaction to JSON-RPC `eth_sendRawTransaction`
* ```
*
* @param envelope - The Transaction Envelope to serialize.
* @param options -
* @returns The serialized Transaction Envelope.
*/
export function TransactionEnvelopeEip1559_serialize(
envelope: PartialBy<TransactionEnvelopeEip1559, 'type'>,
options: TransactionEnvelopeEip1559_serialize.Options = {},
): TransactionEnvelopeEip1559_serialize.ReturnType {
): TransactionEnvelopeEip1559_Serialized {
const {
chainId,
gas,
Expand Down Expand Up @@ -78,8 +112,6 @@ export declare namespace TransactionEnvelopeEip1559_serialize {
signature?: Signature | undefined
}

type ReturnType = TransactionEnvelopeEip1559_Serialized

type ErrorType =
| TransactionEnvelopeEip1559_assert.ErrorType
| Hex_from.ErrorType
Expand Down
5 changes: 2 additions & 3 deletions src/internal/transactionEnvelope/eip1559/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { AccessList } from '../../accessList/types.js'
import type { Signature, Signature_Legacy } from '../../signature/types.js'
import type { Compute, ExactPartial, OneOf } from '../../types.js'
import type { Compute } from '../../types.js'
import type { TransactionEnvelope_Base } from '../types.js'

export type TransactionEnvelopeEip1559_Type = 'eip1559'
Expand All @@ -15,7 +14,7 @@ export type TransactionEnvelopeEip1559 = Compute<
maxFeePerGas?: bigint | undefined
/** Max priority fee per gas (in wei). */
maxPriorityFeePerGas?: bigint | undefined
} & OneOf<ExactPartial<Signature> | ExactPartial<Signature_Legacy>>
}
>

export type TransactionEnvelopeEip1559_SerializedType = '0x02'
Expand Down
16 changes: 15 additions & 1 deletion src/internal/transactionEnvelope/eip2930/assert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,21 @@ import type { TransactionEnvelopeEip2930 } from './types.js'
* Asserts a {@link TransactionEnvelope#Eip2930} is valid.
*
* @example
* // TODO
* ```ts twoslash
* import { TransactionEnvelopeEip2930, Value } from 'ox'
*
* TransactionEnvelopeEip2930.assert({
* gasPrice: 2n ** 256n - 1n + 1n,
* chainId: 1,
* to: '0x0000000000000000000000000000000000000000',
* value: Value.fromEther('1'),
* })
* // @error: GasPriceTooHighError:
* // @error: The gas price (`gasPrice` = 115792089237316195423570985008687907853269984665640564039457584007913 gwei) cannot be
* // @error: higher than the maximum allowed value (2^256-1).
* ```
*
* @param envelope - The transaction envelope to assert.
*/
export function TransactionEnvelopeEip2930_assert(
envelope: PartialBy<TransactionEnvelopeEip2930, 'type'>,
Expand Down
Loading

0 comments on commit 5797217

Please sign in to comment.