-
Notifications
You must be signed in to change notification settings - Fork 54
/
PaymentAddress.ts
94 lines (82 loc) · 2.96 KB
/
PaymentAddress.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import { Address, AddressType } from './Address';
import { DRepID } from './DRepID';
import {
HexBlob,
InvalidStringError,
OpaqueString,
assertIsBech32WithPrefix,
assertIsHexString
} from '@cardano-sdk/util';
import { HydratedTx, HydratedTxIn, Tx, TxIn, TxOut } from '../types';
import { NetworkId } from '../ChainId';
import { RewardAccount } from './RewardAccount';
/** mainnet or testnet address (Shelley as bech32 string, Byron as base58-encoded string) */
export type PaymentAddress = OpaqueString<'PaymentAddress'>;
/**
* @param {string} address mainnet or testnet address
* @throws InvalidStringError
*/
const isRewardAccount = (address: string) => {
try {
assertIsBech32WithPrefix(address, ['stake', 'stake_test']);
return true;
} catch {
return false;
}
};
/**
* Transform a `value` into `Cardano.PaymentAddress`,
* Resulting PaymentAddress will be base58 in case of Byron era or bech32 in case of Shelley era or newer.
*
* @param value bech32 string, base58 string or hex-encoded bytes address.
* @throws {InvalidStringError} if value is invalid
*/
export const PaymentAddress = (value: string): PaymentAddress => {
if (Address.isValid(value)) {
if (isRewardAccount(value) || DRepID.isValid(value)) {
throw new InvalidStringError(value, 'Address type can only be used for payment addresses');
}
return value as unknown as PaymentAddress;
}
try {
assertIsHexString(value);
} catch {
throw new InvalidStringError(value, 'Expected payment address as bech32, base58 or hex-encoded bytes');
}
const address = Address.fromBytes(HexBlob.fromBytes(Buffer.from(value, 'hex')));
return (address.getType() === AddressType.Byron ? address.toBase58() : address.toBech32()) as PaymentAddress;
};
/** Checks that an object containing an address (e.g., output, input) is within a set of provided addresses */
export const isAddressWithin =
(addresses: PaymentAddress[]) =>
({ address }: { address: PaymentAddress }): boolean =>
addresses.includes(address!);
/**
* Receives a transaction and a set of addresses to check if
* some of them are included in the transaction inputs
*
* @returns {HydratedTxIn[]} array of inputs that contain any of the addresses
*/
export const inputsWithAddresses = (tx: HydratedTx, ownAddresses: PaymentAddress[]): HydratedTxIn[] =>
tx.body.inputs.filter(isAddressWithin(ownAddresses));
export type ResolveOptions = {
hints: Tx[];
};
/**
* @param txIn transaction input to resolve associated txOut from
* @returns txOut
*/
export type ResolveInput = (txIn: TxIn, options?: ResolveOptions) => Promise<TxOut | null>;
export interface InputResolver {
resolveInput: ResolveInput;
}
/**
* Gets the network id from the address.
*
* @param address The address to get the network id from.
* @returns The network ID.
*/
export const addressNetworkId = (address: RewardAccount | PaymentAddress | DRepID): NetworkId => {
const addr = Address.fromString(address);
return addr!.getNetworkId();
};