Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions src/get_claimable_balance_id.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import xdr from './xdr';

function parseTransactionResult(transactionResult) {
if (typeof transactionResult === 'string') {
return xdr.TransactionResult.fromXDR(transactionResult, 'base64');
}

if (typeof Buffer !== 'undefined' && Buffer.isBuffer(transactionResult)) {
return xdr.TransactionResult.fromXDR(transactionResult);
}

if (!transactionResult || typeof transactionResult.result !== 'function') {
throw new TypeError(
'transactionResult must be a base64 string, Buffer, or xdr.TransactionResult'
);
}

return transactionResult;
}

function getOperationResults(transactionResult) {
const result = transactionResult.result();
const resultCode = result.switch().name;

if (resultCode === 'txSuccess') {
return result.results();
}

if (resultCode === 'txFeeBumpInnerSuccess') {
return result
.innerResultPair()
.result()
.result()
.results();
}

throw new Error(
`transaction result does not contain successful operation results: ${resultCode}`
);
}
Comment on lines +21 to +40

/**
* getClaimableBalanceIdFromResult extracts a successful createClaimableBalance
* operation's balance ID from a transaction result XDR.
*
* @export
* @param {string|Buffer|xdr.TransactionResult} transactionResult - The transaction
* result XDR as base64, raw Buffer, or XDR object.
* @param {number} [opIndex=0] - The operation index containing
* createClaimableBalance. Defaults to the first operation result.
*
* @return {string} the claimable balance ID as a hex string.
*/
export function getClaimableBalanceIdFromResult(
transactionResult,
opIndex = 0
Comment on lines +47 to +56
) {
if (!Number.isInteger(opIndex) || opIndex < 0) {
throw new RangeError(`invalid operation index: ${opIndex}`);
}

const operationResults = getOperationResults(
parseTransactionResult(transactionResult)
);

if (opIndex >= operationResults.length) {
throw new RangeError(
`invalid operation index: ${opIndex}; valid range is 0..${
operationResults.length - 1
}`
);
}
Comment on lines +58 to +72

const operationResult = operationResults[opIndex];
if (operationResult.switch().name !== 'opInner') {
throw new TypeError(
`expected successful operation result, got ${operationResult.switch().name}`
);
}

const operationResultTr = operationResult.tr();
if (operationResultTr.switch().name !== 'createClaimableBalance') {
throw new TypeError(
`expected createClaimableBalance result, got ${operationResultTr.switch().name}`
);
}

const createClaimableBalanceResult =
operationResultTr.createClaimableBalanceResult();
if (
createClaimableBalanceResult.switch().name !==
'createClaimableBalanceSuccess'
) {
throw new TypeError(
`expected successful createClaimableBalance result, got ${createClaimableBalanceResult.switch().name}`
);
}

return createClaimableBalanceResult.balanceId().toXDR('hex');
}
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export {
getLiquidityPoolId,
LiquidityPoolFeeV18
} from './get_liquidity_pool_id';
export { getClaimableBalanceIdFromResult } from './get_claimable_balance_id';
export { Keypair } from './keypair';
export { UnsignedHyper, Hyper } from '@stellar/js-xdr';
export { TransactionBase } from './transaction_base';
Expand Down
108 changes: 108 additions & 0 deletions test/unit/get_claimable_balance_id_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
function buildClaimableBalanceResult() {
const balanceId = StellarBase.xdr.ClaimableBalanceId.claimableBalanceIdTypeV0(
Buffer.from(
'536af35c666a28d26775008321655e9eda2039154270484e3f81d72c66d5c26f',
'hex'
Comment on lines +1 to +5
)
);

const createClaimableBalanceResult =
StellarBase.xdr.CreateClaimableBalanceResult.createClaimableBalanceSuccess(
balanceId
);
const operationResultTr =
StellarBase.xdr.OperationResultTr.createClaimableBalance(
createClaimableBalanceResult
);
const operationResult = StellarBase.xdr.OperationResult.opInner(
operationResultTr
);

return {
balanceId,
operationResult
};
}

