@vultisig/core-chain 1.2.2 → 1.3.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 (57) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/chains/cardano/cip30/buildCardanoValue.d.ts +18 -0
  3. package/dist/chains/cardano/cip30/buildCardanoValue.d.ts.map +1 -0
  4. package/dist/chains/cardano/cip30/buildCardanoValue.js +72 -0
  5. package/dist/chains/cardano/cip30/buildCardanoValue.js.map +1 -0
  6. package/dist/chains/cardano/cip30/buildCardanoWitnessSet.d.ts +10 -0
  7. package/dist/chains/cardano/cip30/buildCardanoWitnessSet.d.ts.map +1 -0
  8. package/dist/chains/cardano/cip30/buildCardanoWitnessSet.js +15 -0
  9. package/dist/chains/cardano/cip30/buildCardanoWitnessSet.js.map +1 -0
  10. package/dist/chains/cardano/cip30/buildCoseStructures.d.ts +45 -0
  11. package/dist/chains/cardano/cip30/buildCoseStructures.d.ts.map +1 -0
  12. package/dist/chains/cardano/cip30/buildCoseStructures.js +70 -0
  13. package/dist/chains/cardano/cip30/buildCoseStructures.js.map +1 -0
  14. package/dist/chains/cardano/cip30/cardanoAddressBytes.d.ts +6 -0
  15. package/dist/chains/cardano/cip30/cardanoAddressBytes.d.ts.map +1 -0
  16. package/dist/chains/cardano/cip30/cardanoAddressBytes.js +12 -0
  17. package/dist/chains/cardano/cip30/cardanoAddressBytes.js.map +1 -0
  18. package/dist/chains/cardano/cip30/cardanoCborPrimitives.d.ts +53 -0
  19. package/dist/chains/cardano/cip30/cardanoCborPrimitives.d.ts.map +1 -0
  20. package/dist/chains/cardano/cip30/cardanoCborPrimitives.js +91 -0
  21. package/dist/chains/cardano/cip30/cardanoCborPrimitives.js.map +1 -0
  22. package/dist/chains/cardano/cip30/cardanoTxBodyHash.d.ts +6 -0
  23. package/dist/chains/cardano/cip30/cardanoTxBodyHash.d.ts.map +1 -0
  24. package/dist/chains/cardano/cip30/cardanoTxBodyHash.js +55 -0
  25. package/dist/chains/cardano/cip30/cardanoTxBodyHash.js.map +1 -0
  26. package/dist/chains/cardano/cip30/cborEncoder.d.ts +11 -0
  27. package/dist/chains/cardano/cip30/cborEncoder.d.ts.map +1 -0
  28. package/dist/chains/cardano/cip30/cborEncoder.js +14 -0
  29. package/dist/chains/cardano/cip30/cborEncoder.js.map +1 -0
  30. package/dist/chains/cardano/cip30/cborSkip.d.ts +13 -0
  31. package/dist/chains/cardano/cip30/cborSkip.d.ts.map +1 -0
  32. package/dist/chains/cardano/cip30/cborSkip.js +108 -0
  33. package/dist/chains/cardano/cip30/cborSkip.js.map +1 -0
  34. package/dist/chains/cardano/cip30/decodeCardanoAmountValue.d.ts +16 -0
  35. package/dist/chains/cardano/cip30/decodeCardanoAmountValue.d.ts.map +1 -0
  36. package/dist/chains/cardano/cip30/decodeCardanoAmountValue.js +72 -0
  37. package/dist/chains/cardano/cip30/decodeCardanoAmountValue.js.map +1 -0
  38. package/dist/chains/cardano/cip30/encodeCardanoUnspentOutput.d.ts +16 -0
  39. package/dist/chains/cardano/cip30/encodeCardanoUnspentOutput.d.ts.map +1 -0
  40. package/dist/chains/cardano/cip30/encodeCardanoUnspentOutput.js +23 -0
  41. package/dist/chains/cardano/cip30/encodeCardanoUnspentOutput.js.map +1 -0
  42. package/dist/chains/cardano/cip30/encodeCardanoValue.d.ts +4 -0
  43. package/dist/chains/cardano/cip30/encodeCardanoValue.d.ts.map +1 -0
  44. package/dist/chains/cardano/cip30/encodeCardanoValue.js +5 -0
  45. package/dist/chains/cardano/cip30/encodeCardanoValue.js.map +1 -0
  46. package/dist/chains/cardano/cip30/selectCardanoUtxosByLovelace.d.ts +24 -0
  47. package/dist/chains/cardano/cip30/selectCardanoUtxosByLovelace.d.ts.map +1 -0
  48. package/dist/chains/cardano/cip30/selectCardanoUtxosByLovelace.js +23 -0
  49. package/dist/chains/cardano/cip30/selectCardanoUtxosByLovelace.js.map +1 -0
  50. package/dist/chains/cardano/submit/submitCardanoCbor.d.ts +18 -0
  51. package/dist/chains/cardano/submit/submitCardanoCbor.d.ts.map +1 -0
  52. package/dist/chains/cardano/submit/submitCardanoCbor.js +71 -0
  53. package/dist/chains/cardano/submit/submitCardanoCbor.js.map +1 -0
  54. package/dist/tx/broadcast/resolvers/cardano.d.ts.map +1 -1
  55. package/dist/tx/broadcast/resolvers/cardano.js +11 -63
  56. package/dist/tx/broadcast/resolvers/cardano.js.map +1 -1
  57. package/package.json +66 -1
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Walk a CBOR data item starting at `offset` and return the offset
3
+ * immediately after the item ends. This allows extracting raw byte
4
+ * ranges from CBOR without re-encoding.
5
+ *
6
+ * Supports: unsigned/negative ints, byte/text strings, arrays, maps, tags,
7
+ * and simple values (true/false/null). Does NOT support indefinite-length.
8
+ *
9
+ * Every read is bounds-checked so a truncated / malformed CBOR input fails
10
+ * fast with a descriptive error instead of silently returning bogus offsets.
11
+ */
12
+ export const cborSkip = (data, offset) => {
13
+ if (!Number.isInteger(offset) || offset < 0 || offset >= data.length) {
14
+ throw new Error(`cborSkip: offset ${offset} is out of bounds (data length ${data.length})`);
15
+ }
16
+ const initial = data[offset];
17
+ const majorType = initial >> 5;
18
+ const additional = initial & 0x1f;
19
+ const { value, nextOffset } = readArgument(data, offset, additional);
20
+ // Major type 0/1: unsigned/negative integer — head only
21
+ if (majorType <= 1)
22
+ return nextOffset;
23
+ // Major type 2/3: byte/text string — head + N bytes
24
+ if (majorType <= 3) {
25
+ const end = nextOffset + Number(value);
26
+ if (end > data.length) {
27
+ throw new Error(`cborSkip: truncated string at offset ${offset} (need ${Number(value)} bytes, have ${data.length - nextOffset})`);
28
+ }
29
+ return end;
30
+ }
31
+ // Major type 4: array — head + N items
32
+ if (majorType === 4) {
33
+ let pos = nextOffset;
34
+ for (let i = 0; i < Number(value); i++) {
35
+ pos = cborSkip(data, pos);
36
+ }
37
+ return pos;
38
+ }
39
+ // Major type 5: map — head + N key-value pairs
40
+ if (majorType === 5) {
41
+ let pos = nextOffset;
42
+ for (let i = 0; i < Number(value); i++) {
43
+ pos = cborSkip(data, pos); // key
44
+ pos = cborSkip(data, pos); // value
45
+ }
46
+ return pos;
47
+ }
48
+ // Major type 6: tag — head + 1 nested item
49
+ if (majorType === 6)
50
+ return cborSkip(data, nextOffset);
51
+ // Major type 7: simple values / floats
52
+ if (additional <= 23)
53
+ return nextOffset; // simple value in head
54
+ if (additional === 24)
55
+ return nextOffset; // 1-byte simple
56
+ if (additional === 25)
57
+ return nextOffset; // float16 (2 bytes in arg)
58
+ if (additional === 26)
59
+ return nextOffset; // float32 (4 bytes in arg)
60
+ if (additional === 27)
61
+ return nextOffset; // float64 (8 bytes in arg)
62
+ throw new Error(`Unsupported CBOR item at offset ${offset}: initial byte 0x${initial.toString(16)}`);
63
+ };
64
+ /** Read the argument value and return the offset after the argument. */
65
+ const readArgument = (data, offset, additional) => {
66
+ const ensureBytes = (needed) => {
67
+ const end = offset + 1 + needed;
68
+ if (end > data.length) {
69
+ throw new Error(`cborSkip/readArgument: truncated CBOR head at offset ${offset} (need ${needed} argument bytes, have ${data.length - offset - 1})`);
70
+ }
71
+ };
72
+ if (additional < 24)
73
+ return { value: BigInt(additional), nextOffset: offset + 1 };
74
+ if (additional === 24) {
75
+ ensureBytes(1);
76
+ return { value: BigInt(data[offset + 1]), nextOffset: offset + 2 };
77
+ }
78
+ if (additional === 25) {
79
+ ensureBytes(2);
80
+ const v = (data[offset + 1] << 8) | data[offset + 2];
81
+ return { value: BigInt(v), nextOffset: offset + 3 };
82
+ }
83
+ if (additional === 26) {
84
+ ensureBytes(4);
85
+ const v = (data[offset + 1] << 24) |
86
+ (data[offset + 2] << 16) |
87
+ (data[offset + 3] << 8) |
88
+ data[offset + 4];
89
+ return { value: BigInt(v >>> 0), nextOffset: offset + 5 };
90
+ }
91
+ if (additional === 27) {
92
+ ensureBytes(8);
93
+ const hi = (data[offset + 1] << 24) |
94
+ (data[offset + 2] << 16) |
95
+ (data[offset + 3] << 8) |
96
+ data[offset + 4];
97
+ const lo = (data[offset + 5] << 24) |
98
+ (data[offset + 6] << 16) |
99
+ (data[offset + 7] << 8) |
100
+ data[offset + 8];
101
+ return {
102
+ value: (BigInt(hi >>> 0) << 32n) | BigInt(lo >>> 0),
103
+ nextOffset: offset + 9,
104
+ };
105
+ }
106
+ throw new Error(`Unsupported CBOR additional info ${additional}`);
107
+ };
108
+ //# sourceMappingURL=cborSkip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cborSkip.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cardano/cip30/cborSkip.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Decoded shape of a CIP-30 `amount` argument:
3
+ *
4
+ * value = coin / [coin, multiasset<uint>]
5
+ *
6
+ * We surface `hasAssets` as a boolean rather than a full multiasset tree
7
+ * because the main consumer (`getUtxos` coin selection) only selects by
8
+ * lovelace and falls back to a conservative "return all" when the request
9
+ * also has native-token requirements.
10
+ */
11
+ export type CardanoValueRequirement = {
12
+ lovelace: bigint;
13
+ hasAssets: boolean;
14
+ };
15
+ export declare const decodeCardanoAmountValue: (amountHex: string) => CardanoValueRequirement | null;
16
+ //# sourceMappingURL=decodeCardanoAmountValue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decodeCardanoAmountValue.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cardano/cip30/decodeCardanoAmountValue.ts"],"names":[],"mappings":"AAMA;;;;;;;;;GASG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,OAAO,CAAA;CACnB,CAAA;AAoED,eAAO,MAAM,wBAAwB,GACnC,WAAW,MAAM,KAChB,uBAAuB,GAAG,IAI5B,CAAA"}
@@ -0,0 +1,72 @@
1
+ import { stripHexPrefix } from '@vultisig/lib-utils/hex/stripHexPrefix';
2
+ import { attempt } from '@vultisig/lib-utils/attempt';
3
+ import { cardanoCborEncoder } from './cborEncoder.js';
4
+ const hexPattern = /^[0-9a-fA-F]*$/;
5
+ /** Cardano coin is always a non-negative uint — reject anything else. */
6
+ const toBigInt = (value) => {
7
+ if (typeof value === 'bigint')
8
+ return value >= 0n ? value : null;
9
+ if (typeof value === 'number' && Number.isInteger(value) && value >= 0) {
10
+ return BigInt(value);
11
+ }
12
+ return null;
13
+ };
14
+ /**
15
+ * A valid multiasset is a CBOR map:
16
+ *
17
+ * multiasset<a> = { * policy_id => { * asset_name => a } }
18
+ *
19
+ * cbor-x decodes this as a `Map` (because we set `mapsAsObjects: false`), but
20
+ * we accept a plain non-array object too for robustness against inputs that
21
+ * went through a re-encode pass elsewhere. Arrays and scalars are rejected.
22
+ */
23
+ const isMultiassetShape = (value) => value instanceof Map ||
24
+ (typeof value === 'object' && value !== null && !Array.isArray(value));
25
+ const multiassetHasEntries = (value) => {
26
+ if (value instanceof Map)
27
+ return value.size > 0;
28
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
29
+ return Object.keys(value).length > 0;
30
+ }
31
+ return false;
32
+ };
33
+ /**
34
+ * Decode a hex-encoded CBOR `value` (per CIP-30 `getUtxos(amount)`).
35
+ *
36
+ * Returns `null` for inputs that fail to decode or don't match the
37
+ * `coin / [coin, multiasset]` shape — callers should treat a null result as
38
+ * "no usable filter" and fall back to returning all UTXOs.
39
+ */
40
+ const tryDecode = (amountHex) => {
41
+ const stripped = stripHexPrefix(amountHex);
42
+ // Buffer.from('...', 'hex') silently truncates at the first non-hex byte,
43
+ // which would let `0xgg` or odd-length inputs squeak past as valid-looking
44
+ // (but wrong) CBOR. Validate up front.
45
+ if (stripped.length === 0 || stripped.length % 2 !== 0 || !hexPattern.test(stripped)) {
46
+ return null;
47
+ }
48
+ const bytes = Uint8Array.from(Buffer.from(stripped, 'hex'));
49
+ if (bytes.length === 0)
50
+ return null;
51
+ const decoded = cardanoCborEncoder.decode(bytes);
52
+ if (Array.isArray(decoded) && decoded.length === 2) {
53
+ const lovelace = toBigInt(decoded[0]);
54
+ if (lovelace === null)
55
+ return null;
56
+ const ma = decoded[1];
57
+ if (!isMultiassetShape(ma))
58
+ return null;
59
+ return { lovelace, hasAssets: multiassetHasEntries(ma) };
60
+ }
61
+ const lovelace = toBigInt(decoded);
62
+ if (lovelace === null)
63
+ return null;
64
+ return { lovelace, hasAssets: false };
65
+ };
66
+ export const decodeCardanoAmountValue = (amountHex) => {
67
+ const result = attempt(() => tryDecode(amountHex));
68
+ if ('error' in result)
69
+ return null;
70
+ return result.data ?? null;
71
+ };
72
+ //# sourceMappingURL=decodeCardanoAmountValue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decodeCardanoAmountValue.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cardano/cip30/decodeCardanoAmountValue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { CardanoExtendedUtxo } from '../utxo/getCardanoExtendedUtxos.js';
2
+ type Input = {
3
+ utxo: CardanoExtendedUtxo;
4
+ addressBytes: Uint8Array;
5
+ };
6
+ /**
7
+ * CBOR-encode a CIP-30 `transaction_unspent_output = [input, output]`:
8
+ *
9
+ * transaction_input = [ tx_hash: bytes .size 32, index: uint ]
10
+ * transaction_output = [ address: bytes, amount: value ]
11
+ *
12
+ * `address_bytes` should already be the raw address bytes (see `cardanoAddressBytes`).
13
+ */
14
+ export declare const encodeCardanoUnspentOutput: ({ utxo, addressBytes, }: Input) => Uint8Array;
15
+ export {};
16
+ //# sourceMappingURL=encodeCardanoUnspentOutput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encodeCardanoUnspentOutput.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cardano/cip30/encodeCardanoUnspentOutput.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAA;AAOrE,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,mBAAmB,CAAA;IACzB,YAAY,EAAE,UAAU,CAAA;CACzB,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,GAAI,yBAGxC,KAAK,KAAG,UAWV,CAAA"}
@@ -0,0 +1,23 @@
1
+ import { stripHexPrefix } from '@vultisig/lib-utils/hex/stripHexPrefix';
2
+ import { buildCardanoValue } from './buildCardanoValue.js';
3
+ import { cardanoCborEncoder } from './cborEncoder.js';
4
+ const hexToBytes = (hex) => Uint8Array.from(Buffer.from(stripHexPrefix(hex), 'hex'));
5
+ /**
6
+ * CBOR-encode a CIP-30 `transaction_unspent_output = [input, output]`:
7
+ *
8
+ * transaction_input = [ tx_hash: bytes .size 32, index: uint ]
9
+ * transaction_output = [ address: bytes, amount: value ]
10
+ *
11
+ * `address_bytes` should already be the raw address bytes (see `cardanoAddressBytes`).
12
+ */
13
+ export const encodeCardanoUnspentOutput = ({ utxo, addressBytes, }) => {
14
+ const txHashBytes = hexToBytes(utxo.hash);
15
+ if (txHashBytes.length !== 32) {
16
+ throw new Error(`encodeCardanoUnspentOutput: tx_hash must be 32 bytes, got ${txHashBytes.length} (hash=${JSON.stringify(utxo.hash)})`);
17
+ }
18
+ return cardanoCborEncoder.encode([
19
+ [txHashBytes, utxo.index],
20
+ [addressBytes, buildCardanoValue(utxo.amount, utxo.assets)],
21
+ ]);
22
+ };
23
+ //# sourceMappingURL=encodeCardanoUnspentOutput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encodeCardanoUnspentOutput.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cardano/cip30/encodeCardanoUnspentOutput.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAA;AAGvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,MAAM,UAAU,GAAG,CAAC,GAAW,EAAc,EAAE,CAC7C,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAA;AAO1D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,EACzC,IAAI,EACJ,YAAY,GACN,EAAc,EAAE;IACtB,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzC,IAAI,WAAW,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,6DAA6D,WAAW,CAAC,MAAM,UAAU,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACtH,CAAA;IACH,CAAC;IACD,OAAO,kBAAkB,CAAC,MAAM,CAAC;QAC/B,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC;QACzB,CAAC,YAAY,EAAE,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;KAC5D,CAAC,CAAA;AACJ,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { CardanoNativeAsset } from './buildCardanoValue.js';
2
+ /** CBOR-encode a Cardano `value` — the shape returned by `getBalance()` under CIP-30. */
3
+ export declare const encodeCardanoValue: (lovelace: bigint, assets: readonly CardanoNativeAsset[]) => Uint8Array;
4
+ //# sourceMappingURL=encodeCardanoValue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encodeCardanoValue.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cardano/cip30/encodeCardanoValue.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,kBAAkB,EACnB,MAAM,qBAAqB,CAAA;AAG5B,yFAAyF;AACzF,eAAO,MAAM,kBAAkB,GAC7B,UAAU,MAAM,EAChB,QAAQ,SAAS,kBAAkB,EAAE,KACpC,UAC6D,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { buildCardanoValue, } from './buildCardanoValue.js';
2
+ import { cardanoCborEncoder } from './cborEncoder.js';
3
+ /** CBOR-encode a Cardano `value` — the shape returned by `getBalance()` under CIP-30. */
4
+ export const encodeCardanoValue = (lovelace, assets) => cardanoCborEncoder.encode(buildCardanoValue(lovelace, assets));
5
+ //# sourceMappingURL=encodeCardanoValue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encodeCardanoValue.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cardano/cip30/encodeCardanoValue.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,GAElB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,yFAAyF;AACzF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,QAAgB,EAChB,MAAqC,EACzB,EAAE,CACd,kBAAkB,CAAC,MAAM,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Minimal UTXO shape required by lovelace coin selection. Matches
3
+ * `CardanoExtendedUtxo` but is structurally typed so callers can pass any
4
+ * row with an `amount: bigint`.
5
+ */
6
+ export type CardanoCoinSelectionUtxo = {
7
+ amount: bigint;
8
+ };
9
+ export type SelectCardanoUtxosByLovelaceInput<T extends CardanoCoinSelectionUtxo> = {
10
+ utxos: readonly T[];
11
+ targetLovelace: bigint;
12
+ };
13
+ /**
14
+ * Greedy largest-first coin selection by lovelace.
15
+ *
16
+ * Used by CIP-30 `getUtxos(amount)` to return a minimal covering set. The
17
+ * wallet is free to return a superset (the spec explicitly allows it), but
18
+ * picking largest-first keeps the returned set small, which reduces the
19
+ * CBOR payload size and the dApp's downstream selection work.
20
+ *
21
+ * Returns `null` when even the full set is insufficient to meet the target.
22
+ */
23
+ export declare const selectCardanoUtxosByLovelace: <T extends CardanoCoinSelectionUtxo>({ utxos, targetLovelace, }: SelectCardanoUtxosByLovelaceInput<T>) => T[] | null;
24
+ //# sourceMappingURL=selectCardanoUtxosByLovelace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectCardanoUtxosByLovelace.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cardano/cip30/selectCardanoUtxosByLovelace.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,wBAAwB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAEzD,MAAM,MAAM,iCAAiC,CAAC,CAAC,SAAS,wBAAwB,IAAI;IAClF,KAAK,EAAE,SAAS,CAAC,EAAE,CAAA;IACnB,cAAc,EAAE,MAAM,CAAA;CACvB,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,GAAI,CAAC,SAAS,wBAAwB,EAAE,4BAG9E,iCAAiC,CAAC,CAAC,CAAC,KAAG,CAAC,EAAE,GAAG,IAY/C,CAAA"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Greedy largest-first coin selection by lovelace.
3
+ *
4
+ * Used by CIP-30 `getUtxos(amount)` to return a minimal covering set. The
5
+ * wallet is free to return a superset (the spec explicitly allows it), but
6
+ * picking largest-first keeps the returned set small, which reduces the
7
+ * CBOR payload size and the dApp's downstream selection work.
8
+ *
9
+ * Returns `null` when even the full set is insufficient to meet the target.
10
+ */
11
+ export const selectCardanoUtxosByLovelace = ({ utxos, targetLovelace, }) => {
12
+ const sorted = [...utxos].sort((a, b) => a.amount > b.amount ? -1 : a.amount < b.amount ? 1 : 0);
13
+ let total = 0n;
14
+ const picked = [];
15
+ for (const u of sorted) {
16
+ if (total >= targetLovelace)
17
+ break;
18
+ picked.push(u);
19
+ total += u.amount;
20
+ }
21
+ return total >= targetLovelace ? picked : null;
22
+ };
23
+ //# sourceMappingURL=selectCardanoUtxosByLovelace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectCardanoUtxosByLovelace.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cardano/cip30/selectCardanoUtxosByLovelace.ts"],"names":[],"mappings":"AAYA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAqC,EAC/E,KAAK,EACL,cAAc,GACuB,EAAc,EAAE;IACrD,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACtC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACvD,CAAA;IACD,IAAI,KAAK,GAAG,EAAE,CAAA;IACd,MAAM,MAAM,GAAQ,EAAE,CAAA;IACtB,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,KAAK,IAAI,cAAc;YAAE,MAAK;QAClC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACd,KAAK,IAAI,CAAC,CAAC,MAAM,CAAA;IACnB,CAAC;IACD,OAAO,KAAK,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA;AAChD,CAAC,CAAA"}
@@ -0,0 +1,18 @@
1
+ /** Low-level result so callers can branch on already-committed (3117) etc. */
2
+ export type SubmitCardanoCborResult = {
3
+ txHash: string | null;
4
+ errorMessage: string | null;
5
+ /** JSON-RPC error code from the node, when present. */
6
+ rpcErrorCode?: number;
7
+ /** Raw response body, for callers that want to log or pattern match. */
8
+ rawResponse: string;
9
+ };
10
+ /**
11
+ * Broadcast a hex-encoded Cardano transaction CBOR via the Vultisig Ogmios JSON-RPC proxy.
12
+ *
13
+ * This low-level helper exposes the raw response so higher-level callers can
14
+ * distinguish "already-committed" (`rpcErrorCode === 3117`), mempool conflicts,
15
+ * etc. For the common "submit or throw" shape, use `submitCardanoCborTx`.
16
+ */
17
+ export declare const submitCardanoCbor: (cborHex: string) => Promise<SubmitCardanoCborResult>;
18
+ //# sourceMappingURL=submitCardanoCbor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submitCardanoCbor.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cardano/submit/submitCardanoCbor.ts"],"names":[],"mappings":"AAkBA,8EAA8E;AAC9E,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,wEAAwE;IACxE,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAC5B,SAAS,MAAM,KACd,OAAO,CAAC,uBAAuB,CAmEjC,CAAA"}
@@ -0,0 +1,71 @@
1
+ import { rootApiUrl } from '@vultisig/core-config';
2
+ import { extractErrorMsg } from '@vultisig/lib-utils/error/extractErrorMsg';
3
+ import { attempt } from '@vultisig/lib-utils/attempt';
4
+ const cardanoBroadcastUrl = `${rootApiUrl}/ada/`;
5
+ /** Cap a submit at 30s so a hung connection doesn't wedge the signer popup. */
6
+ const cardanoBroadcastTimeoutMs = 30_000;
7
+ const stripHashPrefix = (hash) => hash.replace(/^0x/i, '');
8
+ /**
9
+ * Broadcast a hex-encoded Cardano transaction CBOR via the Vultisig Ogmios JSON-RPC proxy.
10
+ *
11
+ * This low-level helper exposes the raw response so higher-level callers can
12
+ * distinguish "already-committed" (`rpcErrorCode === 3117`), mempool conflicts,
13
+ * etc. For the common "submit or throw" shape, use `submitCardanoCborTx`.
14
+ */
15
+ export const submitCardanoCbor = async (cborHex) => {
16
+ const cleaned = cborHex.replace(/^0x/i, '').toLowerCase();
17
+ // Direct fetch: `queryUrl` auto-runs assertFetchResponse which throws before
18
+ // we can inspect the raw body or status.
19
+ const controller = new AbortController();
20
+ const timeoutId = setTimeout(() => controller.abort(), cardanoBroadcastTimeoutMs);
21
+ const fetchResult = await attempt(() => fetch(cardanoBroadcastUrl, {
22
+ method: 'POST',
23
+ headers: { 'Content-Type': 'application/json' },
24
+ body: JSON.stringify({
25
+ jsonrpc: '2.0',
26
+ method: 'submitTransaction',
27
+ params: { transaction: { cbor: cleaned } },
28
+ id: 1,
29
+ }),
30
+ signal: controller.signal,
31
+ }));
32
+ clearTimeout(timeoutId);
33
+ if ('error' in fetchResult) {
34
+ const timedOut = controller.signal.aborted;
35
+ return {
36
+ txHash: null,
37
+ errorMessage: timedOut
38
+ ? `Cardano broadcast timed out after ${cardanoBroadcastTimeoutMs}ms`
39
+ : extractErrorMsg(fetchResult.error),
40
+ rawResponse: '',
41
+ };
42
+ }
43
+ const response = fetchResult.data;
44
+ const bodyResult = await attempt(() => response.text());
45
+ if ('error' in bodyResult) {
46
+ return {
47
+ txHash: null,
48
+ errorMessage: extractErrorMsg(bodyResult.error),
49
+ rawResponse: '',
50
+ };
51
+ }
52
+ const rawResponse = bodyResult.data;
53
+ const parsedResult = attempt(() => JSON.parse(rawResponse));
54
+ const parsed = 'data' in parsedResult ? parsedResult.data : null;
55
+ const txId = parsed?.result?.transaction?.id;
56
+ if (typeof txId === 'string' && txId.trim()) {
57
+ return {
58
+ txHash: stripHashPrefix(txId.trim()),
59
+ errorMessage: null,
60
+ rpcErrorCode: parsed?.error?.code,
61
+ rawResponse,
62
+ };
63
+ }
64
+ return {
65
+ txHash: null,
66
+ errorMessage: extractErrorMsg(parsed?.error ?? rawResponse),
67
+ rpcErrorCode: parsed?.error?.code,
68
+ rawResponse,
69
+ };
70
+ };
71
+ //# sourceMappingURL=submitCardanoCbor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submitCardanoCbor.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cardano/submit/submitCardanoCbor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAA;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AASrD,MAAM,mBAAmB,GAAG,GAAG,UAAU,OAAO,CAAA;AAEhD,+EAA+E;AAC/E,MAAM,yBAAyB,GAAG,MAAM,CAAA;AAExC,MAAM,eAAe,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;AAY1E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EACpC,OAAe,EACmB,EAAE;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;IAEzD,6EAA6E;IAC7E,yCAAyC;IACzC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;IACxC,MAAM,SAAS,GAAG,UAAU,CAC1B,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EACxB,yBAAyB,CAC1B,CAAA;IAED,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,CACrC,KAAK,CAAC,mBAAmB,EAAE;QACzB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,mBAAmB;YAC3B,MAAM,EAAE,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;YAC1C,EAAE,EAAE,CAAC;SACN,CAAC;QACF,MAAM,EAAE,UAAU,CAAC,MAAM;KAC1B,CAAC,CACH,CAAA;IACD,YAAY,CAAC,SAAS,CAAC,CAAA;IAEvB,IAAI,OAAO,IAAI,WAAW,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,OAAO,CAAA;QAC1C,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,YAAY,EAAE,QAAQ;gBACpB,CAAC,CAAC,qCAAqC,yBAAyB,IAAI;gBACpE,CAAC,CAAC,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC;YACtC,WAAW,EAAE,EAAE;SAChB,CAAA;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAA;IACjC,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IACvD,IAAI,OAAO,IAAI,UAAU,EAAE,CAAC;QAC1B,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,YAAY,EAAE,eAAe,CAAC,UAAU,CAAC,KAAK,CAAC;YAC/C,WAAW,EAAE,EAAE;SAChB,CAAA;IACH,CAAC;IAED,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAA;IACnC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAmB,CAAC,CAAA;IAC7E,MAAM,MAAM,GAAG,MAAM,IAAI,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;IAEhE,MAAM,IAAI,GAAG,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,CAAA;IAC5C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QAC5C,OAAO;YACL,MAAM,EAAE,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACpC,YAAY,EAAE,IAAI;YAClB,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI;YACjC,WAAW;SACZ,CAAA;IACH,CAAC;IAED,OAAO;QACL,MAAM,EAAE,IAAI;QACZ,YAAY,EAAE,eAAe,CAAC,MAAM,EAAE,KAAK,IAAI,WAAW,CAAC;QAC3D,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI;QACjC,WAAW;KACZ,CAAA;AACH,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"cardano.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/cardano.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAMvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAsDjD,eAAO,MAAM,kBAAkB,EAAE,mBAAmB,CAClD,UAAU,CAAC,OAAO,CAwDnB,CAAA"}
1
+ {"version":3,"file":"cardano.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/cardano.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAMvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AASjD,eAAO,MAAM,kBAAkB,EAAE,mBAAmB,CAClD,UAAU,CAAC,OAAO,CA4BnB,CAAA"}
@@ -1,74 +1,22 @@
1
1
  import { getCardanoTxHash } from '@vultisig/core-chain/tx/hash/resolvers/cardano';
