@ngraveio/ur-blockchain-commons
Version:
A JS implementation of Uniform Resources(UR) Registry specification from Blockchain Commons.
130 lines (125 loc) • 4.93 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Address = exports.AddressScriptType = void 0;
const bc_ur_1 = require("@ngraveio/bc-ur");
const CoinInfo_1 = require("./CoinInfo");
const AddressHelpers_1 = require("./helpers/AddressHelpers");
var AddressScriptType;
(function (AddressScriptType) {
AddressScriptType[AddressScriptType["P2PKH"] = 0] = "P2PKH";
AddressScriptType[AddressScriptType["P2SH"] = 1] = "P2SH";
AddressScriptType[AddressScriptType["P2WPKH"] = 2] = "P2WPKH";
AddressScriptType[AddressScriptType["P2WSH"] = 3] = "P2WSH";
AddressScriptType[AddressScriptType["P2TR"] = 4] = "P2TR";
AddressScriptType[AddressScriptType["P2MS"] = 5] = "P2MS";
})(AddressScriptType || (exports.AddressScriptType = AddressScriptType = {}));
// https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-009-address.md
class Address extends (0, bc_ur_1.registryItemFactory)({
tag: 40307,
URType: 'address',
CDDL: `
tagged-address = #6.40307(address)
address = {
? info: tagged-coininfo,
? type: address-type,
data: bytes
}
info = 1
type = 2
data = 3
address-type = p2pkh / p2sh / p2wpkh / p2wsh / p2tr / p2ms
p2pkh = 0
p2sh = 1
p2wpkh = 2
p2wsh = 3
p2tr = 4
p2ms = 5
; The \`type\` field MAY be included for Bitcoin (and similar cryptocurrency) addresses, and MUST be omitted for non-applicable types.
; \`data\` contains:
; For addresses of type \`p2pkh\`, the hash160 of the public key (20 bytes).
; For addresses of type \`p2sh\`, the hash160 of the script bytes (20 bytes).
; For addresses of type \`p2wphk\`, the sha256 of the script bytes (32 bytes).
; For ethereum addresses, the last 20 bytes of the keccak256 hash of the public key (20 bytes).
`,
keyMap: {
info: 1,
type: 2,
data: 3,
},
}) {
constructor(input) {
super(input);
this.getAddressInfo = () => this.data.info || new CoinInfo_1.CoinInfo();
this.getAddressScriptType = () => {
// if its not bitcoin return undefined
if (this.getAddressInfo().getType() !== 0) {
return undefined;
}
// Otherwise return the script type
return this.data.type || AddressScriptType.P2PKH;
};
this.data = input;
}
static fromAddress(address, network) {
const decoded = (0, AddressHelpers_1.decodeAddress)(address);
if (network !== undefined && decoded.network !== network) {
throw new Error(`Address network mismatch: expected ${network}, got ${decoded.network ?? 'unknown'}`);
}
let info;
let scriptType;
const coinType = decoded.type;
switch (coinType) {
case 0:
// Keep undefined for default values
info = new CoinInfo_1.CoinInfo(undefined, decoded.network === 'mainnet' ? undefined : 1);
switch (decoded.scriptType) {
case 'P2PKH':
scriptType = AddressScriptType.P2PKH;
break;
case 'P2SH':
scriptType = AddressScriptType.P2SH;
break;
case 'P2WPKH':
scriptType = AddressScriptType.P2WPKH;
break;
case 'P2WSH':
scriptType = AddressScriptType.P2WSH;
break;
case 'P2TR':
scriptType = AddressScriptType.P2TR;
break;
default:
throw new Error('Unknown script type');
}
break;
case 60:
info = new CoinInfo_1.CoinInfo(60, network === 'mainnet' ? 0 : 1);
scriptType = undefined;
break;
default:
throw new Error('Unknown coin type');
}
return new Address({
data: decoded.payload,
info,
type: scriptType,
});
}
/**
* Convert the address object to its string representation.
* @returns The encoded address string.
*/
toAddress() {
const info = this.getAddressInfo();
const type = info.getType();
const network = info.getNetwork() === 0 ? 'mainnet' : 'testnet';
const scriptTypeValue = this.getAddressScriptType();
const scriptType = scriptTypeValue !== undefined ? AddressScriptType[scriptTypeValue] : undefined;
if (type !== 0 && type !== 60) {
throw new Error('Invalid coin type');
}
return (0, AddressHelpers_1.encodeAddress)(type, scriptType, network, this.data.data);
}
}
exports.Address = Address;
//# sourceMappingURL=Address.js.map