Skip to content

Commit 58c0138

Browse files
committed
Add strkey support for liquidity pools and claimable balances (#799)
1 parent b63fe3a commit 58c0138

File tree

3 files changed

+116
-4
lines changed

3 files changed

+116
-4
lines changed

src/strkey.js

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ const versionBytes = {
1010
preAuthTx: 19 << 3, // T
1111
sha256Hash: 23 << 3, // X
1212
signedPayload: 15 << 3, // P
13-
contract: 2 << 3 // C
13+
contract: 2 << 3, // C
14+
liquidityPool: 11 << 3, // L
15+
claimableBalance: 1 << 3 // B
1416
};
1517

1618
const strkeyTypes = {
@@ -20,7 +22,9 @@ const strkeyTypes = {
2022
T: 'preAuthTx',
2123
X: 'sha256Hash',
2224
P: 'signedPayload',
23-
C: 'contract'
25+
C: 'contract',
26+
L: 'liquidityPool',
27+
B: 'claimableBalance'
2428
};
2529

2630
/**
@@ -205,6 +209,60 @@ export class StrKey {
205209
return isValid('contract', address);
206210
}
207211

212+
/**
213+
* Encodes raw data to strkey claimable balance (B...).
214+
* @param {Buffer} data data to encode
215+
* @returns {string}
216+
*/
217+
static encodeClaimableBalance(data) {
218+
return encodeCheck('claimableBalance', data);
219+
}
220+
221+
/**
222+
* Decodes strkey contract (B...) to raw data.
223+
* @param {string} address balance to decode
224+
* @returns {Buffer}
225+
*/
226+
static decodeClaimableBalance(address) {
227+
return decodeCheck('claimableBalance', address);
228+
}
229+
230+
/**
231+
* Checks validity of alleged claimable balance (B...) strkey address.
232+
* @param {string} address balance to check
233+
* @returns {boolean}
234+
*/
235+
static isValidClaimableBalance(address) {
236+
return isValid('claimableBalance', address);
237+
}
238+
239+
/**
240+
* Encodes raw data to strkey liquidity pool (L...).
241+
* @param {Buffer} data data to encode
242+
* @returns {string}
243+
*/
244+
static encodeLiquidityPool(data) {
245+
return encodeCheck('liquidityPool', data);
246+
}
247+
248+
/**
249+
* Decodes strkey liquidity pool (L...) to raw data.
250+
* @param {string} address address to decode
251+
* @returns {Buffer}
252+
*/
253+
static decodeLiquidityPool(address) {
254+
return decodeCheck('liquidityPool', address);
255+
}
256+
257+
/**
258+
* Checks validity of alleged liquidity pool (L...) strkey address.
259+
* @param {string} address pool to check
260+
* @returns {boolean}
261+
*/
262+
static isValidLiquidityPool(address) {
263+
return isValid('liquidityPool', address);
264+
}
265+
208266
static getVersionByteForPrefix(address) {
209267
return strkeyTypes[address[0]];
210268
}
@@ -234,12 +292,19 @@ function isValid(versionByteName, encoded) {
234292
case 'ed25519SecretSeed': // falls through
235293
case 'preAuthTx': // falls through
236294
case 'sha256Hash': // falls through
237-
case 'contract':
295+
case 'contract': // falls through
296+
case 'liquidityPool':
238297
if (encoded.length !== 56) {
239298
return false;
240299
}
241300
break;
242301

302+
case 'claimableBalance':
303+
if (encoded.length !== 58) {
304+
return false;
305+
}
306+
break;
307+
243308
case 'med25519PublicKey':
244309
if (encoded.length !== 69) {
245310
return false;
@@ -270,8 +335,12 @@ function isValid(versionByteName, encoded) {
270335
case 'preAuthTx': // falls through
271336
case 'sha256Hash': // falls through
272337
case 'contract':
338+
case 'liquidityPool':
273339
return decoded.length === 32;
274340

341+
case 'claimableBalance':
342+
return decoded.length === 32 + 1; // +1 byte for discriminant
343+
275344
case 'med25519PublicKey':
276345
return decoded.length === 40; // +8 bytes for the ID
277346

test/unit/strkey_test.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,37 @@ describe('StrKey', function () {
413413
});
414414
});
415415

416+
describe('#liquidityPools', function () {
417+
it('valid w/ 32-byte hash', function () {
418+
const strkey = 'LA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUPJN';
419+
const asHex =
420+
'3f0c34bf93ad0d9971d04ccc90f705511c838aad9734a4a2fb0d7a03fc7fe89a';
421+
expect(StellarBase.StrKey.isValidLiquidityPool(strkey)).to.be.true;
422+
expect(
423+
StellarBase.StrKey.decodeLiquidityPool(strkey).toString('hex')
424+
).to.equal(asHex);
425+
expect(
426+
StellarBase.StrKey.encodeLiquidityPool(Buffer.from(asHex, 'hex'))
427+
).to.equal(strkey);
428+
});
429+
});
430+
431+
describe('#claimableBalances', function () {
432+
it('valid w/ 33-byte strkey', function () {
433+
const strkey =
434+
'BAAD6DBUX6J22DMZOHIEZTEQ64CVCHEDRKWZONFEUL5Q26QD7R76RGR4TU';
435+
const asHex =
436+
'003f0c34bf93ad0d9971d04ccc90f705511c838aad9734a4a2fb0d7a03fc7fe89a';
437+
expect(StellarBase.StrKey.isValidClaimableBalance(strkey)).to.be.true;
438+
expect(
439+
StellarBase.StrKey.decodeClaimableBalance(strkey).toString('hex')
440+
).to.equal(asHex);
441+
expect(
442+
StellarBase.StrKey.encodeClaimableBalance(Buffer.from(asHex, 'hex'))
443+
).to.equal(strkey);
444+
});
445+
});
446+
416447
describe('#invalidStrKeys', function () {
417448
// From https://stellar.org/protocol/sep-23#invalid-test-cases
418449
const BAD_STRKEYS = [
@@ -430,7 +461,11 @@ describe('StrKey', function () {
430461
// Padding bytes are not allowed
431462
'MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAACJUK===',
432463
// Invalid checksum
433-
'MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAACJUO'
464+
'MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAACJUO',
465+
// Trailing bits should be zeroes
466+
'BAAD6DBUX6J22DMZOHIEZTEQ64CVCHEDRKWZONFEUL5Q26QD7R76RGR4TV',
467+
// Invalid claimable balance type
468+
'BAAT6DBUX6J22DMZOHIEZTEQ64CVCHEDRKWZONFEUL5Q26QD7R76RGXACA'
434469

435470
//
436471
// FIXME: The following test cases don't pass (i.e. don't throw).

types/index.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,14 @@ export namespace StrKey {
989989
function encodeContract(data: Buffer): string;
990990
function decodeContract(address: string): Buffer;
991991
function isValidContract(address: string): boolean;
992+
993+
function encodeClaimableBalance(data: Buffer): string;
994+
function decodeClaimableBalance(address: string): Buffer;
995+
function isValidClaimableBalance(address: string): boolean;
996+
997+
function encodeLiquidityPool(data: Buffer): string;
998+
function decodeLiquidityPool(address: string): Buffer;
999+
function isValidLiquidityPool(address: string): boolean;
9921000
}
9931001

9941002
export namespace SignerKey {

0 commit comments

Comments
 (0)