function buildTransactionResult(result) {
return new StellarBase.xdr.TransactionResult({
feeCharged: StellarBase.xdr.Int64.fromString('100'),
result,
ext: new StellarBase.xdr.TransactionResultExt(0)
});
}

describe('StellarBase#getClaimableBalanceIdFromResult()', function () {
it('extracts the claimable balance ID from a result XDR string', function () {
const { balanceId, operationResult } = buildClaimableBalanceResult();
const transactionResult = buildTransactionResult(
StellarBase.xdr.TransactionResultResult.txSuccess([operationResult])
);

expect(
StellarBase.getClaimableBalanceIdFromResult(
transactionResult.toXDR('base64')
)
).to.equal(balanceId.toXDR('hex'));
});

it('extracts the claimable balance ID from a TransactionResult object', function () {
const { balanceId, operationResult } = buildClaimableBalanceResult();
const transactionResult = buildTransactionResult(
StellarBase.xdr.TransactionResultResult.txSuccess([operationResult])
);

expect(
StellarBase.getClaimableBalanceIdFromResult(transactionResult)
).to.equal(balanceId.toXDR('hex'));
});

it('extracts the claimable balance ID from a successful fee bump inner result', function () {
const { balanceId, operationResult } = buildClaimableBalanceResult();
const innerResult = new StellarBase.xdr.InnerTransactionResult({
feeCharged: StellarBase.xdr.Int64.fromString('100'),
result: StellarBase.xdr.InnerTransactionResultResult.txSuccess([
operationResult
]),
ext: new StellarBase.xdr.InnerTransactionResultExt(0)
});
const innerResultPair = new StellarBase.xdr.InnerTransactionResultPair({
transactionHash: Buffer.alloc(32),
result: innerResult
});
const transactionResult = buildTransactionResult(
StellarBase.xdr.TransactionResultResult.txFeeBumpInnerSuccess(
innerResultPair
)
);

expect(
StellarBase.getClaimableBalanceIdFromResult(transactionResult)
).to.equal(balanceId.toXDR('hex'));
});

it('throws when the operation index is invalid', function () {
const { operationResult } = buildClaimableBalanceResult();
const transactionResult = buildTransactionResult(
StellarBase.xdr.TransactionResultResult.txSuccess([operationResult])
);

expect(() =>
StellarBase.getClaimableBalanceIdFromResult(transactionResult, -1)
).to.throw(/operation index/);
expect(() =>
StellarBase.getClaimableBalanceIdFromResult(transactionResult, 1)
).to.throw(/operation index/);
});

it('throws when the transaction result is not successful', function () {
const { operationResult } = buildClaimableBalanceResult();
const transactionResult = buildTransactionResult(
StellarBase.xdr.TransactionResultResult.txFailed([operationResult])
);

expect(() =>
StellarBase.getClaimableBalanceIdFromResult(transactionResult)
).to.throw(/txFailed/);
});
});
4 changes: 4 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ export class Keypair {
export const LiquidityPoolFeeV18 = 30;

export function getLiquidityPoolId(liquidityPoolType: LiquidityPoolType, liquidityPoolParameters: LiquidityPoolParameters): Buffer;
export function getClaimableBalanceIdFromResult(
transactionResult: string | Buffer | xdr.TransactionResult,
opIndex?: number,
): string;

export namespace LiquidityPoolParameters {
interface ConstantProduct {
Expand Down
1 change: 1 addition & 0 deletions types/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const usd = new StellarSdk.Asset('USD', 'GDGU5OAPHNPU5UCLE5RDJHG7PXZFQYWKCFOEXSX
const account = new StellarSdk.Account(sourceKey.publicKey(), '1'); // $ExpectType Account
const muxedAccount = new StellarSdk.MuxedAccount(account, '123'); // $ExpectType MuxedAccount
const muxedConforms = muxedAccount as StellarSdk.Account; // $ExpectType Account
StellarSdk.getClaimableBalanceIdFromResult('AAAA'); // $ExpectType string

const transaction = new StellarSdk.TransactionBuilder(account, {
fee: "100",
Expand Down