Skip to content
Merged
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
9 changes: 8 additions & 1 deletion modules/sdk-coin-canton/src/canton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,17 @@ export class Canton extends BaseCoin {
if (txParams.recipients !== undefined) {
const filteredRecipients = txParams.recipients?.map((recipient) => {
const { address, amount } = recipient;
const [addressPart, memoId] = address.split('?memoId=');
if (memoId) {
return { address: addressPart, amount, memo: memoId };
}
return { address, amount };
});
const filteredOutputs = explainedTx.outputs?.map((output) => {
const { address, amount } = output;
const { address, amount, memo } = output;
if (memo) {
return { address, amount, memo };
}
return { address, amount };
});
if (JSON.stringify(filteredRecipients) !== JSON.stringify(filteredOutputs)) {
Expand Down
2 changes: 2 additions & 0 deletions modules/sdk-coin-canton/src/lib/iface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ export interface TxData {
receiver: string;
amount: string;
acknowledgeData?: TransferAcknowledge;
memoId?: string;
}

export interface PreparedTxnParsedInfo {
sender: string;
receiver: string;
amount: string;
memoId?: string;
}

export interface WalletInitTxData {
Expand Down
12 changes: 11 additions & 1 deletion modules/sdk-coin-canton/src/lib/transaction/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ export class Transaction extends BaseTransaction {
result.sender = parsedInfo.sender;
result.receiver = parsedInfo.receiver;
result.amount = parsedInfo.amount;
if (parsedInfo.memoId) {
result.memoId = parsedInfo.memoId;
}
return result;
}

Expand Down Expand Up @@ -244,7 +247,14 @@ export class Transaction extends BaseTransaction {
}
case TransactionType.Send: {
const txData = this.toJson();
outputs.push({ address: txData.receiver, amount: txData.amount });
const output: ITransactionRecipient = {
address: txData.receiver,
amount: txData.amount,
};
if (txData.memoId) {
output.memo = txData.memoId;
}
outputs.push(output);
outputAmount = txData.amount;
break;
}
Expand Down
25 changes: 24 additions & 1 deletion modules/sdk-coin-canton/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export class Utils implements BaseUtils {
let sender = '';
let receiver = '';
let amount = '';
let memoId: string | undefined;
let preApprovalNode: RecordField[] = [];
let transferNode: RecordField[] = [];
let transferAcceptRejectNode: RecordField[] = [];
Expand Down Expand Up @@ -161,6 +162,24 @@ export class Utils implements BaseUtils {

const amountData = getField(transferRecord, 'amount');
if (amountData?.oneofKind === 'numeric') amount = amountData.numeric ?? '';

const metaField = getField(transferRecord, 'meta');
if (metaField?.oneofKind === 'record') {
const metaFields = metaField.record?.fields;
if (metaFields && metaFields.length) {
const valuesField = getField(metaFields, 'values');
if (valuesField?.oneofKind === 'textMap') {
const entries = valuesField.textMap?.entries ?? [];
const memoEntry = entries.find((e) => e.key === 'splice.lfdecentralizedtrust.org/reason');
if (memoEntry) {
const memoValue = memoEntry?.value?.sum;
if (memoValue?.oneofKind === 'text') {
memoId = memoValue.text;
}
}
}
}
}
}
}
} else if (transferAcceptRejectNode.length) {
Expand All @@ -185,11 +204,15 @@ export class Utils implements BaseUtils {
throw new Error(`invalid transaction data: missing ${missingFields.join(', ')}`);
}
const convertedAmount = this.convertAmountToLowestUnit(new BigNumber(amount));
return {
const parsedData: PreparedTxnParsedInfo = {
sender,
receiver,
amount: convertedAmount,
};
if (memoId) {
parsedData.memoId = memoId;
}
return parsedData;
}

/**
Expand Down
19 changes: 19 additions & 0 deletions modules/sdk-coin-canton/test/integration/canton.integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import {
GenerateTopologyResponse,
TransferAcceptRawTransaction,
TransferRawTxn,
TransferRawTxnWithMemo,
TransferRejectRawTransaction,
TxParams,
TxParamsWithMemo,
WalletInitRawTransaction,
} from '../resources';
import { Tcanton } from '../../src';
Expand Down Expand Up @@ -54,6 +56,23 @@ describe('Canton integration tests', function () {
const isTxnVerifies = await basecoin.verifyTransaction({ txPrebuild: txPrebuild, txParams: txParams, wallet });
isTxnVerifies.should.equal(true);
});

it('should verify transfer transaction with memo', async function () {
const txPrebuild = {
txHex: TransferRawTxnWithMemo,
txInfo: {},
};
const txParams = {
recipients: [
{
address: TxParamsWithMemo.RECIPIENT_ADDRESS,
amount: TxParamsWithMemo.AMOUNT,
},
],
};
const isTxnVerifies = await basecoin.verifyTransaction({ txPrebuild: txPrebuild, txParams: txParams, wallet });
isTxnVerifies.should.equal(true);
});
});

describe('Explain raw transaction', function () {
Expand Down
11 changes: 11 additions & 0 deletions modules/sdk-coin-canton/test/resources.ts

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions modules/sdk-coin-canton/test/unit/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
GenerateTopologyResponse,
OneStepPreApprovalPrepareResponse,
PreparedTransactionRawData,
PreparedTransactionWithMemo,
PreparedTxn1StepReceiver,
PreparedTxn2StepReceiver,
PrepareSubmissionResponse,
Expand All @@ -27,6 +28,15 @@ describe('Canton Util', function () {
assert.equal(parsedData.amount, '200000000000');
});

it('should parse the prepared transaction with memo id field', function () {
const parsedData = utils.parseRawCantonTransactionData(PreparedTransactionWithMemo, TransactionType.Send);
should.exist(parsedData);
assert.equal(parsedData.sender, '1220b::1220bab6ef3eec37b1b3816099befe72b43bf6c1380077d6349254c41ffb7f7753bb');
assert.equal(parsedData.receiver, '1220a::1220ade60300cf7d0b18ffaa2ffe4f492ad1ad601cfc162b20f77ec99d16c2c2f158');
assert.equal(parsedData.amount, '1000000000');
assert.equal(parsedData.memoId, '11');
});

it('should parse correctly when receiver is on 2-step', () => {
const parsedData = utils.parseRawCantonTransactionData(PreparedTxn2StepReceiver, TransactionType.Send);
should.exist(parsedData);
Expand Down