Skip to content

Commit

Permalink
Update tx input and outpoint types
Browse files Browse the repository at this point in the history
  • Loading branch information
rileystephens28 committed Jun 18, 2024
1 parent ea66c4e commit 7e058a4
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 47 deletions.
16 changes: 13 additions & 3 deletions src/providers/abstract-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// migrate the listener to the static event. We also need to maintain a map
// of Signer to address so we can sync respond to listenerCount.

import { resolveAddress } from '../address/index.js';
import { computeAddress, resolveAddress } from '../address/index.js';
import { Shard, toShard, toZone, Zone } from '../constants/index.js';
import { TxInput, TxOutput } from '../transaction/index.js';
import { Outpoint } from '../transaction/utxo.js';
Expand Down Expand Up @@ -58,6 +58,7 @@ import type { Networkish } from './network.js';
import type {
BlockParams,
LogParams,
OutpointResponseParams,
QiTransactionResponseParams,
TransactionReceiptParams,
TransactionResponseParams,
Expand Down Expand Up @@ -1098,7 +1099,7 @@ export class AbstractProvider<C = FetchRequest> implements Provider {
const addr = Array.isArray((<any>request)[key])
? 'address' in <any>request[key][0]
? (<TxOutput[]>(<any>request)[key]).map((it) => it.address)
: (<TxInput[]>(<any>request)[key]).map((it) => it.address)
: (<TxInput[]>(<any>request)[key]).map((it) => computeAddress(it.pubkey))
: resolveAddress((<any>request)[key]);
if (isPromise(addr)) {
if (Array.isArray(addr)) {
Expand Down Expand Up @@ -1315,7 +1316,16 @@ export class AbstractProvider<C = FetchRequest> implements Provider {
}

async getOutpointsByAddress(address: AddressLike): Promise<Outpoint[]> {
return await this.#getAccountValue({ method: 'getOutpointsByAddress' }, address, 'latest');
const outpoints: OutpointResponseParams[] = await this.#getAccountValue(
{ method: 'getOutpointsByAddress' },
address,
'latest',
);
return outpoints.map((outpoint: OutpointResponseParams) => ({
txhash: outpoint.Txhash,
index: outpoint.Index,
denomination: outpoint.Denomination,
}));
}

async getTransactionCount(address: AddressLike, blockTag?: BlockTag): Promise<number> {
Expand Down
13 changes: 5 additions & 8 deletions src/providers/format.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @ignore
*/
import { computeAddress, getAddress } from '../address/index.js';
import { getAddress } from '../address/index.js';
import { Signature } from '../crypto/index.js';
import { accessListify } from '../transaction/index.js';
import { hexlify } from '../utils/data';
Expand Down Expand Up @@ -400,17 +400,14 @@ export function formatTransactionResponse(value: any): TransactionResponseParams

const _formatTxInput = object(
{
txHash: formatHash,
txhash: formatHash,
index: getNumber,
address: computeAddress,
pubKey: hexlify,
denomination: allowNull(getNumber, 0),
pubkey: hexlify,
},
{
txHash: ['previous_out_point', 'hash', 'value'],
txhash: ['previous_out_point', 'hash', 'value'],
index: ['previous_out_point', 'index'],
address: ['pub_key'],
pubKey: ['pub_key'],
pubkey: ['pub_key'],
},
);

Expand Down
6 changes: 6 additions & 0 deletions src/providers/formatting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -435,3 +435,9 @@ export interface QiTransactionResponseParams {

txInputs?: TxInput[];
}

export interface OutpointResponseParams {
Txhash: string;
Index: number;
Denomination: number;
}
3 changes: 2 additions & 1 deletion src/providers/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
isError,
makeError,
} from '../utils/index.js';
import { computeAddress } from '../address/index.js';
import { accessListify } from '../transaction/index.js';

import type { AddressLike } from '../address/index.js';
Expand Down Expand Up @@ -133,7 +134,7 @@ export function addressFromTransactionRequest(tx: TransactionRequest): AddressLi
return tx.from;
}
if (tx.inputs) {
return tx.inputs[0].address;
return computeAddress(tx.inputs[0].pubkey);
}
if ('to' in tx && tx.to !== null) {
return tx.to as AddressLike;
Expand Down
18 changes: 9 additions & 9 deletions src/transaction/qi-transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AbstractTransaction, TransactionLike, TxInput, TxOutput } from './index
import { assertArgument, getBytes, getZoneForAddress, hexlify, isQiAddress, toBigInt } from '../utils/index.js';
import { decodeProtoTransaction } from '../encoding/index.js';
import { formatNumber } from '../providers/format.js';
import { computeAddress } from '../address/index.js';
import { ProtoTransaction } from './abstract-transaction.js';
import { Zone } from '../constants/index.js';

Expand Down Expand Up @@ -64,8 +65,8 @@ export class QiTransaction extends AbstractTransaction<string> implements QiTran
throw new Error('Transaction must have at least one input and one output');
}

// Use the first input address as the sender address
const senderAddr = this.txInputs[0].address;
const pubKey = hexlify(this.txInputs[0].pubkey);
const senderAddr = computeAddress(pubKey || '');

if (!this.destZone || !this.originZone) {
throw new Error(
Expand Down Expand Up @@ -97,7 +98,8 @@ export class QiTransaction extends AbstractTransaction<string> implements QiTran
* The zone of the sender address
*/
get originZone(): Zone | undefined {
const senderAddr = this.txInputs[0].address;
const pubKey = hexlify(this.txInputs[0].pubkey);
const senderAddr = computeAddress(pubKey || '');

const zone = getZoneForAddress(senderAddr);
return zone ?? undefined;
Expand Down Expand Up @@ -184,10 +186,10 @@ export class QiTransaction extends AbstractTransaction<string> implements QiTran
tx_ins: {
tx_ins: this.txInputs.map((input) => ({
previous_out_point: {
hash: { value: getBytes(input.txHash) },
hash: { value: getBytes(input.txhash) },
index: input.index,
},
pub_key: getBytes(input.pubKey),
pub_key: getBytes(input.pubkey),
})),
},
tx_outs: {
Expand Down Expand Up @@ -259,11 +261,9 @@ export class QiTransaction extends AbstractTransaction<string> implements QiTran
if (protoTx.type == 2) {
tx.txInputs =
protoTx.tx_ins?.tx_ins.map((input) => ({
txHash: hexlify(input.previous_out_point.hash.value),
txhash: hexlify(input.previous_out_point.hash.value),
index: input.previous_out_point.index,
address: hexlify(input.pub_key),
pubKey: hexlify(input.pub_key),
// there is no denomination in the protobuf object, I think the client should return it though
pubkey: hexlify(input.pub_key),
})) ?? [];
tx.txOutputs =
protoTx.tx_outs?.tx_outs.map((output) => ({
Expand Down
40 changes: 19 additions & 21 deletions src/transaction/utxo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import type { BigNumberish } from '../utils/index.js';
*
* @todo If not used, replace with `ignore`
*/
export type Outpoint = {
Txhash: string;
Index: number;
Denomination: number;
export type TxInput = {
txhash: string;
index: number;
pubkey: string;
};

/**
Expand All @@ -20,46 +20,44 @@ export type Outpoint = {
*
* @todo If not used, replace with `ignore`
*/
export interface UTXOEntry {
denomination: null | bigint;
export type TxOutput = {
address: string;
}
denomination: number;
};

/**
* @category Transaction
* @todo Write documentation for this type.
*
* @todo If not used, replace with `ignore`
*/
export interface UTXOLike extends UTXOEntry {
txhash?: null | string;
index?: null | number;
}
export type Outpoint = {
txhash: string;
index: number;
denomination: number;
};

/**
* @category Transaction
* @todo Write documentation for this type.
*
* @todo If not used, replace with `ignore`
*/
export type TxInput = {
txHash: string;
index: number;
export interface UTXOEntry {
denomination: null | bigint;
address: string;
pubKey: string;
denomination?: number;
};
}

/**
* @category Transaction
* @todo Write documentation for this type.
*
* @todo If not used, replace with `ignore`
*/
export type TxOutput = {
address: string;
denomination: number;
};
export interface UTXOLike extends UTXOEntry {
txhash?: null | string;
index?: null | number;
}

/**
* @category Transaction
Expand Down
12 changes: 7 additions & 5 deletions src/wallet/qi-hdwallet.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AbstractHDWallet, NeuteredAddressInfo } from './hdwallet.js';
import { HDNodeWallet } from './hdnodewallet.js';
import { QiTransactionRequest, Provider, TransactionResponse } from '../providers/index.js';
import { computeAddress } from '../address/index.js';
import { getBytes, hexlify } from '../utils/index.js';
import { TransactionLike, QiTransaction, TxInput } from '../transaction/index.js';
import { MuSigFactory } from '@brandonblack/musig';
Expand Down Expand Up @@ -114,13 +115,14 @@ export class QiHDWallet extends AbstractHDWallet {
throw new Error('Transaction has no inputs');
}
const input = tx.inputs[0];
const shard = getZoneForAddress(input.address);
const address = computeAddress(input.pubkey);
const shard = getZoneForAddress(address);
if (!shard) {
throw new Error(`Address ${input.address} not found in any shard`);
throw new Error(`Address ${address} not found in any shard`);
}

// verify all inputs are from the same shard
if (tx.inputs.some((input) => getZoneForAddress(input.address) !== shard)) {
if (tx.inputs.some((input) => getZoneForAddress(computeAddress(input.pubkey)) !== shard)) {
throw new Error('All inputs must be from the same shard');
}

Expand Down Expand Up @@ -178,8 +180,8 @@ export class QiHDWallet extends AbstractHDWallet {

// Helper method that returns the private key for the public key
private derivePrivateKeyForInput(input: TxInput): string {
if (!input.address) throw new Error('Missing address for input');
const address = input.address;
if (!input.pubkey) throw new Error('Missing public key for input');
const address = computeAddress(input.pubkey);
// get address info
const addressInfo = this.getAddressInfo(address);
if (!addressInfo) throw new Error(`Address not found: ${address}`);
Expand Down

0 comments on commit 7e058a4

Please sign in to comment.