add support for Dark Wallet-style addresses
These functions are prefixed DW which stands for Dark Wallet. The code for the Dark Wallet address format can be found here: https://github.com/darkwallet/darkwallet/blob/develop/js/util/stealth.js Note that I deliberately support only the simplest possible format, which is where there is only one payload pubkey and the prefix is blank. I should now go back and replace my old toString, fromString, toBuffer, fromBuffer functions with these Dark Wallet versions, since they are much more well-thought out than mine.
This commit is contained in:
parent
9b8ce05b15
commit
96df77429f
|
@ -2,6 +2,8 @@ var Stealthkey = require('./stealthkey');
|
|||
var Base58check = require('../base58check');
|
||||
var Pubkey = require('../pubkey');
|
||||
var KDF = require('../kdf');
|
||||
var BufferWriter = require('../bufferwriter');
|
||||
var BufferReader = require('../bufferreader');
|
||||
|
||||
var StealthAddress = function StealthAddress(addrstr) {
|
||||
if (!(this instanceof StealthAddress))
|
||||
|
@ -20,6 +22,9 @@ var StealthAddress = function StealthAddress(addrstr) {
|
|||
}
|
||||
};
|
||||
|
||||
StealthAddress.mainver = 42;
|
||||
StealthAddress.testver = 43;
|
||||
|
||||
StealthAddress.prototype.set = function(obj) {
|
||||
this.payloadPubkey = obj.payloadPubkey || this.payloadPubkey;
|
||||
this.scanPubkey = obj.scanPubkey || this.scanPubkey;
|
||||
|
@ -56,6 +61,29 @@ StealthAddress.prototype.fromBuffer = function(buf) {
|
|||
return this;
|
||||
};
|
||||
|
||||
StealthAddress.prototype.fromDWBuffer = function(buf) {
|
||||
var parsed = StealthAddress.parseDWBuffer(buf);
|
||||
if ((parsed.version !== StealthAddress.mainver) && (parsed.version !== StealthAddress.testver))
|
||||
throw new Error('Invalid version');
|
||||
if (parsed.options !== 0)
|
||||
throw new Error('Invalid options');
|
||||
if (!parsed.scanPubkey)
|
||||
throw new Error('Invalid scanPubkey');
|
||||
if (parsed.payloadPubkeys.length !== 1)
|
||||
throw new Error('Must have exactly one payloadPubkey');
|
||||
if (parsed.nSigs !== 1)
|
||||
throw new Error('Must require exactly one signature');
|
||||
if (parsed.prefix.toString() !== "")
|
||||
throw new Error('Only blank prefixes supported');
|
||||
this.scanPubkey = parsed.scanPubkey;
|
||||
this.payloadPubkey = parsed.payloadPubkeys[0];
|
||||
return this;
|
||||
};
|
||||
|
||||
StealthAddress.prototype.fromDWString = function(str) {
|
||||
return this.fromDWBuffer(Base58check(str).toBuffer());
|
||||
};
|
||||
|
||||
StealthAddress.prototype.fromString = function(str) {
|
||||
var buf = Base58check.decode(str);
|
||||
this.fromBuffer(buf);
|
||||
|
@ -86,6 +114,27 @@ StealthAddress.prototype.toBuffer = function() {
|
|||
return Buffer.concat([pBuf, sBuf]);
|
||||
};
|
||||
|
||||
StealthAddress.prototype.toDWBuffer = function(networkstr) {
|
||||
if (networkstr === 'testnet')
|
||||
var version = StealthAddress.testver;
|
||||
else
|
||||
var version = StealthAddress.mainver;
|
||||
var bw = new BufferWriter();
|
||||
bw.writeUInt8(version);
|
||||
bw.writeUInt8(0); //options
|
||||
bw.write(this.scanPubkey.toDER(true));
|
||||
bw.writeUInt8(1); //number of payload keys - we only support 1 (not multisig)
|
||||
bw.write(this.payloadPubkey.toDER(true));
|
||||
bw.writeUInt8(1); //number of signatures - we only support 1 (not multisig)
|
||||
bw.writeUInt8(0); //prefix length - we do not support prefix yet
|
||||
var buf = bw.concat();
|
||||
return buf;
|
||||
};
|
||||
|
||||
StealthAddress.prototype.toDWString = function(networkstr) {
|
||||
return Base58check(this.toDWBuffer(networkstr)).toString();
|
||||
};
|
||||
|
||||
StealthAddress.prototype.toString = function() {
|
||||
var buf = this.toBuffer();
|
||||
var b58 = Base58check.encode(buf);
|
||||
|
@ -93,4 +142,20 @@ StealthAddress.prototype.toString = function() {
|
|||
return b58;
|
||||
};
|
||||
|
||||
StealthAddress.parseDWBuffer = function(buf) {
|
||||
var br = new BufferReader(buf);
|
||||
var parsed = {};
|
||||
parsed.version = br.readUInt8();
|
||||
parsed.options = br.readUInt8();
|
||||
parsed.scanPubkey = Pubkey().fromBuffer(br.read(33));
|
||||
parsed.nPayloadPubkeys = br.readUInt8();
|
||||
parsed.payloadPubkeys = [];
|
||||
for (var i = 0; i < parsed.nPayloadPubkeys; i++)
|
||||
parsed.payloadPubkeys.push(Pubkey().fromBuffer(br.read(33)));
|
||||
parsed.nSigs = br.readUInt8();
|
||||
parsed.nPrefix = br.readUInt8();
|
||||
parsed.prefix = br.read(parsed.nPrefix / 8);
|
||||
return parsed;
|
||||
};
|
||||
|
||||
module.exports = StealthAddress;
|
||||
|
|
|
@ -26,6 +26,7 @@ describe('StealthAddress', function() {
|
|||
senderKeypair.privkey2pubkey();
|
||||
|
||||
var addressString = '9dDbC9FzZ74r8njQkXD6W27gtrxLiWaeFPHxeo1fynQRXPicqxVt7u95ozbwoVVMXyrzaHKN9owsteg63FgwDfrxWx82SAW';
|
||||
var dwhex = '2a0002697763d7e9becb0c180083738c32c05b0e2fee26d6278020c06bbb04d5f66b32010362408459041e0473298af3824dbabe4d2b7f846825ed4d1c2e2c670c07cb275d0100';
|
||||
|
||||
it('should make a new stealth address', function() {
|
||||
var sa = new StealthAddress();
|
||||
|
@ -69,6 +70,22 @@ describe('StealthAddress', function() {
|
|||
|
||||
});
|
||||
|
||||
describe('#fromDWBuffer', function() {
|
||||
|
||||
it('should parse this DW buffer', function() {
|
||||
StealthAddress().fromDWBuffer(new Buffer(dwhex, 'hex')).toDWBuffer().toString('hex').should.equal(dwhex);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#fromDWString', function() {
|
||||
|
||||
it('should parse this DW buffer', function() {
|
||||
StealthAddress().fromDWString(Base58check(new Buffer(dwhex, 'hex')).toString()).toDWBuffer().toString('hex').should.equal(dwhex);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#fromString', function() {
|
||||
|
||||
it('should give a stealthkey address with the right pubkeys', function() {
|
||||
|
@ -126,6 +143,24 @@ describe('StealthAddress', function() {
|
|||
|
||||
});
|
||||
|
||||
describe('#toDWBuffer', function() {
|
||||
|
||||
it('should return this known address buffer', function() {
|
||||
var buf = Base58check.decode(addressString);
|
||||
StealthAddress().fromBuffer(buf).toDWBuffer().toString('hex').should.equal(dwhex);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#toDWString', function() {
|
||||
|
||||
it('should return this known address buffer', function() {
|
||||
var buf = Base58check.decode(addressString);
|
||||
StealthAddress().fromBuffer(buf).toDWString().should.equal(Base58check(new Buffer(dwhex, 'hex')).toString());
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#toString', function() {
|
||||
|
||||
it('should return this known address string', function() {
|
||||
|
@ -134,4 +169,20 @@ describe('StealthAddress', function() {
|
|||
|
||||
});
|
||||
|
||||
describe('@parseDWBuffer', function() {
|
||||
|
||||
it('should parse this known DW buffer', function() {
|
||||
var buf = new Buffer(dwhex, 'hex');
|
||||
var parsed = StealthAddress.parseDWBuffer(buf);
|
||||
parsed.version.should.equal(42);
|
||||
parsed.options.should.equal(0);
|
||||
parsed.scanPubkey.toString().should.equal('02697763d7e9becb0c180083738c32c05b0e2fee26d6278020c06bbb04d5f66b32');
|
||||
parsed.nPayloadPubkeys.should.equal(1);
|
||||
parsed.payloadPubkeys[0].toString().should.equal('0362408459041e0473298af3824dbabe4d2b7f846825ed4d1c2e2c670c07cb275d');
|
||||
parsed.nSigs.should.equal(1);
|
||||
parsed.prefix.toString().should.equal('');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue