-
Notifications
You must be signed in to change notification settings - Fork 137
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
194 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import xdr from './generated/stellar-xdr_generated'; | ||
import { StrKey, encodeCheck, decodeCheck } from './strkey'; | ||
|
||
/** | ||
* A container class with helpers to convert between signer keys | ||
* (`xdr.SignerKey`) and {@link StrKey}s. | ||
* | ||
* It's primarly used for manipulating the `extraSigners` precondition on a | ||
* {@link Transaction}. | ||
* | ||
* @see {@link TransactionBuilder.setExtraSigners} | ||
*/ | ||
export class SignerKey { | ||
/** | ||
* Decodes a StrKey address into an xdr.SignerKey instance. | ||
* | ||
* Only ED25519 public keys (G...), pre-auth transactions (T...), hashes | ||
* (H...), and signed payloads (P...) can be signer keys. | ||
* | ||
* @param {string} address a StrKey-encoded signer address | ||
* @returns {xdr.SignerKey} | ||
*/ | ||
static decodeAddress(address) { | ||
const signerKeyMap = { | ||
ed25519PublicKey: xdr.SignerKey.signerKeyTypeEd25519, | ||
preAuthTx: xdr.SignerKey.signerKeyTypePreAuthTx, | ||
sha256Hash: xdr.SignerKey.signerKeyTypeHashX, | ||
signedPayload: xdr.SignerKey.signerKeyTypeEd25519SignedPayload | ||
}; | ||
|
||
const vb = StrKey.getVersionByteForPrefix(address); | ||
const encoder = signerKeyMap[vb]; | ||
if (!encoder) { | ||
throw new Error(`invalid signer key type (${vb})`); | ||
} | ||
|
||
const raw = decodeCheck(vb, address); | ||
switch (vb) { | ||
case 'signedPayload': | ||
return encoder( | ||
new xdr.SignerKeyEd25519SignedPayload({ | ||
ed25519: raw.slice(0, 32), | ||
payload: raw.slice(32 + 4) | ||
}) | ||
); | ||
|
||
case 'ed25519PublicKey': // falls through | ||
case 'preAuthTx': // falls through | ||
case 'sha256Hash': // falls through | ||
default: | ||
return encoder(raw); | ||
} | ||
} | ||
|
||
/** | ||
* Encodes a signer key into its StrKey equivalent. | ||
* | ||
* @param {xdr.SignerKey} signerKey the signer | ||
* @returns {string} the StrKey representation of the signer | ||
*/ | ||
static encodeSignerKey(signerKey) { | ||
let strkeyType; | ||
let raw; | ||
|
||
switch (signerKey.switch()) { | ||
case xdr.SignerKeyType.signerKeyTypeEd25519(): | ||
strkeyType = 'ed25519PublicKey'; | ||
raw = signerKey.value(); | ||
break; | ||
|
||
case xdr.SignerKeyType.signerKeyTypePreAuthTx(): | ||
strkeyType = 'preAuthTx'; | ||
raw = signerKey.value(); | ||
break; | ||
|
||
case xdr.SignerKeyType.signerKeyTypeHashX(): | ||
strkeyType = 'sha256Hash'; | ||
raw = signerKey.value(); | ||
break; | ||
|
||
case xdr.SignerKeyType.signerKeyTypeEd25519SignedPayload(): | ||
strkeyType = 'signedPayload'; | ||
raw = signerKey.ed25519SignedPayload().toXDR('raw'); | ||
break; | ||
|
||
default: | ||
throw new Error(`invalid SignerKey (type: ${signerKey.switch()})`); | ||
} | ||
|
||
return encodeCheck(strkeyType, raw); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
describe('SignerKey', function() { | ||
describe('encode/decode roundtrip', function() { | ||
const TEST_CASES = [ | ||
{ | ||
strkey: 'GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ', | ||
type: StellarBase.xdr.SignerKeyType.signerKeyTypeEd25519() | ||
}, | ||
{ | ||
strkey: 'TBU2RRGLXH3E5CQHTD3ODLDF2BWDCYUSSBLLZ5GNW7JXHDIYKXZWHXL7', | ||
type: StellarBase.xdr.SignerKeyType.signerKeyTypePreAuthTx() | ||
}, | ||
{ | ||
strkey: 'XBU2RRGLXH3E5CQHTD3ODLDF2BWDCYUSSBLLZ5GNW7JXHDIYKXZWGTOG', | ||
type: StellarBase.xdr.SignerKeyType.signerKeyTypeHashX() | ||
}, | ||
{ | ||
strkey: | ||
'PA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAQACAQDAQCQMBYIBEFAWDANBYHRAEISCMKBKFQXDAMRUGY4DUPB6IBZGM', | ||
type: StellarBase.xdr.SignerKeyType.signerKeyTypeEd25519SignedPayload() | ||
} | ||
]; | ||
|
||
TEST_CASES.forEach((testCase) => { | ||
it(`works for ${testCase.strkey.substring(0, 5)}...`, function() { | ||
const skey = StellarBase.SignerKey.decodeAddress(testCase.strkey); | ||
expect(skey.switch()).to.eql(testCase.type); | ||
|
||
const rawXdr = skey.toXDR('raw'); | ||
const rawSk = StellarBase.xdr.SignerKey.fromXDR(rawXdr, 'raw'); | ||
expect(rawSk).to.eql(skey); | ||
|
||
const address = StellarBase.SignerKey.encodeSignerKey(skey); | ||
expect(address).to.equal(testCase.strkey); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('error cases', function() { | ||
[ | ||
// these are valid strkeys, just not valid signers | ||
'SAB5556L5AN5KSR5WF7UOEFDCIODEWEO7H2UR4S5R62DFTQOGLKOVZDY', | ||
'MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVAAAAAAAAAAAAAJLK', | ||
// this is (literal) nonsense | ||
'NONSENSE' | ||
].forEach((strkey) => { | ||
it(`fails on ${strkey.substring(0, 5)}...`, function() { | ||
expect(() => { | ||
StellarBase.SignerKey.decodeAddress(strkey); | ||
}).to.throw(/invalid signer key type/i); | ||
}); | ||
}); | ||
|
||
it('fails on invalid strkey', function() { | ||
expect(() => | ||
// address taken from strkey_test.js#invalidStrKeys | ||
StellarBase.SignerKey.decodeAddress( | ||
'G47QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVP2I' | ||
) | ||
).to.throw(/invalid version byte/i); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters