-
Notifications
You must be signed in to change notification settings - Fork 302
Expand file tree
/
Copy pathrecipient.ts
More file actions
72 lines (64 loc) · 2.82 KB
/
recipient.ts
File metadata and controls
72 lines (64 loc) · 2.82 KB
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
import * as utxolib from '@bitgo/utxo-lib';
import { getNetworkFromCoinName, UtxoCoinName } from '../names';
const ScriptRecipientPrefix = 'scriptPubKey:';
/**
* Check if the address is a script recipient (starts with `scriptPubKey:`).
* @param address
*/
export function isScriptRecipient(address: string): boolean {
return address.toLowerCase().startsWith(ScriptRecipientPrefix.toLowerCase());
}
/**
* An extended address is one that encodes either a regular address or a hex encoded script with the prefix `scriptPubKey:`.
* This function converts the extended address format to either a script or an address.
* @param extendedAddress
*/
export function fromExtendedAddressFormat(extendedAddress: string): { address: string } | { script: string } {
if (isScriptRecipient(extendedAddress)) {
return { script: extendedAddress.slice(ScriptRecipientPrefix.length) };
}
return { address: extendedAddress };
}
export function fromExtendedAddressFormatToScript(extendedAddress: string, coinName: UtxoCoinName): Buffer {
const result = fromExtendedAddressFormat(extendedAddress);
if ('script' in result) {
return Buffer.from(result.script, 'hex');
}
const network = getNetworkFromCoinName(coinName);
return utxolib.addressFormat.toOutputScriptTryFormats(result.address, network);
}
export function toOutputScript(v: string | { address: string } | { script: string }, coinName: UtxoCoinName): Buffer {
if (typeof v === 'string') {
return fromExtendedAddressFormatToScript(v, coinName);
}
if ('script' in v) {
return Buffer.from(v.script, 'hex');
}
if ('address' in v) {
return fromExtendedAddressFormatToScript(v.address, coinName);
}
throw new Error('invalid input');
}
/**
* Convert a script or address to the extended address format.
* @param script
* @param coinName
* @returns if the script is an OP_RETURN script, then it will be prefixed with `scriptPubKey:`, otherwise it will be converted to an address.
*/
export function toExtendedAddressFormat(script: Buffer, coinName: UtxoCoinName): string {
const network = getNetworkFromCoinName(coinName);
return script[0] === utxolib.opcodes.OP_RETURN
? `${ScriptRecipientPrefix}${script.toString('hex')}`
: utxolib.address.fromOutputScript(script, network);
}
export function assertValidTransactionRecipient(output: { amount: bigint | number | string; address?: string }): void {
// In the case that this is an OP_RETURN output or another non-encodable scriptPubkey, we dont have an address.
// We will verify that the amount is zero, and if it isnt then we will throw an error.
if (!output.address || isScriptRecipient(output.address)) {
if (output.amount.toString() !== '0') {
throw new Error(
`Only zero amounts allowed for non-encodeable scriptPubkeys: amount: ${output.amount}, address: ${output.address}`
);
}
}
}