verus-rpc 0.1.0

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 (75) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +139 -0
  3. package/dist/amount.d.ts +32 -0
  4. package/dist/amount.d.ts.map +1 -0
  5. package/dist/amount.js +65 -0
  6. package/dist/amount.js.map +1 -0
  7. package/dist/client.d.ts +60 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +61 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/errors.d.ts +81 -0
  12. package/dist/errors.d.ts.map +1 -0
  13. package/dist/errors.js +107 -0
  14. package/dist/errors.js.map +1 -0
  15. package/dist/index.d.ts +16 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +21 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/lossless.d.ts +32 -0
  20. package/dist/lossless.d.ts.map +1 -0
  21. package/dist/lossless.js +64 -0
  22. package/dist/lossless.js.map +1 -0
  23. package/dist/mapping.d.ts +41 -0
  24. package/dist/mapping.d.ts.map +1 -0
  25. package/dist/mapping.js +139 -0
  26. package/dist/mapping.js.map +1 -0
  27. package/dist/methods/addressindex.d.ts +69 -0
  28. package/dist/methods/addressindex.d.ts.map +1 -0
  29. package/dist/methods/addressindex.js +97 -0
  30. package/dist/methods/addressindex.js.map +1 -0
  31. package/dist/methods/blockchain.d.ts +99 -0
  32. package/dist/methods/blockchain.d.ts.map +1 -0
  33. package/dist/methods/blockchain.js +141 -0
  34. package/dist/methods/blockchain.js.map +1 -0
  35. package/dist/methods/chain.d.ts +39 -0
  36. package/dist/methods/chain.d.ts.map +1 -0
  37. package/dist/methods/chain.js +44 -0
  38. package/dist/methods/chain.js.map +1 -0
  39. package/dist/methods/currency.d.ts +210 -0
  40. package/dist/methods/currency.d.ts.map +1 -0
  41. package/dist/methods/currency.js +303 -0
  42. package/dist/methods/currency.js.map +1 -0
  43. package/dist/methods/identity.d.ts +284 -0
  44. package/dist/methods/identity.d.ts.map +1 -0
  45. package/dist/methods/identity.js +333 -0
  46. package/dist/methods/identity.js.map +1 -0
  47. package/dist/methods/shielded.d.ts +136 -0
  48. package/dist/methods/shielded.d.ts.map +1 -0
  49. package/dist/methods/shielded.js +175 -0
  50. package/dist/methods/shielded.js.map +1 -0
  51. package/dist/methods/t2.d.ts +8 -0
  52. package/dist/methods/t2.d.ts.map +1 -0
  53. package/dist/methods/t2.js +10 -0
  54. package/dist/methods/t2.js.map +1 -0
  55. package/dist/methods/wallet-types.d.ts +143 -0
  56. package/dist/methods/wallet-types.d.ts.map +1 -0
  57. package/dist/methods/wallet-types.js +6 -0
  58. package/dist/methods/wallet-types.js.map +1 -0
  59. package/dist/methods/wallet.d.ts +206 -0
  60. package/dist/methods/wallet.d.ts.map +1 -0
  61. package/dist/methods/wallet.js +455 -0
  62. package/dist/methods/wallet.js.map +1 -0
  63. package/dist/mock.d.ts +28 -0
  64. package/dist/mock.d.ts.map +1 -0
  65. package/dist/mock.js +61 -0
  66. package/dist/mock.js.map +1 -0
  67. package/dist/resilience.d.ts +20 -0
  68. package/dist/resilience.d.ts.map +1 -0
  69. package/dist/resilience.js +32 -0
  70. package/dist/resilience.js.map +1 -0
  71. package/dist/transport.d.ts +38 -0
  72. package/dist/transport.d.ts.map +1 -0
  73. package/dist/transport.js +79 -0
  74. package/dist/transport.js.map +1 -0
  75. package/package.json +59 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,SAAS,GAAG,cAAc,GAAG,cAAc,CAAC;AAE7F,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;gBAE5B,MAAM,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM;CAK5D;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCf,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAE5E,+DAA+D;AAC/D,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAM1D;AAED;;;;GAIG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAM3D;AAED,qFAAqF;AACrF,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;gBAEtB,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM;CAOpF;AAED,gGAAgG;AAChG,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAK5C"}
