@notabene/javascript-sdk 2.14.1 → 2.14.2-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -4
- package/dist/cjs/notabene.cjs +23 -1
- package/dist/cjs/notabene.d.ts +79 -50
- package/dist/cjs/package.json +1 -1
- package/dist/esm/notabene.d.ts +79 -50
- package/dist/esm/notabene.js +12114 -454
- package/dist/esm/package.json +1 -1
- package/dist/notabene.d.ts +79 -50
- package/dist/notabene.js +12114 -454
- package/package.json +1 -1
- package/src/responseTransformer/__tests__/transformer.test.ts +638 -0
- package/src/responseTransformer/__tests__/utils.test.ts +35 -0
- package/src/responseTransformer/mappers.ts +88 -26
- package/src/responseTransformer/transformer.ts +121 -73
- package/src/responseTransformer/types.ts +12 -1
- package/src/responseTransformer/utils.ts +37 -1
- package/src/types.ts +6 -2
- package/src/utils/arbitraries.ts +1 -1
|
@@ -7,18 +7,26 @@ import type {
|
|
|
7
7
|
} from '@notabene/javascript-sdk/src/ivms/types';
|
|
8
8
|
import type { Agent } from '@taprsvp/types';
|
|
9
9
|
import {
|
|
10
|
+
Deposit,
|
|
10
11
|
PersonType,
|
|
11
12
|
type IVMS101,
|
|
12
13
|
type V1Transaction,
|
|
13
14
|
type Withdrawal,
|
|
14
15
|
} from '../types';
|
|
15
16
|
import type {
|
|
16
|
-
|
|
17
|
+
ResponseToIVMS101RequestConfig,
|
|
18
|
+
ResponseToTxCreateRequestConfig,
|
|
17
19
|
TransactionCreateRequest,
|
|
18
20
|
TransactionCreateRequestV2,
|
|
19
21
|
TransactionIVMS101Request,
|
|
20
22
|
} from './types';
|
|
21
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
convertPersonToV2,
|
|
25
|
+
getCaip10ChainPrefix,
|
|
26
|
+
getPartyId,
|
|
27
|
+
isDeposit,
|
|
28
|
+
isWithdrawal,
|
|
29
|
+
} from './utils';
|
|
22
30
|
|
|
23
31
|
// Constants
|
|
24
32
|
const DEFAULT_GEOGRAPHIC_ADDRESS = [
|
|
@@ -227,16 +235,28 @@ export function mapToV1CreateRequest(
|
|
|
227
235
|
}
|
|
228
236
|
|
|
229
237
|
export function mapToTransactCreateRequest(
|
|
230
|
-
|
|
238
|
+
transaction: Withdrawal | Deposit,
|
|
231
239
|
payload: V1Transaction,
|
|
232
|
-
config:
|
|
240
|
+
config: ResponseToTxCreateRequestConfig = {},
|
|
233
241
|
): TransactionCreateRequestV2 {
|
|
242
|
+
// For withdrawals: customer sends to counterparty
|
|
243
|
+
// For deposits: counterparty sends to customer
|
|
244
|
+
const isWithdrawalTx = isWithdrawal(transaction);
|
|
245
|
+
const originatorParty = isWithdrawalTx
|
|
246
|
+
? transaction.customer
|
|
247
|
+
: transaction.counterparty;
|
|
248
|
+
const beneficiaryParty = isWithdrawalTx
|
|
249
|
+
? transaction.counterparty
|
|
250
|
+
: transaction.customer;
|
|
251
|
+
|
|
234
252
|
const originatorId =
|
|
235
|
-
config?.originatorId || getPartyId('originator',
|
|
253
|
+
config?.originatorId || getPartyId('originator', originatorParty);
|
|
236
254
|
const beneficiaryId =
|
|
237
|
-
config?.beneficiaryId || getPartyId('beneficiary',
|
|
255
|
+
config?.beneficiaryId || getPartyId('beneficiary', beneficiaryParty);
|
|
238
256
|
const referenceId =
|
|
239
|
-
config?.referenceId ||
|
|
257
|
+
config?.referenceId ||
|
|
258
|
+
payload.transactionId ||
|
|
259
|
+
Math.random().toString(36).substring(2, 15);
|
|
240
260
|
const agents: Agent[] = [];
|
|
241
261
|
|
|
242
262
|
if (payload.originatorVASPdid) {
|
|
@@ -255,47 +275,89 @@ export function mapToTransactCreateRequest(
|
|
|
255
275
|
});
|
|
256
276
|
}
|
|
257
277
|
|
|
258
|
-
if (
|
|
278
|
+
if (isWithdrawal(transaction) && transaction?.account?.did) {
|
|
259
279
|
agents.push({
|
|
260
|
-
'@id':
|
|
280
|
+
'@id': transaction.account.did,
|
|
261
281
|
for: payload.beneficiaryVASPdid || beneficiaryId,
|
|
262
282
|
role: 'SettlementAddress',
|
|
263
283
|
});
|
|
264
284
|
}
|
|
265
285
|
|
|
286
|
+
if (isDeposit(transaction) && transaction?.account) {
|
|
287
|
+
if (transaction.account.did) {
|
|
288
|
+
agents.push({
|
|
289
|
+
'@id': transaction.account.did,
|
|
290
|
+
for: payload.originatorVASPdid || originatorId,
|
|
291
|
+
role: 'SourceAddress',
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (config.settlementAddress && transaction.account.caip10) {
|
|
296
|
+
const chainPrefix = getCaip10ChainPrefix(transaction.account.caip10);
|
|
297
|
+
agents.push({
|
|
298
|
+
'@id': `did:pkh:${chainPrefix}:${config.settlementAddress}`,
|
|
299
|
+
for: payload.beneficiaryVASPdid || beneficiaryId,
|
|
300
|
+
role: 'SettlementAddress',
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
266
305
|
return {
|
|
267
306
|
originator: { '@id': originatorId },
|
|
268
307
|
beneficiary: { '@id': beneficiaryId },
|
|
269
|
-
asset:
|
|
270
|
-
amount:
|
|
308
|
+
asset: transaction.asset,
|
|
309
|
+
amount: transaction.amountDecimal?.toString() || payload.transactionAmount,
|
|
271
310
|
agents,
|
|
272
311
|
ref: referenceId,
|
|
273
312
|
};
|
|
274
313
|
}
|
|
275
314
|
|
|
276
315
|
export function mapToAppendPiiRequest(
|
|
277
|
-
|
|
316
|
+
transaction: Withdrawal | Deposit,
|
|
278
317
|
ivms101: IVMS101,
|
|
279
|
-
config:
|
|
318
|
+
config: ResponseToIVMS101RequestConfig = {},
|
|
280
319
|
): TransactionIVMS101Request {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
320
|
+
if (isWithdrawal(transaction)) {
|
|
321
|
+
const beneficiaryId =
|
|
322
|
+
config.beneficiaryId ||
|
|
323
|
+
getPartyId('beneficiary', transaction.counterparty);
|
|
324
|
+
|
|
325
|
+
const beneficiaryPersons =
|
|
326
|
+
// If counterparty type is SELF, reuse originator data for beneficiary
|
|
327
|
+
transaction.counterparty?.type === PersonType.SELF && config.originator
|
|
328
|
+
? config.originator.originatorPerson
|
|
329
|
+
: // Convert all beneficiary persons from V1 to V2 format
|
|
330
|
+
ivms101.beneficiary?.beneficiaryPersons?.map((person) =>
|
|
331
|
+
convertPersonToV2(person, beneficiaryId),
|
|
332
|
+
) || [];
|
|
333
|
+
|
|
334
|
+
return {
|
|
335
|
+
ivms101: {
|
|
336
|
+
originator: config.originator,
|
|
337
|
+
beneficiary: {
|
|
338
|
+
beneficiaryPerson: beneficiaryPersons,
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const originatorId =
|
|
345
|
+
config.originatorId || getPartyId('originator', transaction.counterparty);
|
|
346
|
+
|
|
347
|
+
const originatorPersons =
|
|
348
|
+
transaction.counterparty?.type === PersonType.SELF && config.beneficiary
|
|
349
|
+
? config.beneficiary.beneficiaryPerson
|
|
350
|
+
: // Convert all originator persons from V1 to V2 format
|
|
351
|
+
ivms101.originator?.originatorPersons?.map((person) =>
|
|
352
|
+
convertPersonToV2(person, originatorId),
|
|
291
353
|
) || [];
|
|
292
354
|
|
|
293
355
|
return {
|
|
294
356
|
ivms101: {
|
|
295
|
-
originator:
|
|
296
|
-
|
|
297
|
-
beneficiaryPerson: beneficiaryPersons,
|
|
357
|
+
originator: {
|
|
358
|
+
originatorPerson: originatorPersons,
|
|
298
359
|
},
|
|
360
|
+
beneficiary: config.beneficiary,
|
|
299
361
|
},
|
|
300
362
|
};
|
|
301
363
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { decodeJwt } from 'jose';
|
|
2
2
|
import {
|
|
3
|
+
Deposit,
|
|
4
|
+
DID,
|
|
3
5
|
PersonType,
|
|
4
6
|
type OwnershipProof,
|
|
5
7
|
type TransactionResponse,
|
|
@@ -12,42 +14,65 @@ import {
|
|
|
12
14
|
} from './mappers';
|
|
13
15
|
import type {
|
|
14
16
|
DelegateToken,
|
|
17
|
+
ResponseToIVMS101RequestConfig,
|
|
18
|
+
ResponseToTxCreateRequestConfig,
|
|
15
19
|
ResponseToTxRequestConfig,
|
|
16
20
|
TransactionCreateRequest,
|
|
17
21
|
TransactionCreateRequestV2,
|
|
18
22
|
TransactionIVMS101Request,
|
|
19
23
|
} from './types';
|
|
24
|
+
import { isDeposit, isWithdrawal } from './utils';
|
|
20
25
|
|
|
21
26
|
/**
|
|
22
|
-
* Fills in missing config values by extracting them from the delegate token and
|
|
27
|
+
* Fills in missing config values by extracting them from the delegate token and transaction data
|
|
23
28
|
* @internal
|
|
24
29
|
*/
|
|
25
|
-
function enrichConfig(
|
|
30
|
+
export function enrichConfig(
|
|
26
31
|
config: ResponseToTxRequestConfig,
|
|
27
32
|
delegateToken: string,
|
|
28
|
-
|
|
33
|
+
transaction: Withdrawal | Deposit,
|
|
29
34
|
): ResponseToTxRequestConfig {
|
|
30
35
|
const enrichedConfig = { ...config };
|
|
31
36
|
|
|
32
|
-
// Extract
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
// Extract customer ID from delegate token
|
|
38
|
+
// For withdrawals: customer is originator, for deposits: customer is beneficiary
|
|
39
|
+
let customerIdFromToken: DID | undefined;
|
|
40
|
+
try {
|
|
41
|
+
const tokenPayload = decodeJwt<DelegateToken>(delegateToken);
|
|
42
|
+
customerIdFromToken = tokenPayload?.sub;
|
|
43
|
+
} catch {
|
|
44
|
+
// If decoding fails, customerIdFromToken remains undefined
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (isWithdrawal(transaction)) {
|
|
48
|
+
// Withdrawal: customer sends to counterparty
|
|
49
|
+
if (!enrichedConfig.originatorId && customerIdFromToken) {
|
|
50
|
+
enrichedConfig.originatorId = customerIdFromToken;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!enrichedConfig.beneficiaryId) {
|
|
54
|
+
if (transaction.counterparty?.type === PersonType.SELF) {
|
|
55
|
+
enrichedConfig.beneficiaryId = enrichedConfig.originatorId;
|
|
56
|
+
} else if (transaction.destination) {
|
|
57
|
+
// Generate beneficiaryId from destination if not provided.
|
|
58
|
+
// TODO: Replace with proper DID key identifier creation
|
|
59
|
+
enrichedConfig.beneficiaryId = `did:key:${transaction.destination}`;
|
|
38
60
|
}
|
|
39
|
-
} catch {
|
|
40
|
-
// If decoding fails, originatorId remains undefined
|
|
41
61
|
}
|
|
42
|
-
}
|
|
62
|
+
} else if (isDeposit(transaction)) {
|
|
63
|
+
// Deposit: counterparty sends to customer
|
|
64
|
+
if (!enrichedConfig.beneficiaryId && customerIdFromToken) {
|
|
65
|
+
enrichedConfig.beneficiaryId = customerIdFromToken;
|
|
66
|
+
}
|
|
43
67
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
68
|
+
if (!enrichedConfig.originatorId) {
|
|
69
|
+
if (transaction.counterparty?.type === PersonType.SELF) {
|
|
70
|
+
enrichedConfig.originatorId = enrichedConfig.beneficiaryId;
|
|
71
|
+
} else if (transaction.source) {
|
|
72
|
+
// Generate originatorId from source if not provided.
|
|
73
|
+
// TODO: Replace with proper DID key identifier creation
|
|
74
|
+
enrichedConfig.originatorId = `did:key:${transaction.source}`;
|
|
75
|
+
}
|
|
51
76
|
}
|
|
52
77
|
}
|
|
53
78
|
|
|
@@ -115,51 +140,51 @@ export function componentResponseToV1TxCreateRequest(
|
|
|
115
140
|
* which is useful for V2 workflows where you need to create a transaction first,
|
|
116
141
|
* then append IVMS101 data to it, and finally confirm the relationship.
|
|
117
142
|
*
|
|
143
|
+
* ## IVMS101 Config by Transaction Type
|
|
144
|
+
*
|
|
145
|
+
* The `originator` and `beneficiary` config options provide the customer's PII data.
|
|
146
|
+
* Which one to use depends on the transaction type:
|
|
147
|
+
*
|
|
148
|
+
* - **Withdrawals**: Pass `originator` - the customer is sending funds (customer = originator)
|
|
149
|
+
* - **Deposits**: Pass `beneficiary` - the customer is receiving funds (customer = beneficiary)
|
|
150
|
+
*
|
|
151
|
+
* For self-transfers, the provided data is automatically reused for both parties.
|
|
152
|
+
*
|
|
118
153
|
* @param response - The response from the Notabene Embedded Component
|
|
119
|
-
* @param delegateToken - The JWT delegate token for extracting the
|
|
154
|
+
* @param delegateToken - The JWT delegate token for extracting the customer ID
|
|
120
155
|
* @param config - Optional configuration for IDs and reference
|
|
121
|
-
* @param config.originatorId - Optional originator ID (auto-extracted from delegateToken
|
|
122
|
-
* @param config.beneficiaryId - Optional beneficiary ID (auto-
|
|
156
|
+
* @param config.originatorId - Optional originator ID (auto-extracted from delegateToken for withdrawals)
|
|
157
|
+
* @param config.beneficiaryId - Optional beneficiary ID (auto-extracted from delegateToken for deposits)
|
|
123
158
|
* @param config.referenceId - Optional reference ID (auto-generated if not provided)
|
|
124
|
-
* @param config.originator -
|
|
159
|
+
* @param config.originator - Customer's IVMS101 data for withdrawals (customer is the sender)
|
|
160
|
+
* @param config.beneficiary - Customer's IVMS101 data for deposits (customer is the receiver)
|
|
125
161
|
* @returns Object with `createTx`, `ivms101`, and optional `confirmRelationship` properties containing the respective request bodies
|
|
126
162
|
*
|
|
127
163
|
* @example
|
|
128
164
|
* ```typescript
|
|
129
165
|
* import { componentResponseToTxRequests } from '$lib/notabene-tx-transformer';
|
|
130
166
|
*
|
|
167
|
+
* // For withdrawals: pass originator (customer is sending)
|
|
131
168
|
* withdrawal.on('complete', async (result) => {
|
|
132
|
-
* const { createTx, ivms101
|
|
169
|
+
* const { createTx, ivms101 } = componentResponseToTxRequests(
|
|
133
170
|
* result.response,
|
|
134
|
-
*
|
|
135
|
-
* { originator:
|
|
171
|
+
* delegateToken,
|
|
172
|
+
* { originator: customerIvmsData }
|
|
136
173
|
* );
|
|
174
|
+
* });
|
|
137
175
|
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* const txId = txResponse.transfer['@id'];
|
|
146
|
-
* await fetch(`/entity/${vaspDid}/tx/${txId}/append`, {
|
|
147
|
-
* method: 'POST',
|
|
148
|
-
* body: JSON.stringify(ivms101)
|
|
149
|
-
* });
|
|
150
|
-
*
|
|
151
|
-
* // Finally, confirm relationship
|
|
152
|
-
* if (confirmRelationship) {
|
|
153
|
-
* await fetch(`/entity/${vaspDid}/relationship?to=${to}&from=${from}`, {
|
|
154
|
-
* method: 'PATCH',
|
|
155
|
-
* body: JSON.stringify({ proof: confirmRelationship.proof })
|
|
156
|
-
* });
|
|
157
|
-
* }
|
|
176
|
+
* // For deposits: pass beneficiary (customer is receiving)
|
|
177
|
+
* deposit.on('complete', async (result) => {
|
|
178
|
+
* const { createTx, ivms101 } = componentResponseToTxRequests(
|
|
179
|
+
* result.response,
|
|
180
|
+
* delegateToken,
|
|
181
|
+
* { beneficiary: customerIvmsData }
|
|
182
|
+
* );
|
|
158
183
|
* });
|
|
159
184
|
* ```
|
|
160
185
|
*/
|
|
161
186
|
export function componentResponseToTxRequests(
|
|
162
|
-
response: TransactionResponse<Withdrawal>,
|
|
187
|
+
response: TransactionResponse<Withdrawal | Deposit>,
|
|
163
188
|
delegateToken: string,
|
|
164
189
|
config: ResponseToTxRequestConfig = {},
|
|
165
190
|
): {
|
|
@@ -169,17 +194,21 @@ export function componentResponseToTxRequests(
|
|
|
169
194
|
proof: OwnershipProof;
|
|
170
195
|
};
|
|
171
196
|
} {
|
|
172
|
-
|
|
197
|
+
const { value, txCreate, txUpdate, ivms101, proof } = response;
|
|
198
|
+
|
|
199
|
+
// For withdrawals: use txCreate, for deposits: use txUpdate
|
|
200
|
+
const txPayload = isWithdrawal(value) ? txCreate : txUpdate;
|
|
201
|
+
|
|
202
|
+
if (!txPayload || !ivms101) {
|
|
173
203
|
throw new Error(
|
|
174
|
-
'Invalid response: missing required txCreate or ivms101 data',
|
|
204
|
+
'Invalid response: missing required txCreate/txUpdate or ivms101 data',
|
|
175
205
|
);
|
|
176
206
|
}
|
|
177
207
|
|
|
178
|
-
const { value, txCreate, ivms101, proof } = response;
|
|
179
208
|
const enrichedConfig = enrichConfig(config, delegateToken, value);
|
|
180
209
|
|
|
181
210
|
return {
|
|
182
|
-
createTx: mapToTransactCreateRequest(value,
|
|
211
|
+
createTx: mapToTransactCreateRequest(value, txPayload, enrichedConfig),
|
|
183
212
|
ivms101: mapToAppendPiiRequest(value, ivms101, enrichedConfig),
|
|
184
213
|
...(proof && { confirmRelationship: { proof } }),
|
|
185
214
|
};
|
|
@@ -200,9 +229,11 @@ export function componentResponseToTxRequests(
|
|
|
200
229
|
* ```typescript
|
|
201
230
|
* import { componentResponseToTxCreateRequest } from '$lib/notabene-tx-transformer';
|
|
202
231
|
*
|
|
203
|
-
* withdrawal
|
|
232
|
+
* // Works with both withdrawal and deposit responses
|
|
233
|
+
* transaction.on('complete', async (result) => {
|
|
204
234
|
* const requestBody = componentResponseToTxCreateRequest(
|
|
205
235
|
* result.response,
|
|
236
|
+
* delegateToken,
|
|
206
237
|
* {
|
|
207
238
|
* originatorId: 'mailto:user@example.com',
|
|
208
239
|
* beneficiaryId: 'urn:beneficiary:recipient',
|
|
@@ -218,54 +249,71 @@ export function componentResponseToTxRequests(
|
|
|
218
249
|
* ```
|
|
219
250
|
*/
|
|
220
251
|
export function componentResponseToTxCreateRequest(
|
|
221
|
-
response: TransactionResponse<Withdrawal>,
|
|
252
|
+
response: TransactionResponse<Withdrawal | Deposit>,
|
|
222
253
|
delegateToken: string,
|
|
223
|
-
config:
|
|
254
|
+
config: ResponseToTxCreateRequestConfig = {},
|
|
224
255
|
) {
|
|
225
|
-
|
|
256
|
+
const { value, txCreate, txUpdate } = response;
|
|
257
|
+
|
|
258
|
+
// For withdrawals: use txCreate, for deposits: use txUpdate
|
|
259
|
+
const txPayload = isWithdrawal(value) ? txCreate : txUpdate;
|
|
260
|
+
|
|
261
|
+
if (!txPayload || !response.ivms101) {
|
|
226
262
|
throw new Error(
|
|
227
|
-
'Invalid response: missing required txCreate or ivms101 data',
|
|
263
|
+
'Invalid response: missing required txCreate/txUpdate or ivms101 data',
|
|
228
264
|
);
|
|
229
265
|
}
|
|
230
266
|
|
|
231
|
-
const { value, txCreate } = response;
|
|
232
267
|
const enrichedConfig = enrichConfig(config, delegateToken, value);
|
|
233
268
|
|
|
234
|
-
return mapToTransactCreateRequest(value,
|
|
269
|
+
return mapToTransactCreateRequest(value, txPayload, enrichedConfig);
|
|
235
270
|
}
|
|
236
271
|
|
|
237
272
|
/**
|
|
238
273
|
* Transforms a Notabene component response to IVMS101 format
|
|
239
274
|
*
|
|
275
|
+
* ## IVMS101 Config by Transaction Type
|
|
276
|
+
*
|
|
277
|
+
* The `originator` and `beneficiary` config options provide the customer's PII data.
|
|
278
|
+
* Which one to use depends on the transaction type:
|
|
279
|
+
*
|
|
280
|
+
* - **Withdrawals**: Pass `originator` - the customer is sending funds (customer = originator)
|
|
281
|
+
* - **Deposits**: Pass `beneficiary` - the customer is receiving funds (customer = beneficiary)
|
|
282
|
+
*
|
|
283
|
+
* For self-transfers, the provided data is automatically reused for both parties.
|
|
284
|
+
*
|
|
240
285
|
* @param response - The response from the Notabene Embedded Component
|
|
241
|
-
* @param delegateToken - The JWT delegate token for extracting the
|
|
286
|
+
* @param delegateToken - The JWT delegate token for extracting the customer ID
|
|
242
287
|
* @param config - Configuration object with optional IDs
|
|
243
|
-
* @param config.originatorId - Optional originator ID (auto-extracted from delegateToken
|
|
244
|
-
* @param config.beneficiaryId - Optional beneficiary ID (auto-
|
|
245
|
-
* @param config.
|
|
246
|
-
* @param config.
|
|
288
|
+
* @param config.originatorId - Optional originator ID (auto-extracted from delegateToken for withdrawals)
|
|
289
|
+
* @param config.beneficiaryId - Optional beneficiary ID (auto-extracted from delegateToken for deposits)
|
|
290
|
+
* @param config.originator - Customer's IVMS101 data for withdrawals (customer is the sender)
|
|
291
|
+
* @param config.beneficiary - Customer's IVMS101 data for deposits (customer is the receiver)
|
|
247
292
|
* @returns The transformed request body in IVMS101 format
|
|
248
293
|
*
|
|
249
294
|
* @example
|
|
250
295
|
* ```typescript
|
|
251
296
|
* import { componentResponseToIVMS101 } from '$lib/notabene-tx-transformer';
|
|
252
297
|
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
*
|
|
298
|
+
* // For withdrawals: pass originator (customer is sending)
|
|
299
|
+
* const withdrawalIvms = componentResponseToIVMS101(
|
|
300
|
+
* withdrawalResponse,
|
|
301
|
+
* delegateToken,
|
|
302
|
+
* { originator: customerIvmsData }
|
|
257
303
|
* );
|
|
258
304
|
*
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
-
*
|
|
262
|
-
*
|
|
305
|
+
* // For deposits: pass beneficiary (customer is receiving)
|
|
306
|
+
* const depositIvms = componentResponseToIVMS101(
|
|
307
|
+
* depositResponse,
|
|
308
|
+
* delegateToken,
|
|
309
|
+
* { beneficiary: customerIvmsData }
|
|
310
|
+
* );
|
|
263
311
|
* ```
|
|
264
312
|
*/
|
|
265
313
|
export function componentResponseToIVMS101(
|
|
266
|
-
response: TransactionResponse<Withdrawal>,
|
|
314
|
+
response: TransactionResponse<Withdrawal | Deposit>,
|
|
267
315
|
delegateToken: string,
|
|
268
|
-
config:
|
|
316
|
+
config: ResponseToIVMS101RequestConfig = {},
|
|
269
317
|
) {
|
|
270
318
|
if (!response.ivms101) {
|
|
271
319
|
throw new Error('Invalid response: missing required ivms101 data');
|
|
@@ -14,13 +14,24 @@ export interface DelegateToken {
|
|
|
14
14
|
iat?: number;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
interface BaseRequestConfig {
|
|
18
18
|
originatorId?: DID;
|
|
19
19
|
beneficiaryId?: DID;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ResponseToTxCreateRequestConfig extends BaseRequestConfig {
|
|
20
23
|
referenceId?: string;
|
|
24
|
+
settlementAddress?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ResponseToIVMS101RequestConfig extends BaseRequestConfig {
|
|
21
28
|
originator?: OriginatorV2;
|
|
29
|
+
beneficiary?: BeneficiaryV2;
|
|
22
30
|
}
|
|
23
31
|
|
|
32
|
+
export type ResponseToTxRequestConfig = ResponseToTxCreateRequestConfig &
|
|
33
|
+
ResponseToIVMS101RequestConfig;
|
|
34
|
+
|
|
24
35
|
export interface TransactionCreateRequest {
|
|
25
36
|
transactionAsset: any;
|
|
26
37
|
transactionAmount: string;
|
|
@@ -2,8 +2,21 @@ import type {
|
|
|
2
2
|
NaturalPersonName,
|
|
3
3
|
Person,
|
|
4
4
|
} from '@notabene/javascript-sdk/src/ivms/types';
|
|
5
|
-
import type
|
|
5
|
+
import { CAIP10Schema, type DID } from '@taprsvp/types';
|
|
6
6
|
import type { NaturalPersonNameV2, PersonV2 } from '../ivms';
|
|
7
|
+
import { Deposit, Withdrawal } from '../types';
|
|
8
|
+
|
|
9
|
+
export function isDeposit(
|
|
10
|
+
transaction: Withdrawal | Deposit,
|
|
11
|
+
): transaction is Deposit {
|
|
12
|
+
return 'source' in transaction && transaction.source !== undefined;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function isWithdrawal(
|
|
16
|
+
transaction: Withdrawal | Deposit,
|
|
17
|
+
): transaction is Withdrawal {
|
|
18
|
+
return !isDeposit(transaction);
|
|
19
|
+
}
|
|
7
20
|
|
|
8
21
|
/**
|
|
9
22
|
* Generates a backup DID identifier for a party
|
|
@@ -59,3 +72,26 @@ export function convertPersonToV2(
|
|
|
59
72
|
accountNumber: [accountNumber],
|
|
60
73
|
};
|
|
61
74
|
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Extracts the chain prefix ({namespace}:{chainId}) from a CAIP-10 address
|
|
78
|
+
* @param caip10Address - An address in the format {namespace}:{chainId}:{address}
|
|
79
|
+
* @returns The chain prefix (e.g., eip155:1)
|
|
80
|
+
* @throws Error if the address is not in valid CAIP-10 format
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* getCaip10ChainPrefix('eip155:1:0x123...') // returns 'eip155:1'
|
|
84
|
+
* getCaip10ChainPrefix('solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp:7kfAoE5o...') // returns 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'
|
|
85
|
+
*/
|
|
86
|
+
export function getCaip10ChainPrefix(caip10Address: string): string {
|
|
87
|
+
const result = CAIP10Schema.safeParse(caip10Address);
|
|
88
|
+
if (!result.success) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
`Invalid CAIP-10 format: "${caip10Address}". Expected format: {namespace}:{chainId}:{address}`,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Extract chain (namespace:chainId) by removing the last segment (address)
|
|
95
|
+
const lastColonIndex = caip10Address.lastIndexOf(':');
|
|
96
|
+
return caip10Address.slice(0, lastColonIndex);
|
|
97
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -237,8 +237,11 @@ export type ISOCurrency = string;
|
|
|
237
237
|
*/
|
|
238
238
|
export type Theme = {
|
|
239
239
|
mode: 'light' | 'dark'; // Defaults to 'light'
|
|
240
|
+
backgroundColor?: string;
|
|
240
241
|
primaryColor?: string;
|
|
242
|
+
primaryForeground?: string;
|
|
241
243
|
secondaryColor?: string;
|
|
244
|
+
secondaryForeground?: string;
|
|
242
245
|
fontFamily?: string;
|
|
243
246
|
logo?: string;
|
|
244
247
|
};
|
|
@@ -491,7 +494,7 @@ export type LegalPersonFields = Partial<{
|
|
|
491
494
|
* @public
|
|
492
495
|
*/
|
|
493
496
|
type OriginatorFields = {
|
|
494
|
-
source
|
|
497
|
+
source: Source | Source[];
|
|
495
498
|
};
|
|
496
499
|
|
|
497
500
|
/**
|
|
@@ -499,7 +502,7 @@ type OriginatorFields = {
|
|
|
499
502
|
* @public
|
|
500
503
|
*/
|
|
501
504
|
type BeneficiaryFields = {
|
|
502
|
-
destination
|
|
505
|
+
destination: Destination;
|
|
503
506
|
};
|
|
504
507
|
|
|
505
508
|
/**
|
|
@@ -889,6 +892,7 @@ export interface TransactionOptions {
|
|
|
889
892
|
hide?: ValidationSections[]; // You can hide a specific section of the component by listing it here
|
|
890
893
|
counterpartyAssist?: CounterpartyAssistConfig;
|
|
891
894
|
autoSubmit?: boolean; // Defaults to false
|
|
895
|
+
supportUrl?: string;
|
|
892
896
|
}
|
|
893
897
|
/**
|
|
894
898
|
* Component Message Type enum representing different message types that can be sent
|
package/src/utils/arbitraries.ts
CHANGED
|
@@ -250,5 +250,5 @@ export const arbitraryDeposit = (): fc.Arbitrary<Deposit> =>
|
|
|
250
250
|
asset: arbitraryTransactionAsset(),
|
|
251
251
|
amountDecimal: fc.float({ min: 0, max: 1e6 }),
|
|
252
252
|
origin: fc.oneof(arbitraryBlockchainAddress(), arbitraryCAIP10()),
|
|
253
|
-
|
|
253
|
+
source: fc.oneof(arbitraryBlockchainAddress(), arbitraryCAIP10()),
|
|
254
254
|
});
|