@keetanetwork/anchor 0.0.45 → 0.0.48
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/LICENSE +163 -34
- package/lib/asset.d.ts +30 -0
- package/lib/asset.d.ts.map +1 -0
- package/lib/asset.js +78 -0
- package/lib/asset.js.map +1 -0
- package/lib/certificates.d.ts +11 -38
- package/lib/certificates.d.ts.map +1 -1
- package/lib/certificates.js +33 -336
- package/lib/certificates.js.map +1 -1
- package/lib/resolver.d.ts +9 -2
- package/lib/resolver.d.ts.map +1 -1
- package/lib/resolver.js +195 -159
- package/lib/resolver.js.map +1 -1
- package/lib/sensitive-attribute.d.ts +87 -0
- package/lib/sensitive-attribute.d.ts.map +1 -0
- package/lib/sensitive-attribute.js +419 -0
- package/lib/sensitive-attribute.js.map +1 -0
- package/lib/token-metadata.d.ts +21 -0
- package/lib/token-metadata.d.ts.map +1 -0
- package/lib/token-metadata.generated.d.ts +5 -0
- package/lib/token-metadata.generated.d.ts.map +1 -0
- package/lib/token-metadata.generated.js +70 -0
- package/lib/token-metadata.generated.js.map +1 -0
- package/lib/token-metadata.js +57 -0
- package/lib/token-metadata.js.map +1 -0
- package/lib/utils/pii.d.ts +128 -0
- package/lib/utils/pii.d.ts.map +1 -0
- package/lib/utils/pii.js +198 -0
- package/lib/utils/pii.js.map +1 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/services/asset-movement/common.d.ts +7 -29
- package/services/asset-movement/common.d.ts.map +1 -1
- package/services/asset-movement/common.js +5223 -2660
- package/services/asset-movement/common.js.map +1 -1
- package/services/asset-movement/lib/data/addresses/bank-account/iban-swift.d.ts.map +1 -1
- package/services/asset-movement/lib/data/addresses/bank-account/iban-swift.js +22 -1
- package/services/asset-movement/lib/data/addresses/bank-account/iban-swift.js.map +1 -1
- package/services/asset-movement/lib/data/addresses/bank-account/interac.d.ts +1 -1
- package/services/asset-movement/lib/data/addresses/bank-account/interac.d.ts.map +1 -1
- package/services/asset-movement/lib/data/addresses/bank-account/interac.js +13 -3
- package/services/asset-movement/lib/data/addresses/bank-account/interac.js.map +1 -1
- package/services/asset-movement/lib/data/addresses/bank-account/pix.d.ts +1 -1
- package/services/asset-movement/lib/data/addresses/bank-account/pix.d.ts.map +1 -1
- package/services/asset-movement/lib/data/addresses/bank-account/pix.js +11 -1
- package/services/asset-movement/lib/data/addresses/bank-account/pix.js.map +1 -1
- package/services/asset-movement/lib/data/addresses/types.generated.d.ts +116 -33
- package/services/asset-movement/lib/data/addresses/types.generated.d.ts.map +1 -1
- package/services/asset-movement/lib/data/addresses/types.generated.js +102 -26
- package/services/asset-movement/lib/data/addresses/types.generated.js.map +1 -1
- package/services/asset-movement/lib/data/types.d.ts.map +1 -1
- package/services/asset-movement/lib/data/types.js +15 -10
- package/services/asset-movement/lib/data/types.js.map +1 -1
- package/services/fx/client.d.ts.map +1 -1
- package/services/fx/client.js +6 -2
- package/services/fx/client.js.map +1 -1
- package/services/fx/common.d.ts +14 -6
- package/services/fx/common.d.ts.map +1 -1
- package/services/fx/common.js +34 -8
- package/services/fx/common.js.map +1 -1
- package/services/fx/server.d.ts +6 -0
- package/services/fx/server.d.ts.map +1 -1
- package/services/fx/server.js +52 -10
- package/services/fx/server.js.map +1 -1
- package/services/kyc/common.d.ts +7 -0
- package/services/kyc/common.d.ts.map +1 -1
- package/services/kyc/common.generated.js +6 -1
- package/services/kyc/common.generated.js.map +1 -1
- package/services/kyc/common.js.map +1 -1
- package/services/notification/client.d.ts +1 -1
- package/services/notification/client.d.ts.map +1 -1
- package/services/notification/client.js +65 -2
- package/services/notification/client.js.map +1 -1
- package/services/notification/common.d.ts +1 -0
- package/services/notification/common.d.ts.map +1 -1
- package/services/notification/common.js.map +1 -1
- package/services/storage/clients/contacts.generated.js +506 -233
- package/services/storage/clients/contacts.generated.js.map +1 -1
- package/services/storage/server.d.ts +8 -1
- package/services/storage/server.d.ts.map +1 -1
- package/services/storage/server.js +9 -1
- package/services/storage/server.js.map +1 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as __typia_transform__assertGuard from "typia/lib/internal/_assertGuard.js";
|
|
2
|
+
import * as __typia_transform__jsonStringifyString from "typia/lib/internal/_jsonStringifyString.js";
|
|
3
|
+
import * as __typia_transform__throwTypeGuardError from "typia/lib/internal/_throwTypeGuardError.js";
|
|
4
|
+
import { createAssert, json } from "typia";
|
|
5
|
+
export const parseTokenMetadataJSON = (() => { const _io0 = input => ("string" === typeof input.decimalPlaces || "number" === typeof input.decimalPlaces) && (undefined === input.logoURI || "string" === typeof input.logoURI); const _ao0 = (input, _path, _exceptionable = true) => ("string" === typeof input.decimalPlaces || "number" === typeof input.decimalPlaces || __typia_transform__assertGuard._assertGuard(_exceptionable, {
|
|
6
|
+
method: "json.createAssertParse",
|
|
7
|
+
path: _path + ".decimalPlaces",
|
|
8
|
+
expected: "(number | string)",
|
|
9
|
+
value: input.decimalPlaces
|
|
10
|
+
}, _errorFactory)) && (undefined === input.logoURI || "string" === typeof input.logoURI || __typia_transform__assertGuard._assertGuard(_exceptionable, {
|
|
11
|
+
method: "json.createAssertParse",
|
|
12
|
+
path: _path + ".logoURI",
|
|
13
|
+
expected: "(string | undefined)",
|
|
14
|
+
value: input.logoURI
|
|
15
|
+
}, _errorFactory)); const __is = input => "object" === typeof input && null !== input && _io0(input); let _errorFactory; const __assert = (input, errorFactory) => {
|
|
16
|
+
if (false === __is(input)) {
|
|
17
|
+
_errorFactory = errorFactory;
|
|
18
|
+
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || __typia_transform__assertGuard._assertGuard(true, {
|
|
19
|
+
method: "json.createAssertParse",
|
|
20
|
+
path: _path + "",
|
|
21
|
+
expected: "TokenMetadataJSON",
|
|
22
|
+
value: input
|
|
23
|
+
}, _errorFactory)) && _ao0(input, _path + "", true) || __typia_transform__assertGuard._assertGuard(true, {
|
|
24
|
+
method: "json.createAssertParse",
|
|
25
|
+
path: _path + "",
|
|
26
|
+
expected: "TokenMetadataJSON",
|
|
27
|
+
value: input
|
|
28
|
+
}, _errorFactory))(input, "$input", true);
|
|
29
|
+
}
|
|
30
|
+
return input;
|
|
31
|
+
}; return (input, errorFactory) => __assert(JSON.parse(input), errorFactory); })();
|
|
32
|
+
export const stringifyTokenMetadataJSON = (() => { const _so0 = input => `{${undefined === input.logoURI ? "" : `"logoURI":${undefined !== input.logoURI ? __typia_transform__jsonStringifyString._jsonStringifyString(input.logoURI) : undefined},`}"decimalPlaces":${(() => {
|
|
33
|
+
if ("string" === typeof input.decimalPlaces)
|
|
34
|
+
return __typia_transform__jsonStringifyString._jsonStringifyString(input.decimalPlaces);
|
|
35
|
+
if ("number" === typeof input.decimalPlaces)
|
|
36
|
+
return input.decimalPlaces;
|
|
37
|
+
__typia_transform__throwTypeGuardError._throwTypeGuardError({
|
|
38
|
+
method: "json.createStringify",
|
|
39
|
+
expected: "(number | string)",
|
|
40
|
+
value: input.decimalPlaces
|
|
41
|
+
});
|
|
42
|
+
})()}}`; return input => _so0(input); })();
|
|
43
|
+
export const assertTokenMetadataJSON = (() => { const _io0 = input => ("string" === typeof input.decimalPlaces || "number" === typeof input.decimalPlaces) && (undefined === input.logoURI || "string" === typeof input.logoURI); const _ao0 = (input, _path, _exceptionable = true) => ("string" === typeof input.decimalPlaces || "number" === typeof input.decimalPlaces || __typia_transform__assertGuard._assertGuard(_exceptionable, {
|
|
44
|
+
method: "createAssert",
|
|
45
|
+
path: _path + ".decimalPlaces",
|
|
46
|
+
expected: "(number | string)",
|
|
47
|
+
value: input.decimalPlaces
|
|
48
|
+
}, _errorFactory)) && (undefined === input.logoURI || "string" === typeof input.logoURI || __typia_transform__assertGuard._assertGuard(_exceptionable, {
|
|
49
|
+
method: "createAssert",
|
|
50
|
+
path: _path + ".logoURI",
|
|
51
|
+
expected: "(string | undefined)",
|
|
52
|
+
value: input.logoURI
|
|
53
|
+
}, _errorFactory)); const __is = input => "object" === typeof input && null !== input && _io0(input); let _errorFactory; return (input, errorFactory) => {
|
|
54
|
+
if (false === __is(input)) {
|
|
55
|
+
_errorFactory = errorFactory;
|
|
56
|
+
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || __typia_transform__assertGuard._assertGuard(true, {
|
|
57
|
+
method: "createAssert",
|
|
58
|
+
path: _path + "",
|
|
59
|
+
expected: "TokenMetadataJSON",
|
|
60
|
+
value: input
|
|
61
|
+
}, _errorFactory)) && _ao0(input, _path + "", true) || __typia_transform__assertGuard._assertGuard(true, {
|
|
62
|
+
method: "createAssert",
|
|
63
|
+
path: _path + "",
|
|
64
|
+
expected: "TokenMetadataJSON",
|
|
65
|
+
value: input
|
|
66
|
+
}, _errorFactory))(input, "$input", true);
|
|
67
|
+
}
|
|
68
|
+
return input;
|
|
69
|
+
}; })();
|
|
70
|
+
//# sourceMappingURL=token-metadata.generated.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-metadata.generated.js","sourceRoot":"","sources":["../../src/lib/token-metadata.generated.ts"],"names":[],"mappings":";;;AAAA,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAG3C,MAAM,CAAC,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;kFAAoF,CAAC;AACxH,MAAM,CAAC,MAAM,0BAA0B;;;;;;;;;;0CAAkF,CAAC;AAC1H,MAAM,CAAC,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;OAA2E,CAAC","sourcesContent":["import { createAssert, json } from \"typia\";\nimport type { TokenMetadataJSON } from \"./token-metadata.js\";\n\nexport const parseTokenMetadataJSON: (input: string) => TokenMetadataJSON = json.createAssertParse<TokenMetadataJSON>();\nexport const stringifyTokenMetadataJSON: (input: TokenMetadataJSON) => string = json.createStringify<TokenMetadataJSON>();\nexport const assertTokenMetadataJSON: (input: unknown) => TokenMetadataJSON = createAssert<TokenMetadataJSON>();\n"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { KeetaAnchorUserValidationError } from "./error.js";
|
|
2
|
+
import { parseTokenMetadataJSON, stringifyTokenMetadataJSON } from "./token-metadata.generated.js";
|
|
3
|
+
function parseDecimalPlaces(input) {
|
|
4
|
+
let valid = true;
|
|
5
|
+
let value = input;
|
|
6
|
+
if (typeof value === 'string') {
|
|
7
|
+
if (value.trim() === '') {
|
|
8
|
+
valid = false;
|
|
9
|
+
}
|
|
10
|
+
value = Number(value);
|
|
11
|
+
}
|
|
12
|
+
if (Number.isNaN(value) || value < 0 || !Number.isInteger(value)) {
|
|
13
|
+
valid = false;
|
|
14
|
+
}
|
|
15
|
+
if (!valid) {
|
|
16
|
+
throw (new KeetaAnchorUserValidationError({
|
|
17
|
+
fields: [
|
|
18
|
+
{
|
|
19
|
+
path: 'decimalPlaces',
|
|
20
|
+
message: `Invalid decimalPlaces value: ${input}`
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
return (value);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parse token metadata from a base64-encoded JSON string or a TokenMetadataJSON object, returning a TokenMetadata object.
|
|
29
|
+
* @param encoded the value to parse
|
|
30
|
+
* @returns the parsed TokenMetadata object
|
|
31
|
+
*/
|
|
32
|
+
export function decodeTokenMetadata(encoded) {
|
|
33
|
+
let decoded;
|
|
34
|
+
if (typeof encoded === "string") {
|
|
35
|
+
decoded = parseTokenMetadataJSON(atob(encoded));
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
decoded = encoded;
|
|
39
|
+
}
|
|
40
|
+
return ({
|
|
41
|
+
...decoded,
|
|
42
|
+
decimalPlaces: parseDecimalPlaces(decoded.decimalPlaces)
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Encodes token metadata into a base64-encoded JSON string.
|
|
47
|
+
*
|
|
48
|
+
* @param metadata - The token metadata to encode {@link TokenMetadata}
|
|
49
|
+
* @returns The base64-encoded JSON string containing the token metadata
|
|
50
|
+
*/
|
|
51
|
+
export function encodeTokenMetadata(metadata) {
|
|
52
|
+
// Normalize metadata so that decimalPlaces is always a number, ensuring canonical encoding
|
|
53
|
+
const normalized = decodeTokenMetadata(metadata);
|
|
54
|
+
const payload = stringifyTokenMetadataJSON(normalized);
|
|
55
|
+
return (btoa(payload));
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=token-metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-metadata.js","sourceRoot":"","sources":["../../src/lib/token-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAYnG,SAAS,kBAAkB,CAAC,KAAsB;IACjD,IAAI,KAAK,GAAG,IAAI,CAAC;IAEjB,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACzB,KAAK,GAAG,KAAK,CAAC;QACf,CAAC;QAED,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QAClE,KAAK,GAAG,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,MAAK,CAAC,IAAI,8BAA8B,CAAC;YACxC,MAAM,EAAE;gBACP;oBACC,IAAI,EAAE,eAAe;oBACrB,OAAO,EAAE,gCAAgC,KAAK,EAAE;iBAChD;aACD;SACD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAM,CAAC,KAAK,CAAC,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAmD;IACtF,IAAI,OAAO,CAAC;IACZ,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,GAAG,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACjD,CAAC;SAAM,CAAC;QACP,OAAO,GAAG,OAAO,CAAC;IACnB,CAAC;IAED,OAAM,CAAC;QACN,GAAG,OAAO;QACV,aAAa,EAAE,kBAAkB,CAAC,OAAO,CAAC,aAAa,CAAC;KACxD,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAA2C;IAC9E,2FAA2F;IAC3F,MAAM,UAAU,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,0BAA0B,CAAC,UAAU,CAAC,CAAC;IACvD,OAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;AACvB,CAAC","sourcesContent":["import { KeetaAnchorUserValidationError } from \"./error.js\";\nimport { parseTokenMetadataJSON, stringifyTokenMetadataJSON } from \"./token-metadata.generated.js\";\n\nexport interface TokenMetadata {\n\tdecimalPlaces: number;\n\tlogoURI?: string;\n}\n\n\nexport interface TokenMetadataJSON extends Omit<TokenMetadata, \"decimalPlaces\"> {\n\tdecimalPlaces: number | string;\n}\n\nfunction parseDecimalPlaces(input: number | string): number {\n\tlet valid = true;\n\n\tlet value = input;\n\tif (typeof value === 'string') {\n\t\tif (value.trim() === '') {\n\t\t\tvalid = false;\n\t\t}\n\n\t\tvalue = Number(value);\n\t}\n\n\tif (Number.isNaN(value) || value < 0 || !Number.isInteger(value)) {\n\t\tvalid = false;\n\t}\n\n\tif (!valid) {\n\t\tthrow(new KeetaAnchorUserValidationError({\n\t\t\tfields: [\n\t\t\t\t{\n\t\t\t\t\tpath: 'decimalPlaces',\n\t\t\t\t\tmessage: `Invalid decimalPlaces value: ${input}`\n\t\t\t\t}\n\t\t\t]\n\t\t}));\n\t}\n\n\treturn(value);\n}\n\n/**\n * Parse token metadata from a base64-encoded JSON string or a TokenMetadataJSON object, returning a TokenMetadata object.\n * @param encoded the value to parse\n * @returns the parsed TokenMetadata object\n */\nexport function decodeTokenMetadata(encoded: string | TokenMetadataJSON | TokenMetadata): TokenMetadata {\n\tlet decoded;\n\tif (typeof encoded === \"string\") {\n\t\tdecoded = parseTokenMetadataJSON(atob(encoded));\n\t} else {\n\t\tdecoded = encoded;\n\t}\n\n\treturn({\n\t\t...decoded,\n\t\tdecimalPlaces: parseDecimalPlaces(decoded.decimalPlaces)\n\t});\n}\n\n/**\n * Encodes token metadata into a base64-encoded JSON string.\n *\n * @param metadata - The token metadata to encode {@link TokenMetadata}\n * @returns The base64-encoded JSON string containing the token metadata\n */\nexport function encodeTokenMetadata(metadata: TokenMetadata | TokenMetadataJSON): string {\n\t// Normalize metadata so that decimalPlaces is always a number, ensuring canonical encoding\n\tconst normalized = decodeTokenMetadata(metadata);\n\tconst payload = stringifyTokenMetadataJSON(normalized);\n\treturn(btoa(payload));\n}\n"]}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import type * as KeetaNetClient from '@keetanetwork/keetanet-client';
|
|
2
|
+
import { type CertificateAttributeValueMap, type CertificateAttributeValue } from '../../services/kyc/iso20022.generated.js';
|
|
3
|
+
import type { CertificateBuilder, Certificate } from '../certificates.js';
|
|
4
|
+
import { SensitiveAttribute } from '../certificates.js';
|
|
5
|
+
import { KeetaAnchorError } from '../error.js';
|
|
6
|
+
type AccountKeyAlgorithm = InstanceType<typeof KeetaNetClient.lib.Account>['keyType'];
|
|
7
|
+
type KeetaNetAccount = ReturnType<typeof KeetaNetClient.lib.Account.fromSeed<AccountKeyAlgorithm>>;
|
|
8
|
+
/**
|
|
9
|
+
* Type alias for certificate attribute names
|
|
10
|
+
*/
|
|
11
|
+
export type PIIAttributeNames = keyof CertificateAttributeValueMap;
|
|
12
|
+
/**
|
|
13
|
+
* PII error codes
|
|
14
|
+
*/
|
|
15
|
+
export type PIIErrorCode = 'PII_ATTRIBUTE_NOT_FOUND' | 'PII_EXTERNAL_ATTRIBUTE';
|
|
16
|
+
/**
|
|
17
|
+
* Error class for PII-related errors
|
|
18
|
+
*/
|
|
19
|
+
export declare class PIIError extends KeetaAnchorError {
|
|
20
|
+
static readonly name: string;
|
|
21
|
+
private readonly PIIErrorObjectTypeID;
|
|
22
|
+
private static readonly PIIErrorObjectTypeID;
|
|
23
|
+
readonly code: PIIErrorCode;
|
|
24
|
+
readonly attributeName: string;
|
|
25
|
+
constructor(code: PIIErrorCode, attributeName: string, message: string);
|
|
26
|
+
static isInstance(input: unknown, code?: PIIErrorCode): input is PIIError;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* PIIStore is a secure container for Personally Identifiable Information (PII).
|
|
30
|
+
*
|
|
31
|
+
* It encapsulates sensitive data and prevents accidental logging or serialization
|
|
32
|
+
* by overriding common output methods to return redacted placeholders.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* const store = new PIIStore();
|
|
37
|
+
* store.setAttribute('firstName', 'John');
|
|
38
|
+
* store.setAttribute('lastName', 'Doe');
|
|
39
|
+
*
|
|
40
|
+
* console.log(store); // '[PIIStore: REDACTED]'
|
|
41
|
+
* JSON.stringify(store); // '{"type":"PIIStore","message":"REDACTED"}'
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare class PIIStore {
|
|
45
|
+
#private;
|
|
46
|
+
constructor();
|
|
47
|
+
/**
|
|
48
|
+
* Create a PIIStore from a Certificate, extracting all attributes
|
|
49
|
+
*
|
|
50
|
+
* @param certificate - The certificate to extract attributes from
|
|
51
|
+
*
|
|
52
|
+
* @returns A new PIIStore populated with the certificate's attributes
|
|
53
|
+
*/
|
|
54
|
+
static fromCertificate(certificate: Certificate): PIIStore;
|
|
55
|
+
/**
|
|
56
|
+
* Set a known certificate attribute
|
|
57
|
+
*
|
|
58
|
+
* @param name - The attribute name
|
|
59
|
+
* @param value - The value to store
|
|
60
|
+
* @param sensitive - Whether the attribute is sensitive (default: true)
|
|
61
|
+
*/
|
|
62
|
+
setAttribute<K extends PIIAttributeNames>(name: K, value: CertificateAttributeValue<K>, sensitive?: boolean): void;
|
|
63
|
+
setAttribute<T>(name: string, value: T, sensitive?: boolean): void;
|
|
64
|
+
/**
|
|
65
|
+
* Check if an attribute exists in the store
|
|
66
|
+
*/
|
|
67
|
+
hasAttribute(name: string): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Get all attribute names currently stored
|
|
70
|
+
*/
|
|
71
|
+
getAttributeNames(): string[];
|
|
72
|
+
/**
|
|
73
|
+
* Execute a function with scoped access to PII values
|
|
74
|
+
*
|
|
75
|
+
* Provides controlled access to all attribute values. Known certificate attributes
|
|
76
|
+
* are automatically typed; external attributes require an explicit type parameter.
|
|
77
|
+
*
|
|
78
|
+
* @param fn - Function that receives a getter for accessing attribute values
|
|
79
|
+
* @returns The return value of the callback function
|
|
80
|
+
*
|
|
81
|
+
* @throws PIIError with PII_ATTRIBUTE_NOT_FOUND if accessing a missing attribute
|
|
82
|
+
*/
|
|
83
|
+
run<R>(fn: (get: {
|
|
84
|
+
<K extends PIIAttributeNames>(name: K): CertificateAttributeValue<K>;
|
|
85
|
+
<T>(name: string): T;
|
|
86
|
+
}) => R): R;
|
|
87
|
+
/**
|
|
88
|
+
* Create a SensitiveAttribute for a known certificate attribute
|
|
89
|
+
*
|
|
90
|
+
* Only known certificate attributes are supported. External attributes
|
|
91
|
+
* cannot be converted to SensitiveAttributes.
|
|
92
|
+
*
|
|
93
|
+
* @param name - The attribute name to convert (must be a known certificate attribute)
|
|
94
|
+
* @param subjectKey - The account to encrypt the attribute for
|
|
95
|
+
* @returns A SensitiveAttribute containing the encrypted value
|
|
96
|
+
*
|
|
97
|
+
* @throws PIIError with PII_ATTRIBUTE_NOT_FOUND if the attribute is not set
|
|
98
|
+
* @throws Error if the attribute is not a known certificate attribute
|
|
99
|
+
*/
|
|
100
|
+
toSensitiveAttribute<K extends PIIAttributeNames>(name: K, subjectKey: KeetaNetAccount): Promise<SensitiveAttribute<CertificateAttributeValue<K>>>;
|
|
101
|
+
/**
|
|
102
|
+
* Apply known attributes to a CertificateBuilder
|
|
103
|
+
*
|
|
104
|
+
* External attributes are not included in the certificate.
|
|
105
|
+
*
|
|
106
|
+
* @param builder - The certificate builder to apply attributes to
|
|
107
|
+
* @param subjectKey - The subject's account key (required to encrypt sensitive attributes)
|
|
108
|
+
* @returns The certificate builder with the attributes applied
|
|
109
|
+
*/
|
|
110
|
+
toCertificateBuilder(builder: CertificateBuilder, subjectKey: KeetaNetAccount): Promise<CertificateBuilder>;
|
|
111
|
+
/**
|
|
112
|
+
* Prevent logging of PII data via string coercion
|
|
113
|
+
*/
|
|
114
|
+
toString(): string;
|
|
115
|
+
/**
|
|
116
|
+
* Serialize to JSON with redacted values
|
|
117
|
+
*
|
|
118
|
+
* Shows attribute names for debugging, but all values are redacted.
|
|
119
|
+
*/
|
|
120
|
+
toJSON(): {
|
|
121
|
+
type: string;
|
|
122
|
+
attributes: {
|
|
123
|
+
[key: string]: string;
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
export {};
|
|
128
|
+
//# sourceMappingURL=pii.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pii.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/pii.ts"],"names":[],"mappings":"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"}
|
package/lib/utils/pii.js
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { CertificateAttributeOIDDB } from '../../services/kyc/iso20022.generated.js';
|
|
2
|
+
import { SensitiveAttribute } from '../certificates.js';
|
|
3
|
+
import { KeetaAnchorError } from '../error.js';
|
|
4
|
+
/**
|
|
5
|
+
* Redacted message shown when attempting to log or serialize PIIStore
|
|
6
|
+
*/
|
|
7
|
+
const REDACTED = '[PII: REDACTED]';
|
|
8
|
+
/**
|
|
9
|
+
* Error class for PII-related errors
|
|
10
|
+
*/
|
|
11
|
+
export class PIIError extends KeetaAnchorError {
|
|
12
|
+
static name = 'PIIError';
|
|
13
|
+
PIIErrorObjectTypeID;
|
|
14
|
+
static PIIErrorObjectTypeID = 'b8e3c7a1-5d2f-4e6b-9a1c-3f8d2e7b4c5a';
|
|
15
|
+
code;
|
|
16
|
+
attributeName;
|
|
17
|
+
constructor(code, attributeName, message) {
|
|
18
|
+
super(message);
|
|
19
|
+
Object.defineProperty(this, 'PIIErrorObjectTypeID', {
|
|
20
|
+
value: PIIError.PIIErrorObjectTypeID,
|
|
21
|
+
enumerable: false
|
|
22
|
+
});
|
|
23
|
+
this.code = code;
|
|
24
|
+
this.attributeName = attributeName;
|
|
25
|
+
}
|
|
26
|
+
static isInstance(input, code) {
|
|
27
|
+
if (!this.hasPropWithValue(input, 'PIIErrorObjectTypeID', PIIError.PIIErrorObjectTypeID)) {
|
|
28
|
+
return (false);
|
|
29
|
+
}
|
|
30
|
+
if (code && !this.hasPropWithValue(input, 'code', code)) {
|
|
31
|
+
return (false);
|
|
32
|
+
}
|
|
33
|
+
return (true);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* PIIStore is a secure container for Personally Identifiable Information (PII).
|
|
38
|
+
*
|
|
39
|
+
* It encapsulates sensitive data and prevents accidental logging or serialization
|
|
40
|
+
* by overriding common output methods to return redacted placeholders.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* const store = new PIIStore();
|
|
45
|
+
* store.setAttribute('firstName', 'John');
|
|
46
|
+
* store.setAttribute('lastName', 'Doe');
|
|
47
|
+
*
|
|
48
|
+
* console.log(store); // '[PIIStore: REDACTED]'
|
|
49
|
+
* JSON.stringify(store); // '{"type":"PIIStore","message":"REDACTED"}'
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export class PIIStore {
|
|
53
|
+
#attributes = new Map();
|
|
54
|
+
constructor() {
|
|
55
|
+
// Define Node.js util.inspect custom formatter to prevent PII exposure
|
|
56
|
+
Object.defineProperty(this, Symbol.for('nodejs.util.inspect.custom'), {
|
|
57
|
+
value: () => REDACTED,
|
|
58
|
+
enumerable: false,
|
|
59
|
+
writable: false,
|
|
60
|
+
configurable: false
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Create a PIIStore from a Certificate, extracting all attributes
|
|
65
|
+
*
|
|
66
|
+
* @param certificate - The certificate to extract attributes from
|
|
67
|
+
*
|
|
68
|
+
* @returns A new PIIStore populated with the certificate's attributes
|
|
69
|
+
*/
|
|
70
|
+
static fromCertificate(certificate) {
|
|
71
|
+
const store = new PIIStore();
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
73
|
+
const attributeNames = Object.keys(certificate.attributes);
|
|
74
|
+
for (const name of attributeNames) {
|
|
75
|
+
const attr = certificate.attributes[name];
|
|
76
|
+
if (attr) {
|
|
77
|
+
store.#attributes.set(name, {
|
|
78
|
+
value: attr.value,
|
|
79
|
+
sensitive: attr.sensitive
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return (store);
|
|
84
|
+
}
|
|
85
|
+
setAttribute(name, value, sensitive = true) {
|
|
86
|
+
this.#attributes.set(name, { value, sensitive });
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Check if an attribute exists in the store
|
|
90
|
+
*/
|
|
91
|
+
hasAttribute(name) {
|
|
92
|
+
return (this.#attributes.has(name));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get all attribute names currently stored
|
|
96
|
+
*/
|
|
97
|
+
getAttributeNames() {
|
|
98
|
+
return (Array.from(this.#attributes.keys()));
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Execute a function with scoped access to PII values
|
|
102
|
+
*
|
|
103
|
+
* Provides controlled access to all attribute values. Known certificate attributes
|
|
104
|
+
* are automatically typed; external attributes require an explicit type parameter.
|
|
105
|
+
*
|
|
106
|
+
* @param fn - Function that receives a getter for accessing attribute values
|
|
107
|
+
* @returns The return value of the callback function
|
|
108
|
+
*
|
|
109
|
+
* @throws PIIError with PII_ATTRIBUTE_NOT_FOUND if accessing a missing attribute
|
|
110
|
+
*/
|
|
111
|
+
run(fn) {
|
|
112
|
+
const attributes = this.#attributes;
|
|
113
|
+
const get = (name) => {
|
|
114
|
+
if (!this.hasAttribute(name)) {
|
|
115
|
+
throw (new PIIError('PII_ATTRIBUTE_NOT_FOUND', name, `Attribute '${name}' not found in PIIStore`));
|
|
116
|
+
}
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
118
|
+
return attributes.get(name)?.value;
|
|
119
|
+
};
|
|
120
|
+
return (fn(get));
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Create a SensitiveAttribute for a known certificate attribute
|
|
124
|
+
*
|
|
125
|
+
* Only known certificate attributes are supported. External attributes
|
|
126
|
+
* cannot be converted to SensitiveAttributes.
|
|
127
|
+
*
|
|
128
|
+
* @param name - The attribute name to convert (must be a known certificate attribute)
|
|
129
|
+
* @param subjectKey - The account to encrypt the attribute for
|
|
130
|
+
* @returns A SensitiveAttribute containing the encrypted value
|
|
131
|
+
*
|
|
132
|
+
* @throws PIIError with PII_ATTRIBUTE_NOT_FOUND if the attribute is not set
|
|
133
|
+
* @throws Error if the attribute is not a known certificate attribute
|
|
134
|
+
*/
|
|
135
|
+
async toSensitiveAttribute(name, subjectKey) {
|
|
136
|
+
if (!this.hasAttribute(name)) {
|
|
137
|
+
throw (new PIIError('PII_ATTRIBUTE_NOT_FOUND', name, `Attribute '${name}' not found in PIIStore`));
|
|
138
|
+
}
|
|
139
|
+
if (!this.#isKnownAttribute(name)) {
|
|
140
|
+
throw (new PIIError('PII_EXTERNAL_ATTRIBUTE', name, `Cannot convert external attribute '${name}' to SensitiveAttribute`));
|
|
141
|
+
}
|
|
142
|
+
const stored = this.#attributes.get(name);
|
|
143
|
+
const storedValue = stored?.value;
|
|
144
|
+
if (SensitiveAttribute.isInstance(storedValue)) {
|
|
145
|
+
// If already a SensitiveAttribute, return it directly
|
|
146
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
147
|
+
return storedValue;
|
|
148
|
+
}
|
|
149
|
+
// @ts-expect-error storedValue type is validated at setAttribute time
|
|
150
|
+
const result = await SensitiveAttribute.create(subjectKey, name, storedValue);
|
|
151
|
+
return (result);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Apply known attributes to a CertificateBuilder
|
|
155
|
+
*
|
|
156
|
+
* External attributes are not included in the certificate.
|
|
157
|
+
*
|
|
158
|
+
* @param builder - The certificate builder to apply attributes to
|
|
159
|
+
* @param subjectKey - The subject's account key (required to encrypt sensitive attributes)
|
|
160
|
+
* @returns The certificate builder with the attributes applied
|
|
161
|
+
*/
|
|
162
|
+
async toCertificateBuilder(builder, subjectKey) {
|
|
163
|
+
for (const [name, attr] of this.#attributes.entries()) {
|
|
164
|
+
if (this.#isKnownAttribute(name) && attr.value !== undefined && attr.value !== null) {
|
|
165
|
+
if (attr.sensitive) {
|
|
166
|
+
const sensitiveAttr = await this.toSensitiveAttribute(name, subjectKey);
|
|
167
|
+
builder.setSensitiveAttribute(name, sensitiveAttr);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
builder.setAttribute(name, false, attr.value);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return (builder);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Prevent logging of PII data via string coercion
|
|
178
|
+
*/
|
|
179
|
+
toString() {
|
|
180
|
+
return (REDACTED);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Serialize to JSON with redacted values
|
|
184
|
+
*
|
|
185
|
+
* Shows attribute names for debugging, but all values are redacted.
|
|
186
|
+
*/
|
|
187
|
+
toJSON() {
|
|
188
|
+
const attributes = {};
|
|
189
|
+
for (const name of this.#attributes.keys()) {
|
|
190
|
+
attributes[name] = '[REDACTED]';
|
|
191
|
+
}
|
|
192
|
+
return ({ type: 'PIIStore', attributes });
|
|
193
|
+
}
|
|
194
|
+
#isKnownAttribute(name) {
|
|
195
|
+
return (name in CertificateAttributeOIDDB);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=pii.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pii.js","sourceRoot":"","sources":["../../../src/lib/utils/pii.ts"],"names":[],"mappings":"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","sourcesContent":["import type * as KeetaNetClient from '@keetanetwork/keetanet-client';\nimport { CertificateAttributeOIDDB, type CertificateAttributeValueMap, type CertificateAttributeValue } from '../../services/kyc/iso20022.generated.js';\nimport type { CertificateBuilder, Certificate } from '../certificates.js';\nimport { SensitiveAttribute } from '../certificates.js';\nimport { KeetaAnchorError } from '../error.js';\n\ntype AccountKeyAlgorithm = InstanceType<typeof KeetaNetClient.lib.Account>['keyType'];\ntype KeetaNetAccount = ReturnType<typeof KeetaNetClient.lib.Account.fromSeed<AccountKeyAlgorithm>>;\n\n/**\n * Type alias for certificate attribute names\n */\nexport type PIIAttributeNames = keyof CertificateAttributeValueMap;\n\n/**\n * Redacted message shown when attempting to log or serialize PIIStore\n */\nconst REDACTED = '[PII: REDACTED]';\n\n/**\n * PII error codes\n */\nexport type PIIErrorCode = 'PII_ATTRIBUTE_NOT_FOUND' | 'PII_EXTERNAL_ATTRIBUTE';\n\n/**\n * Error class for PII-related errors\n */\nexport class PIIError extends KeetaAnchorError {\n\tstatic override readonly name: string = 'PIIError';\n\tprivate readonly PIIErrorObjectTypeID!: string;\n\tprivate static readonly PIIErrorObjectTypeID = 'b8e3c7a1-5d2f-4e6b-9a1c-3f8d2e7b4c5a';\n\n\treadonly code: PIIErrorCode;\n\treadonly attributeName: string;\n\n\tconstructor(code: PIIErrorCode, attributeName: string, message: string) {\n\t\tsuper(message);\n\n\t\tObject.defineProperty(this, 'PIIErrorObjectTypeID', {\n\t\t\tvalue: PIIError.PIIErrorObjectTypeID,\n\t\t\tenumerable: false\n\t\t});\n\n\t\tthis.code = code;\n\t\tthis.attributeName = attributeName;\n\t}\n\n\tstatic isInstance(input: unknown, code?: PIIErrorCode): input is PIIError {\n\t\tif (!this.hasPropWithValue(input, 'PIIErrorObjectTypeID', PIIError.PIIErrorObjectTypeID)) {\n\t\t\treturn(false);\n\t\t}\n\t\tif (code && !this.hasPropWithValue(input, 'code', code)) {\n\t\t\treturn(false);\n\t\t}\n\n\t\treturn(true);\n\t}\n}\n\ntype StoredAttribute = {\n\tvalue: unknown;\n\tsensitive: boolean;\n};\n\n/**\n * PIIStore is a secure container for Personally Identifiable Information (PII).\n *\n * It encapsulates sensitive data and prevents accidental logging or serialization\n * by overriding common output methods to return redacted placeholders.\n *\n * @example\n * ```typescript\n * const store = new PIIStore();\n * store.setAttribute('firstName', 'John');\n * store.setAttribute('lastName', 'Doe');\n *\n * console.log(store); // '[PIIStore: REDACTED]'\n * JSON.stringify(store); // '{\"type\":\"PIIStore\",\"message\":\"REDACTED\"}'\n * ```\n */\nexport class PIIStore {\n\treadonly #attributes = new Map<string, StoredAttribute>();\n\n\tconstructor() {\n\t\t// Define Node.js util.inspect custom formatter to prevent PII exposure\n\t\tObject.defineProperty(this, Symbol.for('nodejs.util.inspect.custom'), {\n\t\t\tvalue: () => REDACTED,\n\t\t\tenumerable: false,\n\t\t\twritable: false,\n\t\t\tconfigurable: false\n\t\t});\n\t}\n\n\t/**\n\t * Create a PIIStore from a Certificate, extracting all attributes\n\t *\n\t * @param certificate - The certificate to extract attributes from\n\t *\n\t * @returns A new PIIStore populated with the certificate's attributes\n\t */\n\tstatic fromCertificate(certificate: Certificate): PIIStore {\n\t\tconst store = new PIIStore();\n\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\tconst attributeNames = Object.keys(certificate.attributes) as PIIAttributeNames[];\n\t\tfor (const name of attributeNames) {\n\t\t\tconst attr = certificate.attributes[name];\n\t\t\tif (attr) {\n\t\t\t\tstore.#attributes.set(name, {\n\t\t\t\t\tvalue: attr.value,\n\t\t\t\t\tsensitive: attr.sensitive\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn(store);\n\t}\n\n\t/**\n\t * Set a known certificate attribute\n\t *\n\t * @param name - The attribute name\n\t * @param value - The value to store\n\t * @param sensitive - Whether the attribute is sensitive (default: true)\n\t */\n\tsetAttribute<K extends PIIAttributeNames>(name: K, value: CertificateAttributeValue<K>, sensitive?: boolean): void;\n\tsetAttribute<T>(name: string, value: T, sensitive?: boolean): void;\n\tsetAttribute(name: string, value: unknown, sensitive = true): void {\n\t\tthis.#attributes.set(name, { value, sensitive });\n\t}\n\n\t/**\n\t * Check if an attribute exists in the store\n\t */\n\thasAttribute(name: string): boolean {\n\t\treturn(this.#attributes.has(name));\n\t}\n\n\t/**\n\t * Get all attribute names currently stored\n\t */\n\tgetAttributeNames(): string[] {\n\t\treturn(Array.from(this.#attributes.keys()));\n\t}\n\n\t/**\n\t * Execute a function with scoped access to PII values\n\t *\n\t * Provides controlled access to all attribute values. Known certificate attributes\n\t * are automatically typed; external attributes require an explicit type parameter.\n\t *\n\t * @param fn - Function that receives a getter for accessing attribute values\n\t * @returns The return value of the callback function\n\t *\n\t * @throws PIIError with PII_ATTRIBUTE_NOT_FOUND if accessing a missing attribute\n\t */\n\trun<R>(fn: (get: {\n\t\t<K extends PIIAttributeNames>(name: K): CertificateAttributeValue<K>;\n\t\t<T>(name: string): T;\n\t}) => R): R {\n\t\tconst attributes = this.#attributes;\n\t\tconst get = <T>(name: string): T => {\n\t\t\tif (!this.hasAttribute(name)) {\n\t\t\t\tthrow(new PIIError('PII_ATTRIBUTE_NOT_FOUND', name, `Attribute '${name}' not found in PIIStore`));\n\t\t\t}\n\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\treturn(attributes.get(name)?.value as T);\n\t\t};\n\n\t\treturn(fn(get));\n\t}\n\n\t/**\n\t * Create a SensitiveAttribute for a known certificate attribute\n\t *\n\t * Only known certificate attributes are supported. External attributes\n\t * cannot be converted to SensitiveAttributes.\n\t *\n\t * @param name - The attribute name to convert (must be a known certificate attribute)\n\t * @param subjectKey - The account to encrypt the attribute for\n\t * @returns A SensitiveAttribute containing the encrypted value\n\t *\n\t * @throws PIIError with PII_ATTRIBUTE_NOT_FOUND if the attribute is not set\n\t * @throws Error if the attribute is not a known certificate attribute\n\t */\n\tasync toSensitiveAttribute<K extends PIIAttributeNames>(\n\t\tname: K,\n\t\tsubjectKey: KeetaNetAccount\n\t): Promise<SensitiveAttribute<CertificateAttributeValue<K>>> {\n\t\tif (!this.hasAttribute(name)) {\n\t\t\tthrow(new PIIError('PII_ATTRIBUTE_NOT_FOUND', name, `Attribute '${name}' not found in PIIStore`));\n\t\t}\n\t\tif (!this.#isKnownAttribute(name)) {\n\t\t\tthrow(new PIIError('PII_EXTERNAL_ATTRIBUTE', name, `Cannot convert external attribute '${name}' to SensitiveAttribute`));\n\t\t}\n\n\t\tconst stored = this.#attributes.get(name);\n\t\tconst storedValue = stored?.value;\n\t\tif (SensitiveAttribute.isInstance(storedValue)) {\n\t\t\t// If already a SensitiveAttribute, return it directly\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\t\treturn(storedValue as SensitiveAttribute<CertificateAttributeValue<K>>);\n\t\t}\n\n\t\t// @ts-expect-error storedValue type is validated at setAttribute time\n\t\tconst result = await SensitiveAttribute.create(subjectKey, name, storedValue);\n\t\treturn(result);\n\t}\n\n\t/**\n\t * Apply known attributes to a CertificateBuilder\n\t *\n\t * External attributes are not included in the certificate.\n\t *\n\t * @param builder - The certificate builder to apply attributes to\n\t * @param subjectKey - The subject's account key (required to encrypt sensitive attributes)\n\t * @returns The certificate builder with the attributes applied\n\t */\n\tasync toCertificateBuilder(builder: CertificateBuilder, subjectKey: KeetaNetAccount): Promise<CertificateBuilder> {\n\t\tfor (const [name, attr] of this.#attributes.entries()) {\n\t\t\tif (this.#isKnownAttribute(name) && attr.value !== undefined && attr.value !== null) {\n\t\t\t\tif (attr.sensitive) {\n\t\t\t\t\tconst sensitiveAttr = await this.toSensitiveAttribute(name, subjectKey);\n\t\t\t\t\tbuilder.setSensitiveAttribute(name, sensitiveAttr);\n\t\t\t\t} else {\n\t\t\t\t\tbuilder.setAttribute(name, false, attr.value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn(builder);\n\t}\n\n\t/**\n\t * Prevent logging of PII data via string coercion\n\t */\n\ttoString(): string {\n\t\treturn(REDACTED);\n\t}\n\n\t/**\n\t * Serialize to JSON with redacted values\n\t *\n\t * Shows attribute names for debugging, but all values are redacted.\n\t */\n\ttoJSON(): { type: string; attributes: { [key: string]: string }} {\n\t\tconst attributes: { [key: string]: string } = {};\n\t\tfor (const name of this.#attributes.keys()) {\n\t\t\tattributes[name] = '[REDACTED]';\n\t\t}\n\n\t\treturn({ type: 'PIIStore', attributes });\n\t}\n\n\t#isKnownAttribute(name: string): name is PIIAttributeNames {\n\t\treturn(name in CertificateAttributeOIDDB);\n\t}\n}\n"]}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keetanetwork/anchor",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.48",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@keetanetwork/anchor",
|
|
9
|
-
"version": "0.0.
|
|
9
|
+
"version": "0.0.48",
|
|
10
10
|
"license": "SEE LICENSE IN LICENSE",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@keetanetwork/currency-info": "1.2.5",
|
package/package.json
CHANGED
|
@@ -1,41 +1,20 @@
|
|
|
1
1
|
import type { ServiceMetadata } from '../../lib/resolver.ts';
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import type { AccountKeyAlgorithm, IdentifierKeyAlgorithm, TokenAddress, TokenPublicKeyString } from '@keetanetwork/keetanet-client/lib/account.js';
|
|
2
|
+
import type * as CurrencyInfo from '@keetanetwork/currency-info';
|
|
3
|
+
import type { AccountKeyAlgorithm, IdentifierKeyAlgorithm, TokenPublicKeyString } from '@keetanetwork/keetanet-client/lib/account.js';
|
|
5
4
|
import type { ToJSONSerializable } from '@keetanetwork/keetanet-client/lib/utils/conversion.js';
|
|
6
5
|
import type { HTTPSignedField } from '../../lib/http-server/common.js';
|
|
7
6
|
import type { Signable } from '../../lib/utils/signing.js';
|
|
8
7
|
import type { SharableCertificateAttributes } from '../../lib/certificates.js';
|
|
9
|
-
import
|
|
8
|
+
import * as KeetaNet from '@keetanetwork/keetanet-client';
|
|
10
9
|
import { KeetaAnchorUserError } from '../../lib/error.js';
|
|
11
10
|
import type { AssetLocationLike, AssetLocationString, AssetLocationInput, AssetLocationCanonical } from './lib/location.js';
|
|
12
11
|
import type { BankAccountAddressObfuscated, BankAccountAddressResolved, MobileWalletAddressObfuscated, MobileWalletAddressResolved } from './lib/data/addresses/types.generated.js';
|
|
12
|
+
import type { HexString, KeetaNetAccount, MovableAsset, MovableAssetSearchCanonical, CurrencySearchCanonical } from '../../lib/asset.js';
|
|
13
13
|
export * from './lib/data/addresses/types.generated.js';
|
|
14
14
|
export * from './lib/location.js';
|
|
15
|
-
type HexString
|
|
16
|
-
export
|
|
17
|
-
export type KeetaNetTokenPublicKeyString = ReturnType<InstanceType<typeof KeetaNetLib.Account<typeof KeetaNetLib.Account.AccountKeyAlgorithm.TOKEN>>['publicKeyString']['get']>;
|
|
15
|
+
export type { HexString, KeetaNetAccount, KeetaNetTokenPublicKeyString, EVMAsset, TronAsset, SolanaAsset, ChainAssetString, MovableAssetSearchInput, MovableAssetSearchCanonical, MovableAsset, CurrencySearchCanonical, CurrencySearchInput, TokenSearchInput, TokenSearchCanonical } from '../../lib/asset.js';
|
|
16
|
+
export { toEVMAsset, parseEVMAsset, isEVMAsset, toTronAsset, parseTronAsset, isTronAsset, toSolanaAsset, parseSolanaAsset, isSolanaAsset, convertAssetSearchInputToCanonical } from '../../lib/asset.js';
|
|
18
17
|
export type ISOCountryCode = CurrencyInfo.ISOCountryCode;
|
|
19
|
-
type CurrencySearchCanonical = CurrencyInfo.ISOCurrencyCode | `$${string}`;
|
|
20
|
-
type CurrencySearchInput = CurrencySearchCanonical | CurrencyInfo.Currency;
|
|
21
|
-
type TokenSearchInput = TokenAddress | TokenPublicKeyString;
|
|
22
|
-
type TokenSearchCanonical = TokenPublicKeyString;
|
|
23
|
-
export type EVMAsset = `evm:${HexString}`;
|
|
24
|
-
export type TronAsset = `tron:${string}`;
|
|
25
|
-
export type SolanaAsset = `solana:${string}`;
|
|
26
|
-
export type ChainAssetString = SolanaAsset | EVMAsset | TronAsset | TokenPublicKeyString;
|
|
27
|
-
export type MovableAssetSearchInput = CurrencySearchInput | TokenSearchInput | ChainAssetString;
|
|
28
|
-
export type MovableAssetSearchCanonical = CurrencySearchCanonical | TokenSearchCanonical | ChainAssetString;
|
|
29
|
-
export type MovableAsset = TokenAddress | TokenPublicKeyString | CurrencySearchInput | ChainAssetString;
|
|
30
|
-
export declare function toEVMAsset(input: HexString): EVMAsset;
|
|
31
|
-
export declare function parseEVMAsset(input: EVMAsset): HexString;
|
|
32
|
-
export declare function isEVMAsset(input: unknown): input is EVMAsset;
|
|
33
|
-
export declare function toTronAsset(input: string): TronAsset;
|
|
34
|
-
export declare function parseTronAsset(input: TronAsset): string;
|
|
35
|
-
export declare function isTronAsset(input: unknown): input is TronAsset;
|
|
36
|
-
export declare function toSolanaAsset(input: string): SolanaAsset;
|
|
37
|
-
export declare function parseSolanaAsset(input: SolanaAsset): string;
|
|
38
|
-
export declare function isSolanaAsset(input: unknown): input is SolanaAsset;
|
|
39
18
|
type RailOrRails = Rail | Rail[];
|
|
40
19
|
/**
|
|
41
20
|
* Search criteria for filtering asset movement rails when searching for supported rails for a given transfer.
|
|
@@ -164,7 +143,6 @@ export interface RailWithExtendedDetails {
|
|
|
164
143
|
}
|
|
165
144
|
export type RailOrRailWithExtendedDetails = Rail | RailWithExtendedDetails;
|
|
166
145
|
export declare function commonJSONStringify(input: unknown): string;
|
|
167
|
-
export declare function convertAssetSearchInputToCanonical(input: MovableAssetSearchInput): MovableAssetSearchCanonical;
|
|
168
146
|
export type AssetPair<From extends MovableAsset = MovableAsset, To extends MovableAsset = MovableAsset> = {
|
|
169
147
|
from: From;
|
|
170
148
|
to: To;
|
|
@@ -332,7 +310,7 @@ export type AssetTransferInstructions = ({
|
|
|
332
310
|
*/
|
|
333
311
|
contractMethodArgs: string[];
|
|
334
312
|
} | {
|
|
335
|
-
type:
|
|
313
|
+
type: FiatRails;
|
|
336
314
|
/**
|
|
337
315
|
* The resolved bank account address details to send funds to
|
|
338
316
|
*/
|