@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.
Files changed (82) hide show
  1. package/LICENSE +163 -34
  2. package/lib/asset.d.ts +30 -0
  3. package/lib/asset.d.ts.map +1 -0
  4. package/lib/asset.js +78 -0
  5. package/lib/asset.js.map +1 -0
  6. package/lib/certificates.d.ts +11 -38
  7. package/lib/certificates.d.ts.map +1 -1
  8. package/lib/certificates.js +33 -336
  9. package/lib/certificates.js.map +1 -1
  10. package/lib/resolver.d.ts +9 -2
  11. package/lib/resolver.d.ts.map +1 -1
  12. package/lib/resolver.js +195 -159
  13. package/lib/resolver.js.map +1 -1
  14. package/lib/sensitive-attribute.d.ts +87 -0
  15. package/lib/sensitive-attribute.d.ts.map +1 -0
  16. package/lib/sensitive-attribute.js +419 -0
  17. package/lib/sensitive-attribute.js.map +1 -0
  18. package/lib/token-metadata.d.ts +21 -0
  19. package/lib/token-metadata.d.ts.map +1 -0
  20. package/lib/token-metadata.generated.d.ts +5 -0
  21. package/lib/token-metadata.generated.d.ts.map +1 -0
  22. package/lib/token-metadata.generated.js +70 -0
  23. package/lib/token-metadata.generated.js.map +1 -0
  24. package/lib/token-metadata.js +57 -0
  25. package/lib/token-metadata.js.map +1 -0
  26. package/lib/utils/pii.d.ts +128 -0
  27. package/lib/utils/pii.d.ts.map +1 -0
  28. package/lib/utils/pii.js +198 -0
  29. package/lib/utils/pii.js.map +1 -0
  30. package/npm-shrinkwrap.json +2 -2
  31. package/package.json +1 -1
  32. package/services/asset-movement/common.d.ts +7 -29
  33. package/services/asset-movement/common.d.ts.map +1 -1
  34. package/services/asset-movement/common.js +5223 -2660
  35. package/services/asset-movement/common.js.map +1 -1
  36. package/services/asset-movement/lib/data/addresses/bank-account/iban-swift.d.ts.map +1 -1
  37. package/services/asset-movement/lib/data/addresses/bank-account/iban-swift.js +22 -1
  38. package/services/asset-movement/lib/data/addresses/bank-account/iban-swift.js.map +1 -1
  39. package/services/asset-movement/lib/data/addresses/bank-account/interac.d.ts +1 -1
  40. package/services/asset-movement/lib/data/addresses/bank-account/interac.d.ts.map +1 -1
  41. package/services/asset-movement/lib/data/addresses/bank-account/interac.js +13 -3
  42. package/services/asset-movement/lib/data/addresses/bank-account/interac.js.map +1 -1
  43. package/services/asset-movement/lib/data/addresses/bank-account/pix.d.ts +1 -1
  44. package/services/asset-movement/lib/data/addresses/bank-account/pix.d.ts.map +1 -1
  45. package/services/asset-movement/lib/data/addresses/bank-account/pix.js +11 -1
  46. package/services/asset-movement/lib/data/addresses/bank-account/pix.js.map +1 -1
  47. package/services/asset-movement/lib/data/addresses/types.generated.d.ts +116 -33
  48. package/services/asset-movement/lib/data/addresses/types.generated.d.ts.map +1 -1
  49. package/services/asset-movement/lib/data/addresses/types.generated.js +102 -26
  50. package/services/asset-movement/lib/data/addresses/types.generated.js.map +1 -1
  51. package/services/asset-movement/lib/data/types.d.ts.map +1 -1
  52. package/services/asset-movement/lib/data/types.js +15 -10
  53. package/services/asset-movement/lib/data/types.js.map +1 -1
  54. package/services/fx/client.d.ts.map +1 -1
  55. package/services/fx/client.js +6 -2
  56. package/services/fx/client.js.map +1 -1
  57. package/services/fx/common.d.ts +14 -6
  58. package/services/fx/common.d.ts.map +1 -1
  59. package/services/fx/common.js +34 -8
  60. package/services/fx/common.js.map +1 -1
  61. package/services/fx/server.d.ts +6 -0
  62. package/services/fx/server.d.ts.map +1 -1
  63. package/services/fx/server.js +52 -10
  64. package/services/fx/server.js.map +1 -1
  65. package/services/kyc/common.d.ts +7 -0
  66. package/services/kyc/common.d.ts.map +1 -1
  67. package/services/kyc/common.generated.js +6 -1
  68. package/services/kyc/common.generated.js.map +1 -1
  69. package/services/kyc/common.js.map +1 -1
  70. package/services/notification/client.d.ts +1 -1
  71. package/services/notification/client.d.ts.map +1 -1
  72. package/services/notification/client.js +65 -2
  73. package/services/notification/client.js.map +1 -1
  74. package/services/notification/common.d.ts +1 -0
  75. package/services/notification/common.d.ts.map +1 -1
  76. package/services/notification/common.js.map +1 -1
  77. package/services/storage/clients/contacts.generated.js +506 -233
  78. package/services/storage/clients/contacts.generated.js.map +1 -1
  79. package/services/storage/server.d.ts +8 -1
  80. package/services/storage/server.d.ts.map +1 -1
  81. package/services/storage/server.js +9 -1
  82. 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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"}
@@ -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"]}
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@keetanetwork/anchor",
3
- "version": "0.0.45",
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.45",
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@keetanetwork/anchor",
3
- "version": "0.0.45",
3
+ "version": "0.0.48",
4
4
  "description": "KeetaNetwork Network Anchor",
5
5
  "main": "client/index.js",
6
6
  "scripts": {
@@ -1,41 +1,20 @@
1
1
  import type { ServiceMetadata } from '../../lib/resolver.ts';
2
- import { lib as KeetaNetLib } from '@keetanetwork/keetanet-client';
3
- import * as CurrencyInfo from '@keetanetwork/currency-info';
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 { KeetaNet } from '../../client/index.js';
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 = `0x${string}`;
16
- export type KeetaNetAccount = InstanceType<typeof KeetaNetLib.Account>;
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: 'WIRE' | 'ACH' | 'SEPA_PUSH';
313
+ type: FiatRails;
336
314
  /**
337
315
  * The resolved bank account address details to send funds to
338
316
  */