Skip to content

Commit 5b70b72

Browse files
authored
Merge pull request #7346 from BitGo/COIN-6180
feat(sdk-coin-canton): added handling is parse raw canton transaction to correctly extract the data
2 parents 6ef5e3f + f2422d3 commit 5b70b72

File tree

2 files changed

+65
-23
lines changed

2 files changed

+65
-23
lines changed

modules/sdk-coin-canton/src/lib/utils.ts

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -94,32 +94,47 @@ export class Utils implements BaseUtils {
9494

9595
const createNode = nodeType.create;
9696

97+
const getField = (fields: RecordField[], label: string) => fields.find((f) => f.label === label)?.value?.sum;
98+
9799
// Check if it's the correct template
98100
const template = createNode.templateId;
99-
if (template?.entityName !== 'AmuletTransferInstruction') return;
100-
101-
// Now parse the 'create' argument
102-
if (createNode.argument?.sum?.oneofKind !== 'record') return;
103-
const fields = createNode.argument?.sum?.record?.fields;
101+
const argSum = createNode.argument?.sum;
102+
if (!argSum || argSum.oneofKind !== 'record') return;
103+
const fields = argSum.record?.fields;
104104
if (!fields) return;
105-
106-
// Find the 'transfer' field
107-
const transferField = fields.find((f) => f.label === 'transfer');
108-
if (transferField?.value?.sum?.oneofKind !== 'record') return;
109-
const transferRecord = transferField?.value?.sum?.record?.fields;
110-
if (!transferRecord) return;
111-
112-
const getField = (fields: RecordField[], label: string) => fields.find((f) => f.label === label)?.value?.sum;
113-
114-
const senderData = getField(transferRecord, 'sender');
115-
if (!senderData || senderData.oneofKind !== 'party') return;
116-
sender = senderData.party;
117-
const receiverData = getField(transferRecord, 'receiver');
118-
if (!receiverData || receiverData.oneofKind !== 'party') return;
119-
receiver = receiverData.party;
120-
const amountData = getField(transferRecord, 'amount');
121-
if (!amountData || amountData.oneofKind !== 'numeric') return;
122-
amount = amountData.numeric;
105+
if (template?.entityName === 'AmuletTransferInstruction') {
106+
const transferField = fields.find((f) => f.label === 'transfer');
107+
const transferSum = transferField?.value?.sum;
108+
if (!transferSum || transferSum.oneofKind !== 'record') return;
109+
const transferRecord = transferSum.record?.fields;
110+
if (!transferRecord) return;
111+
const senderData = getField(transferRecord, 'sender');
112+
if (senderData?.oneofKind === 'party') sender = senderData.party ?? '';
113+
114+
const receiverData = getField(transferRecord, 'receiver');
115+
if (receiverData?.oneofKind === 'party') receiver = receiverData.party ?? '';
116+
117+
const amountData = getField(transferRecord, 'amount');
118+
if (amountData?.oneofKind === 'numeric') amount = amountData.numeric ?? '';
119+
} else if (template?.entityName === 'Amulet') {
120+
const dsoData = getField(fields, 'dso');
121+
if (dsoData?.oneofKind === 'party') sender = dsoData.party ?? '';
122+
const ownerData = getField(fields, 'owner');
123+
if (ownerData?.oneofKind === 'party') receiver = ownerData.party ?? '';
124+
const amountField = getField(fields, 'amount');
125+
if (!amountField || amountField.oneofKind !== 'record') return;
126+
127+
const amountRecord = amountField.record?.fields;
128+
if (!amountRecord) return;
129+
const initialAmountData = getField(amountRecord, 'initialAmount');
130+
if (initialAmountData?.oneofKind === 'numeric') amount = initialAmountData.numeric ?? '';
131+
} else if (template?.entityName === 'TransferPreapprovalProposal') {
132+
const receiverData = getField(fields, 'receiver');
133+
if (receiverData?.oneofKind === 'party') receiver = receiverData.party ?? '';
134+
const providerData = getField(fields, 'provider');
135+
if (providerData?.oneofKind === 'party') sender = providerData.party ?? '';
136+
amount = '0';
137+
}
123138
});
124139
if (!sender || !receiver || !amount) {
125140
const missingFields: string[] = [];

modules/sdk-coin-canton/test/unit/utils.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import utils from '../../src/lib/utils';
44
import {
55
CANTON_ADDRESSES,
66
GenerateTopologyResponse,
7+
OneStepPreApprovalPrepareResponse,
78
PreparedTransactionRawData,
89
PrepareSubmissionResponse,
10+
TransferAcceptancePrepareResponse,
911
} from '../resources';
1012

1113
describe('Canton Util', function () {
@@ -17,6 +19,31 @@ describe('Canton Util', function () {
1719
assert.equal(parsedData.receiver, 'abc-2::12207e96ada18a845adf4dc01410265633d5266dca9bb280c98e35c3692db87d3e35');
1820
assert.equal(parsedData.amount, '20.0000000000');
1921
});
22+
23+
it('should parse the acceptance prepared transaction', () => {
24+
const parsedData = utils.parseRawCantonTransactionData(TransferAcceptancePrepareResponse.preparedTransaction);
25+
should.exist(parsedData);
26+
assert.equal(parsedData.sender, 'DSO::1220be58c29e65de40bf273be1dc2b266d43a9a002ea5b18955aeef7aac881bb471a');
27+
assert.equal(
28+
parsedData.receiver,
29+
'ravi-demo-party-txn-01-tapper::1220ea7ab5a723f8a6b2078e617e6c58cb7e78e49947ddc239e1a941aa56e6ba08b4'
30+
);
31+
assert.equal(parsedData.amount, '5.0000000000');
32+
});
33+
34+
it('should parse the one-step preapproval prepared transaction', () => {
35+
const parsedData = utils.parseRawCantonTransactionData(OneStepPreApprovalPrepareResponse.preparedTransaction);
36+
should.exist(parsedData);
37+
assert.equal(
38+
parsedData.sender,
39+
'Bitgo-devnet-validator-1::1220a0a0f60b0e62b5d750c484b18c091dba23080c133d944614ba75a5858cba3045'
40+
);
41+
assert.equal(
42+
parsedData.receiver,
43+
'ravi-test-party-1::12205b4e3537a95126d90604592344d8ad3c3ddccda4f79901954280ee19c576714d'
44+
);
45+
assert.equal(parsedData.amount, '0');
46+
});
2047
});
2148

2249
describe('Wallet init transaction', function () {

0 commit comments

Comments
 (0)