- Consolidated duplicate UndoManagers to single instance - Fixed connection promise to only resolve on 'connected' status - Fixed WebSocketProvider import (WebsocketProvider) - Added proper doc.destroy() cleanup - Renamed isPresenceInitialized property to avoid conflict Co-Authored-By: Paperclip <noreply@paperclip.ing>
150 lines
4.4 KiB
TypeScript
150 lines
4.4 KiB
TypeScript
// TODO: Find opportunities to make this file less duplicated + more simplified with Viem v3.
|
|
|
|
import type { Address } from 'abitype'
|
|
import * as Hex from 'ox/Hex'
|
|
import {
|
|
Transaction as ox_Transaction,
|
|
TransactionRequest as ox_TransactionRequest,
|
|
} from 'ox/tempo'
|
|
import type { Account as viem_Account } from '../accounts/types.js'
|
|
import { parseAccount } from '../accounts/utils/parseAccount.js'
|
|
import { formatTransaction as viem_formatTransaction } from '../utils/formatters/transaction.js'
|
|
import { formatTransactionReceipt as viem_formatTransactionReceipt } from '../utils/formatters/transactionReceipt.js'
|
|
import { formatTransactionRequest as viem_formatTransactionRequest } from '../utils/formatters/transactionRequest.js'
|
|
import type { Account } from './Account.js'
|
|
import {
|
|
isTempo,
|
|
type Transaction,
|
|
type TransactionReceipt,
|
|
type TransactionReceiptRpc,
|
|
type TransactionRequest,
|
|
type TransactionRequestRpc,
|
|
type TransactionRpc,
|
|
} from './Transaction.js'
|
|
|
|
export function formatTransaction(
|
|
transaction: TransactionRpc,
|
|
): Transaction<bigint, number, boolean> {
|
|
if (!isTempo(transaction)) return viem_formatTransaction(transaction as never)
|
|
|
|
const {
|
|
feePayerSignature,
|
|
gasPrice: _,
|
|
nonce,
|
|
...tx
|
|
} = ox_Transaction.fromRpc(transaction as never) as ox_Transaction.Tempo
|
|
|
|
return {
|
|
...tx,
|
|
accessList: tx.accessList!,
|
|
feePayerSignature: feePayerSignature
|
|
? {
|
|
r: Hex.fromNumber(feePayerSignature.r, { size: 32 }),
|
|
s: Hex.fromNumber(feePayerSignature.s, { size: 32 }),
|
|
v: BigInt(feePayerSignature.v ?? 27),
|
|
yParity: feePayerSignature.yParity,
|
|
}
|
|
: undefined,
|
|
nonce: Number(nonce),
|
|
typeHex:
|
|
ox_Transaction.toRpcType[
|
|
tx.type as keyof typeof ox_Transaction.toRpcType
|
|
],
|
|
type: tx.type as 'tempo',
|
|
}
|
|
}
|
|
|
|
export function formatTransactionReceipt(
|
|
receipt: TransactionReceiptRpc,
|
|
): TransactionReceipt {
|
|
return viem_formatTransactionReceipt(receipt as never)
|
|
}
|
|
|
|
export function formatTransactionRequest(
|
|
r: TransactionRequest,
|
|
action?: string | undefined,
|
|
): TransactionRequestRpc {
|
|
const request = r as TransactionRequest & {
|
|
account?: viem_Account | Address | undefined
|
|
}
|
|
const account = request.account
|
|
? parseAccount<Account | viem_Account | Address>(request.account)
|
|
: undefined
|
|
|
|
// If the request is not a Tempo transaction, route to Viem formatter.
|
|
if (!isTempo(request))
|
|
return viem_formatTransactionRequest(
|
|
r as never,
|
|
action,
|
|
) as TransactionRequestRpc
|
|
|
|
if (action)
|
|
request.calls = request.calls ?? [
|
|
{
|
|
to:
|
|
r.to ||
|
|
(!r.data || r.data === '0x'
|
|
? '0x0000000000000000000000000000000000000000'
|
|
: undefined),
|
|
value: r.value,
|
|
data: r.data,
|
|
},
|
|
]
|
|
|
|
// If we have marked the transaction as intended to be paid
|
|
// by a fee payer (feePayer: true), we will not use the fee token
|
|
// as the fee payer will choose their fee token.
|
|
if (request.feePayer === true) delete request.feeToken
|
|
|
|
const rpc = ox_TransactionRequest.toRpc({
|
|
...request,
|
|
type: 'tempo',
|
|
} as never)
|
|
|
|
if (action === 'estimateGas') {
|
|
rpc.maxFeePerGas = undefined
|
|
rpc.maxPriorityFeePerGas = undefined
|
|
}
|
|
|
|
rpc.to = undefined
|
|
rpc.data = undefined
|
|
rpc.value = undefined
|
|
|
|
const [keyType, keyData] = (() => {
|
|
const type =
|
|
account && 'keyType' in account ? account.keyType : account?.source
|
|
if (!type) return [undefined, undefined]
|
|
if (type === 'webAuthn')
|
|
// TODO: derive correct bytes size of key data based on webauthn create metadata.
|
|
return ['webAuthn', `0x${'ff'.repeat(1400)}`]
|
|
if (['p256', 'secp256k1'].includes(type)) return [type, undefined]
|
|
return [undefined, undefined]
|
|
})()
|
|
|
|
const keyId =
|
|
account && 'accessKeyAddress' in account
|
|
? account.accessKeyAddress
|
|
: undefined
|
|
|
|
if (account) rpc.from = account.address
|
|
|
|
return {
|
|
...rpc,
|
|
...(keyData ? { keyData } : {}),
|
|
...(keyId ? { keyId } : {}),
|
|
...(keyType ? { keyType } : {}),
|
|
...(typeof request.feePayer !== 'undefined'
|
|
? {
|
|
feePayer:
|
|
typeof request.feePayer === 'object'
|
|
? parseAccount(request.feePayer)
|
|
: request.feePayer,
|
|
}
|
|
: {}),
|
|
...('feePayerSignature' in request &&
|
|
request.feePayerSignature !== undefined
|
|
? { feePayerSignature: request.feePayerSignature }
|
|
: {}),
|
|
} as never
|
|
}
|