2
- import { rootApiUrl } from '@vultisig/core-config';
3
- import { extractErrorMsg } from '@vultisig/lib-utils/error/extractErrorMsg';
4
2
  import { isInError } from '@vultisig/lib-utils/error/isInError';
3
+ import { submitCardanoCbor } from '../../../chains/cardano/submit/submitCardanoCbor.js';
5
4
  import { selectEncodedBytes } from './utxo.js';
6
- const cardanoBroadcastUrl = `${rootApiUrl}/ada/`;
7
- const normalizeHash = (hash) => hash.replace(/^0x/i, '');
8
- const parseJson = (raw) => {
9
- try {
10
- return JSON.parse(raw);
11
- }
12
- catch {
13
- return null;
14
- }
15
- };
16
- const extractTxHash = (response) => {
17
- if (!response) {
18
- return null;
19
- }
20
- if (typeof response === 'string') {
21
- const trimmed = response.trim();
22
- return trimmed ? normalizeHash(trimmed) : null;
23
- }
24
- const txId = response.result?.transaction?.id;
25
- if (typeof txId === 'string' && txId.trim()) {
26
- return normalizeHash(txId.trim());
27
- }
28
- return null;
29
- };
30
- const extractError = (response, raw) => {
31
- if (!response) {
32
- return extractErrorMsg(raw);
33
- }
34
- if (typeof response === 'string') {
35
- return extractErrorMsg(response);
36
- }
37
- return extractErrorMsg(response.error ?? raw);
38
- };
5
+ /**
6
+ * Ogmios code for "transaction already known / in ledger". When the node
7
+ * reports this, we hash the tx locally to return the deterministic id.
8
+ */
9
+ const alreadyCommittedCode = 3117;
39
10
  export const broadcastCardanoTx = async ({ chain, tx }) => {
40
11
  const encodedBytes = selectEncodedBytes(chain, tx);
41
12
  const cborHex = Buffer.from(encodedBytes).toString('hex');
42
- // @tony: sticking with the direct fetch here. Our 'queryUrl' auto-runs assertFetchResponse, which throws before we can inspect the raw body or status.
43
- const response = await fetch(cardanoBroadcastUrl, {
44
- method: 'POST',
45
- headers: {
46
- 'Content-Type': 'application/json',
47
- },
48
- body: JSON.stringify({
49
- jsonrpc: '2.0',
50
- method: 'submitTransaction',
51
- params: {
52
- transaction: {
53
- cbor: cborHex,
54
- },
55
- },
56
- id: 1,
57
- }),
58
- });
59
- const responseText = await response.text();
60
- const parsed = parseJson(responseText);
61
- const rpcErrorCode = parsed && typeof parsed === 'object' && !Array.isArray(parsed)
62
- ? parsed.error?.code
63
- : undefined;
64
- if (rpcErrorCode === 3117) {
65
- return normalizeHash(await getCardanoTxHash(tx));
66
- }
67
- const txHash = extractTxHash(parsed) ?? extractTxHash(responseText);
68
- if (txHash) {
13
+ const { txHash, errorMessage, rpcErrorCode } = await submitCardanoCbor(cborHex);
14
+ if (txHash)
69
15
  return txHash;
16
+ if (rpcErrorCode === alreadyCommittedCode) {
17
+ return (await getCardanoTxHash(tx)).replace(/^0x/i, '');
70
18
  }
71
- const error = extractError(parsed, responseText);
19
+ const error = errorMessage ?? 'unknown broadcast failure';
72
20
  if (isInError(error, 'BadInputsUTxO', 'timed out', 'txn-mempool-conflict', 'already known')) {
73
21
  return null;
74
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cardano.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/cardano.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gDAAgD,CAAA;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAA;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAG/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAA;AAE3C,MAAM,mBAAmB,GAAG,GAAG,UAAU,OAAO,CAAA;AAUhD,MAAM,aAAa,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;AAExE,MAAM,SAAS,GAAG,CAAC,GAAW,EAAyB,EAAE;IACvD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC,CAAA;AAED,MAAM,aAAa,GAAG,CAAC,QAA+B,EAAiB,EAAE;IACvE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAA;QAC/B,OAAO,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAChD,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,CAAA;IAE7C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QAC5C,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;IACnC,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,CAAC,QAA+B,EAAE,GAAW,EAAU,EAAE;IAC5E,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,eAAe,CAAC,GAAG,CAAC,CAAA;IAC7B,CAAC;IAED,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAA;IAClC,CAAC;IAED,OAAO,eAAe,CAAC,QAAQ,CAAC,KAAK,IAAI,GAAG,CAAC,CAAA;AAC/C,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAE3B,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE;IAC1B,MAAM,YAAY,GAAG,kBAAkB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAClD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAEzD,uJAAuJ;IACvJ,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,mBAAmB,EAAE;QAChD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,mBAAmB;YAC3B,MAAM,EAAE;gBACN,WAAW,EAAE;oBACX,IAAI,EAAE,OAAO;iBACd;aACF;YACD,EAAE,EAAE,CAAC;SACN,CAAC;KACH,CAAC,CAAA;IAEF,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;IAC1C,MAAM,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC,CAAA;IAEtC,MAAM,YAAY,GAChB,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAC5D,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI;QACpB,CAAC,CAAC,SAAS,CAAA;IAEf,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO,aAAa,CAAC,MAAM,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAA;IAClD,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,aAAa,CAAC,YAAY,CAAC,CAAA;IAEnE,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAM,CAAA;IACf,CAAC;IAED,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IAEhD,IACE,SAAS,CACP,KAAK,EACL,eAAe,EACf,WAAW,EACX,sBAAsB,EACtB,eAAe,CAChB,EACD,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,oCAAoC,KAAK,EAAE,CAAC,CAAA;AAC9D,CAAC,CAAA"}
1
+ {"version":3,"file":"cardano.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/cardano.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gDAAgD,CAAA;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAE/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kDAAkD,CAAA;AAGpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAA;AAE3C;;;GAGG;AACH,MAAM,oBAAoB,GAAG,IAAI,CAAA;AAEjC,MAAM,CAAC,MAAM,kBAAkB,GAE3B,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE;IAC1B,MAAM,YAAY,GAAG,kBAAkB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAClD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAEzD,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAA;IAE/E,IAAI,MAAM;QAAE,OAAO,MAAM,CAAA;IAEzB,IAAI,YAAY,KAAK,oBAAoB,EAAE,CAAC;QAC1C,OAAO,CAAC,MAAM,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IACzD,CAAC;IAED,MAAM,KAAK,GAAG,YAAY,IAAI,2BAA2B,CAAA;IAEzD,IACE,SAAS,CACP,KAAK,EACL,eAAe,EACf,WAAW,EACX,sBAAsB,EACtB,eAAe,CAChB,EACD,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,oCAAoC,KAAK,EAAE,CAAC,CAAA;AAC9D,CAAC,CAAA"}