package/dist/errors.js ADDED
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Error taxonomy — the split matters for resilience:
3
+ *
4
+ * - `VerusRpcError` — the daemon answered with a JSON-RPC error (bad params,
5
+ * unknown identity, insufficient funds, …). The node is HEALTHY; these never
6
+ * count toward the optional circuit breaker, otherwise malformed requests
7
+ * could trip it and deny service (v402 lesson).
8
+ * - `TransportError` — the node could not be reached, did not answer in time,
9
+ * answered with an unparseable body, or the breaker is open.
10
+ */
11
+ export class TransportError extends Error {
12
+ reason;
13
+ constructor(reason, message) {
14
+ super(message);
15
+ this.name = "TransportError";
16
+ this.reason = reason;
17
+ }
18
+ }
19
+ /**
20
+ * Common daemon error codes (Bitcoin/Zcash lineage, `rpcprotocol.h`) so
21
+ * consumers can branch on `error.code` without string-matching messages.
22
+ */
23
+ export const RpcErrorCode = {
24
+ // JSON-RPC 2.0-style protocol errors
25
+ RPC_INVALID_REQUEST: -32600,
26
+ RPC_METHOD_NOT_FOUND: -32601,
27
+ RPC_INVALID_PARAMS: -32602,
28
+ RPC_INTERNAL_ERROR: -32603,
29
+ RPC_PARSE_ERROR: -32700,
30
+ // General application errors
31
+ RPC_MISC_ERROR: -1,
32
+ RPC_FORBIDDEN_BY_SAFE_MODE: -2,
33
+ RPC_TYPE_ERROR: -3,
34
+ RPC_INVALID_ADDRESS_OR_KEY: -5,
35
+ RPC_OUT_OF_MEMORY: -7,
36
+ RPC_INVALID_PARAMETER: -8,
37
+ RPC_DATABASE_ERROR: -20,
38
+ RPC_DESERIALIZATION_ERROR: -22,
39
+ RPC_VERIFY_ERROR: -25,
40
+ RPC_VERIFY_REJECTED: -26,
41
+ RPC_VERIFY_ALREADY_IN_CHAIN: -27,
42
+ RPC_IN_WARMUP: -28,
43
+ // P2P client errors
44
+ RPC_CLIENT_NOT_CONNECTED: -9,
45
+ RPC_CLIENT_IN_INITIAL_DOWNLOAD: -10,
46
+ RPC_CLIENT_NODE_ALREADY_ADDED: -23,
47
+ RPC_CLIENT_NODE_NOT_ADDED: -24,
48
+ // Wallet errors
49
+ RPC_WALLET_ERROR: -4,
50
+ RPC_WALLET_INSUFFICIENT_FUNDS: -6,
51
+ RPC_WALLET_INVALID_ACCOUNT_NAME: -11,
52
+ RPC_WALLET_KEYPOOL_RAN_OUT: -12,
53
+ RPC_WALLET_UNLOCK_NEEDED: -13,
54
+ RPC_WALLET_PASSPHRASE_INCORRECT: -14,
55
+ RPC_WALLET_WRONG_ENC_STATE: -15,
56
+ RPC_WALLET_ENCRYPTION_FAILED: -16,
57
+ RPC_WALLET_ALREADY_UNLOCKED: -17,
58
+ };
59
+ /** The daemon answered the call with a JSON-RPC error body. */
60
+ export class VerusRpcError extends Error {
61
+ method;
62
+ code;
63
+ constructor(method, code, message) {
64
+ super(`${method}: ${message} (code ${code})`);
65
+ this.name = "VerusRpcError";
66
+ this.method = method;
67
+ this.code = code;
68
+ }
69
+ }
70
+ /**
71
+ * A curated (T1) response did not have the shape the mapper expects — the
72
+ * daemon version drifted or the type curation is wrong. The raw value is
73
+ * intact on the wire; `client.call()` always works as the escape hatch.
74
+ */
75
+ export class ResponseMappingError extends Error {
76
+ method;
77
+ field;
78
+ constructor(method, field, message) {
79
+ super(`${method}: field "${field}": ${message}`);
80
+ this.name = "ResponseMappingError";
81
+ this.method = method;
82
+ this.field = field;
83
+ }
84
+ }
85
+ /** An async wallet operation (opid) finished with status "failed" or "cancelled". */
86
+ export class OperationFailedError extends Error {
87
+ opid;
88
+ status;
89
+ code;
90
+ constructor(opid, status, code, message) {
91
+ super(`operation ${opid} ${status}: ${message}`);
92
+ this.name = "OperationFailedError";
93
+ this.opid = opid;
94
+ this.status = status;
95
+ this.code = code;
96
+ }
97
+ }
98
+ /** An async wallet operation (opid) did not reach a final state within the polling deadline. */
99
+ export class OperationTimeoutError extends Error {
100
+ opid;
101
+ constructor(opid, timeoutMs) {
102
+ super(`operation ${opid} still pending after ${timeoutMs}ms`);
103
+ this.name = "OperationTimeoutError";
104
+ this.opid = opid;
105
+ }
106
+ }
107
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export { formatAmount, parseAmount, SATS_PER_COIN, type ParseAmountOptions } from "./amount.js";
2
+ export { OperationFailedError, OperationTimeoutError, ResponseMappingError, RpcErrorCode, TransportError, VerusRpcError, type TransportFailureReason, } from "./errors.js";
3
+ export { isLosslessNumber, LosslessNumber, toJsNumbers, toSafeNumbers } from "./lossless.js";
4
+ export { DaemonTransport, type DaemonTransportConfig, type RpcTransport } from "./transport.js";
5
+ export { withResilience, type ResilienceConfig } from "./resilience.js";
6
+ export { MockTransport } from "./mock.js";
7
+ export { VerusClient, type CallNumbersMode, type CallOptions, type VerusClientConfig, } from "./client.js";
8
+ export { ChainApi, mapGetInfo, type GetInfoResult } from "./methods/chain.js";
9
+ export { AddressIndexApi, mapAddressBalance, mapAddressDelta, mapAddressUtxo, type AddressBalanceResult, type AddressDelta, type AddressRangeOptions, type AddressUtxo, } from "./methods/addressindex.js";
10
+ export { BlockchainApi, mapGetVdxfId, type CreateRawTransactionInput, type GetVdxfIdResult, type RawTransactionOptions, } from "./methods/blockchain.js";
11
+ export { ShieldedApi, type WaitForOperationOptions, type ZReceivedEntry, type ZSendManyEntry, type ZSendManyOptions, type ZTotalBalanceResult, type ZUnspentEntry, } from "./methods/shielded.js";
12
+ export { CurrencyApi, mapConversionEstimate, mapCurrencyConverterEntry, mapCurrencyDefinition, mapCurrencyState, type ConversionEstimate, type CurrencyConversionData, type CurrencyConverterEntry, type CurrencyDefinition, type CurrencyState, type CurrencyStateSnapshot, type EstimateConversionOptions, type GetCurrencyOptions, type GetCurrencyStateOptions, type ListCurrenciesEntry, type ListCurrenciesOptions, type ListCurrenciesQuery, type ReserveCurrencyState, } from "./methods/currency.js";
13
+ export { IdentityApi, mapGetIdentity, mapIdentityDefinition, mapIdentityHistory, mapIdentityResult, mapNameCommitment, type GetIdentityContentOptions, type GetIdentityHistoryOptions, type GetIdentityHistoryResult, type GetIdentityOptions, type GetIdentityResult, type IdentitiesByAddressQuery, type IdentitiesByAuthorityQuery, type IdentityDefinition, type IdentityHistoryEntry, type IdentitySpec, type IndexedIdentity, type ListIdentitiesOptions, type NameCommitmentResult, type NameReservation, type RecoverIdentityOptions, type RegisterIdentityFlowOptions, type RegisterIdentityFlowResult, type RegisterIdentityOptions, type RegisterNameCommitmentOptions, type RevokeIdentityOptions, type SetIdentityTimelockOptions, type SignFileOptions, type UpdateIdentityOptions, } from "./methods/identity.js";
14
+ export type { GetWalletInfoResult, GroupedAddress, ImportAddressOptions, ImportPrivKeyOptions, ListReceivedOptions, ListTransactionsOptions, ListUnspentOptions, ListedTransaction, ReceivedByAddressEntry, SendManyOptions, SignMessageOptions, SignMessageResult, UnspentOutput, VerifyMessageOptions, } from "./methods/wallet-types.js";
15
+ export { WalletApi, mapAddressGroupings, mapCurrencyBalance, mapGetTransaction, mapGetWalletInfo, mapListedTransaction, mapOperationStatus, mapSignMessage, mapUnspentOutput, type GetBalanceOptions, type GetCurrencyBalanceOptions, type GetOperationStatusOptions, type GetTransactionOptions, type GetTransactionResult, type OperationError, type OperationResult, type OperationStatus, type SendCurrencyAndWaitOptions, type SendCurrencyAndWaitResult, type SendCurrencyOptions, type SendCurrencyOutput, type TransactionDetail, } from "./methods/wallet.js";
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ // verus-rpc — the npm-published, full-coverage, precision-honest TypeScript
2
+ // client for talking to your own verusd.
3
+ //
4
+ // Invariant: no float ever crosses this API for a value field. Curated (T1)
5
+ // methods surface amounts as bigint satoshis; typed (T2) methods as exact
6
+ // decimal strings; `call()` is the always-available escape hatch.
7
+ export { formatAmount, parseAmount, SATS_PER_COIN } from "./amount.js";
8
+ export { OperationFailedError, OperationTimeoutError, ResponseMappingError, RpcErrorCode, TransportError, VerusRpcError, } from "./errors.js";
9
+ export { isLosslessNumber, LosslessNumber, toJsNumbers, toSafeNumbers } from "./lossless.js";
10
+ export { DaemonTransport } from "./transport.js";
11
+ export { withResilience } from "./resilience.js";
12
+ export { MockTransport } from "./mock.js";
13
+ export { VerusClient, } from "./client.js";
14
+ export { ChainApi, mapGetInfo } from "./methods/chain.js";
15
+ export { AddressIndexApi, mapAddressBalance, mapAddressDelta, mapAddressUtxo, } from "./methods/addressindex.js";
16
+ export { BlockchainApi, mapGetVdxfId, } from "./methods/blockchain.js";
17
+ export { ShieldedApi, } from "./methods/shielded.js";
18
+ export { CurrencyApi, mapConversionEstimate, mapCurrencyConverterEntry, mapCurrencyDefinition, mapCurrencyState, } from "./methods/currency.js";
19
+ export { IdentityApi, mapGetIdentity, mapIdentityDefinition, mapIdentityHistory, mapIdentityResult, mapNameCommitment, } from "./methods/identity.js";
20
+ export { WalletApi, mapAddressGroupings, mapCurrencyBalance, mapGetTransaction, mapGetWalletInfo, mapListedTransaction, mapOperationStatus, mapSignMessage, mapUnspentOutput, } from "./methods/wallet.js";
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,yCAAyC;AACzC,EAAE;AACF,4EAA4E;AAC5E,0EAA0E;AAC1E,kEAAkE;AAElE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAA2B,MAAM,aAAa,CAAC;AAChG,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,aAAa,GAEd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7F,OAAO,EAAE,eAAe,EAAiD,MAAM,gBAAgB,CAAC;AAChG,OAAO,EAAE,cAAc,EAAyB,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EACL,WAAW,GAIZ,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAsB,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,cAAc,GAKf,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,aAAa,EACb,YAAY,GAIb,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,WAAW,GAOZ,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,WAAW,EACX,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,gBAAgB,GAcjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,GAwBlB,MAAM,uBAAuB,CAAC;AAiB/B,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,gBAAgB,GAcjB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Lossless JSON layer — the daemon emits value amounts as JSON decimal
3
+ * numbers (`{"VRSCTEST":2.00000000}`), so the transport never runs them
4
+ * through `JSON.parse`'s float64. Number literals survive parsing as
5
+ * `LosslessNumber` (exact decimal string inside) until a mapper decides what
6
+ * they are.
7
+ */
8
+ import { isLosslessNumber, LosslessNumber } from "lossless-json";
9
+ export { isLosslessNumber, LosslessNumber };
10
+ /** Parse JSON text with number literals preserved as `LosslessNumber`. */
11
+ export declare function parseLossless(text: string): unknown;
12
+ /**
13
+ * Serialize a request/params tree. `LosslessNumber` and `bigint` nodes are
14
+ * written as exact JSON number tokens — outbound amounts keep full precision
15
+ * without relying on the daemon accepting strings for numeric params.
16
+ */
17
+ export declare function stringifyLossless(value: unknown): string;
18
+ /**
19
+ * Deep-convert `LosslessNumber` nodes for surfaces without curated types
20
+ * (unknown T1 passthrough fields, `call()` in "lossless" mode):
21
+ * safe integers become `number`, everything else (fractional values,
22
+ * integers beyond 2^53) becomes an exact decimal `string`. No float64
23
+ * rounding can occur.
24
+ */
25
+ export declare function toSafeNumbers(tree: unknown): unknown;
26
+ /**
27
+ * Deep-convert `LosslessNumber` nodes to plain JS `number` — classic
28
+ * `JSON.parse` semantics. Float64 rounding applies; documented as unsafe for
29
+ * arithmetic on amounts. Used by `call()` in "js" mode only.
30
+ */
31
+ export declare function toJsNumbers(tree: unknown): unknown;
32
+ //# sourceMappingURL=lossless.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lossless.d.ts","sourceRoot":"","sources":["../src/lossless.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAoB,MAAM,eAAe,CAAC;AAEnF,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,CAAC;AAE5C,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAMxD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAMpD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAElD"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Lossless JSON layer — the daemon emits value amounts as JSON decimal
3
+ * numbers (`{"VRSCTEST":2.00000000}`), so the transport never runs them
4
+ * through `JSON.parse`'s float64. Number literals survive parsing as
5
+ * `LosslessNumber` (exact decimal string inside) until a mapper decides what
6
+ * they are.
7
+ */
8
+ import { isLosslessNumber, LosslessNumber, parse, stringify } from "lossless-json";
9
+ export { isLosslessNumber, LosslessNumber };
10
+ /** Parse JSON text with number literals preserved as `LosslessNumber`. */
11
+ export function parseLossless(text) {
12
+ return parse(text);
13
+ }
14
+ /**
15
+ * Serialize a request/params tree. `LosslessNumber` and `bigint` nodes are
16
+ * written as exact JSON number tokens — outbound amounts keep full precision
17
+ * without relying on the daemon accepting strings for numeric params.
18
+ */
19
+ export function stringifyLossless(value) {
20
+ const text = stringify(value);
21
+ if (text === undefined) {
22
+ throw new TypeError("value is not serializable to JSON");
23
+ }
24
+ return text;
25
+ }
26
+ /**
27
+ * Deep-convert `LosslessNumber` nodes for surfaces without curated types
28
+ * (unknown T1 passthrough fields, `call()` in "lossless" mode):
29
+ * safe integers become `number`, everything else (fractional values,
30
+ * integers beyond 2^53) becomes an exact decimal `string`. No float64
31
+ * rounding can occur.
32
+ */
33
+ export function toSafeNumbers(tree) {
34
+ return transformNumbers(tree, (ln) => {
35
+ const text = ln.toString();
36
+ const value = Number(text);
37
+ return Number.isSafeInteger(value) && String(value) === text ? value : text;
38
+ });
39
+ }
40
+ /**
41
+ * Deep-convert `LosslessNumber` nodes to plain JS `number` — classic
42
+ * `JSON.parse` semantics. Float64 rounding applies; documented as unsafe for
43
+ * arithmetic on amounts. Used by `call()` in "js" mode only.
44
+ */
45
+ export function toJsNumbers(tree) {
46
+ return transformNumbers(tree, (ln) => Number(ln.toString()));
47
+ }
48
+ function transformNumbers(tree, convert) {
49
+ if (isLosslessNumber(tree)) {
50
+ return convert(tree);
51
+ }
52
+ if (Array.isArray(tree)) {
53
+ return tree.map((item) => transformNumbers(item, convert));
54
+ }
55
+ if (tree !== null && typeof tree === "object") {
56
+ const out = {};
57
+ for (const [key, value] of Object.entries(tree)) {
58
+ out[key] = transformNumbers(value, convert);
59
+ }
60
+ return out;
61
+ }
62
+ return tree;
63
+ }
64
+ //# sourceMappingURL=lossless.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lossless.js","sourceRoot":"","sources":["../src/lossless.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAEnF,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,CAAC;AAE5C,0EAA0E;AAC1E,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,IAAI,SAAS,CAAC,mCAAmC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,IAAa;IACzC,OAAO,gBAAgB,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9E,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,IAAa;IACvC,OAAO,gBAAgB,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAa,EAAE,OAAwC;IAC/E,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9C,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,GAAG,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,41 @@
1
+ export interface FieldContext {
2
+ method: string;
3
+ field: string;
4
+ }
5
+ /** A known value field: exact decimal → bigint sats. */
6
+ export declare function mapAmount(value: unknown, ctx: FieldContext, opts?: {
7
+ signed?: boolean;
8
+ }): bigint;
9
+ export declare function mapAmountOptional(value: unknown, ctx: FieldContext, opts?: {
10
+ signed?: boolean;
11
+ }): bigint | undefined;
12
+ /**
13
+ * A satoshi-INTEGER field (addressindex family emits raw sats, not
14
+ * decimals) → bigint. Exact at any magnitude.
15
+ */
16
+ export declare function mapSats(value: unknown, ctx: FieldContext, opts?: {
17
+ signed?: boolean;
18
+ }): bigint;
19
+ export declare function mapSatsOptional(value: unknown, ctx: FieldContext, opts?: {
20
+ signed?: boolean;
21
+ }): bigint | undefined;
22
+ /** Heights, counts, indexes, timestamps — plain safe integers. */
23
+ export declare function mapInt(value: unknown, ctx: FieldContext): number;
24
+ export declare function mapIntOptional(value: unknown, ctx: FieldContext): number | undefined;
25
+ /** Non-value floats (e.g. difficulty) — float64 is the honest type here. */
26
+ export declare function mapFloat(value: unknown, ctx: FieldContext): number;
27
+ export declare function mapString(value: unknown, ctx: FieldContext): string;
28
+ export declare function mapStringOptional(value: unknown, ctx: FieldContext): string | undefined;
29
+ export declare function mapBoolean(value: unknown, ctx: FieldContext): boolean;
30
+ export declare function mapBooleanOptional(value: unknown, ctx: FieldContext): boolean | undefined;
31
+ export declare function mapStringArray(value: unknown, ctx: FieldContext): string[];
32
+ /** Assert the raw result is a JSON object and return it for field access. */
33
+ export declare function expectObject(value: unknown, method: string): Record<string, unknown>;
34
+ export declare function expectArray(value: unknown, method: string, field?: string): unknown[];
35
+ /**
36
+ * Merge unmapped fields into a curated object: every key of `raw` not
37
+ * already produced by the mapper is passed through with safe-number
38
+ * conversion. Newer daemons must never break a reader (drift rule).
39
+ */
40
+ export declare function withPassthrough<T extends Record<string, unknown>>(raw: Record<string, unknown>, curated: T): T;
41
+ //# sourceMappingURL=mapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapping.d.ts","sourceRoot":"","sources":["../src/mapping.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAMD,wDAAwD;AACxD,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAShG;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,YAAY,EACjB,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1B,MAAM,GAAG,SAAS,CAEpB;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAa9F;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,GAAG,SAAS,CAElH;AAED,kEAAkE;AAClE,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,GAAG,MAAM,CAUhE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAEpF;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,GAAG,MAAM,CAKlE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,GAAG,MAAM,CAKnE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAEvF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAKrE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,GAAG,SAAS,CAEzF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,GAAG,MAAM,EAAE,CAK1E;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKpF;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,SAAa,GAAG,OAAO,EAAE,CAKzF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAW9G"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Response-mapping helpers for curated (T1) methods. Mappers receive the raw
3
+ * lossless tree from the transport (`LosslessNumber` for every number
4
+ * literal) and produce the curated shape: value fields as bigint sats,
5
+ * heights/counts/timestamps as `number`, unknown fields passed through with
6
+ * safe-number conversion (safe integers → number, everything else → exact
7
+ * decimal string — no float64 rounding, ever).
8
+ */
9
+ import { parseAmount } from "./amount.js";
10
+ import { ResponseMappingError } from "./errors.js";
11
+ import { isLosslessNumber, toSafeNumbers } from "./lossless.js";
12
+ function fail(ctx, message) {
13
+ throw new ResponseMappingError(ctx.method, ctx.field, message);
14
+ }
15
+ /** A known value field: exact decimal → bigint sats. */
16
+ export function mapAmount(value, ctx, opts) {
17
+ if (!isLosslessNumber(value)) {
18
+ fail(ctx, `expected a JSON number (amount), got ${describe(value)}`);
19
+ }
20
+ try {
21
+ return parseAmount(value.toString(), opts?.signed === true ? { allowNegative: true } : undefined);
22
+ }
23
+ catch (err) {
24
+ fail(ctx, err instanceof Error ? err.message : String(err));
25
+ }
26
+ }
27
+ export function mapAmountOptional(value, ctx, opts) {
28
+ return value === undefined || value === null ? undefined : mapAmount(value, ctx, opts);
29
+ }
30
+ /**
31
+ * A satoshi-INTEGER field (addressindex family emits raw sats, not
32
+ * decimals) → bigint. Exact at any magnitude.
33
+ */
34
+ export function mapSats(value, ctx, opts) {
35
+ if (!isLosslessNumber(value)) {
36
+ fail(ctx, `expected a JSON number (integer satoshis), got ${describe(value)}`);
37
+ }
38
+ const text = value.toString();
39
+ if (!/^-?\d+$/.test(text)) {
40
+ fail(ctx, `expected integer satoshis, got ${text}`);
41
+ }
42
+ const sats = BigInt(text);
43
+ if (sats < 0n && opts?.signed !== true) {
44
+ fail(ctx, `negative satoshis: ${text}`);
45
+ }
46
+ return sats;
47
+ }
48
+ export function mapSatsOptional(value, ctx, opts) {
49
+ return value === undefined || value === null ? undefined : mapSats(value, ctx, opts);
50
+ }
51
+ /** Heights, counts, indexes, timestamps — plain safe integers. */
52
+ export function mapInt(value, ctx) {
53
+ if (!isLosslessNumber(value)) {
54
+ fail(ctx, `expected a JSON number (integer), got ${describe(value)}`);
55
+ }
56
+ const text = value.toString();
57
+ const num = Number(text);
58
+ if (!Number.isSafeInteger(num) || String(num) !== text) {
59
+ fail(ctx, `expected a safe integer, got ${text}`);
60
+ }
61
+ return num;
62
+ }
63
+ export function mapIntOptional(value, ctx) {
64
+ return value === undefined || value === null ? undefined : mapInt(value, ctx);
65
+ }
66
+ /** Non-value floats (e.g. difficulty) — float64 is the honest type here. */
67
+ export function mapFloat(value, ctx) {
68
+ if (!isLosslessNumber(value)) {
69
+ fail(ctx, `expected a JSON number, got ${describe(value)}`);
70
+ }
71
+ return Number(value.toString());
72
+ }
73
+ export function mapString(value, ctx) {
74
+ if (typeof value !== "string") {
75
+ fail(ctx, `expected a string, got ${describe(value)}`);
76
+ }
77
+ return value;
78
+ }
79
+ export function mapStringOptional(value, ctx) {
80
+ return value === undefined || value === null ? undefined : mapString(value, ctx);
81
+ }
82
+ export function mapBoolean(value, ctx) {
83
+ if (typeof value !== "boolean") {
84
+ fail(ctx, `expected a boolean, got ${describe(value)}`);
85
+ }
86
+ return value;
87
+ }
88
+ export function mapBooleanOptional(value, ctx) {
89
+ return value === undefined || value === null ? undefined : mapBoolean(value, ctx);
90
+ }
91
+ export function mapStringArray(value, ctx) {
92
+ if (!Array.isArray(value)) {
93
+ fail(ctx, `expected an array, got ${describe(value)}`);
94
+ }
95
+ return value.map((item, i) => mapString(item, { method: ctx.method, field: `${ctx.field}[${i}]` }));
96
+ }
97
+ /** Assert the raw result is a JSON object and return it for field access. */
98
+ export function expectObject(value, method) {
99
+ if (value === null || typeof value !== "object" || Array.isArray(value) || isLosslessNumber(value)) {
100
+ throw new ResponseMappingError(method, "(result)", `expected an object, got ${describe(value)}`);
101
+ }
102
+ return value;
103
+ }
104
+ export function expectArray(value, method, field = "(result)") {
105
+ if (!Array.isArray(value)) {
106
+ throw new ResponseMappingError(method, field, `expected an array, got ${describe(value)}`);
107
+ }
108
+ return value;
109
+ }
110
+ /**
111
+ * Merge unmapped fields into a curated object: every key of `raw` not
112
+ * already produced by the mapper is passed through with safe-number
113
+ * conversion. Newer daemons must never break a reader (drift rule).
114
+ */
115
+ export function withPassthrough(raw, curated) {
116
+ const out = {};
117
+ for (const [key, value] of Object.entries(curated)) {
118
+ if (value !== undefined)
119
+ out[key] = value; // absent optionals stay absent
120
+ }
121
+ for (const [key, value] of Object.entries(raw)) {
122
+ if (!(key in curated)) {
123
+ out[key] = toSafeNumbers(value);
124
+ }
125
+ }
126
+ return out;
127
+ }
128
+ function describe(value) {
129
+ if (value === null)
130
+ return "null";
131
+ if (value === undefined)
132
+ return "undefined";
133
+ if (isLosslessNumber(value))
134
+ return `number (${value.toString()})`;
135
+ if (Array.isArray(value))
136
+ return "array";
137
+ return typeof value;
138
+ }
139
+ //# sourceMappingURL=mapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapping.js","sourceRoot":"","sources":["../src/mapping.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import type { RpcTransport } from "../transport.js";
2
+ /**
3
+ * Addressindex family (requires `-addressindex=1` on the daemon; the public
4
+ * gateway exposes it too). Wire quirk, empirically recorded: `balance` /
5
+ * `received` / `satoshis` are raw satoshi INTEGERS while `currencybalance` /
6
+ * `currencyreceived` are 8-decimal values — both map to bigint sats here.
7
+ */
8
+ export interface AddressBalanceResult {
9
+ /** Native-currency balance — bigint sats (wire: satoshi integer). */
10
+ balance: bigint;
11
+ /** Total received — bigint sats (wire: satoshi integer). */
12
+ received: bigint;
13
+ /** Per-currency balances — bigint sats (wire: 8-decimal values). */
14
+ currencybalance?: Record<string, bigint> | undefined;
15
+ currencyreceived?: Record<string, bigint> | undefined;
16
+ [key: string]: unknown;
17
+ }
18
+ export interface AddressUtxo {
19
+ address: string;
20
+ txid: string;
21
+ outputIndex: number;
22
+ script: string;
23
+ /** Bigint sats (wire: satoshi integer). */
24
+ satoshis: bigint;
25
+ height?: number | undefined;
26
+ [key: string]: unknown;
27
+ }
28
+ export interface AddressDelta {
29
+ address: string;
30
+ txid: string;
31
+ /** Signed — bigint sats (wire: satoshi integer). */
32
+ satoshis: bigint;
33
+ index: number;
34
+ blockindex?: number | undefined;
35
+ height?: number | undefined;
36
+ [key: string]: unknown;
37
+ }
38
+ export interface AddressRangeOptions {
39
+ addresses: string[];
40
+ /** Start block height. */
41
+ start?: number;
42
+ /** End block height. */
43
+ end?: number;
44
+ }
45
+ export declare function mapAddressBalance(raw: unknown): AddressBalanceResult;
46
+ export declare function mapAddressUtxo(raw: unknown, index: number): AddressUtxo;
47
+ export declare function mapAddressDelta(raw: unknown, method: string, index: number): AddressDelta;
48
+ /** Address index queries (transparent addresses, cross-wallet). */
49
+ export declare class AddressIndexApi {
50
+ private readonly transport;
51
+ constructor(transport: RpcTransport);
52
+ /** Balance/received of arbitrary transparent addresses — bigint sats. */
53
+ getAddressBalance(options: {
54
+ addresses: string[];
55
+ }): Promise<AddressBalanceResult>;
56
+ /** Unspent outputs of arbitrary transparent addresses — bigint sats. */
57
+ getAddressUtxos(options: {
58
+ addresses: string[];
59
+ }): Promise<AddressUtxo[]>;
60
+ /** Balance changes per address over a height range — signed bigint sats. */
61
+ getAddressDeltas(options: AddressRangeOptions): Promise<AddressDelta[]>;
62
+ /** Mempool deltas touching these addresses — signed bigint sats. */
63
+ getAddressMempool(options: {
64
+ addresses: string[];
65
+ }): Promise<AddressDelta[]>;
66
+ /** Txids touching these addresses (optionally height-bounded). */
67
+ getAddressTxids(options: AddressRangeOptions): Promise<string[]>;
68
+ }
69
+ //# sourceMappingURL=addressindex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addressindex.d.ts","sourceRoot":"","sources":["../../src/methods/addressindex.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD;;;;;GAKG;AAEH,MAAM,WAAW,oBAAoB;IACnC,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACtD,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,0BAA0B;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAoBD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB,CASpE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAYvE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAWzF;AAED,mEAAmE;AACnE,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,YAAY;IAEpD,yEAAyE;IACnE,iBAAiB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAIxF,wEAAwE;IAClE,eAAe,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAQ/E,4EAA4E;IACtE,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAQ7E,oEAAoE;IAC9D,iBAAiB,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAQlF,kEAAkE;IAC5D,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CASvE"}